(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 = "89f3a85f4f23470aac3a073ed40a1430";
  window.nativeAdId = "fd100d98b2a14efba49ecd135827b0ec";
  window.videoAdId = "47f4c5e5d61240448e1aa2791442b74a";

  //初始化变量
  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 () {
          // console.log('insertAdverV2',"ZZZZZZZZZZZZZ")
          // return;
          // if(Advertisement.isShow == true){
          //     Advertisement.isShow = false;
          //     setTimeout(() =>{
          //         Advertisement.isShow = true;
          //     },7000);
              
          // }
          this.testDate = new Date();
          console.log('insertAdverV2',"ZZZZZZZZZZZZZ");
              if(!Advertisement.TimeManger(2024,11,30,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.25;
  		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;
  	}
  }

  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);
  		}
  	}
  	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 * TweenSystem.timeScale);
  			});
  		}
  	}
  	get ActionManager() {
  		return this.actionMgr;
  	}
  	postUpdate(dt) {
  		this.actionMgr.update(dt);
  	}
  }
  TweenSystem.ID = 'tween';
  TweenSystem.timeScale = 1;

  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}]`);
  		}
  		return db;
  	}
  	static get_adv_banner_int_db_map() {
  		return this.getDb("adv_banner_int_db");
  	}
  	static get_adv_banner_int_db(advName, bSilent = true) {
  		try {
  			let data = this.get_adv_banner_int_db_map()[advName];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in adv_banner_int_db by advName [${advName}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_adv_db_map() {
  		return this.getDb("adv_db");
  	}
  	static get_adv_db(advName, bSilent = true) {
  		try {
  			let data = this.get_adv_db_map()[advName];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in adv_db by advName [${advName}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_ad_banner_int_ui_db_map() {
  		return this.getDb("ad_banner_int_ui_db");
  	}
  	static get_ad_banner_int_ui_db(viewName, bSilent = true) {
  		try {
  			let data = this.get_ad_banner_int_ui_db_map()[viewName];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in ad_banner_int_ui_db by viewName [${viewName}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_alert_router_db_map() {
  		return this.getDb("alert_router_db");
  	}
  	static get_alert_router_db(routerId, index, bSilent = true) {
  		try {
  			let data = this.get_alert_router_db_map()[routerId][index];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in alert_router_db by index [${index}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_amaze_cloth_crossing_config_map() {
  		return this.getDb("amaze_cloth_crossing_config");
  	}
  	static get_amaze_cloth_crossing_config(id, bSilent = true) {
  		try {
  			let data = this.get_amaze_cloth_crossing_config_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in amaze_cloth_crossing_config by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_amaze_cloth_crossing_item_db_map() {
  		return this.getDb("amaze_cloth_crossing_item_db");
  	}
  	static get_amaze_cloth_crossing_item_db(id, bSilent = true) {
  		try {
  			let data = this.get_amaze_cloth_crossing_item_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in amaze_cloth_crossing_item_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_amaze_cloth_crossing_property_to_logic_role_map() {
  		return this.getDb("amaze_cloth_crossing_property_to_logic_role");
  	}
  	static get_amaze_cloth_crossing_property_to_logic_role(id, bSilent = true) {
  		try {
  			let data = this.get_amaze_cloth_crossing_property_to_logic_role_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in amaze_cloth_crossing_property_to_logic_role by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_amaze_cloth_crossing_question_db_map() {
  		return this.getDb("amaze_cloth_crossing_question_db");
  	}
  	static get_amaze_cloth_crossing_question_db(id, bSilent = true) {
  		try {
  			let data = this.get_amaze_cloth_crossing_question_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in amaze_cloth_crossing_question_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_amaze_cloth_crossing_question_road_db_map() {
  		return this.getDb("amaze_cloth_crossing_question_road_db");
  	}
  	static get_amaze_cloth_crossing_question_road_db(id, bSilent = true) {
  		try {
  			let data = this.get_amaze_cloth_crossing_question_road_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in amaze_cloth_crossing_question_road_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_amaze_cloth_crossing_result_interactive_db_map() {
  		return this.getDb("amaze_cloth_crossing_result_interactive_db");
  	}
  	static get_amaze_cloth_crossing_result_interactive_db(quoteName, bSilent = true) {
  		try {
  			let data = this.get_amaze_cloth_crossing_result_interactive_db_map()[quoteName];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in amaze_cloth_crossing_result_interactive_db by quoteName [${quoteName}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_amaze_cloth_crossing_road_event_db_map() {
  		return this.getDb("amaze_cloth_crossing_road_event_db");
  	}
  	static get_amaze_cloth_crossing_road_event_db(id, bSilent = true) {
  		try {
  			let data = this.get_amaze_cloth_crossing_road_event_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in amaze_cloth_crossing_road_event_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_amaze_cloth_crossing_role_born_type_map() {
  		return this.getDb("amaze_cloth_crossing_role_born_type");
  	}
  	static get_amaze_cloth_crossing_role_born_type(id, bSilent = true) {
  		try {
  			let data = this.get_amaze_cloth_crossing_role_born_type_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in amaze_cloth_crossing_role_born_type by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_amaze_cloth_crossing_role_db_map() {
  		return this.getDb("amaze_cloth_crossing_role_db");
  	}
  	static get_amaze_cloth_crossing_role_db(id, bSilent = true) {
  		try {
  			let data = this.get_amaze_cloth_crossing_role_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in amaze_cloth_crossing_role_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_amaze_cloth_crossing_role_head_deco_db_map() {
  		return this.getDb("amaze_cloth_crossing_role_head_deco_db");
  	}
  	static get_amaze_cloth_crossing_role_head_deco_db(id, bSilent = true) {
  		try {
  			let data = this.get_amaze_cloth_crossing_role_head_deco_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in amaze_cloth_crossing_role_head_deco_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_amaze_cloth_crossing_role_property_map() {
  		return this.getDb("amaze_cloth_crossing_role_property");
  	}
  	static get_amaze_cloth_crossing_role_property(id, bSilent = true) {
  		try {
  			let data = this.get_amaze_cloth_crossing_role_property_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in amaze_cloth_crossing_role_property by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_amaze_cloth_crossing_stage_db_map() {
  		return this.getDb("amaze_cloth_crossing_stage_db");
  	}
  	static get_amaze_cloth_crossing_stage_db(id, bSilent = true) {
  		try {
  			let data = this.get_amaze_cloth_crossing_stage_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in amaze_cloth_crossing_stage_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_animation_db_map() {
  		return this.getDb("animation_db");
  	}
  	static get_animation_db(id, bSilent = true) {
  		try {
  			let data = this.get_animation_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in animation_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_auto_increase_db_map() {
  		return this.getDb("auto_increase_db");
  	}
  	static get_auto_increase_db(itemId, bSilent = true) {
  		try {
  			let data = this.get_auto_increase_db_map()[itemId];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in auto_increase_db by itemId [${itemId}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_cube_map_db_map() {
  		return this.getDb("cube_map_db");
  	}
  	static get_cube_map_db(id, bSilent = true) {
  		try {
  			let data = this.get_cube_map_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in cube_map_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_douyin_follow_config_map() {
  		return this.getDb("douyin_follow_config");
  	}
  	static get_douyin_follow_config(id, bSilent = true) {
  		try {
  			let data = this.get_douyin_follow_config_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in douyin_follow_config by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_drop_db_map() {
  		return this.getDb("drop_db");
  	}
  	static get_drop_db(id, bSilent = true) {
  		try {
  			let data = this.get_drop_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in drop_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_ggg_activement_template_db_map() {
  		return this.getDb("ggg_activement_template_db");
  	}
  	static get_ggg_activement_template_db(id, bSilent = true) {
  		try {
  			let data = this.get_ggg_activement_template_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in ggg_activement_template_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_ggg_challenge_stage_config_map() {
  		return this.getDb("ggg_challenge_stage_config");
  	}
  	static get_ggg_challenge_stage_config(challengeType, bSilent = true) {
  		try {
  			let data = this.get_ggg_challenge_stage_config_map()[challengeType];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in ggg_challenge_stage_config by challengeType [${challengeType}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_ggg_extra_item_property_template_db_map() {
  		return this.getDb("ggg_extra_item_property_template_db");
  	}
  	static get_ggg_extra_item_property_template_db(level, bSilent = true) {
  		try {
  			let data = this.get_ggg_extra_item_property_template_db_map()[level];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in ggg_extra_item_property_template_db by level [${level}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_ggg_pet_template_db_map() {
  		return this.getDb("ggg_pet_template_db");
  	}
  	static get_ggg_pet_template_db(id, level, bSilent = true) {
  		try {
  			let data = this.get_ggg_pet_template_db_map()[id][level];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in ggg_pet_template_db by level [${level}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_ggg_retinue_template_db_map() {
  		return this.getDb("ggg_retinue_template_db");
  	}
  	static get_ggg_retinue_template_db(id, level, bSilent = true) {
  		try {
  			let data = this.get_ggg_retinue_template_db_map()[id][level];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in ggg_retinue_template_db by level [${level}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_ggg_skill_template_db_map() {
  		return this.getDb("ggg_skill_template_db");
  	}
  	static get_ggg_skill_template_db(id, bSilent = true) {
  		try {
  			let data = this.get_ggg_skill_template_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in ggg_skill_template_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_ggg_timeline_config_db_map() {
  		return this.getDb("ggg_timeline_config_db");
  	}
  	static get_ggg_timeline_config_db(id, bSilent = true) {
  		try {
  			let data = this.get_ggg_timeline_config_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in ggg_timeline_config_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_ggg_timeline_movie_word_db_map() {
  		return this.getDb("ggg_timeline_movie_word_db");
  	}
  	static get_ggg_timeline_movie_word_db(id, bSilent = true) {
  		try {
  			let data = this.get_ggg_timeline_movie_word_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in ggg_timeline_movie_word_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_ggg_yard_build_template_db_map() {
  		return this.getDb("ggg_yard_build_template_db");
  	}
  	static get_ggg_yard_build_template_db(id, level, bSilent = true) {
  		try {
  			let data = this.get_ggg_yard_build_template_db_map()[id][level];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in ggg_yard_build_template_db by level [${level}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_ggg_yard_config_map() {
  		return this.getDb("ggg_yard_config");
  	}
  	static get_ggg_yard_config(id, bSilent = true) {
  		try {
  			let data = this.get_ggg_yard_config_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in ggg_yard_config by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_ggg_yard_lottery_template_db_map() {
  		return this.getDb("ggg_yard_lottery_template_db");
  	}
  	static get_ggg_yard_lottery_template_db(id, bSilent = true) {
  		try {
  			let data = this.get_ggg_yard_lottery_template_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in ggg_yard_lottery_template_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_goal_db_map() {
  		return this.getDb("goal_db");
  	}
  	static get_goal_db(id, bSilent = true) {
  		try {
  			let data = this.get_goal_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in goal_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_goal_router_db_map() {
  		return this.getDb("goal_router_db");
  	}
  	static get_goal_router_db(type, bSilent = true) {
  		try {
  			let data = this.get_goal_router_db_map()[type];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in goal_router_db by type [${type}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_guide_db_map() {
  		return this.getDb("guide_db");
  	}
  	static get_guide_db(id, bSilent = true) {
  		try {
  			let data = this.get_guide_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in guide_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_item_add_sub_statis_db_map() {
  		return this.getDb("item_add_sub_statis_db");
  	}
  	static get_item_add_sub_statis_db(index, bSilent = true) {
  		try {
  			let data = this.get_item_add_sub_statis_db_map()[index];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in item_add_sub_statis_db by index [${index}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_item_db_map() {
  		return this.getDb("item_db");
  	}
  	static get_item_db(id, bSilent = true) {
  		try {
  			let data = this.get_item_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in item_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_jump_point_event_db_map() {
  		return this.getDb("jump_point_event_db");
  	}
  	static get_jump_point_event_db(viewName, bSilent = true) {
  		try {
  			let data = this.get_jump_point_event_db_map()[viewName];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in jump_point_event_db by viewName [${viewName}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_light_map_map() {
  		return this.getDb("light_map");
  	}
  	static get_light_map(id, bSilent = true) {
  		try {
  			let data = this.get_light_map_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in light_map by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_manual_custom_point_event_db_map() {
  		return this.getDb("manual_custom_point_event_db");
  	}
  	static get_manual_custom_point_event_db(pointEventId, bSilent = true) {
  		try {
  			let data = this.get_manual_custom_point_event_db_map()[pointEventId];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in manual_custom_point_event_db by pointEventId [${pointEventId}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_model_db_map() {
  		return this.getDb("model_db");
  	}
  	static get_model_db(id, bSilent = true) {
  		try {
  			let data = this.get_model_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in model_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_money_tree_config_map() {
  		return this.getDb("money_tree_config");
  	}
  	static get_money_tree_config(id, bSilent = true) {
  		try {
  			let data = this.get_money_tree_config_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in money_tree_config by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_pay_db_map() {
  		return this.getDb("pay_db");
  	}
  	static get_pay_db(id, bSilent = true) {
  		try {
  			let data = this.get_pay_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in pay_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_quest_db_map() {
  		return this.getDb("quest_db");
  	}
  	static get_quest_db(id, bSilent = true) {
  		try {
  			let data = this.get_quest_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in quest_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_random_tip_db_map() {
  		return this.getDb("random_tip_db");
  	}
  	static get_random_tip_db(word1, bSilent = true) {
  		try {
  			let data = this.get_random_tip_db_map()[word1];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in random_tip_db by word1 [${word1}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_scene_db_map() {
  		return this.getDb("scene_db");
  	}
  	static get_scene_db(id, bSilent = true) {
  		try {
  			let data = this.get_scene_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in scene_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_sound_db_map() {
  		return this.getDb("sound_db");
  	}
  	static get_sound_db(id, bSilent = true) {
  		try {
  			let data = this.get_sound_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in sound_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_spine_db_map() {
  		return this.getDb("spine_db");
  	}
  	static get_spine_db(id, bSilent = true) {
  		try {
  			let data = this.get_spine_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in spine_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_sub_cop_map() {
  		return this.getDb("sub_cop");
  	}
  	static get_sub_cop(subCopKey, bSilent = true) {
  		try {
  			let data = this.get_sub_cop_map()[subCopKey];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in sub_cop by subCopKey [${subCopKey}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_switch_db_map() {
  		return this.getDb("switch_db");
  	}
  	static get_switch_db(id, bSilent = true) {
  		try {
  			let data = this.get_switch_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in switch_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_timeline_db_map() {
  		return this.getDb("timeline_db");
  	}
  	static get_timeline_db(id, bSilent = true) {
  		try {
  			let data = this.get_timeline_db_map()[id];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in timeline_db by id [${id}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_ui_statis_button_db_map() {
  		return this.getDb("ui_statis_button_db");
  	}
  	static get_ui_statis_button_db(viewName, bSilent = true) {
  		try {
  			let data = this.get_ui_statis_button_db_map()[viewName];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in ui_statis_button_db by viewName [${viewName}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	static get_ui_statis_duration_db_map() {
  		return this.getDb("ui_statis_duration_db");
  	}
  	static get_ui_statis_duration_db(viewName, bSilent = true) {
  		try {
  			let data = this.get_ui_statis_duration_db_map()[viewName];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in ui_statis_duration_db by viewName [${viewName}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  	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, bSilent = true) {
  		try {
  			let data = this.get_view_method_call_point_event_db_map()[panelName][index];
  			if (data == null && !bSilent) {
  				console.log(`can't find data in view_method_call_point_event_db by index [${index}]`);
  			}
  			return data;
  		}
  		catch (e) { }
  	}
  }
  db.ADV_DB_ADVNAME = {
  	video_PanelVideoFreeEnergy_energy: "video_PanelVideoFreeEnergy_energy",
  	video_PanelRoleLevelDown_revival: "video_PanelRoleLevelDown_revival",
  	video_PanelPartGotDialog_extral: "video_PanelPartGotDialog_extral",
  	video_PanelGoGoGo_property: "video_PanelGoGoGo_property",
  	video_PanelStartBorn_born: "video_PanelStartBorn_born",
  	video_PanelPreview_property: "video_PanelPreview_property",
  	video_PanelQuestionEvent_question: "video_PanelQuestionEvent_question",
  	video_PanelChoosePosition_start: "video_PanelChoosePosition_start",
  	video_PanelSettlement_double: "video_PanelSettlement_double",
  	video_PanelVideoFreeCopperCoin_free: "video_PanelVideoFreeCopperCoin_free",
  	video_PanelAttendant_friend: "video_PanelAttendant_friend",
  	video_PanelAttendant_train: "video_PanelAttendant_train",
  	video_PanelGoGoGo_lvup_external: "video_PanelGoGoGo_lvup_external",
  	video_PanelGoGoGo_gold_challenge: "video_PanelGoGoGo_gold_challenge",
  	video_PanelGoGoGo_speed_challenge: "video_PanelGoGoGo_speed_challenge",
  	video_PanelSpecialStagePreview1_ad_unlock: "video_PanelSpecialStagePreview1_ad_unlock",
  	video_PanelSpecialStagePreview2_ad_unlock: "video_PanelSpecialStagePreview2_ad_unlock",
  	video_PanelSpecialStageSuccess1_ad_double: "video_PanelSpecialStageSuccess1_ad_double",
  	video_PanelSpecialStageSuccess2_ad_double: "video_PanelSpecialStageSuccess2_ad_double",
  	video_PanelSpecialStageFail2_ad_time: "video_PanelSpecialStageFail2_ad_time",
  	video_PanelPet_ad_upgrade: "video_PanelPet_ad_upgrade",
  	video_PanelYardPreview_ad_unlock: "video_PanelYardPreview_ad_unlock",
  	video_PanelYardBuildingLvup_lvup: "video_PanelYardBuildingLvup_lvup",
  	video_PanelYardEventReward_double: "video_PanelYardEventReward_double",
  	video_PanelYardGold_double: "video_PanelYardGold_double",
  	video_PanelYardLottery_lottery: "video_PanelYardLottery_lottery",
  	video_PanelTrail_trial: "video_PanelTrail_trial",
  	ul_adv: "ul_adv",
  };
  db.ANIMATION_DB_ID = {
  	_116_ui_loop_finger_01_116_ui_loop_finger_01: "116_ui_loop_finger_01_116_ui_loop_finger_01",
  	_130_levp_scene_shuichi_03_water_03_130_levp_scene_shuichi_03_water_03: "130_levp_scene_shuichi_03_water_03_130_levp_scene_shuichi_03_water_03",
  	_130_levp_scene_shuichi_03_water_04_130_levp_scene_shuichi_03_water_04: "130_levp_scene_shuichi_03_water_04_130_levp_scene_shuichi_03_water_04",
  	doorIdle_doorIdle: "doorIdle_doorIdle",
  	doorOpen_doorOpen: "doorOpen_doorOpen",
  	shu03_idle: "shu03_idle",
  	shu04_idle: "shu04_idle",
  	shu05_idle: "shu05_idle",
  	jingbagou_ainm_idle01: "jingbagou_ainm_idle01",
  	jingbagou_ainm_idle02: "jingbagou_ainm_idle02",
  	jingbagou_ainm_move01: "jingbagou_ainm_move01",
  	ma_anim_idle01: "ma_anim_idle01",
  	ma_anim_idle02: "ma_anim_idle02",
  	ma_anim_move01: "ma_anim_move01",
  	mao_ainm_idle01: "mao_ainm_idle01",
  	mao_ainm_idle02: "mao_ainm_idle02",
  	mao_ainm_move01: "mao_ainm_move01",
  	yingwu_anim_idle01: "yingwu_anim_idle01",
  	yingwu_anim_idle02: "yingwu_anim_idle02",
  	yingwu_anim_move01: "yingwu_anim_move01",
  	yingwu_anim02_show01: "yingwu_anim02_show01",
  	yingwu_anim02_stand01: "yingwu_anim02_stand01",
  	ch_anim_idle01: "ch_anim_idle01",
  	ch_anim_lose01: "ch_anim_lose01",
  	ch_anim_move01: "ch_anim_move01",
  	ch_anim_move02: "ch_anim_move02",
  	ch_anim_move03: "ch_anim_move03",
  	ch_anim_shengji01: "ch_anim_shengji01",
  	ch_anim_song: "ch_anim_song",
  	ch_anim_xingli01: "ch_anim_xingli01",
  	ch_anim_xingli02: "ch_anim_xingli02",
  	ch_chugong_chugong: "ch_chugong_chugong",
  	ch_diedao_diedao01: "ch_diedao_diedao01",
  	ch_diedao_diedao02: "ch_diedao_diedao02",
  	ch_maitou_maitou: "ch_maitou_maitou",
  	ch_tuozou_diedao: "ch_tuozou_diedao",
  	ch_tuozou_tuozou: "ch_tuozou_tuozou",
  	ch_xiagui_xiagui01: "ch_xiagui_xiagui01",
  	ch_xiagui_xiagui02: "ch_xiagui_xiagui02",
  	ch_xiagui_xiagui03: "ch_xiagui_xiagui03",
  	ddsr01_anim_idle01: "ddsr01_anim_idle01",
  	ddsr01_anim_lose01: "ddsr01_anim_lose01",
  	ddsr01_anim_move01: "ddsr01_anim_move01",
  	ddsr01_anim_move02: "ddsr01_anim_move02",
  	ddsr01_anim_move03: "ddsr01_anim_move03",
  	ddsr01_anim_shengji01: "ddsr01_anim_shengji01",
  	ddsr01_anim_xingli01: "ddsr01_anim_xingli01",
  	ddsr01_anim_xingli02: "ddsr01_anim_xingli02",
  	ddsr01_diedao_diedao01: "ddsr01_diedao_diedao01",
  	ddsr01_diedao_diedao02: "ddsr01_diedao_diedao02",
  	ddsr04_anim_idle01: "ddsr04_anim_idle01",
  	ddsr04_anim_lose01: "ddsr04_anim_lose01",
  	ddsr04_anim_move01: "ddsr04_anim_move01",
  	ddsr04_anim_move02: "ddsr04_anim_move02",
  	ddsr04_anim_move03: "ddsr04_anim_move03",
  	ddsr04_anim_shengji01: "ddsr04_anim_shengji01",
  	ddsr04_anim_xingli01: "ddsr04_anim_xingli01",
  	ddsr04_anim_xingli02: "ddsr04_anim_xingli02",
  	ddsr04_chugong_chugong: "ddsr04_chugong_chugong",
  	ddsr04_diedao_diedao01: "ddsr04_diedao_diedao01",
  	ddsr04_diedao_diedao02: "ddsr04_diedao_diedao02",
  	ddsr04_maitou_maitou: "ddsr04_maitou_maitou",
  	ddsr04_song_song: "ddsr04_song_song",
  	ddsr04_tuozou_diedao: "ddsr04_tuozou_diedao",
  	ddsr04_tuozou_tuozou: "ddsr04_tuozou_tuozou",
  	ddsr_xiagui_xiagui01: "ddsr_xiagui_xiagui01",
  	ddsr_xiagui_xiagui02: "ddsr_xiagui_xiagui02",
  	ddsr_xiagui_xiagui03: "ddsr_xiagui_xiagui03",
  	fsx_anim_idle01: "fsx_anim_idle01",
  	fsx_anim_lose01: "fsx_anim_lose01",
  	fsx_anim_move01: "fsx_anim_move01",
  	fsx_anim_move02: "fsx_anim_move02",
  	fsx_anim_move03: "fsx_anim_move03",
  	fsx_anim_shengji01: "fsx_anim_shengji01",
  	fsx_anim_xingli01: "fsx_anim_xingli01",
  	fsx_anim_xingli02: "fsx_anim_xingli02",
  	fsx_chugong_chugong: "fsx_chugong_chugong",
  	fsx_diedao_diedao01: "fsx_diedao_diedao01",
  	fsx_diedao_diedao02: "fsx_diedao_diedao02",
  	fsx_maitou_maitou: "fsx_maitou_maitou",
  	fsx_song_song: "fsx_song_song",
  	fsx_tuozou_diedao: "fsx_tuozou_diedao",
  	fsx_tuozou_tuozou: "fsx_tuozou_tuozou",
  	fsx_xiagui_xiagui01: "fsx_xiagui_xiagui01",
  	fsx_xiagui_xiagui02: "fsx_xiagui_xiagui02",
  	fsx_xiagui_xiagui03: "fsx_xiagui_xiagui03",
  	ggx01_anim_idle01: "ggx01_anim_idle01",
  	ggx01_anim_lose: "ggx01_anim_lose",
  	ggx01_anim_move01: "ggx01_anim_move01",
  	ggx01_anim_move02: "ggx01_anim_move02",
  	ggx01_anim_move03: "ggx01_anim_move03",
  	ggx01_anim_shengji: "ggx01_anim_shengji",
  	ggx01_anim_xingli01: "ggx01_anim_xingli01",
  	ggx01_anim_xingli02: "ggx01_anim_xingli02",
  	ggx01_diedao_diedao01: "ggx01_diedao_diedao01",
  	ggx01_diedao_diedao02: "ggx01_diedao_diedao02",
  	ggx03_anim_idle01: "ggx03_anim_idle01",
  	ggx03_anim_move01: "ggx03_anim_move01",
  	ggx03_anim_move03: "ggx03_anim_move03",
  	ggx03_anim_shengji: "ggx03_anim_shengji",
  	ggx03_anim_xingli01: "ggx03_anim_xingli01",
  	ggx03_anim_xingli02: "ggx03_anim_xingli02",
  	ggx03_anim_xingli03: "ggx03_anim_xingli03",
  	ggx03_anim_xingli04: "ggx03_anim_xingli04",
  	ggx03_diedao_diedao01: "ggx03_diedao_diedao01",
  	ggx03_diedao_diedao02: "ggx03_diedao_diedao02",
  	ggx05_anim_idle01: "ggx05_anim_idle01",
  	ggx05_anim_move01: "ggx05_anim_move01",
  	ggx05_anim_move03: "ggx05_anim_move03",
  	ggx05_anim_qilai: "ggx05_anim_qilai",
  	ggx05_anim_shengji: "ggx05_anim_shengji",
  	ggx05_anim_xingli01: "ggx05_anim_xingli01",
  	ggx05_anim_xingli02: "ggx05_anim_xingli02",
  	ggx05_anim_xingli03: "ggx05_anim_xingli03",
  	ggx05_diedao_diedao01: "ggx05_diedao_diedao01",
  	ggx05_diedao_diedao02: "ggx05_diedao_diedao02",
  	ggx_chugong_chugong: "ggx_chugong_chugong",
  	ggx_maitou_maitou: "ggx_maitou_maitou",
  	ggx_song_song: "ggx_song_song",
  	ggx_tuozou_diedao: "ggx_tuozou_diedao",
  	ggx_tuozou_tuozou: "ggx_tuozou_tuozou",
  	ggx_xiagui_xiagui01: "ggx_xiagui_xiagui01",
  	ggx_xiagui_xiagui02: "ggx_xiagui_xiagui02",
  	ggx_xiagui_xiagui03: "ggx_xiagui_xiagui03",
  	gyx01_anim_idle01: "gyx01_anim_idle01",
  	gyx01_anim_lose: "gyx01_anim_lose",
  	gyx01_anim_move01: "gyx01_anim_move01",
  	gyx01_anim_move02: "gyx01_anim_move02",
  	gyx01_anim_move03: "gyx01_anim_move03",
  	gyx01_anim_shengji: "gyx01_anim_shengji",
  	gyx01_anim_xingli01: "gyx01_anim_xingli01",
  	gyx01_anim_xingli02: "gyx01_anim_xingli02",
  	gyx01_diedao_diedao: "gyx01_diedao_diedao",
  	gyx01_diedao_diedao01: "gyx01_diedao_diedao01",
  	gyx01_diedao_diedao02: "gyx01_diedao_diedao02",
  	gyx03_anim_idle01: "gyx03_anim_idle01",
  	gyx03_anim_move01: "gyx03_anim_move01",
  	gyx03_anim_move03: "gyx03_anim_move03",
  	gyx03_anim_shengji: "gyx03_anim_shengji",
  	gyx03_anim_xingli01: "gyx03_anim_xingli01",
  	gyx03_anim_xingli02: "gyx03_anim_xingli02",
  	gyx03_diedao_diedao: "gyx03_diedao_diedao",
  	gyx03_diedao_diedao01: "gyx03_diedao_diedao01",
  	gyx03_diedao_diedao02: "gyx03_diedao_diedao02",
  	gyx05_anim_idle01: "gyx05_anim_idle01",
  	gyx05_anim_move01: "gyx05_anim_move01",
  	gyx05_anim_move03: "gyx05_anim_move03",
  	gyx05_anim_shengji: "gyx05_anim_shengji",
  	gyx05_anim_xingli01: "gyx05_anim_xingli01",
  	gyx05_anim_xingli02: "gyx05_anim_xingli02",
  	gyx05_diedao_diedao: "gyx05_diedao_diedao",
  	gyx05_diedao_diedao01: "gyx05_diedao_diedao01",
  	gyx05_diedao_diedao02: "gyx05_diedao_diedao02",
  	gyx_chugong_chugong: "gyx_chugong_chugong",
  	gyx_maitou_maitou: "gyx_maitou_maitou",
  	gyx_song_song: "gyx_song_song",
  	gyx_tuozou_diedao: "gyx_tuozou_diedao",
  	gyx_tuozou_tuozou: "gyx_tuozou_tuozou",
  	gyx_xiagui_xiagui01: "gyx_xiagui_xiagui01",
  	gyx_xiagui_xiagui02: "gyx_xiagui_xiagui02",
  	gyx_xiagui_xiagui03: "gyx_xiagui_xiagui03",
  	npc_01_idle01: "npc_01_idle01",
  	npc_01_kuqi: "npc_01_kuqi",
  	npc_01_lose01: "npc_01_lose01",
  	npc_01_move01: "npc_01_move01",
  	npc_01_xingli: "npc_01_xingli",
  	npc_01_anim_idle01: "npc_01_anim_idle01",
  	npc_01_anim_kuqi: "npc_01_anim_kuqi",
  	npc_01_anim_lose01: "npc_01_anim_lose01",
  	npc_01_anim_move01: "npc_01_anim_move01",
  	npc_01_anim_xingli: "npc_01_anim_xingli",
  	npc_01_qqhua_qqh: "npc_01_qqhua_qqh",
  	npc_01_qugan_qugan: "npc_01_qugan_qugan",
  	npc_01_thth_idle01_npc_01_thth_idle01: "npc_01_thth_idle01_npc_01_thth_idle01",
  	npc_01_thth_idle01_thth_idle01: "npc_01_thth_idle01_thth_idle01",
  	npc_01_tuozou_npc01_tuozou: "npc_01_tuozou_npc01_tuozou",
  	npc_01_tuozou_npc_01_tuozou: "npc_01_tuozou_npc_01_tuozou",
  	npc_01_tuozou_tuozou: "npc_01_tuozou_tuozou",
  	npc_01_xiagui_xiagui01: "npc_01_xiagui_xiagui01",
  	npc_01_xiagui_xiagui02: "npc_01_xiagui_xiagui02",
  	npc_01_xiagui_xiagui03: "npc_01_xiagui_xiagui03",
  	npc02_ainm_baibai: "npc02_ainm_baibai",
  	npc02_ainm_enci: "npc02_ainm_enci",
  	npc02_ainm_idle01: "npc02_ainm_idle01",
  	npc02_ainm_idle02: "npc02_ainm_idle02",
  	npc02_ainm_qifen: "npc02_ainm_qifen",
  	npc02_gongzhubao_gongzhubao: "npc02_gongzhubao_gongzhubao",
  	npc02_move_move: "npc02_move_move",
  	npc02_run_run: "npc02_run_run",
  	npc_02_xingli_npc_02_xingli: "npc_02_xingli_npc_02_xingli",
  	npc_02_xingli_xingli: "npc_02_xingli_xingli",
  	npc03_ainm_npc03_gaoxing: "npc03_ainm_npc03_gaoxing",
  	npc03_ainm_npc03_idle: "npc03_ainm_npc03_idle",
  	npc03_ainm_npc03_shengqi: "npc03_ainm_npc03_shengqi",
  	npc_03_anim_diedao: "npc_03_anim_diedao",
  	npc_03_anim_gaoxing: "npc_03_anim_gaoxing",
  	npc_03_anim_idle01: "npc_03_anim_idle01",
  	npc_03_anim_move01: "npc_03_anim_move01",
  	npc_03_anim_qqhua: "npc_03_anim_qqhua",
  	npc_03_anim_shengqi: "npc_03_anim_shengqi",
  	npc_03_anim_talk: "npc_03_anim_talk",
  	npc_03_anim_xingli01: "npc_03_anim_xingli01",
  	npc_03_anim_xingli02: "npc_03_anim_xingli02",
  	npc_03_idle02_idle02: "npc_03_idle02_idle02",
  	npc_03_qugan_qugan: "npc_03_qugan_qugan",
  	npc_03_tuozou_tuozou: "npc_03_tuozou_tuozou",
  	npc_03_xiagui_xiagui01: "npc_03_xiagui_xiagui01",
  	npc_03_xiagui_xiagui02: "npc_03_xiagui_xiagui02",
  	npc_03_xiagui_xiagui03: "npc_03_xiagui_xiagui03",
  	npc_04_anim_diedao: "npc_04_anim_diedao",
  	npc_04_anim_gaoxing: "npc_04_anim_gaoxing",
  	npc_04_anim_idle01: "npc_04_anim_idle01",
  	npc_04_anim_kuqi: "npc_04_anim_kuqi",
  	npc_04_anim_lose01: "npc_04_anim_lose01",
  	npc_04_anim_move01: "npc_04_anim_move01",
  	npc_04_anim_shengqi: "npc_04_anim_shengqi",
  	npc_04_anim_talk: "npc_04_anim_talk",
  	npc_04_anim_xingli01: "npc_04_anim_xingli01",
  	npc_04_anim_xingli02: "npc_04_anim_xingli02",
  	npc_04_anim_xingli03: "npc_04_anim_xingli03",
  	npc_04_anim_xingli04: "npc_04_anim_xingli04",
  	npc_04_chanfu_chanfu: "npc_04_chanfu_chanfu",
  	npc_04_tuozou_tuozou: "npc_04_tuozou_tuozou",
  	npc_04_xiagui_xiagui01: "npc_04_xiagui_xiagui01",
  	npc_04_xiagui_xiagui02: "npc_04_xiagui_xiagui02",
  	npc_04_xiagui_xiagui03: "npc_04_xiagui_xiagui03",
  	npc_05_anim_diedao: "npc_05_anim_diedao",
  	npc_05_anim_gaoxing: "npc_05_anim_gaoxing",
  	npc_05_anim_idle01: "npc_05_anim_idle01",
  	npc_05_anim_move01: "npc_05_anim_move01",
  	npc_05_anim_shengqi: "npc_05_anim_shengqi",
  	npc_05_anim_talk: "npc_05_anim_talk",
  	npc_05_anim_xingli01: "npc_05_anim_xingli01",
  	npc_05_anim_xingli02: "npc_05_anim_xingli02",
  	npc_05_anim_xingli03: "npc_05_anim_xingli03",
  	npc_05_anim_xingli04: "npc_05_anim_xingli04",
  	npc_05_m_idle_npc_05_m_idle: "npc_05_m_idle_npc_05_m_idle",
  	npc_05_m_move01_npc_05_m_move01: "npc_05_m_move01_npc_05_m_move01",
  	npc_06_anim_gaoxing: "npc_06_anim_gaoxing",
  	npc_06_anim_idle01: "npc_06_anim_idle01",
  	npc_06_anim_move01: "npc_06_anim_move01",
  	npc_06_anim_shengqi: "npc_06_anim_shengqi",
  	npc_06_anim_talk: "npc_06_anim_talk",
  	npc_06_anim_xingli01: "npc_06_anim_xingli01",
  	npc_06_anim_xingli02: "npc_06_anim_xingli02",
  	npc_06_anim_zhiliao: "npc_06_anim_zhiliao",
  	npc_06_xiagui_xiagui01: "npc_06_xiagui_xiagui01",
  	npc_06_xiagui_xiagui02: "npc_06_xiagui_xiagui02",
  	npc_06_xiagui_xiagui03: "npc_06_xiagui_xiagui03",
  	npc_07_anim_idle01: "npc_07_anim_idle01",
  	npc_07_anim_move01: "npc_07_anim_move01",
  	player01_idle01: "player01_idle01",
  	player01_lose01: "player01_lose01",
  	player01_move01: "player01_move01",
  	player01_move02: "player01_move02",
  	player01_move03: "player01_move03",
  	player01_shengji01: "player01_shengji01",
  	player01_win01: "player01_win01",
  	player01_1_anim_idle01: "player01_1_anim_idle01",
  	player01_1_anim_move01: "player01_1_anim_move01",
  	player01_anim_idle01: "player01_anim_idle01",
  	player01_anim_lose01: "player01_anim_lose01",
  	player01_anim_move01: "player01_anim_move01",
  	player01_anim_move02: "player01_anim_move02",
  	player01_anim_move03: "player01_anim_move03",
  	player01_anim_shengji01: "player01_anim_shengji01",
  	player01_anim_win01: "player01_anim_win01",
  	player01_chugong_chugong: "player01_chugong_chugong",
  	player01_chugong_player01_chugong: "player01_chugong_player01_chugong",
  	player01_liufang_liufang: "player01_liufang_liufang",
  	player01_liufang_player01_liufang: "player01_liufang_player01_liufang",
  	player01_maitou_maitou: "player01_maitou_maitou",
  	player01_tuozou_diedao: "player01_tuozou_diedao",
  	player01_tuozou_player01_tuozou: "player01_tuozou_player01_tuozou",
  	player01_tuozou_tuozou: "player01_tuozou_tuozou",
  	pose_Take_001: "pose_Take 001",
  	player01_4_anim_idle01: "player01_4_anim_idle01",
  	player01_4_anim_lose01: "player01_4_anim_lose01",
  	player01_4_anim_move01: "player01_4_anim_move01",
  	player01_4_anim_move02: "player01_4_anim_move02",
  	player01_4_anim_move03: "player01_4_anim_move03",
  	player01_4_anim_shengji01: "player01_4_anim_shengji01",
  	player01_4_anim_win01: "player01_4_anim_win01",
  	player01_4_chang_chang: "player01_4_chang_chang",
  	player01_4_chang_player01_4_chang: "player01_4_chang_player01_4_chang",
  	player01_4_chugong_chugong: "player01_4_chugong_chugong",
  	player01_4_diedao_diedao01: "player01_4_diedao_diedao01",
  	player01_4_diedao_diedao02: "player01_4_diedao_diedao02",
  	player01_4_gongzhubao_gongzhubao: "player01_4_gongzhubao_gongzhubao",
  	player01_4_huili_huili: "player01_4_huili_huili",
  	player01_4_liufang_liufang: "player01_4_liufang_liufang",
  	player01_4_maitou_maitou: "player01_4_maitou_maitou",
  	player01_4_song_player01_4_song: "player01_4_song_player01_4_song",
  	player01_4_song_song: "player01_4_song_song",
  	player01_4_tl_xingli_xingli01: "player01_4_tl_xingli_xingli01",
  	player01_4_tl_xingli_xingli02: "player01_4_tl_xingli_xingli02",
  	player01_4_tl_xingli_xingli03: "player01_4_tl_xingli_xingli03",
  	player01_4_tl_xingli_xingli04: "player01_4_tl_xingli_xingli04",
  	player01_4_tuozou_diedao: "player01_4_tuozou_diedao",
  	player01_4_tuozou_tuozou: "player01_4_tuozou_tuozou",
  	player01_4_xiagui_xiagui01: "player01_4_xiagui_xiagui01",
  	player01_4_xiagui_xiagui02: "player01_4_xiagui_xiagui02",
  	player01_4_xiagui_xiagui03: "player01_4_xiagui_xiagui03",
  	player01_4_xingli_xingli_gj: "player01_4_xingli_xingli_gj",
  	player01_4_xingli_xingli_gj01: "player01_4_xingli_xingli_gj01",
  	player01_4_xingli_xingli_pj_ds: "player01_4_xingli_xingli_pj_ds",
  	player01_4_xingli_xingli_pj_ds01: "player01_4_xingli_xingli_pj_ds01",
  	player01_4_xingli_xingli_pj_wj: "player01_4_xingli_xingli_pj_wj",
  	player01_4_xingli_xingli_pj_wj01: "player01_4_xingli_xingli_pj_wj01",
  	player03_idle01: "player03_idle01",
  	player03_lose01: "player03_lose01",
  	player03_move01: "player03_move01",
  	player03_shengji01: "player03_shengji01",
  	player03_win01: "player03_win01",
  	player03_anim_idle01: "player03_anim_idle01",
  	player03_anim_lose01: "player03_anim_lose01",
  	player03_anim_move01: "player03_anim_move01",
  	player03_anim_move02: "player03_anim_move02",
  	player03_anim_move03: "player03_anim_move03",
  	player03_anim_shengji01: "player03_anim_shengji01",
  	player03_anim_win01: "player03_anim_win01",
  	player04_idle01: "player04_idle01",
  	player04_lose01: "player04_lose01",
  	player04_move01: "player04_move01",
  	player04_move02: "player04_move02",
  	player04_move03: "player04_move03",
  	player04_shengji01: "player04_shengji01",
  	player04_win01: "player04_win01",
  	player04_anim_idle01: "player04_anim_idle01",
  	player04_anim_lose01: "player04_anim_lose01",
  	player04_anim_move01: "player04_anim_move01",
  	player04_anim_move02: "player04_anim_move02",
  	player04_anim_move03: "player04_anim_move03",
  	player04_anim_shengji01: "player04_anim_shengji01",
  	player04_anim_win01: "player04_anim_win01",
  	player04_chang_chang: "player04_chang_chang",
  	player04_chang_player04_chang: "player04_chang_player04_chang",
  	player04_chugong_chugong: "player04_chugong_chugong",
  	player04_chugong_player04_chugong: "player04_chugong_player04_chugong",
  	player04_diedao_diedao01: "player04_diedao_diedao01",
  	player04_diedao_diedao02: "player04_diedao_diedao02",
  	player04_gongzhubao_gongzhubao: "player04_gongzhubao_gongzhubao",
  	player04_huili_huili: "player04_huili_huili",
  	player04_liufang_liufang: "player04_liufang_liufang",
  	player04_liufang_player04_liufang: "player04_liufang_player04_liufang",
  	player04_maitou_maitou: "player04_maitou_maitou",
  	player04_song_player04_song: "player04_song_player04_song",
  	player04_song_song: "player04_song_song",
  	player04_tuozou_diedao: "player04_tuozou_diedao",
  	player04_tuozou_player04_tuozou: "player04_tuozou_player04_tuozou",
  	player04_tuozou_tuozou: "player04_tuozou_tuozou",
  	player04_xiagui_xiagui01: "player04_xiagui_xiagui01",
  	player04_xiagui_xiagui02: "player04_xiagui_xiagui02",
  	player04_xiagui_xiagui03: "player04_xiagui_xiagui03",
  	player04_xingli_xingli01: "player04_xingli_xingli01",
  	player04_xingli_xingli02: "player04_xingli_xingli02",
  	player04_xingli_xingli_gj: "player04_xingli_xingli_gj",
  	player04_xingli_xingli_gj04: "player04_xingli_xingli_gj04",
  	player04_xingli_xingli_pj_ds: "player04_xingli_xingli_pj_ds",
  	player04_xingli_xingli_pj_ds04: "player04_xingli_xingli_pj_ds04",
  	player04_xingli_xingli_pj_wj: "player04_xingli_xingli_pj_wj",
  	player04_xingli_xingli_pj_wj04: "player04_xingli_xingli_pj_wj04",
  	player05_idle01: "player05_idle01",
  	player05_lose01: "player05_lose01",
  	player05_move01: "player05_move01",
  	player05_move02: "player05_move02",
  	player05_move03: "player05_move03",
  	player05_shengji01: "player05_shengji01",
  	player05_win01: "player05_win01",
  	player05_anim_idle01: "player05_anim_idle01",
  	player05_anim_lose01: "player05_anim_lose01",
  	player05_anim_move01: "player05_anim_move01",
  	player05_anim_move02: "player05_anim_move02",
  	player05_anim_move03: "player05_anim_move03",
  	player05_anim_shengji01: "player05_anim_shengji01",
  	player05_anim_win01: "player05_anim_win01",
  	player05_chang_chang: "player05_chang_chang",
  	player05_chang_player05_chang: "player05_chang_player05_chang",
  	player05_dance_dance: "player05_dance_dance",
  	player05_dance_player05_dance: "player05_dance_player05_dance",
  	player05_diedao_diedao01: "player05_diedao_diedao01",
  	player05_diedao_diedao02: "player05_diedao_diedao02",
  	player05_gongzhubao_gongzhubao: "player05_gongzhubao_gongzhubao",
  	player05_huili_huili: "player05_huili_huili",
  	player05_maitou_maitou: "player05_maitou_maitou",
  	player05_song_player05_song: "player05_song_player05_song",
  	player05_song_song: "player05_song_song",
  	player05_xiagui_xiagui01: "player05_xiagui_xiagui01",
  	player05_xiagui_xiagui02: "player05_xiagui_xiagui02",
  	player05_xiagui_xiagui03: "player05_xiagui_xiagui03",
  	player05_xingli_xingli_gj: "player05_xingli_xingli_gj",
  	player05_xingli_xingli_pj_ds: "player05_xingli_xingli_pj_ds",
  	player05_xingli_xingli_pj_wj: "player05_xingli_xingli_pj_wj",
  	role05_gongzhubao_gongzhubao: "role05_gongzhubao_gongzhubao",
  	role05_huili_huili: "role05_huili_huili",
  	role05_maitou_maitou: "role05_maitou_maitou",
  	role05_xingli_xingli_gj05: "role05_xingli_xingli_gj05",
  	role05_xingli_xingli_pj_ds05: "role05_xingli_xingli_pj_ds05",
  	role05_xingli_xingli_pj_wj05: "role05_xingli_xingli_pj_wj05",
  	player06_anim_idle01: "player06_anim_idle01",
  	player06_anim_lose01: "player06_anim_lose01",
  	player06_anim_move01: "player06_anim_move01",
  	player06_anim_shengji01: "player06_anim_shengji01",
  	player06_anim_win01: "player06_anim_win01",
  	player06_anim_xingli: "player06_anim_xingli",
  	player06_anim_xingli01: "player06_anim_xingli01",
  	player06_shengqi_player06_shengqi: "player06_shengqi_player06_shengqi",
  	player06_shengqi_shengqi: "player06_shengqi_shengqi",
  	player06_thth_anim_gaoxing: "player06_thth_anim_gaoxing",
  	player06_thth_anim_idle01: "player06_thth_anim_idle01",
  	player06_thth_anim_shengqi: "player06_thth_anim_shengqi",
  	player06_thth_move_move01: "player06_thth_move_move01",
  	gaitou_anim_gaitou_idle01: "gaitou_anim_gaitou_idle01",
  	gaitou_anim_gaitou_lose01: "gaitou_anim_gaitou_lose01",
  	gaitou_anim_gaitou_move01: "gaitou_anim_gaitou_move01",
  	gaitou_anim_gaitou_move02: "gaitou_anim_gaitou_move02",
  	gaitou_anim_gaitou_move03: "gaitou_anim_gaitou_move03",
  	gaitou_anim_gaitou_shengji01: "gaitou_anim_gaitou_shengji01",
  	gaitou_anim_gaitou_song: "gaitou_anim_gaitou_song",
  	gaitou_anim_gaitou_xingli01: "gaitou_anim_gaitou_xingli01",
  	gaitou_anim_gaitou_xingli02: "gaitou_anim_gaitou_xingli02",
  	gaitou_chugong_gaitou_chugong: "gaitou_chugong_gaitou_chugong",
  	gaitou_diedao_gaitou_diedao01: "gaitou_diedao_gaitou_diedao01",
  	gaitou_diedao_gaitou_diedao02: "gaitou_diedao_gaitou_diedao02",
  	gaitou_maitou_gaitou_maitou: "gaitou_maitou_gaitou_maitou",
  	gaitou_tuozou_gaitou_tuozou: "gaitou_tuozou_gaitou_tuozou",
  	gaitou_xiagui_xiagui01: "gaitou_xiagui_xiagui01",
  	gaitou_xiagui_xiagui02: "gaitou_xiagui_xiagui02",
  	gaitou_xiagui_xiagui03: "gaitou_xiagui_xiagui03",
  	wangfei_anim_idle01: "wangfei_anim_idle01",
  	wangfei_anim_lose01: "wangfei_anim_lose01",
  	wangfei_anim_move01: "wangfei_anim_move01",
  	wangfei_anim_move02: "wangfei_anim_move02",
  	wangfei_anim_move03: "wangfei_anim_move03",
  	wangfei_anim_shengji01: "wangfei_anim_shengji01",
  	wangfei_anim_song: "wangfei_anim_song",
  	wangfei_anim_xingli01: "wangfei_anim_xingli01",
  	wangfei_anim_xingli02: "wangfei_anim_xingli02",
  	wangfei_chugong_chugong: "wangfei_chugong_chugong",
  	wangfei_diedao_diedao01: "wangfei_diedao_diedao01",
  	wangfei_diedao_diedao02: "wangfei_diedao_diedao02",
  	wangfei_maitou_maitou: "wangfei_maitou_maitou",
  	wangfei_tuozou_diedao: "wangfei_tuozou_diedao",
  	wangfei_tuozou_tuozou: "wangfei_tuozou_tuozou",
  	wangfei_xiagui_xiagui01: "wangfei_xiagui_xiagui01",
  	wangfei_xiagui_xiagui02: "wangfei_xiagui_xiagui02",
  	wangfei_xiagui_xiagui03: "wangfei_xiagui_xiagui03",
  	xss01_ainm_diedao: "xss01_ainm_diedao",
  	xss01_ainm_idle01: "xss01_ainm_idle01",
  	xss01_ainm_lose01: "xss01_ainm_lose01",
  	xss01_ainm_maitou: "xss01_ainm_maitou",
  	xss01_ainm_move01: "xss01_ainm_move01",
  	xss01_ainm_move02: "xss01_ainm_move02",
  	xss01_ainm_move03: "xss01_ainm_move03",
  	xss01_ainm_shengji01: "xss01_ainm_shengji01",
  	xss01_ainm_song: "xss01_ainm_song",
  	xss01_ainm_songli: "xss01_ainm_songli",
  	xss01_ainm_tuozou: "xss01_ainm_tuozou",
  	xss01_ainm_xingli01: "xss01_ainm_xingli01",
  	xss01_ainm_xingli02: "xss01_ainm_xingli02",
  	xss01_chugong_chugong: "xss01_chugong_chugong",
  	xss01_diedao_diedao01: "xss01_diedao_diedao01",
  	xss01_diedao_diedao02: "xss01_diedao_diedao02",
  	xss03_ainm_diedao: "xss03_ainm_diedao",
  	xss03_ainm_idle01: "xss03_ainm_idle01",
  	xss03_ainm_lose01: "xss03_ainm_lose01",
  	xss03_ainm_maitou: "xss03_ainm_maitou",
  	xss03_ainm_move01: "xss03_ainm_move01",
  	xss03_ainm_move02: "xss03_ainm_move02",
  	xss03_ainm_move03: "xss03_ainm_move03",
  	xss03_ainm_shengji01: "xss03_ainm_shengji01",
  	xss03_ainm_song: "xss03_ainm_song",
  	xss03_ainm_songli: "xss03_ainm_songli",
  	xss03_ainm_tuozou: "xss03_ainm_tuozou",
  	xss03_ainm_xingli01: "xss03_ainm_xingli01",
  	xss03_ainm_xingli02: "xss03_ainm_xingli02",
  	xss03_chugong_chugong: "xss03_chugong_chugong",
  	xss03_diedao_diedao01: "xss03_diedao_diedao01",
  	xss03_diedao_diedao02: "xss03_diedao_diedao02",
  	xsx_xiagui_xiagui01: "xsx_xiagui_xiagui01",
  	xsx_xiagui_xiagui02: "xsx_xiagui_xiagui02",
  	xsx_xiagui_xiagui03: "xsx_xiagui_xiagui03",
  	yszg_anim_idle01: "yszg_anim_idle01",
  	yszg_anim_lose01: "yszg_anim_lose01",
  	yszg_anim_maitou: "yszg_anim_maitou",
  	yszg_anim_move01: "yszg_anim_move01",
  	yszg_anim_move02: "yszg_anim_move02",
  	yszg_anim_move03: "yszg_anim_move03",
  	yszg_anim_shengji01: "yszg_anim_shengji01",
  	yszg_anim_song: "yszg_anim_song",
  	yszg_anim_songli: "yszg_anim_songli",
  	yszg_anim_tuozou: "yszg_anim_tuozou",
  	yszg_anim_xingli01: "yszg_anim_xingli01",
  	yszg_anim_xingli02: "yszg_anim_xingli02",
  	yszg_chugong_chugong: "yszg_chugong_chugong",
  	yszg_diedao_diedao01: "yszg_diedao_diedao01",
  	yszg_diedao_diedao02: "yszg_diedao_diedao02",
  	yszg_xiagui_xiagui01: "yszg_xiagui_xiagui01",
  	yszg_xiagui_xiagui02: "yszg_xiagui_xiagui02",
  	yszg_xiagui_xiagui03: "yszg_xiagui_xiagui03",
  	ywx03_anim_idle01: "ywx03_anim_idle01",
  	ywx03_anim_lose01: "ywx03_anim_lose01",
  	ywx03_anim_move01: "ywx03_anim_move01",
  	ywx03_anim_move02: "ywx03_anim_move02",
  	ywx03_anim_move03: "ywx03_anim_move03",
  	ywx03_anim_shengji01: "ywx03_anim_shengji01",
  	ywx03_anim_song: "ywx03_anim_song",
  	ywx03_anim_xingli01: "ywx03_anim_xingli01",
  	ywx03_anim_xingli02: "ywx03_anim_xingli02",
  	ywx03_chugong_chugong: "ywx03_chugong_chugong",
  	ywx03_diedao_diedao01: "ywx03_diedao_diedao01",
  	ywx03_diedao_diedao02: "ywx03_diedao_diedao02",
  	ywx03_maitou_maitou: "ywx03_maitou_maitou",
  	ywx03_tuozou_diedao: "ywx03_tuozou_diedao",
  	ywx03_tuozou_tuozou: "ywx03_tuozou_tuozou",
  	ywx03_xiagui_xiagui01: "ywx03_xiagui_xiagui01",
  	ywx03_xiagui_xiagui02: "ywx03_xiagui_xiagui02",
  	ywx03_xiagui_xiagui03: "ywx03_xiagui_xiagui03",
  	ywx05_anim_idle01: "ywx05_anim_idle01",
  	ywx05_anim_move01: "ywx05_anim_move01",
  	ywx07_anim_idle01: "ywx07_anim_idle01",
  	ywx07_anim_lose01: "ywx07_anim_lose01",
  	ywx07_anim_move01: "ywx07_anim_move01",
  	ywx07_anim_move02: "ywx07_anim_move02",
  	ywx07_anim_move03: "ywx07_anim_move03",
  	ywx07_anim_shengji01: "ywx07_anim_shengji01",
  	ywx07_anim_song: "ywx07_anim_song",
  	ywx07_anim_xingli01: "ywx07_anim_xingli01",
  	ywx07_anim_xingli02: "ywx07_anim_xingli02",
  	ywx07_chugong_chugong: "ywx07_chugong_chugong",
  	ywx07_diedao_diedao01: "ywx07_diedao_diedao01",
  	ywx07_diedao_diedao02: "ywx07_diedao_diedao02",
  	ywx07_maitou_maitou: "ywx07_maitou_maitou",
  	ywx07_tuozou_diedao: "ywx07_tuozou_diedao",
  	ywx07_tuozou_tuozou: "ywx07_tuozou_tuozou",
  	ywx07_xiagui_xiagui01: "ywx07_xiagui_xiagui01",
  	ywx07_xiagui_xiagui02: "ywx07_xiagui_xiagui02",
  	ywx07_xiagui_xiagui03: "ywx07_xiagui_xiagui03",
  	zgmm_anim_diedao: "zgmm_anim_diedao",
  	zgmm_anim_idle01: "zgmm_anim_idle01",
  	zgmm_anim_lose01: "zgmm_anim_lose01",
  	zgmm_anim_maitou: "zgmm_anim_maitou",
  	zgmm_anim_move01: "zgmm_anim_move01",
  	zgmm_anim_move02: "zgmm_anim_move02",
  	zgmm_anim_move03: "zgmm_anim_move03",
  	zgmm_anim_shengji01: "zgmm_anim_shengji01",
  	zgmm_anim_song: "zgmm_anim_song",
  	zgmm_anim_songli: "zgmm_anim_songli",
  	zgmm_anim_tuozou: "zgmm_anim_tuozou",
  	zgmm_anim_xingli01: "zgmm_anim_xingli01",
  	zgmm_anim_xingli02: "zgmm_anim_xingli02",
  	zgmm_chugong_chugong: "zgmm_chugong_chugong",
  	zgmm_diedao_diedao01: "zgmm_diedao_diedao01",
  	zgmm_diedao_diedao02: "zgmm_diedao_diedao02",
  	zgmm_xiagui_xiagui01: "zgmm_xiagui_xiagui01",
  	zgmm_xiagui_xiagui02: "zgmm_xiagui_xiagui02",
  	zgmm_xiagui_xiagui03: "zgmm_xiagui_xiagui03",
  	ch_chuhang_timeline_ch_idle01: "ch_chuhang_timeline_ch_idle01",
  	ch_chuhang_timeline_ch_look: "ch_chuhang_timeline_ch_look",
  	hai_hai: "hai_hai",
  	npc02_chuiltz_timeline_cltz_hs_idle: "npc02_chuiltz_timeline_cltz_hs_idle",
  	player06_chuiltz_timeline_cltz_th_idle01: "player06_chuiltz_timeline_cltz_th_idle01",
  	player06_chuiltz_timeline_clzt_th_huili: "player06_chuiltz_timeline_clzt_th_huili",
  	EmptyAnimation_EmptyAnimation: "EmptyAnimation_EmptyAnimation",
  	npc02_gongdou01_2_timeline_fuqi: "npc02_gongdou01_2_timeline_fuqi",
  	npc02_gongdou01_timeline_fangsi: "npc02_gongdou01_timeline_fangsi",
  	npc02_gongdou01_timeline_talk: "npc02_gongdou01_timeline_talk",
  	npc_01_gongdou01_fu: "npc_01_gongdou01_fu",
  	npc_01_gongdou01_qqh: "npc_01_gongdou01_qqh",
  	npc_01_gongdou01_xiagui: "npc_01_gongdou01_xiagui",
  	npc_04_gongdou01_2_tui: "npc_04_gongdou01_2_tui",
  	player04_gongdou01_2_timeline_diedao001: "player04_gongdou01_2_timeline_diedao001",
  	player04_gongdou01_2_timeline_diedao002: "player04_gongdou01_2_timeline_diedao002",
  	player04_gongdou01_2_timeline_ku: "player04_gongdou01_2_timeline_ku",
  	player04_gongdou01_2_timeline_qilai: "player04_gongdou01_2_timeline_qilai",
  	player04_gongdou01_timeline_chaofeng: "player04_gongdou01_timeline_chaofeng",
  	player04_gongdou01_timeline_heng: "player04_gongdou01_timeline_heng",
  	player04_gongdou01_timeline_look: "player04_gongdou01_timeline_look",
  	player04_taihou_timeline_th_pf_idle01: "player04_taihou_timeline_th_pf_idle01",
  	player04_taihou_timeline_th_xingli01: "player04_taihou_timeline_th_xingli01",
  	player05_taihou_timeline_th_xingli_hh: "player05_taihou_timeline_th_xingli_hh",
  	player06_taihou_timeline_th_huili: "player06_taihou_timeline_th_huili",
  	player06_taihou_timeline_th_idle01: "player06_taihou_timeline_th_idle01",
  	npc_01_thsc_timeline_sc_idle01: "npc_01_thsc_timeline_sc_idle01",
  	npc_01_thsc_timeline_sc_move01: "npc_01_thsc_timeline_sc_move01",
  	npc_01_thsc_timeline_sc_move02: "npc_01_thsc_timeline_sc_move02",
  	player05_yangwuzd_timeline_th_chanfu_hh: "player05_yangwuzd_timeline_th_chanfu_hh",
  	ywx07_yangwuzd_timeline_paizhao: "ywx07_yangwuzd_timeline_paizhao",
  	npc_02_yszg_timeline_shangci: "npc_02_yszg_timeline_shangci",
  	npc_03_yszg_timeline_huangjin_idle: "npc_03_yszg_timeline_huangjin_idle",
  	npc_03_yszg_timeline_huangjin_move: "npc_03_yszg_timeline_huangjin_move",
  	yszg_yszg_timeline_huangjin_idle: "yszg_yszg_timeline_huangjin_idle",
  	yszg_yszg_timeline_huangjin_xingli: "yszg_yszg_timeline_huangjin_xingli",
  	yszg_yszg_timeline_songtang_idle: "yszg_yszg_timeline_songtang_idle",
  	yszg_yszg_timeline_songtang_move: "yszg_yszg_timeline_songtang_move",
  	yszg_yszg_timeline_songtang_xingli: "yszg_yszg_timeline_songtang_xingli",
  	npc02_zhuihs_timeline_fuqi: "npc02_zhuihs_timeline_fuqi",
  	player01_zhuihs_timeline_jiandongxi: "player01_zhuihs_timeline_jiandongxi",
  	chuhaihangxing_Recorded: "chuhaihangxing_Recorded",
  	chuhaihangxing_Recorded__1_: "chuhaihangxing_Recorded__1_",
  	chuhaihangxing_Recorded__2_: "chuhaihangxing_Recorded__2_",
  	chuhaihangxing_Recorded__3_: "chuhaihangxing_Recorded__3_",
  	chuhaihangxing_Recorded__4_: "chuhaihangxing_Recorded__4_",
  	chuiltz_Recorded: "chuiltz_Recorded",
  	chuiltz_Recorded__1_: "chuiltz_Recorded__1_",
  	chuiltz_Recorded__2_: "chuiltz_Recorded__2_",
  	chusaiheqinTimeline_Recorded: "chusaiheqinTimeline_Recorded",
  	chusaiheqinTimeline_Recorded__1_: "chusaiheqinTimeline_Recorded__1_",
  	chusaiheqinTimeline_Recorded__2_: "chusaiheqinTimeline_Recorded__2_",
  	chusaiheqinTimeline_Recorded__4_: "chusaiheqinTimeline_Recorded__4_",
  	chusaiheqinTimeline_Recorded__5_: "chusaiheqinTimeline_Recorded__5_",
  	huanghouTimeline_Recorded: "huanghouTimeline_Recorded",
  	huanghouTimeline_Recorded__1_: "huanghouTimeline_Recorded__1_",
  	huanghouTimeline_Recorded__2_: "huanghouTimeline_Recorded__2_",
  	huanghouTimeline_Recorded__3_: "huanghouTimeline_Recorded__3_",
  	hubushangshuTimeline_Recorded: "hubushangshuTimeline_Recorded",
  	hubushangshuTimeline_Recorded__1_: "hubushangshuTimeline_Recorded__1_",
  	hubushangshuTimeline_Recorded__2_: "hubushangshuTimeline_Recorded__2_",
  	hubushangshuTimeline_Recorded__3_: "hubushangshuTimeline_Recorded__3_",
  	hubushangshuTimeline_Recorded__4_: "hubushangshuTimeline_Recorded__4_",
  	hubushangshuTimeline_Recorded__5_: "hubushangshuTimeline_Recorded__5_",
  	nvchengxiangTimeline_Recorded: "nvchengxiangTimeline_Recorded",
  	nvchengxiangTimeline_Recorded__1_: "nvchengxiangTimeline_Recorded__1_",
  	nvchengxiangTimeline_Recorded__2_: "nvchengxiangTimeline_Recorded__2_",
  	nvchengxiangTimeline_Recorded__3_: "nvchengxiangTimeline_Recorded__3_",
  	taihou_Recorded: "taihou_Recorded",
  	taihou_Recorded__1_: "taihou_Recorded__1_",
  	thdeshangci_Recorded: "thdeshangci_Recorded",
  	thdeshangci_Recorded__1_: "thdeshangci_Recorded__1_",
  	thdeshangci_Recorded__2_: "thdeshangci_Recorded__2_",
  	wangyewangfeiTimeline_Recorded: "wangyewangfeiTimeline_Recorded",
  	wangyewangfeiTimeline_Recorded__1_: "wangyewangfeiTimeline_Recorded__1_",
  	wangyewangfeiTimeline_Recorded__2_: "wangyewangfeiTimeline_Recorded__2_",
  	xiajiajiangjunTimeline_Recorded: "xiajiajiangjunTimeline_Recorded",
  	xiajiajiangjunTimeline_Recorded__1_: "xiajiajiangjunTimeline_Recorded__1_",
  	xiajiajiangjunTimeline_Recorded__2_: "xiajiajiangjunTimeline_Recorded__2_",
  	xiajiajiangjunTimeline_Recorded__3_: "xiajiajiangjunTimeline_Recorded__3_",
  	xiajiajiangjunTimeline_Recorded__4_: "xiajiajiangjunTimeline_Recorded__4_",
  	xiajiajiangjunTimeline_Recorded__5_: "xiajiajiangjunTimeline_Recorded__5_",
  	xiajiajiangjunTimeline_Recorded__6_: "xiajiajiangjunTimeline_Recorded__6_",
  	yangwuzongdu_Recorded: "yangwuzongdu_Recorded",
  	yangwuzongdu_Recorded__1_: "yangwuzongdu_Recorded__1_",
  	yangwuzongdu_Recorded__2_: "yangwuzongdu_Recorded__2_",
  	yangwuzongdu_Recorded__3_: "yangwuzongdu_Recorded__3_",
  	yushanzhuguan_Recorded: "yushanzhuguan_Recorded",
  	yushanzhuguan_Recorded__1_: "yushanzhuguan_Recorded__1_",
  	yushanzhuguan_Recorded__2_: "yushanzhuguan_Recorded__2_",
  	yushanzhuguan_Recorded__3_: "yushanzhuguan_Recorded__3_",
  	yushanzhuguan_Recorded__4_: "yushanzhuguan_Recorded__4_",
  	zhuihuangshang_Recorded: "zhuihuangshang_Recorded",
  	zhuihuangshang_Recorded__1_: "zhuihuangshang_Recorded__1_",
  	zhuihuangshang_Recorded__2_: "zhuihuangshang_Recorded__2_",
  	zhuihuangshang_Recorded__3_: "zhuihuangshang_Recorded__3_",
  	zongguanmomoTimeline_Recorded: "zongguanmomoTimeline_Recorded",
  	zongguanmomoTimeline_Recorded__1_: "zongguanmomoTimeline_Recorded__1_",
  	zongguanmomoTimeline_Recorded__2_: "zongguanmomoTimeline_Recorded__2_",
  };
  db.cop_db = {
  	ad_interstitial_switchs: [],
  	ad_interstitial_ratios: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  	ad_banner_button_switchs: [],
  	ad_banner_button_tag: 0,
  	ad_banner_switchs: [],
  	ad_banner_ratios: [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],
  	ad_video_cds: [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],
  	ad_inst_cd: 0.5,
  	ad_banner_refresh_cd: 10,
  	native_insert_mode: 1,
  	native_insert_close_size_wh: 50,
  	native_insert_close_show_delay_second: 0,
  	b_native_insert_close_click_trigger_ad: 0,
  	b_native_insert_close_click_trigger_ad_gap: 0,
  	b_native_insert_close_click_trigger_ad_daily_count: 0,
  	b_native_insert_close_blur_mode: 0,
  	b_banner_in_guide: 0,
  	b_inst_in_guide: 0,
  	some_function: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  	b_open_statics_item: 0,
  	pop_review_ratio: 0,
  	url_notice: "",
  	b_open_follow: 0,
  	alert_weights_main: [100, 100],
  	alert_cds_main: [60, 60],
  	alert_orders_main: [1, 2],
  	alert_weights_cloth: [100],
  	alert_cds_cloth: [60],
  	alert_orders_cloth: [1],
  	video_share_mode: 0,
  	video_share_delay_time: 0,
  	video_ad_close_button: 0,
  	video_ad_close_delay: 0,
  	check_mode: 0,
  	video_failed_retry_mode: 0,
  	jump_single_switchs: [0],
  	jump_banner_switchs: [0],
  	jump_left_switchs: [0],
  	douyin_follow_switch: 0,
  	ad_flag_style: 0,
  	b_defaultUnlock: 0,
  	s_kefu_text: "",
  	ad_h5: [0],
  	isThirdExit: false,
  	isAbout: false,
  	isShareEnabled: false,
  	isPayEnabled: true,
  	isULMoreGame: false,
  	isUseSdkRank: false,
  	isWebView: false,
  	isShowUrlAdIcon: false,
  	isSupportRecordShare: false,
  	isSupportInstallShortcut: false,
  	isSupportFindMinigames: false,
  	isSupportRecommendationBtn: false,
  	is4399Watermark: false,
  	isJumpLeisureEnabled: false,
  	isSupportFollowOfficialAccount: false,
  	isSupportFavoriteGuide: false,
  	jump_alert_cd: 0,
  	jump_other_game_switchs: [],
  	grid_ad_switchs: [],
  	grid_ad_ratios: [],
  	native_wx_ad_switchs: [],
  	try_add_gold_cd: 0,
  	try_add_gold_ratio: 0,
  	b_advanced_setting: 0,
  	b_auto_release_enabled: 0,
  	b_grey_mode: 0,
  	b_result_beautifull_word: 0,
  	go_btm_btns_pos_mode: 0,
  	b_open_chest: 0,
  	chest_cd: 60,
  	free_level_up_ratio: [0, 0, 0, 0],
  	free_level_up_cd: [0, 0, 0, 0],
  	free_level_up_day_count: [0, 0, 0, 0],
  	b_adapt_go_ui_banner_when_start_go: 0,
  	b_hub_show_button_zq: 0,
  	custom_max_energy: 10,
  	pop_trial_retinue_ui_normal_year_ratio: 0,
  	pop_trial_retinue_ui_get_year_ratio: 0,
  	b_show_rocker_btn: 0,
  	b_show_mask: 0,
  	question_fierce_type: 0,
  	b_disable_stage_corner_video_ad2: 0,
  	b_disable_stage_corner_video_ad3: 0,
  	b_disable_stage_corner_video_ad4: 0,
  	b_disable_stage_corner_video_ad5: 0,
  	ui_bottom_mode_switch: [0, 0, 0],
  	ui_bottom_recovery_ratio: [0, 0, 0],
  	ui_bottom_delay_time: [0, 0, 0],
  	ui_bottom_not_recovery_time: 0,
  	ui_bottom_recovery_cd: 0,
  };
  db.MODEL_DB_ID = {
  	_116_ui_loop_finger_01: "116_ui_loop_finger_01",
  	_116_ui_loop_finger_02: "116_ui_loop_finger_02",
  	_120_e_once_glow_01: "120_e_once_glow_01",
  	_130_chuansongmen_blue: "130_chuansongmen_blue",
  	_130_chuansongmen_green: "130_chuansongmen_green",
  	_130_chuansongmen_purple: "130_chuansongmen_purple",
  	_130_chuansongmen_purple2: "130_chuansongmen_purple2",
  	_130_chuansongmen_red: "130_chuansongmen_red",
  	_130_chuansongmen_red2: "130_chuansongmen_red2",
  	_130_e_fudm_loop_01: "130_e_fudm_loop_01",
  	_130_e_fudm_loop_02: "130_e_fudm_loop_02",
  	_130_e_fuxy_loop_01: "130_e_fuxy_loop_01",
  	_130_e_fuxy_loop_02: "130_e_fuxy_loop_02",
  	_130_e_loop_cloud_01: "130_e_loop_cloud_01",
  	_130_e_loop_dengji_01: "130_e_loop_dengji_01",
  	_130_e_loop_dengji_02: "130_e_loop_dengji_02",
  	_130_e_loop_dengji_03: "130_e_loop_dengji_03",
  	_130_e_loop_jiasu: "130_e_loop_jiasu",
  	_130_e_loop_shengli_01: "130_e_loop_shengli_01",
  	_130_e_loop_shibai_01: "130_e_loop_shibai_01",
  	_130_e_loop_smoke_01: "130_e_loop_smoke_01",
  	_130_e_loop_smoke_02: "130_e_loop_smoke_02",
  	_130_e_loop_snow_03: "130_e_loop_snow_03",
  	_130_e_loop_trail_blue: "130_e_loop_trail_blue",
  	_130_e_loop_trail_green: "130_e_loop_trail_green",
  	_130_e_loop_trail_orange: "130_e_loop_trail_orange",
  	_130_e_loop_trail_pink: "130_e_loop_trail_pink",
  	_130_e_loop_trail_purple: "130_e_loop_trail_purple",
  	_130_e_loop_yinfu_01: "130_e_loop_yinfu_01",
  	_130_e_once_buff: "130_e_once_buff",
  	_130_e_once_debuff: "130_e_once_debuff",
  	_130_e_once_glow_01: "130_e_once_glow_01",
  	_130_e_once_glow_baoji: "130_e_once_glow_baoji",
  	_130_e_once_glow_blue: "130_e_once_glow_blue",
  	_130_e_once_glow_green: "130_e_once_glow_green",
  	_130_e_once_glow_pink: "130_e_once_glow_pink",
  	_130_e_once_glow_purple: "130_e_once_glow_purple",
  	_130_e_once_jiansubuff: "130_e_once_jiansubuff",
  	_130_e_once_jiasubuff: "130_e_once_jiasubuff",
  	_130_e_once_shengji_01: "130_e_once_shengji_01",
  	_130_e_once_timuglow_01: "130_e_once_timuglow_01",
  	_130_e_skill_gn_01: "130_e_skill_gn_01",
  	_130_e_skill_mm_01: "130_e_skill_mm_01",
  	_130_e_skill_sw_01: "130_e_skill_sw_01",
  	_130_e_skill_ty_01: "130_e_skill_ty_01",
  	_130_levp_scene_shizhuo_02: "130_levp_scene_shizhuo_02",
  	_130_levp_scene_shizhuo_03: "130_levp_scene_shizhuo_03",
  	_130_levp_scene_shizhuo_04: "130_levp_scene_shizhuo_04",
  	_130_levp_scene_shizhuo_04_1: "130_levp_scene_shizhuo_04_1",
  	_130_levp_scene_shizhuo_05: "130_levp_scene_shizhuo_05",
  	_130_levp_scene_shuichi_01: "130_levp_scene_shuichi_01",
  	_130_levp_scene_shuichi_02: "130_levp_scene_shuichi_02",
  	_130_levp_scene_shuichi_03: "130_levp_scene_shuichi_03",
  	_130_levp_scene_shuichi_03_water: "130_levp_scene_shuichi_03_water",
  	_130_levp_scene_shuichi_04: "130_levp_scene_shuichi_04",
  	_130_levp_scene_shuichi_05: "130_levp_scene_shuichi_05",
  	_130_levp_scene_shuichi_05_water: "130_levp_scene_shuichi_05_water",
  	_130_levp_scene_shu_02: "130_levp_scene_shu_02",
  	_130_levp_scene_shu_03: "130_levp_scene_shu_03",
  	_130_levp_scene_shu_05: "130_levp_scene_shu_05",
  	_130_levp_scene_tingzi_02: "130_levp_scene_tingzi_02",
  	_130_ui_once_jsdc_01: "130_ui_once_jsdc_01",
  	_130_ui_once_jsdc_02: "130_ui_once_jsdc_02",
  	_130_ui_once_levp_cw: "130_ui_once_levp_cw",
  	_130_ui_once_openbox_01: "130_ui_once_openbox_01",
  	_130_ui_once_ray_01: "130_ui_once_ray_01",
  	_130_ui_sc_shengji_01: "130_ui_sc_shengji_01",
  	all_animation_controller: "all_animation_controller",
  	baoguo: "baoguo",
  	baozuo: "baozuo",
  	ch: "ch",
  	chuhaihangxing: "chuhaihangxing",
  	chuiltz: "chuiltz",
  	chusaiheqin: "chusaiheqin",
  	CM_vcam1: "CM vcam1",
  	CM_vcam2: "CM vcam2",
  	daolu: "daolu",
  	daolu01: "daolu01",
  	daolu010: "daolu010",
  	daolu02: "daolu02",
  	daolu03: "daolu03",
  	daolu04: "daolu04",
  	daolu05: "daolu05",
  	daolu06: "daolu06",
  	daolu07: "daolu07",
  	daolu08: "daolu08",
  	daolu09: "daolu09",
  	daolu10: "daolu10",
  	daomeifu: "daomeifu",
  	dasuan: "dasuan",
  	ddsr01: "ddsr01",
  	ddsr02: "ddsr02",
  	ddsr03: "ddsr03",
  	ddsr04: "ddsr04",
  	ddsr05: "ddsr05",
  	ddsr06: "ddsr06",
  	Directional_Light: "Directional Light",
  	dizi: "dizi",
  	dj1: "dj1",
  	dj12: "dj12",
  	dj13: "dj13",
  	dj14: "dj14",
  	dj22: "dj22",
  	dj23: "dj23",
  	dj24: "dj24",
  	dj5: "dj5",
  	dj63: "dj63",
  	dj72: "dj72",
  	dj9: "dj9",
  	fsx01: "fsx01",
  	fsx02: "fsx02",
  	fsx03: "fsx03",
  	gaitou: "gaitou",
  	ggx01: "ggx01",
  	ggx02: "ggx02",
  	ggx03: "ggx03",
  	ggx04: "ggx04",
  	ggx05: "ggx05",
  	ggx06: "ggx06",
  	gyx01: "gyx01",
  	gyx02: "gyx02",
  	gyx03: "gyx03",
  	gyx04: "gyx04",
  	gyx05: "gyx05",
  	gyx06: "gyx06",
  	hehuachi01: "hehuachi01",
  	hehuachi03: "hehuachi03",
  	hehuachi04: "hehuachi04",
  	hehualu01: "hehualu01",
  	hehualu02: "hehualu02",
  	hehualu03: "hehualu03",
  	hehualu04: "hehualu04",
  	hongqiang01: "hongqiang01",
  	hongqiang02: "hongqiang02",
  	hongqiang03: "hongqiang03",
  	hongqiang04: "hongqiang04",
  	hongqianglu01: "hongqianglu01",
  	hongqianglu02: "hongqianglu02",
  	hongqianglu03: "hongqianglu03",
  	hongqianglu04: "hongqianglu04",
  	hualu01: "hualu01",
  	hualu02: "hualu02",
  	hualu03: "hualu03",
  	hualu04: "hualu04",
  	huanghou: "huanghou",
  	huatai01: "huatai01",
  	huatai03: "huatai03",
  	huatai04: "huatai04",
  	hubushangshu: "hubushangshu",
  	jiasuo: "jiasuo",
  	jiesuantai: "jiesuantai",
  	jiesuantai2: "jiesuantai2",
  	jiesuantai3: "jiesuantai3",
  	jiesuantai4: "jiesuantai4",
  	jingbagou: "jingbagou",
  	jishui: "jishui",
  	ma: "ma",
  	ma02: "ma02",
  	ma03: "ma03",
  	Main_Camera: "Main Camera",
  	mao: "mao",
  	map01: "map01",
  	men_b: "men_b",
  	men_blue: "men_blue",
  	men_green: "men_green",
  	men_pink: "men_pink",
  	men_r: "men_r",
  	men_red: "men_red",
  	mlb: "mlb",
  	npc01: "npc01",
  	npc02: "npc02",
  	npc03: "npc03",
  	npc04: "npc04",
  	npc05: "npc05",
  	npc06: "npc06",
  	npc07: "npc07",
  	npc_01: "npc_01",
  	npc_01_skin: "npc_01_skin",
  	npc_01_tuozou: "npc_01_tuozou",
  	npc_02: "npc_02",
  	npc_03: "npc_03",
  	npc_04: "npc_04",
  	npc_05: "npc_05",
  	npc_06: "npc_06",
  	npc_07: "npc_07",
  	nvchengxiang: "nvchengxiang",
  	oushilu01: "oushilu01",
  	oushilu03: "oushilu03",
  	oushilu04: "oushilu04",
  	oushilu10: "oushilu10",
  	panzi: "panzi",
  	player01: "player01",
  	player01_1: "player01_1",
  	player01_2: "player01_2",
  	player01_3: "player01_3",
  	player01_3_1: "player01_3_1",
  	player01_4: "player01_4",
  	player01_4_anim: "player01_4_anim",
  	player01_z: "player01_z",
  	player02: "player02",
  	player02_1: "player02_1",
  	player02_2: "player02_2",
  	player02_3: "player02_3",
  	player03: "player03",
  	player03_1: "player03_1",
  	player03_2: "player03_2",
  	player03_3: "player03_3",
  	player04: "player04",
  	player04_1: "player04_1",
  	player04_2: "player04_2",
  	player04_3: "player04_3",
  	player04_4: "player04_4",
  	player05: "player05",
  	player05_1: "player05_1",
  	player05_2: "player05_2",
  	player06: "player06",
  	player06_thth: "player06_thth",
  	player07: "player07",
  	player08: "player08",
  	player09: "player09",
  	player10: "player10",
  	player11: "player11",
  	player12: "player12",
  	player13: "player13",
  	player14: "player14",
  	player15: "player15",
  	prop: "prop",
  	question: "question",
  	role: "role",
  	roleNpc01AllController: "roleNpc01AllController",
  	roleNpc02AllController: "roleNpc02AllController",
  	roleNpc03AllController: "roleNpc03AllController",
  	roleNpc04AllController: "roleNpc04AllController",
  	roleNpc05AllController: "roleNpc05AllController",
  	roleNpc06AllController: "roleNpc06AllController",
  	roleNpc07AllController: "roleNpc07AllController",
  	roleNpc_01_tuozouAllController: "roleNpc_01_tuozouAllController",
  	rolePlayer01AllController: "rolePlayer01AllController",
  	rolePlayer01_4AllController: "rolePlayer01_4AllController",
  	rolePlayer03AllController: "rolePlayer03AllController",
  	rolePlayer04AllController: "rolePlayer04AllController",
  	rolePlayer05AllController: "rolePlayer05AllController",
  	rolePlayer06AllController: "rolePlayer06AllController",
  	role_challcontroller: "role_challcontroller",
  	role_ddsr01allcontroller: "role_ddsr01allcontroller",
  	role_ddsr02allcontroller: "role_ddsr02allcontroller",
  	role_ddsr03allcontroller: "role_ddsr03allcontroller",
  	role_ddsr04allcontroller: "role_ddsr04allcontroller",
  	role_ddsr05allcontroller: "role_ddsr05allcontroller",
  	role_ddsr06allcontroller: "role_ddsr06allcontroller",
  	role_ddsrallcontroller: "role_ddsrallcontroller",
  	role_fsx01allcontroller: "role_fsx01allcontroller",
  	role_fsx02allcontroller: "role_fsx02allcontroller",
  	role_fsx03allcontroller: "role_fsx03allcontroller",
  	role_ggx01allcontroller: "role_ggx01allcontroller",
  	role_ggx02allcontroller: "role_ggx02allcontroller",
  	role_ggx03allcontroller: "role_ggx03allcontroller",
  	role_ggx04allcontroller: "role_ggx04allcontroller",
  	role_ggx05allcontroller: "role_ggx05allcontroller",
  	role_ggxallcontroller: "role_ggxallcontroller",
  	role_gyx01allcontroller: "role_gyx01allcontroller",
  	role_gyx02allcontroller: "role_gyx02allcontroller",
  	role_gyx03allcontroller: "role_gyx03allcontroller",
  	role_gyx04allcontroller: "role_gyx04allcontroller",
  	role_gyx05allcontroller: "role_gyx05allcontroller",
  	role_gyx06allcontroller: "role_gyx06allcontroller",
  	role_gyxallcontroller: "role_gyxallcontroller",
  	role_jingbagouallcontroller: "role_jingbagouallcontroller",
  	role_ma02allcontroller: "role_ma02allcontroller",
  	role_ma03allcontroller: "role_ma03allcontroller",
  	role_maoallcontroller: "role_maoallcontroller",
  	role_npc01allcontroller: "role_npc01allcontroller",
  	role_npc02allcontroller: "role_npc02allcontroller",
  	role_npc03allcontroller: "role_npc03allcontroller",
  	role_npc04allcontroller: "role_npc04allcontroller",
  	role_npc05allcontroller: "role_npc05allcontroller",
  	role_npc06allcontroller: "role_npc06allcontroller",
  	role_npc07allcontroller: "role_npc07allcontroller",
  	role_npc_01_skinallcontroller: "role_npc_01_skinallcontroller",
  	role_player06_ththallcontroller: "role_player06_ththallcontroller",
  	role_wangfeiallcontroller: "role_wangfeiallcontroller",
  	role_xss01allcontroller: "role_xss01allcontroller",
  	role_xss02allcontroller: "role_xss02allcontroller",
  	role_xss03allcontroller: "role_xss03allcontroller",
  	role_xss04allcontroller: "role_xss04allcontroller",
  	role_yingwuallcontroller: "role_yingwuallcontroller",
  	role_yszgallcontroller: "role_yszgallcontroller",
  	role_yszgfeiallcontroller: "role_yszgfeiallcontroller",
  	role_ywx01allcontroller: "role_ywx01allcontroller",
  	role_ywx02allcontroller: "role_ywx02allcontroller",
  	role_ywx03allcontroller: "role_ywx03allcontroller",
  	role_ywx04allcontroller: "role_ywx04allcontroller",
  	role_ywx05allcontroller: "role_ywx05allcontroller",
  	role_ywx06allcontroller: "role_ywx06allcontroller",
  	role_ywx07allcontroller: "role_ywx07allcontroller",
  	role_zgmmallcontroller: "role_zgmmallcontroller",
  	shanzi: "shanzi",
  	shu2: "shu2",
  	shufang: "shufang",
  	shuji: "shuji",
  	sky: "sky",
  	skydusk: "skydusk",
  	stage01: "stage01",
  	stage02: "stage02",
  	stage03: "stage03",
  	stage04: "stage04",
  	stage05: "stage05",
  	stage06: "stage06",
  	stage07: "stage07",
  	stage08: "stage08",
  	stage09: "stage09",
  	stage10: "stage10",
  	stage101: "stage101",
  	stage102: "stage102",
  	stage103: "stage103",
  	stage104: "stage104",
  	stage105: "stage105",
  	stage106: "stage106",
  	stage107: "stage107",
  	stage108: "stage108",
  	stage109: "stage109",
  	stage11: "stage11",
  	stage110: "stage110",
  	stage111: "stage111",
  	stage112: "stage112",
  	stage113: "stage113",
  	stage114: "stage114",
  	stage115: "stage115",
  	stage116: "stage116",
  	stage117: "stage117",
  	stage118: "stage118",
  	stage119: "stage119",
  	stage12: "stage12",
  	stage120: "stage120",
  	stage20: "stage20",
  	stage201: "stage201",
  	stage202: "stage202",
  	stage21: "stage21",
  	stage22: "stage22",
  	stage23: "stage23",
  	stage24: "stage24",
  	stage_pool1_01: "stage_pool1_01",
  	stage_pool1_01_test: "stage_pool1_01_test",
  	stage_pool1_02: "stage_pool1_02",
  	stage_pool1_0221: "stage_pool1_0221",
  	stage_pool1_0272: "stage_pool1_0272",
  	stage_pool1_03: "stage_pool1_03",
  	stage_pool1_0301: "stage_pool1_0301",
  	stage_pool1_0310: "stage_pool1_0310",
  	stage_pool1_04: "stage_pool1_04",
  	stage_pool1_05: "stage_pool1_05",
  	stage_pool1_06: "stage_pool1_06",
  	stage_pool1_0603: "stage_pool1_0603",
  	stage_pool1_0611: "stage_pool1_0611",
  	stage_pool1_07: "stage_pool1_07",
  	stage_pool1_08: "stage_pool1_08",
  	stage_pool1_09: "stage_pool1_09",
  	stage_pool1_0900: "stage_pool1_0900",
  	stage_pool1_10: "stage_pool1_10",
  	stage_pool1_1000: "stage_pool1_1000",
  	stage_pool1_101: "stage_pool1_101",
  	stage_pool1_102: "stage_pool1_102",
  	stage_pool1_11: "stage_pool1_11",
  	stage_pool1_12: "stage_pool1_12",
  	stage_pool1_1200: "stage_pool1_1200",
  	stage_pool1_1203: "stage_pool1_1203",
  	stage_pool1_13: "stage_pool1_13",
  	stage_pool1_201: "stage_pool1_201",
  	stage_pool1_202: "stage_pool1_202",
  	stage_pool1_301: "stage_pool1_301",
  	stage_pool1_401: "stage_pool1_401",
  	stage_pool1_501: "stage_pool1_501",
  	stage_pool1_601: "stage_pool1_601",
  	stage_pool1_602: "stage_pool1_602",
  	stage_pool1_603: "stage_pool1_603",
  	stage_pool1_604: "stage_pool1_604",
  	stage_pool1_605: "stage_pool1_605",
  	stage_pool1_606: "stage_pool1_606",
  	stage_pool1_607: "stage_pool1_607",
  	stage_pool1_608: "stage_pool1_608",
  	stage_pool1_609: "stage_pool1_609",
  	stage_pool1_610: "stage_pool1_610",
  	stage_pool1_611: "stage_pool1_611",
  	stage_pool1_612: "stage_pool1_612",
  	stage_pool1_613: "stage_pool1_613",
  	stage_pool1_614: "stage_pool1_614",
  	stage_pool2_01: "stage_pool2_01",
  	stage_pool2_01_test: "stage_pool2_01_test",
  	stage_pool2_02: "stage_pool2_02",
  	stage_pool2_0206: "stage_pool2_0206",
  	stage_pool2_0221: "stage_pool2_0221",
  	stage_pool2_0231: "stage_pool2_0231",
  	stage_pool2_0272: "stage_pool2_0272",
  	stage_pool2_03: "stage_pool2_03",
  	stage_pool2_0310: "stage_pool2_0310",
  	stage_pool2_04: "stage_pool2_04",
  	stage_pool2_05: "stage_pool2_05",
  	stage_pool2_06: "stage_pool2_06",
  	stage_pool2_0601: "stage_pool2_0601",
  	stage_pool2_0602: "stage_pool2_0602",
  	stage_pool2_0603: "stage_pool2_0603",
  	stage_pool2_07: "stage_pool2_07",
  	stage_pool2_08: "stage_pool2_08",
  	stage_pool2_09: "stage_pool2_09",
  	stage_pool2_0900: "stage_pool2_0900",
  	stage_pool2_10: "stage_pool2_10",
  	stage_pool2_1000: "stage_pool2_1000",
  	stage_pool2_101: "stage_pool2_101",
  	stage_pool2_102: "stage_pool2_102",
  	stage_pool2_103: "stage_pool2_103",
  	stage_pool2_11: "stage_pool2_11",
  	stage_pool2_12: "stage_pool2_12",
  	stage_pool2_1200: "stage_pool2_1200",
  	stage_pool2_1203: "stage_pool2_1203",
  	stage_pool2_13: "stage_pool2_13",
  	stage_pool2_14: "stage_pool2_14",
  	stage_pool2_201: "stage_pool2_201",
  	stage_pool2_202: "stage_pool2_202",
  	stage_pool2_203: "stage_pool2_203",
  	stage_pool2_301: "stage_pool2_301",
  	stage_pool2_401: "stage_pool2_401",
  	stage_pool2_502: "stage_pool2_502",
  	stage_pool2_601: "stage_pool2_601",
  	stage_pool2_602: "stage_pool2_602",
  	stage_pool2_603: "stage_pool2_603",
  	stage_pool2_604: "stage_pool2_604",
  	stage_pool2_605: "stage_pool2_605",
  	stage_pool2_606: "stage_pool2_606",
  	stage_pool2_607: "stage_pool2_607",
  	stage_pool2_608: "stage_pool2_608",
  	stage_pool2_609: "stage_pool2_609",
  	stage_pool2_610: "stage_pool2_610",
  	stage_pool2_611: "stage_pool2_611",
  	stage_pool2_612: "stage_pool2_612",
  	stage_pool2_613: "stage_pool2_613",
  	stage_pool2_614: "stage_pool2_614",
  	stage_pool3_01_test: "stage_pool3_01_test",
  	stage_pool3_601: "stage_pool3_601",
  	sudu: "sudu",
  	sx1: "sx1",
  	sx104_zl: "sx104_zl",
  	sx2: "sx2",
  	sx3: "sx3",
  	sx4: "sx4",
  	sx5: "sx5",
  	sx6: "sx6",
  	taihou: "taihou",
  	thdeshangci: "thdeshangci",
  	tiankonghe: "tiankonghe",
  	timu: "timu",
  	tinglanglu01: "tinglanglu01",
  	tinglanglu02: "tinglanglu02",
  	tinglanglu03: "tinglanglu03",
  	tinglanglu04: "tinglanglu04",
  	tinglanglu05: "tinglanglu05",
  	tingyuan: "tingyuan",
  	tongqian: "tongqian",
  	tongyong: "tongyong",
  	touzi: "touzi",
  	wangfei: "wangfei",
  	wangyewangfei: "wangyewangfei",
  	xiajiajiangjun: "xiajiajiangjun",
  	xingyunfu: "xingyunfu",
  	xss01: "xss01",
  	xss02: "xss02",
  	xss03: "xss03",
  	xss04: "xss04",
  	yangwuzongdu: "yangwuzongdu",
  	yinghualu00: "yinghualu00",
  	yinghualu01: "yinghualu01",
  	yinghualu03: "yinghualu03",
  	yinghualu04: "yinghualu04",
  	yinghualu05: "yinghualu05",
  	yinghualu10: "yinghualu10",
  	yingwu: "yingwu",
  	yszg: "yszg",
  	yuanbao: "yuanbao",
  	yuhu: "yuhu",
  	yun01: "yun01",
  	yushanzhuguan: "yushanzhuguan",
  	ywx01: "ywx01",
  	ywx02: "ywx02",
  	ywx03: "ywx03",
  	ywx04: "ywx04",
  	ywx05: "ywx05",
  	ywx06: "ywx06",
  	ywx07: "ywx07",
  	zgmm: "zgmm",
  	zgmm_02: "zgmm_02",
  	zhengling: "zhengling",
  	zhong: "zhong",
  	zhuihuangshang: "zhuihuangshang",
  	zhuzi01: "zhuzi01",
  	zhuzi03: "zhuzi03",
  	zhuzi04: "zhuzi04",
  	zongguanmomo: "zongguanmomo",
  };
  db.SPINE_DB_ID = {
  	ui_lihe: "ui_lihe",
  	ui_loading: "ui_loading",
  };

  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",
  	SYS_MOUSE_WHEEL: "SYS_MOUSE_WHEEL",
  	SYS_RIGHT_MOUSE_DOWN: "SYS_RIGHT_MOUSE_DOWN",
  	SYS_RIGHT_MOUSE_UP: "SYS_MOUSE_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_PRE_PAY: "SDK_PRE_PAY",
  	SDK_ADD_ITEM: "SDK_ADD_ITEM",
  	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",
  	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",
  	MSG_GUIDE_FINISH: "MSG_GUIDE_FINISH",
  	MSG_STATISTICS_BUTTON_FOCUS: "MSG_STATISTICS_BUTTON_FOCUS",
  };
  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 = {}));
  var BASE_ACTION_ID;
  (function (BASE_ACTION_ID) {
  	BASE_ACTION_ID["CONSUME_ITME"] = "1";
  	BASE_ACTION_ID["ADD_ITEM"] = "2";
  	BASE_ACTION_ID["SIGN"] = "3";
  	BASE_ACTION_ID["FAIRY_GIFT"] = "4";
  	BASE_ACTION_ID["FREE_WEAR"] = "5";
  	BASE_ACTION_ID["EXTRACT_CLOTH"] = "6";
  	BASE_ACTION_ID["STAGE"] = "7";
  	BASE_ACTION_ID["STAGE_COUNT"] = "8";
  	BASE_ACTION_ID["LIKE"] = "9";
  	BASE_ACTION_ID["MATCH"] = "10";
  	BASE_ACTION_ID["CLICK_ROLE"] = "11";
  	BASE_ACTION_ID["SWITCH_ROLE"] = "12";
  	BASE_ACTION_ID["ROLE_TEST"] = "13";
  	BASE_ACTION_ID["ROLE_TEST_ROLE_COUNT"] = "14";
  	BASE_ACTION_ID["ROLE_TEST_SPECIAL_ROLE"] = "15";
  	BASE_ACTION_ID["ROLE_TEST_ROLE_OR"] = "16";
  	BASE_ACTION_ID["ROLE_TEST_ROLE_ADD"] = "17";
  	BASE_ACTION_ID["FAIRY_TEST"] = "18";
  	BASE_ACTION_ID["FAIRY_TEST_SPECIAL_FAIRY"] = "19";
  	BASE_ACTION_ID["FAIRY_TEST_ADD"] = "20";
  	BASE_ACTION_ID["NATAL_FAIRY_COUNT"] = "21";
  	BASE_ACTION_ID["PLANT_COUNT"] = "22";
  	BASE_ACTION_ID["PLANT_FLOWER_COUNT"] = "23";
  	BASE_ACTION_ID["UPGRADE_ANY_FLOWER2LEVEL"] = "24";
  	BASE_ACTION_ID["UPGRADE_SPECIAL_FLOWER2LEVEL"] = "25";
  	BASE_ACTION_ID["GOT_FAIRY_COUNT"] = "26";
  	BASE_ACTION_ID["UNLOCK_FAIRY"] = "27";
  	BASE_ACTION_ID["INTERACTION_PRACTICE"] = "28";
  	BASE_ACTION_ID["INTERACTION_PURIFY"] = "29";
  	BASE_ACTION_ID["INTERACTION_BALL"] = "30";
  	BASE_ACTION_ID["INTERACTION_DATE"] = "31";
  	BASE_ACTION_ID["COURSE_HELP"] = "32";
  	BASE_ACTION_ID["COURSE_CHEEK"] = "33";
  	BASE_ACTION_ID["COURSE_RAISE"] = "34";
  	BASE_ACTION_ID["COURSE_PUNISH"] = "35";
  	BASE_ACTION_ID["COURSE_COLLECT_PART"] = "36";
  	BASE_ACTION_ID["COURSE_COLLECT_SUIT"] = "37";
  	BASE_ACTION_ID["SWITCH_FAIRY"] = "38";
  	BASE_ACTION_ID["ADD_PART"] = "39";
  	BASE_ACTION_ID["COLLECT_SPECIAL_SUIT"] = "40";
  })(BASE_ACTION_ID || (BASE_ACTION_ID = {}));
  const BASE_SWITCH_ID = {
  	DAILY: "1",
  	WEEKLY: "2",
  };

  let cur_log_level = 0;
  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 _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  const lookup = new Uint8Array(256);
  for (let i = 0; i < _keyStr.length; i++) {
  	lookup[_keyStr.charCodeAt(i)] = i;
  }
  class Base64 {
  	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 = Base64.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 _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;
  }

  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:
  			case RES_TYPE.BUFFER:
  				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 getRes(url) {
  		return Laya.loader.getRes(url);
  	}
  	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 = {};

  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 TimelineClip {
  	constructor(track, data) {
  		this.track = track;
  		this.data = data;
  		this.state = 0;
  		this.clipElapsedTime = 0;
  		this.startCount = 0;
  	}
  	dispose() {
  		this.track = null;
  		this.data = null;
  		this.state = 2;
  	}
  	get start() {
  		return this.data.start;
  	}
  	get end() {
  		return this.data.end;
  	}
  	get duration() {
  		return this.end - this.start;
  	}
  	get isUpdating() {
  		return this.state == 1;
  	}
  	update(elapsedTime, bJump, bCrossAnim) {
  		switch (this.state) {
  			case 0:
  				this.tryStart(elapsedTime, bCrossAnim);
  				break;
  			case 1:
  				this.tryUpdate(elapsedTime, bJump, bCrossAnim);
  				break;
  		}
  	}
  	stop() {
  		if (this.state == 1) {
  			this.state = 0;
  			this.onEnd();
  		}
  	}
  	loopStart(elapsedTime) {
  		if (this.state == 1) {
  			if (elapsedTime >= this.start) {
  				this.clipElapsedTime = elapsedTime - this.start;
  				this.onLoopStart();
  			}
  			else {
  				this.stop();
  			}
  		}
  	}
  	onReset() {
  		this.startCount = 0;
  	}
  	onStart(bCrossAnim) { }
  	;
  	onUpdate() { }
  	;
  	onEnd() { }
  	;
  	onLoopStart() { }
  	onJumpTo(bCrossAnim) { }
  	tryStart(elapsedTime, bCrossAnim) {
  		if (elapsedTime >= this.end)
  			return;
  		if (elapsedTime >= this.start) {
  			this.clipElapsedTime = elapsedTime - this.start;
  			this.state = 1;
  			this.startCount++;
  			this.onStart(bCrossAnim);
  		}
  	}
  	tryUpdate(elapsedTime, bJump, bCrossAnim) {
  		this.clipElapsedTime = elapsedTime - this.start;
  		if (elapsedTime >= this.end) {
  			this.stop();
  		}
  		else {
  			if (bJump) {
  				if (elapsedTime >= this.start) {
  					this.onJumpTo(bCrossAnim);
  				}
  				else {
  					this.stop();
  				}
  			}
  			this.onUpdate();
  		}
  	}
  }

  let DEBUG_TIME_LINE = false;
  class TimelineTools {
  	static debugLog(msg1, msg2) {
  		if (DEBUG_TIME_LINE) {
  			if (msg2) {
  				console.log("timeline:" + msg1, msg2, this.roundFloat(Laya.timer.currTimer / 1000), Laya.timer.currFrame);
  			}
  			else {
  				console.log("timeline:" + msg1, this.roundFloat(Laya.timer.currTimer / 1000), Laya.timer.currFrame);
  			}
  		}
  	}
  	static getFileNameWithoutExt(file) {
  		return file.replace(/(.*\/)*([^.]+).*/ig, "$2");
  	}
  	static findChild(root, childName) {
  		if (!childName)
  			return null;
  		if (!root)
  			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 findChildPath(root, childPath) {
  		if (childPath == null)
  			return null;
  		if (!root)
  			return null;
  		if (childPath == "")
  			return root;
  		let paths = childPath.split("/");
  		for (let i = 0; i < paths.length; i++) {
  			root = root.getChildByName(paths[i]);
  			if (!root)
  				return null;
  		}
  		return root;
  	}
  	static roundFloat(value) {
  		value *= 1000;
  		return Math.round(value) / 1000;
  	}
  	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 getComponentsInChildren(root, type, out) {
  		out = out || [];
  		for (let i = root.numChildren - 1; i >= 0; i--) {
  			let child = root.getChildAt(i);
  			if (child) {
  				let comp = child.getComponent(type);
  				if (comp) {
  					out.push(comp);
  				}
  				this.getComponentsInChildren(child, type, out);
  			}
  		}
  		return out;
  	}
  	static playParticleNode(node) {
  		if (node.particleSystem) {
  			node.particleSystem.play();
  		}
  		for (let i = 0; i < node.numChildren; i++) {
  			this.playParticleNode(node.getChildAt(i));
  		}
  	}
  	static stopParticleNode(node) {
  		if (node.particleSystem) {
  			node.particleSystem.stop();
  		}
  		for (let i = 0; i < node.numChildren; i++) {
  			this.stopParticleNode(node.getChildAt(i));
  		}
  	}
  }
  TimelineTools.UP = new Laya.Vector3(0, 1, 0);

  class AnimationClip extends TimelineClip {
  	get animator() {
  		return this.track.bindObject;
  	}
  	onStart(bCrossAnim) {
  		let animator = this.animator;
  		if (!animator) {
  			console.error("AnimationClip：缺少Animator.");
  			return;
  		}
  		if (!this.data.assetPath) {
  			console.error("AnimationClip：缺少AnimationClip.");
  			return;
  		}
  		this.animName = TimelineTools.getFileNameWithoutExt(this.data.assetPath);
  		let animState = animator.getControllerLayer(0).getAnimatorState(this.animName);
  		if (!animState) {
  			let clip = Laya.loader.getRes(this.data.assetPath);
  			if (!clip) {
  				this.animName = null;
  				console.error("AnimationClip：未加载AnimationClip.");
  				return;
  			}
  			let state = new Laya.AnimatorState();
  			state.clip = clip;
  			state.clipStart = 0;
  			state.clipEnd = 1;
  			state.name = this.animName;
  			animator.getControllerLayer(0).addState(state);
  		}
  		animator.speed = this.data.timeScale;
  		if (bCrossAnim) {
  			let t = TimelineTools.clamp(0.3 / this.duration, 0, 0.1);
  			animator.crossFade(this.animName, t, 0, this.normalizedTime);
  		}
  		else {
  			let track = this.track;
  			let crossTime = track.getCrossTime(this);
  			if (crossTime == 0) {
  				animator.play(this.animName, 0, this.normalizedTime);
  			}
  			else {
  				animator.crossFade(this.animName, crossTime / this.duration, 0, this.normalizedTime);
  			}
  		}
  		TimelineTools.debugLog("AnimationClip.start ", this.animName);
  	}
  	onEnd() {
  		TimelineTools.debugLog("AnimationClip.end ", this.animName);
  	}
  	onLoopStart() {
  		this.animator.crossFade(this.animName, 0.1, 0, this.normalizedTime);
  	}
  	onJumpTo(bCrossAnim) {
  		if (bCrossAnim) {
  			let t = TimelineTools.clamp(0.3 / this.duration, 0, 0.1);
  			this.animator.crossFade(this.animName, t, 0, this.normalizedTime);
  		}
  		else {
  			this.animator.play(this.animName, 0, this.normalizedTime);
  		}
  	}
  	get normalizedTime() {
  		if (this.track.data.inClipMode) {
  			var time = this.clipElapsedTime / this.duration;
  		}
  		else {
  			var time = this.track.director.elapsedTime / this.end;
  		}
  		return TimelineTools.clamp01(time);
  	}
  }

  class TrackBase {
  	constructor(director, data) {
  		this.clips = [];
  		this.director = director;
  		this.data = data;
  	}
  	get name() {
  		return this.data.name;
  	}
  	dispose() {
  		if (this.clips) {
  			for (let i = 0; i < this.clips.length; i++) {
  				this.clips[i].dispose();
  			}
  			this.clips = null;
  		}
  		this.bindObject = null;
  	}
  	getClipInfo() {
  		return null;
  	}
  	createClip() {
  		let clipInfo = this.getClipInfo();
  		if (clipInfo) {
  			let clipClass = clipInfo.clipClass;
  			let clipList = clipInfo.clipList;
  			if (clipClass && clipList) {
  				for (let i = 0; i < clipList.length; i++) {
  					let clip = new clipClass(this, clipList[i]);
  					this.clips.push(clip);
  				}
  			}
  		}
  	}
  	genericBinding(obj) {
  		this.bindObject = obj;
  	}
  	reset() {
  		for (let i = 0; i < this.clips.length; i++) {
  			this.clips[i].onReset();
  		}
  	}
  	stop() {
  		for (let i = 0; i < this.clips.length; i++) {
  			this.clips[i].stop();
  		}
  	}
  	update(elapsedTime, bJump, bCrossAnim) {
  		for (let i = 0; i < this.clips.length; i++) {
  			this.clips[i].update(elapsedTime, bJump, bCrossAnim);
  		}
  	}
  	loopStart(elapsedTime) {
  		for (let i = 0; i < this.clips.length; i++) {
  			this.clips[i].loopStart(elapsedTime);
  		}
  	}
  }

  class AnimationTrack extends TrackBase {
  	dispose() {
  		if (this.bindObject) {
  			let controller = this.bindObject.getControllerLayer(0);
  			if (controller) {
  				controller.playOnWake = this.defaultPlayOnWake;
  			}
  		}
  		super.dispose();
  	}
  	reset() {
  		var bBindSuc = false;
  		if (this.data.owner) {
  			let child = this.director.findChildPath(this.data.owner);
  			if (child) {
  				let animator = child.getComponent(Laya.Animator);
  				if (!animator) {
  					animator = child.addComponent(Laya.Animator);
  				}
  				animator.speed = 0;
  				this.genericBinding(animator);
  				bBindSuc = true;
  			}
  		}
  		if (!bBindSuc) {
  			console.error("AnimationTrack: 缺少Animator! owner:", this.data.owner);
  		}
  		super.reset();
  	}
  	getClipInfo() {
  		return { clipClass: AnimationClip, clipList: this.data.clipList };
  	}
  	genericBinding(obj) {
  		if (obj) {
  			super.genericBinding(obj);
  			let controller = obj.getControllerLayer(0);
  			if (!controller) {
  				controller = new Laya.AnimatorControllerLayer("default");
  				obj.addControllerLayer(controller);
  			}
  			this.defaultPlayOnWake = controller.playOnWake;
  			controller.playOnWake = false;
  		}
  	}
  	getCrossTime(curClip) {
  		for (let i = 0; i < this.clips.length; i++) {
  			let clip = this.clips[i];
  			if (clip.start < curClip.start && clip.end > curClip.start) {
  				return clip.end - curClip.start;
  			}
  		}
  		return 0;
  	}
  }

  class ActivationClip extends TimelineClip {
  	get node() {
  		return this.track.bindObject;
  	}
  	onReset() {
  		super.onReset();
  		TimelineTools.stopParticleNode(this.node);
  		this.node.active = false;
  	}
  	onStart() {
  		this.node.active = true;
  		TimelineTools.playParticleNode(this.node);
  		TimelineTools.debugLog("ActivationClip.start ", this.node.name);
  		let arr = this.track.director["trackList"];
  		for (let index = 0; index < arr.length; index++) {
  			var anim = arr[index];
  			if (anim instanceof AnimationTrack) {
  				for (let i = 0; i < anim.clips.length; i++) {
  					const clip = anim.clips[i];
  					if (clip.state == 1) {
  						clip.animator.play(clip.animName, 0, clip.normalizedTime);
  					}
  				}
  			}
  		}
  	}
  	onEnd() {
  		TimelineTools.stopParticleNode(this.node);
  		this.node.active = false;
  		TimelineTools.debugLog("ActivationClip.end ", this.node.name);
  	}
  }

  class ActivationTrack extends TrackBase {
  	reset() {
  		var bBindSuc = false;
  		if (this.data.owner) {
  			let child = this.director.findChildPath(this.data.owner);
  			if (child) {
  				this.genericBinding(child);
  				bBindSuc = true;
  			}
  		}
  		if (!bBindSuc) {
  			console.error("ActivationTrack: 缺少Node! owner:", this.data.owner);
  		}
  		super.reset();
  	}
  	getClipInfo() {
  		return { clipClass: ActivationClip, clipList: this.data.clipList };
  	}
  }

  class CinemachineClip extends TimelineClip {
  	onReset() {
  		super.onReset();
  		var data = this.data;
  		let cvCameraNode = this.track.director.findChildPath(data.camera);
  		if (!cvCameraNode) {
  			console.error("找不到VirtualCamera.", data.camera);
  			return;
  		}
  		if (this.camera && !this.camera.destroyed) {
  			this.camera.active = false;
  			return;
  		}
  		let newCamera = new Laya.Camera(0, 0.01, 1000);
  		cvCameraNode.addChild(newCamera);
  		newCamera.transform.localRotationEuler = new Laya.Vector3(0, 180, 0);
  		newCamera.fieldOfView = data.fov;
  		newCamera.name = "auto_create_" + data.displayName;
  		newCamera.useOcclusionCulling = false;
  		newCamera.enableHDR = false;
  		newCamera.active = false;
  		this.camera = newCamera;
  		if (data.lookAt) {
  			this.lookAt = this.track.director.findChildPath(data.lookAt);
  		}
  	}
  	onStart() {
  		if (this.camera) {
  			this.camera.active = true;
  			TimelineTools.debugLog("CinemachineClip.start:", this.camera.name);
  		}
  		else {
  			console.log("CinemachineClip.start: 没有镜头.", this.data.camera);
  		}
  	}
  	onUpdate() {
  		if (this.lookAt && this.camera) {
  			this.camera.transform.lookAt(this.lookAt.transform.position, TimelineTools.UP, false);
  		}
  	}
  	onEnd() {
  		if (this.camera) {
  			this.camera.active = false;
  			TimelineTools.debugLog("CinemachineClip.end:", this.camera.name);
  		}
  		else {
  			console.log("CinemachineClip.end: 没有镜头.", this.data.camera);
  		}
  	}
  }

  class CinemachineTrack extends TrackBase {
  	reset() {
  		var bBindSuc = false;
  		if (this.data.owner) {
  			let child = this.director.findChildPath(this.data.owner);
  			if (child) {
  				this.genericBinding(child);
  				bBindSuc = true;
  			}
  		}
  		if (!bBindSuc) {
  			console.error("CinemachineTrack: 缺少Camera! owner:", this.data.owner);
  		}
  		super.reset();
  	}
  	getClipInfo() {
  		return { clipClass: CinemachineClip, clipList: this.data.clipList };
  	}
  	genericBinding(obj) {
  		super.genericBinding(obj);
  		obj.active = false;
  	}
  }

  var ControlType;
  (function (ControlType) {
  	ControlType[ControlType["ChildNode"] = 0] = "ChildNode";
  	ControlType[ControlType["Resource"] = 1] = "Resource";
  })(ControlType || (ControlType = {}));
  class ControlClip extends TimelineClip {
  	onReset() {
  		super.onReset();
  		var data = this.data;
  		this.controlType = data.assetPath ? ControlType.Resource : ControlType.ChildNode;
  		if (this.controlType == ControlType.ChildNode) {
  			this._node = this.track.director.findChildPath(data.parent);
  			if (this._node) {
  				TimelineTools.stopParticleNode(this._node);
  				this._node.active = false;
  			}
  			else {
  				console.error("找不到需要控制的子节点:", data.parent);
  			}
  		}
  	}
  	onStart() {
  		let data = this.data;
  		if (this.controlType == ControlType.Resource) {
  			if (this._node) {
  				return;
  			}
  			let res = Laya.loader.getRes(data.assetPath);
  			if (!res) {
  				console.error("ControlClip.onStart: 节点未加载:", data.assetPath);
  				return;
  			}
  			this._node = Laya.Sprite3D.instantiate(res);
  			if (data.parent) {
  				let parentNode = this.track.director.findChildPath(data.parent);
  				if (!parentNode) {
  					this._node.destroy();
  					TimelineTools.debugLog("ControlClip.onStart: 找不到parent:", data.parent);
  					return;
  				}
  				parentNode.addChild(this._node);
  			}
  			else {
  				this.track.director.addChildToRoot(this._node);
  			}
  		}
  		else {
  			if (this._node) {
  				this._node.active = true;
  			}
  			else {
  				return;
  			}
  		}
  		TimelineTools.playParticleNode(this._node);
  		TimelineTools.debugLog("ControlClip.start ", this._node.name);
  	}
  	onEnd() {
  		if (this.controlType == ControlType.Resource) {
  			if (this._node) {
  				TimelineTools.debugLog("ControlClip.end ", this._node.name);
  				this._node.destroy();
  				this._node = null;
  			}
  		}
  		else {
  			if (this._node) {
  				TimelineTools.debugLog("ControlClip.end ", this._node.name);
  				TimelineTools.stopParticleNode(this._node);
  				this._node.active = false;
  			}
  		}
  	}
  	onLoopStart() {
  	}
  	onJumpTo(bCrossAnim) {
  	}
  }

  class ControlTrack extends TrackBase {
  	getClipInfo() {
  		return { clipClass: ControlClip, clipList: this.data.clipList };
  	}
  }

  class PlayableDirector extends Laya.Sprite3D {
  	constructor() {
  		super(...arguments);
  		this.elapsedTime = 0;
  		this.endTime = 0;
  		this.stopUpdateOnlyWhenFinish = false;
  		this.loopStartFrame = -1;
  		this.loopEndFrame = -1;
  		this.trackList = [];
  	}
  	destroy(destoryChild) {
  		if (this.trackList) {
  			for (let i = 0; i < this.trackList.length; i++) {
  				this.trackList[i].dispose();
  			}
  			this.trackList = null;
  		}
  		this.timelineAsset = null;
  		if (this.timelineModel) {
  			this.timelineModel.destroy();
  			this.timelineModel = null;
  		}
  		super.destroy(destoryChild);
  	}
  	load(timelineAssetUrl, callback) {
  		if (!timelineAssetUrl) {
  			console.error("load: timelineAssetUrl不能为空!");
  			return;
  		}
  		Laya.loader.load(timelineAssetUrl, Laya.Handler.create(this, this.onTimelineDataLoaded, [timelineAssetUrl, callback]), null, Laya.Loader.JSON);
  	}
  	onTimelineDataLoaded(timelineAssetUrl, callback) {
  		if (this.destroyed)
  			return;
  		let timelineAsset = Laya.loader.getRes(timelineAssetUrl);
  		Laya.Sprite3D.load(timelineAsset.modelUrl, Laya.Handler.create(this, this.onModelLoaded, [timelineAsset, callback]));
  	}
  	onModelLoaded(timelineAsset, callback) {
  		if (this.destroyed)
  			return;
  		let timelineModel = Laya.Sprite3D.instantiate(Laya.loader.getRes(timelineAsset.modelUrl));
  		this.init(timelineAsset, timelineModel);
  		let resList = this.getDepRes();
  		Laya.loader.create(resList, Laya.Handler.create(this, () => {
  			if (this.destroyed)
  				return;
  			this.event("LOADED");
  			callback && callback();
  		}));
  	}
  	init(timelineAsset, timelineModel) {
  		if (this.destroyed)
  			return;
  		if (this.timelineAsset) {
  			console.error("PlayableDirector.createTracks: 重复加载");
  		}
  		this.timelineAsset = timelineAsset;
  		this.timelineModel = timelineModel;
  		if (!timelineAsset || !timelineModel) {
  			console.error("PlayableDirector.createTracks：资源加载异常.");
  			return;
  		}
  		this.addChild(timelineModel);
  		this.fps = timelineAsset.fps;
  		this.version = timelineAsset.version;
  		this.calclEndTime();
  		this.createTrack(CinemachineTrack, timelineAsset.cinemachineTrackList);
  		this.createTrack(ControlTrack, timelineAsset.controlTrackList);
  		this.createTrack(ActivationTrack, timelineAsset.activationTrackList);
  		this.createTrack(AnimationTrack, timelineAsset.animationTrackList);
  	}
  	calclEndTime() {
  		let maxTime = 0;
  		function getMaxTime(list) {
  			if (!list)
  				return;
  			for (var i = 0; i < list.length; i++) {
  				maxTime = Math.max(maxTime, list[i].end);
  			}
  		}
  		let data = this.timelineAsset;
  		for (let i = 0; i < data.animationTrackList.length; i++) {
  			getMaxTime(data.animationTrackList[i].clipList);
  		}
  		for (let i = 0; i < data.cinemachineTrackList.length; i++) {
  			getMaxTime(data.cinemachineTrackList[i].clipList);
  		}
  		for (let i = 0; i < data.controlTrackList.length; i++) {
  			getMaxTime(data.controlTrackList[i].clipList);
  		}
  		for (let i = 0; i < data.activationTrackList.length; i++) {
  			getMaxTime(data.activationTrackList[i].clipList);
  		}
  		this.endTime = maxTime;
  	}
  	createTrack(trackClass, dataList) {
  		for (let i = 0; i < dataList.length; i++) {
  			let data = dataList[i];
  			let track = new trackClass(this, data);
  			track.createClip();
  			track.reset();
  			this.trackList.push(track);
  		}
  	}
  	getDepRes() {
  		if (!this.timelineAsset) {
  			console.warn("PlayableDirector.getDepRes: 资源还未加载");
  			return [];
  		}
  		let resList = [];
  		for (var i = 0; i < this.timelineAsset.animationTrackList.length; i++) {
  			let item = this.timelineAsset.animationTrackList[i];
  			for (var j = 0; j < item.clipList.length; j++) {
  				let clip = item.clipList[j];
  				if (clip.assetPath) {
  					resList.push({ url: clip.assetPath, type: Laya.Loader.ANIMATIONCLIP });
  				}
  			}
  		}
  		for (var i = 0; i < this.timelineAsset.controlTrackList.length; i++) {
  			let item = this.timelineAsset.controlTrackList[i];
  			for (var j = 0; j < item.clipList.length; j++) {
  				let clip = item.clipList[j];
  				if (clip.assetPath) {
  					resList.push({ url: clip.assetPath, type: Laya.Loader.HIERARCHY });
  				}
  			}
  		}
  		return resList;
  	}
  	addChildToRoot(child) {
  		if (this.timelineModel) {
  			this.timelineModel.addChild(child);
  		}
  	}
  	findChildPath(childPath) {
  		return TimelineTools.findChildPath(this.timelineModel, childPath);
  	}
  	getChildPath(child, root) {
  		if (root == child)
  			return "";
  		root = root || this.timelineModel;
  		if (!root)
  			return null;
  		var path = child.name;
  		var parent = child.parent;
  		while (parent != root) {
  			if (!parent) {
  				console.error("getChildPath 节点不在根节点上.");
  				return null;
  			}
  			else {
  				path = parent.name + "/" + path;
  				parent = parent.parent;
  			}
  		}
  		return path;
  	}
  	findChild(childName) {
  		return TimelineTools.findChild(this.timelineModel, childName);
  	}
  	getGenericBinding(trackName) {
  		for (let i = 0; i < this.trackList.length; i++) {
  			if (this.trackList[i].name == trackName) {
  				return this.trackList[i].bindObject;
  			}
  		}
  	}
  	setGenericBinding(trackName, obj) {
  		for (let i = 0; i < this.trackList.length; i++) {
  			if (this.trackList[i].name == trackName) {
  				this.trackList[i].genericBinding(obj);
  			}
  		}
  	}
  	getTrack(trackType) {
  		let arr = [];
  		for (let i = 0; i < this.trackList.length; i++) {
  			if (this.trackList[i] instanceof trackType) {
  				arr.push(this.trackList[i]);
  			}
  		}
  		return arr;
  	}
  	replaceNode(nodePath, newNode, destroyOld) {
  		let oldNode = this.findChildPath(nodePath);
  		if (!oldNode) {
  			console.error("changeNode 找不到替换节点:", nodePath);
  			return;
  		}
  		function isParent(child, parent) {
  			if (!child || !child.parent)
  				return false;
  			if (child.parent == parent)
  				return true;
  			return isParent(child.parent, parent);
  		}
  		let allBindObjInfo = [];
  		for (let i = 0; i < this.trackList.length; i++) {
  			let bindObj = this.trackList[i].bindObject;
  			if (bindObj) {
  				let node;
  				if (bindObj instanceof Laya.Animator) {
  					node = bindObj.owner;
  				}
  				else {
  					node = bindObj;
  				}
  				if (isParent(node, oldNode)) {
  					let parentPath = this.getChildPath(node.parent, oldNode);
  					let nodePath = parentPath + "/" + node.name;
  					if (!parentPath || parentPath.length == 0) {
  						nodePath = node.name;
  					}
  					allBindObjInfo.push({ parentPath: parentPath, nodePath: nodePath, node: node });
  				}
  			}
  		}
  		for (let i = allBindObjInfo.length - 1; i >= 0; i--) {
  			if (TimelineTools.findChildPath(newNode, allBindObjInfo[i].nodePath)) {
  				TimelineTools.debugLog("发现相同的节点:", allBindObjInfo[i].nodePath);
  				allBindObjInfo.splice(i, 1);
  			}
  		}
  		for (let i = allBindObjInfo.length - 1; i >= 0; i--) {
  			let child = allBindObjInfo[i];
  			for (let j = allBindObjInfo.length - 1; j >= 0; j--) {
  				if (i == j)
  					continue;
  				let parent = allBindObjInfo[j];
  				if (~child.nodePath.indexOf(parent.nodePath)) {
  					TimelineTools.debugLog("发现子节点", child.nodePath);
  					allBindObjInfo.splice(i, 1);
  					break;
  				}
  			}
  		}
  		for (let i = 0; i < allBindObjInfo.length; i++) {
  			let parent = TimelineTools.findChildPath(newNode, allBindObjInfo[i].parentPath);
  			if (parent) {
  				allBindObjInfo[i].newParent = parent;
  			}
  			else {
  				console.error("changeNode 找不到节点:", allBindObjInfo[i].parentPath);
  				return;
  			}
  		}
  		newNode.name = oldNode.name;
  		function moveNode(node, newParent) {
  			let idx = node.parent.getChildIndex(node);
  			newParent.addChildAt(node, idx);
  		}
  		oldNode.parent.addChildAt(newNode, oldNode.parent.getChildIndex(oldNode));
  		newNode.transform.position = oldNode.transform.position;
  		oldNode.removeSelf();
  		for (let i = 0; i < allBindObjInfo.length; i++) {
  			moveNode(allBindObjInfo[i].node, allBindObjInfo[i].newParent);
  		}
  		if (destroyOld)
  			oldNode.destroy();
  		this.reset();
  		return allBindObjInfo;
  	}
  	play() {
  		if (!this.timelineAsset) {
  			console.error("PlayableDirector.start: 资源尚未加载.");
  			return;
  		}
  		this.elapsedTime = 0;
  		this.reset();
  		this.update();
  		Laya.timer.frameLoop(1, this, this.update, null, true);
  		this.event("START");
  		TimelineTools.debugLog("PlayableDirector.play");
  	}
  	reset() {
  		for (let i = 0; i < this.trackList.length; i++) {
  			this.trackList[i].reset();
  		}
  	}
  	update() {
  		let deltaTime = Laya.timer.delta / 1000;
  		this.elapsedTime += deltaTime;
  		if (this.elapsedTime >= this.endTime) {
  			if (this.stopUpdateOnlyWhenFinish) {
  				this.clearTime();
  				this.event("STOPPED");
  				return;
  			}
  		}
  		if (this.loopEndFrame > 0) {
  			if (this.elapsedTime >= TimelineTools.roundFloat(this.loopEndFrame / this.fps)) {
  				this.elapsedTime = TimelineTools.roundFloat(this.loopStartFrame / this.fps);
  				let list = this.trackList;
  				for (let i = 0; i < list.length; i++) {
  					let track = list[i];
  					track.loopStart(this.elapsedTime);
  				}
  				this.event("LOOP_START");
  			}
  		}
  		this.updateTrack(false, false);
  	}
  	updateTrack(isJump, bCrossAnim) {
  		let list = this.trackList || [];
  		for (let i = 0; i < list.length; i++) {
  			let track = list[i];
  			track.update(this.elapsedTime, isJump, bCrossAnim);
  		}
  		if (this.elapsedTime >= this.endTime) {
  			this.stop();
  		}
  	}
  	stop() {
  		this.clearTime();
  		for (let i = 0; i < this.trackList.length; i++) {
  			this.trackList[i].stop();
  		}
  		this.event("STOPPED");
  		TimelineTools.debugLog("PlayableDirector.stop");
  	}
  	clearTime() {
  		Laya.timer.clearAll(this);
  	}
  	pause() {
  	}
  	setLoopFrame(startFrame, endFrame) {
  		if (startFrame < 0) {
  			console.error("PlayableDirector.setLoop: startFrame < 0!");
  			return;
  		}
  		if (endFrame <= startFrame) {
  			console.error("PlayableDirector.setLoop: endFrame <= startFrame!");
  			return;
  		}
  		this.loopStartFrame = startFrame;
  		this.loopEndFrame = endFrame;
  	}
  	jumpTo(frame, bCrossAnim = true) {
  		this.loopStartFrame = -1;
  		this.loopEndFrame = -1;
  		this.elapsedTime = TimelineTools.roundFloat(frame / this.fps);
  		this.updateTrack(true, bCrossAnim);
  	}
  	createLight(lightColor) {
  		let tracks = this.getTrack(CinemachineTrack);
  		for (let i = 0; i < tracks.length; i++) {
  			let track = tracks[i];
  			let clips = track.clips;
  			for (let i = 0; i < clips.length; i++) {
  				let camera = clips[i].camera;
  				if (camera) {
  					let light = camera.getChildByName("auto_create_light");
  					if (light) {
  						console.warn("PlayableDirector.createLight：灯光已存在.");
  					}
  					else {
  						light = camera.addChild(new Laya.DirectionLight());
  						light.name = "auto_create_light";
  					}
  					light.color = lightColor || new Laya.Vector3(1, 1, 1);
  				}
  			}
  		}
  	}
  }

  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 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 time() {
  		return Date.now() / 1000;
  	}
  	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);
  		time -= hour * 3600;
  		let minute = Math.floor(time / 60) % 60;
  		let second = Math.ceil(time) % 60;
  		let result = "";
  		if (hour > 0) {
  			if (hour > 9) {
  				result = `${hour}:`;
  			}
  			else {
  				result = `0${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 random(min, max) {
  		if (min == null && max == null) {
  			return Math.random();
  		}
  		else if (max == null) {
  			if (min == 0) {
  				return 0;
  			}
  			return Math.floor(Math.random() * min + 1);
  		}
  		else if (min == max) {
  			return min;
  		}
  		else {
  			return Math.floor(Math.random() * (max - min + 1) + min);
  		}
  	}
  	static randomGetListArr(min, max, count) {
  		let offset = max - min;
  		let useCount = Math.min(offset, count || offset);
  		if (useCount <= 0) {
  			return [];
  		}
  		let dict = {};
  		let maxRanCount = Math.min(useCount * 10, 10000);
  		let ranCount = 0;
  		let validCount = 0;
  		while (ranCount < maxRanCount) {
  			ranCount += 1;
  			let value = Tools.random(min, max);
  			if (!dict[value]) {
  				validCount += 1;
  				dict[value] = ranCount;
  				if (validCount == count) {
  					break;
  				}
  			}
  		}
  		let arr = [];
  		for (let k in dict) {
  			arr.push({ value: parseInt(k), order: dict[k] });
  		}
  		arr = Tools.sortArrayByField(arr, "order");
  		let retArr = [];
  		for (let i = 0; i < arr.length; i++) {
  			retArr.push(arr[i].value);
  		}
  		return retArr;
  	}
  	static randomGotOneArrayData(arr) {
  		let data = this.randomGotArrayDatas(arr, 1) || [];
  		return data[0];
  	}
  	static randomGotArrayDatas(arr, expectNum) {
  		if (!arr || arr.length <= 0 || !expectNum || expectNum <= 0) {
  			return [];
  		}
  		let newArr = [];
  		expectNum = Math.min(expectNum, arr.length);
  		let indexArr = [];
  		for (let i = 0; i < arr.length; i++) {
  			indexArr.push(i);
  		}
  		let gotNum = 0;
  		while (gotNum < expectNum) {
  			let index = Tools.random(0, indexArr.length - 1);
  			let indexValue = indexArr[index];
  			let data = arr[indexValue];
  			newArr.push(data);
  			indexArr.splice(index, 1);
  			gotNum += 1;
  		}
  		return newArr;
  	}
  	static randomRemoveArrayDatas(arr, expectNum) {
  		if (!arr || arr.length <= 0 || !expectNum || expectNum < 0) {
  			return [];
  		}
  		let newArr = [];
  		if (expectNum >= arr.length) {
  			let count = arr.length;
  			for (let index = (count - 1); index >= 0; index--) {
  				newArr.push(arr[index]);
  				arr.splice(index, 1);
  			}
  			return newArr;
  		}
  		let indexArr = [];
  		for (let i = 0; i < arr.length; i++) {
  			indexArr.push(i);
  		}
  		let removeIndexArr = [];
  		let gotNum = 0;
  		while (gotNum < expectNum) {
  			let index = Tools.random(0, indexArr.length - 1);
  			let indexValue = indexArr[index];
  			let data = arr[indexValue];
  			newArr.push(data);
  			indexArr.splice(index, 1);
  			removeIndexArr.push({ index: indexValue });
  			gotNum += 1;
  		}
  		if (gotNum > 0) {
  			removeIndexArr = this.sortArrayByField(removeIndexArr, "-index");
  			for (let tmp = 0; tmp < gotNum; tmp++) {
  				let data = removeIndexArr[tmp];
  				arr.splice(data.index, 1);
  			}
  		}
  		return newArr;
  	}
  	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, length) {
  		if (src.length < srcPos + length)
  			throw "arrayCopy: src out of bound";
  		if (dest.length < destPos + length)
  			throw "arrayCopy: dest out of bound";
  		for (let i = 0; i < length; 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 getBigNumberStr(count, step = 4) {
  		let unitStr3 = ["", "K", "M", "B", "T", "AA", "AB", "AC", "AD", "AE", "AF", "AG", "AH"];
  		let unitStr4 = ["", "万", "亿", "兆", "京", "垓", "杼", "穰", "沟", "涧", "正", "载"];
  		let factor = step == 3 ? 1000 : 10000;
  		let unitStr = step == 3 ? unitStr3 : unitStr4;
  		let order = 0;
  		let _tempCount = count;
  		while (_tempCount > factor) {
  			order++;
  			_tempCount /= factor;
  		}
  		return `${order == 0 ? _tempCount : _tempCount.toFixed(1)}${unitStr[order]}`;
  	}
  	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 findSkinnedMeshSprite3d(node) {
  		for (let i = 0; i < node.numChildren; i++) {
  			let child = node.getChildAt(i);
  			if (child instanceof Laya.SkinnedMeshSprite3D) {
  				return child;
  			}
  		}
  		for (let i = 0; i < node.numChildren; i++) {
  			let child = node.getChildAt(i);
  			let re = this.findSkinnedMeshSprite3d(child);
  			if (re)
  				return re;
  		}
  	}
  	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 findMeshSprite3d(node) {
  		for (let i = 0; i < node.numChildren; i++) {
  			let child = node.getChildAt(i);
  			if (child instanceof Laya.MeshSprite3D) {
  				return child;
  			}
  		}
  		for (let i = 0; i < node.numChildren; i++) {
  			let child = node.getChildAt(i);
  			let re = this.findMeshSprite3d(child);
  			if (re)
  				return re;
  		}
  	}
  	static findCamera(node) {
  		for (let i = 0; i < node.numChildren; i++) {
  			let child = node.getChildAt(i);
  			if (child instanceof Laya.Camera && child.active == true) {
  				return child;
  			}
  		}
  		for (let i = 0; i < node.numChildren; i++) {
  			let child = node.getChildAt(i);
  			let re = this.findCamera(child);
  			if (re)
  				return re;
  		}
  	}
  	static findCameras(node, cameras = []) {
  		for (let i = 0; i < node.numChildren; i++) {
  			let child = node.getChildAt(i);
  			if (child instanceof Laya.Camera) {
  				cameras.push(child);
  			}
  		}
  		for (let i = 0; i < node.numChildren; i++) {
  			let child = node.getChildAt(i);
  			this.findCameras(child, cameras);
  		}
  		return cameras;
  	}
  	static findAllRenderers(node) {
  		let out = [];
  		this.__findAllRenderers(node, out, node);
  		return out;
  	}
  	static __findAllRenderers(node, out, root) {
  		let render = node["_render"];
  		if (render && !(node instanceof Laya.ShuriKenParticle3D)) {
  			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 findNodeReg(nodeName, root) {
  		let reg = new RegExp(nodeName);
  		if (reg.test(root.name)) {
  			return root;
  		}
  		for (let i = 0; i < root.numChildren; i++) {
  			let child = root.getChildAt(i);
  			if (reg.test(child.name))
  				return child;
  			else {
  				let node = this.findNodeReg(nodeName, child);
  				if (node)
  					return node;
  			}
  		}
  		return null;
  	}
  	static findAllNodeReg(nodeName, root, nodes) {
  		nodes = nodes || [];
  		let reg = new RegExp(nodeName);
  		if (reg.test(root.name)) {
  			nodes.push(root);
  		}
  		for (let i = 0; i < root.numChildren; i++) {
  			let child = root.getChildAt(i);
  			if (reg.test(child.name)) {
  				nodes.push(child);
  			}
  			else {
  				this.findAllNodeReg(nodeName, child, nodes);
  			}
  		}
  		return nodes;
  	}
  	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 findChildByPath(node, path) {
  		let names = path.split('/');
  		for (let name of names) {
  			node = node.getChildByName(name);
  			if (!node)
  				return null;
  		}
  		return node;
  	}
  	static findChildByName(root, name) {
  		if (root.name == name)
  			return root;
  		for (let i = 0; i < root.numChildren; i++) {
  			let child = root.getChildAt(i);
  			let node = this.findChildByName(child, name);
  			if (node) {
  				return node;
  			}
  		}
  		return null;
  	}
  	static findChildsByName(root, rep, out) {
  		if ((new RegExp(rep, "img")).test(root.name)) {
  			out.push(root);
  		}
  		for (let i = 0; i < root.numChildren; i++) {
  			let child = root.getChildAt(i);
  			this.findChildsByName(child, rep, out);
  		}
  	}
  	static loadImg(sp, path, bAdaptTextureSize = false, callback) {
  		if (!sp) {
  			return;
  		}
  		;
  		if (!path) {
  			return;
  		}
  		;
  		ResLoader.loadRes(path, Laya.Loader.IMAGE, (texture) => {
  			if (sp.destroyed)
  				return;
  			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 tranlateWorld3D2Screen(camera, worldPos) {
  		if (!camera) {
  			return {
  				bSuccessful: false,
  				outPos: null
  			};
  		}
  		let outPos = new Laya.Vector4();
  		let inputPos = worldPos.clone();
  		camera.viewport.project(inputPos, camera.projectionViewMatrix, outPos);
  		outPos.x /= Laya.stage.clientScaleX;
  		outPos.y /= Laya.stage.clientScaleY;
  		return {
  			bSuccessful: true,
  			outPos: outPos,
  		};
  	}
  	static castRayFromScreenPos(scene, camera, screenPos, outray) {
  		let ray = null;
  		if (!!outray) {
  			ray = outray;
  		}
  		else {
  			ray = new Laya.Ray(new Laya.Vector3(0, 0, 10), new Laya.Vector3(0, 0, -1000));
  		}
  		screenPos.x *= Laya.stage.clientScaleX;
  		screenPos.y *= Laya.stage.clientScaleY;
  		camera.viewportPointToRay(screenPos, ray);
  		let outHitResult = new Laya.CannonHitResult;
  		scene.cannonPhysicsSimulation.rayCast(ray, outHitResult);
  		return outHitResult;
  	}
  	static createRayFromScreenPos(camera, screenPos, outray) {
  		screenPos = screenPos.clone();
  		let ray = null;
  		if (!!outray) {
  			ray = outray;
  		}
  		else {
  			ray = new Laya.Ray(new Laya.Vector3(0, 0, 10), new Laya.Vector3(0, 0, -1000));
  		}
  		screenPos.x *= Laya.stage.clientScaleX;
  		screenPos.y *= Laya.stage.clientScaleY;
  		camera.viewportPointToRay(screenPos, ray);
  		return ray;
  	}
  	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 backward(transform, pos) {
  		transform.lookAt(pos, 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 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 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 getAngle(x1, y1, x2 = 0, y2 = 0) {
  		var x = x1 - x2;
  		var y = y1 - y2;
  		var z = Math.abs(Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)));
  		var cos = y / z;
  		var radina = Math.acos(cos);
  		var angle = 180 / (Math.PI / radina);
  		if (x < 0) {
  			angle = -angle;
  		}
  		return angle;
  	}
  	static rotateCirclePoint(r, point, diffRot) {
  		let cRot = Math.atan(point.y / point.x);
  	}
  	static getCircleBorderPosPointArr(centerPos, radius, span = 2) {
  		let points = [];
  		for (let i = 0; i < 360; i += span) {
  			points.push(this.getCircleBorderPosPoint(centerPos, radius, i));
  		}
  		return points;
  	}
  	static getCircleBorderPosPoint(centerPos, radius, rot) {
  		Math.acosh;
  		let x = centerPos.x + radius * Math.cos(rot * Math.PI / 180);
  		let y = centerPos.y + radius * Math.sin(rot * Math.PI / 180);
  		return new Laya.Point(x, y);
  	}
  	static getRotByCenterPosRAndPosY(centerPos, r, borderPosValue) {
  		let rot = Math.asin((borderPosValue - centerPos.y) / r) / (Math.PI / 180);
  		return rot;
  	}
  	static getRotByCenterPosRAndPosX(centerPos, r, borderPosValue) {
  		let rot = Math.asin((borderPosValue - centerPos.x) / r) / (Math.PI / 180);
  		return rot;
  	}
  	static getBezierPoint(points, t, out) {
  		let path = new Laya.Bezier().getBezierPoints(points, 5, 2);
  		if (path.length == 0) {
  			return;
  		}
  		t = this.clamp01(t);
  		if (out == null) {
  			out = new Laya.Point(0, 0);
  		}
  		if (t == 0) {
  			out.setTo(path[0], path[1]);
  		}
  		else if (t == 1) {
  			out.setTo(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 = Laya.MathUtil.lerp(path[min * 2], path[max * 2], value - min);
  				out.y = Laya.MathUtil.lerp(path[min * 2 + 1], path[max * 2 + 1], value - min);
  			}
  			else {
  				out.setTo(path[max * 2], path[max * 2 + 1]);
  			}
  		}
  		return out;
  	}
  	static isInScreen(camera, inPos) {
  		let outPos = this.tranlateWorld3D2Screen(camera, inPos).outPos;
  		if (outPos.x > 0
  			&& outPos.x < Laya.stage.width / Laya.stage.clientScaleX
  			&& outPos.y > 0
  			&& outPos.y < Laya.stage.height / Laya.stage.clientScaleY)
  			return true;
  		else
  			return false;
  	}
  	static randomArray(arr) {
  		let newArr = [];
  		while (arr.length > 0) {
  			let index = Mathf.random(0, arr.length - 1);
  			newArr.push(arr[index]);
  			arr.splice(index, 1);
  		}
  		return newArr;
  	}
  	static layoutH(node, space = 8, anchor = 0.5, bWithScale = true) {
  		let totalWidth = 0;
  		let count = 0;
  		for (let index = 0; index < node["_children"].length; index++) {
  			const element = node["_children"][index];
  			if (element.visible) {
  				totalWidth += element.width * (bWithScale ? element.scaleX : 1);
  				count++;
  			}
  		}
  		totalWidth += (count - 1) * space;
  		let offset = node.width * anchor;
  		if (anchor > 1) {
  			offset = anchor;
  		}
  		if (anchor == 0.5) {
  			offset -= totalWidth / 2;
  		}
  		let cursor = offset;
  		for (let index = 0; index < node["_children"].length; index++) {
  			const element = node["_children"][index];
  			if (element.visible) {
  				cursor += element.pivotX * (bWithScale ? element.scaleX : 1);
  				element.x = cursor;
  				cursor += (element.width - element.pivotX) * (bWithScale ? element.scaleX : 1) + space;
  			}
  		}
  	}
  	static layoutHFGUI(node, space = 3, anchor = 0.5, bWithScale = true) {
  		let totalWidth = 0;
  		let count = 0;
  		for (let index = 0; index < node["_children"].length; index++) {
  			const element = node["_children"][index];
  			if (element.visible) {
  				totalWidth += element.width * (bWithScale ? element.scaleX : 1);
  				count++;
  			}
  		}
  		totalWidth += (count - 1) * space;
  		let offset = node.width * anchor;
  		if (anchor > 1) {
  			offset = anchor;
  		}
  		if (anchor == 0.5) {
  			offset -= totalWidth / 2;
  		}
  		let cursor = offset;
  		for (let index = 0; index < node["_children"].length; index++) {
  			const element = node["_children"][index];
  			if (element.visible) {
  				cursor += element.pivotX * element.width * (bWithScale ? element.scaleX : 1);
  				element.x = cursor;
  				cursor += (element.width - element.pivotX * element.width) * (bWithScale ? element.scaleX : 1) + space;
  			}
  		}
  	}
  	static layoutV(node, space = 8, anchor = 0.5) {
  		let totalHeight = 0;
  		let count = 0;
  		for (let index = 0; index < node["_children"].length; index++) {
  			const element = node["_children"][index];
  			if (element.visible) {
  				totalHeight += element.height * element.scaleY;
  				count++;
  			}
  		}
  		totalHeight += (count - 1) * space;
  		let offset = node.height * anchor;
  		if (anchor > 1) {
  			offset = anchor;
  		}
  		if (anchor == 0.5) {
  			offset -= totalHeight / 2;
  		}
  		let cursor = offset;
  		for (let index = 0; index < node["_children"].length; index++) {
  			const element = node["_children"][index];
  			if (element.visible) {
  				cursor += element.pivotY * element.scaleY;
  				element.y = cursor;
  				cursor += (element.height - element.pivotY) * element.scaleY + space;
  			}
  		}
  	}
  	static equal(a, b) {
  		if (a === b)
  			return true;
  		let typeA = this.getType(a);
  		let typeB = this.getType(b);
  		if (typeA != typeB)
  			return false;
  		if (typeA == `object` || typeA == `array`) {
  			if (typeA == `array`) {
  				let bEqual = true;
  				for (let i = 0; i < a.length; i++) {
  					const ea = a[i];
  					const eb = b[i];
  					if (!this.equal(ea, eb)) {
  						bEqual = false;
  					}
  				}
  				return bEqual;
  			}
  			else {
  				let bEqual = true;
  				for (const k in a) {
  					const ea = a[k];
  					const eb = b[k];
  					if (!this.equal(ea, eb)) {
  						bEqual = false;
  					}
  				}
  				return bEqual;
  			}
  		}
  		else {
  			return a === b;
  		}
  	}
  	static setWorldLossyScale(node, scaleX, scaleY, scaleZ) {
  		node.transform.setWorldLossyScale(new Laya.Vector3(scaleX, scaleY, scaleZ));
  		for (let i = 0; i < node.numChildren; i++) {
  			let child = node.getChildAt(i);
  			this.setWorldLossyScale(child, scaleX, scaleY, scaleZ);
  		}
  	}
  	static takeAPhoto(width, height, camera, callback) {
  		let renderTexture = new Laya.RenderTexture(width, height, Laya.RenderTextureFormat.R8G8B8A8);
  		let oldRenderTexture = camera.renderTarget;
  		camera.renderTarget = renderTexture;
  		let oldRender = camera.render.bind(camera);
  		camera.render = (...agrs) => {
  			oldRender(...agrs);
  			camera.render = oldRender;
  			camera.renderTarget = oldRenderTexture;
  			let pixels = new Uint8Array(width * height * 4);
  			renderTexture.getData(0, 0, width, height, pixels);
  			for (let i = 0; i < height; i++) {
  				for (let j = 0; j < width; j++) {
  					let index = i * width + j;
  					let colorR = pixels[index * 4 + 1];
  					let colorG = pixels[index * 4 + 1];
  					let colorB = pixels[index * 4 + 2];
  					let colorA = pixels[index * 4 + 3];
  					if (colorR == 0 && colorG == 0 && colorB == 0 && (colorA == 0 || colorA == 255)) {
  						pixels[index * 4] = 5;
  						pixels[index * 4 + 1] = 5;
  						pixels[index * 4 + 2] = 5;
  						pixels[index * 4 + 3] = 5;
  					}
  				}
  			}
  			let tex2d = new Laya.Texture2D(width, height, undefined, false, true);
  			tex2d.setPixels(pixels);
  			callback(tex2d);
  		};
  	}
  	static drawToRtx(sprite, offsetX, offsetY, rt, ctx) {
  		offsetX -= sprite.x;
  		offsetY -= sprite.y;
  		offsetX |= 0;
  		offsetY |= 0;
  		ctx["_targets"] = rt;
  		rt.start();
  		Laya.RenderSprite.renders[sprite["_renderType"]][`_fun`](sprite, ctx, offsetX, offsetY);
  		ctx.flush();
  		rt.end();
  		rt.restore();
  		ctx["_targets"] = null;
  	}
  	static randomOne(array) {
  		if (array == null || array.length == 0)
  			return null;
  		let index = Mathf.random(0, array.length - 1);
  		return array[index];
  	}
  	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;
  	}
  	static encodeRenderTexture(renderTexture) {
  		let width = renderTexture.width;
  		let height = renderTexture.height;
  		let pixels = new Uint8Array(width * height * 4);
  		renderTexture.getData(0, 0, width, height, pixels);
  		let tex2d = new Laya.Texture2D(width, height, undefined, false, true);
  		tex2d.setPixels(pixels);
  		return this.encodeTexture(tex2d);
  	}
  	static encodeTexture(texture) {
  		let pixels = texture.getPixels();
  		let data = this.compressArr(pixels);
  		return Base64.encodeArrayBuffer(data);
  	}
  	static decodeTexture(value, width = 576, height = 1024) {
  		let data = Base64.decodeArrayBuffer(value);
  		let pixels = this.decompressArr(new Uint8Array(data));
  		let texture2d = new Laya.Texture2D(width, height, undefined, false);
  		texture2d.setPixels(pixels);
  		return texture2d;
  	}
  	static createTimelineDirector(jsonPath, callback) {
  		let director = new PlayableDirector();
  		director.load(jsonPath, () => {
  			callback && callback(director);
  		});
  	}
  	static isContainWorldPos(parent, wPos) {
  		if (!parent || parent.destroyed)
  			return false;
  		let pos1 = parent.localToGlobal(new Laya.Point);
  		let pos2 = parent.localToGlobal(new Laya.Point(parent.width, 0));
  		let pos3 = parent.localToGlobal(new Laya.Point(0, parent.height));
  		let pos4 = parent.localToGlobal(new Laya.Point(parent.width, parent.height));
  		let minX = Math.min(pos1.x, pos2.x, pos3.x, pos4.x);
  		let maxX = Math.max(pos1.x, pos2.x, pos3.x, pos4.x);
  		let minY = Math.min(pos1.y, pos2.y, pos3.y, pos4.y);
  		let maxY = Math.max(pos1.y, pos2.y, pos3.y, pos4.y);
  		if (wPos.x > minX && wPos.x < maxX && wPos.y > minY && wPos.y < maxY) {
  			return true;
  		}
  		return false;
  	}
  	static isContainFGUI(node, globalX, globalY, bIgnoreY = false) {
  		let localPos = node.globalToLocal(globalX, globalY);
  		let startX = 0;
  		let endX = node.width;
  		let startY = 0;
  		let endY = node.height;
  		if (node.pivotAsAnchor) {
  			startX = -node.pivotX * node.width;
  			endX = +(1 - node.pivotX) * node.width;
  			startY = -node.pivotY * node.height;
  			endY = +(1 - node.pivotY) * node.height;
  		}
  		if (localPos.x > startX && localPos.x < endX
  			&& ((localPos.y > startY && localPos.y < endY) || bIgnoreY)) {
  			return true;
  		}
  		else {
  			return false;
  		}
  	}
  	static isContainSprite(node, globalX, globalY) {
  		let localPos = node.globalToLocal(new Laya.Point(globalX, globalY));
  		if (localPos.x < 0)
  			return false;
  		if (localPos.y < 0)
  			return false;
  		if (localPos.x > node.width)
  			return false;
  		if (localPos.y > node.height)
  			return false;
  		return true;
  	}
  	static setTexture2dToRepeat(texture2d) {
  		if (texture2d.wrapModeU != Laya.WarpMode.Repeat) {
  			texture2d.lock = true;
  			texture2d.wrapModeU = Laya.WarpMode.Repeat;
  			texture2d.wrapModeV = Laya.WarpMode.Repeat;
  			texture2d.filterMode = Laya.FilterMode.Bilinear;
  			texture2d.generateMipmap();
  		}
  	}
  	static setTexture2dToNotRepeat(texture2d) {
  		if (texture2d.wrapModeU == Laya.WarpMode.Repeat) {
  			texture2d.lock = true;
  			texture2d.wrapModeU = Laya.WarpMode.Clamp;
  			texture2d.wrapModeV = Laya.WarpMode.Clamp;
  			texture2d.filterMode = Laya.FilterMode.Bilinear;
  			texture2d.generateMipmap();
  		}
  	}
  	static playTranslation(node, name, endHookCallback, hookName, hook) {
  		let trans = node.getTransition(name);
  		if (!trans) {
  			console.error(`没有找到动效: ${name}`);
  			return;
  		}
  		trans.clearHooks();
  		trans.play(endHookCallback);
  		if (hook && hookName) {
  			trans.setHook(hookName, hook);
  		}
  	}
  	static playTranslationInverse(node, name, endHookCallback, hookName, hook) {
  		let trans = node.getTransition(name);
  		if (!trans) {
  			console.error(`没有找到动效: ${name}`);
  			return;
  		}
  		trans.clearHooks();
  		trans.playReverse(endHookCallback);
  		if (hook && hookName) {
  			trans.setHook(hookName, hook);
  		}
  	}
  	static getMeshRender(node) {
  		if (!node) {
  			return null;
  		}
  		return node[`skinnedMeshRenderer`] || node[`meshRenderer`];
  	}
  	static getFirstChildBone(node) {
  		if (!node || node.destroyed) {
  			return null;
  		}
  		let numChildren = node.numChildren;
  		for (let i = 0; i < numChildren; i++) {
  			let child = node.getChildAt(i);
  			if (!Tools.getMeshRender(child)) {
  				return child;
  			}
  		}
  		return null;
  	}
  	static setModelAlbedoColor(model, color) {
  		let renderer = Tools.getMeshRender(model);
  		if (renderer) {
  			let sharedMaterials = renderer.sharedMaterials;
  			sharedMaterials[0].albedoColor = new Laya.Vector4(color.r, color.g, color.b, 1);
  		}
  		else {
  			for (let i = 0; i < model.numChildren; i++) {
  				let child = model.getChildAt(i);
  				let renderer = Tools.getMeshRender(child);
  				if (renderer) {
  					let sharedMaterials = renderer.sharedMaterials;
  					sharedMaterials[0].albedoColor = new Laya.Vector4(color.r, color.g, color.b, 1);
  				}
  			}
  		}
  	}
  	static createPureColorTexture(color) {
  		let pixels = new Uint8Array(16);
  		for (let i = 0; i < 4; i++) {
  			pixels[i * 4 + 0] = color.r * 255;
  			pixels[i * 4 + 1] = color.g * 255;
  			pixels[i * 4 + 2] = color.b * 255;
  			pixels[i * 4 + 3] = color.a * 255;
  		}
  		let tex2d = new Laya.Texture2D(2, 2, Laya.TextureFormat.R8G8B8A8);
  		tex2d.setPixels(pixels);
  		let texture = new Laya.Texture(tex2d);
  		return texture;
  	}
  	static cameraForSaveImg(camera, saveImgName) {
  		Tools.takeAPhoto(768, 1280, camera, (tex2d) => {
  			let pixels = tex2d.getPixels();
  			this.downloadCameraForSaveImg(pixels, saveImgName);
  		});
  	}
  	static downloadCameraForSaveImg(pixels, saveImgName) {
  		saveImgName = saveImgName || "icon.png";
  		let canvasId = "__test_download_camera_for_save_canvas";
  		let linkId = "__test_download_camera_for_save_link";
  		let doDownload = () => {
  			var targetPx = new Uint8ClampedArray(pixels);
  			var ctx = newCanvas.getContext("2d");
  			var imageData = ctx.getImageData(0, 0, newCanvas.width, newCanvas.height);
  			var px = imageData.data;
  			for (var i = 0; i < px.length; i += 4) {
  				px[i] = targetPx[i];
  				px[i + 1] = targetPx[i + 1];
  				px[i + 2] = targetPx[i + 2];
  				px[i + 3] = targetPx[i + 3];
  			}
  			ctx.putImageData(imageData, 0, 0);
  			if (document.getElementById(linkId)) {
  				document.removeChild(document.getElementById(linkId));
  			}
  			var dataUri = newCanvas.toDataURL("image/png");
  			var link = document.createElement('a');
  			link.id = "";
  			link.href = dataUri;
  			link.download = saveImgName;
  			link.click();
  		};
  		var newCanvas = document.getElementById(canvasId);
  		if (!!newCanvas) {
  			doDownload();
  		}
  		else {
  			newCanvas = document.createElement("canvas");
  			newCanvas.id = canvasId;
  			var image = new Image();
  			image.crossOrigin = "Anonymous";
  			image.onload = function () {
  				newCanvas.width = image.width;
  				newCanvas.height = image.height;
  				newCanvas.getContext("2d").drawImage(image, 0, 0, image.width, image.height);
  				doDownload();
  			};
  			let index = window.location.href.indexOf("index.html");
  			image.src = window.location.href.substring(0, index - 1) + "/res/ui/common/mask.png";
  			document.body.insertAdjacentElement('afterbegin', newCanvas);
  		}
  	}
  	static changeParticleSimulationSpeed(model, speed = 1) {
  		if (!model || model.destroyed) {
  			return;
  		}
  		for (var i = 0; i < model.numChildren; i++) {
  			var otherChild = model.getChildAt(i);
  			let particleSystem = otherChild["particleSystem"];
  			if (!particleSystem) {
  				continue;
  			}
  			particleSystem.simulationSpeed = speed;
  			this.changeParticleSimulationSpeed(otherChild, speed);
  		}
  	}
  	static getQuad3D() {
  		let scale = 1;
  		let textureBg = Tools.createPureColorTexture(new Laya.Color(169 / 255, 131 / 255, 1, 1));
  		let quadMeshBg = Laya.PrimitiveMesh.createQuad(scale, scale);
  		let quadBg = new Laya.MeshSprite3D(quadMeshBg);
  		let materialBg = new Laya.UnlitMaterial;
  		materialBg.renderMode = Laya.UnlitMaterial.RENDERMODE_OPAQUE;
  		materialBg.cull = Laya.RenderState.CULL_NONE;
  		materialBg.albedoTexture = textureBg.bitmap;
  		quadBg.meshRenderer.sharedMaterial = materialBg;
  		quadBg.transform.setWorldLossyScale(new Laya.Vector3(5, 5, 5));
  		return quadBg;
  	}
  	static getQuad3DByTexture(texture, scale) {
  		scale = scale || 1;
  		let quadMeshBg = Laya.PrimitiveMesh.createQuad(scale, scale);
  		let quadBg = new Laya.MeshSprite3D(quadMeshBg);
  		let tex2d = texture.bitmap;
  		if (tex2d.wrapModeU != Laya.WarpMode.Repeat) {
  			tex2d.wrapModeU = Laya.WarpMode.Repeat;
  			tex2d.wrapModeV = Laya.WarpMode.Repeat;
  			tex2d.filterMode = Laya.FilterMode.Bilinear;
  			tex2d.generateMipmap();
  		}
  		let materialBg = new Laya.UnlitMaterial;
  		materialBg.renderMode = Laya.UnlitMaterial.RENDERMODE_TRANSPARENT;
  		materialBg.cull = Laya.RenderState.CULL_NONE;
  		materialBg.albedoTexture = tex2d;
  		quadBg.meshRenderer.sharedMaterial = materialBg;
  		return quadBg;
  	}
  	static isEqualArr(array1, array2) {
  		if (!array1)
  			return false;
  		if (!array2)
  			return false;
  		if (array1.length != array2.length)
  			return false;
  		for (var i = 0, l = array1.length; i < l; i++) {
  			if (array1[i] instanceof Array && array2[i] instanceof Array) {
  				if (!Tools.isEqualArr(array1[i], array2[i]))
  					return false;
  			}
  			else if (array1[i] != array2[i]) {
  				return false;
  			}
  		}
  		return true;
  	}
  	static transparentBlackArea(pixels, sizeW, sizeH) {
  		for (let hIndex = 0; hIndex < sizeH; hIndex++) {
  			for (let wIndex = 0; wIndex < sizeW; wIndex++) {
  				let pixelsIndex = wIndex * hIndex;
  				if (pixels[pixelsIndex * 4 + 0] == 0 && pixels[pixelsIndex * 4 + 1] == 0 && pixels[pixelsIndex * 4 + 2] == 0) {
  					pixels[pixelsIndex * 4 + 0] = 0.00001;
  					pixels[pixelsIndex * 4 + 1] = 0.00001;
  					pixels[pixelsIndex * 4 + 2] = 0.00001;
  					pixels[pixelsIndex * 4 + 3] = 0.00001;
  				}
  			}
  		}
  		return pixels;
  	}
  	static CalculateCubicBezierPoint(t, p0, p1, p2) {
  		let u = 1 - t;
  		let tt = t * t;
  		let uu = u * u;
  		let p = new Laya.Vector3;
  		Laya.Vector3.scale(p0, uu, p);
  		let ptmp1 = new Laya.Vector3;
  		Laya.Vector3.scale(p1, 2 * u * t, ptmp1);
  		Laya.Vector3.add(p, ptmp1, p);
  		let ptmp2 = new Laya.Vector3;
  		Laya.Vector3.scale(p2, tt, ptmp2);
  		Laya.Vector3.add(p, ptmp2, p);
  		return p;
  	}
  	static GetBeizerList(startPoint, controlPoint, endPoint, segmentNum) {
  		segmentNum = Math.max(1, segmentNum);
  		let path = new Laya.Vector3[segmentNum];
  		for (let i = 1; i <= segmentNum; i++) {
  			let t = i / segmentNum;
  			let pixel = this.CalculateCubicBezierPoint(t, startPoint, controlPoint, endPoint);
  			path[i - 1] = pixel;
  		}
  		return path;
  	}
  }
  Tools.bigNumberStrs = ["K", "M", "G", "B", "T"];

  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;
  	}
  }

  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 || 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;

  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 = bLog;
  	}
  	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) {
  			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++) {
  				urlData.push({ url: url[i], type: type });
  			}
  		}
  		else {
  			urlData.push({ url: url, type: type });
  		}
  	}
  	addFguiPackage(resKey) {
  		this.addCall(function (resolve) {
  			fgui.UIPackage.loadPackage(resKey, new Laya.Handler(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);
  					break;
  			}
  		}
  	}
  	get isEmpty() {
  		return this.resCount == 0;
  	}
  	loadAll(caller) {
  		if (this.isLoading) {
  			return;
  		}
  		this.caller = caller;
  		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);
  				}
  				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, new Laya.Handler(this, onAllLoaded));
  						return;
  					}
  					onAllLoaded(true);
  				}
  				else {
  					onAllLoaded(false);
  				}
  			};
  			Laya.loader.load(item.url, new Laya.Handler(this, onPrefabLoaded), null, item.type);
  		}
  		else {
  			complete(true);
  		}
  	}
  	_load2d(complete, progress) {
  		if (this.urlData.d2.length > 0) {
  			Laya.loader.load(this.urlData.d2, new Laya.Handler(this, complete), new Laya.Handler(this, progress));
  		}
  		else {
  			complete(true);
  		}
  	}
  	_load3d(complete, progress) {
  		if (this.urlData.d3.length > 0) {
  			Laya.loader.create(this.urlData.d3, new Laya.Handler(this, complete), new Laya.Handler(this, progress));
  		}
  		else {
  			complete(true);
  		}
  	}
  	loadOneByOne(deltaTime = 1) {
  		if (this.isLoading) {
  			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 {
  					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) {
  		if (this.destroyed)
  			return;
  		if (!this.caller)
  			return;
  		if (this.caller.destroyed)
  			return;
  		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(this);
  		}
  		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 __init() {
  		Manager._managerInstances.push(this);
  		this.managerMap[this.name] = 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.managerMap = {};
  Manager._bNetworkResponseRegistered = false;

  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) {
  		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, () => {
  			});
  			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;

  var EditorType;
  (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 || (EditorType = {}));
  var EDITOR_MES;
  (function (EDITOR_MES) {
  })(EDITOR_MES || (EDITOR_MES = {}));

  const PBRShadowCasterVS = `
#include "ShadowCasterVS.glsl"

void main()
{
    vec4 positionCS =  shadowCasterVertex();
    gl_Position=remapGLPositionZ(positionCS);
}`;
  const PBRShadowCasterPS = `
#ifdef GL_FRAGMENT_PRECISION_HIGH
    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.paintLayer1TilingOffset = new Laya.Vector4(1, 1, 0, 0);
  		this.detailNormalTextureTillingOffset = new Laya.Vector4(1, 1, 0, 0);
  		this.smoothness = 0.0;
  		this.metallic = 0.0;
  		this.FadeColor = new Laya.Vector4;
  		this.FadeFactor = 0.0;
  		this.alphaTestValue = 0.5;
  		this.alpha = 1;
  	}
  	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_LAYER1_TEXTURE = Laya.Shader3D.getDefineByName("LAYER1_TEXTURE");
  		BagMaterial.SHADERDEFINE_LAYER2_TEXTURE = Laya.Shader3D.getDefineByName("LAYER2_TEXTURE");
  		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");
  		BagMaterial.SHADERDEFINE_GRAY = Laya.Shader3D.getDefineByName("SHADERDEFINE_GRAY");
  		BagMaterial.SHADERDEFINE_PROGRESS = Laya.Shader3D.getDefineByName("SHADERDEFINE_PROGRESS");
  		BagMaterial.SHADERDEFINE_BURN = Laya.Shader3D.getDefineByName("SHADERDEFINE_BURN");
  		BagMaterial.SHADERDEFINE_BURN_INVERST = Laya.Shader3D.getDefineByName("SHADERDEFINE_BURN_INVERST");
  		BagMaterial.SHADERDEFINE_WHITE_FACTOR = Laya.Shader3D.getDefineByName("SHADERDEFINE_WHITE_FACTOR");
  	}
  	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_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_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_PaintLayer1Texture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_PaintLayer1TilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_PaintLayer2Texture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_PaintLayer2TilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
  			"u_fade_factor": Laya.Shader3D.PERIOD_MATERIAL,
  			"u_fade_color": Laya.Shader3D.PERIOD_MATERIAL,
  			"u_FakePoints": Laya.Shader3D.PERIOD_MATERIAL,
  			"u_FakeRadius": Laya.Shader3D.PERIOD_MATERIAL,
  			"u_fakeShadowCount": Laya.Shader3D.PERIOD_MATERIAL,
  			'u_AlphaTestValue': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_Progress': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BurnTexture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BurnFactor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BurnTextureTillingOffset': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_WhiteFactor': Laya.Shader3D.PERIOD_MATERIAL,
  			'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_ViewProjection': Laya.Shader3D.PERIOD_CAMERA,
  		};
  		var BagMaterial3D = Laya.Shader3D.add("BagMaterial");
  		var subShader = new Laya.SubShader(attributeMap, uniformMap);
  		BagMaterial3D.addSubShader(subShader);
  		var vs2 = `
		#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";

		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;

		varying vec4 v_posView;

		#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;

		#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
            varying vec4 v_ShadowCoord;
        #endif
		
		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; 

			v_posView = gl_Position.xyzw;
			gl_Position.z=gl_Position.z * 2.0 - gl_Position.w;

			#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
                v_ShadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));
            #endif
		}`;
  		var ps2 = `
		#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";
		uniform DirectionLight u_SunLight;

		#ifdef SPOTLIGHT
			struct SpotLight {
				vec3 color;
				vec3 position;
				float range;
				vec3 direction;
				float spot;
			};
			uniform SpotLight u_SpotLight;
		#endif

		#ifdef ALBEDOCOLOR
			uniform vec4 u_AlbedoColor;
		#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

		#ifdef SHADERDEFINE_BURN
			uniform float u_BurnFactor;
			uniform sampler2D u_BurnTexture;
			uniform vec4 u_BurnTextureTillingOffset;
		#endif
		#ifdef SHADERDEFINE_WHITE_FACTOR
			uniform float u_WhiteFactor;
		#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;
		//双重阴影参数
		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_PaintLayer1Texture;
		uniform vec4 u_PaintLayer1TilingOffset;
		uniform sampler2D u_PaintLayer2Texture;
		uniform vec4 u_PaintLayer2TilingOffset;

		uniform float u_fade_factor;
		uniform vec4 u_fade_color;

		varying vec2 v_Texcoord0;
		varying vec3 v_Normal;
		varying vec3 v_PositionWorld;
		varying vec3 v_ViewDir;
		varying vec3 v_worldPos;
		varying vec4 v_posView;
		varying float v_viewDistance;

		#ifdef WHOLE_ALPHA
		uniform float u_alpha;
		#endif


		uniform float u_AlphaTestValue;
		uniform float u_Progress;

		#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
			varying vec4 v_ShadowCoord;
		#endif
		
		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_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 disCamera = clamp(v_viewDistance, minv, maxv);
				float scalefactor = 1.0 - (disCamera - 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(0.0);
			
			
			vec2 texcoord = vec2(v_Texcoord0.x, 1.0 - v_Texcoord0.y);
			#ifdef LAYER1_TEXTURE
				// 计算层级1的颜色
				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;
			#endif

			#ifdef LAYER2_TEXTURE
				// 计算层级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.rgba = albedoTextureColor.rgba * (1.0 - paintLayer2Color.a) + paintLayer2Color.a * paintLayer2Color.rgba;
				albedoTextureColor.rgb = albedoTextureColor.rgb * (1.0 - paintLayer2Color.a) + paintLayer2Color.rgb;
				albedoTextureColor.a = albedoTextureColor.a * (1.0 - paintLayer2Color.a) + paintLayer2Color.a;
			#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 SHADERDEFINE_PROGRESS
				float through = 0.02;
				float halfTh = through/2.0;
				float realP = v_posView.y/v_posView.w * 0.5 + 0.5;
				//是否在进度跳
				float fInP = step(realP, u_Progress - halfTh);
				float fInNP = step(u_Progress + halfTh, realP);
				float aFactor = fInNP * 0.0 + fInP * 1.0 + (1.0 - fInP)*(1.0-fInNP)*(1.0 - (realP - u_Progress + halfTh)/through);
				albedoTextureColor.a *= aFactor;
			#endif

			#ifdef SHADERDEFINE_BURN
				#ifdef SHADERDEFINE_BURN_INVERST
					//噪波图的当前值
					float value = texture2D(u_BurnTexture, TransformUV(v_Texcoord0, u_BurnTextureTillingOffset)).x;

					float disburn = distance(v_posView.xyz/v_posView.w, vec3(0.0,0.0,0.0));
					disburn += value;
					float through = 0.02;

					float inMaxRange = step(disburn , u_BurnFactor + through*2.0);
					float outSecondRange = step(u_BurnFactor + through, disburn);
					float inFirst = inMaxRange * outSecondRange;
					
					float inSencondRange = step(disburn, u_BurnFactor + through);
					float outThirdRange = step(u_BurnFactor, disburn);
					float inSecond = inSencondRange * outThirdRange;

					float inThird = step(disburn, u_BurnFactor);
					float inFourth = (1.0 - inFirst) * (1.0 - inSecond) * (1.0 - inThird);

					vec4 outColor = vec4(236.0/255.0, 131.0/255.0, 255.0/255.0, albedoTextureColor.a);
					vec4 secondColor = vec4(245.0/255.0, 228.0/255.0, 255.0/255.0, albedoTextureColor.a);
					vec4 thirdColor = albedoTextureColor.rgba;
					vec4 forthColor = vec4(0.0,0.0,0.0,0.0);

					albedoTextureColor = outColor*inFirst + secondColor*inSecond + inThird * thirdColor + forthColor * inFourth;

					// if(disburn < u_BurnFactor + through*2.0 && disburn >= u_BurnFactor + through){
					// 	albedoTextureColor.a = albedoTextureColor.a;
					// 	albedoTextureColor.rgb = vec3(236.0/255.0, 131.0/255.0, 255.0/255.0);
					// }
					// else if(disburn < u_BurnFactor + through && disburn >= u_BurnFactor){
					// 	albedoTextureColor.a = albedoTextureColor.a;
					// 	albedoTextureColor.rgb = vec3(245.0/255.0, 228.0/255.0, 255.0/255.0);
					// }
					// else if(disburn > u_BurnFactor){
					// 	albedoTextureColor.a = 0.0;
					// }
					// else{
					// 	albedoTextureColor.a = albedoTextureColor.a;
					// }
				#else
					//噪波图的当前值
					float value = texture2D(u_BurnTexture, TransformUV(v_Texcoord0, u_BurnTextureTillingOffset)).x;

					float disburn = distance(v_posView.xyz/v_posView.w, vec3(0.0,0.0,0.0));
					disburn += value;
					float through = 0.02;

					float inMaxRange = step(disburn , u_BurnFactor + through*2.0);
					float outSecondRange = step(u_BurnFactor + through, disburn);
					float inFirst = inMaxRange * outSecondRange;
					
					float inSencondRange = step(disburn, u_BurnFactor + through);
					float outThirdRange = step(u_BurnFactor, disburn);
					float inSecond = inSencondRange * outThirdRange;

					float inThird = step(disburn, u_BurnFactor);
					float inFourth = (1.0 - inFirst) * (1.0 - inSecond) * (1.0 - inThird);

					vec4 outColor = vec4(236.0/255.0, 131.0/255.0, 255.0/255.0, albedoTextureColor.a);
					vec4 secondColor = vec4(245.0/255.0, 228.0/255.0, 255.0/255.0, albedoTextureColor.a);
					vec4 thirdColor = vec4(0.0,0.0,0.0,0.0);
					vec4 forthColor = albedoTextureColor.rgba;
					
					albedoTextureColor = outColor*inFirst + secondColor*inSecond + inThird * thirdColor + forthColor * inFourth;

					// if(disburn < u_BurnFactor + through*2.0 && disburn >= u_BurnFactor + through){
					// 	albedoTextureColor.a = albedoTextureColor.a;
					// 	albedoTextureColor.rgb = vec3(245.0/255.0, 228.0/255.0, 255.0/255.0);
					// }
					// else if(disburn < u_BurnFactor + through && disburn >= u_BurnFactor){
					// 	albedoTextureColor.a = albedoTextureColor.a;
					// 	albedoTextureColor.rgb = vec3(236.0/255.0, 131.0/255.0, 255.0/255.0);
					// }
					// else if(disburn < u_BurnFactor){
					// 	albedoTextureColor.a = 0.0;
					// }
					// else{
					// 	albedoTextureColor.a = albedoTextureColor.a;
					// }
				#endif
			#endif
			

			#ifdef WHOLE_ALPHA
				//叠加全局透明度
				albedoTextureColor.a *= u_alpha;
			#endif

			#ifdef ALPHATEST
				if(albedoTextureColor.a <= u_AlphaTestValue){
					discard;
				}
			#endif

			#ifdef ALBEDOCOLOR
				albedoTextureColor *= u_AlbedoColor;
			#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);

			shadow *= u_ShadowIntensity;
			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;

			float shadowAttenuation = 1.0;
			#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
						shadowAttenuation *= sampleShadowmap(shadowCoord);
                    #endif
                #else
					#ifdef SHADOW_CASCADE
						vec4 shadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));
					#else
						vec4 shadowCoord = v_ShadowCoord;
					#endif
					shadowAttenuation *= sampleShadowmap(shadowCoord);
                #endif
            #endif
			//混合漫反射 + 高光 + 阴影
			vec3 finalColor = albedoAreaColor + speculAreaColor + shadowAreaColor;
            finalColor *= shadowAttenuation;

			//阴影补光计算
            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 SHADERDEFINE_WHITE_FACTOR
				float diswhite = distance(v_worldPos.xyz, vec3(0.0,0.0,0.0));
				float whiteFactor = smoothstep(diswhite+1.0, diswhite, u_WhiteFactor);
				finalColor.rgb = finalColor.rgb * whiteFactor + vec3(1.0,1.0,1.0)*(1.0-whiteFactor);
			#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 = albedoColor.rgb * inSpot * inDir * 0.5;
				vec3 sunColor = u_SunLight.color * albedoColor.rgb;

				finalColor *= spotColor + sunColor;
			#else
				finalColor *= u_SunLight.color;
			#endif

			#ifdef SHADERDEFINE_GRAY
				float ff = (finalColor.r + finalColor.g + finalColor.b)/3.0;
				finalColor.rgb = vec3(ff, ff, ff);
			#endif

			gl_FragColor = vec4(finalColor.rgb, albedoTextureColor.a);

			//bagmagerial
		}
	
		void main()
		{
			main_normal();
		}`;
  		subShader.addShaderPass(vs2, ps2, stateMap);
  		subShader.addShaderPass(PBRShadowCasterVS, PBRShadowCasterPS, stateMap, "ShadowCaster");
  	}
  	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 whiteFactor() {
  		return this._shaderValues.getNumber(BagMaterial.WHITE_FACTOR);
  	}
  	set whiteFactor(value) {
  		if (value != null) {
  			value = Math.max(0.0, value);
  			this._shaderValues.setNumber(BagMaterial.WHITE_FACTOR, value);
  			this._shaderValues.addDefine(BagMaterial.SHADERDEFINE_WHITE_FACTOR);
  		}
  		else {
  			this._shaderValues.removeDefine(BagMaterial.SHADERDEFINE_WHITE_FACTOR);
  		}
  	}
  	get bBurnInvert() {
  		return this._shaderValues.hasDefine(BagMaterial.SHADERDEFINE_BURN_INVERST);
  	}
  	set bBurnInvert(value) {
  		if (value) {
  			this._shaderValues.addDefine(BagMaterial.SHADERDEFINE_BURN_INVERST);
  		}
  		else {
  			this._shaderValues.removeDefine(BagMaterial.SHADERDEFINE_BURN_INVERST);
  		}
  	}
  	get burnFactor() {
  		return this._shaderValues.getNumber(BagMaterial.BURN_FACTOR);
  	}
  	set burnFactor(value) {
  		if (value != null) {
  			value = Math.max(0.0, value);
  			this._shaderValues.setNumber(BagMaterial.BURN_FACTOR, value);
  		}
  	}
  	get burnTexture() {
  		return this._shaderValues.getTexture(BagMaterial.BURNTEXTURE);
  	}
  	set burnTexture(value) {
  		if (value) {
  			this._defineDatas.add(BagMaterial.SHADERDEFINE_BURN);
  			this._shaderValues.setTexture(BagMaterial.BURNTEXTURE, value);
  		}
  		else {
  			this._defineDatas.remove(BagMaterial.SHADERDEFINE_BURN);
  		}
  	}
  	get BurnTillingOffset() {
  		return this._shaderValues.getVector(BagMaterial.BRUN_TEXTURE_TILLING_OFFSET);
  	}
  	set BurnTillingOffset(value) {
  		this._shaderValues.setVector(BagMaterial.BRUN_TEXTURE_TILLING_OFFSET, value);
  	}
  	get mprogress() {
  		return this._shaderValues.getNumber(BagMaterial.PROGRESS);
  	}
  	set mprogress(value) {
  		if (value != null) {
  			this._defineDatas.add(BagMaterial.SHADERDEFINE_PROGRESS);
  			value = Math.max(0.0, value);
  			this._shaderValues.setNumber(BagMaterial.PROGRESS, value);
  		}
  		else {
  			this._defineDatas.remove(BagMaterial.SHADERDEFINE_PROGRESS);
  		}
  	}
  	get gray() {
  		if (this._defineDatas.has(BagMaterial.SHADERDEFINE_GRAY)) {
  			return true;
  		}
  		else {
  			return false;
  		}
  	}
  	set gray(value) {
  		if (value) {
  			this._defineDatas.add(BagMaterial.SHADERDEFINE_GRAY);
  		}
  		else {
  			this._defineDatas.remove(BagMaterial.SHADERDEFINE_GRAY);
  		}
  	}
  	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 albedoTexture() {
  		return this._shaderValues.getTexture(BagMaterial.PAINT_LAYER1_TEXTURE);
  	}
  	set albedoTexture(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);
  	}
  	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);
  	}
  	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);
  	}
  	get alphaTestValue() {
  		return this._shaderValues.getNumber(Laya.Material.ALPHATESTVALUE) || 0;
  	}
  	set alphaTestValue(value) {
  		if (value == null)
  			return;
  		this._shaderValues.setNumber(Laya.Material.ALPHATESTVALUE, value);
  	}
  	getCanEditorParamList() {
  		return [
  			{
  				name: `renderMode`, desc: `渲染模式`, type: EditorType.option, options: [
  					{ desc: "不透明", value: 1 },
  					{ desc: "裁剪", value: 2 },
  					{ desc: "裁剪双面", value: 3 },
  					{ desc: "透明", value: 4 },
  					{ desc: "透明双面", value: 5 },
  					{ desc: "不透明双面", value: 6 },
  				],
  			},
  			{ name: `alphaTestValue`, desc: `alpha裁剪参数`, type: EditorType.slider, range: [0, 1] },
  			{ name: `paintLayer1TilingOffset`, desc: `uv平铺`, type: EditorType.vec4 },
  			{ name: `renderQueue`, desc: `renderQueue`, type: EditorType.num },
  			{ name: `albedoColor`, desc: `基础色`, type: EditorType.color },
  			{ name: `shadowColor`, desc: `阴影颜色`, type: EditorType.color },
  			{ name: `shadowRange`, desc: `阴影范围`, type: EditorType.slider, range: [0, 1] },
  			{ name: `shadowIntensity`, desc: `阴影强度`, type: EditorType.slider, range: [0, 1] },
  			{ name: `shadowBoundary`, 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.PROGRESS = Laya.Shader3D.propertyNameToID("u_Progress");
  BagMaterial.BURN_FACTOR = Laya.Shader3D.propertyNameToID("u_BurnFactor");
  BagMaterial.BURNTEXTURE = Laya.Shader3D.propertyNameToID("u_BurnTexture");
  BagMaterial.BRUN_TEXTURE_TILLING_OFFSET = Laya.Shader3D.propertyNameToID("u_BurnTextureTillingOffset");
  BagMaterial.WHITE_FACTOR = Laya.Shader3D.propertyNameToID("u_WhiteFactor");
  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.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");
  		NormalMaterial.SHADERDEFINE_UVRECT = Laya.Shader3D.getDefineByName("UVRECT");
  		NormalMaterial.SHADERDEFINE_INVERSE_PREMUL = Laya.Shader3D.getDefineByName("INVERSE_PREMUL");
  		NormalMaterial.SHADERDEFINE_PROGRESS = Laya.Shader3D.getDefineByName("PROGRESS");
  	}
  	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_UVRect': 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_Progress': Laya.Shader3D.PERIOD_MATERIAL,
  		};
  		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 GL_FRAGMENT_PRECISION_HIGH
            precision highp float;
            precision highp int;
        #else
            precision mediump float;
            precision mediump int;
        #endif

		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;

		#ifdef UVRECT
			uniform vec4 u_UVRect;
		#endif

		#ifdef PROGRESS
			uniform float u_Progress;
		#endif

		void main_normal(){
			vec4 albedoTextureColor = vec4(1.0);
			vec2 texcoord = v_Texcoord0.xy;
			#ifdef UVRECT
				texcoord.x = u_UVRect.x + u_UVRect.z * texcoord.x;
				texcoord.y = u_UVRect.y + u_UVRect.w * texcoord.y;
			#endif

			#ifdef ALBEDOTEXTURE
				albedoTextureColor = texture2D(u_AlbedoTexture, texcoord);
			#endif

			#ifdef INVERSE_PREMUL
				albedoTextureColor.rgb /= albedoTextureColor.a;
			#endif

			#ifdef ALBEDOCOLOR
				albedoTextureColor *= u_AlbedoColor * u_AlbedoIdentity;
			#endif

			#ifdef PROGRESS
				float through = 0.02;
				float halfTh = through/2.0;
				float realP = 1.0 - v_Texcoord0.y;
				//是否在进度跳
				float fInP = step(realP, u_Progress - halfTh);
				float fInNP = step(u_Progress + halfTh, realP);
				float aFactor = fInNP * 0.0 + fInP * 1.0 + (1.0 - fInP)*(1.0-fInNP)*(1.0 - (realP - u_Progress + halfTh)/through);
				albedoTextureColor.a *= aFactor;
			#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

			// gl_FragColor.xy = v_Texcoord0.xy;
		}
	
		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 mprogress() {
  		return this._shaderValues.getNumber(NormalMaterial.PROGRESS);
  	}
  	set mprogress(value) {
  		value = Math.max(0.0, value);
  		this._shaderValues.setNumber(NormalMaterial.PROGRESS, value);
  		this._shaderValues.addDefine(NormalMaterial.SHADERDEFINE_PROGRESS);
  	}
  	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 uvrect() {
  		return this._shaderValues.getVector(NormalMaterial.UVRECT);
  	}
  	set uvrect(value) {
  		if (value) {
  			if (value.x != 1 || value.y != 1 || value.z != 0 || value.w != 0)
  				this._shaderValues.addDefine(NormalMaterial.SHADERDEFINE_UVRECT);
  			else
  				this._shaderValues.removeDefine(NormalMaterial.SHADERDEFINE_UVRECT);
  		}
  		else {
  			this._shaderValues.removeDefine(NormalMaterial.SHADERDEFINE_UVRECT);
  		}
  		this._shaderValues.setVector(NormalMaterial.UVRECT, value);
  	}
  	get bInversePremul() {
  		return this._shaderValues.hasDefine(NormalMaterial.SHADERDEFINE_INVERSE_PREMUL);
  	}
  	set bInversePremul(value) {
  		if (value) {
  			this._shaderValues.addDefine(NormalMaterial.SHADERDEFINE_INVERSE_PREMUL);
  		}
  		else {
  			this._shaderValues.removeDefine(NormalMaterial.SHADERDEFINE_INVERSE_PREMUL);
  		}
  	}
  	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_LESS;
  				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.UVRECT = Laya.Shader3D.propertyNameToID("u_UVRect");
  NormalMaterial.WHOLE_ALPHA = Laya.Shader3D.propertyNameToID("u_alpha");
  NormalMaterial.PROGRESS = Laya.Shader3D.propertyNameToID("u_Progress");
  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 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");
  		PaintMaterial.SHADERDEFINE_BLEND_R = Laya.Shader3D.getDefineByName("BLEND_R");
  		PaintMaterial.SHADERDEFINE_BLEND_G = Laya.Shader3D.getDefineByName("BLEND_G");
  		PaintMaterial.SHADERDEFINE_BLEND_B = Laya.Shader3D.getDefineByName("BLEND_B");
  		PaintMaterial.SHADERDEFINE_BLEND_A = Laya.Shader3D.getDefineByName("BLEND_A");
  		PaintMaterial.SHADERDEFINE_BLEND_MASK_R = Laya.Shader3D.getDefineByName("BLEND_MASK_R");
  		PaintMaterial.SHADERDEFINE_BLEND_MASK_G = Laya.Shader3D.getDefineByName("BLEND_MASK_G");
  		PaintMaterial.SHADERDEFINE_BLEND_MASK_B = Laya.Shader3D.getDefineByName("BLEND_MASK_B");
  		PaintMaterial.SHADERDEFINE_BLEND_MASK_A = Laya.Shader3D.getDefineByName("BLEND_MASK_A");
  	}
  	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 GL_FRAGMENT_PRECISION_HIGH
            precision highp float;
            precision highp int;
        #else
            precision mediump float;
            precision mediump int;
        #endif
	
        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);

				float mask = maskColor.a;
				#ifdef BLEND_MASK_R
					mask = maskColor.r;
				#endif
				#ifdef BLEND_MASK_G
					mask = maskColor.g;
				#endif
				#ifdef BLEND_MASK_B
					mask = maskColor.b;
				#endif
				#ifdef BLEND_MASK_A
					mask = maskColor.a;
				#endif
				
				vec4 blend = vec4(0.0);
				#ifdef BLEND_R
					blend.r = mask;
				#endif
				#ifdef BLEND_G
                    blend.g = mask;
				#endif
				#ifdef BLEND_B
                    blend.b = mask;
				#endif
				#ifdef BLEND_A
                    blend.a = mask;
				#endif
                albedoTextureColor.rgba = baseColor.rgba * (1.0 - blend.rgba) + blend.rgba*paintColor;
			#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 bBlendR() {
  		return this._shaderValues.hasDefine(PaintMaterial.SHADERDEFINE_BLEND_R);
  	}
  	set bBlendR(value) {
  		if (value) {
  			this._defineDatas.add(PaintMaterial.SHADERDEFINE_BLEND_R);
  		}
  		else {
  			this._defineDatas.remove(PaintMaterial.SHADERDEFINE_BLEND_R);
  		}
  	}
  	get bBlendG() {
  		return this._shaderValues.hasDefine(PaintMaterial.SHADERDEFINE_BLEND_G);
  	}
  	set bBlendG(value) {
  		if (value) {
  			this._defineDatas.add(PaintMaterial.SHADERDEFINE_BLEND_G);
  		}
  		else {
  			this._defineDatas.remove(PaintMaterial.SHADERDEFINE_BLEND_G);
  		}
  	}
  	get bBlendB() {
  		return this._shaderValues.hasDefine(PaintMaterial.SHADERDEFINE_BLEND_B);
  	}
  	set bBlendB(value) {
  		if (value) {
  			this._defineDatas.add(PaintMaterial.SHADERDEFINE_BLEND_B);
  		}
  		else {
  			this._defineDatas.remove(PaintMaterial.SHADERDEFINE_BLEND_B);
  		}
  	}
  	get bBlendA() {
  		return this._shaderValues.hasDefine(PaintMaterial.SHADERDEFINE_BLEND_A);
  	}
  	set bBlendA(value) {
  		if (value) {
  			this._defineDatas.add(PaintMaterial.SHADERDEFINE_BLEND_A);
  		}
  		else {
  			this._defineDatas.remove(PaintMaterial.SHADERDEFINE_BLEND_A);
  		}
  	}
  	get bBlendMaskR() {
  		return this._shaderValues.hasDefine(PaintMaterial.SHADERDEFINE_BLEND_MASK_R);
  	}
  	set bBlendMaskR(value) {
  		if (value) {
  			this._defineDatas.add(PaintMaterial.SHADERDEFINE_BLEND_MASK_R);
  		}
  		else {
  			this._defineDatas.remove(PaintMaterial.SHADERDEFINE_BLEND_MASK_R);
  		}
  	}
  	get bBlendMaskG() {
  		return this._shaderValues.hasDefine(PaintMaterial.SHADERDEFINE_BLEND_MASK_G);
  	}
  	set bBlendMaskG(value) {
  		if (value) {
  			this._defineDatas.add(PaintMaterial.SHADERDEFINE_BLEND_MASK_G);
  		}
  		else {
  			this._defineDatas.remove(PaintMaterial.SHADERDEFINE_BLEND_MASK_G);
  		}
  	}
  	get bBlendMaskB() {
  		return this._shaderValues.hasDefine(PaintMaterial.SHADERDEFINE_BLEND_MASK_B);
  	}
  	set bBlendMaskB(value) {
  		if (value) {
  			this._defineDatas.add(PaintMaterial.SHADERDEFINE_BLEND_MASK_B);
  		}
  		else {
  			this._defineDatas.remove(PaintMaterial.SHADERDEFINE_BLEND_MASK_B);
  		}
  	}
  	get bBlendMaskA() {
  		return this._shaderValues.hasDefine(PaintMaterial.SHADERDEFINE_BLEND_MASK_A);
  	}
  	set bBlendMaskA(value) {
  		if (value) {
  			this._defineDatas.add(PaintMaterial.SHADERDEFINE_BLEND_MASK_A);
  		}
  		else {
  			this._defineDatas.remove(PaintMaterial.SHADERDEFINE_BLEND_MASK_A);
  		}
  	}
  	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 FillColorMaterial extends Laya.Material {
  	constructor() {
  		super();
  		this.setShaderName("FillColorMaterial");
  		this._shaderValues.setNumber(FillColorMaterial.ALBEDOIDENTITY, 0.5);
  		this._shaderValues.setVector(FillColorMaterial.ALBEDOCOLOR, new Laya.Vector4(1.0, 1.0, 1.0, 1.0));
  		this.alpha = 1;
  	}
  	static __init__() {
  		FillColorMaterial.SHADERDEFINE_BONE = Laya.Shader3D.getDefineByName("BONE");
  		FillColorMaterial.SHADERDEFINE_TILINGOFFSET = Laya.Shader3D.getDefineByName("TILINGOFFSET");
  		FillColorMaterial.SHADERDEFINE_WHOLE_ALPHA = Laya.Shader3D.getDefineByName("WHOLE_ALPHA");
  		FillColorMaterial.SHADERDEFINE_ALBEDOTEXTURE = Laya.Shader3D.getDefineByName("ALBEDOTEXTURE");
  		FillColorMaterial.SHADERDEFINE_ALBEDOCOLOR = Laya.Shader3D.getDefineByName("ALBEDOCOLOR");
  		FillColorMaterial.SHADERDEFINE_FILL_MASK_TEXTURE = Laya.Shader3D.getDefineByName("FILL_MASK_TEXTURE");
  		FillColorMaterial.SHADERDEFINE_FILL_TEXTURE = Laya.Shader3D.getDefineByName("FILL_TEXTURE");
  		FillColorMaterial.SHADERDEFINE_BLING_TEXTURE = Laya.Shader3D.getDefineByName("BLING_TEXTURE");
  	}
  	static initShader() {
  		FillColorMaterial.__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_Bones': Laya.Shader3D.PERIOD_CUSTOM,
  			'u_alpha': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_FillMaskTexture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_FillTexture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BlingTexture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_Time': Laya.Shader3D.PERIOD_SCENE,
  		};
  		var FillColorMaterial3D = Laya.Shader3D.add("FillColorMaterial");
  		var subShader = new Laya.SubShader(attributeMap, uniformMap);
  		FillColorMaterial3D.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 GL_FRAGMENT_PRECISION_HIGH
            precision highp float;
            precision highp int;
        #else
            precision mediump float;
            precision mediump int;
        #endif

		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;
        
        uniform sampler2D u_FillMaskTexture;
		uniform sampler2D u_FillTexture;
		uniform sampler2D u_BlingTexture;

		uniform float u_Time;

		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
				//叠加全局透明度
				albedoTextureColor = vec4(albedoTextureColor.rgb, albedoTextureColor.a*u_alpha);
			#else
                albedoTextureColor = vec4(albedoTextureColor.rgb, albedoTextureColor.a);
            #endif
            
            #ifdef FILL_TEXTURE
                #ifdef FILL_MASK_TEXTURE
                vec4 fillMaskColor = texture2D(u_FillMaskTexture, v_Texcoord0);
                vec4 fillColor = texture2D(u_FillTexture, v_Texcoord0);
                //在可填充区域, 用填充颜色
                // float fillFactor = step(0.01, fillMaskColor.a);
                albedoTextureColor.rgb = albedoTextureColor.rgb * (1.0 - fillMaskColor.r) + fillColor.rgb * fillMaskColor.r;
                #endif
			#endif
			
			#ifdef BLING_TEXTURE
				// vec2 newuv = vec2(u_Time/10.0, u_Time/10.0);
				// vec4 blingColor = texture2D(u_BlingTexture, newuv);
				vec3 addc = vec3(sin(u_Time * 4.0)*0.5 + 0.5);
				albedoTextureColor.rgb += addc;
			#endif

            gl_FragColor = albedoTextureColor;
		}
	
		void main() 
		{ 
			main_normal();
		}`;
  		subShader.addShaderPass(vs1, ps1, stateMap);
  	}
  	get blingTexture() {
  		return this._shaderValues.getTexture(FillColorMaterial.BLING_TEXTURE);
  	}
  	set blingTexture(value) {
  		if (value) {
  			this._shaderValues.addDefine(FillColorMaterial.SHADERDEFINE_BLING_TEXTURE);
  		}
  		else {
  			this._shaderValues.removeDefine(FillColorMaterial.SHADERDEFINE_BLING_TEXTURE);
  		}
  		this._shaderValues.setTexture(FillColorMaterial.BLING_TEXTURE, value);
  	}
  	get albedoTexture() {
  		return this._shaderValues.getTexture(FillColorMaterial.ALBEDOTEXTURE);
  	}
  	set albedoTexture(value) {
  		if (value) {
  			this._shaderValues.addDefine(FillColorMaterial.SHADERDEFINE_ALBEDOTEXTURE);
  		}
  		else {
  			this._shaderValues.removeDefine(FillColorMaterial.SHADERDEFINE_ALBEDOTEXTURE);
  		}
  		this._shaderValues.setTexture(FillColorMaterial.ALBEDOTEXTURE, value);
  	}
  	get fillMaskTexture() {
  		return this._shaderValues.getTexture(FillColorMaterial.FILL_MASK_TEXTURE);
  	}
  	set fillMaskTexture(value) {
  		if (value) {
  			this._shaderValues.addDefine(FillColorMaterial.SHADERDEFINE_FILL_MASK_TEXTURE);
  		}
  		else {
  			this._shaderValues.removeDefine(FillColorMaterial.SHADERDEFINE_FILL_MASK_TEXTURE);
  		}
  		this._shaderValues.setTexture(FillColorMaterial.FILL_MASK_TEXTURE, value);
  	}
  	get fillTexture() {
  		return this._shaderValues.getTexture(FillColorMaterial.FILL_TEXTURE);
  	}
  	set fillTexture(value) {
  		if (value) {
  			this._shaderValues.addDefine(FillColorMaterial.SHADERDEFINE_FILL_TEXTURE);
  		}
  		else {
  			this._shaderValues.removeDefine(FillColorMaterial.SHADERDEFINE_FILL_TEXTURE);
  		}
  		this._shaderValues.setTexture(FillColorMaterial.FILL_TEXTURE, value);
  	}
  	get albedoColor() {
  		return this._shaderValues.getVector(FillColorMaterial.ALBEDOCOLOR);
  	}
  	set albedoColor(value) {
  		if (value) {
  			this._defineDatas.add(FillColorMaterial.SHADERDEFINE_ALBEDOCOLOR);
  		}
  		else {
  			this._defineDatas.remove(FillColorMaterial.SHADERDEFINE_ALBEDOCOLOR);
  		}
  		this._shaderValues.setVector(FillColorMaterial.ALBEDOCOLOR, value);
  	}
  	get albedoIdentity() {
  		return this._shaderValues.getNumber(FillColorMaterial.ALBEDOIDENTITY);
  	}
  	set albedoIdentity(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(FillColorMaterial.ALBEDOIDENTITY, value);
  	}
  	get tilingOffset() {
  		return this._shaderValues.getVector(FillColorMaterial.TILINGOFFSET);
  	}
  	set tilingOffset(value) {
  		if (value) {
  			if (value.x != 1 || value.y != 1 || value.z != 0 || value.w != 0)
  				this._shaderValues.addDefine(FillColorMaterial.SHADERDEFINE_TILINGOFFSET);
  			else
  				this._shaderValues.removeDefine(FillColorMaterial.SHADERDEFINE_TILINGOFFSET);
  		}
  		else {
  			this._shaderValues.removeDefine(FillColorMaterial.SHADERDEFINE_TILINGOFFSET);
  		}
  		this._shaderValues.setVector(FillColorMaterial.TILINGOFFSET, value);
  	}
  	get alpha() {
  		return this._shaderValues.getNumber(FillColorMaterial.WHOLE_ALPHA);
  	}
  	set alpha(value) {
  		if (value != null) {
  			this._defineDatas.add(FillColorMaterial.SHADERDEFINE_WHOLE_ALPHA);
  		}
  		else {
  			this._defineDatas.remove(FillColorMaterial.SHADERDEFINE_WHOLE_ALPHA);
  		}
  		this._shaderValues.setNumber(FillColorMaterial.WHOLE_ALPHA, value);
  	}
  	get cull() {
  		return this._shaderValues.getInt(FillColorMaterial.CULL);
  	}
  	set cull(value) {
  		this._shaderValues.setInt(FillColorMaterial.CULL, value);
  	}
  	get blend() {
  		return this._shaderValues.getInt(FillColorMaterial.BLEND);
  	}
  	set blend(value) {
  		this._shaderValues.setInt(FillColorMaterial.BLEND, value);
  	}
  	get blendSrc() {
  		return this._shaderValues.getInt(FillColorMaterial.BLEND_SRC);
  	}
  	set blendSrc(value) {
  		this._shaderValues.setInt(FillColorMaterial.BLEND_SRC, value);
  	}
  	get blendDst() {
  		return this._shaderValues.getInt(FillColorMaterial.BLEND_DST);
  	}
  	set blendDst(value) {
  		this._shaderValues.setInt(FillColorMaterial.BLEND_DST, value);
  	}
  	get depthTest() {
  		return this._shaderValues.getInt(FillColorMaterial.DEPTH_TEST);
  	}
  	set depthTest(value) {
  		this._shaderValues.setInt(FillColorMaterial.DEPTH_TEST, value);
  	}
  	get depthWrite() {
  		return this._shaderValues.getBool(FillColorMaterial.DEPTH_WRITE);
  	}
  	set depthWrite(value) {
  		this._shaderValues.setBool(FillColorMaterial.DEPTH_WRITE, value);
  	}
  	set renderMode(value) {
  		switch (value) {
  			case FillColorMaterial.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 FillColorMaterial.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 FillColorMaterial.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 FillColorMaterial.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 FillColorMaterial.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("FillColorMaterial : renderMode value error.");
  		}
  	}
  }
  FillColorMaterial.ALBEDOTEXTURE = Laya.Shader3D.propertyNameToID("u_AlbedoTexture");
  FillColorMaterial.ALBEDOIDENTITY = Laya.Shader3D.propertyNameToID("u_AlbedoIdentity");
  FillColorMaterial.ALBEDOCOLOR = Laya.Shader3D.propertyNameToID("u_AlbedoColor");
  FillColorMaterial.TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_TilingOffset");
  FillColorMaterial.WHOLE_ALPHA = Laya.Shader3D.propertyNameToID("u_alpha");
  FillColorMaterial.FILL_MASK_TEXTURE = Laya.Shader3D.propertyNameToID("u_FillMaskTexture");
  FillColorMaterial.FILL_TEXTURE = Laya.Shader3D.propertyNameToID("u_FillTexture");
  FillColorMaterial.BLING_TEXTURE = Laya.Shader3D.propertyNameToID("u_BlingTexture");
  FillColorMaterial.CULL = Laya.Shader3D.propertyNameToID("s_Cull");
  FillColorMaterial.BLEND = Laya.Shader3D.propertyNameToID("s_Blend");
  FillColorMaterial.BLEND_SRC = Laya.Shader3D.propertyNameToID("s_BlendSrc");
  FillColorMaterial.BLEND_DST = Laya.Shader3D.propertyNameToID("s_BlendDst");
  FillColorMaterial.DEPTH_TEST = Laya.Shader3D.propertyNameToID("s_DepthTest");
  FillColorMaterial.DEPTH_WRITE = Laya.Shader3D.propertyNameToID("s_DepthWrite");
  FillColorMaterial.RENDERMODE_OPAQUE = 1;
  FillColorMaterial.RENDERMODE_CUTOUT = 2;
  FillColorMaterial.RENDERMODE_CUTOUT_CULL_NONE = 3;
  FillColorMaterial.RENDERMODE_TRANSPARENT = 4;
  FillColorMaterial.RENDERMODE_TRANSPARENT_CULL_NONE = 5;

  class SharkMaterial extends Laya.Material {
  	constructor() {
  		super();
  		this.setShaderName("SharkMaterial");
  		this._shaderValues.setNumber(SharkMaterial.ALBEDOIDENTITY, 0.5);
  		this._shaderValues.setVector(SharkMaterial.ALBEDOCOLOR, new Laya.Vector4(1.0, 1.0, 1.0, 1.0));
  		this.alpha = 1;
  		this.sharkIdentity = 0;
  	}
  	static __init__() {
  		SharkMaterial.SHADERDEFINE_BONE = Laya.Shader3D.getDefineByName("BONE");
  		SharkMaterial.SHADERDEFINE_TILINGOFFSET = Laya.Shader3D.getDefineByName("TILINGOFFSET");
  		SharkMaterial.SHADERDEFINE_WHOLE_ALPHA = Laya.Shader3D.getDefineByName("WHOLE_ALPHA");
  		SharkMaterial.SHADERDEFINE_ALBEDOTEXTURE = Laya.Shader3D.getDefineByName("ALBEDOTEXTURE");
  		SharkMaterial.SHADERDEFINE_ALBEDOCOLOR = Laya.Shader3D.getDefineByName("ALBEDOCOLOR");
  		SharkMaterial.SHADERDEFINE_SHARKTEXTURE = Laya.Shader3D.getDefineByName("SHARKTEXTURE");
  	}
  	static initShader() {
  		SharkMaterial.__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,
  			'u_SharkTexture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_SharkIdentity': Laya.Shader3D.PERIOD_MATERIAL,
  		};
  		var SharkMaterial3D = Laya.Shader3D.add("SharkMaterial");
  		var subShader = new Laya.SubShader(attributeMap, uniformMap);
  		SharkMaterial3D.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 GL_FRAGMENT_PRECISION_HIGH
            precision highp float;
            precision highp int;
        #else
            precision mediump float;
            precision mediump int;
        #endif

		varying vec3 v_PositionWorld;
	
		varying vec2 v_Texcoord0; 

		#ifdef WHOLE_ALPHA
			uniform float u_alpha;
		#endif

		#ifdef ALBEDOTEXTURE
			uniform sampler2D u_AlbedoTexture;
			uniform float u_AlbedoIdentity;
			uniform vec4 u_AlbedoColor;
		#endif

		#ifdef SHARKTEXTURE
			uniform sampler2D u_SharkTexture;
			uniform float u_SharkIdentity;
		#endif

		void main_normal(){
			vec4 albedoTextureColor = vec4(1.0);
			#ifdef ALBEDOTEXTURE
				albedoTextureColor = texture2D(u_AlbedoTexture, v_Texcoord0);
				albedoTextureColor.rgb/=albedoTextureColor.a;
			#endif

			#ifdef ALBEDOCOLOR
				albedoTextureColor.rgb *= u_AlbedoColor.rgb * u_AlbedoIdentity;
			#endif

			//闪光叠加效果
			#ifdef SHARKTEXTURE
				vec4 sharkTextureColor = texture2D(u_SharkTexture, v_Texcoord0);
				albedoTextureColor += sharkTextureColor * u_SharkIdentity;
				// albedoTextureColor = vec4(u_SharkIdentity);
			#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(SharkMaterial.ALBEDOTEXTURE);
  	}
  	set albedoTexture(value) {
  		if (value) {
  			this._shaderValues.addDefine(SharkMaterial.SHADERDEFINE_ALBEDOTEXTURE);
  		}
  		else {
  			this._shaderValues.removeDefine(SharkMaterial.SHADERDEFINE_ALBEDOTEXTURE);
  		}
  		this._shaderValues.setTexture(SharkMaterial.ALBEDOTEXTURE, value);
  	}
  	get sharkTexture() {
  		return this._shaderValues.getTexture(SharkMaterial.SHARKTEXTURE);
  	}
  	set sharkTexture(value) {
  		if (value) {
  			this._shaderValues.addDefine(SharkMaterial.SHADERDEFINE_SHARKTEXTURE);
  		}
  		else {
  			this._shaderValues.removeDefine(SharkMaterial.SHADERDEFINE_SHARKTEXTURE);
  		}
  		this._shaderValues.setTexture(SharkMaterial.SHARKTEXTURE, value);
  	}
  	get sharkIdentity() {
  		return this._shaderValues.getNumber(SharkMaterial.SHARKIDENTITY);
  	}
  	set sharkIdentity(value) {
  		value = Math.max(0.0, value);
  		this._shaderValues.setNumber(SharkMaterial.SHARKIDENTITY, value);
  	}
  	get albedoColor() {
  		return this._shaderValues.getVector(SharkMaterial.ALBEDOCOLOR);
  	}
  	set albedoColor(value) {
  		if (value) {
  			this._defineDatas.add(SharkMaterial.SHADERDEFINE_ALBEDOCOLOR);
  		}
  		else {
  			this._defineDatas.remove(SharkMaterial.SHADERDEFINE_ALBEDOCOLOR);
  		}
  		this._shaderValues.setVector(SharkMaterial.ALBEDOCOLOR, value);
  	}
  	get albedoIdentity() {
  		return this._shaderValues.getNumber(SharkMaterial.ALBEDOIDENTITY);
  	}
  	set albedoIdentity(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(SharkMaterial.ALBEDOIDENTITY, value);
  	}
  	get tilingOffset() {
  		return this._shaderValues.getVector(SharkMaterial.TILINGOFFSET);
  	}
  	set tilingOffset(value) {
  		if (value) {
  			if (value.x != 1 || value.y != 1 || value.z != 0 || value.w != 0)
  				this._shaderValues.addDefine(SharkMaterial.SHADERDEFINE_TILINGOFFSET);
  			else
  				this._shaderValues.removeDefine(SharkMaterial.SHADERDEFINE_TILINGOFFSET);
  		}
  		else {
  			this._shaderValues.removeDefine(SharkMaterial.SHADERDEFINE_TILINGOFFSET);
  		}
  		this._shaderValues.setVector(SharkMaterial.TILINGOFFSET, value);
  	}
  	get alpha() {
  		return this._shaderValues.getNumber(SharkMaterial.WHOLE_ALPHA);
  	}
  	set alpha(value) {
  		if (value != null) {
  			this._defineDatas.add(SharkMaterial.SHADERDEFINE_WHOLE_ALPHA);
  		}
  		else {
  			this._defineDatas.remove(SharkMaterial.SHADERDEFINE_WHOLE_ALPHA);
  		}
  		this._shaderValues.setNumber(SharkMaterial.WHOLE_ALPHA, value);
  	}
  	get cull() {
  		return this._shaderValues.getInt(SharkMaterial.CULL);
  	}
  	set cull(value) {
  		this._shaderValues.setInt(SharkMaterial.CULL, value);
  	}
  	get blend() {
  		return this._shaderValues.getInt(SharkMaterial.BLEND);
  	}
  	set blend(value) {
  		this._shaderValues.setInt(SharkMaterial.BLEND, value);
  	}
  	get blendSrc() {
  		return this._shaderValues.getInt(SharkMaterial.BLEND_SRC);
  	}
  	set blendSrc(value) {
  		this._shaderValues.setInt(SharkMaterial.BLEND_SRC, value);
  	}
  	get blendDst() {
  		return this._shaderValues.getInt(SharkMaterial.BLEND_DST);
  	}
  	set blendDst(value) {
  		this._shaderValues.setInt(SharkMaterial.BLEND_DST, value);
  	}
  	get depthTest() {
  		return this._shaderValues.getInt(SharkMaterial.DEPTH_TEST);
  	}
  	set depthTest(value) {
  		this._shaderValues.setInt(SharkMaterial.DEPTH_TEST, value);
  	}
  	get depthWrite() {
  		return this._shaderValues.getBool(SharkMaterial.DEPTH_WRITE);
  	}
  	set depthWrite(value) {
  		this._shaderValues.setBool(SharkMaterial.DEPTH_WRITE, value);
  	}
  	set renderMode(value) {
  		switch (value) {
  			case SharkMaterial.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 SharkMaterial.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 SharkMaterial.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 SharkMaterial.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 SharkMaterial.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 SharkMaterial.RENDERMODE_TRANSPARENT_BLEND_ADD:
  				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_ONE_MINUS_DST_ALPHA;
  				this.blendDst = Laya.RenderState.BLENDPARAM_ONE;
  				this.depthTest = Laya.RenderState.DEPTHTEST_LEQUAL;
  				break;
  			default:
  				throw new Error("SharkMaterial : renderMode value error.");
  		}
  	}
  }
  SharkMaterial.ALBEDOTEXTURE = Laya.Shader3D.propertyNameToID("u_AlbedoTexture");
  SharkMaterial.ALBEDOIDENTITY = Laya.Shader3D.propertyNameToID("u_AlbedoIdentity");
  SharkMaterial.ALBEDOCOLOR = Laya.Shader3D.propertyNameToID("u_AlbedoColor");
  SharkMaterial.SHARKTEXTURE = Laya.Shader3D.propertyNameToID("u_SharkTexture");
  SharkMaterial.SHARKIDENTITY = Laya.Shader3D.propertyNameToID("u_SharkIdentity");
  SharkMaterial.TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_TilingOffset");
  SharkMaterial.WHOLE_ALPHA = Laya.Shader3D.propertyNameToID("u_alpha");
  SharkMaterial.CULL = Laya.Shader3D.propertyNameToID("s_Cull");
  SharkMaterial.BLEND = Laya.Shader3D.propertyNameToID("s_Blend");
  SharkMaterial.BLEND_SRC = Laya.Shader3D.propertyNameToID("s_BlendSrc");
  SharkMaterial.BLEND_DST = Laya.Shader3D.propertyNameToID("s_BlendDst");
  SharkMaterial.DEPTH_TEST = Laya.Shader3D.propertyNameToID("s_DepthTest");
  SharkMaterial.DEPTH_WRITE = Laya.Shader3D.propertyNameToID("s_DepthWrite");
  SharkMaterial.RENDERMODE_OPAQUE = 1;
  SharkMaterial.RENDERMODE_CUTOUT = 2;
  SharkMaterial.RENDERMODE_CUTOUT_CULL_NONE = 3;
  SharkMaterial.RENDERMODE_TRANSPARENT = 4;
  SharkMaterial.RENDERMODE_TRANSPARENT_CULL_NONE = 5;
  SharkMaterial.RENDERMODE_TRANSPARENT_BLEND_ADD = 6;

  class ProgressMaterial extends Laya.Material {
  	constructor() {
  		super();
  		this.setShaderName("ProgressMaterial");
  		this._shaderValues.setNumber(ProgressMaterial.ALBEDOIDENTITY, 0.5);
  		this._shaderValues.setVector(ProgressMaterial.ALBEDOCOLOR, new Laya.Vector4(1.0, 1.0, 1.0, 1.0));
  		this.alpha = 1;
  		this.sharkIdentity = 0;
  		this.mprogress = 0;
  	}
  	static __init__() {
  		ProgressMaterial.SHADERDEFINE_BONE = Laya.Shader3D.getDefineByName("BONE");
  		ProgressMaterial.SHADERDEFINE_TILINGOFFSET = Laya.Shader3D.getDefineByName("TILINGOFFSET");
  		ProgressMaterial.SHADERDEFINE_WHOLE_ALPHA = Laya.Shader3D.getDefineByName("WHOLE_ALPHA");
  		ProgressMaterial.SHADERDEFINE_ALBEDOTEXTURE = Laya.Shader3D.getDefineByName("ALBEDOTEXTURE");
  		ProgressMaterial.SHADERDEFINE_ALBEDOCOLOR = Laya.Shader3D.getDefineByName("ALBEDOCOLOR");
  		ProgressMaterial.SHADERDEFINE_SHARKTEXTURE = Laya.Shader3D.getDefineByName("SHARKTEXTURE");
  	}
  	static initShader() {
  		ProgressMaterial.__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,
  			'u_SharkTexture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_SharkIdentity': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_Progress': Laya.Shader3D.PERIOD_MATERIAL,
  		};
  		var ProgressMaterial3D = Laya.Shader3D.add("ProgressMaterial");
  		var subShader = new Laya.SubShader(attributeMap, uniformMap);
  		ProgressMaterial3D.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 GL_FRAGMENT_PRECISION_HIGH
            precision highp float;
            precision highp int;
        #else
            precision mediump float;
            precision mediump int;
        #endif

		varying vec3 v_PositionWorld;
	
		varying vec2 v_Texcoord0; 

		#ifdef WHOLE_ALPHA
			uniform float u_alpha;
		#endif

		// #ifdef ALBEDOTEXTURE
			
		// #endif

		uniform sampler2D u_AlbedoTexture;
		uniform float u_AlbedoIdentity;
		uniform vec4 u_AlbedoColor;

		#ifdef SHARKTEXTURE
			uniform sampler2D u_SharkTexture;
			uniform float u_SharkIdentity;
		#endif

		uniform float u_Progress;

		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 SHARKTEXTURE
				vec4 sharkTextureColor = texture2D(u_SharkTexture, v_Texcoord0);
				albedoTextureColor += sharkTextureColor * u_SharkIdentity;
				// albedoTextureColor = vec4(u_SharkIdentity);
			#endif

			float through = 0.02;
			float halfTh = through/2.0;
			float realP = 1.0 - v_Texcoord0.y;
			//是否在进度跳
			float fInP = step(realP, u_Progress - halfTh);
			float fInNP = step(u_Progress + halfTh, realP);
			float aFactor = fInNP * 0.0 + fInP * 1.0 + (1.0 - fInP)*(1.0-fInNP)*(1.0 - (realP - u_Progress + halfTh)/through);
			albedoTextureColor.a *= aFactor;

			#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(ProgressMaterial.ALBEDOTEXTURE);
  	}
  	set albedoTexture(value) {
  		if (value) {
  			this._shaderValues.addDefine(ProgressMaterial.SHADERDEFINE_ALBEDOTEXTURE);
  		}
  		else {
  			this._shaderValues.removeDefine(ProgressMaterial.SHADERDEFINE_ALBEDOTEXTURE);
  		}
  		this._shaderValues.setTexture(ProgressMaterial.ALBEDOTEXTURE, value);
  	}
  	get sharkTexture() {
  		return this._shaderValues.getTexture(ProgressMaterial.SHARKTEXTURE);
  	}
  	set sharkTexture(value) {
  		if (value) {
  			this._shaderValues.addDefine(ProgressMaterial.SHADERDEFINE_SHARKTEXTURE);
  		}
  		else {
  			this._shaderValues.removeDefine(ProgressMaterial.SHADERDEFINE_SHARKTEXTURE);
  		}
  		this._shaderValues.setTexture(ProgressMaterial.SHARKTEXTURE, value);
  	}
  	get sharkIdentity() {
  		return this._shaderValues.getNumber(ProgressMaterial.SHARKIDENTITY);
  	}
  	set sharkIdentity(value) {
  		value = Math.max(0.0, value);
  		this._shaderValues.setNumber(ProgressMaterial.SHARKIDENTITY, value);
  	}
  	get mprogress() {
  		return this._shaderValues.getNumber(ProgressMaterial.PROGRESS);
  	}
  	set mprogress(value) {
  		value = Math.max(0.0, value);
  		this._shaderValues.setNumber(ProgressMaterial.PROGRESS, value);
  	}
  	get albedoColor() {
  		return this._shaderValues.getVector(ProgressMaterial.ALBEDOCOLOR);
  	}
  	set albedoColor(value) {
  		if (value) {
  			this._defineDatas.add(ProgressMaterial.SHADERDEFINE_ALBEDOCOLOR);
  		}
  		else {
  			this._defineDatas.remove(ProgressMaterial.SHADERDEFINE_ALBEDOCOLOR);
  		}
  		this._shaderValues.setVector(ProgressMaterial.ALBEDOCOLOR, value);
  	}
  	get albedoIdentity() {
  		return this._shaderValues.getNumber(ProgressMaterial.ALBEDOIDENTITY);
  	}
  	set albedoIdentity(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(ProgressMaterial.ALBEDOIDENTITY, value);
  	}
  	get tilingOffset() {
  		return this._shaderValues.getVector(ProgressMaterial.TILINGOFFSET);
  	}
  	set tilingOffset(value) {
  		if (value) {
  			if (value.x != 1 || value.y != 1 || value.z != 0 || value.w != 0)
  				this._shaderValues.addDefine(ProgressMaterial.SHADERDEFINE_TILINGOFFSET);
  			else
  				this._shaderValues.removeDefine(ProgressMaterial.SHADERDEFINE_TILINGOFFSET);
  		}
  		else {
  			this._shaderValues.removeDefine(ProgressMaterial.SHADERDEFINE_TILINGOFFSET);
  		}
  		this._shaderValues.setVector(ProgressMaterial.TILINGOFFSET, value);
  	}
  	get alpha() {
  		return this._shaderValues.getNumber(ProgressMaterial.WHOLE_ALPHA);
  	}
  	set alpha(value) {
  		if (value != null) {
  			this._defineDatas.add(ProgressMaterial.SHADERDEFINE_WHOLE_ALPHA);
  		}
  		else {
  			this._defineDatas.remove(ProgressMaterial.SHADERDEFINE_WHOLE_ALPHA);
  		}
  		this._shaderValues.setNumber(ProgressMaterial.WHOLE_ALPHA, value);
  	}
  	get cull() {
  		return this._shaderValues.getInt(ProgressMaterial.CULL);
  	}
  	set cull(value) {
  		this._shaderValues.setInt(ProgressMaterial.CULL, value);
  	}
  	get blend() {
  		return this._shaderValues.getInt(ProgressMaterial.BLEND);
  	}
  	set blend(value) {
  		this._shaderValues.setInt(ProgressMaterial.BLEND, value);
  	}
  	get blendSrc() {
  		return this._shaderValues.getInt(ProgressMaterial.BLEND_SRC);
  	}
  	set blendSrc(value) {
  		this._shaderValues.setInt(ProgressMaterial.BLEND_SRC, value);
  	}
  	get blendDst() {
  		return this._shaderValues.getInt(ProgressMaterial.BLEND_DST);
  	}
  	set blendDst(value) {
  		this._shaderValues.setInt(ProgressMaterial.BLEND_DST, value);
  	}
  	get depthTest() {
  		return this._shaderValues.getInt(ProgressMaterial.DEPTH_TEST);
  	}
  	set depthTest(value) {
  		this._shaderValues.setInt(ProgressMaterial.DEPTH_TEST, value);
  	}
  	get depthWrite() {
  		return this._shaderValues.getBool(ProgressMaterial.DEPTH_WRITE);
  	}
  	set depthWrite(value) {
  		this._shaderValues.setBool(ProgressMaterial.DEPTH_WRITE, value);
  	}
  	set renderMode(value) {
  		switch (value) {
  			case ProgressMaterial.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 ProgressMaterial.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 ProgressMaterial.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 ProgressMaterial.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 ProgressMaterial.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 ProgressMaterial.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("ProgressMaterial : renderMode value error.");
  		}
  	}
  }
  ProgressMaterial.ALBEDOTEXTURE = Laya.Shader3D.propertyNameToID("u_AlbedoTexture");
  ProgressMaterial.ALBEDOIDENTITY = Laya.Shader3D.propertyNameToID("u_AlbedoIdentity");
  ProgressMaterial.ALBEDOCOLOR = Laya.Shader3D.propertyNameToID("u_AlbedoColor");
  ProgressMaterial.SHARKTEXTURE = Laya.Shader3D.propertyNameToID("u_SharkTexture");
  ProgressMaterial.SHARKIDENTITY = Laya.Shader3D.propertyNameToID("u_SharkIdentity");
  ProgressMaterial.PROGRESS = Laya.Shader3D.propertyNameToID("u_Progress");
  ProgressMaterial.TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_TilingOffset");
  ProgressMaterial.WHOLE_ALPHA = Laya.Shader3D.propertyNameToID("u_alpha");
  ProgressMaterial.CULL = Laya.Shader3D.propertyNameToID("s_Cull");
  ProgressMaterial.BLEND = Laya.Shader3D.propertyNameToID("s_Blend");
  ProgressMaterial.BLEND_SRC = Laya.Shader3D.propertyNameToID("s_BlendSrc");
  ProgressMaterial.BLEND_DST = Laya.Shader3D.propertyNameToID("s_BlendDst");
  ProgressMaterial.DEPTH_TEST = Laya.Shader3D.propertyNameToID("s_DepthTest");
  ProgressMaterial.DEPTH_WRITE = Laya.Shader3D.propertyNameToID("s_DepthWrite");
  ProgressMaterial.RENDERMODE_OPAQUE = 1;
  ProgressMaterial.RENDERMODE_CUTOUT = 2;
  ProgressMaterial.RENDERMODE_CUTOUT_CULL_NONE = 3;
  ProgressMaterial.RENDERMODE_TRANSPARENT = 4;
  ProgressMaterial.RENDERMODE_TRANSPARENT_CULL_NONE = 5;
  ProgressMaterial.RENDERMODE_TRANSPARENT_BLEND_ADD = 6;

  class BurnMaterial extends Laya.Material {
  	constructor() {
  		super();
  		this.setShaderName("BurnMaterial");
  		this._shaderValues.setNumber(BurnMaterial.ALBEDOIDENTITY, 0.5);
  		this._shaderValues.setVector(BurnMaterial.ALBEDOCOLOR, new Laya.Vector4(1.0, 1.0, 1.0, 1.0));
  		this.alpha = 1;
  		this.burnFactor = 0;
  		this._shaderValues.setVector(BurnMaterial.BRUN_TEXTURE_TILLING_OFFSET, new Laya.Vector4(4.0, 4.0, 0.0, 0.0));
  	}
  	static __init__() {
  		BurnMaterial.SHADERDEFINE_BONE = Laya.Shader3D.getDefineByName("BONE");
  		BurnMaterial.SHADERDEFINE_TILINGOFFSET = Laya.Shader3D.getDefineByName("TILINGOFFSET");
  		BurnMaterial.SHADERDEFINE_WHOLE_ALPHA = Laya.Shader3D.getDefineByName("WHOLE_ALPHA");
  		BurnMaterial.SHADERDEFINE_ALBEDOTEXTURE = Laya.Shader3D.getDefineByName("ALBEDOTEXTURE");
  		BurnMaterial.SHADERDEFINE_ALBEDOCOLOR = Laya.Shader3D.getDefineByName("ALBEDOCOLOR");
  	}
  	static initShader() {
  		BurnMaterial.__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_TilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BurnTexture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BurnTextureTillingOffset': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BurnFactor': Laya.Shader3D.PERIOD_MATERIAL,
  			"u_BurnAfterTexture": Laya.Shader3D.PERIOD_MATERIAL,
  			'u_Time': Laya.Shader3D.PERIOD_SCENE,
  		};
  		var BurnMaterial3D = Laya.Shader3D.add("BurnMaterial");
  		var subShader = new Laya.SubShader(attributeMap, uniformMap);
  		BurnMaterial3D.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 vec4 v_posView;
        
		#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	

			vec3 v_PositionWorld;
			#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;

			v_posView = gl_Position.xyzw;
		}`;
  		var ps1 = `
		#ifdef GL_FRAGMENT_PRECISION_HIGH
            precision highp float;
            precision highp int;
        #else
            precision mediump float;
            precision mediump int;
        #endif
	
		varying vec2 v_Texcoord0; 
		varying vec4 v_posView;

		#ifdef WHOLE_ALPHA
			uniform float u_alpha;
		#endif
		uniform sampler2D u_AlbedoTexture;
		uniform float u_AlbedoIdentity;
        uniform vec4 u_AlbedoColor;
        
		uniform sampler2D u_BurnTexture;
		uniform vec4 u_BurnTextureTillingOffset;
		uniform sampler2D u_BurnAfterTexture;
		uniform float u_Time;
		uniform float u_BurnFactor;
		
		vec3 DecodeLightmap(vec4 color) {
			return color.rgb*color.a*5.0;
		}
		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);
			#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
				//叠加全局透明度
				albedoTextureColor = vec4(albedoTextureColor.rgb, albedoTextureColor.a*u_alpha);
			#else
				albedoTextureColor = vec4(albedoTextureColor.rgb, albedoTextureColor.a);
			#endif
			
		
			vec2 texcoord = TransformUV(v_Texcoord0, u_BurnTextureTillingOffset);
            float value = texture2D(u_BurnTexture, texcoord).x;
			
			float dis = distance(v_Texcoord0, vec2(0.5,0.5));
			float inRange = step(dis, u_BurnFactor);
			float inThrough = step(dis, u_BurnFactor+0.1);
            float factor = inRange + (1.0 - inRange)*inThrough * (1.0 - (dis - u_BurnFactor)/0.1);
            // factor *= (value + factor);
            // factor = clamp(factor, 0.0, 1.0);
			//
			vec4 burnColor = texture2D(u_BurnAfterTexture, v_Texcoord0);
			gl_FragColor = albedoTextureColor * (1.0 - factor) + burnColor * factor;
		}
	
		void main() 
		{ 
			main_normal();
		}`;
  		subShader.addShaderPass(vs1, ps1, stateMap);
  	}
  	get albedoTexture() {
  		return this._shaderValues.getTexture(BurnMaterial.ALBEDOTEXTURE);
  	}
  	set albedoTexture(value) {
  		if (value) {
  			this._shaderValues.addDefine(BurnMaterial.SHADERDEFINE_ALBEDOTEXTURE);
  		}
  		else {
  			this._shaderValues.removeDefine(BurnMaterial.SHADERDEFINE_ALBEDOTEXTURE);
  		}
  		this._shaderValues.setTexture(BurnMaterial.ALBEDOTEXTURE, value);
  	}
  	get albedoColor() {
  		return this._shaderValues.getVector(BurnMaterial.ALBEDOCOLOR);
  	}
  	set albedoColor(value) {
  		if (value) {
  			this._defineDatas.add(BurnMaterial.SHADERDEFINE_ALBEDOCOLOR);
  		}
  		else {
  			this._defineDatas.remove(BurnMaterial.SHADERDEFINE_ALBEDOCOLOR);
  		}
  		this._shaderValues.setVector(BurnMaterial.ALBEDOCOLOR, value);
  	}
  	get albedoIdentity() {
  		return this._shaderValues.getNumber(BurnMaterial.ALBEDOIDENTITY);
  	}
  	set albedoIdentity(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(BurnMaterial.ALBEDOIDENTITY, value);
  	}
  	get tilingOffset() {
  		return this._shaderValues.getVector(BurnMaterial.TILINGOFFSET);
  	}
  	set tilingOffset(value) {
  		if (value) {
  			if (value.x != 1 || value.y != 1 || value.z != 0 || value.w != 0)
  				this._shaderValues.addDefine(BurnMaterial.SHADERDEFINE_TILINGOFFSET);
  			else
  				this._shaderValues.removeDefine(BurnMaterial.SHADERDEFINE_TILINGOFFSET);
  		}
  		else {
  			this._shaderValues.removeDefine(BurnMaterial.SHADERDEFINE_TILINGOFFSET);
  		}
  		this._shaderValues.setVector(BurnMaterial.TILINGOFFSET, value);
  	}
  	get BurnTillingOffset() {
  		return this._shaderValues.getVector(BurnMaterial.BRUN_TEXTURE_TILLING_OFFSET);
  	}
  	set BurnTillingOffset(value) {
  		this._shaderValues.setVector(BurnMaterial.BRUN_TEXTURE_TILLING_OFFSET, value);
  	}
  	get burnTexture() {
  		return this._shaderValues.getTexture(BurnMaterial.BURNTEXTURE);
  	}
  	set burnTexture(value) {
  		this._shaderValues.setTexture(BurnMaterial.BURNTEXTURE, value);
  	}
  	get burnAfterTexture() {
  		return this._shaderValues.getTexture(BurnMaterial.BURNAFTERTEXTURE);
  	}
  	set burnAfterTexture(value) {
  		this._shaderValues.setTexture(BurnMaterial.BURNAFTERTEXTURE, value);
  	}
  	get burnFactor() {
  		return this._shaderValues.getNumber(BurnMaterial.BURN_FACTOR);
  	}
  	set burnFactor(value) {
  		this._shaderValues.setNumber(BurnMaterial.BURN_FACTOR, value);
  	}
  	get alpha() {
  		return this._shaderValues.getNumber(BurnMaterial.WHOLE_ALPHA);
  	}
  	set alpha(value) {
  		if (value != null) {
  			this._defineDatas.add(BurnMaterial.SHADERDEFINE_WHOLE_ALPHA);
  		}
  		else {
  			this._defineDatas.remove(BurnMaterial.SHADERDEFINE_WHOLE_ALPHA);
  		}
  		this._shaderValues.setNumber(BurnMaterial.WHOLE_ALPHA, value);
  	}
  	get cull() {
  		return this._shaderValues.getInt(BurnMaterial.CULL);
  	}
  	set cull(value) {
  		this._shaderValues.setInt(BurnMaterial.CULL, value);
  	}
  	get blend() {
  		return this._shaderValues.getInt(BurnMaterial.BLEND);
  	}
  	set blend(value) {
  		this._shaderValues.setInt(BurnMaterial.BLEND, value);
  	}
  	get blendSrc() {
  		return this._shaderValues.getInt(BurnMaterial.BLEND_SRC);
  	}
  	set blendSrc(value) {
  		this._shaderValues.setInt(BurnMaterial.BLEND_SRC, value);
  	}
  	get blendDst() {
  		return this._shaderValues.getInt(BurnMaterial.BLEND_DST);
  	}
  	set blendDst(value) {
  		this._shaderValues.setInt(BurnMaterial.BLEND_DST, value);
  	}
  	get depthTest() {
  		return this._shaderValues.getInt(BurnMaterial.DEPTH_TEST);
  	}
  	set depthTest(value) {
  		this._shaderValues.setInt(BurnMaterial.DEPTH_TEST, value);
  	}
  	get depthWrite() {
  		return this._shaderValues.getBool(BurnMaterial.DEPTH_WRITE);
  	}
  	set depthWrite(value) {
  		this._shaderValues.setBool(BurnMaterial.DEPTH_WRITE, value);
  	}
  	set renderMode(value) {
  		switch (value) {
  			case BurnMaterial.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 BurnMaterial.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 BurnMaterial.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 BurnMaterial.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 BurnMaterial.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("BurnMaterial : renderMode value error.");
  		}
  	}
  }
  BurnMaterial.ALBEDOTEXTURE = Laya.Shader3D.propertyNameToID("u_AlbedoTexture");
  BurnMaterial.ALBEDOIDENTITY = Laya.Shader3D.propertyNameToID("u_AlbedoIdentity");
  BurnMaterial.ALBEDOCOLOR = Laya.Shader3D.propertyNameToID("u_AlbedoColor");
  BurnMaterial.TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_TilingOffset");
  BurnMaterial.WHOLE_ALPHA = Laya.Shader3D.propertyNameToID("u_alpha");
  BurnMaterial.BURNTEXTURE = Laya.Shader3D.propertyNameToID("u_BurnTexture");
  BurnMaterial.BRUN_TEXTURE_TILLING_OFFSET = Laya.Shader3D.propertyNameToID("u_BurnTextureTillingOffset");
  BurnMaterial.BURNAFTERTEXTURE = Laya.Shader3D.propertyNameToID("u_BurnAfterTexture");
  BurnMaterial.BURN_FACTOR = Laya.Shader3D.propertyNameToID("u_BurnFactor");
  BurnMaterial.CULL = Laya.Shader3D.propertyNameToID("s_Cull");
  BurnMaterial.BLEND = Laya.Shader3D.propertyNameToID("s_Blend");
  BurnMaterial.BLEND_SRC = Laya.Shader3D.propertyNameToID("s_BlendSrc");
  BurnMaterial.BLEND_DST = Laya.Shader3D.propertyNameToID("s_BlendDst");
  BurnMaterial.DEPTH_TEST = Laya.Shader3D.propertyNameToID("s_DepthTest");
  BurnMaterial.DEPTH_WRITE = Laya.Shader3D.propertyNameToID("s_DepthWrite");
  BurnMaterial.RENDERMODE_OPAQUE = 1;
  BurnMaterial.RENDERMODE_CUTOUT = 2;
  BurnMaterial.RENDERMODE_CUTOUT_CULL_NONE = 3;
  BurnMaterial.RENDERMODE_TRANSPARENT = 4;
  BurnMaterial.RENDERMODE_TRANSPARENT_CULL_NONE = 5;

  const CartoonStrokeVs = `
attribute vec4 a_Position; 
attribute vec3 a_Normal; 
attribute vec2 a_Texcoord0;
uniform mat4 u_MvpMatrix; 
uniform float u_OutlineWidth; 
uniform mat4 u_WorldMat;
uniform vec3 u_CameraPos;
varying vec2 v_Texcoord0;     
varying float v_outlineWidth;
varying vec3 v_Normal;
varying vec3 v_ViewDir;

#ifdef BONE
    const int c_MaxBoneCount = 24;
    attribute vec4 a_BoneIndices;
    attribute vec4 a_BoneWeights;
    uniform mat4 u_Bones[c_MaxBoneCount];
#endif

void main() 
{ 
    //局部坐标系下扩大模型
    vec4 position = vec4(a_Position.xyz + a_Normal * u_OutlineWidth, 1.0);

    #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;
        position = skinTransform * position;
        mat3 worldMat=mat3(u_WorldMat * skinTransform);
    #else
        mat3 worldMat=mat3(u_WorldMat);
    #endif

    v_Texcoord0 = a_Texcoord0;	
    gl_Position = u_MvpMatrix * position; 
    gl_Position.z=gl_Position.z * 2.0 - gl_Position.w;
}`;
  const CartoonStrokeFs = `
#ifdef FSHIGHPRECISION 
   precision highp float; 
#else 
   precision mediump float; 
#endif 

varying vec2 v_Texcoord0; 

uniform float u_OutlineBlend; 
uniform vec4 u_OutlineColor;
uniform float u_RandomDiscardFactor;

uniform sampler2D u_PaintLayer1Texture;
uniform vec4 u_PaintLayer1TilingOffset;
uniform sampler2D u_PaintLayer2Texture;
uniform vec4 u_PaintLayer2TilingOffset;

uniform float u_Time;
uniform float u_AlphaTestValue;
#ifdef SHADERDEFINE_CUT_TEXTURE
uniform sampler2D u_CutTexture;
#endif

varying float v_outlineWidth;
varying vec3 v_Normal;
varying vec3 v_ViewDir;

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() 
{ 
    vec4 albedoTextureColor = vec4(0.0);
    #ifdef LAYER1_TEXTURE
        // 计算层级1的颜色
        vec2 texcoordL1 = TransformUV(v_Texcoord0, u_PaintLayer1TilingOffset);
        vec4 paintLayer1Color = texture2D(u_PaintLayer1Texture, texcoordL1);
        // 层级1的颜色混合
        albedoTextureColor.rgb = albedoTextureColor.rgb * (1.0 - paintLayer1Color.a) + paintLayer1Color.rgb;
        albedoTextureColor.a = albedoTextureColor.a * (1.0 - paintLayer1Color.a) + paintLayer1Color.a;
    #endif

    #ifdef LAYER2_TEXTURE
        // 计算层级2的颜色
        vec2 texcoordL2 = TransformUV(v_Texcoord0, u_PaintLayer2TilingOffset);
        vec4 paintLayer2Color = texture2D(u_PaintLayer2Texture, texcoordL2);
        // 层级2的颜色混合
        // albedoTextureColor.rgba = albedoTextureColor.rgba * (1.0 - paintLayer2Color.a) + paintLayer2Color.a * paintLayer2Color.rgba;
        albedoTextureColor.rgb = albedoTextureColor.rgb * (1.0 - paintLayer2Color.a) + paintLayer2Color.rgb;
        albedoTextureColor.a = albedoTextureColor.a * (1.0 - paintLayer2Color.a) + paintLayer2Color.a;
    #endif

    #ifdef SHADERDEFINE_CUT_TEXTURE
        vec2 texcoordCutTexture = vec2(v_Texcoord0.x, v_Texcoord0.y);
        vec4 cutTextureColor = texture2D(u_CutTexture, texcoordCutTexture);
        //r 通道表示可裁剪区域, r通道随时间显示为红色的; b通道表示是否展示可裁剪区域.
        // float f1 = cutTextureColor.r * cutTextureColor.b * (cos(u_Time*2.5)/2.0 + 0.5);
        // albedoTextureColor.rgb = albedoTextureColor.rgb * (1.0 - f1) + vec3(0.9,0.9,1.0) * f1;
        // g通道表示已裁剪区域;
        albedoTextureColor.a *= (1.0 - cutTextureColor.g * cutTextureColor.r);
    #endif

    if(albedoTextureColor.a <= u_AlphaTestValue){
        discard;
    }

    vec3 outlineTextureColor = u_OutlineColor.rgb*albedoTextureColor.rgb*albedoTextureColor.rgb * u_OutlineBlend + albedoTextureColor.rgb * (1.0 - u_OutlineBlend);
    gl_FragColor = vec4(outlineTextureColor,albedoTextureColor.a); 
}`;

  class CartoonHairMaterial extends Laya.Material {
  	constructor() {
  		super();
  		this.setShaderName("CartoonHairMaterial");
  		this._shaderValues.setVector(CartoonHairMaterial.SHADOWCOLOR, new Laya.Vector4(0.6663285, 0.6544118, 1, 1));
  		this.outlineWidth = 0.001;
  		this.outlineColor = new Laya.Vector4(0.5, 0.5, 0.5, 1);
  		this.outlineBlend = 1;
  		this.shadowEdge0 = 0;
  		this.shadowEdge1 = 0.1;
  		this.shadowColor = new Laya.Vector4(0.5, 0.5, 0.5, 1);
  		this.brightColor = new Laya.Vector4(1, 1, 1, 1);
  		this.hightlightShininess = 2.0;
  		this.hightlightItensity = 0.5;
  		this.edgeHightlightColor = new Laya.Vector4(1.0, 1.0, 1.0, 1.0);
  		this.edgeHightlightEdge0 = 0.6;
  		this.edgeHightlightEdge1 = 0.5;
  		this._shaderValues.setNumber(CartoonHairMaterial.NORMAL_SCALE, 1.0);
  		this._shaderValues.setNumber(CartoonHairMaterial.DETAIL_NORMAL_SCALE, 1.0);
  		this.normalTextureScale = 1;
  		this.detailNormalTextureScale = 1;
  		this.paintLayer1TilingOffset = new Laya.Vector4(1, 1, 0, 0);
  		this.detailNormalTextureTillingOffset = new Laya.Vector4(1, 1, 0, 0);
  		this.smoothness = 0.0;
  		this.metallic = 0.0;
  		this.FadeColor = new Laya.Vector4;
  		this.FadeFactor = 0.0;
  		this.alphaTestValue = 0.5;
  		this.alpha = 1;
  		this.bUseGlobalLight = false;
  	}
  	static __init__() {
  		CartoonHairMaterial.SHADERDEFINE_ALBEDOCOLOR = Laya.Shader3D.getDefineByName("ALBEDOCOLOR");
  		CartoonHairMaterial.SHADERDEFINE_BONE = Laya.Shader3D.getDefineByName("BONE");
  		CartoonHairMaterial.SHADERDEFINE_WHOLE_ALPHA = Laya.Shader3D.getDefineByName("WHOLE_ALPHA");
  		CartoonHairMaterial.SHADERDEFINE_NORMALTEXTURE = Laya.Shader3D.getDefineByName("NORMALTEXTURE");
  		CartoonHairMaterial.SHADERDEFINE_DETAIL_NORMAL_TEXTURE = Laya.Shader3D.getDefineByName("DETAIL_NORMAL_TEXTURE");
  		CartoonHairMaterial.SHADERDEFINE_LAYER1_TEXTURE = Laya.Shader3D.getDefineByName("LAYER1_TEXTURE");
  		CartoonHairMaterial.SHADERDEFINE_LAYER2_TEXTURE = Laya.Shader3D.getDefineByName("LAYER2_TEXTURE");
  		CartoonHairMaterial.SHADERDEFINE_REFLECT_CUBE = Laya.Shader3D.getDefineByName("REFLECT_CUBE");
  		CartoonHairMaterial.SHADERDEFINE_FRESNEL_REFLECTION = Laya.Shader3D.getDefineByName("FRESNEL_REFLECTION");
  		CartoonHairMaterial.SHADERDEFINE_DRAWING_MASK = Laya.Shader3D.getDefineByName("SHADERDEFINE_DRAWING_MASK");
  		CartoonHairMaterial.SHADERDEFINE_DRAWING_MASK_ZERO = Laya.Shader3D.getDefineByName("SHADERDEFINE_DRAWING_MASK_ZERO");
  		CartoonHairMaterial.SHADERDEFINE_GRAY = Laya.Shader3D.getDefineByName("SHADERDEFINE_GRAY");
  		CartoonHairMaterial.SHADERDEFINE_PROGRESS = Laya.Shader3D.getDefineByName("SHADERDEFINE_PROGRESS");
  		CartoonHairMaterial.SHADERDEFINE_BURN = Laya.Shader3D.getDefineByName("SHADERDEFINE_BURN");
  		CartoonHairMaterial.SHADERDEFINE_BURN_INVERST = Laya.Shader3D.getDefineByName("SHADERDEFINE_BURN_INVERST");
  		CartoonHairMaterial.SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR = Laya.Shader3D.getDefineByName("SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR");
  	}
  	static initShader() {
  		CartoonHairMaterial.__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_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_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_PaintLayer1Texture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_PaintLayer1TilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_PaintLayer2Texture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_PaintLayer2TilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
  			"u_fade_factor": Laya.Shader3D.PERIOD_MATERIAL,
  			"u_fade_color": Laya.Shader3D.PERIOD_MATERIAL,
  			'u_AlphaTestValue': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_Progress': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BurnTexture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BurnFactor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BurnTextureTillingOffset': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_OutlineWidth': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_OutlineBlend': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_OutlineColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_ShadowColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BrightColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_ShadowEdge0': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_ShadowEdge1': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_LightMap': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_HightlightShininess': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_HightlightItensity': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_EdgeHightlightEdge0': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_EdgeHightlightEdge1': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_EdgeHightlightColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_ViewProjection': Laya.Shader3D.PERIOD_CAMERA,
  		};
  		var vs1 = CartoonStrokeVs;
  		var ps1 = CartoonStrokeFs;
  		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;

		varying vec4 v_posView;

		#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; 

			v_posView = gl_Position.xyzw;
			gl_Position.z=gl_Position.z * 2.0 - gl_Position.w;
		}`;
  		var ps2 = `
		#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;
		};
		uniform DirectionLight u_SunLight;

		#ifdef SPOTLIGHT
			struct SpotLight {
				vec3 color;
				vec3 position;
				float range;
				vec3 direction;
				float spot;
			};
			uniform SpotLight u_SpotLight;
		#endif

		#ifdef ALBEDOCOLOR
			uniform vec4 u_AlbedoColor;
		#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

		#ifdef SHADERDEFINE_BURN
			uniform float u_BurnFactor;
			uniform sampler2D u_BurnTexture;
			uniform vec4 u_BurnTextureTillingOffset;
		#endif

		varying vec2 v_Texcoord0;
		varying vec3 v_Normal;
		varying vec3 v_PositionWorld;
		varying vec3 v_ViewDir;
		varying vec3 v_worldPos;
		varying vec4 v_posView;
		varying float v_viewDistance;

		uniform vec4 u_ShadowColor;
		uniform vec4 u_BrightColor;
		uniform float u_ShadowEdge0;
		uniform float u_ShadowEdge1;
		uniform sampler2D u_LightMap;
		uniform vec3 u_LightMapForward;
		uniform vec3 u_LightMapRight;
		uniform float u_LightMapBound;
		uniform float u_HightlightShininess;
		uniform float u_HightlightItensity;

		uniform float u_EdgeHightlightEdge0;
		uniform float u_EdgeHightlightEdge1;
		uniform vec4 u_EdgeHightlightColor;
		
		//喷绘相关
		uniform sampler2D u_PaintLayer1Texture;
		uniform vec4 u_PaintLayer1TilingOffset;
		uniform sampler2D u_PaintLayer2Texture;
		uniform vec4 u_PaintLayer2TilingOffset;

		uniform float u_fade_factor;
		uniform vec4 u_fade_color;
		

		#ifdef WHOLE_ALPHA
		uniform float u_alpha;
		#endif

		uniform float u_AlphaTestValue;
		uniform float u_Progress;


		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_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 disCamera = clamp(v_viewDistance, minv, maxv);
				float scalefactor = 1.0 - (disCamera - 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(0.0);
			
			
			vec2 texcoord = vec2(v_Texcoord0.x, 1.0 - v_Texcoord0.y);
			#ifdef LAYER1_TEXTURE
				// 计算层级1的颜色
				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;
			#endif

			#ifdef LAYER2_TEXTURE
				// 计算层级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.rgba = albedoTextureColor.rgba * (1.0 - paintLayer2Color.a) + paintLayer2Color.a * paintLayer2Color.rgba;
				albedoTextureColor.rgb = albedoTextureColor.rgb * (1.0 - paintLayer2Color.a) + paintLayer2Color.rgb;
				albedoTextureColor.a = albedoTextureColor.a * (1.0 - paintLayer2Color.a) + paintLayer2Color.a;
			#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 SHADERDEFINE_PROGRESS
				float through = 0.02;
				float halfTh = through/2.0;
				float realP = v_posView.y/v_posView.w * 0.5 + 0.5;
				//是否在进度跳
				float fInP = step(realP, u_Progress - halfTh);
				float fInNP = step(u_Progress + halfTh, realP);
				float aFactor = fInNP * 0.0 + fInP * 1.0 + (1.0 - fInP)*(1.0-fInNP)*(1.0 - (realP - u_Progress + halfTh)/through);
				albedoTextureColor.a *= aFactor;
			#endif

			#ifdef SHADERDEFINE_BURN
				#ifdef SHADERDEFINE_BURN_INVERST
					//噪波图的当前值
					float value = texture2D(u_BurnTexture, TransformUV(v_Texcoord0, u_BurnTextureTillingOffset)).x;

					float disburn = distance(v_posView.xyz/v_posView.w, vec3(0,0,0));
					disburn += value;
					float through = 0.02;

					float inMaxRange = step(disburn , u_BurnFactor + through*2.0);
					float outSecondRange = step(u_BurnFactor + through, disburn);
					float inFirst = inMaxRange * outSecondRange;
					
					float inSencondRange = step(disburn, u_BurnFactor + through);
					float outThirdRange = step(u_BurnFactor, disburn);
					float inSecond = inSencondRange * outThirdRange;

					float inThird = step(disburn, u_BurnFactor);
					float inFourth = (1.0 - inFirst) * (1.0 - inSecond) * (1.0 - inThird);

					vec4 outColor = vec4(236.0/255.0, 131.0/255.0, 255.0/255.0, albedoTextureColor.a);
					vec4 secondColor = vec4(245.0/255.0, 228.0/255.0, 255.0/255.0, albedoTextureColor.a);
					vec4 thirdColor = albedoTextureColor.rgba;
					vec4 forthColor = vec4(0.0,0.0,0.0,0.0);

					albedoTextureColor = outColor*inFirst + secondColor*inSecond + inThird * thirdColor + forthColor * inFourth;

					// if(disburn < u_BurnFactor + through*2.0 && disburn >= u_BurnFactor + through){
					// 	albedoTextureColor.a = albedoTextureColor.a;
					// 	albedoTextureColor.rgb = vec3(236.0/255.0, 131.0/255.0, 255.0/255.0);
					// }
					// else if(disburn < u_BurnFactor + through && disburn >= u_BurnFactor){
					// 	albedoTextureColor.a = albedoTextureColor.a;
					// 	albedoTextureColor.rgb = vec3(245.0/255.0, 228.0/255.0, 255.0/255.0);
					// }
					// else if(disburn > u_BurnFactor){
					// 	albedoTextureColor.a = 0.0;
					// }
					// else{
					// 	albedoTextureColor.a = albedoTextureColor.a;
					// }
				#else
					//噪波图的当前值
					float value = texture2D(u_BurnTexture, TransformUV(v_Texcoord0, u_BurnTextureTillingOffset)).x;

					float disburn = distance(v_posView.xyz/v_posView.w, vec3(0,0,0));
					disburn += value;
					float through = 0.02;

					float inMaxRange = step(disburn , u_BurnFactor + through*2.0);
					float outSecondRange = step(u_BurnFactor + through, disburn);
					float inFirst = inMaxRange * outSecondRange;
					
					float inSencondRange = step(disburn, u_BurnFactor + through);
					float outThirdRange = step(u_BurnFactor, disburn);
					float inSecond = inSencondRange * outThirdRange;

					float inThird = step(disburn, u_BurnFactor);
					float inFourth = (1.0 - inFirst) * (1.0 - inSecond) * (1.0 - inThird);

					vec4 outColor = vec4(236.0/255.0, 131.0/255.0, 255.0/255.0, albedoTextureColor.a);
					vec4 secondColor = vec4(245.0/255.0, 228.0/255.0, 255.0/255.0, albedoTextureColor.a);
					vec4 thirdColor = vec4(0.0,0.0,0.0,0.0);
					vec4 forthColor = albedoTextureColor.rgba;
					
					albedoTextureColor = outColor*inFirst + secondColor*inSecond + inThird * thirdColor + forthColor * inFourth;

					// if(disburn < u_BurnFactor + through*2.0 && disburn >= u_BurnFactor + through){
					// 	albedoTextureColor.a = albedoTextureColor.a;
					// 	albedoTextureColor.rgb = vec3(245.0/255.0, 228.0/255.0, 255.0/255.0);
					// }
					// else if(disburn < u_BurnFactor + through && disburn >= u_BurnFactor){
					// 	albedoTextureColor.a = albedoTextureColor.a;
					// 	albedoTextureColor.rgb = vec3(236.0/255.0, 131.0/255.0, 255.0/255.0);
					// }
					// else if(disburn < u_BurnFactor){
					// 	albedoTextureColor.a = 0.0;
					// }
					// else{
					// 	albedoTextureColor.a = albedoTextureColor.a;
					// }
				#endif
			#endif
			
			#ifdef ALPHATEST
				if(albedoTextureColor.a <= u_AlphaTestValue){
					discard;
				}
			#endif

			#ifdef ALBEDOCOLOR
				albedoTextureColor *= u_AlbedoColor;
			#endif
		
			//屏蔽掉卡通色转换, 使用模型原始颜色
			vec3 albedoColor = albedoTextureColor.rgb;
	
			///////////////// 头发cartoonShader ////////////////
			//使用lightMap
			vec2 texcoordLightMap = vec2(v_Texcoord0.x, v_Texcoord0.y);
			vec4 lightMapColor = texture2D(u_LightMap, texcoordLightMap);

			// #ifdef SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR
			// 	vec3 brightColor = u_SunLight.color;
			// #else
			// 	vec3 brightColor = u_BrightColor.rgb;
			// #endif

			vec3 brightColor = u_BrightColor.rgb;

			//使用通道图控制光照
			float ndotl = max(dot(normal, -lightDir), 0.0);
			float wrapLambert = ndotl + lightMapColor.g;
			float shadowStep = smoothstep(u_ShadowEdge0, u_ShadowEdge1, wrapLambert);
			vec3 shadowColor = u_ShadowColor.rgb * (1.0-shadowStep) + brightColor * shadowStep;

			vec3 finalColor = shadowColor;
			//计算高光部分
			finalColor += pow(max(dot(viewdir, normal), 0.0), u_HightlightShininess) * lightMapColor.b * u_HightlightItensity;
			

			//计算边缘高光部分
			float ndotv = max(dot(normal, viewdir), 0.0);
			float edgeHightlightStep = smoothstep(u_EdgeHightlightEdge0,u_EdgeHightlightEdge1, ndotv);
			finalColor = u_EdgeHightlightColor.rgb *2.0*finalColor* edgeHightlightStep + finalColor * (1.0 - edgeHightlightStep);
			
			
			finalColor.rgb *= albedoColor.rgb;

			#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 = albedoColor.rgb * inSpot * inDir * 0.5;
				vec3 sunColor = u_SunLight.color * albedoColor.rgb;

				finalColor *= spotColor + sunColor;
			#else
				finalColor *= u_SunLight.color;
			#endif

			#ifdef SHADERDEFINE_GRAY
				float ff = (finalColor.r + finalColor.g + finalColor.b)/3.0;
				finalColor.rgb = vec3(ff, ff, ff);
			#endif

			#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();
		}`;
  		var CartoonHairMaterial3D = Laya.Shader3D.add("CartoonHairMaterial", attributeMap, uniformMap, true);
  		var subShader = new Laya.SubShader(attributeMap, uniformMap);
  		CartoonHairMaterial3D.addSubShader(subShader);
  		var pass1 = subShader.addShaderPass(vs1, ps1);
  		pass1.renderState.cull = Laya.RenderState.CULL_FRONT;
  		subShader.addShaderPass(vs2, ps2, stateMap, "Forward");
  		subShader.addShaderPass(PBRShadowCasterVS, PBRShadowCasterPS, stateMap, "ShadowCaster");
  	}
  	get cull() {
  		return this._shaderValues.getInt(CartoonHairMaterial.CULL);
  	}
  	set cull(value) {
  		this._shaderValues.setInt(CartoonHairMaterial.CULL, value);
  	}
  	get blend() {
  		return this._shaderValues.getInt(CartoonHairMaterial.BLEND);
  	}
  	set blend(value) {
  		this._shaderValues.setInt(CartoonHairMaterial.BLEND, value);
  	}
  	get blendSrc() {
  		return this._shaderValues.getInt(CartoonHairMaterial.BLEND_SRC);
  	}
  	set blendSrc(value) {
  		this._shaderValues.setInt(CartoonHairMaterial.BLEND_SRC, value);
  	}
  	get blendDst() {
  		return this._shaderValues.getInt(CartoonHairMaterial.BLEND_DST);
  	}
  	set blendDst(value) {
  		this._shaderValues.setInt(CartoonHairMaterial.BLEND_DST, value);
  	}
  	get depthTest() {
  		return this._shaderValues.getInt(CartoonHairMaterial.DEPTH_TEST);
  	}
  	set depthTest(value) {
  		this._shaderValues.setInt(CartoonHairMaterial.DEPTH_TEST, value);
  	}
  	get depthWrite() {
  		return this._shaderValues.getBool(CartoonHairMaterial.DEPTH_WRITE);
  	}
  	set depthWrite(value) {
  		this._shaderValues.setBool(CartoonHairMaterial.DEPTH_WRITE, value);
  	}
  	get renderMode() {
  		return this.__render_mode__;
  	}
  	set renderMode(value) {
  		this.__render_mode__ = value;
  		switch (value) {
  			case CartoonHairMaterial.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 CartoonHairMaterial.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 CartoonHairMaterial.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 CartoonHairMaterial.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 CartoonHairMaterial.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 CartoonHairMaterial.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 bBurnInvert() {
  		return this._shaderValues.hasDefine(CartoonHairMaterial.SHADERDEFINE_BURN_INVERST);
  	}
  	set bBurnInvert(value) {
  		if (value) {
  			this._shaderValues.addDefine(CartoonHairMaterial.SHADERDEFINE_BURN_INVERST);
  		}
  		else {
  			this._shaderValues.removeDefine(CartoonHairMaterial.SHADERDEFINE_BURN_INVERST);
  		}
  	}
  	get burnFactor() {
  		return this._shaderValues.getNumber(CartoonHairMaterial.BURN_FACTOR);
  	}
  	set burnFactor(value) {
  		if (value != null) {
  			value = Math.max(0.0, value);
  			this._shaderValues.setNumber(CartoonHairMaterial.BURN_FACTOR, value);
  		}
  	}
  	get burnTexture() {
  		return this._shaderValues.getTexture(CartoonHairMaterial.BURNTEXTURE);
  	}
  	set burnTexture(value) {
  		if (value) {
  			this._defineDatas.add(CartoonHairMaterial.SHADERDEFINE_BURN);
  			this._shaderValues.setTexture(CartoonHairMaterial.BURNTEXTURE, value);
  		}
  		else {
  			this._defineDatas.remove(CartoonHairMaterial.SHADERDEFINE_BURN);
  		}
  	}
  	get BurnTillingOffset() {
  		return this._shaderValues.getVector(CartoonHairMaterial.BRUN_TEXTURE_TILLING_OFFSET);
  	}
  	set BurnTillingOffset(value) {
  		this._shaderValues.setVector(CartoonHairMaterial.BRUN_TEXTURE_TILLING_OFFSET, value);
  	}
  	get mprogress() {
  		return this._shaderValues.getNumber(CartoonHairMaterial.PROGRESS);
  	}
  	set mprogress(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonHairMaterial.SHADERDEFINE_PROGRESS);
  			value = Math.max(0.0, value);
  			this._shaderValues.setNumber(CartoonHairMaterial.PROGRESS, value);
  		}
  		else {
  			this._defineDatas.remove(CartoonHairMaterial.SHADERDEFINE_PROGRESS);
  		}
  	}
  	get gray() {
  		if (this._defineDatas.has(CartoonHairMaterial.SHADERDEFINE_GRAY)) {
  			return true;
  		}
  		else {
  			return false;
  		}
  	}
  	set gray(value) {
  		if (value) {
  			this._defineDatas.add(CartoonHairMaterial.SHADERDEFINE_GRAY);
  		}
  		else {
  			this._defineDatas.remove(CartoonHairMaterial.SHADERDEFINE_GRAY);
  		}
  	}
  	get albedoColor() {
  		return this._shaderValues.getVector(CartoonHairMaterial.ALBEDOCOLOR);
  	}
  	set albedoColor(value) {
  		if (value) {
  			this._defineDatas.add(CartoonHairMaterial.SHADERDEFINE_ALBEDOCOLOR);
  		}
  		else {
  			this._defineDatas.remove(CartoonHairMaterial.SHADERDEFINE_ALBEDOCOLOR);
  		}
  		this._shaderValues.setVector(CartoonHairMaterial.ALBEDOCOLOR, value);
  	}
  	get shadowColor() {
  		return this._shaderValues.getVector(CartoonHairMaterial.SHADOWCOLOR);
  	}
  	set shadowColor(value) {
  		this._shaderValues.setVector(CartoonHairMaterial.SHADOWCOLOR, value);
  	}
  	get brightColor() {
  		return this._shaderValues.getVector(CartoonHairMaterial.BRIGHTCOLOR);
  	}
  	set brightColor(value) {
  		this._shaderValues.setVector(CartoonHairMaterial.BRIGHTCOLOR, value);
  	}
  	get shadowEdge0() {
  		return this._shaderValues.getNumber(CartoonHairMaterial.SHADOWEDGE0);
  	}
  	set shadowEdge0(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(CartoonHairMaterial.SHADOWEDGE0, value);
  	}
  	get shadowEdge1() {
  		return this._shaderValues.getNumber(CartoonHairMaterial.SHADOWEDGE1);
  	}
  	set shadowEdge1(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(CartoonHairMaterial.SHADOWEDGE1, value);
  	}
  	get lightmap() {
  		return this._shaderValues.getTexture(CartoonHairMaterial.LIGHTMAP);
  	}
  	set lightmap(value) {
  		this._shaderValues.setTexture(CartoonHairMaterial.LIGHTMAP, value);
  	}
  	get hightlightShininess() {
  		return this._shaderValues.getNumber(CartoonHairMaterial.HIGHLIGHT_SHININESS);
  	}
  	set hightlightShininess(value) {
  		this._shaderValues.setNumber(CartoonHairMaterial.HIGHLIGHT_SHININESS, value);
  	}
  	get hightlightItensity() {
  		return this._shaderValues.getNumber(CartoonHairMaterial.HIGHLIGHT_ITENSITY);
  	}
  	set hightlightItensity(value) {
  		this._shaderValues.setNumber(CartoonHairMaterial.HIGHLIGHT_ITENSITY, value);
  	}
  	get alpha() {
  		return this._shaderValues.getNumber(CartoonHairMaterial.WHOLE_ALPHA);
  	}
  	set alpha(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonHairMaterial.SHADERDEFINE_WHOLE_ALPHA);
  		}
  		else {
  			this._defineDatas.remove(CartoonHairMaterial.SHADERDEFINE_WHOLE_ALPHA);
  		}
  		this._shaderValues.setNumber(CartoonHairMaterial.WHOLE_ALPHA, value);
  	}
  	get albedoTexture() {
  		return this._shaderValues.getTexture(CartoonHairMaterial.PAINT_LAYER1_TEXTURE);
  	}
  	set albedoTexture(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonHairMaterial.SHADERDEFINE_LAYER1_TEXTURE);
  		}
  		else {
  			this._defineDatas.remove(CartoonHairMaterial.SHADERDEFINE_LAYER1_TEXTURE);
  		}
  		this._shaderValues.setTexture(CartoonHairMaterial.PAINT_LAYER1_TEXTURE, value);
  	}
  	get paintLayer1TilingOffset() {
  		return this._shaderValues.getVector(CartoonHairMaterial.PAINT_LAYER1_TILINGOFFSET);
  	}
  	set paintLayer1TilingOffset(value) {
  		this._shaderValues.setVector(CartoonHairMaterial.PAINT_LAYER1_TILINGOFFSET, value);
  	}
  	get paintLayer2Texture() {
  		return this._shaderValues.getTexture(CartoonHairMaterial.PAINT_LAYER2_TEXTURE);
  	}
  	set paintLayer2Texture(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonHairMaterial.SHADERDEFINE_LAYER2_TEXTURE);
  		}
  		else {
  			this._defineDatas.remove(CartoonHairMaterial.SHADERDEFINE_LAYER2_TEXTURE);
  		}
  		this._shaderValues.setTexture(CartoonHairMaterial.PAINT_LAYER2_TEXTURE, value);
  	}
  	get paintLayer2TilingOffset() {
  		return this._shaderValues.getVector(CartoonHairMaterial.PAINT_LAYER2_TILINGOFFSET);
  	}
  	set paintLayer2TilingOffset(value) {
  		this._shaderValues.setVector(CartoonHairMaterial.PAINT_LAYER2_TILINGOFFSET, value);
  	}
  	get normalTexture() {
  		return this._shaderValues.getTexture(CartoonHairMaterial.NORMAL_TEXTURE);
  	}
  	set normalTexture(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonHairMaterial.SHADERDEFINE_NORMALTEXTURE);
  		}
  		else {
  			this._defineDatas.remove(CartoonHairMaterial.SHADERDEFINE_NORMALTEXTURE);
  		}
  		this._shaderValues.setTexture(CartoonHairMaterial.NORMAL_TEXTURE, value);
  	}
  	get normalTextureScale() {
  		return this._shaderValues.getNumber(CartoonHairMaterial.NORMAL_SCALE);
  	}
  	set normalTextureScale(value) {
  		this._shaderValues.setNumber(CartoonHairMaterial.NORMAL_SCALE, value);
  	}
  	get normalTextureTillingOffset() {
  		return this._shaderValues.getVector(CartoonHairMaterial.NORMAL_TILLING_OFFSET);
  	}
  	set normalTextureTillingOffset(value) {
  		this._shaderValues.setVector(CartoonHairMaterial.NORMAL_TILLING_OFFSET, value);
  	}
  	get detailNormalTexture() {
  		return this._shaderValues.getTexture(CartoonHairMaterial.DETAIL_NORMAL_TEXTURE);
  	}
  	set detailNormalTexture(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonHairMaterial.SHADERDEFINE_DETAIL_NORMAL_TEXTURE);
  		}
  		else {
  			this._defineDatas.remove(CartoonHairMaterial.SHADERDEFINE_DETAIL_NORMAL_TEXTURE);
  		}
  		this._shaderValues.setTexture(CartoonHairMaterial.DETAIL_NORMAL_TEXTURE, value);
  	}
  	get detailNormalTextureTillingOffset() {
  		return this._shaderValues.getVector(CartoonHairMaterial.DETAIL_NORMAL_TILLING_OFFSET);
  	}
  	set detailNormalTextureTillingOffset(value) {
  		this._shaderValues.setVector(CartoonHairMaterial.DETAIL_NORMAL_TILLING_OFFSET, value);
  	}
  	get detailNormalTextureScale() {
  		return this._shaderValues.getNumber(CartoonHairMaterial.DETAIL_NORMAL_SCALE);
  	}
  	set detailNormalTextureScale(value) {
  		this._shaderValues.setNumber(CartoonHairMaterial.DETAIL_NORMAL_SCALE, value);
  	}
  	get reflectionCube() {
  		return this._shaderValues.getTexture(CartoonHairMaterial.REFLECTION_CUBE);
  	}
  	set reflectionCube(value) {
  		if (value) {
  			this._defineDatas.add(CartoonHairMaterial.SHADERDEFINE_REFLECT_CUBE);
  		}
  		else {
  			this._defineDatas.remove(CartoonHairMaterial.SHADERDEFINE_REFLECT_CUBE);
  		}
  		this._shaderValues.setTexture(CartoonHairMaterial.REFLECTION_CUBE, value);
  	}
  	get smoothness() {
  		return this._shaderValues.getNumber(CartoonHairMaterial.SMOOTHNESS);
  	}
  	set smoothness(value) {
  		this._shaderValues.setNumber(CartoonHairMaterial.SMOOTHNESS, value);
  	}
  	get reflectionBoxCenter() {
  		return this._shaderValues.getVector3(CartoonHairMaterial.REFLECTION_BOX_CENTER);
  	}
  	set reflectionBoxCenter(value) {
  		this._shaderValues.setVector3(CartoonHairMaterial.REFLECTION_BOX_CENTER, value);
  	}
  	get reflectionBoxSize() {
  		return this._shaderValues.getVector3(CartoonHairMaterial.REFLECTION_BOX_SIZE);
  	}
  	set reflectionBoxSize(value) {
  		this._shaderValues.setVector3(CartoonHairMaterial.REFLECTION_BOX_SIZE, value);
  	}
  	get metallic() {
  		return this._shaderValues.getNumber(CartoonHairMaterial.METALLIC);
  	}
  	set metallic(value) {
  		this._shaderValues.setNumber(CartoonHairMaterial.METALLIC, value);
  	}
  	set bPickZero(value) {
  		if (value) {
  			this._defineDatas.add(CartoonHairMaterial.SHADERDEFINE_DRAWING_MASK_ZERO);
  		}
  		else {
  			this._defineDatas.remove(CartoonHairMaterial.SHADERDEFINE_DRAWING_MASK_ZERO);
  		}
  	}
  	set FadeColor(value) {
  		this._shaderValues.setVector(CartoonHairMaterial.FADE_COLOR, value);
  	}
  	set FadeFactor(value) {
  		this._shaderValues.setNumber(CartoonHairMaterial.FADE_FACTOR, value);
  	}
  	get alphaTestValue() {
  		return this._shaderValues.getNumber(Laya.Material.ALPHATESTVALUE) || 0;
  	}
  	set alphaTestValue(value) {
  		if (value == null)
  			return;
  		this._shaderValues.setNumber(Laya.Material.ALPHATESTVALUE, value);
  	}
  	get outlineWidth() {
  		return this._shaderValues.getNumber(CartoonHairMaterial.OUTLINEWIDTH);
  	}
  	set outlineWidth(value) {
  		value = Math.max(0.0, Math.min(0.05, value));
  		this._shaderValues.setNumber(CartoonHairMaterial.OUTLINEWIDTH, value);
  	}
  	get outlineColor() {
  		return this._shaderValues.getVector(CartoonHairMaterial.OUTLINECOLOR);
  	}
  	set outlineColor(value) {
  		this._shaderValues.setVector(CartoonHairMaterial.OUTLINECOLOR, value);
  	}
  	get outlineBlend() {
  		return this._shaderValues.getNumber(CartoonHairMaterial.OUTLINEBLEND);
  	}
  	set outlineBlend(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(CartoonHairMaterial.OUTLINEBLEND, value);
  	}
  	get edgeHightlightEdge0() {
  		return this._shaderValues.getNumber(CartoonHairMaterial.EDGE_HIGHTLIGHT_EDGE0);
  	}
  	set edgeHightlightEdge0(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(CartoonHairMaterial.EDGE_HIGHTLIGHT_EDGE0, value);
  	}
  	get edgeHightlightEdge1() {
  		return this._shaderValues.getNumber(CartoonHairMaterial.EDGE_HIGHTLIGHT_EDGE1);
  	}
  	set edgeHightlightEdge1(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(CartoonHairMaterial.EDGE_HIGHTLIGHT_EDGE1, value);
  	}
  	get edgeHightlightColor() {
  		return this._shaderValues.getVector(CartoonHairMaterial.EDGE_HIGHTLIGHT_COLOR);
  	}
  	set edgeHightlightColor(value) {
  		this._shaderValues.setVector(CartoonHairMaterial.EDGE_HIGHTLIGHT_COLOR, value);
  	}
  	get bUseGlobalLight() {
  		return this._defineDatas.has(CartoonHairMaterial.SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR);
  	}
  	set bUseGlobalLight(value) {
  		if (value) {
  			this._defineDatas.add(CartoonHairMaterial.SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR);
  		}
  		else {
  			this._defineDatas.remove(CartoonHairMaterial.SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR);
  		}
  	}
  	getCanEditorParamList() {
  		return [
  			{
  				name: `renderMode`, desc: `渲染模式`, type: EditorType.option, options: [
  					{ desc: "不透明", value: 1 },
  					{ desc: "裁剪", value: 2 },
  					{ desc: "裁剪双面", value: 3 },
  					{ desc: "透明", value: 4 },
  					{ desc: "透明双面", value: 5 },
  					{ desc: "不透明双面", value: 6 },
  				],
  			},
  			{ name: `outlineWidth`, desc: `描边宽度`, type: EditorType.slider, range: [0, 0.02, 4] },
  			{ name: `outlineColor`, desc: `描边颜色`, type: EditorType.color, },
  			{ name: `outlineBlend`, desc: `描边混合`, type: EditorType.slider, range: [0, 1] },
  			{ name: `alphaTestValue`, desc: `alpha裁剪参数`, type: EditorType.slider, range: [0, 1] },
  			{ name: `paintLayer1TilingOffset`, desc: `uv平铺`, type: EditorType.vec4 },
  			{ name: `renderQueue`, desc: `renderQueue`, type: EditorType.num },
  			{ name: `albedoColor`, desc: `基础色`, type: EditorType.color },
  			{ name: `lightmap`, desc: `阴影贴图`, type: EditorType.texture2d, options: mgrMaterial.textures },
  			{ name: `shadowColor`, desc: `阴影颜色`, type: EditorType.color },
  			{ name: `brightColor`, desc: `亮部颜色`, type: EditorType.color },
  			{ name: `shadowEdge0`, desc: `阴影边缘1`, type: EditorType.slider, range: [0, 1, 4] },
  			{ name: `shadowEdge1`, desc: `阴影边缘2`, type: EditorType.slider, range: [0, 1, 4] },
  			{ name: `hightlightShininess`, desc: `高光光泽度`, type: EditorType.slider, range: [0, 5, 4] },
  			{ name: `hightlightItensity`, desc: `高光强度`, type: EditorType.slider, range: [0, 1, 4] },
  			{ name: `edgeHightlightColor`, desc: `边缘高光颜色`, type: EditorType.color },
  			{ name: `edgeHightlightEdge0`, desc: `边缘高光边界1`, type: EditorType.slider, range: [0, 1, 4] },
  			{ name: `edgeHightlightEdge1`, desc: `边缘高光边界2`, type: EditorType.slider, range: [0, 1, 4] },
  		];
  	}
  }
  CartoonHairMaterial.ALBEDOCOLOR = Laya.Shader3D.propertyNameToID("u_AlbedoColor");
  CartoonHairMaterial.SHADOWCOLOR = Laya.Shader3D.propertyNameToID("u_ShadowColor");
  CartoonHairMaterial.BRIGHTCOLOR = Laya.Shader3D.propertyNameToID("u_BrightColor");
  CartoonHairMaterial.SHADOWEDGE0 = Laya.Shader3D.propertyNameToID("u_ShadowEdge0");
  CartoonHairMaterial.SHADOWEDGE1 = Laya.Shader3D.propertyNameToID("u_ShadowEdge1");
  CartoonHairMaterial.LIGHTMAP = Laya.Shader3D.propertyNameToID("u_LightMap");
  CartoonHairMaterial.HIGHLIGHT_SHININESS = Laya.Shader3D.propertyNameToID("u_HightlightShininess");
  CartoonHairMaterial.HIGHLIGHT_ITENSITY = Laya.Shader3D.propertyNameToID("u_HightlightItensity");
  CartoonHairMaterial.EDGE_HIGHTLIGHT_EDGE0 = Laya.Shader3D.propertyNameToID("u_EdgeHightlightEdge0");
  CartoonHairMaterial.EDGE_HIGHTLIGHT_EDGE1 = Laya.Shader3D.propertyNameToID("u_EdgeHightlightEdge1");
  CartoonHairMaterial.EDGE_HIGHTLIGHT_COLOR = Laya.Shader3D.propertyNameToID("u_EdgeHightlightColor");
  CartoonHairMaterial.DIRECTIONLIGHTDIRECTION = Laya.Shader3D.propertyNameToID("u_SunLight.direction");
  CartoonHairMaterial.DIRECTIONLIGHTCOLOR = Laya.Shader3D.propertyNameToID("u_SunLight.color");
  CartoonHairMaterial.SPOT_LIGHT_COLOR = Laya.Shader3D.propertyNameToID("u_SpotLight.color");
  CartoonHairMaterial.SPOT_LIGHT_DIRECTION = Laya.Shader3D.propertyNameToID("u_SpotLight.direction");
  CartoonHairMaterial.SPOT_LIGHT_RANGE = Laya.Shader3D.propertyNameToID("u_SpotLight.range");
  CartoonHairMaterial.SPOT_LIGHT_SPOT = Laya.Shader3D.propertyNameToID("u_SpotLight.spot");
  CartoonHairMaterial.SPOT_LIGHT_POSITION = Laya.Shader3D.propertyNameToID("u_SpotLight.position");
  CartoonHairMaterial.WHOLE_ALPHA = Laya.Shader3D.propertyNameToID("u_alpha");
  CartoonHairMaterial.NORMAL_TEXTURE = Laya.Shader3D.propertyNameToID("u_NormalTexture");
  CartoonHairMaterial.NORMAL_SCALE = Laya.Shader3D.propertyNameToID("u_NormalScale");
  CartoonHairMaterial.NORMAL_TILLING_OFFSET = Laya.Shader3D.propertyNameToID("u_NormalTillingOffset");
  CartoonHairMaterial.DETAIL_NORMAL_TEXTURE = Laya.Shader3D.propertyNameToID("u_DetailNormalTexture");
  CartoonHairMaterial.DETAIL_NORMAL_TILLING_OFFSET = Laya.Shader3D.propertyNameToID("u_DetailNormalTillingOffset");
  CartoonHairMaterial.DETAIL_NORMAL_SCALE = Laya.Shader3D.propertyNameToID("u_DetailNormalScale");
  CartoonHairMaterial.REFLECTION_CUBE = Laya.Shader3D.propertyNameToID("u_reflection_cube");
  CartoonHairMaterial.SMOOTHNESS = Laya.Shader3D.propertyNameToID("u_Smoothness");
  CartoonHairMaterial.METALLIC = Laya.Shader3D.propertyNameToID("u_Metallic");
  CartoonHairMaterial.REFLECTION_BOX_CENTER = Laya.Shader3D.propertyNameToID("u_reflection_box_center");
  CartoonHairMaterial.REFLECTION_BOX_SIZE = Laya.Shader3D.propertyNameToID("u_reflection_box_size");
  CartoonHairMaterial.FADE_FACTOR = Laya.Shader3D.propertyNameToID("u_fade_factor");
  CartoonHairMaterial.FADE_COLOR = Laya.Shader3D.propertyNameToID("u_fade_color");
  CartoonHairMaterial.PROGRESS = Laya.Shader3D.propertyNameToID("u_Progress");
  CartoonHairMaterial.BURN_FACTOR = Laya.Shader3D.propertyNameToID("u_BurnFactor");
  CartoonHairMaterial.BURNTEXTURE = Laya.Shader3D.propertyNameToID("u_BurnTexture");
  CartoonHairMaterial.BRUN_TEXTURE_TILLING_OFFSET = Laya.Shader3D.propertyNameToID("u_BurnTextureTillingOffset");
  CartoonHairMaterial.PAINT_LAYER1_TEXTURE = Laya.Shader3D.propertyNameToID("u_PaintLayer1Texture");
  CartoonHairMaterial.PAINT_LAYER1_TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_PaintLayer1TilingOffset");
  CartoonHairMaterial.PAINT_LAYER2_TEXTURE = Laya.Shader3D.propertyNameToID("u_PaintLayer2Texture");
  CartoonHairMaterial.PAINT_LAYER2_TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_PaintLayer2TilingOffset");
  CartoonHairMaterial.OUTLINEWIDTH = Laya.Shader3D.propertyNameToID("u_OutlineWidth");
  CartoonHairMaterial.OUTLINEBLEND = Laya.Shader3D.propertyNameToID("u_OutlineBlend");
  CartoonHairMaterial.OUTLINECOLOR = Laya.Shader3D.propertyNameToID("u_OutlineColor");
  CartoonHairMaterial.CULL = Laya.Shader3D.propertyNameToID("s_Cull");
  CartoonHairMaterial.BLEND = Laya.Shader3D.propertyNameToID("s_Blend");
  CartoonHairMaterial.BLEND_SRC = Laya.Shader3D.propertyNameToID("s_BlendSrc");
  CartoonHairMaterial.BLEND_DST = Laya.Shader3D.propertyNameToID("s_BlendDst");
  CartoonHairMaterial.DEPTH_TEST = Laya.Shader3D.propertyNameToID("s_DepthTest");
  CartoonHairMaterial.DEPTH_WRITE = Laya.Shader3D.propertyNameToID("s_DepthWrite");
  CartoonHairMaterial.RENDERMODE_OPAQUE = 1;
  CartoonHairMaterial.RENDERMODE_CUTOUT = 2;
  CartoonHairMaterial.RENDERMODE_CUTOUT_CULL_NONE = 3;
  CartoonHairMaterial.RENDERMODE_TRANSPARENT = 4;
  CartoonHairMaterial.RENDERMODE_TRANSPARENT_CULL_NONE = 5;
  CartoonHairMaterial.RENDERMODE_OPAQUE_CULL_NONE = 6;

  class CartoonFaceMaterial extends Laya.Material {
  	constructor() {
  		super();
  		this.setShaderName("CartoonFaceShader");
  		this._shaderValues.setVector(CartoonFaceMaterial.SHADOWCOLOR, new Laya.Vector4(0.6663285, 0.6544118, 1, 1));
  		this.renderMode = CartoonFaceMaterial.RENDERMODE_OPAQUE;
  		this.outlineWidth = 0.001;
  		this.outlineColor = new Laya.Vector4(0.5, 0.5, 0.5, 1);
  		this.outlineBlend = 1;
  		this.albedoColor = new Laya.Vector4(1, 1, 1, 1);
  		this.shadowColor = new Laya.Vector4(0.8, 0.8, 0.8, 1);
  		this.brightColor = new Laya.Vector4(1.0, 1.0, 1.0, 1);
  		this.lightMapBound = 0.01;
  		this.edgeHightlightColor = new Laya.Vector4(1.0, 1.0, 1.0, 1.0);
  		this.edgeHightlightEdge0 = 0.6;
  		this.edgeHightlightEdge1 = 0.5;
  		this.normalTextureScale = 1;
  		this.detailNormalTextureScale = 1;
  		this.paintLayer1TilingOffset = new Laya.Vector4(1, 1, 0, 0);
  		this.detailNormalTextureTillingOffset = new Laya.Vector4(1, 1, 0, 0);
  		this.smoothness = 0.0;
  		this.metallic = 0.0;
  		this.FadeColor = new Laya.Vector4;
  		this.FadeFactor = 0.0;
  		this.alphaTestValue = 0.5;
  		this.alpha = 1;
  		this.bUseGlobalLight = false;
  	}
  	static __init__() {
  		CartoonFaceMaterial.SHADERDEFINE_ALBEDOCOLOR = Laya.Shader3D.getDefineByName("ALBEDOCOLOR");
  		CartoonFaceMaterial.SHADERDEFINE_BONE = Laya.Shader3D.getDefineByName("BONE");
  		CartoonFaceMaterial.SHADERDEFINE_WHOLE_ALPHA = Laya.Shader3D.getDefineByName("WHOLE_ALPHA");
  		CartoonFaceMaterial.SHADERDEFINE_NORMALTEXTURE = Laya.Shader3D.getDefineByName("NORMALTEXTURE");
  		CartoonFaceMaterial.SHADERDEFINE_DETAIL_NORMAL_TEXTURE = Laya.Shader3D.getDefineByName("DETAIL_NORMAL_TEXTURE");
  		CartoonFaceMaterial.SHADERDEFINE_LAYER1_TEXTURE = Laya.Shader3D.getDefineByName("LAYER1_TEXTURE");
  		CartoonFaceMaterial.SHADERDEFINE_LAYER2_TEXTURE = Laya.Shader3D.getDefineByName("LAYER2_TEXTURE");
  		CartoonFaceMaterial.SHADERDEFINE_REFLECT_CUBE = Laya.Shader3D.getDefineByName("REFLECT_CUBE");
  		CartoonFaceMaterial.SHADERDEFINE_FRESNEL_REFLECTION = Laya.Shader3D.getDefineByName("FRESNEL_REFLECTION");
  		CartoonFaceMaterial.SHADERDEFINE_DRAWING_MASK = Laya.Shader3D.getDefineByName("SHADERDEFINE_DRAWING_MASK");
  		CartoonFaceMaterial.SHADERDEFINE_DRAWING_MASK_ZERO = Laya.Shader3D.getDefineByName("SHADERDEFINE_DRAWING_MASK_ZERO");
  		CartoonFaceMaterial.FAKE_SHADOW = Laya.Shader3D.getDefineByName("FAKE_SHADOW");
  		CartoonFaceMaterial.SHADERDEFINE_GRAY = Laya.Shader3D.getDefineByName("SHADERDEFINE_GRAY");
  		CartoonFaceMaterial.SHADERDEFINE_PROGRESS = Laya.Shader3D.getDefineByName("SHADERDEFINE_PROGRESS");
  		CartoonFaceMaterial.SHADERDEFINE_BURN = Laya.Shader3D.getDefineByName("SHADERDEFINE_BURN");
  		CartoonFaceMaterial.SHADERDEFINE_BURN_INVERST = Laya.Shader3D.getDefineByName("SHADERDEFINE_BURN_INVERST");
  		CartoonFaceMaterial.SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR = Laya.Shader3D.getDefineByName("SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR");
  	}
  	static initShader() {
  		CartoonFaceMaterial.__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_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_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_PaintLayer1Texture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_PaintLayer1TilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_PaintLayer2Texture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_PaintLayer2TilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
  			"u_fade_factor": Laya.Shader3D.PERIOD_MATERIAL,
  			"u_fade_color": Laya.Shader3D.PERIOD_MATERIAL,
  			'u_AlphaTestValue': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_Progress': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BurnTexture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BurnFactor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BurnTextureTillingOffset': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_OutlineWidth': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_OutlineBlend': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_OutlineColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_ShadowColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BrightColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_LightMap': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_LightMapForward': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_LightMapRight': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_LightMapBound': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_EdgeHightlightEdge0': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_EdgeHightlightEdge1': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_EdgeHightlightColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_ViewProjection': Laya.Shader3D.PERIOD_CAMERA,
  			'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,
  		};
  		var CartoonFaceShader3D = Laya.Shader3D.add("CartoonFaceShader");
  		var subShader = new Laya.SubShader(attributeMap, uniformMap);
  		CartoonFaceShader3D.addSubShader(subShader);
  		var vs1 = CartoonStrokeVs;
  		var ps1 = CartoonStrokeFs;
  		var pass1 = subShader.addShaderPass(vs1, ps1);
  		pass1.renderState.cull = Laya.RenderState.CULL_FRONT;
  		var vs2 = `
		#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";

		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;

		varying vec4 v_posView;

		#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;

		#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
            varying vec4 v_ShadowCoord;
        #endif
		
		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; 

			v_posView = gl_Position.xyzw;
			gl_Position.z=gl_Position.z * 2.0 - gl_Position.w;

			#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
                v_ShadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));
            #endif
		}`;
  		var ps2 = `
		#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";
	
		uniform DirectionLight u_SunLight;

		#ifdef SPOTLIGHT
			struct SpotLight {
				vec3 color;
				vec3 position;
				float range;
				vec3 direction;
				float spot;
			};
			uniform SpotLight u_SpotLight;
		#endif

		#ifdef ALBEDOCOLOR
			uniform vec4 u_AlbedoColor;
		#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

		#ifdef SHADERDEFINE_BURN
			uniform float u_BurnFactor;
			uniform sampler2D u_BurnTexture;
			uniform vec4 u_BurnTextureTillingOffset;
		#endif

		varying vec2 v_Texcoord0;
		varying vec3 v_Normal;
		varying vec3 v_PositionWorld;
		varying vec3 v_ViewDir;
		varying vec3 v_worldPos;
		varying vec4 v_posView;
		varying float v_viewDistance;

		uniform vec4 u_ShadowColor;
		uniform vec4 u_BrightColor;
		uniform sampler2D u_LightMap;
		uniform vec3 u_LightMapForward;
		uniform vec3 u_LightMapRight;
		uniform float u_LightMapBound;

		uniform float u_EdgeHightlightEdge0;
		uniform float u_EdgeHightlightEdge1;
		uniform vec4 u_EdgeHightlightColor;
		
		//喷绘相关
		uniform sampler2D u_PaintLayer1Texture;
		uniform vec4 u_PaintLayer1TilingOffset;
		uniform sampler2D u_PaintLayer2Texture;
		uniform vec4 u_PaintLayer2TilingOffset;

		uniform float u_fade_factor;
		uniform vec4 u_fade_color;
		

		#ifdef WHOLE_ALPHA
		uniform float u_alpha;
		#endif

		uniform float u_AlphaTestValue;
		uniform float u_Progress;

		#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
			varying vec4 v_ShadowCoord;
		#endif
		
		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_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 disCamera = clamp(v_viewDistance, minv, maxv);
				float scalefactor = 1.0 - (disCamera - 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(0.0);
			
			
			vec2 texcoord = vec2(v_Texcoord0.x, 1.0 - v_Texcoord0.y);
			#ifdef LAYER1_TEXTURE
				// 计算层级1的颜色
				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;
			#endif

			#ifdef LAYER2_TEXTURE
				// 计算层级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.rgba = albedoTextureColor.rgba * (1.0 - paintLayer2Color.a) + paintLayer2Color.a * paintLayer2Color.rgba;
				albedoTextureColor.rgb = albedoTextureColor.rgb * (1.0 - paintLayer2Color.a) + paintLayer2Color.rgb;
				albedoTextureColor.a = albedoTextureColor.a * (1.0 - paintLayer2Color.a) + paintLayer2Color.a;
			#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 SHADERDEFINE_PROGRESS
				float through = 0.02;
				float halfTh = through/2.0;
				float realP = v_posView.y/v_posView.w * 0.5 + 0.5;
				//是否在进度跳
				float fInP = step(realP, u_Progress - halfTh);
				float fInNP = step(u_Progress + halfTh, realP);
				float aFactor = fInNP * 0.0 + fInP * 1.0 + (1.0 - fInP)*(1.0-fInNP)*(1.0 - (realP - u_Progress + halfTh)/through);
				albedoTextureColor.a *= aFactor;
			#endif

			#ifdef SHADERDEFINE_BURN
				#ifdef SHADERDEFINE_BURN_INVERST
					//噪波图的当前值
					float value = texture2D(u_BurnTexture, TransformUV(v_Texcoord0, u_BurnTextureTillingOffset)).x;

					float disburn = distance(v_posView.xyz/v_posView.w, vec3(0,0,0));
					disburn += value;
					float through = 0.02;

					float inMaxRange = step(disburn , u_BurnFactor + through*2.0);
					float outSecondRange = step(u_BurnFactor + through, disburn);
					float inFirst = inMaxRange * outSecondRange;
					
					float inSencondRange = step(disburn, u_BurnFactor + through);
					float outThirdRange = step(u_BurnFactor, disburn);
					float inSecond = inSencondRange * outThirdRange;

					float inThird = step(disburn, u_BurnFactor);
					float inFourth = (1.0 - inFirst) * (1.0 - inSecond) * (1.0 - inThird);

					vec4 outColor = vec4(236.0/255.0, 131.0/255.0, 255.0/255.0, albedoTextureColor.a);
					vec4 secondColor = vec4(245.0/255.0, 228.0/255.0, 255.0/255.0, albedoTextureColor.a);
					vec4 thirdColor = albedoTextureColor.rgba;
					vec4 forthColor = vec4(0.0,0.0,0.0,0.0);

					albedoTextureColor = outColor*inFirst + secondColor*inSecond + inThird * thirdColor + forthColor * inFourth;

					// if(disburn < u_BurnFactor + through*2.0 && disburn >= u_BurnFactor + through){
					// 	albedoTextureColor.a = albedoTextureColor.a;
					// 	albedoTextureColor.rgb = vec3(236.0/255.0, 131.0/255.0, 255.0/255.0);
					// }
					// else if(disburn < u_BurnFactor + through && disburn >= u_BurnFactor){
					// 	albedoTextureColor.a = albedoTextureColor.a;
					// 	albedoTextureColor.rgb = vec3(245.0/255.0, 228.0/255.0, 255.0/255.0);
					// }
					// else if(disburn > u_BurnFactor){
					// 	albedoTextureColor.a = 0.0;
					// }
					// else{
					// 	albedoTextureColor.a = albedoTextureColor.a;
					// }
				#else
					//噪波图的当前值
					float value = texture2D(u_BurnTexture, TransformUV(v_Texcoord0, u_BurnTextureTillingOffset)).x;

					float disburn = distance(v_posView.xyz/v_posView.w, vec3(0,0,0));
					disburn += value;
					float through = 0.02;

					float inMaxRange = step(disburn , u_BurnFactor + through*2.0);
					float outSecondRange = step(u_BurnFactor + through, disburn);
					float inFirst = inMaxRange * outSecondRange;
					
					float inSencondRange = step(disburn, u_BurnFactor + through);
					float outThirdRange = step(u_BurnFactor, disburn);
					float inSecond = inSencondRange * outThirdRange;

					float inThird = step(disburn, u_BurnFactor);
					float inFourth = (1.0 - inFirst) * (1.0 - inSecond) * (1.0 - inThird);

					vec4 outColor = vec4(236.0/255.0, 131.0/255.0, 255.0/255.0, albedoTextureColor.a);
					vec4 secondColor = vec4(245.0/255.0, 228.0/255.0, 255.0/255.0, albedoTextureColor.a);
					vec4 thirdColor = vec4(0.0,0.0,0.0,0.0);
					vec4 forthColor = albedoTextureColor.rgba;
					
					albedoTextureColor = outColor*inFirst + secondColor*inSecond + inThird * thirdColor + forthColor * inFourth;

					// if(disburn < u_BurnFactor + through*2.0 && disburn >= u_BurnFactor + through){
					// 	albedoTextureColor.a = albedoTextureColor.a;
					// 	albedoTextureColor.rgb = vec3(245.0/255.0, 228.0/255.0, 255.0/255.0);
					// }
					// else if(disburn < u_BurnFactor + through && disburn >= u_BurnFactor){
					// 	albedoTextureColor.a = albedoTextureColor.a;
					// 	albedoTextureColor.rgb = vec3(236.0/255.0, 131.0/255.0, 255.0/255.0);
					// }
					// else if(disburn < u_BurnFactor){
					// 	albedoTextureColor.a = 0.0;
					// }
					// else{
					// 	albedoTextureColor.a = albedoTextureColor.a;
					// }
				#endif
			#endif
			
			#ifdef ALPHATEST
				if(albedoTextureColor.a <= u_AlphaTestValue){
					discard;
				}
			#endif

			#ifdef ALBEDOCOLOR
				albedoTextureColor *= u_AlbedoColor;
			#endif
		
			//屏蔽掉卡通色转换, 使用模型原始颜色
			vec3 albedoColor = albedoTextureColor.rgb;		
			// #ifdef SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR
			// 	vec3 brightColor = u_SunLight.color;
			// #else
			// 	vec3 brightColor = u_BrightColor.rgb;
			// #endif
			vec3 brightColor = u_BrightColor.rgb;
			// 阴影计算部分计算
			vec3 lightMapForward = normalize(u_LightMapForward);
			vec3 lightMapRight = normalize(u_LightMapRight);
			vec3 finalColor;
			vec2 texcoordLightMap = vec2(v_Texcoord0.x, v_Texcoord0.y);
			//光在右侧  正常取值
			//光在左侧 反向取值
			float ldotl = dot(lightMapRight, -lightDir);
			texcoordLightMap.x = step(0.0, ldotl) * texcoordLightMap.x + (1.0 - step(0.0, ldotl)) * (1.0 - texcoordLightMap.x);
			vec4 lightMapColor = texture2D(u_LightMap, texcoordLightMap);

			float interval = u_LightMapBound;
			float factor = 1.0 - dot(lightMapForward, -lightDir);
			float shadowStep = smoothstep(factor-interval, factor+interval, lightMapColor.r);
			finalColor = u_ShadowColor.rgb * (1.0-shadowStep) + brightColor * shadowStep;

			//计算边缘高光部分
			float ndotv = max(dot(normal, viewdir), 0.0);
			float edgeHightlightStep = smoothstep(u_EdgeHightlightEdge0,u_EdgeHightlightEdge1, ndotv);
			finalColor = u_EdgeHightlightColor.rgb *2.0*finalColor* edgeHightlightStep + finalColor * (1.0 - edgeHightlightStep);

            finalColor.rgb *= albedoColor.rgb;

			float shadowAttenuation = 1.0;
			#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
						shadowAttenuation *= sampleShadowmap(shadowCoord);
                    #endif
                #else
					#ifdef SHADOW_CASCADE
						vec4 shadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));
					#else
						vec4 shadowCoord = v_ShadowCoord;
					#endif
					shadowAttenuation *= sampleShadowmap(shadowCoord);
                #endif
            #endif
			finalColor *= shadowAttenuation;

			#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 = albedoColor.rgb * inSpot * inDir * 0.5;
				vec3 sunColor = u_SunLight.color * albedoColor.rgb;

				finalColor *= spotColor + sunColor;
			#else
				finalColor *= u_SunLight.color;
			#endif

			#ifdef SHADERDEFINE_GRAY
				float ff = (finalColor.r + finalColor.g + finalColor.b)/3.0;
				finalColor.rgb = vec3(ff, ff, ff);
			#endif

			#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(vs2, ps2, stateMap);
  		subShader.addShaderPass(PBRShadowCasterVS, PBRShadowCasterPS, stateMap, "ShadowCaster");
  	}
  	get cull() {
  		return this._shaderValues.getInt(CartoonFaceMaterial.CULL);
  	}
  	set cull(value) {
  		this._shaderValues.setInt(CartoonFaceMaterial.CULL, value);
  	}
  	get blend() {
  		return this._shaderValues.getInt(CartoonFaceMaterial.BLEND);
  	}
  	set blend(value) {
  		this._shaderValues.setInt(CartoonFaceMaterial.BLEND, value);
  	}
  	get blendSrc() {
  		return this._shaderValues.getInt(CartoonFaceMaterial.BLEND_SRC);
  	}
  	set blendSrc(value) {
  		this._shaderValues.setInt(CartoonFaceMaterial.BLEND_SRC, value);
  	}
  	get blendDst() {
  		return this._shaderValues.getInt(CartoonFaceMaterial.BLEND_DST);
  	}
  	set blendDst(value) {
  		this._shaderValues.setInt(CartoonFaceMaterial.BLEND_DST, value);
  	}
  	get depthTest() {
  		return this._shaderValues.getInt(CartoonFaceMaterial.DEPTH_TEST);
  	}
  	set depthTest(value) {
  		this._shaderValues.setInt(CartoonFaceMaterial.DEPTH_TEST, value);
  	}
  	get depthWrite() {
  		return this._shaderValues.getBool(CartoonFaceMaterial.DEPTH_WRITE);
  	}
  	set depthWrite(value) {
  		this._shaderValues.setBool(CartoonFaceMaterial.DEPTH_WRITE, value);
  	}
  	get renderMode() {
  		return this.__render_mode__;
  	}
  	set renderMode(value) {
  		this.__render_mode__ = value;
  		switch (value) {
  			case CartoonFaceMaterial.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 CartoonFaceMaterial.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 CartoonFaceMaterial.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 CartoonFaceMaterial.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 CartoonFaceMaterial.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 CartoonFaceMaterial.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 bBurnInvert() {
  		return this._shaderValues.hasDefine(CartoonFaceMaterial.SHADERDEFINE_BURN_INVERST);
  	}
  	set bBurnInvert(value) {
  		if (value) {
  			this._shaderValues.addDefine(CartoonFaceMaterial.SHADERDEFINE_BURN_INVERST);
  		}
  		else {
  			this._shaderValues.removeDefine(CartoonFaceMaterial.SHADERDEFINE_BURN_INVERST);
  		}
  	}
  	get burnFactor() {
  		return this._shaderValues.getNumber(CartoonFaceMaterial.BURN_FACTOR);
  	}
  	set burnFactor(value) {
  		if (value != null) {
  			value = Math.max(0.0, value);
  			this._shaderValues.setNumber(CartoonFaceMaterial.BURN_FACTOR, value);
  		}
  	}
  	get burnTexture() {
  		return this._shaderValues.getTexture(CartoonFaceMaterial.BURNTEXTURE);
  	}
  	set burnTexture(value) {
  		if (value) {
  			this._defineDatas.add(CartoonFaceMaterial.SHADERDEFINE_BURN);
  			this._shaderValues.setTexture(CartoonFaceMaterial.BURNTEXTURE, value);
  		}
  		else {
  			this._defineDatas.remove(CartoonFaceMaterial.SHADERDEFINE_BURN);
  		}
  	}
  	get BurnTillingOffset() {
  		return this._shaderValues.getVector(CartoonFaceMaterial.BRUN_TEXTURE_TILLING_OFFSET);
  	}
  	set BurnTillingOffset(value) {
  		this._shaderValues.setVector(CartoonFaceMaterial.BRUN_TEXTURE_TILLING_OFFSET, value);
  	}
  	get mprogress() {
  		return this._shaderValues.getNumber(CartoonFaceMaterial.PROGRESS);
  	}
  	set mprogress(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonFaceMaterial.SHADERDEFINE_PROGRESS);
  			value = Math.max(0.0, value);
  			this._shaderValues.setNumber(CartoonFaceMaterial.PROGRESS, value);
  		}
  		else {
  			this._defineDatas.remove(CartoonFaceMaterial.SHADERDEFINE_PROGRESS);
  		}
  	}
  	get gray() {
  		if (this._defineDatas.has(CartoonFaceMaterial.SHADERDEFINE_GRAY)) {
  			return true;
  		}
  		else {
  			return false;
  		}
  	}
  	set gray(value) {
  		if (value) {
  			this._defineDatas.add(CartoonFaceMaterial.SHADERDEFINE_GRAY);
  		}
  		else {
  			this._defineDatas.remove(CartoonFaceMaterial.SHADERDEFINE_GRAY);
  		}
  	}
  	get albedoColor() {
  		return this._shaderValues.getVector(CartoonFaceMaterial.ALBEDOCOLOR);
  	}
  	set albedoColor(value) {
  		if (value) {
  			this._defineDatas.add(CartoonFaceMaterial.SHADERDEFINE_ALBEDOCOLOR);
  		}
  		else {
  			this._defineDatas.remove(CartoonFaceMaterial.SHADERDEFINE_ALBEDOCOLOR);
  		}
  		this._shaderValues.setVector(CartoonFaceMaterial.ALBEDOCOLOR, value);
  	}
  	get shadowColor() {
  		return this._shaderValues.getVector(CartoonFaceMaterial.SHADOWCOLOR);
  	}
  	set shadowColor(value) {
  		this._shaderValues.setVector(CartoonFaceMaterial.SHADOWCOLOR, value);
  	}
  	get brightColor() {
  		return this._shaderValues.getVector(CartoonFaceMaterial.BRIGHTCOLOR);
  	}
  	set brightColor(value) {
  		this._shaderValues.setVector(CartoonFaceMaterial.BRIGHTCOLOR, value);
  	}
  	get lightmap() {
  		return this._shaderValues.getTexture(CartoonFaceMaterial.LIGHTMAP);
  	}
  	set lightmap(value) {
  		this._shaderValues.setTexture(CartoonFaceMaterial.LIGHTMAP, value);
  	}
  	get lightMapForward() {
  		return this._shaderValues.getVector3(CartoonFaceMaterial.LIGHTMAPFORWARD);
  	}
  	set lightMapForward(value) {
  		this._shaderValues.setVector3(CartoonFaceMaterial.LIGHTMAPFORWARD, value);
  	}
  	get lightMapRight() {
  		return this._shaderValues.getVector3(CartoonFaceMaterial.LIGHTMAPRIGHT);
  	}
  	set lightMapRight(value) {
  		this._shaderValues.setVector3(CartoonFaceMaterial.LIGHTMAPRIGHT, value);
  	}
  	get lightMapBound() {
  		return this._shaderValues.getNumber(CartoonFaceMaterial.LIGHTMAPBOUND);
  	}
  	set lightMapBound(value) {
  		this._shaderValues.setNumber(CartoonFaceMaterial.LIGHTMAPBOUND, value);
  	}
  	get edgeHightlightEdge0() {
  		return this._shaderValues.getNumber(CartoonFaceMaterial.EDGE_HIGHTLIGHT_EDGE0);
  	}
  	set edgeHightlightEdge0(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(CartoonFaceMaterial.EDGE_HIGHTLIGHT_EDGE0, value);
  	}
  	get edgeHightlightEdge1() {
  		return this._shaderValues.getNumber(CartoonFaceMaterial.EDGE_HIGHTLIGHT_EDGE1);
  	}
  	set edgeHightlightEdge1(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(CartoonFaceMaterial.EDGE_HIGHTLIGHT_EDGE1, value);
  	}
  	get edgeHightlightColor() {
  		return this._shaderValues.getVector(CartoonFaceMaterial.EDGE_HIGHTLIGHT_COLOR);
  	}
  	set edgeHightlightColor(value) {
  		this._shaderValues.setVector(CartoonFaceMaterial.EDGE_HIGHTLIGHT_COLOR, value);
  	}
  	get alpha() {
  		return this._shaderValues.getNumber(CartoonFaceMaterial.WHOLE_ALPHA);
  	}
  	set alpha(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonFaceMaterial.SHADERDEFINE_WHOLE_ALPHA);
  		}
  		else {
  			this._defineDatas.remove(CartoonFaceMaterial.SHADERDEFINE_WHOLE_ALPHA);
  		}
  		this._shaderValues.setNumber(CartoonFaceMaterial.WHOLE_ALPHA, value);
  	}
  	get albedoTexture() {
  		return this._shaderValues.getTexture(CartoonFaceMaterial.PAINT_LAYER1_TEXTURE);
  	}
  	set albedoTexture(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonFaceMaterial.SHADERDEFINE_LAYER1_TEXTURE);
  		}
  		else {
  			this._defineDatas.remove(CartoonFaceMaterial.SHADERDEFINE_LAYER1_TEXTURE);
  		}
  		this._shaderValues.setTexture(CartoonFaceMaterial.PAINT_LAYER1_TEXTURE, value);
  	}
  	get paintLayer1TilingOffset() {
  		return this._shaderValues.getVector(CartoonFaceMaterial.PAINT_LAYER1_TILINGOFFSET);
  	}
  	set paintLayer1TilingOffset(value) {
  		this._shaderValues.setVector(CartoonFaceMaterial.PAINT_LAYER1_TILINGOFFSET, value);
  	}
  	get paintLayer2Texture() {
  		return this._shaderValues.getTexture(CartoonFaceMaterial.PAINT_LAYER2_TEXTURE);
  	}
  	set paintLayer2Texture(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonFaceMaterial.SHADERDEFINE_LAYER2_TEXTURE);
  		}
  		else {
  			this._defineDatas.remove(CartoonFaceMaterial.SHADERDEFINE_LAYER2_TEXTURE);
  		}
  		this._shaderValues.setTexture(CartoonFaceMaterial.PAINT_LAYER2_TEXTURE, value);
  	}
  	get paintLayer2TilingOffset() {
  		return this._shaderValues.getVector(CartoonFaceMaterial.PAINT_LAYER2_TILINGOFFSET);
  	}
  	set paintLayer2TilingOffset(value) {
  		this._shaderValues.setVector(CartoonFaceMaterial.PAINT_LAYER2_TILINGOFFSET, value);
  	}
  	get normalTexture() {
  		return this._shaderValues.getTexture(CartoonFaceMaterial.NORMAL_TEXTURE);
  	}
  	set normalTexture(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonFaceMaterial.SHADERDEFINE_NORMALTEXTURE);
  		}
  		else {
  			this._defineDatas.remove(CartoonFaceMaterial.SHADERDEFINE_NORMALTEXTURE);
  		}
  		this._shaderValues.setTexture(CartoonFaceMaterial.NORMAL_TEXTURE, value);
  	}
  	get normalTextureScale() {
  		return this._shaderValues.getNumber(CartoonFaceMaterial.NORMAL_SCALE);
  	}
  	set normalTextureScale(value) {
  		this._shaderValues.setNumber(CartoonFaceMaterial.NORMAL_SCALE, value);
  	}
  	get normalTextureTillingOffset() {
  		return this._shaderValues.getVector(CartoonFaceMaterial.NORMAL_TILLING_OFFSET);
  	}
  	set normalTextureTillingOffset(value) {
  		this._shaderValues.setVector(CartoonFaceMaterial.NORMAL_TILLING_OFFSET, value);
  	}
  	get detailNormalTexture() {
  		return this._shaderValues.getTexture(CartoonFaceMaterial.DETAIL_NORMAL_TEXTURE);
  	}
  	set detailNormalTexture(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonFaceMaterial.SHADERDEFINE_DETAIL_NORMAL_TEXTURE);
  		}
  		else {
  			this._defineDatas.remove(CartoonFaceMaterial.SHADERDEFINE_DETAIL_NORMAL_TEXTURE);
  		}
  		this._shaderValues.setTexture(CartoonFaceMaterial.DETAIL_NORMAL_TEXTURE, value);
  	}
  	get detailNormalTextureTillingOffset() {
  		return this._shaderValues.getVector(CartoonFaceMaterial.DETAIL_NORMAL_TILLING_OFFSET);
  	}
  	set detailNormalTextureTillingOffset(value) {
  		this._shaderValues.setVector(CartoonFaceMaterial.DETAIL_NORMAL_TILLING_OFFSET, value);
  	}
  	get detailNormalTextureScale() {
  		return this._shaderValues.getNumber(CartoonFaceMaterial.DETAIL_NORMAL_SCALE);
  	}
  	set detailNormalTextureScale(value) {
  		this._shaderValues.setNumber(CartoonFaceMaterial.DETAIL_NORMAL_SCALE, value);
  	}
  	get reflectionCube() {
  		return this._shaderValues.getTexture(CartoonFaceMaterial.REFLECTION_CUBE);
  	}
  	set reflectionCube(value) {
  		if (value) {
  			this._defineDatas.add(CartoonFaceMaterial.SHADERDEFINE_REFLECT_CUBE);
  		}
  		else {
  			this._defineDatas.remove(CartoonFaceMaterial.SHADERDEFINE_REFLECT_CUBE);
  		}
  		this._shaderValues.setTexture(CartoonFaceMaterial.REFLECTION_CUBE, value);
  	}
  	get smoothness() {
  		return this._shaderValues.getNumber(CartoonFaceMaterial.SMOOTHNESS);
  	}
  	set smoothness(value) {
  		this._shaderValues.setNumber(CartoonFaceMaterial.SMOOTHNESS, value);
  	}
  	get reflectionBoxCenter() {
  		return this._shaderValues.getVector3(CartoonFaceMaterial.REFLECTION_BOX_CENTER);
  	}
  	set reflectionBoxCenter(value) {
  		this._shaderValues.setVector3(CartoonFaceMaterial.REFLECTION_BOX_CENTER, value);
  	}
  	get reflectionBoxSize() {
  		return this._shaderValues.getVector3(CartoonFaceMaterial.REFLECTION_BOX_SIZE);
  	}
  	set reflectionBoxSize(value) {
  		this._shaderValues.setVector3(CartoonFaceMaterial.REFLECTION_BOX_SIZE, value);
  	}
  	get metallic() {
  		return this._shaderValues.getNumber(CartoonFaceMaterial.METALLIC);
  	}
  	set metallic(value) {
  		this._shaderValues.setNumber(CartoonFaceMaterial.METALLIC, value);
  	}
  	set bPickZero(value) {
  		if (value) {
  			this._defineDatas.add(CartoonFaceMaterial.SHADERDEFINE_DRAWING_MASK_ZERO);
  		}
  		else {
  			this._defineDatas.remove(CartoonFaceMaterial.SHADERDEFINE_DRAWING_MASK_ZERO);
  		}
  	}
  	set FadeColor(value) {
  		this._shaderValues.setVector(CartoonFaceMaterial.FADE_COLOR, value);
  	}
  	set FadeFactor(value) {
  		this._shaderValues.setNumber(CartoonFaceMaterial.FADE_FACTOR, value);
  	}
  	get alphaTestValue() {
  		return this._shaderValues.getNumber(Laya.Material.ALPHATESTVALUE) || 0;
  	}
  	set alphaTestValue(value) {
  		if (value == null)
  			return;
  		this._shaderValues.setNumber(Laya.Material.ALPHATESTVALUE, value);
  	}
  	get outlineWidth() {
  		return this._shaderValues.getNumber(CartoonFaceMaterial.OUTLINEWIDTH);
  	}
  	set outlineWidth(value) {
  		value = Math.max(0.0, Math.min(0.05, value));
  		this._shaderValues.setNumber(CartoonFaceMaterial.OUTLINEWIDTH, value);
  	}
  	get outlineColor() {
  		return this._shaderValues.getVector(CartoonFaceMaterial.OUTLINECOLOR);
  	}
  	set outlineColor(value) {
  		this._shaderValues.setVector(CartoonFaceMaterial.OUTLINECOLOR, value);
  	}
  	get outlineBlend() {
  		return this._shaderValues.getNumber(CartoonFaceMaterial.OUTLINEBLEND);
  	}
  	set outlineBlend(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(CartoonFaceMaterial.OUTLINEBLEND, value);
  	}
  	get bUseGlobalLight() {
  		return this._defineDatas.has(CartoonFaceMaterial.SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR);
  	}
  	set bUseGlobalLight(value) {
  		if (value) {
  			this._defineDatas.add(CartoonFaceMaterial.SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR);
  		}
  		else {
  			this._defineDatas.remove(CartoonFaceMaterial.SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR);
  		}
  	}
  	getCanEditorParamList() {
  		return [
  			{
  				name: `renderMode`, desc: `渲染模式`, type: EditorType.option, options: [
  					{ desc: "不透明", value: 1 },
  					{ desc: "裁剪", value: 2 },
  					{ desc: "裁剪双面", value: 3 },
  					{ desc: "透明", value: 4 },
  					{ desc: "透明双面", value: 5 },
  					{ desc: "不透明双面", value: 6 },
  				],
  			},
  			{ name: `outlineWidth`, desc: `描边宽度`, type: EditorType.slider, range: [0, 0.02, 4] },
  			{ name: `outlineColor`, desc: `描边颜色`, type: EditorType.color, },
  			{ name: `outlineBlend`, desc: `描边混合`, type: EditorType.slider, range: [0, 1] },
  			{ name: `alphaTestValue`, desc: `alpha裁剪参数`, type: EditorType.slider, range: [0, 1] },
  			{ name: `paintLayer1TilingOffset`, desc: `uv平铺`, type: EditorType.vec4 },
  			{ name: `renderQueue`, desc: `renderQueue`, type: EditorType.num },
  			{ name: `albedoColor`, desc: `基础色`, type: EditorType.color },
  			{ name: `shadowColor`, desc: `阴影颜色`, type: EditorType.color },
  			{ name: `brightColor`, desc: `亮部颜色`, type: EditorType.color },
  			{ name: `lightmap`, desc: `阴影贴图`, type: EditorType.texture2d, options: mgrMaterial.textures },
  			{ name: `lightMapBound`, desc: `阴影过渡`, type: EditorType.slider, range: [0, 0.02, 4] },
  			{ name: `edgeHightlightColor`, desc: `边缘高光颜色`, type: EditorType.color },
  			{ name: `edgeHightlightEdge0`, desc: `边缘高光边界1`, type: EditorType.slider, range: [0, 1, 4] },
  			{ name: `edgeHightlightEdge1`, desc: `边缘高光边界2`, type: EditorType.slider, range: [0, 1, 4] },
  		];
  	}
  }
  CartoonFaceMaterial.ALBEDOCOLOR = Laya.Shader3D.propertyNameToID("u_AlbedoColor");
  CartoonFaceMaterial.SHADOWCOLOR = Laya.Shader3D.propertyNameToID("u_ShadowColor");
  CartoonFaceMaterial.BRIGHTCOLOR = Laya.Shader3D.propertyNameToID("u_BrightColor");
  CartoonFaceMaterial.LIGHTMAP = Laya.Shader3D.propertyNameToID("u_LightMap");
  CartoonFaceMaterial.LIGHTMAPBOUND = Laya.Shader3D.propertyNameToID("u_LightMapBound");
  CartoonFaceMaterial.LIGHTMAPFORWARD = Laya.Shader3D.propertyNameToID("u_LightMapForward");
  CartoonFaceMaterial.LIGHTMAPRIGHT = Laya.Shader3D.propertyNameToID("u_LightMapRight");
  CartoonFaceMaterial.EDGE_HIGHTLIGHT_EDGE0 = Laya.Shader3D.propertyNameToID("u_EdgeHightlightEdge0");
  CartoonFaceMaterial.EDGE_HIGHTLIGHT_EDGE1 = Laya.Shader3D.propertyNameToID("u_EdgeHightlightEdge1");
  CartoonFaceMaterial.EDGE_HIGHTLIGHT_COLOR = Laya.Shader3D.propertyNameToID("u_EdgeHightlightColor");
  CartoonFaceMaterial.DIRECTIONLIGHTDIRECTION = Laya.Shader3D.propertyNameToID("u_SunLight.direction");
  CartoonFaceMaterial.DIRECTIONLIGHTCOLOR = Laya.Shader3D.propertyNameToID("u_SunLight.color");
  CartoonFaceMaterial.SPOT_LIGHT_COLOR = Laya.Shader3D.propertyNameToID("u_SpotLight.color");
  CartoonFaceMaterial.SPOT_LIGHT_DIRECTION = Laya.Shader3D.propertyNameToID("u_SpotLight.direction");
  CartoonFaceMaterial.SPOT_LIGHT_RANGE = Laya.Shader3D.propertyNameToID("u_SpotLight.range");
  CartoonFaceMaterial.SPOT_LIGHT_SPOT = Laya.Shader3D.propertyNameToID("u_SpotLight.spot");
  CartoonFaceMaterial.SPOT_LIGHT_POSITION = Laya.Shader3D.propertyNameToID("u_SpotLight.position");
  CartoonFaceMaterial.WHOLE_ALPHA = Laya.Shader3D.propertyNameToID("u_alpha");
  CartoonFaceMaterial.NORMAL_TEXTURE = Laya.Shader3D.propertyNameToID("u_NormalTexture");
  CartoonFaceMaterial.NORMAL_SCALE = Laya.Shader3D.propertyNameToID("u_NormalScale");
  CartoonFaceMaterial.NORMAL_TILLING_OFFSET = Laya.Shader3D.propertyNameToID("u_NormalTillingOffset");
  CartoonFaceMaterial.DETAIL_NORMAL_TEXTURE = Laya.Shader3D.propertyNameToID("u_DetailNormalTexture");
  CartoonFaceMaterial.DETAIL_NORMAL_TILLING_OFFSET = Laya.Shader3D.propertyNameToID("u_DetailNormalTillingOffset");
  CartoonFaceMaterial.DETAIL_NORMAL_SCALE = Laya.Shader3D.propertyNameToID("u_DetailNormalScale");
  CartoonFaceMaterial.REFLECTION_CUBE = Laya.Shader3D.propertyNameToID("u_reflection_cube");
  CartoonFaceMaterial.SMOOTHNESS = Laya.Shader3D.propertyNameToID("u_Smoothness");
  CartoonFaceMaterial.METALLIC = Laya.Shader3D.propertyNameToID("u_Metallic");
  CartoonFaceMaterial.REFLECTION_BOX_CENTER = Laya.Shader3D.propertyNameToID("u_reflection_box_center");
  CartoonFaceMaterial.REFLECTION_BOX_SIZE = Laya.Shader3D.propertyNameToID("u_reflection_box_size");
  CartoonFaceMaterial.FADE_FACTOR = Laya.Shader3D.propertyNameToID("u_fade_factor");
  CartoonFaceMaterial.FADE_COLOR = Laya.Shader3D.propertyNameToID("u_fade_color");
  CartoonFaceMaterial.PROGRESS = Laya.Shader3D.propertyNameToID("u_Progress");
  CartoonFaceMaterial.BURN_FACTOR = Laya.Shader3D.propertyNameToID("u_BurnFactor");
  CartoonFaceMaterial.BURNTEXTURE = Laya.Shader3D.propertyNameToID("u_BurnTexture");
  CartoonFaceMaterial.BRUN_TEXTURE_TILLING_OFFSET = Laya.Shader3D.propertyNameToID("u_BurnTextureTillingOffset");
  CartoonFaceMaterial.PAINT_LAYER1_TEXTURE = Laya.Shader3D.propertyNameToID("u_PaintLayer1Texture");
  CartoonFaceMaterial.PAINT_LAYER1_TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_PaintLayer1TilingOffset");
  CartoonFaceMaterial.PAINT_LAYER2_TEXTURE = Laya.Shader3D.propertyNameToID("u_PaintLayer2Texture");
  CartoonFaceMaterial.PAINT_LAYER2_TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_PaintLayer2TilingOffset");
  CartoonFaceMaterial.OUTLINEWIDTH = Laya.Shader3D.propertyNameToID("u_OutlineWidth");
  CartoonFaceMaterial.OUTLINEBLEND = Laya.Shader3D.propertyNameToID("u_OutlineBlend");
  CartoonFaceMaterial.OUTLINECOLOR = Laya.Shader3D.propertyNameToID("u_OutlineColor");
  CartoonFaceMaterial.CULL = Laya.Shader3D.propertyNameToID("s_Cull");
  CartoonFaceMaterial.BLEND = Laya.Shader3D.propertyNameToID("s_Blend");
  CartoonFaceMaterial.BLEND_SRC = Laya.Shader3D.propertyNameToID("s_BlendSrc");
  CartoonFaceMaterial.BLEND_DST = Laya.Shader3D.propertyNameToID("s_BlendDst");
  CartoonFaceMaterial.DEPTH_TEST = Laya.Shader3D.propertyNameToID("s_DepthTest");
  CartoonFaceMaterial.DEPTH_WRITE = Laya.Shader3D.propertyNameToID("s_DepthWrite");
  CartoonFaceMaterial.RENDERMODE_OPAQUE = 1;
  CartoonFaceMaterial.RENDERMODE_CUTOUT = 2;
  CartoonFaceMaterial.RENDERMODE_CUTOUT_CULL_NONE = 3;
  CartoonFaceMaterial.RENDERMODE_TRANSPARENT = 4;
  CartoonFaceMaterial.RENDERMODE_TRANSPARENT_CULL_NONE = 5;
  CartoonFaceMaterial.RENDERMODE_OPAQUE_CULL_NONE = 6;

  class CartoonBodyMaterial extends Laya.Material {
  	constructor() {
  		super();
  		this.setShaderName("CartoonBodyMaterial");
  		this._shaderValues.setVector(CartoonBodyMaterial.SHADOWCOLOR, new Laya.Vector4(0.6663285, 0.6544118, 1, 1));
  		this.outlineWidth = 0.001;
  		this.outlineColor = new Laya.Vector4(0.5, 0.5, 0.5, 1);
  		this.outlineBlend = 1;
  		this.shadowEdge0 = 0;
  		this.shadowEdge1 = 0.1;
  		this.shadowColor = new Laya.Vector4(0.5, 0.5, 0.5, 1);
  		this.brightColor = new Laya.Vector4(1, 1, 1, 1);
  		this.hightlightShininess = 2.0;
  		this.hightlightItensity = 0.5;
  		this.metaColor = new Laya.Vector4(1, 1, 1, 1);
  		this.hightlightColor = new Laya.Vector4(1, 1, 1, 1);
  		this.edgeHightlightColor = new Laya.Vector4(1.0, 1.0, 1.0, 1.0);
  		this.edgeHightlightEdge0 = 0.6;
  		this.edgeHightlightEdge1 = 0.5;
  		this._shaderValues.setNumber(CartoonBodyMaterial.NORMAL_SCALE, 1.0);
  		this._shaderValues.setNumber(CartoonBodyMaterial.DETAIL_NORMAL_SCALE, 1.0);
  		this.normalTextureScale = 1;
  		this.detailNormalTextureScale = 1;
  		this.paintLayer1TilingOffset = new Laya.Vector4(1, 1, 0, 0);
  		this.detailNormalTextureTillingOffset = new Laya.Vector4(1, 1, 0, 0);
  		this.smoothness = 0.0;
  		this.metallic = 0.0;
  		this.FadeColor = new Laya.Vector4;
  		this.FadeFactor = 0.0;
  		this.alphaTestValue = 0.5;
  		this.alpha = 1;
  		this.bUseGlobalLight = false;
  	}
  	static __init__() {
  		CartoonBodyMaterial.SHADERDEFINE_ALBEDOCOLOR = Laya.Shader3D.getDefineByName("ALBEDOCOLOR");
  		CartoonBodyMaterial.SHADERDEFINE_BONE = Laya.Shader3D.getDefineByName("BONE");
  		CartoonBodyMaterial.SHADERDEFINE_WHOLE_ALPHA = Laya.Shader3D.getDefineByName("WHOLE_ALPHA");
  		CartoonBodyMaterial.SHADERDEFINE_NORMALTEXTURE = Laya.Shader3D.getDefineByName("NORMALTEXTURE");
  		CartoonBodyMaterial.SHADERDEFINE_DETAIL_NORMAL_TEXTURE = Laya.Shader3D.getDefineByName("DETAIL_NORMAL_TEXTURE");
  		CartoonBodyMaterial.SHADERDEFINE_LAYER1_TEXTURE = Laya.Shader3D.getDefineByName("LAYER1_TEXTURE");
  		CartoonBodyMaterial.SHADERDEFINE_LAYER2_TEXTURE = Laya.Shader3D.getDefineByName("LAYER2_TEXTURE");
  		CartoonBodyMaterial.SHADERDEFINE_REFLECT_CUBE = Laya.Shader3D.getDefineByName("REFLECT_CUBE");
  		CartoonBodyMaterial.SHADERDEFINE_FRESNEL_REFLECTION = Laya.Shader3D.getDefineByName("FRESNEL_REFLECTION");
  		CartoonBodyMaterial.SHADERDEFINE_DRAWING_MASK = Laya.Shader3D.getDefineByName("SHADERDEFINE_DRAWING_MASK");
  		CartoonBodyMaterial.SHADERDEFINE_DRAWING_MASK_ZERO = Laya.Shader3D.getDefineByName("SHADERDEFINE_DRAWING_MASK_ZERO");
  		CartoonBodyMaterial.SHADERDEFINE_GRAY = Laya.Shader3D.getDefineByName("SHADERDEFINE_GRAY");
  		CartoonBodyMaterial.SHADERDEFINE_PROGRESS = Laya.Shader3D.getDefineByName("SHADERDEFINE_PROGRESS");
  		CartoonBodyMaterial.SHADERDEFINE_BURN = Laya.Shader3D.getDefineByName("SHADERDEFINE_BURN");
  		CartoonBodyMaterial.SHADERDEFINE_BURN_INVERST = Laya.Shader3D.getDefineByName("SHADERDEFINE_BURN_INVERST");
  		CartoonBodyMaterial.SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR = Laya.Shader3D.getDefineByName("SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR");
  	}
  	static initShader() {
  		CartoonBodyMaterial.__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_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_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_PaintLayer1Texture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_PaintLayer1TilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_PaintLayer2Texture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_PaintLayer2TilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
  			"u_fade_factor": Laya.Shader3D.PERIOD_MATERIAL,
  			"u_fade_color": Laya.Shader3D.PERIOD_MATERIAL,
  			'u_AlphaTestValue': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_Progress': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BurnTexture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BurnFactor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BurnTextureTillingOffset': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_OutlineWidth': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_OutlineBlend': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_OutlineColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_ShadowColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BrightColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_ShadowEdge0': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_ShadowEdge1': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_LightMap': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_HightlightShininess': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_HightlightItensity': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_HightlightColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_MetaColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_EdgeHightlightEdge0': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_EdgeHightlightEdge1': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_EdgeHightlightColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'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_ViewProjection': Laya.Shader3D.PERIOD_CAMERA,
  		};
  		var CartoonBodyMaterial3D = Laya.Shader3D.add("CartoonBodyMaterial");
  		var subShader = new Laya.SubShader(attributeMap, uniformMap);
  		CartoonBodyMaterial3D.addSubShader(subShader);
  		var vs1 = CartoonStrokeVs;
  		var ps1 = CartoonStrokeFs;
  		var pass1 = subShader.addShaderPass(vs1, ps1, stateMap, "Forward");
  		pass1.renderState.cull = Laya.RenderState.CULL_FRONT;
  		var vs2 = `
		#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";

		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;

		varying vec4 v_posView;

		#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;

		#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
            varying vec4 v_ShadowCoord;
        #endif
		
		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; 

			v_posView = gl_Position.xyzw;
			gl_Position.z=gl_Position.z * 2.0 - gl_Position.w;

			#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
                v_ShadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));
            #endif
		}`;
  		var ps2 = `
		#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";

		uniform DirectionLight u_SunLight;

		#ifdef SPOTLIGHT
			struct SpotLight {
				vec3 color;
				vec3 position;
				float range;
				vec3 direction;
				float spot;
			};
			uniform SpotLight u_SpotLight;
		#endif

		#ifdef ALBEDOCOLOR
			uniform vec4 u_AlbedoColor;
		#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

		#ifdef SHADERDEFINE_BURN
			uniform float u_BurnFactor;
			uniform sampler2D u_BurnTexture;
			uniform vec4 u_BurnTextureTillingOffset;
		#endif

		varying vec2 v_Texcoord0;
		varying vec3 v_Normal;
		varying vec3 v_PositionWorld;
		varying vec3 v_ViewDir;
		varying vec3 v_worldPos;
		varying vec4 v_posView;
		varying float v_viewDistance;

		uniform vec4 u_ShadowColor;
		uniform vec4 u_BrightColor;
		uniform float u_ShadowEdge0;
		uniform float u_ShadowEdge1;
		uniform sampler2D u_LightMap;
		uniform float u_HightlightShininess;
		uniform float u_HightlightItensity;
		uniform vec4 u_HightlightColor;
		uniform vec4 u_MetaColor;

		uniform float u_EdgeHightlightEdge0;
		uniform float u_EdgeHightlightEdge1;
		uniform vec4 u_EdgeHightlightColor;
		
		//喷绘相关
		uniform sampler2D u_PaintLayer1Texture;
		uniform vec4 u_PaintLayer1TilingOffset;
		uniform sampler2D u_PaintLayer2Texture;
		uniform vec4 u_PaintLayer2TilingOffset;

		uniform float u_fade_factor;
		uniform vec4 u_fade_color;
		

		#ifdef WHOLE_ALPHA
		uniform float u_alpha;
		#endif
		uniform float u_AlphaTestValue;
		uniform float u_Progress;

		#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
			varying vec4 v_ShadowCoord;
		#endif

		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_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 disCamera = clamp(v_viewDistance, minv, maxv);
				float scalefactor = 1.0 - (disCamera - minv)/(maxv - minv);
				vec3 detailNormal = normalInTangentSpace(u_DetailNormalTexture, detailNormalTexcoord, scalefactor * u_DetailNormalScale);
				detailNormal = TBN * detailNormal;
				normal += detailNormal;

				normal /= 2.0;
			#endif


			vec3 viewdir = normalize(v_ViewDir);
			vec3 lightDir = normalize(u_SunLight.direction);

			vec4 albedoTextureColor = vec4(0.0);
			
			
			vec2 texcoord = vec2(v_Texcoord0.x, 1.0 - v_Texcoord0.y);
			#ifdef LAYER1_TEXTURE
				// 计算层级1的颜色
				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;
			#endif

			#ifdef LAYER2_TEXTURE
				// 计算层级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.rgba = albedoTextureColor.rgba * (1.0 - paintLayer2Color.a) + paintLayer2Color.a * paintLayer2Color.rgba;
				albedoTextureColor.rgb = albedoTextureColor.rgb * (1.0 - paintLayer2Color.a) + paintLayer2Color.rgb;
				albedoTextureColor.a = albedoTextureColor.a * (1.0 - paintLayer2Color.a) + paintLayer2Color.a;
			#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 SHADERDEFINE_PROGRESS
				float through = 0.02;
				float halfTh = through/2.0;
				float realP = v_posView.y/v_posView.w * 0.5 + 0.5;
				//是否在进度跳
				float fInP = step(realP, u_Progress - halfTh);
				float fInNP = step(u_Progress + halfTh, realP);
				float aFactor = fInNP * 0.0 + fInP * 1.0 + (1.0 - fInP)*(1.0-fInNP)*(1.0 - (realP - u_Progress + halfTh)/through);
				albedoTextureColor.a *= aFactor;
			#endif

			#ifdef SHADERDEFINE_BURN
				#ifdef SHADERDEFINE_BURN_INVERST
					//噪波图的当前值
					float value = texture2D(u_BurnTexture, TransformUV(v_Texcoord0, u_BurnTextureTillingOffset)).x;

					float disburn = distance(v_posView.xyz/v_posView.w, vec3(0,0,0));
					disburn += value;
					float through = 0.02;

					float inMaxRange = step(disburn , u_BurnFactor + through*2.0);
					float outSecondRange = step(u_BurnFactor + through, disburn);
					float inFirst = inMaxRange * outSecondRange;
					
					float inSencondRange = step(disburn, u_BurnFactor + through);
					float outThirdRange = step(u_BurnFactor, disburn);
					float inSecond = inSencondRange * outThirdRange;

					float inThird = step(disburn, u_BurnFactor);
					float inFourth = (1.0 - inFirst) * (1.0 - inSecond) * (1.0 - inThird);

					vec4 outColor = vec4(236.0/255.0, 131.0/255.0, 255.0/255.0, albedoTextureColor.a);
					vec4 secondColor = vec4(245.0/255.0, 228.0/255.0, 255.0/255.0, albedoTextureColor.a);
					vec4 thirdColor = albedoTextureColor.rgba;
					vec4 forthColor = vec4(0.0,0.0,0.0,0.0);

					albedoTextureColor = outColor*inFirst + secondColor*inSecond + inThird * thirdColor + forthColor * inFourth;
				#else
					//噪波图的当前值
					float value = texture2D(u_BurnTexture, TransformUV(v_Texcoord0, u_BurnTextureTillingOffset)).x;

					float disburn = distance(v_posView.xyz/v_posView.w, vec3(0,0,0));
					disburn += value;
					float through = 0.02;

					float inMaxRange = step(disburn , u_BurnFactor + through*2.0);
					float outSecondRange = step(u_BurnFactor + through, disburn);
					float inFirst = inMaxRange * outSecondRange;
					
					float inSencondRange = step(disburn, u_BurnFactor + through);
					float outThirdRange = step(u_BurnFactor, disburn);
					float inSecond = inSencondRange * outThirdRange;

					float inThird = step(disburn, u_BurnFactor);
					float inFourth = (1.0 - inFirst) * (1.0 - inSecond) * (1.0 - inThird);

					vec4 outColor = vec4(236.0/255.0, 131.0/255.0, 255.0/255.0, albedoTextureColor.a);
					vec4 secondColor = vec4(245.0/255.0, 228.0/255.0, 255.0/255.0, albedoTextureColor.a);
					vec4 thirdColor = vec4(0.0,0.0,0.0,0.0);
					vec4 forthColor = albedoTextureColor.rgba;
					
					albedoTextureColor = outColor*inFirst + secondColor*inSecond + inThird * thirdColor + forthColor * inFourth;
				#endif
			#endif
			
			#ifdef ALPHATEST
				if(albedoTextureColor.a <= u_AlphaTestValue){
					discard;
				}
			#endif

			#ifdef ALBEDOCOLOR
				albedoTextureColor *= u_AlbedoColor;
			#endif
		
			//屏蔽掉卡通色转换, 使用模型原始颜色
			vec3 albedoColor = albedoTextureColor.rgb;
			vec3 brightColor = u_BrightColor.rgb;
			//使用lightMap
			vec2 texcoordLightMap = vec2(v_Texcoord0.x, v_Texcoord0.y);
			vec4 lightMapColor = texture2D(u_LightMap, texcoordLightMap);

			//使用通道图控制光照
			float ndotl = max(dot(normal, -lightDir), 0.0);
			float wrapLambert = ndotl + lightMapColor.g;
			float shadowStep = smoothstep(u_ShadowEdge0, u_ShadowEdge1, wrapLambert);
			shadowStep = min(lightMapColor.r, shadowStep);
			vec3 shadowColor = u_ShadowColor.rgb * (1.0-shadowStep) + brightColor * shadowStep;

			vec3 finalColor = shadowColor;
			
			//计算高光部分
			finalColor += pow(ndotl, u_HightlightShininess) * lightMapColor.b * u_HightlightItensity * u_HightlightColor.rgb;
			

			//计算边缘高光部分
			float ndotv = max(dot(normal, viewdir), 0.0);
			float edgeHightlightStep = smoothstep(u_EdgeHightlightEdge0,u_EdgeHightlightEdge1, ndotv);
			finalColor = u_EdgeHightlightColor.rgb *2.0*finalColor* edgeHightlightStep + finalColor * (1.0 - edgeHightlightStep);

			float shadowAttenuation = 1.0;
			#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
						shadowAttenuation *= sampleShadowmap(shadowCoord);
                    #endif
                #else
					#ifdef SHADOW_CASCADE
						vec4 shadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));
					#else
						vec4 shadowCoord = v_ShadowCoord;
					#endif
					shadowAttenuation *= sampleShadowmap(shadowCoord);
                #endif
            #endif
			finalColor *= shadowAttenuation;
			
			
			finalColor.rgb *= albedoColor.rgb;

			#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 = albedoColor.rgb * inSpot * inDir * 0.5;
				vec3 sunColor = u_SunLight.color * albedoColor.rgb;

				finalColor *= spotColor + sunColor;
			#else
				finalColor *= u_SunLight.color;
			#endif

			#ifdef SHADERDEFINE_GRAY
				float ff = (finalColor.r + finalColor.g + finalColor.b)/3.0;
				finalColor.rgb = vec3(ff, ff, ff);
			#endif

			#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(vs2, ps2, stateMap, "Forward");
  		subShader.addShaderPass(PBRShadowCasterVS, PBRShadowCasterPS, stateMap, "ShadowCaster");
  	}
  	get cull() {
  		return this._shaderValues.getInt(CartoonBodyMaterial.CULL);
  	}
  	set cull(value) {
  		this._shaderValues.setInt(CartoonBodyMaterial.CULL, value);
  	}
  	get blend() {
  		return this._shaderValues.getInt(CartoonBodyMaterial.BLEND);
  	}
  	set blend(value) {
  		this._shaderValues.setInt(CartoonBodyMaterial.BLEND, value);
  	}
  	get blendSrc() {
  		return this._shaderValues.getInt(CartoonBodyMaterial.BLEND_SRC);
  	}
  	set blendSrc(value) {
  		this._shaderValues.setInt(CartoonBodyMaterial.BLEND_SRC, value);
  	}
  	get blendDst() {
  		return this._shaderValues.getInt(CartoonBodyMaterial.BLEND_DST);
  	}
  	set blendDst(value) {
  		this._shaderValues.setInt(CartoonBodyMaterial.BLEND_DST, value);
  	}
  	get depthTest() {
  		return this._shaderValues.getInt(CartoonBodyMaterial.DEPTH_TEST);
  	}
  	set depthTest(value) {
  		this._shaderValues.setInt(CartoonBodyMaterial.DEPTH_TEST, value);
  	}
  	get depthWrite() {
  		return this._shaderValues.getBool(CartoonBodyMaterial.DEPTH_WRITE);
  	}
  	set depthWrite(value) {
  		this._shaderValues.setBool(CartoonBodyMaterial.DEPTH_WRITE, value);
  	}
  	get renderMode() {
  		return this.__render_mode__;
  	}
  	set renderMode(value) {
  		this.__render_mode__ = value;
  		switch (value) {
  			case CartoonBodyMaterial.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 CartoonBodyMaterial.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 CartoonBodyMaterial.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 CartoonBodyMaterial.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 CartoonBodyMaterial.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 CartoonBodyMaterial.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 bBurnInvert() {
  		return this._shaderValues.hasDefine(CartoonBodyMaterial.SHADERDEFINE_BURN_INVERST);
  	}
  	set bBurnInvert(value) {
  		if (value) {
  			this._shaderValues.addDefine(CartoonBodyMaterial.SHADERDEFINE_BURN_INVERST);
  		}
  		else {
  			this._shaderValues.removeDefine(CartoonBodyMaterial.SHADERDEFINE_BURN_INVERST);
  		}
  	}
  	get burnFactor() {
  		return this._shaderValues.getNumber(CartoonBodyMaterial.BURN_FACTOR);
  	}
  	set burnFactor(value) {
  		if (value != null) {
  			value = Math.max(0.0, value);
  			this._shaderValues.setNumber(CartoonBodyMaterial.BURN_FACTOR, value);
  		}
  	}
  	get burnTexture() {
  		return this._shaderValues.getTexture(CartoonBodyMaterial.BURNTEXTURE);
  	}
  	set burnTexture(value) {
  		if (value) {
  			this._defineDatas.add(CartoonBodyMaterial.SHADERDEFINE_BURN);
  			this._shaderValues.setTexture(CartoonBodyMaterial.BURNTEXTURE, value);
  		}
  		else {
  			this._defineDatas.remove(CartoonBodyMaterial.SHADERDEFINE_BURN);
  		}
  	}
  	get BurnTillingOffset() {
  		return this._shaderValues.getVector(CartoonBodyMaterial.BRUN_TEXTURE_TILLING_OFFSET);
  	}
  	set BurnTillingOffset(value) {
  		this._shaderValues.setVector(CartoonBodyMaterial.BRUN_TEXTURE_TILLING_OFFSET, value);
  	}
  	get mprogress() {
  		return this._shaderValues.getNumber(CartoonBodyMaterial.PROGRESS);
  	}
  	set mprogress(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonBodyMaterial.SHADERDEFINE_PROGRESS);
  			value = Math.max(0.0, value);
  			this._shaderValues.setNumber(CartoonBodyMaterial.PROGRESS, value);
  		}
  		else {
  			this._defineDatas.remove(CartoonBodyMaterial.SHADERDEFINE_PROGRESS);
  		}
  	}
  	get gray() {
  		if (this._defineDatas.has(CartoonBodyMaterial.SHADERDEFINE_GRAY)) {
  			return true;
  		}
  		else {
  			return false;
  		}
  	}
  	set gray(value) {
  		if (value) {
  			this._defineDatas.add(CartoonBodyMaterial.SHADERDEFINE_GRAY);
  		}
  		else {
  			this._defineDatas.remove(CartoonBodyMaterial.SHADERDEFINE_GRAY);
  		}
  	}
  	get albedoColor() {
  		return this._shaderValues.getVector(CartoonBodyMaterial.ALBEDOCOLOR);
  	}
  	set albedoColor(value) {
  		if (value) {
  			this._defineDatas.add(CartoonBodyMaterial.SHADERDEFINE_ALBEDOCOLOR);
  		}
  		else {
  			this._defineDatas.remove(CartoonBodyMaterial.SHADERDEFINE_ALBEDOCOLOR);
  		}
  		this._shaderValues.setVector(CartoonBodyMaterial.ALBEDOCOLOR, value);
  	}
  	get shadowColor() {
  		return this._shaderValues.getVector(CartoonBodyMaterial.SHADOWCOLOR);
  	}
  	set shadowColor(value) {
  		this._shaderValues.setVector(CartoonBodyMaterial.SHADOWCOLOR, value);
  	}
  	get brightColor() {
  		return this._shaderValues.getVector(CartoonBodyMaterial.BRIGHTCOLOR);
  	}
  	set brightColor(value) {
  		this._shaderValues.setVector(CartoonBodyMaterial.BRIGHTCOLOR, value);
  	}
  	get shadowEdge0() {
  		return this._shaderValues.getNumber(CartoonBodyMaterial.SHADOWEDGE0);
  	}
  	set shadowEdge0(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(CartoonBodyMaterial.SHADOWEDGE0, value);
  	}
  	get shadowEdge1() {
  		return this._shaderValues.getNumber(CartoonBodyMaterial.SHADOWEDGE1);
  	}
  	set shadowEdge1(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(CartoonBodyMaterial.SHADOWEDGE1, value);
  	}
  	get lightmap() {
  		return this._shaderValues.getTexture(CartoonBodyMaterial.LIGHTMAP);
  	}
  	set lightmap(value) {
  		this._shaderValues.setTexture(CartoonBodyMaterial.LIGHTMAP, value);
  	}
  	get hightlightShininess() {
  		return this._shaderValues.getNumber(CartoonBodyMaterial.HIGHLIGHT_SHININESS);
  	}
  	set hightlightShininess(value) {
  		this._shaderValues.setNumber(CartoonBodyMaterial.HIGHLIGHT_SHININESS, value);
  	}
  	get hightlightItensity() {
  		return this._shaderValues.getNumber(CartoonBodyMaterial.HIGHLIGHT_ITENSITY);
  	}
  	set hightlightItensity(value) {
  		this._shaderValues.setNumber(CartoonBodyMaterial.HIGHLIGHT_ITENSITY, value);
  	}
  	get alpha() {
  		return this._shaderValues.getNumber(CartoonBodyMaterial.WHOLE_ALPHA);
  	}
  	set alpha(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonBodyMaterial.SHADERDEFINE_WHOLE_ALPHA);
  		}
  		else {
  			this._defineDatas.remove(CartoonBodyMaterial.SHADERDEFINE_WHOLE_ALPHA);
  		}
  		this._shaderValues.setNumber(CartoonBodyMaterial.WHOLE_ALPHA, value);
  	}
  	get albedoTexture() {
  		return this._shaderValues.getTexture(CartoonBodyMaterial.PAINT_LAYER1_TEXTURE);
  	}
  	set albedoTexture(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonBodyMaterial.SHADERDEFINE_LAYER1_TEXTURE);
  		}
  		else {
  			this._defineDatas.remove(CartoonBodyMaterial.SHADERDEFINE_LAYER1_TEXTURE);
  		}
  		this._shaderValues.setTexture(CartoonBodyMaterial.PAINT_LAYER1_TEXTURE, value);
  	}
  	get paintLayer1TilingOffset() {
  		return this._shaderValues.getVector(CartoonBodyMaterial.PAINT_LAYER1_TILINGOFFSET);
  	}
  	set paintLayer1TilingOffset(value) {
  		this._shaderValues.setVector(CartoonBodyMaterial.PAINT_LAYER1_TILINGOFFSET, value);
  	}
  	get paintLayer2Texture() {
  		return this._shaderValues.getTexture(CartoonBodyMaterial.PAINT_LAYER2_TEXTURE);
  	}
  	set paintLayer2Texture(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonBodyMaterial.SHADERDEFINE_LAYER2_TEXTURE);
  		}
  		else {
  			this._defineDatas.remove(CartoonBodyMaterial.SHADERDEFINE_LAYER2_TEXTURE);
  		}
  		this._shaderValues.setTexture(CartoonBodyMaterial.PAINT_LAYER2_TEXTURE, value);
  	}
  	get paintLayer2TilingOffset() {
  		return this._shaderValues.getVector(CartoonBodyMaterial.PAINT_LAYER2_TILINGOFFSET);
  	}
  	set paintLayer2TilingOffset(value) {
  		this._shaderValues.setVector(CartoonBodyMaterial.PAINT_LAYER2_TILINGOFFSET, value);
  	}
  	get normalTexture() {
  		return this._shaderValues.getTexture(CartoonBodyMaterial.NORMAL_TEXTURE);
  	}
  	set normalTexture(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonBodyMaterial.SHADERDEFINE_NORMALTEXTURE);
  		}
  		else {
  			this._defineDatas.remove(CartoonBodyMaterial.SHADERDEFINE_NORMALTEXTURE);
  		}
  		this._shaderValues.setTexture(CartoonBodyMaterial.NORMAL_TEXTURE, value);
  	}
  	get normalTextureScale() {
  		return this._shaderValues.getNumber(CartoonBodyMaterial.NORMAL_SCALE);
  	}
  	set normalTextureScale(value) {
  		this._shaderValues.setNumber(CartoonBodyMaterial.NORMAL_SCALE, value);
  	}
  	get normalTextureTillingOffset() {
  		return this._shaderValues.getVector(CartoonBodyMaterial.NORMAL_TILLING_OFFSET);
  	}
  	set normalTextureTillingOffset(value) {
  		this._shaderValues.setVector(CartoonBodyMaterial.NORMAL_TILLING_OFFSET, value);
  	}
  	get detailNormalTexture() {
  		return this._shaderValues.getTexture(CartoonBodyMaterial.DETAIL_NORMAL_TEXTURE);
  	}
  	set detailNormalTexture(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonBodyMaterial.SHADERDEFINE_DETAIL_NORMAL_TEXTURE);
  		}
  		else {
  			this._defineDatas.remove(CartoonBodyMaterial.SHADERDEFINE_DETAIL_NORMAL_TEXTURE);
  		}
  		this._shaderValues.setTexture(CartoonBodyMaterial.DETAIL_NORMAL_TEXTURE, value);
  	}
  	get detailNormalTextureTillingOffset() {
  		return this._shaderValues.getVector(CartoonBodyMaterial.DETAIL_NORMAL_TILLING_OFFSET);
  	}
  	set detailNormalTextureTillingOffset(value) {
  		this._shaderValues.setVector(CartoonBodyMaterial.DETAIL_NORMAL_TILLING_OFFSET, value);
  	}
  	get detailNormalTextureScale() {
  		return this._shaderValues.getNumber(CartoonBodyMaterial.DETAIL_NORMAL_SCALE);
  	}
  	set detailNormalTextureScale(value) {
  		this._shaderValues.setNumber(CartoonBodyMaterial.DETAIL_NORMAL_SCALE, value);
  	}
  	get reflectionCube() {
  		return this._shaderValues.getTexture(CartoonBodyMaterial.REFLECTION_CUBE);
  	}
  	set reflectionCube(value) {
  		if (value) {
  			this._defineDatas.add(CartoonBodyMaterial.SHADERDEFINE_REFLECT_CUBE);
  		}
  		else {
  			this._defineDatas.remove(CartoonBodyMaterial.SHADERDEFINE_REFLECT_CUBE);
  		}
  		this._shaderValues.setTexture(CartoonBodyMaterial.REFLECTION_CUBE, value);
  	}
  	get smoothness() {
  		return this._shaderValues.getNumber(CartoonBodyMaterial.SMOOTHNESS);
  	}
  	set smoothness(value) {
  		this._shaderValues.setNumber(CartoonBodyMaterial.SMOOTHNESS, value);
  	}
  	get reflectionBoxCenter() {
  		return this._shaderValues.getVector3(CartoonBodyMaterial.REFLECTION_BOX_CENTER);
  	}
  	set reflectionBoxCenter(value) {
  		this._shaderValues.setVector3(CartoonBodyMaterial.REFLECTION_BOX_CENTER, value);
  	}
  	get reflectionBoxSize() {
  		return this._shaderValues.getVector3(CartoonBodyMaterial.REFLECTION_BOX_SIZE);
  	}
  	set reflectionBoxSize(value) {
  		this._shaderValues.setVector3(CartoonBodyMaterial.REFLECTION_BOX_SIZE, value);
  	}
  	get metallic() {
  		return this._shaderValues.getNumber(CartoonBodyMaterial.METALLIC);
  	}
  	set metallic(value) {
  		this._shaderValues.setNumber(CartoonBodyMaterial.METALLIC, value);
  	}
  	set bPickZero(value) {
  		if (value) {
  			this._defineDatas.add(CartoonBodyMaterial.SHADERDEFINE_DRAWING_MASK_ZERO);
  		}
  		else {
  			this._defineDatas.remove(CartoonBodyMaterial.SHADERDEFINE_DRAWING_MASK_ZERO);
  		}
  	}
  	set FadeColor(value) {
  		this._shaderValues.setVector(CartoonBodyMaterial.FADE_COLOR, value);
  	}
  	set FadeFactor(value) {
  		this._shaderValues.setNumber(CartoonBodyMaterial.FADE_FACTOR, value);
  	}
  	get alphaTestValue() {
  		return this._shaderValues.getNumber(Laya.Material.ALPHATESTVALUE) || 0;
  	}
  	set alphaTestValue(value) {
  		if (value == null)
  			return;
  		this._shaderValues.setNumber(Laya.Material.ALPHATESTVALUE, value);
  	}
  	get outlineWidth() {
  		return this._shaderValues.getNumber(CartoonBodyMaterial.OUTLINEWIDTH);
  	}
  	set outlineWidth(value) {
  		value = Math.max(0.0, Math.min(0.05, value));
  		this._shaderValues.setNumber(CartoonBodyMaterial.OUTLINEWIDTH, value);
  	}
  	get outlineColor() {
  		return this._shaderValues.getVector(CartoonBodyMaterial.OUTLINECOLOR);
  	}
  	set outlineColor(value) {
  		this._shaderValues.setVector(CartoonBodyMaterial.OUTLINECOLOR, value);
  	}
  	get outlineBlend() {
  		return this._shaderValues.getNumber(CartoonBodyMaterial.OUTLINEBLEND);
  	}
  	set outlineBlend(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(CartoonBodyMaterial.OUTLINEBLEND, value);
  	}
  	get edgeHightlightEdge0() {
  		return this._shaderValues.getNumber(CartoonBodyMaterial.EDGE_HIGHTLIGHT_EDGE0);
  	}
  	set edgeHightlightEdge0(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(CartoonBodyMaterial.EDGE_HIGHTLIGHT_EDGE0, value);
  	}
  	get edgeHightlightEdge1() {
  		return this._shaderValues.getNumber(CartoonBodyMaterial.EDGE_HIGHTLIGHT_EDGE1);
  	}
  	set edgeHightlightEdge1(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(CartoonBodyMaterial.EDGE_HIGHTLIGHT_EDGE1, value);
  	}
  	get edgeHightlightColor() {
  		return this._shaderValues.getVector(CartoonBodyMaterial.EDGE_HIGHTLIGHT_COLOR);
  	}
  	set edgeHightlightColor(value) {
  		this._shaderValues.setVector(CartoonBodyMaterial.EDGE_HIGHTLIGHT_COLOR, value);
  	}
  	get metaColor() {
  		return this._shaderValues.getVector(CartoonBodyMaterial.META_COLOR);
  	}
  	set metaColor(value) {
  		this._shaderValues.setVector(CartoonBodyMaterial.META_COLOR, value);
  	}
  	get hightlightColor() {
  		return this._shaderValues.getVector(CartoonBodyMaterial.HIGHLIGHT_COLOR);
  	}
  	set hightlightColor(value) {
  		this._shaderValues.setVector(CartoonBodyMaterial.HIGHLIGHT_COLOR, value);
  	}
  	get bUseGlobalLight() {
  		return this._defineDatas.has(CartoonBodyMaterial.SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR);
  	}
  	set bUseGlobalLight(value) {
  		if (value) {
  			this._defineDatas.add(CartoonBodyMaterial.SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR);
  		}
  		else {
  			this._defineDatas.remove(CartoonBodyMaterial.SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR);
  		}
  	}
  	getCanEditorParamList() {
  		return [
  			{
  				name: `renderMode`, desc: `渲染模式`, type: EditorType.option, options: [
  					{ desc: "不透明", value: 1 },
  					{ desc: "裁剪", value: 2 },
  					{ desc: "裁剪双面", value: 3 },
  					{ desc: "透明", value: 4 },
  					{ desc: "透明双面", value: 5 },
  					{ desc: "不透明双面", value: 6 },
  				],
  			},
  			{ name: `outlineWidth`, desc: `描边宽度`, type: EditorType.slider, range: [0, 0.02, 4] },
  			{ name: `outlineColor`, desc: `描边颜色`, type: EditorType.color, },
  			{ name: `outlineBlend`, desc: `描边混合`, type: EditorType.slider, range: [0, 1] },
  			{ name: `alphaTestValue`, desc: `alpha裁剪参数`, type: EditorType.slider, range: [0, 1] },
  			{ name: `paintLayer1TilingOffset`, desc: `uv平铺`, type: EditorType.vec4 },
  			{ name: `renderQueue`, desc: `renderQueue`, type: EditorType.num },
  			{ name: `albedoColor`, desc: `基础色`, type: EditorType.color },
  			{ name: `lightmap`, desc: `阴影贴图`, type: EditorType.texture2d, options: mgrMaterial.textures },
  			{ name: `shadowColor`, desc: `阴影颜色`, type: EditorType.color },
  			{ name: `brightColor`, desc: `亮部颜色`, type: EditorType.color },
  			{ name: `shadowEdge0`, desc: `阴影边缘1`, type: EditorType.slider, range: [0, 1, 4] },
  			{ name: `shadowEdge1`, desc: `阴影边缘2`, type: EditorType.slider, range: [0, 1, 4] },
  			{ name: `hightlightShininess`, desc: `高光光泽度`, type: EditorType.slider, range: [0, 100, 4] },
  			{ name: `hightlightItensity`, desc: `高光强度`, type: EditorType.slider, range: [0, 5, 4] },
  			{ name: `hightlightColor`, desc: `高光高光颜色`, type: EditorType.color },
  			{ name: `edgeHightlightColor`, desc: `边缘高光颜色`, type: EditorType.color },
  			{ name: `edgeHightlightEdge0`, desc: `边缘高光边界1`, type: EditorType.slider, range: [0, 1, 4] },
  			{ name: `edgeHightlightEdge1`, desc: `边缘高光边界2`, type: EditorType.slider, range: [0, 1, 4] },
  		];
  	}
  }
  CartoonBodyMaterial.ALBEDOCOLOR = Laya.Shader3D.propertyNameToID("u_AlbedoColor");
  CartoonBodyMaterial.SHADOWCOLOR = Laya.Shader3D.propertyNameToID("u_ShadowColor");
  CartoonBodyMaterial.BRIGHTCOLOR = Laya.Shader3D.propertyNameToID("u_BrightColor");
  CartoonBodyMaterial.SHADOWEDGE0 = Laya.Shader3D.propertyNameToID("u_ShadowEdge0");
  CartoonBodyMaterial.SHADOWEDGE1 = Laya.Shader3D.propertyNameToID("u_ShadowEdge1");
  CartoonBodyMaterial.LIGHTMAP = Laya.Shader3D.propertyNameToID("u_LightMap");
  CartoonBodyMaterial.HIGHLIGHT_SHININESS = Laya.Shader3D.propertyNameToID("u_HightlightShininess");
  CartoonBodyMaterial.HIGHLIGHT_ITENSITY = Laya.Shader3D.propertyNameToID("u_HightlightItensity");
  CartoonBodyMaterial.HIGHLIGHT_COLOR = Laya.Shader3D.propertyNameToID("u_HightlightColor");
  CartoonBodyMaterial.META_COLOR = Laya.Shader3D.propertyNameToID("u_MetaColor");
  CartoonBodyMaterial.EDGE_HIGHTLIGHT_EDGE0 = Laya.Shader3D.propertyNameToID("u_EdgeHightlightEdge0");
  CartoonBodyMaterial.EDGE_HIGHTLIGHT_EDGE1 = Laya.Shader3D.propertyNameToID("u_EdgeHightlightEdge1");
  CartoonBodyMaterial.EDGE_HIGHTLIGHT_COLOR = Laya.Shader3D.propertyNameToID("u_EdgeHightlightColor");
  CartoonBodyMaterial.DIRECTIONLIGHTDIRECTION = Laya.Shader3D.propertyNameToID("u_SunLight.direction");
  CartoonBodyMaterial.DIRECTIONLIGHTCOLOR = Laya.Shader3D.propertyNameToID("u_SunLight.color");
  CartoonBodyMaterial.SPOT_LIGHT_COLOR = Laya.Shader3D.propertyNameToID("u_SpotLight.color");
  CartoonBodyMaterial.SPOT_LIGHT_DIRECTION = Laya.Shader3D.propertyNameToID("u_SpotLight.direction");
  CartoonBodyMaterial.SPOT_LIGHT_RANGE = Laya.Shader3D.propertyNameToID("u_SpotLight.range");
  CartoonBodyMaterial.SPOT_LIGHT_SPOT = Laya.Shader3D.propertyNameToID("u_SpotLight.spot");
  CartoonBodyMaterial.SPOT_LIGHT_POSITION = Laya.Shader3D.propertyNameToID("u_SpotLight.position");
  CartoonBodyMaterial.WHOLE_ALPHA = Laya.Shader3D.propertyNameToID("u_alpha");
  CartoonBodyMaterial.NORMAL_TEXTURE = Laya.Shader3D.propertyNameToID("u_NormalTexture");
  CartoonBodyMaterial.NORMAL_SCALE = Laya.Shader3D.propertyNameToID("u_NormalScale");
  CartoonBodyMaterial.NORMAL_TILLING_OFFSET = Laya.Shader3D.propertyNameToID("u_NormalTillingOffset");
  CartoonBodyMaterial.DETAIL_NORMAL_TEXTURE = Laya.Shader3D.propertyNameToID("u_DetailNormalTexture");
  CartoonBodyMaterial.DETAIL_NORMAL_TILLING_OFFSET = Laya.Shader3D.propertyNameToID("u_DetailNormalTillingOffset");
  CartoonBodyMaterial.DETAIL_NORMAL_SCALE = Laya.Shader3D.propertyNameToID("u_DetailNormalScale");
  CartoonBodyMaterial.REFLECTION_CUBE = Laya.Shader3D.propertyNameToID("u_reflection_cube");
  CartoonBodyMaterial.SMOOTHNESS = Laya.Shader3D.propertyNameToID("u_Smoothness");
  CartoonBodyMaterial.METALLIC = Laya.Shader3D.propertyNameToID("u_Metallic");
  CartoonBodyMaterial.REFLECTION_BOX_CENTER = Laya.Shader3D.propertyNameToID("u_reflection_box_center");
  CartoonBodyMaterial.REFLECTION_BOX_SIZE = Laya.Shader3D.propertyNameToID("u_reflection_box_size");
  CartoonBodyMaterial.FADE_FACTOR = Laya.Shader3D.propertyNameToID("u_fade_factor");
  CartoonBodyMaterial.FADE_COLOR = Laya.Shader3D.propertyNameToID("u_fade_color");
  CartoonBodyMaterial.PROGRESS = Laya.Shader3D.propertyNameToID("u_Progress");
  CartoonBodyMaterial.BURN_FACTOR = Laya.Shader3D.propertyNameToID("u_BurnFactor");
  CartoonBodyMaterial.BURNTEXTURE = Laya.Shader3D.propertyNameToID("u_BurnTexture");
  CartoonBodyMaterial.BRUN_TEXTURE_TILLING_OFFSET = Laya.Shader3D.propertyNameToID("u_BurnTextureTillingOffset");
  CartoonBodyMaterial.PAINT_LAYER1_TEXTURE = Laya.Shader3D.propertyNameToID("u_PaintLayer1Texture");
  CartoonBodyMaterial.PAINT_LAYER1_TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_PaintLayer1TilingOffset");
  CartoonBodyMaterial.PAINT_LAYER2_TEXTURE = Laya.Shader3D.propertyNameToID("u_PaintLayer2Texture");
  CartoonBodyMaterial.PAINT_LAYER2_TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_PaintLayer2TilingOffset");
  CartoonBodyMaterial.OUTLINEWIDTH = Laya.Shader3D.propertyNameToID("u_OutlineWidth");
  CartoonBodyMaterial.OUTLINEBLEND = Laya.Shader3D.propertyNameToID("u_OutlineBlend");
  CartoonBodyMaterial.OUTLINECOLOR = Laya.Shader3D.propertyNameToID("u_OutlineColor");
  CartoonBodyMaterial.CULL = Laya.Shader3D.propertyNameToID("s_Cull");
  CartoonBodyMaterial.BLEND = Laya.Shader3D.propertyNameToID("s_Blend");
  CartoonBodyMaterial.BLEND_SRC = Laya.Shader3D.propertyNameToID("s_BlendSrc");
  CartoonBodyMaterial.BLEND_DST = Laya.Shader3D.propertyNameToID("s_BlendDst");
  CartoonBodyMaterial.DEPTH_TEST = Laya.Shader3D.propertyNameToID("s_DepthTest");
  CartoonBodyMaterial.DEPTH_WRITE = Laya.Shader3D.propertyNameToID("s_DepthWrite");
  CartoonBodyMaterial.RENDERMODE_OPAQUE = 1;
  CartoonBodyMaterial.RENDERMODE_CUTOUT = 2;
  CartoonBodyMaterial.RENDERMODE_CUTOUT_CULL_NONE = 3;
  CartoonBodyMaterial.RENDERMODE_TRANSPARENT = 4;
  CartoonBodyMaterial.RENDERMODE_TRANSPARENT_CULL_NONE = 5;
  CartoonBodyMaterial.RENDERMODE_OPAQUE_CULL_NONE = 6;

  const CartoonClothVs = `
#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";

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;

varying vec4 v_posView;

#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;

#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
	varying vec4 v_ShadowCoord;
#endif

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; 

	v_posView = gl_Position.xyzw;
	gl_Position.z=gl_Position.z * 2.0 - gl_Position.w;

	#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
		v_ShadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));
	#endif
}`;
  const CartoonClothFs = `
#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";

uniform DirectionLight u_SunLight;

#ifdef SPOTLIGHT
	struct SpotLight {
		vec3 color;
		vec3 position;
		float range;
		vec3 direction;
		float spot;
	};
	uniform SpotLight u_SpotLight;
#endif

#ifdef ALBEDOCOLOR
	uniform vec4 u_AlbedoColor;
#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

#ifdef SHADERDEFINE_BURN
	uniform float u_BurnFactor;
	uniform sampler2D u_BurnTexture;
	uniform vec4 u_BurnTextureTillingOffset;
#endif

varying vec2 v_Texcoord0;
varying vec3 v_Normal;
varying vec3 v_PositionWorld;
varying vec3 v_ViewDir;
varying vec3 v_worldPos;
varying vec4 v_posView;
varying float v_viewDistance;

uniform vec4 u_ShadowColor;
uniform vec4 u_BrightColor;
uniform float u_ShadowEdge0;
uniform float u_ShadowEdge1;
uniform sampler2D u_LightMap;
uniform vec4 u_LightMapTillingOffset;
uniform float u_HightlightShininess;
uniform float u_HightlightItensity;
uniform vec4 u_HightlightColor;
uniform vec4 u_MetaColor;

uniform float u_EdgeHightlightEdge0;
uniform float u_EdgeHightlightEdge1;
uniform vec4 u_EdgeHightlightColor;

//喷绘相关
uniform sampler2D u_PaintLayer1Texture;
uniform vec4 u_PaintLayer1TilingOffset;
uniform sampler2D u_PaintLayer2Texture;
uniform vec4 u_PaintLayer2TilingOffset;

uniform float u_fade_factor;
uniform vec4 u_fade_color;

#ifdef SHADERDEFINE_CUT_TEXTURE
uniform sampler2D u_CutTexture;
#endif

#ifdef SHADERDEFINE_TIP_TEXTURE
uniform sampler2D u_TipTexture;
#endif


#ifdef WHOLE_ALPHA
uniform float u_alpha;
#endif
uniform float u_AlphaTestValue;
uniform float u_Progress;
uniform float u_Time;

#if defined(CALCULATE_SHADOWS)&&!defined(SHADOW_CASCADE)
	varying vec4 v_ShadowCoord;
#endif

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_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 disCamera = clamp(v_viewDistance, minv, maxv);
		float scalefactor = 1.0 - (disCamera - 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(0.0);
	
	
	vec2 texcoord = vec2(v_Texcoord0.x, 1.0 - v_Texcoord0.y);
	#ifdef LAYER1_TEXTURE
		// 计算层级1的颜色
		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;
	#endif

	#ifdef LAYER2_TEXTURE
		// 计算层级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.rgba = albedoTextureColor.rgba * (1.0 - paintLayer2Color.a) + paintLayer2Color.a * paintLayer2Color.rgba;
		albedoTextureColor.rgb = albedoTextureColor.rgb * (1.0 - paintLayer2Color.a) + paintLayer2Color.rgb;
		albedoTextureColor.a = albedoTextureColor.a * (1.0 - paintLayer2Color.a) + paintLayer2Color.a;
	#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 SHADERDEFINE_PROGRESS
		float through = 0.02;
		float halfTh = through/2.0;
		float realP = v_posView.y/v_posView.w * 0.5 + 0.5;
		//是否在进度跳
		float fInP = step(realP, u_Progress - halfTh);
		float fInNP = step(u_Progress + halfTh, realP);
		float aFactor = fInNP * 0.0 + fInP * 1.0 + (1.0 - fInP)*(1.0-fInNP)*(1.0 - (realP - u_Progress + halfTh)/through);
		albedoTextureColor.a *= aFactor;
	#endif

	#ifdef SHADERDEFINE_BURN
		#ifdef SHADERDEFINE_BURN_INVERST
			//噪波图的当前值
			float value = texture2D(u_BurnTexture, TransformUV(v_Texcoord0, u_BurnTextureTillingOffset)).x;

			float disburn = distance(v_posView.xyz/v_posView.w, vec3(0,0,0));
			disburn += value;
			float through = 0.02;

			float inMaxRange = step(disburn , u_BurnFactor + through*2.0);
			float outSecondRange = step(u_BurnFactor + through, disburn);
			float inFirst = inMaxRange * outSecondRange;
			
			float inSencondRange = step(disburn, u_BurnFactor + through);
			float outThirdRange = step(u_BurnFactor, disburn);
			float inSecond = inSencondRange * outThirdRange;

			float inThird = step(disburn, u_BurnFactor);
			float inFourth = (1.0 - inFirst) * (1.0 - inSecond) * (1.0 - inThird);

			vec4 outColor = vec4(236.0/255.0, 131.0/255.0, 255.0/255.0, albedoTextureColor.a);
			vec4 secondColor = vec4(245.0/255.0, 228.0/255.0, 255.0/255.0, albedoTextureColor.a);
			vec4 thirdColor = albedoTextureColor.rgba;
			vec4 forthColor = vec4(0.0,0.0,0.0,0.0);

			albedoTextureColor = outColor*inFirst + secondColor*inSecond + inThird * thirdColor + forthColor * inFourth;

			// if(disburn < u_BurnFactor + through*2.0 && disburn >= u_BurnFactor + through){
			// 	albedoTextureColor.a = albedoTextureColor.a;
			// 	albedoTextureColor.rgb = vec3(236.0/255.0, 131.0/255.0, 255.0/255.0);
			// }
			// else if(disburn < u_BurnFactor + through && disburn >= u_BurnFactor){
			// 	albedoTextureColor.a = albedoTextureColor.a;
			// 	albedoTextureColor.rgb = vec3(245.0/255.0, 228.0/255.0, 255.0/255.0);
			// }
			// else if(disburn > u_BurnFactor){
			// 	albedoTextureColor.a = 0.0;
			// }
			// else{
			// 	albedoTextureColor.a = albedoTextureColor.a;
			// }
		#else
			//噪波图的当前值
			float value = texture2D(u_BurnTexture, TransformUV(v_Texcoord0, u_BurnTextureTillingOffset)).x;

			float disburn = distance(v_posView.xyz/v_posView.w, vec3(0,0,0));
			disburn += value;
			float through = 0.02;

			float inMaxRange = step(disburn , u_BurnFactor + through*2.0);
			float outSecondRange = step(u_BurnFactor + through, disburn);
			float inFirst = inMaxRange * outSecondRange;
			
			float inSencondRange = step(disburn, u_BurnFactor + through);
			float outThirdRange = step(u_BurnFactor, disburn);
			float inSecond = inSencondRange * outThirdRange;

			float inThird = step(disburn, u_BurnFactor);
			float inFourth = (1.0 - inFirst) * (1.0 - inSecond) * (1.0 - inThird);

			vec4 outColor = vec4(236.0/255.0, 131.0/255.0, 255.0/255.0, albedoTextureColor.a);
			vec4 secondColor = vec4(245.0/255.0, 228.0/255.0, 255.0/255.0, albedoTextureColor.a);
			vec4 thirdColor = vec4(0.0,0.0,0.0,0.0);
			vec4 forthColor = albedoTextureColor.rgba;
			
			albedoTextureColor = outColor*inFirst + secondColor*inSecond + inThird * thirdColor + forthColor * inFourth;

			// if(disburn < u_BurnFactor + through*2.0 && disburn >= u_BurnFactor + through){
			// 	albedoTextureColor.a = albedoTextureColor.a;
			// 	albedoTextureColor.rgb = vec3(245.0/255.0, 228.0/255.0, 255.0/255.0);
			// }
			// else if(disburn < u_BurnFactor + through && disburn >= u_BurnFactor){
			// 	albedoTextureColor.a = albedoTextureColor.a;
			// 	albedoTextureColor.rgb = vec3(236.0/255.0, 131.0/255.0, 255.0/255.0);
			// }
			// else if(disburn < u_BurnFactor){
			// 	albedoTextureColor.a = 0.0;
			// }
			// else{
			// 	albedoTextureColor.a = albedoTextureColor.a;
			// }
		#endif
	#endif

	#ifdef SHADERDEFINE_CUT_TEXTURE
		vec2 texcoordCutTexture = vec2(v_Texcoord0.x, v_Texcoord0.y);
		vec4 cutTextureColor = texture2D(u_CutTexture, texcoordCutTexture);
		//r 通道表示可裁剪区域, r通道随时间显示为红色的; b通道表示是否展示可裁剪区域.
		// float f1 = cutTextureColor.r * cutTextureColor.b * (cos(u_Time*2.5)/2.0 + 0.5);
		// albedoTextureColor.rgb = albedoTextureColor.rgb * (1.0 - f1) + vec3(0.9,0.9,1.0) * f1;
		// g通道表示已裁剪区域;
		albedoTextureColor.a *= (1.0 - cutTextureColor.g * cutTextureColor.r);
	#endif

	#ifdef SHADERDEFINE_TIP_TEXTURE
		vec2 texcoordTipTexture = vec2(v_Texcoord0.x, v_Texcoord0.y);
		vec4 tipTextureColor = texture2D(u_TipTexture, texcoordTipTexture);
		#ifdef SHADERDEFINE_TIPPASS_R
			//提示r通道
			float f2 = tipTextureColor.r * (cos(u_Time*5.0)/2.0 + 0.5);
			albedoTextureColor.rgb = albedoTextureColor.rgb * (1.0 - f2) + albedoTextureColor.rgb * 0.8 * f2;
		#endif
		#ifdef SHADERDEFINE_TIPPASS_G
			//提示g通道
			float f2 = tipTextureColor.g * (cos(u_Time*5.0)/2.0 + 0.5);
			albedoTextureColor.rgb = albedoTextureColor.rgb * (1.0 - f2) + albedoTextureColor.rgb * 0.8 * f2;
		#endif
		#ifdef SHADERDEFINE_TIPPASS_B
			//提示b通道
			float f2 = tipTextureColor.b * (cos(u_Time*5.0)/2.0 + 0.5);
			albedoTextureColor.rgb = albedoTextureColor.rgb * (1.0 - f2) + albedoTextureColor.rgb * 0.8 * f2;
		#endif
	#endif
	
	#ifdef ALPHATEST
		if(albedoTextureColor.a <= u_AlphaTestValue){
			discard;
		}
	#endif

	#ifdef ALBEDOCOLOR
		albedoTextureColor *= u_AlbedoColor;
	#endif

	//屏蔽掉卡通色转换, 使用模型原始颜色
	vec3 albedoColor = albedoTextureColor.rgb;
	// #ifdef SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR
	// 	vec3 brightColor = u_SunLight.color;
	// #else
	// 	vec3 brightColor = u_BrightColor.rgb;
	// #endif
	vec3 brightColor = u_BrightColor.rgb;
	//使用lightMap
	vec2 texcoordLightMap = vec2(v_Texcoord0.x, v_Texcoord0.y);
	texcoordLightMap = TransformUV(texcoordLightMap, u_LightMapTillingOffset);
	vec4 lightMapColor = texture2D(u_LightMap, texcoordLightMap);

	//使用通道图控制光照
	float ndotl = max(dot(normal, -lightDir), 0.0);
	float wrapLambert = ndotl + lightMapColor.g;
	float shadowStep = smoothstep(u_ShadowEdge0, u_ShadowEdge1, wrapLambert);
	vec3 finalColor = u_ShadowColor.rgb * (1.0-shadowStep) + brightColor * shadowStep;
	//计算金属
	finalColor = lightMapColor.r * u_MetaColor.rgb + (1.0 - lightMapColor.r) * finalColor;
	//计算高光部分
	finalColor += pow(ndotl, u_HightlightShininess) * lightMapColor.r * u_HightlightItensity * u_HightlightColor.rgb;

	#ifdef SHADERDEFINE_USE_DEFAULT_HIGHTLIGHT
	#else		
	#endif


	//计算边缘高光部分
	float ndotv = max(dot(normal, viewdir), 0.0);
	float edgeHightlightStep = smoothstep(u_EdgeHightlightEdge0,u_EdgeHightlightEdge1, ndotv);
	finalColor = u_EdgeHightlightColor.rgb *2.0*finalColor* edgeHightlightStep + finalColor * (1.0 - edgeHightlightStep);

	float shadowAttenuation = 1.0;
	#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
				shadowAttenuation *= sampleShadowmap(shadowCoord);
			#endif
		#else
			#ifdef SHADOW_CASCADE
				vec4 shadowCoord = getShadowCoord(vec4(v_PositionWorld,1.0));
			#else
				vec4 shadowCoord = v_ShadowCoord;
			#endif
			shadowAttenuation *= sampleShadowmap(shadowCoord);
		#endif
	#endif
	finalColor *= shadowAttenuation;
	
	
	finalColor.rgb *= albedoColor.rgb;



	#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 = albedoColor.rgb * inSpot * inDir * 0.5;
		vec3 sunColor = u_SunLight.color * albedoColor.rgb;

		finalColor *= spotColor + sunColor;
	#else
		finalColor *= u_SunLight.color;
	#endif

	#ifdef SHADERDEFINE_GRAY
		float ff = (finalColor.r + finalColor.g + finalColor.b)/3.0;
		finalColor.rgb = vec3(ff, ff, ff);
	#endif

	#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();
}`;

  class CartoonClothMaterial extends Laya.Material {
  	constructor() {
  		super();
  		this.setShaderName("CartoonClothMaterial");
  		this._shaderValues.setVector(CartoonClothMaterial.SHADOWCOLOR, new Laya.Vector4(0.6663285, 0.6544118, 1, 1));
  		this.outlineWidth = 0.001;
  		this.outlineColor = new Laya.Vector4(0.5, 0.5, 0.5, 1);
  		this.outlineBlend = 1;
  		this.shadowEdge0 = 0;
  		this.shadowEdge1 = 0.1;
  		this.shadowColor = new Laya.Vector4(0.5, 0.5, 0.5, 1);
  		this.brightColor = new Laya.Vector4(1, 1, 1, 1);
  		this.hightlightShininess = 2.0;
  		this.hightlightItensity = 0.5;
  		this.metaColor = new Laya.Vector4(1, 1, 1, 1);
  		this.hightlightColor = new Laya.Vector4(1, 1, 1, 1);
  		this.edgeHightlightColor = new Laya.Vector4(1.0, 1.0, 1.0, 1.0);
  		this.edgeHightlightEdge0 = 0.6;
  		this.edgeHightlightEdge1 = 0.5;
  		this._shaderValues.setNumber(CartoonClothMaterial.NORMAL_SCALE, 1.0);
  		this._shaderValues.setNumber(CartoonClothMaterial.DETAIL_NORMAL_SCALE, 1.0);
  		this.normalTextureScale = 1;
  		this.detailNormalTextureScale = 1;
  		this.paintLayer1TilingOffset = new Laya.Vector4(1, 1, 0, 0);
  		this.paintLayer2TilingOffset = new Laya.Vector4(1, 1, 0, 0);
  		this.detailNormalTextureTillingOffset = new Laya.Vector4(1, 1, 0, 0);
  		this.LightMapTillingOffset = new Laya.Vector4(1, 1, 0, 0);
  		this.smoothness = 0.0;
  		this.metallic = 0.0;
  		this.FadeColor = new Laya.Vector4;
  		this.FadeFactor = 0.0;
  		this.alphaTestValue = 0.5;
  		this.alpha = 1;
  		this.bUseGlobalLight = false;
  	}
  	static __init__() {
  		CartoonClothMaterial.SHADERDEFINE_ALBEDOCOLOR = Laya.Shader3D.getDefineByName("ALBEDOCOLOR");
  		CartoonClothMaterial.SHADERDEFINE_BONE = Laya.Shader3D.getDefineByName("BONE");
  		CartoonClothMaterial.SHADERDEFINE_WHOLE_ALPHA = Laya.Shader3D.getDefineByName("WHOLE_ALPHA");
  		CartoonClothMaterial.SHADERDEFINE_NORMALTEXTURE = Laya.Shader3D.getDefineByName("NORMALTEXTURE");
  		CartoonClothMaterial.SHADERDEFINE_DETAIL_NORMAL_TEXTURE = Laya.Shader3D.getDefineByName("DETAIL_NORMAL_TEXTURE");
  		CartoonClothMaterial.SHADERDEFINE_LAYER1_TEXTURE = Laya.Shader3D.getDefineByName("LAYER1_TEXTURE");
  		CartoonClothMaterial.SHADERDEFINE_LAYER2_TEXTURE = Laya.Shader3D.getDefineByName("LAYER2_TEXTURE");
  		CartoonClothMaterial.SHADERDEFINE_REFLECT_CUBE = Laya.Shader3D.getDefineByName("REFLECT_CUBE");
  		CartoonClothMaterial.SHADERDEFINE_FRESNEL_REFLECTION = Laya.Shader3D.getDefineByName("FRESNEL_REFLECTION");
  		CartoonClothMaterial.SHADERDEFINE_DRAWING_MASK = Laya.Shader3D.getDefineByName("SHADERDEFINE_DRAWING_MASK");
  		CartoonClothMaterial.SHADERDEFINE_DRAWING_MASK_ZERO = Laya.Shader3D.getDefineByName("SHADERDEFINE_DRAWING_MASK_ZERO");
  		CartoonClothMaterial.SHADERDEFINE_GRAY = Laya.Shader3D.getDefineByName("SHADERDEFINE_GRAY");
  		CartoonClothMaterial.SHADERDEFINE_PROGRESS = Laya.Shader3D.getDefineByName("SHADERDEFINE_PROGRESS");
  		CartoonClothMaterial.SHADERDEFINE_BURN = Laya.Shader3D.getDefineByName("SHADERDEFINE_BURN");
  		CartoonClothMaterial.SHADERDEFINE_BURN_INVERST = Laya.Shader3D.getDefineByName("SHADERDEFINE_BURN_INVERST");
  		CartoonClothMaterial.SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR = Laya.Shader3D.getDefineByName("SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR");
  		CartoonClothMaterial.SHADERDEFINE_CUT_TEXTURE = Laya.Shader3D.getDefineByName("SHADERDEFINE_CUT_TEXTURE");
  		CartoonClothMaterial.SHADERDEFINE_TIP_TEXTURE = Laya.Shader3D.getDefineByName("SHADERDEFINE_TIP_TEXTURE");
  		CartoonClothMaterial.SHADERDEFINE_TIPPASS_R = Laya.Shader3D.getDefineByName("SHADERDEFINE_TIPPASS_R");
  		CartoonClothMaterial.SHADERDEFINE_TIPPASS_G = Laya.Shader3D.getDefineByName("SHADERDEFINE_TIPPASS_G");
  		CartoonClothMaterial.SHADERDEFINE_TIPPASS_B = Laya.Shader3D.getDefineByName("SHADERDEFINE_TIPPASS_B");
  		CartoonClothMaterial.SHADERDEFINE_TIPPASS_A = Laya.Shader3D.getDefineByName("SHADERDEFINE_TIPPASS_A");
  	}
  	static initShader() {
  		CartoonClothMaterial.__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_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_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_PaintLayer1Texture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_PaintLayer1TilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_PaintLayer2Texture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_PaintLayer2TilingOffset': Laya.Shader3D.PERIOD_MATERIAL,
  			"u_fade_factor": Laya.Shader3D.PERIOD_MATERIAL,
  			"u_fade_color": Laya.Shader3D.PERIOD_MATERIAL,
  			'u_AlphaTestValue': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_Progress': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BurnTexture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BurnFactor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BurnTextureTillingOffset': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_OutlineWidth': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_OutlineBlend': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_OutlineColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_ShadowColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_BrightColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_ShadowEdge0': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_ShadowEdge1': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_LightMap': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_LightMapTillingOffset': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_HightlightShininess': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_HightlightItensity': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_HightlightColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_MetaColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_EdgeHightlightEdge0': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_EdgeHightlightEdge1': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_EdgeHightlightColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'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_ViewProjection': Laya.Shader3D.PERIOD_CAMERA,
  			'u_CutTexture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_TipTexture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_Time': Laya.Shader3D.PERIOD_SCENE,
  		};
  		var CartoonClothMaterial3D = Laya.Shader3D.add("CartoonClothMaterial");
  		var subShader = new Laya.SubShader(attributeMap, uniformMap);
  		CartoonClothMaterial3D.addSubShader(subShader);
  		var vs1 = CartoonStrokeVs;
  		var ps1 = CartoonStrokeFs;
  		var pass1 = subShader.addShaderPass(vs1, ps1);
  		pass1.renderState.cull = Laya.RenderState.CULL_FRONT;
  		var vs2 = CartoonClothVs;
  		var ps2 = CartoonClothFs;
  		subShader.addShaderPass(vs2, ps2, stateMap);
  		subShader.addShaderPass(PBRShadowCasterVS, PBRShadowCasterPS, stateMap, "ShadowCaster");
  	}
  	get cull() {
  		return this._shaderValues.getInt(CartoonClothMaterial.CULL);
  	}
  	set cull(value) {
  		this._shaderValues.setInt(CartoonClothMaterial.CULL, value);
  	}
  	get blend() {
  		return this._shaderValues.getInt(CartoonClothMaterial.BLEND);
  	}
  	set blend(value) {
  		this._shaderValues.setInt(CartoonClothMaterial.BLEND, value);
  	}
  	get blendSrc() {
  		return this._shaderValues.getInt(CartoonClothMaterial.BLEND_SRC);
  	}
  	set blendSrc(value) {
  		this._shaderValues.setInt(CartoonClothMaterial.BLEND_SRC, value);
  	}
  	get blendDst() {
  		return this._shaderValues.getInt(CartoonClothMaterial.BLEND_DST);
  	}
  	set blendDst(value) {
  		this._shaderValues.setInt(CartoonClothMaterial.BLEND_DST, value);
  	}
  	get depthTest() {
  		return this._shaderValues.getInt(CartoonClothMaterial.DEPTH_TEST);
  	}
  	set depthTest(value) {
  		this._shaderValues.setInt(CartoonClothMaterial.DEPTH_TEST, value);
  	}
  	get depthWrite() {
  		return this._shaderValues.getBool(CartoonClothMaterial.DEPTH_WRITE);
  	}
  	set depthWrite(value) {
  		this._shaderValues.setBool(CartoonClothMaterial.DEPTH_WRITE, value);
  	}
  	get renderMode() {
  		return this.__render_mode__;
  	}
  	set renderMode(value) {
  		this.__render_mode__ = value;
  		switch (value) {
  			case CartoonClothMaterial.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 CartoonClothMaterial.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 CartoonClothMaterial.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 CartoonClothMaterial.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 CartoonClothMaterial.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 CartoonClothMaterial.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 bBurnInvert() {
  		return this._shaderValues.hasDefine(CartoonClothMaterial.SHADERDEFINE_BURN_INVERST);
  	}
  	set bBurnInvert(value) {
  		if (value) {
  			this._shaderValues.addDefine(CartoonClothMaterial.SHADERDEFINE_BURN_INVERST);
  		}
  		else {
  			this._shaderValues.removeDefine(CartoonClothMaterial.SHADERDEFINE_BURN_INVERST);
  		}
  	}
  	get burnFactor() {
  		return this._shaderValues.getNumber(CartoonClothMaterial.BURN_FACTOR);
  	}
  	set burnFactor(value) {
  		if (value != null) {
  			value = Math.max(0.0, value);
  			this._shaderValues.setNumber(CartoonClothMaterial.BURN_FACTOR, value);
  		}
  	}
  	get cutTexture() {
  		return this._shaderValues.getTexture(CartoonClothMaterial.CUT_TEXTURE);
  	}
  	set cutTexture(value) {
  		if (value) {
  			this._defineDatas.add(CartoonClothMaterial.SHADERDEFINE_CUT_TEXTURE);
  			this._shaderValues.setTexture(CartoonClothMaterial.CUT_TEXTURE, value);
  		}
  		else {
  			this._defineDatas.remove(CartoonClothMaterial.SHADERDEFINE_CUT_TEXTURE);
  		}
  	}
  	get tipTexture() {
  		return this._shaderValues.getTexture(CartoonClothMaterial.TIP_TEXTURE);
  	}
  	set tipTexture(value) {
  		if (value) {
  			this._defineDatas.add(CartoonClothMaterial.SHADERDEFINE_TIP_TEXTURE);
  			this._shaderValues.setTexture(CartoonClothMaterial.TIP_TEXTURE, value);
  		}
  		else {
  			this._defineDatas.remove(CartoonClothMaterial.SHADERDEFINE_TIP_TEXTURE);
  		}
  	}
  	set tipPassR(value) {
  		if (value) {
  			this._defineDatas.add(CartoonClothMaterial.SHADERDEFINE_TIPPASS_R);
  		}
  		else {
  			this._defineDatas.remove(CartoonClothMaterial.SHADERDEFINE_TIPPASS_R);
  		}
  	}
  	set tipPassG(value) {
  		if (value) {
  			this._defineDatas.add(CartoonClothMaterial.SHADERDEFINE_TIPPASS_G);
  		}
  		else {
  			this._defineDatas.remove(CartoonClothMaterial.SHADERDEFINE_TIPPASS_G);
  		}
  	}
  	set tipPassB(value) {
  		if (value) {
  			this._defineDatas.add(CartoonClothMaterial.SHADERDEFINE_TIPPASS_B);
  		}
  		else {
  			this._defineDatas.remove(CartoonClothMaterial.SHADERDEFINE_TIPPASS_B);
  		}
  	}
  	get burnTexture() {
  		return this._shaderValues.getTexture(CartoonClothMaterial.BURNTEXTURE);
  	}
  	set burnTexture(value) {
  		if (value) {
  			this._defineDatas.add(CartoonClothMaterial.SHADERDEFINE_BURN);
  			this._shaderValues.setTexture(CartoonClothMaterial.BURNTEXTURE, value);
  		}
  		else {
  			this._defineDatas.remove(CartoonClothMaterial.SHADERDEFINE_BURN);
  		}
  	}
  	get BurnTillingOffset() {
  		return this._shaderValues.getVector(CartoonClothMaterial.BRUN_TEXTURE_TILLING_OFFSET);
  	}
  	set BurnTillingOffset(value) {
  		this._shaderValues.setVector(CartoonClothMaterial.BRUN_TEXTURE_TILLING_OFFSET, value);
  	}
  	get mprogress() {
  		return this._shaderValues.getNumber(CartoonClothMaterial.PROGRESS);
  	}
  	set mprogress(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonClothMaterial.SHADERDEFINE_PROGRESS);
  			value = Math.max(0.0, value);
  			this._shaderValues.setNumber(CartoonClothMaterial.PROGRESS, value);
  		}
  		else {
  			this._defineDatas.remove(CartoonClothMaterial.SHADERDEFINE_PROGRESS);
  		}
  	}
  	get gray() {
  		if (this._defineDatas.has(CartoonClothMaterial.SHADERDEFINE_GRAY)) {
  			return true;
  		}
  		else {
  			return false;
  		}
  	}
  	set gray(value) {
  		if (value) {
  			this._defineDatas.add(CartoonClothMaterial.SHADERDEFINE_GRAY);
  		}
  		else {
  			this._defineDatas.remove(CartoonClothMaterial.SHADERDEFINE_GRAY);
  		}
  	}
  	get albedoColor() {
  		return this._shaderValues.getVector(CartoonClothMaterial.ALBEDOCOLOR);
  	}
  	set albedoColor(value) {
  		if (value) {
  			this._defineDatas.add(CartoonClothMaterial.SHADERDEFINE_ALBEDOCOLOR);
  		}
  		else {
  			this._defineDatas.remove(CartoonClothMaterial.SHADERDEFINE_ALBEDOCOLOR);
  		}
  		this._shaderValues.setVector(CartoonClothMaterial.ALBEDOCOLOR, value);
  	}
  	get shadowColor() {
  		return this._shaderValues.getVector(CartoonClothMaterial.SHADOWCOLOR);
  	}
  	set shadowColor(value) {
  		this._shaderValues.setVector(CartoonClothMaterial.SHADOWCOLOR, value);
  	}
  	get brightColor() {
  		return this._shaderValues.getVector(CartoonClothMaterial.BRIGHTCOLOR);
  	}
  	set brightColor(value) {
  		this._shaderValues.setVector(CartoonClothMaterial.BRIGHTCOLOR, value);
  	}
  	get shadowEdge0() {
  		return this._shaderValues.getNumber(CartoonClothMaterial.SHADOWEDGE0);
  	}
  	set shadowEdge0(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(CartoonClothMaterial.SHADOWEDGE0, value);
  	}
  	get shadowEdge1() {
  		return this._shaderValues.getNumber(CartoonClothMaterial.SHADOWEDGE1);
  	}
  	set shadowEdge1(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(CartoonClothMaterial.SHADOWEDGE1, value);
  	}
  	get lightmap() {
  		return this._shaderValues.getTexture(CartoonClothMaterial.LIGHTMAP);
  	}
  	set lightmap(value) {
  		this._shaderValues.setTexture(CartoonClothMaterial.LIGHTMAP, value);
  	}
  	get LightMapTillingOffset() {
  		return this._shaderValues.getVector(CartoonClothMaterial.LIGHTMAP_TILLING_OFFSET);
  	}
  	set LightMapTillingOffset(value) {
  		this._shaderValues.setVector(CartoonClothMaterial.LIGHTMAP_TILLING_OFFSET, value);
  	}
  	get hightlightShininess() {
  		return this._shaderValues.getNumber(CartoonClothMaterial.HIGHLIGHT_SHININESS);
  	}
  	set hightlightShininess(value) {
  		this._shaderValues.setNumber(CartoonClothMaterial.HIGHLIGHT_SHININESS, value);
  	}
  	get hightlightItensity() {
  		return this._shaderValues.getNumber(CartoonClothMaterial.HIGHLIGHT_ITENSITY);
  	}
  	set hightlightItensity(value) {
  		this._shaderValues.setNumber(CartoonClothMaterial.HIGHLIGHT_ITENSITY, value);
  	}
  	get alpha() {
  		return this._shaderValues.getNumber(CartoonClothMaterial.WHOLE_ALPHA);
  	}
  	set alpha(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonClothMaterial.SHADERDEFINE_WHOLE_ALPHA);
  		}
  		else {
  			this._defineDatas.remove(CartoonClothMaterial.SHADERDEFINE_WHOLE_ALPHA);
  		}
  		this._shaderValues.setNumber(CartoonClothMaterial.WHOLE_ALPHA, value);
  	}
  	get albedoTexture() {
  		return this._shaderValues.getTexture(CartoonClothMaterial.PAINT_LAYER1_TEXTURE);
  	}
  	set albedoTexture(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonClothMaterial.SHADERDEFINE_LAYER1_TEXTURE);
  		}
  		else {
  			this._defineDatas.remove(CartoonClothMaterial.SHADERDEFINE_LAYER1_TEXTURE);
  		}
  		this._shaderValues.setTexture(CartoonClothMaterial.PAINT_LAYER1_TEXTURE, value);
  	}
  	get paintLayer1TilingOffset() {
  		return this._shaderValues.getVector(CartoonClothMaterial.PAINT_LAYER1_TILINGOFFSET);
  	}
  	set paintLayer1TilingOffset(value) {
  		this._shaderValues.setVector(CartoonClothMaterial.PAINT_LAYER1_TILINGOFFSET, value);
  	}
  	get paintLayer2Texture() {
  		return this._shaderValues.getTexture(CartoonClothMaterial.PAINT_LAYER2_TEXTURE);
  	}
  	set paintLayer2Texture(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonClothMaterial.SHADERDEFINE_LAYER2_TEXTURE);
  		}
  		else {
  			this._defineDatas.remove(CartoonClothMaterial.SHADERDEFINE_LAYER2_TEXTURE);
  		}
  		this._shaderValues.setTexture(CartoonClothMaterial.PAINT_LAYER2_TEXTURE, value);
  	}
  	get paintLayer2TilingOffset() {
  		return this._shaderValues.getVector(CartoonClothMaterial.PAINT_LAYER2_TILINGOFFSET);
  	}
  	set paintLayer2TilingOffset(value) {
  		this._shaderValues.setVector(CartoonClothMaterial.PAINT_LAYER2_TILINGOFFSET, value);
  	}
  	get normalTexture() {
  		return this._shaderValues.getTexture(CartoonClothMaterial.NORMAL_TEXTURE);
  	}
  	set normalTexture(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonClothMaterial.SHADERDEFINE_NORMALTEXTURE);
  		}
  		else {
  			this._defineDatas.remove(CartoonClothMaterial.SHADERDEFINE_NORMALTEXTURE);
  		}
  		this._shaderValues.setTexture(CartoonClothMaterial.NORMAL_TEXTURE, value);
  	}
  	get normalTextureScale() {
  		return this._shaderValues.getNumber(CartoonClothMaterial.NORMAL_SCALE);
  	}
  	set normalTextureScale(value) {
  		this._shaderValues.setNumber(CartoonClothMaterial.NORMAL_SCALE, value);
  	}
  	get normalTextureTillingOffset() {
  		return this._shaderValues.getVector(CartoonClothMaterial.NORMAL_TILLING_OFFSET);
  	}
  	set normalTextureTillingOffset(value) {
  		this._shaderValues.setVector(CartoonClothMaterial.NORMAL_TILLING_OFFSET, value);
  	}
  	get detailNormalTexture() {
  		return this._shaderValues.getTexture(CartoonClothMaterial.DETAIL_NORMAL_TEXTURE);
  	}
  	set detailNormalTexture(value) {
  		if (value != null) {
  			this._defineDatas.add(CartoonClothMaterial.SHADERDEFINE_DETAIL_NORMAL_TEXTURE);
  		}
  		else {
  			this._defineDatas.remove(CartoonClothMaterial.SHADERDEFINE_DETAIL_NORMAL_TEXTURE);
  		}
  		this._shaderValues.setTexture(CartoonClothMaterial.DETAIL_NORMAL_TEXTURE, value);
  	}
  	get detailNormalTextureTillingOffset() {
  		return this._shaderValues.getVector(CartoonClothMaterial.DETAIL_NORMAL_TILLING_OFFSET);
  	}
  	set detailNormalTextureTillingOffset(value) {
  		this._shaderValues.setVector(CartoonClothMaterial.DETAIL_NORMAL_TILLING_OFFSET, value);
  	}
  	get detailNormalTextureScale() {
  		return this._shaderValues.getNumber(CartoonClothMaterial.DETAIL_NORMAL_SCALE);
  	}
  	set detailNormalTextureScale(value) {
  		this._shaderValues.setNumber(CartoonClothMaterial.DETAIL_NORMAL_SCALE, value);
  	}
  	get reflectionCube() {
  		return this._shaderValues.getTexture(CartoonClothMaterial.REFLECTION_CUBE);
  	}
  	set reflectionCube(value) {
  		if (value) {
  			this._defineDatas.add(CartoonClothMaterial.SHADERDEFINE_REFLECT_CUBE);
  		}
  		else {
  			this._defineDatas.remove(CartoonClothMaterial.SHADERDEFINE_REFLECT_CUBE);
  		}
  		this._shaderValues.setTexture(CartoonClothMaterial.REFLECTION_CUBE, value);
  	}
  	get smoothness() {
  		return this._shaderValues.getNumber(CartoonClothMaterial.SMOOTHNESS);
  	}
  	set smoothness(value) {
  		this._shaderValues.setNumber(CartoonClothMaterial.SMOOTHNESS, value);
  	}
  	get reflectionBoxCenter() {
  		return this._shaderValues.getVector3(CartoonClothMaterial.REFLECTION_BOX_CENTER);
  	}
  	set reflectionBoxCenter(value) {
  		this._shaderValues.setVector3(CartoonClothMaterial.REFLECTION_BOX_CENTER, value);
  	}
  	get reflectionBoxSize() {
  		return this._shaderValues.getVector3(CartoonClothMaterial.REFLECTION_BOX_SIZE);
  	}
  	set reflectionBoxSize(value) {
  		this._shaderValues.setVector3(CartoonClothMaterial.REFLECTION_BOX_SIZE, value);
  	}
  	get metallic() {
  		return this._shaderValues.getNumber(CartoonClothMaterial.METALLIC);
  	}
  	set metallic(value) {
  		this._shaderValues.setNumber(CartoonClothMaterial.METALLIC, value);
  	}
  	set bPickZero(value) {
  		if (value) {
  			this._defineDatas.add(CartoonClothMaterial.SHADERDEFINE_DRAWING_MASK_ZERO);
  		}
  		else {
  			this._defineDatas.remove(CartoonClothMaterial.SHADERDEFINE_DRAWING_MASK_ZERO);
  		}
  	}
  	set FadeColor(value) {
  		this._shaderValues.setVector(CartoonClothMaterial.FADE_COLOR, value);
  	}
  	set FadeFactor(value) {
  		this._shaderValues.setNumber(CartoonClothMaterial.FADE_FACTOR, value);
  	}
  	get alphaTestValue() {
  		return this._shaderValues.getNumber(Laya.Material.ALPHATESTVALUE) || 0;
  	}
  	set alphaTestValue(value) {
  		if (value == null)
  			return;
  		this._shaderValues.setNumber(Laya.Material.ALPHATESTVALUE, value);
  	}
  	get outlineWidth() {
  		return this._shaderValues.getNumber(CartoonClothMaterial.OUTLINEWIDTH);
  	}
  	set outlineWidth(value) {
  		value = Math.max(0.0, Math.min(0.05, value));
  		this._shaderValues.setNumber(CartoonClothMaterial.OUTLINEWIDTH, value);
  	}
  	get outlineColor() {
  		return this._shaderValues.getVector(CartoonClothMaterial.OUTLINECOLOR);
  	}
  	set outlineColor(value) {
  		this._shaderValues.setVector(CartoonClothMaterial.OUTLINECOLOR, value);
  	}
  	get outlineBlend() {
  		return this._shaderValues.getNumber(CartoonClothMaterial.OUTLINEBLEND);
  	}
  	set outlineBlend(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(CartoonClothMaterial.OUTLINEBLEND, value);
  	}
  	get edgeHightlightEdge0() {
  		return this._shaderValues.getNumber(CartoonClothMaterial.EDGE_HIGHTLIGHT_EDGE0);
  	}
  	set edgeHightlightEdge0(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(CartoonClothMaterial.EDGE_HIGHTLIGHT_EDGE0, value);
  	}
  	get edgeHightlightEdge1() {
  		return this._shaderValues.getNumber(CartoonClothMaterial.EDGE_HIGHTLIGHT_EDGE1);
  	}
  	set edgeHightlightEdge1(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(CartoonClothMaterial.EDGE_HIGHTLIGHT_EDGE1, value);
  	}
  	get edgeHightlightColor() {
  		return this._shaderValues.getVector(CartoonClothMaterial.EDGE_HIGHTLIGHT_COLOR);
  	}
  	set edgeHightlightColor(value) {
  		this._shaderValues.setVector(CartoonClothMaterial.EDGE_HIGHTLIGHT_COLOR, value);
  	}
  	get metaColor() {
  		return this._shaderValues.getVector(CartoonClothMaterial.META_COLOR);
  	}
  	set metaColor(value) {
  		this._shaderValues.setVector(CartoonClothMaterial.META_COLOR, value);
  	}
  	get hightlightColor() {
  		return this._shaderValues.getVector(CartoonClothMaterial.HIGHLIGHT_COLOR);
  	}
  	set hightlightColor(value) {
  		this._shaderValues.setVector(CartoonClothMaterial.HIGHLIGHT_COLOR, value);
  	}
  	get bUseGlobalLight() {
  		return this._defineDatas.has(CartoonClothMaterial.SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR);
  	}
  	set bUseGlobalLight(value) {
  		if (value) {
  			this._defineDatas.add(CartoonClothMaterial.SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR);
  		}
  		else {
  			this._defineDatas.remove(CartoonClothMaterial.SHADERDEFINE_USE_GLOBAL_LIGHT_COLOR);
  		}
  	}
  	get bUseDefaultHightLight() {
  		return this._defineDatas.has(CartoonClothMaterial.SHADERDEFINE_USE_DEFAULT_HIGHTLIGHT);
  	}
  	set bUseDefaultHightLight(value) {
  		if (value) {
  			this._defineDatas.add(CartoonClothMaterial.SHADERDEFINE_USE_DEFAULT_HIGHTLIGHT);
  		}
  		else {
  			this._defineDatas.remove(CartoonClothMaterial.SHADERDEFINE_USE_DEFAULT_HIGHTLIGHT);
  		}
  	}
  	getCanEditorParamList() {
  		return [
  			{
  				name: `renderMode`, desc: `渲染模式`, type: EditorType.option, options: [
  					{ desc: "不透明", value: 1 },
  					{ desc: "裁剪", value: 2 },
  					{ desc: "裁剪双面", value: 3 },
  					{ desc: "透明", value: 4 },
  					{ desc: "透明双面", value: 5 },
  					{ desc: "不透明双面", value: 6 },
  				],
  			},
  			{ name: `outlineWidth`, desc: `描边宽度`, type: EditorType.slider, range: [0, 0.02, 4] },
  			{ name: `outlineColor`, desc: `描边颜色`, type: EditorType.color, },
  			{ name: `outlineBlend`, desc: `描边混合`, type: EditorType.slider, range: [0, 1] },
  			{ name: `alphaTestValue`, desc: `alpha裁剪参数`, type: EditorType.slider, range: [0, 1] },
  			{ name: `paintLayer1TilingOffset`, desc: `uv平铺`, type: EditorType.vec4 },
  			{ name: `renderQueue`, desc: `renderQueue`, type: EditorType.num },
  			{ name: `albedoColor`, desc: `基础色`, type: EditorType.color },
  			{ name: `lightmap`, desc: `阴影贴图`, type: EditorType.texture2d, options: mgrMaterial.textures },
  			{ name: `shadowColor`, desc: `阴影颜色`, type: EditorType.color },
  			{ name: `brightColor`, desc: `亮部颜色`, type: EditorType.color },
  			{ name: `shadowEdge0`, desc: `阴影边缘1`, type: EditorType.slider, range: [0, 1, 4] },
  			{ name: `shadowEdge1`, desc: `阴影边缘2`, type: EditorType.slider, range: [0, 1, 4] },
  			{ name: `hightlightShininess`, desc: `高光光泽度`, type: EditorType.slider, range: [0, 100, 4] },
  			{ name: `hightlightItensity`, desc: `高光强度`, type: EditorType.slider, range: [0, 5, 4] },
  			{ name: `metaColor`, desc: `金属颜色`, type: EditorType.color },
  			{ name: `hightlightColor`, desc: `高光高光颜色`, type: EditorType.color },
  			{ name: `edgeHightlightColor`, desc: `边缘高光颜色`, type: EditorType.color },
  			{ name: `edgeHightlightEdge0`, desc: `边缘高光边界1`, type: EditorType.slider, range: [0, 1, 4] },
  			{ name: `edgeHightlightEdge1`, desc: `边缘高光边界2`, type: EditorType.slider, range: [0, 1, 4] },
  			{ name: `detailNormalTexture`, desc: `细节法线贴图`, type: EditorType.texture2d, options: mgrMaterial.textures },
  			{ name: `detailNormalTextureScale`, desc: `细节法线强度`, type: EditorType.slider, range: [0, 5] },
  		];
  	}
  }
  CartoonClothMaterial.ALBEDOCOLOR = Laya.Shader3D.propertyNameToID("u_AlbedoColor");
  CartoonClothMaterial.SHADOWCOLOR = Laya.Shader3D.propertyNameToID("u_ShadowColor");
  CartoonClothMaterial.BRIGHTCOLOR = Laya.Shader3D.propertyNameToID("u_BrightColor");
  CartoonClothMaterial.SHADOWEDGE0 = Laya.Shader3D.propertyNameToID("u_ShadowEdge0");
  CartoonClothMaterial.SHADOWEDGE1 = Laya.Shader3D.propertyNameToID("u_ShadowEdge1");
  CartoonClothMaterial.LIGHTMAP = Laya.Shader3D.propertyNameToID("u_LightMap");
  CartoonClothMaterial.LIGHTMAP_TILLING_OFFSET = Laya.Shader3D.propertyNameToID("u_LightMapTillingOffset");
  CartoonClothMaterial.HIGHLIGHT_SHININESS = Laya.Shader3D.propertyNameToID("u_HightlightShininess");
  CartoonClothMaterial.HIGHLIGHT_ITENSITY = Laya.Shader3D.propertyNameToID("u_HightlightItensity");
  CartoonClothMaterial.HIGHLIGHT_COLOR = Laya.Shader3D.propertyNameToID("u_HightlightColor");
  CartoonClothMaterial.META_COLOR = Laya.Shader3D.propertyNameToID("u_MetaColor");
  CartoonClothMaterial.EDGE_HIGHTLIGHT_EDGE0 = Laya.Shader3D.propertyNameToID("u_EdgeHightlightEdge0");
  CartoonClothMaterial.EDGE_HIGHTLIGHT_EDGE1 = Laya.Shader3D.propertyNameToID("u_EdgeHightlightEdge1");
  CartoonClothMaterial.EDGE_HIGHTLIGHT_COLOR = Laya.Shader3D.propertyNameToID("u_EdgeHightlightColor");
  CartoonClothMaterial.DIRECTIONLIGHTDIRECTION = Laya.Shader3D.propertyNameToID("u_SunLight.direction");
  CartoonClothMaterial.DIRECTIONLIGHTCOLOR = Laya.Shader3D.propertyNameToID("u_SunLight.color");
  CartoonClothMaterial.SPOT_LIGHT_COLOR = Laya.Shader3D.propertyNameToID("u_SpotLight.color");
  CartoonClothMaterial.SPOT_LIGHT_DIRECTION = Laya.Shader3D.propertyNameToID("u_SpotLight.direction");
  CartoonClothMaterial.SPOT_LIGHT_RANGE = Laya.Shader3D.propertyNameToID("u_SpotLight.range");
  CartoonClothMaterial.SPOT_LIGHT_SPOT = Laya.Shader3D.propertyNameToID("u_SpotLight.spot");
  CartoonClothMaterial.SPOT_LIGHT_POSITION = Laya.Shader3D.propertyNameToID("u_SpotLight.position");
  CartoonClothMaterial.WHOLE_ALPHA = Laya.Shader3D.propertyNameToID("u_alpha");
  CartoonClothMaterial.NORMAL_TEXTURE = Laya.Shader3D.propertyNameToID("u_NormalTexture");
  CartoonClothMaterial.NORMAL_SCALE = Laya.Shader3D.propertyNameToID("u_NormalScale");
  CartoonClothMaterial.NORMAL_TILLING_OFFSET = Laya.Shader3D.propertyNameToID("u_NormalTillingOffset");
  CartoonClothMaterial.DETAIL_NORMAL_TEXTURE = Laya.Shader3D.propertyNameToID("u_DetailNormalTexture");
  CartoonClothMaterial.DETAIL_NORMAL_TILLING_OFFSET = Laya.Shader3D.propertyNameToID("u_DetailNormalTillingOffset");
  CartoonClothMaterial.DETAIL_NORMAL_SCALE = Laya.Shader3D.propertyNameToID("u_DetailNormalScale");
  CartoonClothMaterial.REFLECTION_CUBE = Laya.Shader3D.propertyNameToID("u_reflection_cube");
  CartoonClothMaterial.SMOOTHNESS = Laya.Shader3D.propertyNameToID("u_Smoothness");
  CartoonClothMaterial.METALLIC = Laya.Shader3D.propertyNameToID("u_Metallic");
  CartoonClothMaterial.REFLECTION_BOX_CENTER = Laya.Shader3D.propertyNameToID("u_reflection_box_center");
  CartoonClothMaterial.REFLECTION_BOX_SIZE = Laya.Shader3D.propertyNameToID("u_reflection_box_size");
  CartoonClothMaterial.FADE_FACTOR = Laya.Shader3D.propertyNameToID("u_fade_factor");
  CartoonClothMaterial.FADE_COLOR = Laya.Shader3D.propertyNameToID("u_fade_color");
  CartoonClothMaterial.PROGRESS = Laya.Shader3D.propertyNameToID("u_Progress");
  CartoonClothMaterial.BURN_FACTOR = Laya.Shader3D.propertyNameToID("u_BurnFactor");
  CartoonClothMaterial.BURNTEXTURE = Laya.Shader3D.propertyNameToID("u_BurnTexture");
  CartoonClothMaterial.BRUN_TEXTURE_TILLING_OFFSET = Laya.Shader3D.propertyNameToID("u_BurnTextureTillingOffset");
  CartoonClothMaterial.CUT_TEXTURE = Laya.Shader3D.propertyNameToID("u_CutTexture");
  CartoonClothMaterial.TIP_TEXTURE = Laya.Shader3D.propertyNameToID("u_TipTexture");
  CartoonClothMaterial.PAINT_LAYER1_TEXTURE = Laya.Shader3D.propertyNameToID("u_PaintLayer1Texture");
  CartoonClothMaterial.PAINT_LAYER1_TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_PaintLayer1TilingOffset");
  CartoonClothMaterial.PAINT_LAYER2_TEXTURE = Laya.Shader3D.propertyNameToID("u_PaintLayer2Texture");
  CartoonClothMaterial.PAINT_LAYER2_TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_PaintLayer2TilingOffset");
  CartoonClothMaterial.OUTLINEWIDTH = Laya.Shader3D.propertyNameToID("u_OutlineWidth");
  CartoonClothMaterial.OUTLINEBLEND = Laya.Shader3D.propertyNameToID("u_OutlineBlend");
  CartoonClothMaterial.OUTLINECOLOR = Laya.Shader3D.propertyNameToID("u_OutlineColor");
  CartoonClothMaterial.CULL = Laya.Shader3D.propertyNameToID("s_Cull");
  CartoonClothMaterial.BLEND = Laya.Shader3D.propertyNameToID("s_Blend");
  CartoonClothMaterial.BLEND_SRC = Laya.Shader3D.propertyNameToID("s_BlendSrc");
  CartoonClothMaterial.BLEND_DST = Laya.Shader3D.propertyNameToID("s_BlendDst");
  CartoonClothMaterial.DEPTH_TEST = Laya.Shader3D.propertyNameToID("s_DepthTest");
  CartoonClothMaterial.DEPTH_WRITE = Laya.Shader3D.propertyNameToID("s_DepthWrite");
  CartoonClothMaterial.RENDERMODE_OPAQUE = 1;
  CartoonClothMaterial.RENDERMODE_CUTOUT = 2;
  CartoonClothMaterial.RENDERMODE_CUTOUT_CULL_NONE = 3;
  CartoonClothMaterial.RENDERMODE_TRANSPARENT = 4;
  CartoonClothMaterial.RENDERMODE_TRANSPARENT_CULL_NONE = 5;
  CartoonClothMaterial.RENDERMODE_OPAQUE_CULL_NONE = 6;

  class SkinMaterial extends Laya.PBRMaterial {
  	constructor() {
  		super();
  		this.setShaderName("SkinShader");
  		this._shaderValues.setVector(SkinMaterial.SHADOWCOLOR, new Laya.Vector4(0.6663285, 0.6544118, 1, 1));
  		this._shaderValues.setNumber(SkinMaterial.SHADOWRANGE, 0.002);
  		this._shaderValues.setNumber(SkinMaterial.SHADOWINTENSITY, 0.98);
  		this._shaderValues.setNumber(SkinMaterial.SHADOWBOUNDARY, 0.015);
  		this._shaderValues.setNumber(SkinMaterial.SPECULARRANGE, 0.99);
  		this._shaderValues.setNumber(SkinMaterial.SPECULARINTENSITY, 1.0);
  		this._shaderValues.setVector(SkinMaterial.SPECULARCOLOR, new Laya.Vector4(1.0, 1.0, 1.0, 1.0));
  		this._shaderValues.setNumber(SkinMaterial.OUTLINEWIDTH, 0.001);
  		this._shaderValues.setNumber(SkinMaterial.OUTLINELIGHTNESS, 0.25);
  		this._shaderValues.setVector(SkinMaterial.OUTLINECOLOR, new Laya.Vector4(1.0, 1.0, 1.0, 1.0));
  		this._shaderValues.setVector(SkinMaterial.ALBEDOCOLOR, new Laya.Vector4(1.0, 1.0, 1.0, 1.0));
  		this._shaderValues.setVector(SkinMaterial.SECOND_SHADOWCOLOR, new Laya.Vector4(1, 1, 1, 1));
  		this._shaderValues.setNumber(SkinMaterial.SECOND_SHADOWRANGE, 0.00);
  		this._shaderValues.setNumber(SkinMaterial.SECOND_SHADOWINTENSITY, 0.98);
  		this._shaderValues.setNumber(SkinMaterial.SECOND_SHADOWBOUNDARY, 0.0);
  		this._shaderValues.setVector(SkinMaterial.EDGE_HIGHLIGHT_COLOR, new Laya.Vector4(0, 1, 0, 1));
  		this._shaderValues.setNumber(SkinMaterial.EDGE_HIGHLIGHT_RANGE, 0.00);
  		this._shaderValues.setNumber(SkinMaterial.EDGE_HIGHLIGHT_INTENSITY, 0.98);
  		this._shaderValues.setNumber(SkinMaterial.EDGE_HIGHLIGHT_BOUNDARY, 0.0);
  		this._shaderValues.setNumber(SkinMaterial.RANDOM_DISCARD_FACTOR, 1.0);
  		this._shaderValues.setNumber(SkinMaterial.SPOCCLUSIONSTRENGTH, 0.25);
  		this._shaderValues.setNumber(SkinMaterial.SPMETALLIC, 0.0);
  		this._shaderValues.setNumber(SkinMaterial.SPSMOOTHNESS, 1.13);
  		this._shaderValues.setNumber(SkinMaterial.SPMETALLIC2, 0.0);
  		this._shaderValues.setNumber(SkinMaterial.SPSMOOTHNESS2, 0.0);
  		this._shaderValues.setNumber(SkinMaterial.SPNOISEBUMP, 1.2);
  		this._shaderValues.setNumber(SkinMaterial.SPNOISEBUMPTILING, 8.0);
  		this._shaderValues.setNumber(SkinMaterial.SPNOISEBUMPBASICAO, 2.0);
  		this._shaderValues.setNumber(SkinMaterial.SPSHADOWATTEN, 1.0);
  		this._shaderValues.setVector(SkinMaterial.SPEMISSIONCOLORBACK, new Laya.Vector4(0.65, 0.53, 0.53, 1.0));
  		this._shaderValues.setNumber(SkinMaterial.SPEMISSIONCOLORBACKINTENSITY, 0.5);
  		this._shaderValues.setNumber(SkinMaterial.SPBORDEROFFSETAO, -0.43);
  		this._shaderValues.setNumber(SkinMaterial.SPEMISSIONCOLORBACKINTENSITY2, 1.0);
  		this._shaderValues.setNumber(SkinMaterial.SPREDTRANSLUCENCY, 5.0);
  		this._shaderValues.setNumber(SkinMaterial.SPREDTRANSSHADOW, 0.496);
  		this._shaderValues.setNumber(SkinMaterial.SPREDTRANSNORMALDISTORTION, 0.273);
  		this._shaderValues.setNumber(SkinMaterial.SPREDTRANSSCATTERING, 2.2);
  		this._shaderValues.setNumber(SkinMaterial.SPREDTRANSDIRECT, 0.651);
  		this._shaderValues.setNumber(SkinMaterial.SPREDTRANSAMBIENT, 0.715);
  		this._shaderValues.setNumber(SkinMaterial.SPRED3SOFFSET, 0.41);
  		this._shaderValues.setVector(SkinMaterial.SPRED3SCOLOR, new Laya.Vector4(1.0, 0.0, 0.0, 1.0));
  		this._shaderValues.setVector(SkinMaterial.CUSTOMDIRECTLIGHTCOLOR, new Laya.Vector4(0.5, 0.5, 0.5, 1.0));
  		this._shaderValues.setNumber(SkinMaterial.NORMALTEXTURESCALE, 1.0);
  		this._shaderValues.setNumber(SkinMaterial.LIGHTRESULTINTENSITY, 1.0);
  		this._shaderValues.setNumber(SkinMaterial.GRIDTEXTURESCALE, 1.0);
  		this._shaderValues.setNumber(SkinMaterial.SHINETEXTURESCALE, 1.0);
  		this._shaderValues.setNumber(SkinMaterial.ALPHATESTVALUE, 0.0);
  		this._shaderValues.setNumber(SkinMaterial.ALBEDOTILLINGX, 1.0);
  		this._shaderValues.setNumber(SkinMaterial.ALBEDOTILLINGY, 1.0);
  		this._shaderValues.setNumber(SkinMaterial.CUSTOMCOLORSECTIONSTEP, 0.01);
  		this._shaderValues.setNumber(SkinMaterial.GRIDTEXTUREISMULTIPLY, 0.0);
  		this._shaderValues.setNumber(SkinMaterial.SHINETEXTUREISMULTIPLY, 0.0);
  	}
  	static __init__() {
  		SkinMaterial.SHADERDEFINE_ALBEDOTEXTURE = Laya.Shader3D.getDefineByName("ALBEDOTEXTURE");
  		SkinMaterial.SHADERDEFINE_NORMALTEXTURE = Laya.Shader3D.getDefineByName("NORMALTEXTURE");
  		SkinMaterial.SHADERDEFINE_MASKTEXTURE = Laya.Shader3D.getDefineByName("MASKTEXTURE");
  		SkinMaterial.SHADERDEFINE_MASKDETAILTEXTURE = Laya.Shader3D.getDefineByName("MASKDETAILTEXTURE");
  		SkinMaterial.SHADERDEFINE_RAMPMAPTEXTURE = Laya.Shader3D.getDefineByName("RAMPMAPTEXTURE");
  		SkinMaterial.SHADERDEFINE_TILINGOFFSET = Laya.Shader3D.getDefineByName("TILINGOFFSET");
  		SkinMaterial.SHADERDEFINE_BONE = Laya.Shader3D.getDefineByName("BONE");
  		SkinMaterial.SHADERDEFINE_GRIDTEXTURE = Laya.Shader3D.getDefineByName("GRIDTEXTURE");
  		SkinMaterial.SHADERDEFINE_SHINETEXTURE = Laya.Shader3D.getDefineByName("SHINETEXTURE");
  		SkinMaterial.SHADERDEFINE_CONTROLDETAILTEXTURE = Laya.Shader3D.getDefineByName("CONTROLDETAILTEXTURE");
  		SkinMaterial.SHADERDEFINE_DRAWING_MASK = Laya.Shader3D.getDefineByName("SHADERDEFINE_DRAWING_MASK");
  		SkinMaterial.SHADERDEFINE_LAYER1_TEXTURE = Laya.Shader3D.getDefineByName("LAYER1_TEXTURE");
  		SkinMaterial.SHADERDEFINE_CUSTOMCREAMCOLORTEXTURE = Laya.Shader3D.getDefineByName("CUSTOMCREAMCOLORTEXTURE");
  	}
  	static initShader() {
  		SkinMaterial.__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_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_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_SPMetallic2': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_SPSmoothness2': 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_SPEmissionColorBackIntensity2': 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_CustomDirectLightColor': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_LightResultIntensity': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_AlbedoTillingX': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_AlbedoTillingY': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_specularIntensity': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_gridTexture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_shineTexture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_gridTextureScale': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_shineTextureScale': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_gridTextureIsMultiply': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_shineTextureIsMultiply': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_controlDetailTexture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_PlayerCustomChangeFlag': 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_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,
  			'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_CustomColorSectionStep': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_CustomCreamColorTexture': Laya.Shader3D.PERIOD_MATERIAL,
  			'u_FarPlaneWorldPositionZ': 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 vec3 v_Position;
        // 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_Position = position.xyz;
            v_PositionWorld=(worldMat*position).xyz;

            v_Texcoord0=a_Texcoord0;
            // #ifdef TILINGOFFSE
                // v_Texcoord0=TransformUV(a_Texcoord0,u_TilingOffset);
            // #else
                // v_Texcoord0=a_Texcoord0;
            // #endif
// 
            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

        }
        
        void main()
        {
            vertexForward();
            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;
        varying vec3 v_PositionWorld;
        varying vec3 v_Position;

        #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;

        uniform float u_FarPlaneWorldPositionZ;

        vec4 albedoRgba;

        #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
	    uniform vec4 u_CustomDirectLightColor;

        uniform float u_LightResultIntensity;
        uniform float u_specularIntensity;
        uniform float u_AlbedoTillingX;
        uniform float u_AlbedoTillingY;
        #ifdef GRIDTEXTURE
            uniform sampler2D u_gridTexture;
            uniform float u_gridTextureScale;
            uniform float u_gridTextureIsMultiply;
        #endif
        #ifdef SHINETEXTURE
            uniform sampler2D u_shineTexture;
            uniform float u_shineTextureScale;
            uniform float u_shineTextureIsMultiply;
        #endif

        vec4 controlDetailColor;
        #ifdef CONTROLDETAILTEXTURE
            uniform sampler2D u_controlDetailTexture;
            
            uniform float u_SPMetallic2;
            uniform float u_SPSmoothness2;
            uniform float u_SPEmissionColorBackIntensity2;
        #endif

        uniform sampler2D u_PaintLayer1Texture;
		uniform vec4 u_PaintLayer1TilingOffset;
        // #ifdef MODELPROGRESSDATA
        //     uniform vec4 u_ModelProgressData;
        // #endif
        #ifdef CUSTOMCREAMCOLORTEXTURE 
            // uniform float u_CustomColorSection[288];
            uniform float u_CustomColorSectionStep;
            uniform sampler2D u_CustomCreamColorTexture;
        #endif

        mediump float lerpOneTo(mediump float b, mediump float t)
        {
            mediump float oneMinusT = 1.0 - t;
            return oneMinusT + b * t;
        }

        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 vec4 albedo(vec2 uv)
        {
            #ifdef ALBEDOTEXTURE
                return u_AlbedoColor * albedoTextureColor;
            #else
                return u_AlbedoColor;
            #endif
            
        }
        mediump vec2 getMetallicGloss(vec2 uv,float customMetallic,float customSmoothness)
        {
            mediump vec2 ms;//x is metallic,y is smoothness
            //lhcadd
            
            #ifdef MASKTEXTURE
                //vec4 maskRgb = texture2D(u_MaskTexture, uv);
                ms.y =maskTextureColor.r*customSmoothness;

                ms.x =maskTextureColor.g*customMetallic;;//ms.x =maskTextureColor.g*customMetallic;
            #else 
                ms.y = customSmoothness;

                ms.x =customMetallic;//0.7639677;//0.7639677/2.0;
            #endif
            
            return ms;
        }

        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;
        }
        
        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;
            }
        }
        
        #ifdef NORMALTEXTURE
            
            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 );
                    float lerpRatio =  clamp( ( _NoiseBump * ( 1.0 - ( maskTextureColor.g * u_SPNoiseBumpBasicAO ) ) ) ,0.0,1.0);
                    vec3 lerpResult94 = lerpVec3( color93 , tex2DNode60.rgb ,lerpRatio);
                    vec3 appendResult78 = (vec3(( normalTangent.r + lerpResult94.r ) , ( lerpResult94.g + normalTangent.g ) , ( normalTangent.b + tex2DNode60.b )));
                    vec3 normalizeResult85 = normalize( ( 2.0 * appendResult78 ) + u_SPBorderOffsetAO );
                   
                    normalTangent = normalizeResult85;
                
                #endif
                
                
                return normalTangent;
            }
        #endif

        struct FragmentCommonData{
            vec3 diffColor;
            vec3 specColor;
            float oneMinusReflectivity;
            float smoothness;
        };
        
        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,float customMetallic,float customSmoothness)
        {
            mediump vec2 metallicGloss = getMetallicGloss(uv,customMetallic,customSmoothness);
            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(albedoRgba.rgb, 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 main_paint_mask(){
			gl_FragColor = vec4(v_Texcoord0.xy,0.0,1.0);
        }

        void fragmentForward()
        {
            vec2 uv;
            // #if defined(ALBEDOTEXTURE)||defined(METALLICGLOSSTEXTURE)||defined(NORMALTEXTURE)||defined(EMISSIONTEXTURE)||defined(OCCLUSIONTEXTURE)||defined(PARALLAXTEXTURE)
                uv=TransformUV(v_Texcoord0,vec4(u_AlbedoTillingX,u_AlbedoTillingY,0.0,0.0));
            // #endif

            #ifdef ALBEDOTEXTURE
                albedoTextureColor = texture2D(u_AlbedoTexture,uv);
            #endif
            
            albedoRgba = albedo(uv);
            // mediump float alpha = getAlpha(uv);
            #ifdef ALPHATEST
                if(albedoRgba.a<u_AlphaTestValue)
                    discard;
            #endif

            #ifdef FARPLANEWORLDPOSITIONZ
                if(v_PositionWorld.z < u_FarPlaneWorldPositionZ){
                    discard;
                }
            #endif
            // if(v_PositionWorld.z < -10.0){
            //     discard;
            // }

            #ifdef MASKTEXTURE
                maskTextureColor = texture2D(u_MaskTexture,uv);
            #endif

            vec3 lightDir = normalize(u_SunLight.direction);
            
            vec3 binormal;
            vec3 tangent;
            vec3 normal = v_Normal;
            vec3 normalTangent;

            #ifdef NORMALTEXTURE
                tangent = v_Tangent;
                binormal = v_Binormal;
           
                normalTangent=normalInTangentSpace(uv);
            #else
                normalTangent = normalize(normal);
            #endif

            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);
            vec4 color = vec4(0.0);
           
            #ifdef CUSTOMCREAMCOLORTEXTURE

                vec2 texcoordCreamColor = vec2(0.5,1.0-uv.y);
                // vec2 texcoordCreamColor = vec2(mod(colorIndex, 64.0)/64.0, floor(colorIndex / 64.0)/64.0);
                // vec2 texcoordCreamColor = TransformUV(texcoordCreamColor0, vec4(1.0,1.0,0.0,0.0));
                vec4 creamColor = texture2D(u_CustomCreamColorTexture, texcoordCreamColor);

                float flag = step(0.01,creamColor.a);
                vec3 tmpColor = (creamColor.rgb) * flag;
                
                albedoRgba.rgb = tmpColor.rgb + step(1.0,1.0-flag)*albedoRgba.rgb;

            #endif
            #ifdef LAYER1_TEXTURE
                vec2 texcoordL1 = TransformUV(uv, u_PaintLayer1TilingOffset);
                vec4 paintLayer1Color = texture2D(u_PaintLayer1Texture, texcoordL1);

                albedoRgba.rgb = albedoRgba.rgb * (1.0 - paintLayer1Color.a) + paintLayer1Color.rgb;
				albedoRgba.a = albedoRgba.a * (1.0 - paintLayer1Color.a) + paintLayer1Color.a;

            #endif

            #ifdef CONTROLDETAILTEXTURE
            
                controlDetailColor =texture2D(u_controlDetailTexture, uv);

                #ifdef GRIDTEXTURE
                    vec2 tmpCoord1=TransformUV(uv,vec4(u_gridTextureScale,u_gridTextureScale,0.0,0.0));
                   
                    vec4 gridColor =texture2D(u_gridTexture, tmpCoord1);
                    gridColor = gridColor * controlDetailColor.b;

                    // albedoRgba.rgb = albedoRgba.rgb * (1.0 - gridColor.a) + gridColor.rgb;
                    // albedoRgba.a = albedoRgba.a * (1.0 - gridColor.a) + gridColor.a * gridColor.a;

                    float flagGridTexture = step(0.5,u_gridTextureIsMultiply);

                    //vec4 multiplyGridRgba = (albedoRgba+gridColor)*flagGridTexture;

                    vec4 ifflagGrid = vec4( step(albedoRgba.r,0.5),step(albedoRgba.g,0.5),step(albedoRgba.b,0.5),step(albedoRgba.a,0.5) );
                    vec4 multiplyGridRgba = (ifflagGrid*albedoRgba*gridColor*2.0+(vec4(1.0,1.0,1.0,1.0)-ifflagGrid)*(vec4(1.0,1.0,1.0,1.0)-(vec4(1.0,1.0,1.0,1.0)-albedoRgba)*(vec4(1.0,1.0,1.0,1.0)-gridColor)*2.0))*flagGridTexture;
                    
                    vec4 commonGridRgba = vec4(0.0);
                    commonGridRgba.rgb = albedoRgba.rgb * (1.0 - gridColor.a) + gridColor.rgb;
                    commonGridRgba.a = albedoRgba.a * (1.0 - gridColor.a) + gridColor.a * gridColor.a;
                    commonGridRgba = commonGridRgba * (1.0-flagGridTexture);

                    albedoRgba = commonGridRgba + multiplyGridRgba;

                #endif

                #ifdef SHINETEXTURE
                    vec2 tmpCoord2=TransformUV(uv,vec4(u_shineTextureScale,u_shineTextureScale,0.0,0.0));
                    vec4 shineColor =texture2D(u_shineTexture, tmpCoord2);
                    
                    float nl = max(dot(normal, -lightDir), 0.0);
                    float shadow_boundary = 0.2 + 0.01;
                    float shadow_allin = step(nl, 0.3 - shadow_boundary*0.5);
                    float shadow_partin = step(nl, 0.3 + shadow_boundary*0.5);
                    float shadow = shadow_allin + (0.3 + shadow_boundary*0.5 - nl)/shadow_boundary * (shadow_partin - shadow_allin);

                    shadow *= 0.1;
                    
                    float specular = pow(nl,10.0);
                    vec3 speculAreaColor = (1.0 - shadow) * shineColor.rgb * 1.0 * specular * vec4(1.0,1.0,1.0,1.0).rgb ;

                    shineColor.rgb +=speculAreaColor;

                    shineColor = shineColor * controlDetailColor.g;

                    // albedoRgba.rgb = albedoRgba.rgb * (1.0 - shineColor.a) + shineColor.rgb;
                    // albedoRgba.a = albedoRgba.a * (1.0 - shineColor.a) + shineColor.a * shineColor.a;

                    float flagShineTexture = step(0.5,u_shineTextureIsMultiply);

                    // vec4 multiplyShineRgba = (albedoRgba+shineColor)*flagShineTexture;
                    vec4 ifflagShine = vec4( step(albedoRgba.r,0.5),step(albedoRgba.g,0.5),step(albedoRgba.b,0.5),step(albedoRgba.a,0.5) );
                    vec4 multiplyShineRgba = (ifflagShine*albedoRgba*shineColor*2.0+(vec4(1.0,1.0,1.0,1.0)-ifflagShine)*(vec4(1.0,1.0,1.0,1.0)-(vec4(1.0,1.0,1.0,1.0)-albedoRgba)*(vec4(1.0,1.0,1.0,1.0)-shineColor)*2.0))*flagShineTexture;
                    

                    vec4 commonShineRgba = vec4(0.0);
                    commonShineRgba.rgb = albedoRgba.rgb * (1.0 - shineColor.a) + shineColor.rgb;
                    commonShineRgba.a = albedoRgba.a * (1.0 - shineColor.a) + shineColor.a * shineColor.a;
                    commonShineRgba = commonShineRgba * (1.0-flagShineTexture);

                    albedoRgba = commonShineRgba + multiplyShineRgba;
                    
                #endif

                
            #endif


            if(controlDetailColor.r>0.0){
                #ifdef CONTROLDETAILTEXTURE
                    float _AnisoOffset = -u_SPMetallic2;
                    float Specular=u_SPSmoothness2;
                    
                    float HdotA = dot(normalize(normal), -lightDir);
                    float aniso = max(0.0, sin(radians((HdotA + _AnisoOffset) * 180.0)));
                    float spec = min(max(pow(aniso, 128.0) * Specular,0.0),1.0);
                    color.rgb = albedoRgba.rgb * u_SPEmissionColorBackIntensity2 + spec ;
                #endif
            }else{
                FragmentCommonData o = metallicSetup(uv,u_SPMetallic,u_SPSmoothness);
            
                #ifdef TRANSPARENTBLEND
                    o.diffColor=preMultiplyAlpha(o.diffColor,albedoRgba.a,o.oneMinusReflectivity,/*out*/albedoRgba.a);// 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);
                color = LAYA_BRDF_GI(o.diffColor,o.specColor,o.oneMinusReflectivity,o.smoothness,perceptualRoughness,roughness,nv,normalWorld,eyeVec,gi);
                
    
                o.specColor*=u_specularIntensity;
    
                vec4 lightResultColor = vec4(0.0,0.0,0.0,0.0);
    
                // #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);
                //         dirLight.color = u_CustomDirectLightColor.rgb;
                //         lightResultColor+=LAYA_BRDF_LIGHT(o.diffColor,o.specColor,o.oneMinusReflectivity,perceptualRoughness,roughness,nv,normalWorld,eyeVec,dirLight);
        
                //     #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*u_SPShadowAtten);
                        //     if(i==0){
                        //         dirLight.color = u_CustomDirectLightColor.rgb;
                        //     }
                        //     lightResultColor+=LAYA_BRDF_LIGHT(o.diffColor,o.specColor,o.oneMinusReflectivity,perceptualRoughness,roughness,nv,normalWorld,eyeVec,dirLight);
        
                        // }
                        DirectionLight directionLight;
                        directionLight.color = u_SunLight.color;
                        directionLight.direction = u_SunLight.direction;

                        LayaLight dirLight = layaDirectionLightToLight(directionLight,u_SPShadowAtten);
                        dirLight.color = u_CustomDirectLightColor.rgb;
                        lightResultColor+=LAYA_BRDF_LIGHT(o.diffColor,o.specColor,o.oneMinusReflectivity,perceptualRoughness,roughness,nv,normalWorld,eyeVec,dirLight);
                //     #endif
                // #endif
                    
                color += vec4( max(lightResultColor.r,albedoRgba.r*u_LightResultIntensity),max(lightResultColor.g,albedoRgba.g*u_LightResultIntensity),max(lightResultColor.b,albedoRgba.b*u_LightResultIntensity),lightResultColor.a );
            
                vec3 emissionColorBack = u_SPEmissionColorBack.rgb;
                
                float emissionClampRatio = u_SPEmissionColorBackIntensity;
                vec3 emissionColorResult = ( ( 1.0 - emissionClampRatio ) * albedoRgba.rgb * emissionColorBack ).rgb;
                color.rgb += emissionColorResult;
                
                #if defined(RAMPMAPTEXTURE)//&&defined(MASKTEXTURE)
                    
                    vec3 lightColor=vec3(0.0, 0.0, 0.0);
                    
                    vec3 emissionWorldNormal = perPixelWorldNormalByNormalTanget(uv,normal,binormal,tangent,vec3( 0.0, 0.0, 1.0 ));
                    float dotResult32 = dot( lightDir , emissionWorldNormal );//lightDir
                    float tempOutValue = clamp( (dotResult32*u_SPRed3SOffset + 0.5),0.0,1.0 );
                    
                    vec2 tempCastUv = vec2(tempOutValue,tempOutValue);
    
                    vec4 tex2dNodeRamp = texture2D(u_RampMapTexture, tempCastUv);
    
                    vec4 customTranslucencyBasicColor = 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(albedoRgba.rgb * translucency * u_SPRedTranslucency,0.0);
                    color+=c;
                #endif
            }


            
            // #ifdef MODELPROGRESSDATA

            //     // u_ModelProgressData
            //     float progress = u_ModelProgressData.x;
            //     // float startValue = u_ModelProgressData.y;
            //     // float endValue = u_ModelProgressData.z;
            //     // float pType = u_ModelProgressData.w;

            //     // if(v_PositionWorld.y>progress){

            //         float flag = step(progress,v_PositionWorld.y);
            //         color.rgb = vec3(0.6,0.31,0.82) * flag + color.rgb*(1.0-flag);
            //     // }
            // #endif

            gl_FragColor=vec4(color.rgb,albedoRgba.a);
        }

        void main()
        {
            #ifdef SHADERDEFINE_DRAWING_MASK
				main_paint_mask();
			#else
                fragmentForward();
            #endif
        }`;
  		var shader3D = Laya.Shader3D.add("SkinShader", attributeMap, uniformMap, true);
  		var subShader = new Laya.SubShader(attributeMap, uniformMap);
  		shader3D.addSubShader(subShader);
  		subShader.addShaderPass(vs1, ps1, stateMap, "Forward");
  	}
  	get albedoTexture() {
  		return this._shaderValues.getTexture(SkinMaterial.ALBEDOTEXTURE);
  	}
  	set albedoTexture(value) {
  		if (value)
  			this._defineDatas.add(SkinMaterial.SHADERDEFINE_ALBEDOTEXTURE);
  		else
  			this._defineDatas.remove(SkinMaterial.SHADERDEFINE_ALBEDOTEXTURE);
  		this._shaderValues.setTexture(SkinMaterial.ALBEDOTEXTURE, value);
  	}
  	get normalTextureScale() {
  		return this._shaderValues.getNumber(SkinMaterial.NORMALTEXTURESCALE);
  	}
  	set normalTextureScale(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.NORMALTEXTURESCALE, value);
  		this._shaderValues.setNumber(SkinMaterial.NORMALTEXTURESCALE, value);
  	}
  	get maskTexture() {
  		return this._shaderValues.getTexture(SkinMaterial.MASKTEXTURE);
  	}
  	set maskTexture(value) {
  		if (value)
  			this._defineDatas.add(SkinMaterial.SHADERDEFINE_MASKTEXTURE);
  		else
  			this._defineDatas.remove(SkinMaterial.SHADERDEFINE_MASKTEXTURE);
  		this._shaderValues.setTexture(SkinMaterial.MASKTEXTURE, value);
  	}
  	get maskDetailTexture() {
  		return this._shaderValues.getTexture(SkinMaterial.MASKDETAILTEXTURE);
  	}
  	set maskDetailTexture(value) {
  		if (value)
  			this._defineDatas.add(SkinMaterial.SHADERDEFINE_MASKDETAILTEXTURE);
  		else
  			this._defineDatas.remove(SkinMaterial.SHADERDEFINE_MASKDETAILTEXTURE);
  		this._shaderValues.setTexture(SkinMaterial.MASKDETAILTEXTURE, value);
  	}
  	get rampMapTexture() {
  		return this._shaderValues.getTexture(SkinMaterial.RAMPMAPTEXTURE);
  	}
  	set rampMapTexture(value) {
  		if (value)
  			this._defineDatas.add(SkinMaterial.SHADERDEFINE_RAMPMAPTEXTURE);
  		else
  			this._defineDatas.remove(SkinMaterial.SHADERDEFINE_RAMPMAPTEXTURE);
  		this._shaderValues.setTexture(SkinMaterial.RAMPMAPTEXTURE, value);
  	}
  	get gridTexture() {
  		return this._shaderValues.getTexture(SkinMaterial.GRIDTEXTURE);
  	}
  	set gridTexture(value) {
  		if (value)
  			this._defineDatas.add(SkinMaterial.SHADERDEFINE_GRIDTEXTURE);
  		else
  			this._defineDatas.remove(SkinMaterial.SHADERDEFINE_GRIDTEXTURE);
  		this._shaderValues.setTexture(SkinMaterial.GRIDTEXTURE, value);
  	}
  	get shineTexture() {
  		return this._shaderValues.getTexture(SkinMaterial.SHINETEXTURE);
  	}
  	set shineTexture(value) {
  		if (value)
  			this._defineDatas.add(SkinMaterial.SHADERDEFINE_SHINETEXTURE);
  		else
  			this._defineDatas.remove(SkinMaterial.SHADERDEFINE_SHINETEXTURE);
  		this._shaderValues.setTexture(SkinMaterial.SHINETEXTURE, value);
  	}
  	get gridTextureScale() {
  		return this._shaderValues.getNumber(SkinMaterial.GRIDTEXTURESCALE);
  	}
  	set gridTextureScale(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.GRIDTEXTURESCALE, value);
  		this._shaderValues.setNumber(SkinMaterial.GRIDTEXTURESCALE, value);
  	}
  	get shineTextureScale() {
  		return this._shaderValues.getNumber(SkinMaterial.SHINETEXTURESCALE);
  	}
  	set shineTextureScale(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SHINETEXTURESCALE, value);
  		this._shaderValues.setNumber(SkinMaterial.SHINETEXTURESCALE, value);
  	}
  	get gridTextureIsMultiply() {
  		return this._shaderValues.getNumber(SkinMaterial.GRIDTEXTUREISMULTIPLY);
  	}
  	set gridTextureIsMultiply(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.GRIDTEXTUREISMULTIPLY, value);
  		this._shaderValues.setNumber(SkinMaterial.GRIDTEXTUREISMULTIPLY, value);
  	}
  	get shineTextureIsMultiply() {
  		return this._shaderValues.getNumber(SkinMaterial.SHINETEXTUREISMULTIPLY);
  	}
  	set shineTextureIsMultiply(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SHINETEXTUREISMULTIPLY, value);
  		this._shaderValues.setNumber(SkinMaterial.SHINETEXTUREISMULTIPLY, value);
  	}
  	get controlDetailTexture() {
  		return this._shaderValues.getTexture(SkinMaterial.CONTROLDETAILTEXTURE);
  	}
  	set controlDetailTexture(value) {
  		if (value)
  			this._defineDatas.add(SkinMaterial.SHADERDEFINE_CONTROLDETAILTEXTURE);
  		else
  			this._defineDatas.remove(SkinMaterial.SHADERDEFINE_CONTROLDETAILTEXTURE);
  		this._shaderValues.setTexture(SkinMaterial.CONTROLDETAILTEXTURE, value);
  	}
  	get shadowColor() {
  		return this._shaderValues.getVector(SkinMaterial.SHADOWCOLOR);
  	}
  	set shadowColor(value) {
  		this._shaderValues.setVector(SkinMaterial.SHADOWCOLOR, value);
  	}
  	get shadowRange() {
  		return this._shaderValues.getNumber(SkinMaterial.SHADOWRANGE);
  	}
  	set shadowRange(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(SkinMaterial.SHADOWRANGE, value);
  	}
  	get shadowIntensity() {
  		return this._shaderValues.getNumber(SkinMaterial.SHADOWINTENSITY);
  	}
  	set shadowIntensity(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(SkinMaterial.SHADOWINTENSITY, value);
  	}
  	get shadowBoundary() {
  		return this._shaderValues.getNumber(SkinMaterial.SHADOWBOUNDARY);
  	}
  	set shadowBoundary(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(SkinMaterial.SHADOWBOUNDARY, value);
  	}
  	get specularRange() {
  		return this._shaderValues.getNumber(SkinMaterial.SPECULARRANGE);
  	}
  	set specularRange(value) {
  		value = Math.max(0.9, Math.min(1.0, value));
  		this._shaderValues.setNumber(SkinMaterial.SPECULARRANGE, value);
  	}
  	set specularIntensity(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(SkinMaterial.SPECULARINTENSITY, value);
  	}
  	get specularIntensity() {
  		return this._shaderValues.getNumber(SkinMaterial.SPECULARINTENSITY);
  	}
  	get specularColor() {
  		return this._shaderValues.getVector(SkinMaterial.SPECULARCOLOR);
  	}
  	set specularColor(value) {
  		this._shaderValues.setVector(SkinMaterial.SPECULARCOLOR, value);
  	}
  	get outlineWidth() {
  		return this._shaderValues.getNumber(SkinMaterial.OUTLINEWIDTH);
  	}
  	set outlineWidth(value) {
  		value = Math.max(0.0, Math.min(0.05, value));
  		this._shaderValues.setNumber(SkinMaterial.OUTLINEWIDTH, value);
  	}
  	get outlineColor() {
  		return this._shaderValues.getVector(SkinMaterial.OUTLINECOLOR);
  	}
  	set outlineColor(value) {
  		this._shaderValues.setVector(SkinMaterial.OUTLINECOLOR, value);
  	}
  	get outlineLightness() {
  		return this._shaderValues.getNumber(SkinMaterial.OUTLINELIGHTNESS);
  	}
  	set outlineLightness(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(SkinMaterial.OUTLINELIGHTNESS, value);
  	}
  	get secondShadowColor() {
  		return this._shaderValues.getVector(SkinMaterial.SECOND_SHADOWCOLOR);
  	}
  	set secondShadowColor(value) {
  		this._shaderValues.setVector(SkinMaterial.SECOND_SHADOWCOLOR, value);
  	}
  	get secondShadowRange() {
  		return this._shaderValues.getNumber(SkinMaterial.SECOND_SHADOWRANGE);
  	}
  	set secondShadowRange(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(SkinMaterial.SECOND_SHADOWRANGE, value);
  	}
  	get secondShadowIntensity() {
  		return this._shaderValues.getNumber(SkinMaterial.SECOND_SHADOWINTENSITY);
  	}
  	set secondShadowIntensity(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(SkinMaterial.SECOND_SHADOWINTENSITY, value);
  	}
  	get secondShadowBoundary() {
  		return this._shaderValues.getNumber(SkinMaterial.SECOND_SHADOWBOUNDARY);
  	}
  	set secondShadowBoundary(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(SkinMaterial.SECOND_SHADOWBOUNDARY, value);
  	}
  	get EdgeHightColor() {
  		return this._shaderValues.getVector(SkinMaterial.EDGE_HIGHLIGHT_COLOR);
  	}
  	set EdgeHightColor(value) {
  		this._shaderValues.setVector(SkinMaterial.EDGE_HIGHLIGHT_COLOR, value);
  	}
  	get EdgeHightRange() {
  		return this._shaderValues.getNumber(SkinMaterial.EDGE_HIGHLIGHT_RANGE);
  	}
  	set EdgeHightRange(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(SkinMaterial.EDGE_HIGHLIGHT_RANGE, value);
  	}
  	get EdgeHightIntensity() {
  		return this._shaderValues.getNumber(SkinMaterial.EDGE_HIGHLIGHT_INTENSITY);
  	}
  	set EdgeHightIntensity(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(SkinMaterial.EDGE_HIGHLIGHT_INTENSITY, value);
  	}
  	get EdgeHightBoundary() {
  		return this._shaderValues.getNumber(SkinMaterial.EDGE_HIGHLIGHT_BOUNDARY);
  	}
  	set EdgeHightBoundary(value) {
  		value = Math.max(0.0, Math.min(1.0, value));
  		this._shaderValues.setNumber(SkinMaterial.EDGE_HIGHLIGHT_BOUNDARY, value);
  	}
  	get SPOcclusionStrength() {
  		return this._shaderValues.getNumber(SkinMaterial.SPOCCLUSIONSTRENGTH);
  	}
  	set SPOcclusionStrength(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SPOCCLUSIONSTRENGTH, value);
  		this._shaderValues.setNumber(SkinMaterial.SPOCCLUSIONSTRENGTH, value);
  	}
  	get SPMetallic() {
  		return this._shaderValues.getNumber(SkinMaterial.SPMETALLIC);
  	}
  	set SPMetallic(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SPMETALLIC, value);
  		this._shaderValues.setNumber(SkinMaterial.SPMETALLIC, value);
  	}
  	get SPSmoothness() {
  		return this._shaderValues.getNumber(SkinMaterial.SPSMOOTHNESS);
  	}
  	set SPSmoothness(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SPSMOOTHNESS, value);
  		this._shaderValues.setNumber(SkinMaterial.SPSMOOTHNESS, value);
  	}
  	get SPMetallic2() {
  		return this._shaderValues.getNumber(SkinMaterial.SPMETALLIC2);
  	}
  	set SPMetallic2(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SPMETALLIC2, value);
  		this._shaderValues.setNumber(SkinMaterial.SPMETALLIC2, value);
  	}
  	get SPSmoothness2() {
  		return this._shaderValues.getNumber(SkinMaterial.SPSMOOTHNESS2);
  	}
  	set SPSmoothness2(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SPSMOOTHNESS2, value);
  		this._shaderValues.setNumber(SkinMaterial.SPSMOOTHNESS2, value);
  	}
  	get SPNoiseBump() {
  		return this._shaderValues.getNumber(SkinMaterial.SPNOISEBUMP);
  	}
  	set SPNoiseBump(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SPNOISEBUMP, value);
  		this._shaderValues.setNumber(SkinMaterial.SPNOISEBUMP, value);
  	}
  	get SPNoiseBumpTiling() {
  		return this._shaderValues.getNumber(SkinMaterial.SPNOISEBUMPTILING);
  	}
  	set SPNoiseBumpTiling(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SPNOISEBUMPTILING, value);
  		this._shaderValues.setNumber(SkinMaterial.SPNOISEBUMPTILING, value);
  	}
  	get SPNoiseBumpBasicAO() {
  		return this._shaderValues.getNumber(SkinMaterial.SPNOISEBUMPBASICAO);
  	}
  	set SPNoiseBumpBasicAO(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SPNOISEBUMPBASICAO, value);
  		this._shaderValues.setNumber(SkinMaterial.SPNOISEBUMPBASICAO, value);
  	}
  	get SPShadowAtten() {
  		return this._shaderValues.getNumber(SkinMaterial.SPSHADOWATTEN);
  	}
  	set SPShadowAtten(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SPSHADOWATTEN, value);
  		this._shaderValues.setNumber(SkinMaterial.SPSHADOWATTEN, value);
  	}
  	get SPEmissionColorBack() {
  		return this._shaderValues.getVector(SkinMaterial.SPEMISSIONCOLORBACK);
  	}
  	set SPEmissionColorBack(value) {
  		this._shaderValues.setVector(SkinMaterial.SPEMISSIONCOLORBACK, value);
  	}
  	get SPEmissionColorBackIntensity() {
  		return this._shaderValues.getNumber(SkinMaterial.SPEMISSIONCOLORBACKINTENSITY);
  	}
  	set SPEmissionColorBackIntensity(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SPEMISSIONCOLORBACKINTENSITY, value);
  		this._shaderValues.setNumber(SkinMaterial.SPEMISSIONCOLORBACKINTENSITY, value);
  	}
  	get SPBorderOffsetAO() {
  		return this._shaderValues.getNumber(SkinMaterial.SPBORDEROFFSETAO);
  	}
  	set SPBorderOffsetAO(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SPBORDEROFFSETAO, value);
  		this._shaderValues.setNumber(SkinMaterial.SPBORDEROFFSETAO, value);
  	}
  	get SPEmissionColorBackIntensity2() {
  		return this._shaderValues.getNumber(SkinMaterial.SPEMISSIONCOLORBACKINTENSITY2);
  	}
  	set SPEmissionColorBackIntensity2(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SPEMISSIONCOLORBACKINTENSITY2, value);
  		this._shaderValues.setNumber(SkinMaterial.SPEMISSIONCOLORBACKINTENSITY2, value);
  	}
  	get SPRedTranslucency() {
  		return this._shaderValues.getNumber(SkinMaterial.SPREDTRANSLUCENCY);
  	}
  	set SPRedTranslucency(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SPREDTRANSLUCENCY, value);
  		this._shaderValues.setNumber(SkinMaterial.SPREDTRANSLUCENCY, value);
  	}
  	get SPRedTransShadow() {
  		return this._shaderValues.getNumber(SkinMaterial.SPREDTRANSSHADOW);
  	}
  	set SPRedTransShadow(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SPREDTRANSSHADOW, value);
  		this._shaderValues.setNumber(SkinMaterial.SPREDTRANSSHADOW, value);
  	}
  	get SPRedTransNormalDistortion() {
  		return this._shaderValues.getNumber(SkinMaterial.SPREDTRANSNORMALDISTORTION);
  	}
  	set SPRedTransNormalDistortion(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SPREDTRANSNORMALDISTORTION, value);
  		this._shaderValues.setNumber(SkinMaterial.SPREDTRANSNORMALDISTORTION, value);
  	}
  	get SPRedTransScattering() {
  		return this._shaderValues.getNumber(SkinMaterial.SPREDTRANSSCATTERING);
  	}
  	set SPRedTransScattering(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SPREDTRANSSCATTERING, value);
  		this._shaderValues.setNumber(SkinMaterial.SPREDTRANSSCATTERING, value);
  	}
  	get SPRedTransDirect() {
  		return this._shaderValues.getNumber(SkinMaterial.SPREDTRANSDIRECT);
  	}
  	set SPRedTransDirect(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SPREDTRANSDIRECT, value);
  		this._shaderValues.setNumber(SkinMaterial.SPREDTRANSDIRECT, value);
  	}
  	get SPRedTransAmbient() {
  		return this._shaderValues.getNumber(SkinMaterial.SPREDTRANSAMBIENT);
  	}
  	set SPRedTransAmbient(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SPREDTRANSAMBIENT, value);
  		this._shaderValues.setNumber(SkinMaterial.SPREDTRANSAMBIENT, value);
  	}
  	get SPRed3SOffset() {
  		return this._shaderValues.getNumber(SkinMaterial.SPRED3SOFFSET);
  	}
  	set SPRed3SOffset(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.SPRED3SOFFSET, value);
  		this._shaderValues.setNumber(SkinMaterial.SPRED3SOFFSET, value);
  	}
  	get SPRed3SColor() {
  		return this._shaderValues.getVector(SkinMaterial.SPRED3SCOLOR);
  	}
  	set SPRed3SColor(value) {
  		this._shaderValues.setVector(SkinMaterial.SPRED3SCOLOR, value);
  	}
  	get CustomDirectLightColor() {
  		return this._shaderValues.getVector(SkinMaterial.CUSTOMDIRECTLIGHTCOLOR);
  	}
  	set CustomDirectLightColor(value) {
  		this._shaderValues.setVector(SkinMaterial.CUSTOMDIRECTLIGHTCOLOR, value);
  	}
  	get LightResultIntensity() {
  		return this._shaderValues.getNumber(SkinMaterial.LIGHTRESULTINTENSITY);
  	}
  	set LightResultIntensity(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.LIGHTRESULTINTENSITY, value);
  		this._shaderValues.setNumber(SkinMaterial.LIGHTRESULTINTENSITY, value);
  	}
  	get AlbedoTillingX() {
  		return this._shaderValues.getNumber(SkinMaterial.ALBEDOTILLINGX);
  	}
  	set AlbedoTillingX(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.ALBEDOTILLINGX, value);
  		this._shaderValues.setNumber(SkinMaterial.ALBEDOTILLINGX, value);
  	}
  	get AlbedoTillingY() {
  		return this._shaderValues.getNumber(SkinMaterial.ALBEDOTILLINGY);
  	}
  	set AlbedoTillingY(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.ALBEDOTILLINGY, value);
  		this._shaderValues.setNumber(SkinMaterial.ALBEDOTILLINGY, value);
  	}
  	get tilingOffset() {
  		return this._shaderValues.getVector(SkinMaterial.TILINGOFFSET);
  	}
  	set tilingOffset(value) {
  		if (value) {
  			if (value.x != 1 || value.y != 1 || value.z != 0 || value.w != 0)
  				this._defineDatas.add(SkinMaterial.SHADERDEFINE_TILINGOFFSET);
  			else
  				this._defineDatas.remove(SkinMaterial.SHADERDEFINE_TILINGOFFSET);
  		}
  		else {
  			this._defineDatas.remove(SkinMaterial.SHADERDEFINE_TILINGOFFSET);
  		}
  		this._shaderValues.setVector(SkinMaterial.TILINGOFFSET, value);
  	}
  	get CustomColorSectionStep() {
  		return this._shaderValues.getNumber(SkinMaterial.CUSTOMCOLORSECTIONSTEP);
  	}
  	set CustomColorSectionStep(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.CUSTOMCOLORSECTIONSTEP, value);
  		this._shaderValues.setNumber(SkinMaterial.CUSTOMCOLORSECTIONSTEP, value);
  	}
  	get CustomCreamColorTexture() {
  		return this._shaderValues.getTexture(SkinMaterial.CUSTOMCREAMCOLORTEXTURE);
  	}
  	set CustomCreamColorTexture(value) {
  		if (value != null) {
  			this._defineDatas.add(SkinMaterial.SHADERDEFINE_CUSTOMCREAMCOLORTEXTURE);
  		}
  		else {
  			this._defineDatas.remove(SkinMaterial.SHADERDEFINE_CUSTOMCREAMCOLORTEXTURE);
  		}
  		this._shaderValues.setTexture(SkinMaterial.CUSTOMCREAMCOLORTEXTURE, value);
  	}
  	get paintLayer1Texture() {
  		return this._shaderValues.getTexture(SkinMaterial.PAINT_LAYER1_TEXTURE);
  	}
  	set paintLayer1Texture(value) {
  		if (value != null) {
  			this._defineDatas.add(SkinMaterial.SHADERDEFINE_LAYER1_TEXTURE);
  		}
  		else {
  			this._defineDatas.remove(SkinMaterial.SHADERDEFINE_LAYER1_TEXTURE);
  		}
  		this._shaderValues.setTexture(SkinMaterial.PAINT_LAYER1_TEXTURE, value);
  	}
  	get paintLayer1TilingOffset() {
  		return this._shaderValues.getVector(SkinMaterial.PAINT_LAYER1_TILINGOFFSET);
  	}
  	set paintLayer1TilingOffset(value) {
  		this._shaderValues.setVector(SkinMaterial.PAINT_LAYER1_TILINGOFFSET, value);
  	}
  	get PlayerCustomChangeFlag() {
  		return this._shaderValues.getNumber(SkinMaterial.PLAYERCUSTOMCHANGEFLAG);
  	}
  	set PlayerCustomChangeFlag(value) {
  		value = this.clampKeyValueByKey(SkinMaterial.PLAYERCUSTOMCHANGEFLAG, value);
  		this._shaderValues.setNumber(SkinMaterial.PLAYERCUSTOMCHANGEFLAG, value);
  	}
  	getShaderValueRangeWithKey(key) {
  		switch (key) {
  			case SkinMaterial.SPOCCLUSIONSTRENGTH:
  				return [0.0, 2.0];
  				break;
  			case SkinMaterial.SPMETALLIC:
  				return [0.0, 1.0];
  				break;
  			case SkinMaterial.SPSMOOTHNESS:
  				return [0.0, 2.0];
  				break;
  			case SkinMaterial.SPMETALLIC2:
  				return [0.0, 1.0];
  				break;
  			case SkinMaterial.SPSMOOTHNESS2:
  				return [0.0, 2.0];
  				break;
  			case SkinMaterial.SPNOISEBUMP:
  				return [0.0, 2.0];
  				break;
  			case SkinMaterial.SPNOISEBUMPTILING:
  				return [0.0, 16.0];
  				break;
  			case SkinMaterial.SPNOISEBUMPBASICAO:
  				return [0.0, 5.0];
  				break;
  			case SkinMaterial.SPSHADOWATTEN:
  				return [0.0, 2.0];
  				break;
  			case SkinMaterial.SPEMISSIONCOLORBACKINTENSITY:
  				return [0.0, 1.0];
  				break;
  			case SkinMaterial.SPEMISSIONCOLORBACKINTENSITY2:
  				return [0.0, 2.0];
  				break;
  			case SkinMaterial.SPBORDEROFFSETAO:
  				return [-2.0, 2.0];
  				break;
  			case SkinMaterial.SPREDTRANSLUCENCY:
  				return [0.0, 50.0];
  				break;
  			case SkinMaterial.SPREDTRANSSHADOW:
  				return [0.0, 1.0];
  				break;
  			case SkinMaterial.SPREDTRANSNORMALDISTORTION:
  				return [0.0, 1.0];
  				break;
  			case SkinMaterial.SPREDTRANSSCATTERING:
  				return [1.0, 50.0];
  				break;
  			case SkinMaterial.SPREDTRANSDIRECT:
  				return [0.0, 1.0];
  				break;
  			case SkinMaterial.SPREDTRANSAMBIENT:
  				return [0.0, 1.0];
  				break;
  			case SkinMaterial.SPRED3SOFFSET:
  				return [0.0, 1.0];
  				break;
  			case SkinMaterial.NORMALTEXTURESCALE:
  				return [0.0, 2.0];
  				break;
  			case SkinMaterial.SPECULARINTENSITY:
  				return [0.0, 2.0];
  				break;
  			case SkinMaterial.GRIDTEXTURESCALE:
  				return [0.0, 20.0];
  				break;
  			case SkinMaterial.SHINETEXTURESCALE:
  				return [0.0, 20.0];
  				break;
  			case SkinMaterial.ALBEDOTILLINGX:
  				return [0.0, 20.0];
  				break;
  			case SkinMaterial.ALBEDOTILLINGY:
  				return [0.0, 20.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 cull() {
  		return this._shaderValues.getInt(SkinMaterial.CULL);
  	}
  	set cull(value) {
  		this._shaderValues.setInt(SkinMaterial.CULL, value);
  	}
  	get blend() {
  		return this._shaderValues.getInt(SkinMaterial.BLEND);
  	}
  	set blend(value) {
  		this._shaderValues.setInt(SkinMaterial.BLEND, value);
  	}
  	get blendSrc() {
  		return this._shaderValues.getInt(SkinMaterial.BLEND_SRC);
  	}
  	set blendSrc(value) {
  		this._shaderValues.setInt(SkinMaterial.BLEND_SRC, value);
  	}
  	get blendDst() {
  		return this._shaderValues.getInt(SkinMaterial.BLEND_DST);
  	}
  	set blendDst(value) {
  		this._shaderValues.setInt(SkinMaterial.BLEND_DST, value);
  	}
  	get depthTest() {
  		return this._shaderValues.getInt(SkinMaterial.DEPTH_TEST);
  	}
  	set depthTest(value) {
  		this._shaderValues.setInt(SkinMaterial.DEPTH_TEST, value);
  	}
  	get depthWrite() {
  		return this._shaderValues.getBool(SkinMaterial.DEPTH_WRITE);
  	}
  	set depthWrite(value) {
  		this._shaderValues.setBool(SkinMaterial.DEPTH_WRITE, value);
  	}
  	get randomDiscardFactor() {
  		return this._shaderValues.getNumber(SkinMaterial.RANDOM_DISCARD_FACTOR);
  	}
  	set randomDiscardFactor(value) {
  		this._shaderValues.setNumber(SkinMaterial.RANDOM_DISCARD_FACTOR, value);
  	}
  	get renderMode() {
  		return this.__render_mode__;
  	}
  	set renderMode(value) {
  		this.__render_mode__ = value;
  		switch (value) {
  			case SkinMaterial.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 SkinMaterial.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 SkinMaterial.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 SkinMaterial.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 SkinMaterial.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 SkinMaterial.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;
  		}
  	}
  	getCanEditorParamList() {
  		return [
  			{
  				name: `renderMode`, desc: `渲染模式`, type: EditorType.option, options: [
  					{ desc: "不透明", value: 1 },
  					{ desc: "裁剪", value: 2 },
  					{ desc: "裁剪双面", value: 3 },
  					{ desc: "透明", value: 4 },
  					{ desc: "透明双面", value: 5 },
  					{ desc: "不透明双面", value: 6 },
  				],
  			},
  			{ name: `alphaTestValue`, desc: `alpha裁剪参数`, type: EditorType.slider, range: [0, 1] },
  			{ name: `renderQueue`, desc: `renderQueue`, type: EditorType.num },
  			{ name: `albedoTexture`, desc: `基础贴图`, type: EditorType.texture2d, options: mgrMaterial.textures },
  			{ name: `normalTexture`, desc: `法线图片`, type: EditorType.texture2d, options: mgrMaterial.textures },
  			{ name: `rampMapTexture`, desc: `3s图片`, type: EditorType.texture2d, options: mgrMaterial.textures },
  			{ name: `gridTexture`, desc: `网络图片`, type: EditorType.texture2d, options: mgrMaterial.textures },
  			{ name: `shineTexture`, desc: `亮片图片`, type: EditorType.texture2d, options: mgrMaterial.textures },
  			{ name: `controlDetailTexture`, desc: `区域显示控制图片`, type: EditorType.texture2d, options: mgrMaterial.textures },
  			{ name: `CustomDirectLightColor`, desc: `自定义主光色`, type: EditorType.color },
  			{ name: `SPOcclusionStrength`, desc: `遮挡强度`, type: EditorType.slider, range: [0, 2] },
  			{ name: `SPMetallic`, desc: `金属度`, type: EditorType.slider },
  			{ name: `SPSmoothness`, desc: `光滑度`, type: EditorType.slider, range: [0, 2] },
  			{ name: `SPNoiseBump`, desc: `噪点影响值1`, type: EditorType.slider, range: [0, 2] },
  			{ name: `SPNoiseBumpTiling`, desc: `细节贴图平铺度`, type: EditorType.slider, range: [0, 16] },
  			{ name: `SPNoiseBumpBasicAO`, desc: `噪点影响值2`, type: EditorType.slider, range: [0, 5] },
  			{ name: `SPShadowAtten`, desc: `阴影强度`, type: EditorType.slider, range: [0, 2] },
  			{ name: `SPEmissionColorBack`, desc: `自发光底色`, type: EditorType.color },
  			{ name: `SPEmissionColorBackIntensity`, desc: `自发光底色强度`, type: EditorType.slider },
  			{ name: `SPBorderOffsetAO`, desc: `偏移度`, type: EditorType.slider, range: [-2, 2] },
  			{ name: `SPRedTranslucency`, desc: `皮肤透光度影响值`, type: EditorType.slider, range: [0, 50] },
  			{ name: `SPRedTransShadow`, desc: `皮肤暗部影响值`, type: EditorType.slider },
  			{ name: `SPRedTransNormalDistortion`, desc: `法线影响值`, type: EditorType.slider },
  			{ name: `SPRedTransScattering`, desc: `透光散射1`, type: EditorType.slider, range: [0, 50] },
  			{ name: `SPRedTransDirect`, desc: `透光散射2`, type: EditorType.slider },
  			{ name: `SPRedTransAmbient`, desc: `反射度影响值`, type: EditorType.slider },
  			{ name: `SPRed3SOffset`, desc: `法线偏移影响值`, type: EditorType.slider },
  			{ name: `SPRed3SColor`, desc: `透光性影响色调`, type: EditorType.color },
  			{ name: `normalTextureScale`, desc: `法线强度`, type: EditorType.slider, range: [0, 2] },
  			{ name: `bCastShadow`, desc: `是否产生阴影`, type: EditorType.slider },
  			{ name: `bReceiveShadow`, desc: `是否接受阴影`, type: EditorType.slider },
  			{ name: `LightResultIntensity`, desc: `灯光效果强度`, type: EditorType.slider },
  			{ name: `specularIntensity`, desc: `高光强度`, type: EditorType.slider, range: [0, 2] },
  			{ name: `gridTextureScale`, desc: `网络重复度`, type: EditorType.slider, range: [0, 20] },
  			{ name: `shineTextureScale`, desc: `亮片重复度`, type: EditorType.slider, range: [0, 20] },
  			{ name: `AlbedoTillingX`, desc: `底图重复度X`, type: EditorType.slider, range: [0, 20] },
  			{ name: `AlbedoTillingY`, desc: `底图重复度Y`, type: EditorType.slider, range: [0, 20] },
  			{ name: `SPMetallic2`, desc: `金属控制区域金属度`, type: EditorType.slider },
  			{ name: `SPSmoothness2`, desc: `金属控制区域光滑度`, type: EditorType.slider, range: [0, 2] },
  			{ name: `SPEmissionColorBackIntensity2`, desc: `基础色`, type: EditorType.slider, range: [0, 2] },
  			{ name: `gridTextureIsMultiply`, desc: `网络是否是叠加`, type: EditorType.slider },
  			{ name: `shineTextureIsMultiply`, desc: `亮片是否是叠加`, type: EditorType.slider },
  			{ name: `PlayerCustomChangeFlag`, desc: `玩家是否可以更改`, type: EditorType.slider },
  		];
  	}
  }
  SkinMaterial.ALBEDOTEXTURE = Laya.Shader3D.propertyNameToID("u_AlbedoTexture");
  SkinMaterial.ALBEDOCOLOR = Laya.Shader3D.propertyNameToID("u_AlbedoColor");
  SkinMaterial.NORMALTEXTURE = Laya.Shader3D.propertyNameToID("u_NormalTexture");
  SkinMaterial.NORMALTEXTURESCALE = Laya.Shader3D.propertyNameToID("u_NormalScale");
  SkinMaterial.MASKTEXTURE = Laya.Shader3D.propertyNameToID("u_MaskTexture");
  SkinMaterial.MASKDETAILTEXTURE = Laya.Shader3D.propertyNameToID("u_MaskDetailTexture");
  SkinMaterial.RAMPMAPTEXTURE = Laya.Shader3D.propertyNameToID("u_RampMapTexture");
  SkinMaterial.SMOOTHNESS = Laya.Shader3D.propertyNameToID("u_Smoothness");
  SkinMaterial.AMBIENTCOLOR = Laya.Shader3D.propertyNameToID("u_AmbientColor");
  SkinMaterial.GRIDTEXTURE = Laya.Shader3D.propertyNameToID("u_gridTexture");
  SkinMaterial.SHINETEXTURE = Laya.Shader3D.propertyNameToID("u_shineTexture");
  SkinMaterial.CONTROLDETAILTEXTURE = Laya.Shader3D.propertyNameToID("u_controlDetailTexture");
  SkinMaterial.GRIDTEXTURESCALE = Laya.Shader3D.propertyNameToID("u_gridTextureScale");
  SkinMaterial.SHINETEXTURESCALE = Laya.Shader3D.propertyNameToID("u_shineTextureScale");
  SkinMaterial.GRIDTEXTUREISMULTIPLY = Laya.Shader3D.propertyNameToID("u_gridTextureIsMultiply");
  SkinMaterial.SHINETEXTUREISMULTIPLY = Laya.Shader3D.propertyNameToID("u_shineTextureIsMultiply");
  SkinMaterial.OUTLINEWIDTH = Laya.Shader3D.propertyNameToID("u_OutlineWidth");
  SkinMaterial.OUTLINELIGHTNESS = Laya.Shader3D.propertyNameToID("u_OutlineLightness");
  SkinMaterial.OUTLINECOLOR = Laya.Shader3D.propertyNameToID("u_OutlineColor");
  SkinMaterial.SHADOWCOLOR = Laya.Shader3D.propertyNameToID("u_ShadowColor");
  SkinMaterial.SHADOWRANGE = Laya.Shader3D.propertyNameToID("u_ShadowRange");
  SkinMaterial.SHADOWINTENSITY = Laya.Shader3D.propertyNameToID("u_ShadowIntensity");
  SkinMaterial.SHADOWBOUNDARY = Laya.Shader3D.propertyNameToID("u_ShadowBoundary");
  SkinMaterial.SECOND_SHADOWCOLOR = Laya.Shader3D.propertyNameToID("u_Second_ShadowColor");
  SkinMaterial.SECOND_SHADOWRANGE = Laya.Shader3D.propertyNameToID("u_Second_ShadowRange");
  SkinMaterial.SECOND_SHADOWINTENSITY = Laya.Shader3D.propertyNameToID("u_Second_ShadowIntensity");
  SkinMaterial.SECOND_SHADOWBOUNDARY = Laya.Shader3D.propertyNameToID("u_Second_ShadowBoundary");
  SkinMaterial.EDGE_HIGHLIGHT_COLOR = Laya.Shader3D.propertyNameToID("u_Edge_HighlightColor");
  SkinMaterial.EDGE_HIGHLIGHT_RANGE = Laya.Shader3D.propertyNameToID("u_Edge_HighlightRange");
  SkinMaterial.EDGE_HIGHLIGHT_INTENSITY = Laya.Shader3D.propertyNameToID("u_Edge_HighlightIntensity");
  SkinMaterial.EDGE_HIGHLIGHT_BOUNDARY = Laya.Shader3D.propertyNameToID("u_Edge_HighlightBoundary");
  SkinMaterial.SPECULARRANGE = Laya.Shader3D.propertyNameToID("u_SpecularRange");
  SkinMaterial.SPECULARINTENSITY = Laya.Shader3D.propertyNameToID("u_specularIntensity");
  SkinMaterial.SPECULARCOLOR = Laya.Shader3D.propertyNameToID("u_SpecularColor");
  SkinMaterial.RANDOM_DISCARD_FACTOR = Laya.Shader3D.propertyNameToID(`u_RandomDiscardFactor`);
  SkinMaterial.SPOCCLUSIONSTRENGTH = Laya.Shader3D.propertyNameToID(`u_SPOcclusionStrength`);
  SkinMaterial.SPMETALLIC = Laya.Shader3D.propertyNameToID(`u_SPMetallic`);
  SkinMaterial.SPSMOOTHNESS = Laya.Shader3D.propertyNameToID(`u_SPSmoothness`);
  SkinMaterial.SPMETALLIC2 = Laya.Shader3D.propertyNameToID(`u_SPMetallic2`);
  SkinMaterial.SPSMOOTHNESS2 = Laya.Shader3D.propertyNameToID(`u_SPSmoothness2`);
  SkinMaterial.SPNOISEBUMP = Laya.Shader3D.propertyNameToID(`u_SPNoiseBump`);
  SkinMaterial.SPNOISEBUMPTILING = Laya.Shader3D.propertyNameToID(`u_SPNoiseBumpTiling`);
  SkinMaterial.SPNOISEBUMPBASICAO = Laya.Shader3D.propertyNameToID(`u_SPNoiseBumpBasicAO`);
  SkinMaterial.SPSHADOWATTEN = Laya.Shader3D.propertyNameToID(`u_SPShadowAtten`);
  SkinMaterial.SPEMISSIONCOLORBACK = Laya.Shader3D.propertyNameToID(`u_SPEmissionColorBack`);
  SkinMaterial.SPEMISSIONCOLORBACKINTENSITY = Laya.Shader3D.propertyNameToID(`u_SPEmissionColorBackIntensity`);
  SkinMaterial.SPBORDEROFFSETAO = Laya.Shader3D.propertyNameToID(`u_SPBorderOffsetAO`);
  SkinMaterial.SPEMISSIONCOLORBACKINTENSITY2 = Laya.Shader3D.propertyNameToID(`u_SPEmissionColorBackIntensity2`);
  SkinMaterial.SPREDTRANSLUCENCY = Laya.Shader3D.propertyNameToID(`u_SPRedTranslucency`);
  SkinMaterial.SPREDTRANSSHADOW = Laya.Shader3D.propertyNameToID(`u_SPRedTransShadow`);
  SkinMaterial.SPREDTRANSNORMALDISTORTION = Laya.Shader3D.propertyNameToID(`u_SPRedTransNormalDistortion`);
  SkinMaterial.SPREDTRANSSCATTERING = Laya.Shader3D.propertyNameToID(`u_SPRedTransScattering`);
  SkinMaterial.SPREDTRANSDIRECT = Laya.Shader3D.propertyNameToID(`u_SPRedTransDirect`);
  SkinMaterial.SPREDTRANSAMBIENT = Laya.Shader3D.propertyNameToID(`u_SPRedTransAmbient`);
  SkinMaterial.SPRED3SOFFSET = Laya.Shader3D.propertyNameToID(`u_SPRed3SOffset`);
  SkinMaterial.SPRED3SCOLOR = Laya.Shader3D.propertyNameToID(`u_SPRed3SColor`);
  SkinMaterial.CUSTOMDIRECTLIGHTCOLOR = Laya.Shader3D.propertyNameToID(`u_CustomDirectLightColor`);
  SkinMaterial.LIGHTRESULTINTENSITY = Laya.Shader3D.propertyNameToID(`u_LightResultIntensity`);
  SkinMaterial.ALBEDOTILLINGX = Laya.Shader3D.propertyNameToID(`u_AlbedoTillingX`);
  SkinMaterial.ALBEDOTILLINGY = Laya.Shader3D.propertyNameToID(`u_AlbedoTillingY`);
  SkinMaterial.CUSTOMCOLORSECTIONSTEP = Laya.Shader3D.propertyNameToID(`u_CustomColorSectionStep`);
  SkinMaterial.CUSTOMCREAMCOLORTEXTURE = Laya.Shader3D.propertyNameToID("u_CustomCreamColorTexture");
  SkinMaterial.PAINT_LAYER1_TEXTURE = Laya.Shader3D.propertyNameToID("u_PaintLayer1Texture");
  SkinMaterial.PAINT_LAYER1_TILINGOFFSET = Laya.Shader3D.propertyNameToID("u_PaintLayer1TilingOffset");
  SkinMaterial.PLAYERCUSTOMCHANGEFLAG = Laya.Shader3D.propertyNameToID(`u_PlayerCustomChangeFlag`);
  SkinMaterial.CULL = Laya.Shader3D.propertyNameToID("s_Cull");
  SkinMaterial.BLEND = Laya.Shader3D.propertyNameToID("s_Blend");
  SkinMaterial.BLEND_SRC = Laya.Shader3D.propertyNameToID("s_BlendSrc");
  SkinMaterial.BLEND_DST = Laya.Shader3D.propertyNameToID("s_BlendDst");
  SkinMaterial.DEPTH_TEST = Laya.Shader3D.propertyNameToID("s_DepthTest");
  SkinMaterial.DEPTH_WRITE = Laya.Shader3D.propertyNameToID("s_DepthWrite");
  SkinMaterial.RENDERMODE_OPAQUE = 1;
  SkinMaterial.RENDERMODE_CUTOUT = 2;
  SkinMaterial.RENDERMODE_CUTOUT_CULL_NONE = 3;
  SkinMaterial.RENDERMODE_TRANSPARENT = 4;
  SkinMaterial.RENDERMODE_TRANSPARENT_CULL_NONE = 5;
  SkinMaterial.RENDERMODE_OPAQUE_CULL_NONE = 6;

  const KEY_MATERIAL_INFO_VERSION = "KEY_MATERIAL_INFO_VERSION";
  const MATERIAL_INFO_VERSION = 1;
  class mgrMaterial extends Manager {
  	static onLoad() {
  		BagMaterial.initShader();
  		NormalMaterial.initShader();
  		PaintMaterial.initShader();
  		FillColorMaterial.initShader();
  		SharkMaterial.initShader();
  		ProgressMaterial.initShader();
  		BurnMaterial.initShader();
  		CartoonHairMaterial.initShader();
  		CartoonFaceMaterial.initShader();
  		CartoonBodyMaterial.initShader();
  		CartoonClothMaterial.initShader();
  		SkinMaterial.initShader();
  		this.shaderName2Class = {};
  		this.shaderName2Class[`BagMaterial`] = BagMaterial;
  		this.shaderName2Class[`NormalMaterial`] = NormalMaterial;
  		this.shaderName2Class[`PaintMaterial`] = PaintMaterial;
  		this.shaderName2Class[`FillColorMaterial`] = FillColorMaterial;
  		this.shaderName2Class[`SharkMaterial`] = SharkMaterial;
  		this.shaderName2Class[`ProgressMaterial`] = ProgressMaterial;
  		this.shaderName2Class[`BurnMaterial`] = BurnMaterial;
  		this.shaderName2Class[`CartoonHairMaterial`] = CartoonHairMaterial;
  		this.shaderName2Class[`CartoonFaceMaterial`] = CartoonFaceMaterial;
  		this.shaderName2Class[`CartoonBodyMaterial`] = CartoonBodyMaterial;
  		this.shaderName2Class[`CartoonClothMaterial`] = CartoonClothMaterial;
  		this.shaderName2Class[`SkinMaterial`] = SkinMaterial;
  		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();
  		ResLoader.loadRes("res/cfg/editorConfig.json", Laya.Loader.JSON, (res) => {
  			if (res) {
  				if (res[KEY_MATERIAL_INFO_VERSION] == MATERIAL_INFO_VERSION) {
  					this.editorConfig = res;
  				}
  			}
  		});
  		ResLoader.loadRes("res/cfg/texturelist.json", Laya.Loader.JSON, (res) => {
  			if (res) {
  				this.textures = res;
  			}
  		});
  		ResLoader.loadJson(`res/cfg/shaderCompile.json`, (obj) => {
  			this.shaderCompileInfo = obj;
  			super.onLoad();
  		});
  	}
  	static loadFromText() {
  		ResLoader.loadRes("res/cfg/3dConfig.txt", Laya.Loader.BUFFER, (res) => {
  			if (res) {
  				let jsonStr = Tools.decompressArrToStr(Tools.compressArr(res));
  				let data = JSON.parse(jsonStr);
  				this.materialInfos = data.materialInfos || {};
  				this.lightRotation = data.lightRotation || new Laya.Vector3(-10, -11, 25);
  				this.globalShadowConfig = data.globalShadowConfig || {
  					shadowMode: Laya.ShadowMode.None,
  					shadowDistance: 10,
  					shadowNearPlane: 0.1,
  					shadowResolution: 2048,
  					shadowStrength: 0.5,
  					shadowDepthBias: 0.0,
  				};
  			}
  		});
  	}
  	static getSaveData() {
  		let data = {
  			materialInfos: this.materialInfos,
  			lightRotation: this.lightRotation,
  			lightColor: this.lightColor,
  			globalShadowConfig: this.globalShadowConfig,
  		};
  		data[KEY_MATERIAL_INFO_VERSION] = MATERIAL_INFO_VERSION;
  		return data;
  	}
  	static saveToLocal() {
  		if (GameRemoteRouter.instance) {
  			let data = this.getSaveData();
  			GameRemoteRouter.instance.sendMsgToServer({
  				route: "keepInFile",
  				data: {
  					filePath: `res/cfg/3dConfig.txt`,
  					data: data,
  				},
  			});
  			GameRemoteRouter.instance.sendMsgToServer({
  				route: "keepInFile",
  				data: {
  					filePath: `res/cfg/editorConfig.json`,
  					data: this.editorConfig,
  				},
  			});
  			Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "保存数据成功！");
  		}
  		else {
  			Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "未链接存档服务器！");
  		}
  	}
  	static setEditedMaterialData(modelId, nodeName, matIndex, material) {
  		if (!this.materialInfos[modelId])
  			this.materialInfos[modelId] = {};
  		if (!this.materialInfos[modelId][nodeName])
  			this.materialInfos[modelId][nodeName] = {
  				matInfos: {},
  				castShadow: false,
  				receiveShadow: false,
  			};
  		let editInfo = material.getCanEditorParamList();
  		let info = {};
  		for (let i = 0; i < editInfo.length; i++) {
  			const element = editInfo[i];
  			let data = material[element.name];
  			if (data instanceof Laya.BaseTexture) {
  				let url = data.url;
  				url = url.slice(url.indexOf("res"));
  				info[element.name] = "url://" + url;
  			}
  			else {
  				info[element.name] = material[element.name];
  			}
  		}
  		this.materialInfos[modelId][nodeName].matInfos[matIndex] = {
  			matName: material.constructor.name,
  			param: info,
  		};
  	}
  	static getEditedMaterialData(modelId, nodeName, matIndex) {
  		if (!this.materialInfos[modelId]) {
  			return null;
  		}
  		if (!this.materialInfos[modelId][nodeName]) {
  			return null;
  		}
  		if (!this.materialInfos[modelId][nodeName].matInfos[matIndex]) {
  			return null;
  		}
  		return this.materialInfos[modelId][nodeName].matInfos[matIndex];
  	}
  	static useEditedMaterial(model) {
  		if (!model)
  			return [];
  		return this.useEditedMaterialByResNode(model.resNode, model.modelId);
  	}
  	static useEditedMaterialByResNode(model, modelId) {
  		if (!model)
  			return [];
  		let materials = [];
  		let allRenders = Tools.findAllRenderers(model);
  		for (let i = 0; i < allRenders.length; i++) {
  			const element = allRenders[i];
  			element.router = `/${modelId}${element.router}`;
  			const renderInfo = (this.materialInfos[modelId] && this.materialInfos[modelId][element.router]) || { matInfos: {}, castShadow: false, receiveShadow: false };
  			element.renderer.castShadow = renderInfo.castShadow;
  			element.renderer.receiveShadow = renderInfo.receiveShadow;
  			let material = this.__useEditedMaterial(element.renderer, model, modelId, element.router);
  			materials = materials.concat(material);
  		}
  		return materials;
  	}
  	static __useEditedMaterial(render, model, modelId, nodeName) {
  		let newMaterials = [];
  		let sharedMaterials = render.sharedMaterials;
  		for (let i = 0; i < sharedMaterials.length; i++) {
  			const oldMaterial = sharedMaterials[i];
  			let materialData = mgrMaterial.getEditedMaterialData(modelId, nodeName, i);
  			if (!materialData) {
  				newMaterials[i] = oldMaterial;
  				continue;
  			}
  			if (this.shaderName2Class[oldMaterial.constructor.name]) {
  				newMaterials[i] = oldMaterial;
  			}
  			else {
  				newMaterials[i] = this.createMaterial(oldMaterial, materialData.matName);
  			}
  			let node = Tools.findNode(`face_dir`, model);
  			if (node) {
  				node[`faceTimer${i}`] && node[`faceTimer${i}`].stop();
  				node[`faceTimer${i}`] = Timer.callLoopFrame(1, () => {
  					const mat = newMaterials[i];
  					let forward = new Laya.Vector3;
  					node.transform.getRight(forward);
  					Laya.Vector3.scale(forward, -1, forward);
  					mat.lightMapForward = forward;
  					let right = new Laya.Vector3;
  					node.transform.getUp(right);
  					Laya.Vector3.scale(right, -1, right);
  					mat.lightMapRight = right;
  				}, node);
  			}
  			this.fillMaterialData(newMaterials[i], materialData);
  		}
  		render.sharedMaterials = newMaterials;
  		return newMaterials;
  	}
  	static createMaterial(oldMaterial, matName) {
  		let newMaterial = new this.shaderName2Class[matName]();
  		newMaterial.name = oldMaterial.name;
  		if (oldMaterial.albedoTexture) {
  			newMaterial.albedoTexture = oldMaterial.albedoTexture;
  		}
  		newMaterial.paintLayer1TilingOffset = new Laya.Vector4(1, 1, 0, 0);
  		return newMaterial;
  	}
  	static fillMaterialData(newMaterial, materialData) {
  		if (!newMaterial || !materialData)
  			return;
  		Tools.forEachMap(materialData.param, function (key, value) {
  			if (value[`x`]) {
  				newMaterial[key] = new Laya.Vector4(value[`x`], value[`y`], value[`z`], value[`w`]);
  			}
  			else if (typeof value == "string") {
  				if (value.startsWith("url://")) {
  					ResLoader.loadImage(value.substr(6), function (texture) {
  						if (!texture)
  							return;
  						if (newMaterial.destroyed)
  							return;
  						if (newMaterial[key])
  							return;
  						let text2d = texture.bitmap;
  						Tools.setTexture2dToRepeat(text2d);
  						newMaterial[key] = text2d;
  					});
  				}
  				else {
  					console.error(`mgrMaterial.fillMaterialData 未知数据类型key:${key} value:${value}`);
  				}
  			}
  			else {
  				newMaterial[key] = value;
  			}
  		});
  	}
  	static startRecordModelCompileInfo() {
  		if (!Laya.Browser.onPC || window[`conch`])
  			return;
  		this.enableShaderDebugMode();
  		Laya.Shader3D.debugShaderVariantCollection.clear();
  	}
  	static endRecordModelCompileInfo(modelId) {
  		if (!Laya.Browser.onPC || window[`conch`])
  			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 precompileShaderByPanelName(modelId) {
  		if (!!this._compiledShaderDict[modelId]) {
  			return;
  		}
  		let compileInfo = this.shaderCompileInfo[modelId] || [];
  		console.log(`编译shader: ${modelId}!!!`);
  		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}!!!`);
  		this._compiledShaderDict[modelId] = true;
  	}
  	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 lerpMaterial(model, modelId1, modelId2, progress) {
  		if (!model)
  			return [];
  		let allRenders = Tools.findAllRenderers(model);
  		for (let i = 0; i < allRenders.length; i++) {
  			const renderer = allRenders[i];
  			this.___lerpMaterial(renderer.renderer, modelId1, modelId2, renderer.router, progress);
  		}
  	}
  	static ___lerpMaterial(render, modelId1, modelId2, nodeName, progress) {
  		let sharedMaterials = render.sharedMaterials;
  		for (let i = 0; i < sharedMaterials.length; i++) {
  			const mat = sharedMaterials[i];
  			let material1Data = mgrMaterial.getEditedMaterialData(modelId1, nodeName, i);
  			let material2Data = mgrMaterial.getEditedMaterialData(modelId2, nodeName, i);
  			Tools.forEachMap(material1Data, (k, v) => {
  				if (typeof (v) == "number") {
  					mat[k] = material1Data[k] * (1 - progress) + material2Data[k] * progress;
  				}
  				else if (v[`length`]) {
  					for (let i = 0; i < material1Data[k].length; i++) {
  						const element1 = material1Data[k][i];
  						const element2 = material2Data[k][i];
  						if (i == 0) {
  							mat[k].x = element1 * (1 - progress) + element2 * progress;
  						}
  						else if (i == 1) {
  							mat[k].y = element1 * (1 - progress) + element2 * progress;
  						}
  						else if (i == 2) {
  							mat[k].z = element1 * (1 - progress) + element2 * progress;
  						}
  						else if (i == 3) {
  							mat[k].w = element1 * (1 - progress) + element2 * progress;
  						}
  					}
  				}
  			});
  		}
  		;
  	}
  	static useMaterialByClass(matCalss, model, renderIndex, matIndex, extendParams, param, fliterParam) {
  		let renders = Tools.findAllRenderers(model);
  		let allMaterials = [];
  		for (let i = 0; i < renders.length; i++) {
  			if (renderIndex != -1 && i != renderIndex)
  				continue;
  			const renderInfo = renders[i];
  			let newMaterials = [];
  			for (let j = 0; j < renderInfo.renderer.sharedMaterials.length; j++) {
  				const element = renderInfo.renderer.sharedMaterials[j];
  				if (matIndex != -1 && matIndex != j) {
  					newMaterials.push(element);
  					continue;
  				}
  				let mat = null;
  				if (element instanceof matCalss) {
  					mat = element;
  				}
  				else {
  					mat = new matCalss;
  					mat.name = element.name;
  					Tools.forEachMap(extendParams, (k, v) => {
  						mat[k] = element[k];
  					});
  				}
  				Tools.forEachMap(param, (k, v) => {
  					mat[k] = v;
  				});
  				Tools.forEachMap(fliterParam, (k, v) => {
  					if ((new RegExp(v.fliter)).test(mat.name)) {
  						mat[k] = v.value;
  					}
  				});
  				newMaterials.push(mat);
  				allMaterials.push(mat);
  			}
  			renderInfo.renderer.sharedMaterials = newMaterials;
  		}
  		return allMaterials;
  	}
  	static playAnimation(animator, animationId, mixFactor, loadEndCallback, playEndCallback) {
  		if (!animator) {
  			console.warn("-------[ERROR]----No Animator");
  		}
  		let animationData = db.get_animation_db(animationId);
  		let animatorState = animator.getControllerLayer(0).getAnimatorState(animationId);
  		if (!animatorState) {
  			Laya.AnimationClip.load(animationData.path, new Laya.Handler(this, (clip) => {
  				let __temp = animator.getControllerLayer(0).getAnimatorState(animationId);
  				if (__temp)
  					return;
  				animatorState = new Laya.AnimatorState();
  				animatorState.clip = clip;
  				animatorState.clipStart = 0;
  				animatorState.clipEnd = 1;
  				animatorState.name = animationId;
  				animator.getControllerLayer(0).addState(animatorState);
  				if (mixFactor == 0) {
  					animator.play(animationId, 0, 0);
  				}
  				else {
  					animator.crossFade(animationId, mixFactor);
  				}
  				loadEndCallback && loadEndCallback();
  				Timer.callLater(clip.duration(), () => {
  					playEndCallback && playEndCallback();
  				}, animator.owner);
  			}));
  		}
  		else {
  			let clip = animator.getControllerLayer(0).getAnimatorState(animationId).clip;
  			if (animator.getCurrentAnimatorPlayState(0).animatorState.name == animationId && clip.islooping == true) {
  				return;
  			}
  			if (mixFactor == 0) {
  				animator.play(animationId, 0, 0);
  			}
  			else {
  				animator.crossFade(animationId, mixFactor);
  			}
  			loadEndCallback && loadEndCallback();
  			Timer.callLater(clip.duration(), () => {
  				playEndCallback && playEndCallback();
  			}, animator.owner);
  		}
  	}
  	static playLayerAnimation(animator, animationId, controllerLayer = 0, mixFactor = 0, loadEndCallback, playEndCallback) {
  		let animationData = db.get_animation_db(animationId);
  		let animatorState = animator.getControllerLayer(controllerLayer).getAnimatorState(animationId);
  		if (!animatorState) {
  			Laya.AnimationClip.load(animationData.path, new Laya.Handler(this, (clip) => {
  				let __temp = animator.getControllerLayer(controllerLayer).getAnimatorState(animationId);
  				if (__temp)
  					return;
  				animatorState = new Laya.AnimatorState();
  				animatorState.clip = clip;
  				animatorState.clipStart = 0;
  				animatorState.clipEnd = 1;
  				animatorState.name = animationId;
  				animator.getControllerLayer(controllerLayer).addState(animatorState);
  				animator.crossFade(animationId, mixFactor, controllerLayer, 0);
  				loadEndCallback && loadEndCallback();
  				Timer.callLater(clip.duration(), () => {
  					playEndCallback && playEndCallback();
  				}, animator.owner);
  			}));
  		}
  		else {
  			let clip = animator.getControllerLayer(controllerLayer).getAnimatorState(animationId).clip;
  			if (animator.getControllerLayer(controllerLayer).getCurrentPlayState().animatorState.name == animationId && clip.islooping == true) {
  				return;
  			}
  			animator.crossFade(animationId, mixFactor, controllerLayer, 0);
  			loadEndCallback && loadEndCallback();
  			Timer.callLater(clip.duration(), () => {
  				playEndCallback && playEndCallback();
  			}, animator.owner);
  		}
  	}
  }
  mgrMaterial.materialInfos = {};
  mgrMaterial.lightColor = new Laya.Vector3(1, 1, 1);
  mgrMaterial.editorConfig = { camera: {} };
  mgrMaterial.textures = [];
  mgrMaterial.shaderCompileInfo = {};
  mgrMaterial._compiledShaderDict = {};

  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) {
  		let target = this.target;
  		if (!target || target.destroyed || (target.owner && target.owner.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 || (target.owner && target.owner.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 || (target.owner && target.owner.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;
  	}
  	pause() {
  		if (this._target) {
  			TweenSystem.instance.ActionManager.pauseTarget(this._target);
  		}
  		return this;
  	}
  	resume() {
  		if (this._target) {
  			TweenSystem.instance.ActionManager.resumeTarget(this._target);
  		}
  		return this;
  	}
  	removeAllActions() {
  		if (this._target) {
  			TweenSystem.instance.ActionManager.removeAllActionsFromTarget(this._target);
  		}
  		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;
  	}
  	toPos(duration, x, y, easing = Easing.linear) {
  		let opts = {};
  		for (let k in DEFAULT_OPT1) {
  			opts[k] = DEFAULT_OPT1[k];
  		}
  		opts.relative = false;
  		if (easing) {
  			opts.easing = easing;
  		}
  		let props = {
  			x: x,
  			y: y
  		};
  		const action = new TweenAction(duration, props, opts);
  		this._actions.push(action);
  		return this;
  	}
  	toAlpha(duration, alpha, easing = Easing.linear) {
  		let opts = {};
  		for (let k in DEFAULT_OPT1) {
  			opts[k] = DEFAULT_OPT1[k];
  		}
  		opts.relative = false;
  		if (easing) {
  			opts.easing = easing;
  		}
  		let props = {
  			alpha: alpha
  		};
  		const action = new TweenAction(duration, props, opts);
  		this._actions.push(action);
  		return this;
  	}
  	toScale(duration, scale, easing = Easing.linear) {
  		let opts = {};
  		for (let k in DEFAULT_OPT1) {
  			opts[k] = DEFAULT_OPT1[k];
  		}
  		opts.relative = false;
  		if (easing) {
  			opts.easing = easing;
  		}
  		let props = {
  			scaleX: scale,
  			scaleY: scale
  		};
  		const action = new TweenAction(duration, props, opts);
  		this._actions.push(action);
  		return this;
  	}
  	toRotation(duration, rotation, easing = Easing.linear) {
  		let opts = {};
  		for (let k in DEFAULT_OPT1) {
  			opts[k] = DEFAULT_OPT1[k];
  		}
  		opts.relative = false;
  		if (easing) {
  			opts.easing = easing;
  		}
  		let props = {
  			rotation: rotation
  		};
  		const action = new TweenAction(duration, props, opts);
  		this._actions.push(action);
  		return this;
  	}
  	toLocalPos3D(duration, x, y, z, easing = Easing.linear) {
  		let opts = {};
  		for (let k in DEFAULT_OPT1) {
  			opts[k] = DEFAULT_OPT1[k];
  		}
  		opts.relative = false;
  		if (easing) {
  			opts.easing = easing;
  		}
  		let props = {
  			localPositionX: x, localPositionY: y, localPositionZ: z
  		};
  		const action = new TweenAction(duration, props, opts);
  		this._actions.push(action);
  		return this;
  	}
  	toLocalScale3D(duration, scale, easing = Easing.linear) {
  		let opts = {};
  		for (let k in DEFAULT_OPT1) {
  			opts[k] = DEFAULT_OPT1[k];
  		}
  		opts.relative = false;
  		if (easing) {
  			opts.easing = easing;
  		}
  		let props = {
  			localScaleX: scale, localScaleY: scale, localScaleZ: scale
  		};
  		const action = new TweenAction(duration, props, opts);
  		this._actions.push(action);
  		return this;
  	}
  	toLocalRotationEuler3D(duration, x, y, z, easing = Easing.linear) {
  		let opts = {};
  		for (let k in DEFAULT_OPT1) {
  			opts[k] = DEFAULT_OPT1[k];
  		}
  		opts.relative = false;
  		if (easing) {
  			opts.easing = easing;
  		}
  		let props = {
  			localRotationEulerX: x,
  			localRotationEulerY: y,
  			localRotationEulerZ: z,
  		};
  		const action = new TweenAction(duration, props, opts);
  		this._actions.push(action);
  		return this;
  	}
  	toLocalRotationEulerX3D(duration, x, easing = Easing.linear) {
  		let opts = {};
  		for (let k in DEFAULT_OPT1) {
  			opts[k] = DEFAULT_OPT1[k];
  		}
  		opts.relative = false;
  		if (easing) {
  			opts.easing = easing;
  		}
  		let props = {
  			localRotationEulerX: x,
  		};
  		const action = new TweenAction(duration, props, opts);
  		this._actions.push(action);
  		return this;
  	}
  	toLocalRotationEulerY3D(duration, y, easing = Easing.linear) {
  		let opts = {};
  		for (let k in DEFAULT_OPT1) {
  			opts[k] = DEFAULT_OPT1[k];
  		}
  		opts.relative = false;
  		if (easing) {
  			opts.easing = easing;
  		}
  		let props = {
  			localRotationEulerY: y,
  		};
  		const action = new TweenAction(duration, props, opts);
  		this._actions.push(action);
  		return this;
  	}
  	toLocalRotationEulerZ3D(duration, z, easing = Easing.linear) {
  		let opts = {};
  		for (let k in DEFAULT_OPT1) {
  			opts[k] = DEFAULT_OPT1[k];
  		}
  		opts.relative = false;
  		if (easing) {
  			opts.easing = easing;
  		}
  		let props = {
  			localRotationEulerZ: z,
  		};
  		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;
  	}
  	byPos(duration, x, y, easing = Easing.linear) {
  		let opts = {};
  		for (let k in DEFAULT_OPT2) {
  			opts[k] = DEFAULT_OPT2[k];
  		}
  		opts.relative = true;
  		if (easing) {
  			opts.easing = easing;
  		}
  		let props = {
  			x: x, y: y
  		};
  		const action = new TweenAction(duration, props, opts);
  		this._actions.push(action);
  		return this;
  	}
  	byAlpha(duration, alpha, easing = Easing.linear) {
  		let opts = {};
  		for (let k in DEFAULT_OPT2) {
  			opts[k] = DEFAULT_OPT2[k];
  		}
  		opts.relative = true;
  		if (easing) {
  			opts.easing = easing;
  		}
  		let props = {
  			alpha: alpha
  		};
  		const action = new TweenAction(duration, props, opts);
  		this._actions.push(action);
  		return this;
  	}
  	byScale(duration, scale, easing = Easing.linear) {
  		let opts = {};
  		for (let k in DEFAULT_OPT2) {
  			opts[k] = DEFAULT_OPT2[k];
  		}
  		opts.relative = true;
  		if (easing) {
  			opts.easing = easing;
  		}
  		let props = {
  			scaleX: scale,
  			scaleY: scale
  		};
  		const action = new TweenAction(duration, props, opts);
  		this._actions.push(action);
  		return this;
  	}
  	byRotation(duration, rotation, easing = Easing.linear) {
  		let opts = {};
  		for (let k in DEFAULT_OPT2) {
  			opts[k] = DEFAULT_OPT2[k];
  		}
  		opts.relative = true;
  		if (easing) {
  			opts.easing = easing;
  		}
  		let props = {
  			rotation: rotation
  		};
  		const action = new TweenAction(duration, props, opts);
  		this._actions.push(action);
  		return this;
  	}
  	byLocalPos3D(duration, x, y, z, easing = Easing.linear) {
  		let opts = {};
  		for (let k in DEFAULT_OPT2) {
  			opts[k] = DEFAULT_OPT2[k];
  		}
  		opts.relative = true;
  		if (easing) {
  			opts.easing = easing;
  		}
  		let props = {
  			localPositionX: x, localPositionY: y, localPositionZ: z
  		};
  		const action = new TweenAction(duration, props, opts);
  		this._actions.push(action);
  		return this;
  	}
  	byLocalScale3D(duration, scale, easing = Easing.linear) {
  		let opts = {};
  		for (let k in DEFAULT_OPT2) {
  			opts[k] = DEFAULT_OPT2[k];
  		}
  		opts.relative = true;
  		if (easing) {
  			opts.easing = easing;
  		}
  		let props = {
  			localScaleX: scale, localScaleY: scale, localScaleZ: scale
  		};
  		const action = new TweenAction(duration, props, opts);
  		this._actions.push(action);
  		return this;
  	}
  	byLocalRotationEuler3D(duration, x, y, z, easing = Easing.linear) {
  		let opts = {};
  		for (let k in DEFAULT_OPT2) {
  			opts[k] = DEFAULT_OPT2[k];
  		}
  		opts.relative = true;
  		if (easing) {
  			opts.easing = easing;
  		}
  		let props = {
  			localRotationEulerX: x,
  			localRotationEulerY: y,
  			localRotationEulerZ: z,
  		};
  		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;
  	}
  	getNumberOfRunningActions() {
  		if (this._target) {
  			return TweenSystem.instance.ActionManager.getNumberOfRunningActionsInTarget(this._target);
  		}
  		return 0;
  	}
  	_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.setXY(locStartPosition.x + x, 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;
  	}
  }
  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 || (followTarge.owner && followTarge.owner.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.setXY(locStartPosition.x + x, 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);
  	}
  	update(t) {
  		t = this._computeEaseTime(t);
  		if (this.target) {
  			var pos = Vec2.TEMP;
  			BezierTo.lerpPath(this._path, t, pos);
  			var target = this.target;
  			target.setXY(pos.x, pos.y);
  		}
  	}
  	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 BezierV3To extends ActionInterval {
  	constructor(duration, points) {
  		super();
  		this.initWithDuration(duration, points);
  	}
  	initWithDuration(duration, points) {
  		if (super.initWithDuration(duration)) {
  			this.p1 = points[0];
  			this.p2 = points[1];
  			this.p3 = points[2];
  			return true;
  		}
  		return false;
  	}
  	clone() {
  		console.error("暂无clone实现，偷懒而已");
  		return null;
  	}
  	startWithTarget(target) {
  		super.startWithTarget(target);
  	}
  	update(t) {
  		t = this._computeEaseTime(t);
  		if (this.target) {
  			let pos = BezierV3To.bezierCurveMotionV3(this.p1, this.p2, this.p3, t);
  			this.target.position = pos;
  		}
  	}
  	reverse() {
  		console.error("暂无reverse实现，偷懒而已");
  		return null;
  	}
  	static bezierCurveMotionV3(pos1, pos2, pos3, f) {
  		let cp1x = pos1.x * (1 - f) + pos2.x * f;
  		let cp1y = pos1.y * (1 - f) + pos2.y * f;
  		let cp1z = pos1.z * (1 - f) + pos2.z * f;
  		let cp2x = pos2.x * (1 - f) + pos3.x * f;
  		let cp2y = pos2.y * (1 - f) + pos3.y * f;
  		let cp2z = pos2.z * (1 - f) + pos3.z * f;
  		let x = cp1x * (1 - f) + cp2x * f;
  		let y = cp1y * (1 - f) + cp2y * f;
  		let z = cp1z * (1 - f) + cp2z * f;
  		return new Laya.Vector3(x, y, z);
  	}
  }
  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 || (lookAtTarge.owner && lookAtTarge.owner.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 || (followTarge.owner && followTarge.owner.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.setXY(Mathf.lerp(target.x, p.x, 0.1), Mathf.lerp(target.y, p.y, 0.1));
  				}
  			}
  		}
  	}
  }
  Follow2D.temp_point = new Laya.Point();

  var cc$1;
  (function (cc) {
  	function tween(target, clearBefore = true) {
  		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 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 bezierV3To(duration, points) {
  		return new BezierV3To(duration, points);
  	}
  	cc.bezierV3To = bezierV3To;
  	function bezierFromTo(duration, from, to, radiusRate = 0.5) {
  		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, 10);
  	}
  	cc.bezierFromTo = bezierFromTo;
  	function follow2d(target, duration = 0, offset) {
  		return new Follow2D(duration, target, offset);
  	}
  	cc.follow2d = follow2d;
  	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 = {}));

  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);
  	}
  	clearCallback() {
  		this._callbackList = [];
  	}
  	setEventData(node, animId) {
  		this._node = node;
  		this._animId = animId;
  	}
  	onStateEnter() {
  		if (this._node.destroyed || !this._node.scene)
  			return;
  		this._node.event("Enter", this._animId);
  		this._startTime = Timer.time;
  	}
  	onStateUpdate() {
  		if (this._node.destroyed || !this._node.scene) {
  			this._callbackList = [];
  			return;
  		}
  		let deltaTime = Timer.time - this._startTime;
  		for (let i = this._callbackList.length - 1; i >= 0; i--) {
  			const callInfo = this._callbackList[i];
  			if (callInfo) {
  				if (callInfo.time <= deltaTime) {
  					callInfo.callback();
  					this._callbackList.splice(i, 1);
  				}
  			}
  		}
  	}
  	onStateExit() {
  		if (this._node.destroyed || !this._node.scene) {
  			this._callbackList = [];
  			return;
  		}
  		this._node.event("Exit", this._animId);
  		for (let i = this._callbackList.length - 1; i >= 0; i--) {
  			const callInfo = this._callbackList[i];
  			if (callInfo) {
  				callInfo.callback();
  			}
  		}
  		this._callbackList = [];
  	}
  }
  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.allAnimStateScripts = [];
  		this.modelId = modelId;
  		this.name = modelId;
  		this.modelDb = db.get_model_db(modelId);
  		if (!this.modelDb)
  			return;
  		this.sourceName = this.modelDb.resPath;
  		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. this.modelId=", this.modelId);
  			return;
  		}
  		this._isLoading = true;
  		ResLoader.loadRes(this.sourceName, this.resourceType, (res) => {
  			this.onResLoaded(res);
  		});
  	}
  	onResLoaded(res) {
  		Model.allLoadedModelIds[this.modelId] = true;
  		this._isLoading = false;
  		if (res) {
  			if (!this.destroyed) {
  				this._isLoaded = true;
  				this.onResourceLoaded(res);
  				if (!this.destroyed)
  					this.processDelayCalls();
  			}
  		}
  		else {
  			this.onResourceLoadedFail();
  		}
  	}
  	onResourceLoadedFail() {
  		console.warn("资源加载失败:", this.sourceName);
  	}
  	static destroyRes(modelId) {
  		let modelData = db.get_model_db(modelId);
  		let res = Laya.loader.getRes(modelData.resPath);
  		if (res) {
  			res.destroy();
  		}
  	}
  	onResourceLoaded(res) {
  		this.resNode = Laya.Sprite3D.instantiate(res);
  		this.resNode.active = true;
  		this._animtor = this.resNode.getComponent(Laya.Animator);
  		this.addChild(this.resNode);
  		this.resNode.transform.localScale = new Laya.Vector3(1, 1, 1);
  		this.resNode.transform.localPosition = new Laya.Vector3;
  		this.resNode.transform.localRotationEuler = new Laya.Vector3;
  		this.initFaceAnimator();
  		mgrMaterial.precompileShaderByPanelName(this.modelId);
  		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;
  		for (let i = 0; i < this.allAnimStateScripts.length; i++) {
  			const element = this.allAnimStateScripts[i];
  			element.clearCallback();
  		}
  	}
  	unuse() {
  		this._curAnimId = "";
  		this._clearAnimList();
  		this.setSpeed(0);
  		this.removeSelf();
  		cc$1.tween(this.transform).to(0.0, {}).start();
  		this.transform.localPosition = new Laya.Vector3(0, 0, 0);
  		this.transform.localRotationEuler = new Laya.Vector3(0, 0, 0);
  		this.transform.localScale = new Laya.Vector3(1, 1, 1);
  		let renders = Tools.findAllMeshRenderers(this, null, true);
  		if (!!renders && renders.length > 0) {
  			for (let i = 0; i < renders.length; i++) {
  				let rendrer = renders[i];
  				for (let tmp in rendrer.sharedMaterials) {
  					let mat = rendrer.sharedMaterials[tmp];
  					mat.albedoColor = new Laya.Vector4(1, 1, 1, 1);
  				}
  				rendrer.sharedMaterials = rendrer.sharedMaterials;
  			}
  		}
  		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;
  		if (this._animtor.getControllerLayer(0) && this._animtor.getControllerLayer(0).getAnimatorState(animId)) {
  			this._animStates[animId] = AnimLoadState.Loaded;
  			let state = this._animtor.getControllerLayer(0).getAnimatorState(animId);
  			if (!state.getScript(AnimStateScript)) {
  				let script = state.addScript(AnimStateScript);
  				this.allAnimStateScripts.push(script);
  				script.setEventData(this, animId);
  			}
  		}
  		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) {
  					let animDb = db.get_animation_db(animId);
  					if (animDb) {
  						this._animStates[animId] = AnimLoadState.Loading;
  						ResLoader.loadRes(animDb.path, RES_TYPE.ANIMATIONCLIP, (clip) => {
  							if (this.destroyed)
  								return;
  							this.addAnimatorState(animId, clip);
  							this._playAnimOnloaded(animId, transitionDuration, normalizedTime, loop);
  						});
  					}
  				}
  				else {
  					this._playAnimOnloaded(null, transitionDuration, normalizedTime, loop);
  				}
  				break;
  			case AnimLoadState.Loading:
  				break;
  		}
  	}
  	addAnimatorStateById(animId) {
  		if (this._animtor.getControllerLayer(0).getAnimatorState(animId)) {
  			return;
  		}
  		let animDb = db.get_animation_db(animId);
  		let clip = ResLoader.tryLoadRes(animDb.path);
  		if (clip) {
  			this.addAnimatorState(animId, clip);
  		}
  		else {
  			console.error(`Model.addAnimatorStateById: 动画未加载:${animId}`);
  		}
  	}
  	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;
  		let script = state.addScript(AnimStateScript);
  		this.allAnimStateScripts.push(script);
  		script.setEventData(this, animId);
  		if (this.aniDelayCalls[animId]) {
  			for (let i = 0; i < this.aniDelayCalls[animId].length; i++) {
  				const element = this.aniDelayCalls[animId][i];
  				script.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.scene)
  			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) {
  		console.log(`aniId: ${animId}: ${this._curAnimId}`);
  		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;
  		for (let i = 0; i < this.allAnimStateScripts.length; i++) {
  			const element = this.allAnimStateScripts[i];
  			element.clearCallback();
  		}
  	}
  	simulate(animId, normalizedTime) {
  		if (!this.callable) {
  			this.safeCall(this.simulate, animId, normalizedTime);
  			return;
  		}
  		this._clearAnimList();
  		this._checkAnimAndPlay(animId, 0, normalizedTime, false);
  	}
  	initFaceAnimator() {
  		let child = Tools.findChildByPath(this.resNode, "Bip001/Bip001 Pelvis/Bip001 Spine/Bip001 Spine1/Bip001 Neck/Bip001 Head/spirit_lian");
  		if (child) {
  			this.faceAnimator = child.getComponent(Laya.Animator);
  		}
  	}
  	playFaceAnim(animName, callback) {
  		if (this.faceAnimator == null) {
  			this.initFaceAnimator();
  		}
  		if (this.faceAnimator == null) {
  			return;
  		}
  		let animatorState = this.faceAnimator.getControllerLayer(0).getAnimatorState(animName);
  		if (animatorState) {
  			let clip = animatorState.clip;
  			this.faceAnimator.play(animName, 0, 0);
  			if (this.faceBackTimer) {
  				this.faceBackTimer.stop();
  			}
  			if (!clip.islooping) {
  				this.faceBackTimer = Timer.callLater(clip.duration(), () => {
  					callback();
  				}, this);
  			}
  		}
  		else {
  			let animationData = db.get_animation_db(animName);
  			if (!animationData) {
  				return;
  			}
  			Laya.AnimationClip.load(animationData.path, new Laya.Handler(this, (clip) => {
  				let __temp = this.faceAnimator.getControllerLayer(0).getAnimatorState(animName);
  				if (__temp)
  					return;
  				animatorState = new Laya.AnimatorState();
  				animatorState.clip = clip;
  				animatorState.clipStart = 0;
  				animatorState.clipEnd = 1;
  				animatorState.name = animName;
  				this.faceAnimator.getControllerLayer(0).addState(animatorState);
  				this.faceAnimator.play(animName);
  			}));
  		}
  	}
  	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() {
  		if (this.destroyed)
  			return;
  		switch (arguments.length) {
  			case 0:
  				Logger.error("safeCall 参数不能为空");
  				break;
  			default:
  				this._safeCallN.apply(this, arguments);
  				break;
  		}
  	}
  	_safeCallN(method, ...ps) {
  		if (this._isLoaded) {
  			method.call(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, caller) {
  		if (this.destroyed)
  			return;
  		if (this.isLoaded) {
  			this.callDelayFunc(func, caller);
  		}
  		else {
  			this.pushDelayCall(this.callDelayFunc, [func, caller]);
  		}
  	}
  	callDelayFunc(func, caller) {
  		if (!caller)
  			return;
  		if (caller.destroyed)
  			return;
  		if (func) {
  			func();
  		}
  	}
  	get callable() {
  		return this._isLoaded && !this.destroyed;
  	}
  	set timeScale(value) {
  		if (!this._animtor)
  			return;
  		this._animtor.speed = value;
  	}
  	get timeScale() {
  		if (!this._animtor)
  			return 1;
  		return this._animtor.speed;
  	}
  }
  Model.allLoadedModelIds = {};

  class Spine extends Laya.Sprite {
  	constructor(path, loadedCallback, frameRate = 60, cacheMode = 0) {
  		super();
  		this.path = path;
  		this.loadedCallback = loadedCallback;
  		this.frameRate = frameRate;
  		this.cacheMode = cacheMode;
  		let templet = Spine.allTemplets[path];
  		let bLoading = !!Spine.loadingTemplets[path];
  		if (templet && !bLoading) {
  			this.templet = templet;
  			this.parseComplete();
  			return;
  		}
  		else {
  			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;
  				this.templet.lock = true;
  				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;
  			}
  		}
  	}
  	onError() {
  		console.log("骨骼动画初始化 parse error");
  	}
  	parseComplete() {
  		console.log(`骨骼动画初始化 成功!!!:${this.path}:${this.playingAnimationName}`);
  		this.bLoaded = true;
  		Spine.allTemplets[this.path] = this.templet;
  		Spine.loadingTemplets[this.path] = null;
  		if (this.destroyed) {
  			return;
  		}
  		let skeleton;
  		skeleton = this.templet.buildArmature(2);
  		skeleton.showSkinByName("normal");
  		this.addChild(skeleton);
  		this.skeleton = skeleton;
  		this.skeleton.player.cacheFrameRate = this.frameRate;
  		if (this.playingAnimationName)
  			this.playAnimation(this.playingAnimationName, this.bPlayingLoop, this.playEndCallback);
  		if (this.playingBackRate)
  			this.playbackRate = this.playingBackRate;
  		this.loadedCallback && this.loadedCallback(this);
  	}
  	playAnimation(name, loop = true, playEndCallback, speed = 1) {
  		this.bPlayingLoop = loop;
  		this.playingAnimationName = name;
  		this.playEndCallback = playEndCallback;
  		if (!this.bLoaded)
  			return;
  		this.skeleton.play(this.playingAnimationName, loop, true, 0);
  		this.skeleton.playbackRate(speed);
  		if (!loop && this.playEndCallback) {
  			this.callbackTimer = Timer.callLater(this.skeleton.player.playDuration / 1000 / speed, () => {
  				this.callbackTimer = null;
  				if (name !== this.playingAnimationName)
  					return;
  				let temp = this.playEndCallback;
  				this.playEndCallback = null;
  				temp && temp();
  			}, this);
  		}
  	}
  	clearEndCallback() {
  		this.playEndCallback = null;
  		this.callbackTimer && this.callbackTimer.stop();
  		this.callbackTimer = null;
  	}
  	set playbackRate(value) {
  		this.playingBackRate = value;
  		if (!this.bLoaded)
  			return;
  		this.skeleton.playbackRate(this.playingBackRate);
  	}
  	static create(spineId, loadedCallback, frameRate = 60, cacheMode = 0) {
  		let spineData = db.get_spine_db(spineId);
  		if (!spineData)
  			return null;
  		let spine = new Spine(spineData.resPath, loadedCallback, frameRate, cacheMode);
  		spine.name = spineId;
  		return spine;
  	}
  	setXY(x, y) {
  		this.pos(x, y);
  	}
  	getAnimDuration(animName) {
  		if (!this.bLoaded)
  			return;
  		let anis = this.templet[`_anis`];
  		for (let i = 0; i < anis.length; i++) {
  			const element = anis[i];
  			if (element.name == animName) {
  				return element.playTime / 1000;
  			}
  		}
  		return 0;
  	}
  }
  Spine.allTemplets = {};
  Spine.loadingTemplets = {};

  const KEY_POOL_ID = "__pool_id";
  const KEY_POOL_KEY = "__pool_key";
  const KEY_FLAG_IN_POOL = "__pool_flag_inpool";
  const DEBUG_AUTO_RELEASE = false;
  const AUTO_RELEASE_ENABLED = true;
  const MODEL_AUTO_RELEASE_THRESHOLD = 30;
  const MODEL_SOURCE_DESTROY_CD = 30;
  class PoolStack {
  	constructor(poolKey) {
  		this.m_queue = new Queue(16, true);
  		this.m_referenceCount = 0;
  		this.m_lastUseTime = 0;
  		this.m_poolKey = poolKey;
  	}
  	get length() {
  		return this.m_queue.size;
  	}
  	push(t) {
  		this.m_queue.enqueue(t);
  	}
  	pop() {
  		return this.m_queue.dequeue();
  	}
  	get(index) {
  		return this.m_queue.indexOf(index);
  	}
  	retain() {
  		this.m_referenceCount++;
  		this.m_lastUseTime = Timer.now;
  	}
  	release() {
  		this.m_referenceCount--;
  		this.m_lastUseTime = Timer.now;
  	}
  	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(poolKey);
  			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;
  	}
  	isFromPool(reuseNode) {
  		if (!reuseNode) {
  			Logger.warn("PoolManager.isFromPool node is nil!");
  			return false;
  		}
  		let poolId = reuseNode[KEY_POOL_ID];
  		let poolKey = reuseNode[KEY_POOL_KEY];
  		if (poolId == undefined) {
  			Logger.warn("PoolManager.isFromPool obj[KEY_POOL_ID] not found!");
  			return false;
  		}
  		if (!poolKey) {
  			Logger.warn("PoolManager.isFromPool obj[KEY_POOL_KEY] not found!");
  			return false;
  		}
  		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();
  						}
  					}
  				}
  			}
  		}
  	}
  	autoReleaseRes() {
  		console.log("autoReleaseRes.b_auto_release_enabled===", db.cop_db.b_auto_release_enabled);
  		if (!db.cop_db.b_auto_release_enabled)
  			return;
  		DEBUG_AUTO_RELEASE && console.log("autoReleaseRes");
  		if (Laya.loader["_loaderCount"] > 0) {
  			DEBUG_AUTO_RELEASE && console.log("LoaderManager is busy, ignore release res");
  			return;
  		}
  		this.autoReleaseModelRes();
  		this.releaseUnuseResFromLoader();
  		this.releaseUnusedPrefab();
  		for (let i = 0; i < fgui.UIPackage.packages.length; i++) {
  			const pkg = fgui.UIPackage.packages[i];
  			if (!pkg.bReferenced && Timer.now - pkg.__auto_release_lastActiveTime > MODEL_AUTO_RELEASE_THRESHOLD) {
  				fgui.UIPackage.removePackage(pkg.name);
  			}
  		}
  		Laya.Resource.destroyUnusedResources();
  		Tools.forEachMap(Spine["allTemplets"], (key, templet) => {
  			if (templet.destroyed) {
  				DEBUG_AUTO_RELEASE && console.log("清理被卸载的Templets", key);
  				delete Spine["allTemplets"][key];
  			}
  		});
  	}
  	autoReleaseModelRes() {
  		let poolId = Model[KEY_POOL_ID];
  		if (poolId == null) {
  			return;
  		}
  		let pools = this.pools[poolId];
  		let poolArrays = [];
  		Tools.forEachMap(pools, (k, v) => {
  			poolArrays.push(v);
  		});
  		poolArrays = Tools.sortArrayByField(poolArrays, ["-referenceCount", "-m_lastUseTime"]);
  		for (let i = 0; i < poolArrays.length; i++) {
  			const pool = poolArrays[i];
  			if (Timer.now - pool.m_lastUseTime < MODEL_SOURCE_DESTROY_CD) {
  				continue;
  			}
  			if (pool.referenceCount == 0 && i >= MODEL_AUTO_RELEASE_THRESHOLD) {
  				let bAllLoaded = true;
  				for (let __elementIndex = 0; __elementIndex < pool.length; __elementIndex++) {
  					const element = pool.get(__elementIndex);
  					if (!element.isLoaded) {
  						bAllLoaded = false;
  						break;
  					}
  				}
  				if (bAllLoaded) {
  					this.clean(Model, pool.m_poolKey);
  					Model.destroyRes(pool.m_poolKey);
  				}
  			}
  		}
  	}
  	releaseUnuseResFromLoader() {
  		let atlasMap = Laya.Loader.atlasMap;
  		for (const key in atlasMap) {
  			if (Object.prototype.hasOwnProperty.call(atlasMap, key)) {
  				const arr = atlasMap[key];
  				let bHasReference = false;
  				for (let i = 0; i < arr.length; i++) {
  					var resUrl = arr[i];
  					var tex = Laya.Loader.getRes(resUrl);
  					if (tex) {
  						if (tex.lock || tex._referenceCount > 0) {
  							bHasReference = true;
  							break;
  						}
  					}
  				}
  				if (!bHasReference) {
  					DEBUG_AUTO_RELEASE && console.log("Laya.Loader.clearRes unuse atlas", key);
  					Laya.Loader.clearRes(key);
  				}
  			}
  		}
  	}
  	releaseUnusedPrefab() {
  		Tools.forEachMap(Laya.Loader.loadedMap, (k, v) => {
  			if (v && v instanceof Laya.Prefab && v._referenceCount <= 0) {
  				DEBUG_AUTO_RELEASE && console.log("Laya.Loader.clearRes unused prefab", k);
  				Laya.Loader.clearRes(k);
  			}
  		});
  	}
  	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 = "130";
  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;

  const RECORD_DATA_KEY = "record_v2_game" + Global.GAME_ID;
  const RECORD_AGE_KEY = "__age__";
  const RECORD_VERSION_KEY = "__version__";
  const RECORD_FILES_KEY = "__files__";
  class FileRecord {
  	static init() {
  		this._readRecord();
  		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);
  	}
  	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;
  		}
  	}
  }
  FileRecord.record = {};
  FileRecord.bNeedFlush = false;
  FileRecord.writeEnable = true;
  FileRecord.isNewRecord = false;
  FileRecord.compressEnable = false;

  class _mBase {
  	onStart() {
  	}
  }

  const DEFAULT_TARGET_ID = "_default_";
  class mGoal extends _mBase {
  	constructor() {
  		super(...arguments);
  		this.m_data = null;
  	}
  	onLoad() {
  		this.loadRecord();
  		if (!this.m_data) {
  			this.m_data = {
  				goalList: {},
  			};
  		}
  	}
  	loadRecord() {
  		this.m_data = FileRecord.getData("s_goal_data");
  	}
  	saveRecord() {
  		FileRecord.setData("s_goal_data", this.m_data);
  	}
  	getGoalList(actionId, targetId, createIfNotExists) {
  		let actionList = this.m_data[actionId];
  		if (!actionList) {
  			if (createIfNotExists) {
  				actionList = {};
  				this.m_data[actionId] = actionList;
  				this.saveRecord();
  			}
  			else {
  				return null;
  			}
  		}
  		targetId = targetId || DEFAULT_TARGET_ID;
  		if (!actionList[targetId]) {
  			if (createIfNotExists) {
  				actionList[targetId] = {};
  				this.saveRecord();
  			}
  			else {
  				return null;
  			}
  		}
  		return actionList[targetId];
  	}
  	register(goalId, userData) {
  		let goalDb = db.get_goal_db(goalId);
  		if (!goalDb)
  			return;
  		let targetId;
  		if (goalDb.targetId == "") {
  			targetId = DEFAULT_TARGET_ID;
  		}
  		else {
  			targetId = goalDb.targetId;
  		}
  		let goalList = this.getGoalList(goalDb.actionId, targetId, true);
  		if (goalList[goalId]) {
  			if (goalDb.bReset == false) {
  				console.warn(`mGoal.registerGold: goal[${goalId}] is registered and it will be not reset!!!`);
  			}
  			else {
  				console.warn(`mGoal.registerGold: goal[${goalId}] is registered and it will be reset!!!`);
  				goalList[goalId] = { userData: userData, commits: 0 };
  			}
  		}
  		else {
  			goalList[goalId] = { userData: userData, commits: 0 };
  		}
  		this.saveRecord();
  	}
  	unregister(goalId) {
  		let goalDb = db.get_goal_db(goalId);
  		if (!goalDb)
  			return;
  		if (!goalDb.bReset)
  			return;
  		let goalList = this.getGoalList(goalDb.actionId, goalDb.targetId, false);
  		if (goalList) {
  			if (goalList[goalId]) {
  				delete goalList[goalId];
  				this.saveRecord();
  			}
  		}
  	}
  	commit(actionId, count = 1, targetId, mode = 0) {
  		if (targetId === "" || targetId == null) {
  			targetId = DEFAULT_TARGET_ID;
  		}
  		else {
  			targetId = targetId + "";
  		}
  		if (targetId != DEFAULT_TARGET_ID) {
  			this.commit(actionId, count, DEFAULT_TARGET_ID, mode);
  		}
  		let goalList = this.getGoalList(actionId, targetId, false);
  		if (!goalList)
  			return;
  		let goalDb, lastDoneState;
  		Tools.forEachMap(goalList, (goalId, goalItem) => {
  			goalDb = db.get_goal_db(goalId);
  			if (goalDb) {
  				lastDoneState = this._isDone(goalItem.commits, goalDb.value, goalDb.type);
  				switch (mode) {
  					case 0:
  						goalItem.commits += count;
  						break;
  					case 1:
  						goalItem.commits = count;
  						break;
  					case 2:
  						goalItem.commits = Math.max(goalItem.commits, count);
  						break;
  				}
  				if (goalItem.userData) {
  					let curDoneState = this._isDone(goalItem.commits, goalDb.value, goalDb.type);
  					if (curDoneState != lastDoneState) {
  						let event = Global.pool.getObject("GoalStateChangeEvent");
  						event.userData = goalItem.userData;
  						event.goalId = goalId;
  						event.isDone = curDoneState;
  						Global.sendMsg(BASE_MSG.GOAL_STATE_CHANGE, event);
  						Global.pool.put(event);
  					}
  				}
  				this.saveRecord();
  			}
  		});
  	}
  	_isDone(commits, value, type) {
  		if (type == "min") {
  			return commits >= value;
  		}
  		else if (type == "max") {
  			return commits <= value;
  		}
  		else {
  			console.error(`can't find goal type ${type}`);
  		}
  		return false;
  	}
  	isDone(goalId) {
  		let goalDb = db.get_goal_db(goalId);
  		if (!goalDb)
  			return false;
  		let commits = this.getCurValue(goalId);
  		return this._isDone(commits, goalDb.value, goalDb.type);
  	}
  	getCurValue(goalId) {
  		let goalDb = db.get_goal_db(goalId);
  		if (!goalDb)
  			return 0;
  		let goalList = this.getGoalList(goalDb.actionId, goalDb.targetId, false);
  		if (!goalList) {
  			return 0;
  		}
  		let goal = goalList[goalId];
  		if (!goal) {
  			console.warn(`can't find goal entry by entryId ${goalId}`);
  			return 0;
  		}
  		return goal.commits;
  	}
  	getDbValue(goalId) {
  		let goalDb = db.get_goal_db(goalId);
  		if (!goalDb)
  			return 0;
  		return goalDb.value;
  	}
  	getDeltaValue(goalId) {
  		let cur = this.getCurValue(goalId);
  		let dbValue = this.getDbValue(goalId);
  		return dbValue - cur;
  	}
  	getProgress(goalId) {
  		let cur = this.getCurValue(goalId);
  		let dbValue = this.getDbValue(goalId);
  		if (dbValue > 0) {
  			return Mathf.clamp01(cur / dbValue);
  		}
  		else {
  			return 0;
  		}
  	}
  	exists(goalId) {
  		let goalDb = db.get_goal_db(goalId);
  		if (!goalDb)
  			return false;
  		let goalList = this.getGoalList(goalDb.actionId, goalDb.targetId, false);
  		if (!goalList) {
  			return false;
  		}
  		let goal = goalList[goalId];
  		return goal != null;
  	}
  }

  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;
  		if (!this.check(switchId))
  			return false;
  		let data = this.m_data[switchId];
  		data.count--;
  		if (data.count == 0) {
  			let switchDb = db.get_switch_db(switchId);
  			if (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);
  		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) {
  			BaseFacade.mGoal.register(switchDb.params, { type: GOAL_TYPE.SWITCH, data: switchDb.id });
  			recordData.startTime = LONG_DELTA_TIME;
  			recordData.endTime = recordData.startTime;
  		}
  		else {
  			BaseFacade.mGoal.unregister(switchDb.params);
  			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;
  	}
  }

  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);
  				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_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_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_SET_USER_CLOUD_STORAGE = '/c/setUserCloudStorage';
  ULConst.CMD_GET_USER_CLOUD_STORAGE = '/c/getUserCloudStorage';
  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_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_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_SET_USER_CLOUD_STORAGE_RESULT = '/c/setUserCloudStorageResult';
  ULConst.CMD_GET_USER_CLOUD_STORAGE_RESULT = '/c/getUserCloudStorageResult';
  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_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_TOUCH_SCREEN_END = "/sdk/touchScreenEnd";
  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_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_find_mini_game_mode": 0,
    "i_sdk_installShortcut_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": 1,
    "i_sdk_sdk_rank_mode": 0,
    "i_sdk_share_mode": 0,
    "i_sdk_support_open_url": 0,
    "i_sdk_support_record_share": 1,
    "i_sdk_trim_adv_err_switch": 1,
    "layaVersion": "2.8",
    "s_game_name": "小主攻略",
    "s_prj_name": "prj.game130",
    "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": "0",
    "s_sdk_cdk_url": "https://cdkey.ultralisk.cn/commoncdk/usecdk",
    "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_cop_addr": "https://copv7.ultralisk.cn/h5/getdata/",
    "s_sdk_cop_game_id": "72",
    "s_sdk_jump_game_statis_game_indexes": "",
    "s_sdk_lan_debug_address": "",
    "s_sdk_megadata_close_table_type_ids": "",
    "s_sdk_megadata_game_id": "260",
    "s_sdk_megadata_server_jump_game_type_id": "jumpabtest",
    "s_sdk_megadata_server_type_id": "260",
    "s_sdk_megadata_test_url": "https://megadatav7.ultralisk.cn/batchtestmodedataupload",
    "s_sdk_megadata_url": "https://megadatav7.ultralisk.cn/batchdataupload",
    "s_sdk_oppoqg_app_key": "85BhQe6Na2KGogcCc4gcgow8W",
    "s_sdk_oppoqg_appid": "30643179",
    "s_sdk_oppoqg_appsecret": "8eDf692Fe6Be80A078b5d475A75d2Ca4",
    "s_sdk_oppoqg_package_name": "com.ultralisk.game132.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/game130/oppoqg/v1",
    "s_sdk_oppoqg_version_code": "116",
    "s_sdk_oppoqg_version_name": "1.0.16",
    "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": "813c39f23",
    "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_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": ".*goroadface/.*"
        },
        {
            "cmds": "",
            "rep": ".*goqa/.*"
        },
        {
            "cmds": "",
            "rep": ".*_unity/res/Conventional/Assets/Artist/model/map/map01/sky.*"
        },
        {
            "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": {
        
    },
    "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_oppoqg_adv_tag_2_native_index": {
        
    },
    "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_inter_box_adv_tags": [
        
    ],
    "t_sdk_privacyPolicy_dataArray": [
        {
            "name": "隐私政策",
            "url": "https://gamesres.ultralisk.cn/notice/policy/oppoleishoupolicy.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||errCode": {
                "3010003": "您的网络好像不够流畅，请更换到良好的网络环境再播放广告。",
                "3010005||3010006": "正在为您播放广告，请稍等一会儿，不要重复点击。"
            }
        },
        "headline||weixin||qq": {
            "code||errCode": {
                "1004": "暂时没有适合您观看的广告，请稍等一会儿再试吧！"
            }
        },
        "oppoqg": {
            "(this.errCode==1001 || this.errCode == 1004)&&errMsg": {
                "/10001/||/10100/||/10101/||/10403/": "您的网络好像不够流畅，请更换到良好的网络环境再播放广告。",
                "/10405/": "您的操作系统版本太低，不能播放广告。",
                "/10406/": "需要连接到 Wifi 网络",
                "/11002/": "这个广告只能在OPPO手机上播放，请确认您的机型。",
                "/11003/": "暂时无法播放广告，请稍等一会儿再试吧1！"
            }
        },
        "vivo": {
            "code||errCode": {
                "-100||101||500": "您的网络好像不够流畅，请更换到良好的网络环境再播放广告。",
                "-3||108||30005": "暂时无法播放广告，请稍等一会儿再试吧！",
                "30007": "暂时无法播放广告，请稍等一会儿再试吧！",
                "30010": "广告播放失败了，可能是是由于您经常关闭广告造成的，稍等一会儿再试吧。"
            }
        }
    },
    "targetCreatorBranch": "",
    "targetCreatorExePath": "",
    "targetCreatorGitAddr": "",
    "targetProjectBranch": "v1_h5_release",
    "targetProjectGitAddr": "ude2/prj.game130",
    "tempCreatorProjectPaths": [
        [
            ".laya/",
            ".laya/"
        ],
        [
            "bin/",
            "bin/",
            [
                "**/vconsole.*"
            ]
        ],
        [
            "declare/",
            "declare/"
        ],
        [
            "laya/",
            "laya/"
        ],
        [
            "libs/",
            "libs/"
        ],
        [
            "node_modules/",
            "node_modules/"
        ],
        [
            "src/",
            "src/"
        ],
        [
            "package-lock.json",
            ""
        ],
        [
            "prj.game130.laya",
            ""
        ],
        [
            "tsconfig.json",
            ""
        ]
    ],
    "tempProjectName": "laya_proj",
    "autoUploadPack": true,
    "B_OBFUSCATOR_CCONFIG": false,
    "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.game132.nearme.gamecenter",
            "versionCode": "116",
            "versionName": "1.0.16"
        },
        "title": "小主攻略",
        "url_path": "https://gamesres.ultralisk.cn/h5_games_res/game130/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": "16612",
    "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": "2022-09-07 14:40:10 +0800-tangyuanlin-32449057e",
    "_target_last_commit_time": 1662532810,
    "prjVersion": "32449057e",
    "rootPath": "E:/ulwork/ulsdk/",
    "rootSdkPath": "E:/ulwork/ulsdk/prj.sdk.html5/",
    "gitRepoPath": "E:/ulwork/ulsdk/h5_games_res/",
    "taskDate": "2022_09_07",
    "taskTick": "2022_09_07_14_41_47",
    "taskTickShort": "0907_144147",
    "taskName": "oppo",
    "configName": "task_game130_xzgl_v1",
    "targetPath": "E:/ulwork/ulsdk/h5_out/30_oppo_0907_144147/",
    "resCachePath": "E:/ulwork/ulsdk/h5_res_cache/prj.game130/",
    "packagePath": "E:/ulwork/ulsdk/prj.games.html5.channels.packages/prj.game130/prj.game130_v1_h5_release_oppo_0907_144147/",
    "buildDisabled": false,
    "creatorExePath": "",
    "taskJsonPath": "E:/ulwork/ulsdk/prj.games.html5.channels.tasks/task_game130_xzgl_v1/task.json",
    "tempProjPath": "E:/ulwork/ulsdk/h5_out/30_oppo_0907_144147/laya_proj/",
    "moduleList": "common,build_laya_oppogame,oppoqg,privacyPolicy",
    "envCheckResult": [
        
    ]
}`);

  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) {
  		if (ULConst.B_INNER_DEBUG)
  			ULLog.console.log(ULTools.format("ULStorageManager.setStorage(%s, %s)", 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) {
  			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() {
  		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 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 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"] && 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 {
  					ULLog.console.warn("ULTools.httpGet on error:", xhr.readyState, xhr.status);
  					if (obj.fail instanceof Function)
  						obj.fail(xhr.status.toString());
  				}
  			}
  		};
  		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 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());
  				}
  			}
  		};
  		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 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 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());
  				}
  			}
  		};
  		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 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 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() {
  		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;
  		};
  		if (!this._console_log)
  			this._console_log = trim_console_func(1, console.log);
  		if (!this._console_warn)
  			this._console_warn = trim_console_func(2, console.warn);
  		if (!this._console_error)
  			this._console_error = trim_console_func(3, console.error);
  		if (window["cc"]) {
  			if (!this._cc_log)
  				this._cc_log = trim_console_func(1, window["cc"]["log"]);
  			if (!this._cc_warn)
  				this._cc_warn = trim_console_func(2, window["cc"]["warn"]);
  			if (!this._cc_error)
  				this._cc_error = trim_console_func(3, window["cc"]["error"]);
  		}
  		let config = ULConfig.getConfig();
  		console.log = (config.i_sdk_debug_mode < ULConst.CONSOLE_OUTPUT_LEVEL_LOG) ? () => { } : this._console_log;
  		console.warn = (config.i_sdk_debug_mode < ULConst.CONSOLE_OUTPUT_LEVEL_WARN) ? () => { } : this._console_warn;
  		console.error = (config.i_sdk_debug_mode < ULConst.CONSOLE_OUTPUT_LEVEL_ERROR) ? () => { } : this._console_error;
  		if (window["cc"]) {
  			window["cc"]["log"] = (config.i_sdk_debug_mode < ULConst.CONSOLE_OUTPUT_LEVEL_LOG) ? () => { } : this._cc_log;
  			window["cc"]["warn"] = (config.i_sdk_debug_mode < ULConst.CONSOLE_OUTPUT_LEVEL_WARN) ? () => { } : this._cc_warn;
  			window["cc"]["error"] = (config.i_sdk_debug_mode < ULConst.CONSOLE_OUTPUT_LEVEL_ERROR) ? () => { } : this._cc_error;
  		}
  	}
  	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;
  				};
  				ws.onerror = function (err) {
  					ULLog.console.error("Connection onerror:", err);
  					ULSdkManager.getInstance().moduleCheckerManager.removeDebugInfo("console_lan_id");
  					ULTools.socketingWS = null;
  				};
  			}
  			catch (error) {
  				ws = null;
  				ULLog.console.log("局域网调试错误:", JSON.stringify(error));
  			}
  			finally {
  				if (ws == null) {
  					return;
  				}
  				ULTools.socketingWS = ws;
  			}
  		}
  		else {
  			ULLog.console.log("不支持WebSocket局域网调试");
  		}
  	}
  	static _close_console_print_LAN() {
  		if (ULTools.socketingWS) {
  			ULTools.socketingWS.close();
  			ULTools.socketingWS = null;
  		}
  	}
  	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 };
  	}
  }
  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 = data.channelId;
  		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";
  	}
  	init() {
  		super.init();
  		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;
  		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);
  			},
  		});
  	}
  }

  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";
  		this.show = false;
  	}
  	init() {
  		super.init();
  		this.initSdk();
  	}
  	initSdk() {
  		ULLog.console.info("ULModulePrivacyPolicy-initSdk");
  		const msg = Laya.LocalStorage.getItem("huaweiMsg");
  		if (!msg) {
  			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", "666");
  					view.close();
  					// YYGMiniGames.showBanner()
  				});
  			}));
  		}
  		// 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();
  		ULSdkManager.getInstance().moduleCheckerManager.alertPrivacy("温馨提示", config.t_sdk_privacyPolicy_dataArray, ["返回"], [() => {
  		}]);
  	}
  	onCmdSetVersion(e) {
  		// 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);
  			callback(1, "执行成功");
  		}
  		else {
  			callback(0, "未找到对应配置");
  		}
  	}
  	showPrivacyPolicy() {
  		let hadSurePrivacy = ULStorageManager.getInstance().getStorage("hadSurePrivacy") || "0";
  		if (hadSurePrivacy == "0") {
  			let config = ULConfig.getConfig();
  			ULSdkManager.getInstance().moduleCheckerManager.alertPrivacy("温馨提示", config.t_sdk_privacyPolicy_dataArray, ["拒绝", "同意"], [() => {
  				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");
  							}
  						});
  						return true;
  					}
  					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");
  							}
  						});
  						return true;
  					}
  				}
  				ULLog.console.log("未配置 退出游戏 渠道");
  				return true;
  			}, () => {
  				ULStorageManager.getInstance().setStorage("hadSurePrivacy", "1");
  				ULSdkManager.getInstance().waits.removeCondition("privacy_agree");
  			}]);
  		}
  		else {
  			ULSdkManager.getInstance().waits.removeCondition("privacy_agree");
  		}
  	}
  }

  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() {
  		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() {
  		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 SYMBOL = {
  	"*": { order: 3, argCount: 2, handler: (a, b) => { return a * b; } },
  	"/": { order: 3, argCount: 2, handler: (a, b) => { return a / b; } },
  	"+": { order: 2, argCount: 2, handler: (a, b) => { return Number(a) + Number(b); } },
  	"-": { order: 2, argCount: 2, handler: (a, b) => { return a - b; } },
  	">=": { order: 1, argCount: 2, handler: (a, b) => { return a >= b; } },
  	">": { order: 1, argCount: 2, handler: (a, b) => { return a > b; } },
  	"<=": { order: 1, argCount: 2, handler: (a, b) => { return a <= b; } },
  	"<": { order: 1, argCount: 2, handler: (a, b) => { return a < b; } },
  	"==": { order: 0, argCount: 2, handler: (a, b) => { return a == b; } },
  	"!=": { order: 0, argCount: 2, handler: (a, b) => { return a != b; } },
  	"&&": { order: -1, argCount: 2, handler: (a, b) => { return a && b; } },
  	"||": { order: -1, argCount: 2, handler: (a, b) => { return a || b; } },
  };
  let SYMBOLKeysDic = {};
  Object.keys(SYMBOL).forEach((value) => {
  	SYMBOLKeysDic[value.length] = true;
  });
  let SYMBOLKeys = Object.keys(SYMBOLKeysDic).map(a => {
  	return Number(a);
  }).sort((a, b) => {
  	return b - a;
  });
  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) {
  		ULLog.console.log("ULAdvExpManager calcExp:", exp);
  		return ULAdvExpManager.getInstance().calcExpResults(exp);
  	}
  	static updateExpValue(expKey) {
  		ULAdvExpManager.getInstance().setStoreValue(expKey);
  	}
  	trimCalcExp(exp) {
  		exp = exp.replace(/\s/g, "");
  		let expArray = exp.split("");
  		let value = "";
  		let expCache = [];
  		let symbolCache = [];
  		let rightParenthesis = 0;
  		let expCacheString = "";
  		while (expArray.length) {
  			let char = expArray.pop();
  			switch (char) {
  				case "(":
  					{
  						rightParenthesis--;
  						expCacheString = char + expCacheString;
  						if (rightParenthesis == 0) {
  							expCacheString = expCacheString.substring(1, expCacheString.length - 1);
  							expCache = expCache.concat(this.trimCalcExp(expCacheString).reverse());
  							expCacheString = "";
  							continue;
  						}
  					}
  					break;
  				case ")":
  					{
  						rightParenthesis++;
  						expCacheString = char + expCacheString;
  					}
  					break;
  				default: {
  					if (rightParenthesis != 0) {
  						expCacheString = char + expCacheString;
  						continue;
  					}
  					let symbol = null;
  					for (let i = 0; i < SYMBOLKeys.length; i++) {
  						let length = SYMBOLKeys[i] - 1;
  						if (expArray.length > length) {
  							let key = expArray.slice(expArray.length - length, expArray.length) + char;
  							if (SYMBOL[key]) {
  								char = key;
  								symbol = SYMBOL[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 = SYMBOL[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;
  	}
  	calcExpResults(exp) {
  		try {
  			let numArray = this.trimCalcExp(exp);
  			if (numArray.length == 0) {
  				return true;
  			}
  			ULLog.console.log("ULAdvExpManager calcExpResults numArray:", numArray);
  			let resultArray = [];
  			while (numArray.length) {
  				let key = numArray.pop();
  				let value = SYMBOL[key];
  				if (value) {
  					let num1 = Number(resultArray.pop());
  					let num2 = Number(resultArray.pop());
  					let result = value.handler(num1, num2);
  					resultArray.push(result);
  				}
  				else {
  					let trimKey = this.getCalcExpValue(key);
  					ULLog.console.log(`ULAdvExpManager calcExpResults getCalcExpValue ${key}:${trimKey}`);
  					resultArray.push(trimKey);
  				}
  			}
  			ULLog.console.log("ULAdvExpManager calcExpResults result:", resultArray[0]);
  			return Boolean(resultArray[0]);
  		}
  		catch (error) {
  			ULLog.console.warn("ULAdvExpManager exp规则错误：", exp);
  			return false;
  		}
  	}
  	_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) {
  		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.");
  			let string = "if (" + trimRule + ") { judge = true } else { judge = false }";
  			try {
  				var judge = false;
  				eval(string);
  				return judge;
  			}
  			catch (error) {
  				ULLog.console.log(error);
  				return false;
  			}
  		}
  		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);
  		}
  	}
  	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 objectBases = this.advType_2_advObjectArray[advType];
  		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;
  		}
  		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();
  		}
  		ULSdkManager.getInstance().response(ULConst.CMD_OPEN_ADV_RESULT, returnData);
  	}
  	responseRewardAdvResult(data, code, msg) {
  		ULSdkManager.getInstance().response(ULConst.CMD_REWARD_ADV_RESULT, {
  			code: code,
  			msg: msg,
  			advId: data.advId || "",
  			userData: data.userData || "",
  			tag: data.tag || ""
  		});
  	}
  	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);
  	}
  	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;
  			ULSdkManager.getInstance().statisManager.reportAdvSuccess(advItem, title);
  		}
  	}
  	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() {
  		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) {
  		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.showBannerGameBoxTags = {};
  		this.statisticsAdvertiser = "ULAdvOppoQgBannerBox";
  	}
  	onDisposeModule() {
  		super.onDisposeModule();
  		ULLog.console.log("ULAdvOppoQgBannerBox-onDisposeModule arg:", this.arg);
  		if (this.gameBannerAd) {
  			this.gameBannerAd.offShow();
  			this.gameBannerAd.offLoad();
  			this.gameBannerAd.offError();
  			this.gameBannerAd.destroy();
  			this.gameBannerAd = null;
  		}
  	}
  	initAdv() {
  		ULLog.console.log("ULAdvOppoQgBannerBox-initAdv");
  		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 bannerTags = config.t_sdk_oppoqg_show_banner_box_adv_tags || [];
  		for (let index = 0; index < bannerTags.length; index++) {
  			let tag = bannerTags[index];
  			this.showBannerGameBoxTags[tag] = true;
  		}
  		ULLog.console.log("ULAdvOppoQgBannerBox showBannerGameBoxTags:", this.showBannerGameBoxTags);
  	}
  	loadAdv() {
  	}
  	showAdv(data) {
  		if (this.preLoadState != ULConst.ADV_PRELOAD_STATE_READY) {
  			console.warn("ULAdvOppoQgBannerBox-showAdv:广告未加载就绪,直接跳过当前广告展示");
  			this.advSkip(data, { code: "", msg: "adv not ready" });
  			return;
  		}
  		if (qg$3.getSystemInfoSync().platformVersionCode < 1076) {
  			ULLog.console.log('ULAdvOppoQgBannerBox-showAdv:快应用平台版本号低于1076，暂不支持互推盒子相关 API');
  			this.advSkip(data, { code: "", msg: "api unsupport" });
  			return;
  		}
  		let tag = data["tag"] || "";
  		if (!this.showBannerGameBoxTags[tag]) {
  			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 = qg$3.createGameBannerAd({
  				adUnitId: this.arg
  			});
  			if (!this.gameBannerAd) {
  				ULLog.console.log('ULAdvOppoQgBannerBox-showAdv:广告对象创建失败，请检查参数配置');
  				this.advSkip(this.showData, { code: "", msg: "obj create fail" });
  				return;
  			}
  			this.gameBannerAd.offLoad(() => {
  				ULLog.console.log("ULAdvOppoQgBannerBox-showAdv-offLoad");
  			});
  			this.gameBannerAd.offError(() => {
  				ULLog.console.log("ULAdvOppoQgBannerBox-showAdv-offError");
  			});
  			this.gameBannerAd.onLoad(() => {
  				ULLog.console.log("ULAdvOppoQgBannerBox-showAdv-onLoad");
  				ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestSuccess(this.advKey);
  			});
  			this.gameBannerAd.onError((err) => {
  				ULLog.console.log("ULAdvOppoQgBannerBox-showAdv-onError:", err);
  				ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequestFailed(this.advKey, { code: String(err.errCode), msg: err.errMsg });
  			});
  		}
  		ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleRequest(this.advKey);
  		this.gameBannerAd.show().then(() => {
  			ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleShow(this.advKey, ULConst.ADV_RESULT_MSG_SUCCESS, this.showData);
  			ULSdkManager.getInstance().advManager.onAdvObjectLifeCycleClose(this.advKey, data);
  		}).catch((error) => {
  			ULLog.console.log("ULAdvOppoQgBannerBox-showAdv-show-catch:", error);
  			this.isOpened = false;
  			let errMsg = error.errCode + ',' + error.errMsg;
  			this.advSkip(this.showData, { 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) {
  		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) {
  		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) {
  		Advertisement.insertAdverV2();
  		console.info("777777777777777777777777777777777777777777777777777");
  		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) {
  		// Advertisement.insertAdverV2();
  		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) {
  		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.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.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.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.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.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.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:初始化失败");
  		}
  	}
  }

  let qg$c = window["qg"];
  class ULModuleOppoQg extends ULChannelModuleBase {
  	constructor() {
  		super(...arguments);
  		this.className = "ULModuleOppoQg";
  		this.manualCloseBannerCount = 0;
  		this.lastDailyResetTime = 0;
  		this.openId = null;
  	}
  	getSubAdModuleClassName() {
  		return ["ULAdvOppoQgInter", "ULAdvOppoQgBanner", "ULAdvOppoQgVideo", "ULAdvOppoQgBannerBox", "ULAdvOppoQgPortalBox", "ULAdvOppoQgNativeBanner", "ULAdvOppoQgNativeInter", "ULAdvOppoQgNativeEmbed", "ULAdvOppoQgAutoNativeBanner", "ULAdvOppoQgAutoNativeInter", "ULAdvOppoQgAutoNativeEmbed"];
  	}
  	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;
  			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_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$c.getLaunchOptionsSync();
  		let referrerInfo = options && (options.referrerInfo || {});
  		if (JSON.stringify(referrerInfo) != "{}") {
  			ULSdkManager.getInstance().statisManager.setGameStartSourceMsg(JSON.stringify(referrerInfo));
  		}
  		if (qg$c.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$c.getClipboardData({
  			success: function (res) {
  				finishCallback(res.data);
  			},
  			fail: function (res) {
  				finishCallback(null);
  			}
  		});
  	}
  	_hook_setClipboardData(clipboardData, finishCallback) {
  		qg$c.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$c.getSystemInfoSync().platformVersion
  				};
  				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$c.getSystemInfoSync().platformVersion.toString(),
  						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;
  						if (code == 1) {
  							let orderNo = resMsg.data.orderNo;
  							let timestamp = resMsg.data.timestamp;
  							let sign = resMsg.data.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$c.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);
  		});
  	}
  	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$c.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);
  			}
  		});
  	}
  	getOpenId(obj) {
  		if (this.openId) {
  			obj.success && obj.success(this.openId);
  			return;
  		}
  		let config = ULConfig.getConfig();
  		this.login({
  			success: (token) => {
  				ULLog.console.log("ULModuleOppoQg.getOpenId 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.getOpenId success", responseText);
  						let resultObj = JSON.parse(responseText);
  						if (resultObj.code == 1) {
  							let openId = resultObj.openId;
  							this.openId = openId;
  							ULSdkManager.getInstance().channelInfo.channelUserId = openId;
  							obj.success && obj.success(this.openId);
  						}
  						else {
  							ULLog.console.log("ULModuleOppoQg.getOpenId resultObj:", resultObj);
  							obj.fail && obj.fail(JSON.stringify(resultObj));
  						}
  					},
  					fail: (res) => {
  						ULLog.console.log("ULModuleOppoQg.getOpenId fail:", res);
  						obj.fail && obj.fail(JSON.stringify(res));
  					}
  				});
  			},
  			fail: (res) => {
  				ULLog.console.log("ULModuleOppoQg.getOpenId 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$c.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$c.hasShortcutInstalled) {
  			qg$c.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) {
  		console.info("添加桌面快捷方式失败");
  		e.stopImmediatePropagation();
  		let config = ULConfig.getConfig();
  		let data = e.data;
  		let userData = data.userData;
  		qg$c.hasShortcutInstalled({
  			success: (res) => {
  				if (res == false) {
  					qg$c.installShortcut({
  						success: () => {
  							setTimeout(() => {
  								qg$c.hasShortcutInstalled({
  									success: (res) => {
  										if (res == false) {
  											ULLog.console.log("ULModuleOppoQg.onCmdInstallShortcut.hasShortcutInstalled 2 success false :", res);
  											ULSdkManager.getInstance().response(ULConst.CMD_INSTALL_SHORTCUT_RESULT, {
  												code: 0,
  												msg: "添加桌面快捷方式失败",
  												userData: userData,
  											});
  											this.onCmdGetShortcutState(new ULEvent(ULConst.CMD_GET_SHORTCUT_STATE, {}));
  										}
  										else {
  											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) => {
  										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$c.getSystemInfoSync().platformVersion;
  		ULLog.console.log("ULModuleOppoQg.onCmdSetVersion.....version: ", version);
  		if (version >= 1060) {
  			ULLog.console.log("ULModuleOppoQg.onCmdSetVersion........数据正在上报");
  			qg$c.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$c.vibrateShort || !qg$c.vibrateShort) {
  		}
  		let type = data.type || "short";
  		switch (type) {
  			case "long":
  				this.vibrateLong(data);
  				break;
  			default:
  				this.vibrateShort(data);
  				break;
  		}
  	}
  	vibrateShort(data) {
  		qg$c.vibrateShort({
  			success: () => {
  				this.responsePhoneVibrate(1, "success", data);
  			},
  			fail: () => {
  				this.responsePhoneVibrate(0, "fail", data);
  			},
  			complete: () => {
  			}
  		});
  	}
  	vibrateLong(data) {
  		qg$c.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.getOpenId({
  			success: (openId) => {
  				callback && callback(openId, null);
  			},
  			fail: (err) => {
  				callback && callback(null, JSON.stringify(err));
  			}
  		});
  	}
  }

  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.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.getChannelOpenIdFunc = null;
  		ULEventDispatcher.getInstance().addListener(ULConst.CMD_SDK_COLLECTION_MODULE_CHECKER_CONFIG, ULConst.PRIORITY_NONE, this.onCmdSdkCollectionModuleCheckerConfig.bind(this));
  		this.waits = new ULWaitTool();
  	}
  	set channelUserId(v) {
  		if (this._channelUserId == v)
  			return;
  		this._channelUserId = v;
  		if (!!this._channelUserId) {
  			ULSdkManager.getInstance().statisManager.reportUserChannelId(this._channelUserId);
  		}
  	}
  	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,
  			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;
  		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
  		};
  	}
  	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;
  		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 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 ULStatisManager {
  	constructor() {
  		this.bUploading = false;
  		this.lastTimerLoopTime = null;
  		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 (!!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 || "");
  		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) {
  		advItem.statisNativeAdTitle = nativeAdvTitle;
  		this.reportAdvInfo(advItem.statisChannelName, advItem.showAdvType, "success", "", advItem.advGroupId, advItem.advId, advItem.tag, advItem.statisNativeAdTitle, advItem.statisSdkAdvId, "");
  	}
  	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) {
  		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 || "");
  		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_USER_MESSAGE);
  		let updata = [];
  		updata.push(ULTools.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
  		updata.push(this.channelInfoUuid);
  		updata.push("");
  		updata.push(config.s_sdk_cop_version);
  		updata.push(config.s_sdk_cop_channel_id);
  		updata.push("");
  		updata.push("");
  		updata.push("1");
  		updata.push(channelId);
  		this._report(typeid, updata);
  	}
  	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)) {
  			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)) {
  			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.ultralisk.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.ultralisk.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.ultralisk.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.ultralisk.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.ultralisk.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.ultralisk.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.ultralisk.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.ultralisk.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.ultralisk.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]);
  	}
  	_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.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;
  			}
  		});
  	}
  	onCmdSdkOnGamePause(e) {
  		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.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: "游戏金手指:      " });
  		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 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.ultralisk.cn/checkwhiteuser?gameId=${gameId}&userId=${userId}&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));
  					}
  				});
  			},
  		});
  		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 = {};
  	}
  	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 nodeCanvas = scene.getChildByName("Canvas");
  		if (!nodeCanvas) {
  			ULLog.console.warn("MCPanelCreator.getNodeCanvas nodeCanvas not found!");
  			return null;
  		}
  		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) {
  		this.closeWebView();
  		let nodeCanvas = this.getNodeCanvas();
  		if (!nodeCanvas) {
  			return;
  		}
  		console.log(`showWebView title:${title} url:${url}`);
  		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.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(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());
  		nodeContent.addComponent(_cc.Layout).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) {
  				}
  				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) {
  		this.showWebView(title, url);
  	}
  	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 privacyArray = [];
  		let privacyUrlDic = {};
  		for (let index = 0; index < contentArray.length; index++) {
  			const element = contentArray[index];
  			let privacyName = element.name || "";
  			let privacyUrl = element.url || "";
  			privacyArray.push(privacyName);
  			privacyUrlDic[privacyName] = privacyUrl;
  		}
  		let footer = `1.为了向您展示您感兴趣的广告，【本应用】将收集和处理您的以下信息，并仅在上述的目的范围内分享给第三方广告服务平台：\\n 1）  设备及使用信息：设备标识符、操作系统的设置信息、设备的硬件信息、应用的基本信息及使用信息、网络信息、运营商信息、帐号信息。\\n 2）广告互动信息：对广告的浏览、点击、关闭和播放信息。打开和关闭应用的时间、应用使用频率、应用错误日志。\\n 3）位置信息。我们会收集、使用并处理您设备的模糊位置或准确位置，这些位置信息通过 GPS、WLAN 和服务提供商的网络 ID 获取。我们会询问您要为本应用程序启用基于位置的服务。您可在设备的设置菜单中选择关闭设备上的相应权限，拒绝共享您的位置信息。 上述数据将会传输并保存至【中华人民共和国境内】的服务器，保存期限为60天，超出这一保留时间后将删除，但法律法规另有要求除外。 \\n2.如果您不同意我们采集上述信息，或不同意调用相关手机权限或功能，本软件将无法正常运行。您可通过卸载或退出本软件来终止数据收集及上传。更新时间：2023年5月8日
        `;
  		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 < privacyArray.length; index++) {
  			let buttonText = privacyArray[index];
  			let buttonNode = new _cc.Node();
  			buttonNode.color = _cc.color(156, 176, 222, 255);
  			buttonNode.parent = nodeContent;
  			buttonNode.setAnchorPoint(0.5, 1);
  			let buttonLabel = buttonNode.addComponent(_cc.Label);
  			buttonLabel.string = `《${buttonText}》`;
  			buttonLabel.fontSize = 18;
  			buttonLabel.lineHeight = 26;
  			buttonNode.setContentSize(nodeContent.getContentSize());
  			buttonLabel.overflow = _cc.Label.Overflow.RESIZE_HEIGHT;
  			this.registerTouchHandler(buttonNode, (e) => {
  				if (!this.isTouchEventClick(e))
  					return;
  				this.showWebView(buttonText, privacyUrlDic[buttonText]);
  			});
  		}
  		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;
  				}
  			});
  		}
  	}
  	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(() => {
  			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;
  			}
  		}, 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;
  		}
  	}
  }

  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 = {};
  	}
  	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) {
  		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 resultObj = JSON.parse(responseText);
  				let content = resultObj.policyText;
  				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) {
  		this.showWebView(title, url);
  	}
  	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 privacyArray = [];
  		let privacyUrlDic = {};
  		for (let index = 0; index < contentArray.length; index++) {
  			const element = contentArray[index];
  			let privacyName = element.name || "";
  			let privacyUrl = element.url || "";
  			privacyArray.push(privacyName);
  			privacyUrlDic[privacyName] = privacyUrl;
  		}
  		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 < privacyArray.length; index++) {
  					const buttonText = privacyArray[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 = `《${buttonText}》`;
  					label.pos(0, footerLabelPosY);
  					label["_tf"]["isChanged"] = true;
  					footerLabelPosY = footerLabelPosY + label.height;
  					self.registerTouchHander(label, (e) => {
  						if (e.name == "click") {
  							self.showWebView(buttonText, privacyUrlDic[buttonText]);
  						}
  					});
  				}
  				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;
  					}
  				}
  			});
  		}
  	}
  	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) {
  		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(() => {
  			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;
  			}
  		}, 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;
  		}
  	}
  }

  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 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;
  	}
  	init() {
  		if (ULConst.B_INNER_DEBUG)
  			ULLog.console.log("ULModuleCheckerManager.init");
  		this.registerTouchListener();
  		this.refreshDebugInfo();
  		if (window["cc"]) {
  			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("版本信息", "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) {
  		this.getOrCreatePanel();
  		if (!this.panel)
  			return;
  		this.panel.showPrivacyContent(title, url);
  	}
  	alertPrivacy(title, content, btnTexts, callbacks) {
  		this.getOrCreatePanel();
  		if (!this.panel)
  			return;
  		this.panel.showPrivacyDialog(title, content, btnTexts, callbacks);
  	}
  	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);
  	}
  	getOrCreatePanel() {
  		if (!this.panel) {
  			if (window["cc"]) {
  				this.panel = new MCPanelCreator();
  			}
  			else if (window["Laya"]) {
  				this.panel = new MCPanelLaya();
  			}
  			else {
  				ULLog.console.warn("ULModuleCheckerManager.getOrCreatePanel unknown platform!");
  			}
  		}
  		return this.panel;
  	}
  	registerTouchListener() {
  		if (ULConst.B_INNER_DEBUG)
  			ULLog.console.log("ULModuleCheckerManager.registerTouchListener");
  		if (ULConst.B_INNER_DEBUG)
  			ULLog.console.log("  cc", window["cc"]);
  		if (ULConst.B_INNER_DEBUG)
  			ULLog.console.log("  laya", window["laya"]);
  		if (ULConst.B_INNER_DEBUG)
  			ULLog.console.log("  Laya", window["Laya"]);
  		if (window["cc"] && window["cc"]["systemEvent"]) {
  			let cc = window["cc"];
  			let scene = window["cc"].director.getScene();
  			if (!scene) {
  				if (ULConst.B_INNER_DEBUG)
  					ULLog.console.log("  scene not found!");
  				return null;
  			}
  			let nodeCanvas = scene.getChildByName("Canvas");
  			if (!nodeCanvas) {
  				if (ULConst.B_INNER_DEBUG)
  					ULLog.console.log("  nodeCanvas not found!");
  				return null;
  			}
  			if (ULConst.B_INNER_DEBUG)
  				ULLog.console.log("nodeCanvas", nodeCanvas);
  			nodeCanvas.on(window["cc"].Node.EventType.TOUCH_START, (e) => {
  				let p = e.getLocation();
  				let size = nodeCanvas.getContentSize();
  				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);
  				}
  			}, null, true);
  			nodeCanvas.on(window["cc"].Node.EventType.TOUCH_END, (e) => {
  				ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_TOUCH_SCREEN_END, { lastTouchScreenEnd: ULTools.time() });
  			}, null, 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 Laya.Script {
  					onStageClick(e) {
  						if (ULConst.B_INNER_DEBUG)
  							ULLog.console.log("LayaStageToucher.onStageClick", e);
  						ULEventDispatcher.getInstance().dispatch(ULConst.CMD_SDK_TOUCH_SCREEN_END, { lastTouchScreenEnd: ULTools.time() });
  						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);
  		}
  	}
  	refreshDebugInfo() {
  		let length = ULTools.getObjSize(this.debugInfos);
  		if (length <= 0) {
  			if (this.debugInfoRenderNode) {
  				if (window["cc"]) {
  					if (window["cc"].isValid(this.debugInfoRenderNode)) {
  						this.debugInfoRenderNode.destroy();
  					}
  				}
  				else if (window["Laya"]) {
  					this.debugInfoRenderNode.destroy();
  				}
  				else {
  				}
  				this.debugInfoRenderNode = null;
  			}
  			return;
  		}
  		let arr = [];
  		ULTools.forEachMap(this.debugInfos, (k, v) => {
  			arr.push(v);
  		});
  		let text = arr.join("\n");
  		if (!this.debugInfoRenderNode) {
  			if (window["cc"]) {
  				let cc = window["cc"];
  				let scene = window["cc"].director.getScene();
  				if (!scene) {
  					if (ULConst.B_INNER_DEBUG)
  						ULLog.console.log("  scene not found!");
  					return null;
  				}
  				let nodeCanvas = scene.getChildByName("Canvas");
  				if (!nodeCanvas) {
  					if (ULConst.B_INNER_DEBUG)
  						ULLog.console.log("  nodeCanvas not found!");
  					return null;
  				}
  				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))));
  				this.debugInfoRenderNode = nodeDebugInfo;
  			}
  			else if (window["Laya"]) {
  				let Laya = window["Laya"];
  				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;
  				this.debugInfoRenderNode = label;
  			}
  		}
  		if (this.debugInfoRenderNode) {
  			if (window["cc"]) {
  				let cc = window["cc"];
  				let nodeDebugInfo = this.debugInfoRenderNode;
  				nodeDebugInfo.getComponent(window["cc"].Label).string = text;
  			}
  			else if (window["Laya"]) {
  				let label = this.debugInfoRenderNode;
  				label.text = text;
  			}
  			else {
  			}
  		}
  	}
  	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;
  	}
  }

  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.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.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");
  			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.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 = [];
  	}
  	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(error);
  				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(error);
  				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("  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["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!: ${jsonStr}`);
  			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;

  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(camera, pos, 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(camera, screenPos, distance, out) {
  		out = out || new Laya.Vector3();
  		camera.viewportPointToRay(screenPos, this.ray_temp);
  		Laya.Vector3.scale(this.ray_temp.direction, distance, out);
  		Laya.Vector3.add(this.ray_temp.origin, out, out);
  		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 = (Math.min(UIRoot.uiFitHeight, 1152) - 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 = (Math.min(UIRoot.uiFitHeight, 1152) - 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 = (Math.min(UIRoot.uiFitHeight, 1152) - 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 = (Math.min(UIRoot.uiFitHeight, 1152) - UIRoot.designHeight) / 2;
  		!bDisableH && (node.x = node[`_originPos_`].x + offsetX);
  		!bDisableV && (node.y = node[`_originPos_`].y + offsetY);
  	}
  	static setGray(sprite) {
  		let colorMat = [
  			1, 0, 0, 0, 0,
  			0, 1, 0, 0, 0,
  			0, 0, 1, 0, 0,
  			0, 0, 0, 1, 0,
  		];
  		let filter = new Laya.ColorFilter(colorMat);
  		filter.gray();
  		sprite.filters = [filter];
  	}
  	static setRed(sprite) {
  		let colorMat = [
  			1, 0, 0, 0, 0,
  			0, 0, 0, 0, 0,
  			0, 0, 0, 0, 0,
  			0, 0, 0, 0.95, 0,
  		];
  		let filter = new Laya.ColorFilter(colorMat);
  		sprite.filters = [filter];
  	}
  	static setBlack(sprite) {
  		let colorMat = [
  			0, 0, 0, 0, 0,
  			0, 0, 0, 0, 0,
  			0, 0, 0, 0, 0,
  			0, 0, 0, 0.95, 0,
  		];
  		let filter = new Laya.ColorFilter(colorMat);
  		sprite.filters = [filter];
  	}
  	static setNormal(sprite) {
  		sprite.filters = [];
  	}
  	static widget(h, v, node, anchor = { x: 0, y: 0 }, parent = Laya.stage) {
  		if (parent == Laya.stage) {
  			if (Laya.stage.height > 1152) {
  				let delta = Laya.stage.height - 1152;
  				let minV = delta / 2;
  				let maxV = Laya.stage.height - minV;
  				if (v >= 0 && v <= 1) {
  					v = Mathf.clamp(v, minV / Laya.stage.height, maxV / Laya.stage.height);
  				}
  				else if (v > 1) {
  					if (v < 300) {
  						v = Mathf.clamp(v + minV, minV, maxV);
  					}
  					else if (v > Laya.stage.width - 300) {
  						v = Mathf.clamp(v - minV, minV, maxV);
  					}
  					else {
  						v = Mathf.clamp(v, minV, maxV);
  					}
  				}
  			}
  		}
  		let absh = Math.abs(h);
  		let absv = Math.abs(v);
  		let x = parent.width * h;
  		let y = parent.height * v;
  		if (absh > 1)
  			x = h;
  		if (absv > 1)
  			y = v;
  		if (node)
  			if (node[`anchorX`] == null || isNaN(node[`anchorX`])) {
  				node[`anchorX`] = node.pivotX / node.width;
  			}
  		if (node[`anchorY`] == null || isNaN(node[`anchorY`])) {
  			node[`anchorY`] = node.pivotY / node.height;
  		}
  		x += node[`anchorX`] * node.width - anchor.x * node.width;
  		y += node[`anchorY`] * node.height - anchor.y * node.height;
  		let wPos = parent.localToGlobal(new Laya.Point(x, y));
  		let nplPos = node.parent.globalToLocal(new Laya.Point(wPos.x, wPos.y));
  		if (h == -1)
  			nplPos.x = node.x;
  		if (v == -1)
  			nplPos.y = node.y;
  		if (node instanceof fgui.GObject) {
  			node.setXY(nplPos.x, nplPos.y);
  		}
  		else {
  			node.pos(nplPos.x, nplPos.y, true);
  		}
  	}
  }
  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();

  class Particle extends Model {
  	onResourceLoaded(res) {
  		this._pss = [];
  		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);
  		}
  	}
  	start() {
  		if (this.callable) {
  			for (var i = this._pss.length - 1; i >= 0; i--) {
  				this._pss[i].play();
  			}
  		}
  		else {
  			this.safeCall(this.start);
  		}
  	}
  	putBack() {
  		if (this.callable) {
  			Global.poolManager.put(this);
  		}
  		else {
  			this.safeCall(this.putBack);
  		}
  	}
  	resetTrail(mode) {
  		if (this.callable) {
  			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);
  			}
  		}
  		else {
  			this.safeCall(this.resetTrail, mode);
  		}
  	}
  	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);
  		}
  	}
  	setColor(color) {
  		if (this.callable) {
  			for (let i = 0; i < this._pss.length; i++) {
  				const element = this._pss[i];
  				element.startColorConstant = color;
  				element.startColorConstantMin = color;
  				element.startColorConstantMax = color;
  			}
  		}
  		else {
  			this.safeCall(this.setColor, color);
  		}
  	}
  	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 StageTouchEvent extends Laya.Script {
  	onStart() {
  	}
  	onStageMouseDown(e) {
  		if (!db[`_allDbs`])
  			return;
  	}
  }

  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() {
  		console.log("1111111111111111111111111111111111111111111111111111");
  		this.initScene();
  		console.info("Director.onLoad");
  	}
  	static getDialogViewStack() {
  		let uiViewStack = this.view_stack[1];
  		let dialogViewStack = this.view_stack[2];
  		let viewStack = uiViewStack.concat(dialogViewStack);
  		return viewStack;
  	}
  	static runScene(sceneClass, loadingClass, params) {
  		console.log("mgrScene startRun.");
  		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.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(this);
  			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;
  			this.runningScene.onEnter(params);
  			Global.sendMsg(BASE_MSG.RES_LOAD_END);
  		}
  		else {
  			console.error("mgrSceen.onResComplete error.");
  		}
  	}
  	static initScene() {
  		this.init2DLayer();
  		this.init3DLayer();
  	}
  	static init2DLayer() {
  		if (!this.layers2D) {
  			this.layers2D = [];
  			Laya.stage.addChild(fgui.GRoot.inst.displayObject);
  			for (let i = 0; i <= 6; i++) {
  				let layer = new fgui.GComponent();
  				layer.name = "Layer" + i;
  				layer.displayObject.name = layer.name;
  				layer.makeFullScreen();
  				layer["__is_custom_root_layer_component"] = true;
  				fgui.GRoot.inst.addChild(layer);
  				this.layers2D.push(layer);
  				this.view_stack.push([]);
  			}
  		}
  	}
  	static isCustomRootLayer(nodeLayer) {
  		if (!!nodeLayer && !!nodeLayer["__is_custom_root_layer_component"]) {
  			return true;
  		}
  		else {
  			return false;
  		}
  	}
  	static getLayer(layer = 1) {
  		return this.layers2D[layer];
  	}
  	static getLayerUI() {
  		return Director.getLayer(1);
  	}
  	static getLayerTop() {
  		return Director.getLayer(5);
  	}
  	static getLayerUITop() {
  		return Director.getLayer(2);
  	}
  	static getDialogLayer() {
  		return this.getLayer;
  	}
  	static init3DLayer() {
  		if (!this.scene3deffect) {
  			this.scene3deffect = new Laya.Scene3D();
  			this.getLayer(4).displayObject.addChild(this.scene3deffect);
  			var camera = this.scene3deffect.addChild(new Laya.Camera(0, 0.1, 20));
  			this.cameraEffect = camera;
  			camera.orthographic = true;
  			camera.orthographicVerticalSize *= UIRoot.canvasHeight / 1024;
  			camera.transform.position = new Laya.Vector3(0, 0, 10);
  			camera.clearFlag = Laya.CameraClearFlags.DepthOnly;
  			Laya.stage.addComponent(StageTouchEvent);
  		}
  	}
  	static getScene3D() {
  		return this.scene3deffect;
  	}
  	static getCamera() {
  		return this.cameraEffect;
  	}
  	static addEffect(modelId, pos, duration, scale = 1, offsetX = 0, offsetY = 0) {
  		let x = 0;
  		let y = 0;
  		let scaleX = scale;
  		let scaleY = scale;
  		let scaleZ = scale;
  		x = pos.x;
  		y = pos.y;
  		let outPos = new Laya.Vector3;
  		this.cameraEffect.convertScreenCoordToOrthographicCoord(new Laya.Vector3(x, y, 0), outPos);
  		let mode = Global.poolManager.get(Particle, modelId);
  		mode.resetTrail();
  		this.scene3deffect.addChild(mode);
  		mode.transform.position = outPos;
  		Tools.setWorldLossyScale(mode, scaleX, scaleY, scaleZ);
  		Timer.callLater(duration, () => {
  			Global.poolManager.put(mode);
  		}, this);
  		return mode;
  	}
  	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.constructor[`sourceName`]} in layer:${panel.panelLayer}`);
  			panel.dispose();
  			return index;
  		}
  		return -1;
  	}
  	static closePanel(panel) {
  		if (!panel || !panel.isLoaded)
  			return;
  		if (panel.bFocus)
  			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;
  			this.__updatePanelVisibleByLayer(layer);
  			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) {
  		console.log("-------------openPanel=", panel["_name"] || panel["PANEL_NAME"]);
  		Global.sendMsg(`MSG_OPEN_PANEL`, panel);
  		let panelClass = this.getPanelClass(panel);
  		if (!panelClass) {
  			callback && callback();
  			return;
  		}
  		var panelInstance = new panelClass(context);
  		panelInstance.name = panel;
  		console.log("打开面板：" + panel);
  		return this.openPanelInstance(panelInstance, panelClass, callback);
  	}
  	static openPanelWithClearLayer(panel, context, callback) {
  		console.log("-------------openPanelWithClearLayer=", panel["_name"] || panel["PANEL_NAME"]);
  		Global.poolManager.autoReleaseRes();
  		let panelInstance = this.openPanel(panel, context, (bSuccess) => {
  			Timer.callLaterFrame(1, () => {
  				let stack = this.view_stack[panelInstance.panelLayer];
  				let bFindSelf = false;
  				for (let i = stack.length - 1; i >= 0; i--) {
  					bFindSelf = bFindSelf || stack[i] === panelInstance;
  					if (!bFindSelf || stack[i] === panelInstance)
  						continue;
  					else
  						stack[i].close();
  				}
  				callback && callback(bSuccess);
  			}, this);
  		});
  	}
  	static openPanelInstance(panel, panelClass, callback) {
  		console.log("-------------openPanelInstance=", panel["_name"] || panel["PANEL_NAME"]);
  		panel[CLASS_KEY] = panelClass;
  		panel.create(function (suc) {
  			if (suc)
  				panelClass[FLAG_LOADED] = true;
  			callback && callback(suc);
  			console.info("打开:" + panel.constructor[`sourceName`], suc);
  		});
  		return panel;
  	}
  	static openPanelWithSingleton(panel, context, callback) {
  		console.log("-------------openPanelWithSingleton=", panel["_name"] || panel["PANEL_NAME"]);
  		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();
  			return view;
  		}
  		else {
  			if (panelClass[FLAG_OPENING]) {
  				console.info(`${panelClass} is opening`);
  				return;
  			}
  			panelClass[FLAG_OPENING] = true;
  			return this.openPanel(panel, context, function (suc) {
  				panelClass[FLAG_OPENING] = false;
  				callback && callback(suc);
  			});
  		}
  	}
  	static openPanelByWait(panel, context, callback) {
  		console.log("-------------openPanelByWait=", panel["_name"] || panel["PANEL_NAME"]);
  		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 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.constructor[`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) {
  			this.__updatePanelVisibleByLayer(layer);
  			topPanel.onFocus(false);
  		}
  		panel.onFocus(true);
  	}
  	static __updatePanelVisibleByLayer(layer) {
  		let stack = this.view_stack[layer];
  		if (!stack)
  			return;
  		let bFindFull = false;
  		for (let i = stack.length - 1; i >= 0; i--) {
  			let panel = stack[i];
  			if (panel.panelStyle == 0)
  				continue;
  			if (!bFindFull)
  				panel.show();
  			else
  				panel.hide();
  			bFindFull = bFindFull || panel.panelStyle == 1;
  		}
  	}
  	static setPanelToTop(panel) {
  		let stack = this.view_stack[panel.panelLayer];
  		stack[stack.length - 1].onFocus(false);
  		let index = stack.indexOf(panel);
  		stack.splice(index, 1);
  		stack.push(panel);
  		panel.onFocus(true);
  		this.__updatePanelVisibleByLayer(panel.panelLayer);
  	}
  	static setPanelToBottom(panel) {
  		panel.focused && panel.onFocus(false);
  		let stack = this.view_stack[panel.panelLayer];
  		let index = stack.indexOf(panel);
  		stack.splice(index, 1);
  		stack.unshift(panel);
  		!stack[stack.length - 1].focused && stack[stack.length - 1].onFocus(true);
  		this.__updatePanelVisibleByLayer(panel.panelLayer);
  	}
  	static disposeAllPanel() {
  		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];
  				panel[CLASS_KEY][FLAG_OPENING] = 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.constructor[`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.constructor[`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.constructor[`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;
  	}
  }
  Director._isSceneOpening = false;
  Director.runningScene = null;
  Director.nextScene = null;
  Director.nextSceneparams = null;
  Director.view_stack = [];
  Director.waitRouters = [];

  const SOUND_TYPE_MUSIC = 1;
  const SOUND_TYPE_EFFECT = 2;
  const SOUND_TYPE_VOICE = 3;
  let WTF = "wtf";
  class mgrSound extends Manager {
  	static get musicEnabled() {
  		return this.musicVolume != 0;
  	}
  	static set musicEnabled(value) {
  		this.musicVolume = value ? 1 : 0;
  		this.saveRecord();
  		value ? this.resumeMusic() : this.pauseMusic();
  	}
  	static get soundEnabled() {
  		return this.effectVolume != 0;
  	}
  	static set soundEnabled(value) {
  		this.effectVolume = value ? 1 : 0;
  		this.saveRecord();
  		value ? this.resumeEffect() : this.pauseEffect();
  	}
  	static onLoad() {
  		Laya.SoundManager.autoStopMusic = true;
  		ResLoader.loadJson(`res/cfg/soundDuration.json`, (obj) => {
  			this.soundDurations = obj;
  		});
  		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;
  		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;
  				Timer.callLater(0.1, () => {
  					Laya.SoundManager.musicMuted = false;
  				});
  			});
  			wx.onHide(() => {
  			});
  		}
  		this.setMusicVomue(this.musicVolume, true);
  		this.setEffectVolume(this.effectVolume, true);
  	}
  	static saveRecord() {
  		let record = {
  			musicVolume: this.musicVolume,
  			effectVolume: this.effectVolume,
  		};
  		FileRecord.setData("sound", record);
  	}
  	static playMusic(soundId, loop = false) {
  		Logger.log("play music:", soundId);
  		this.play(soundId, loop);
  	}
  	static playSound(soundId, loop = false) {
  		this.play(soundId, loop);
  	}
  	static playTalk(soundId) {
  		if (this._lastTalkId) {
  			this.stopSound(this._lastTalkId);
  		}
  		this._lastTalkId = soundId;
  		this.play(soundId, false);
  	}
  	static playSoundIfTimeout(soundId, soundGroup, deltaTime) {
  		let lastTime = this._lastSoundPlayTime[soundId];
  		if (lastTime && (Timer.time - lastTime < deltaTime)) {
  			return;
  		}
  		this._lastSoundPlayTime[soundId] = Timer.time;
  		this.playSound(soundId);
  	}
  	static play(soundId, bLoop = false, complete) {
  		if (!soundId) {
  			return;
  		}
  		console.log(`mgrSound.play: ${soundId}`);
  		let soundData = db.get_sound_db(soundId);
  		if (!soundData) {
  			console.error(`没有找到音乐id: ${soundId}配置`);
  			return;
  		}
  		if (soundData.type == SOUND_TYPE_MUSIC) {
  			if (soundId == this.playingMusicSoundId)
  				return;
  			this.playingMusicSoundId = soundId;
  			var url = this.getUrl(soundId);
  			let playMusic = () => {
  				Logger.debug(`开始播放音乐:${url} ${this.musicVolume}`);
  				Laya.SoundManager.playMusic(url, 0, complete);
  				!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 {
  			var url = this.getUrl(soundId);
  			let playEffect = () => {
  				this.bLoadingEffect = false;
  				if (soundData.bStopAllEffect) {
  					Laya.SoundManager.stopAllSound();
  				}
  				Laya.SoundManager.playSound(url, bLoop ? 0 : 1, complete);
  			};
  			if (window.document && window.document[`__custom_web_platform_tag__`] && !window[`conch`]) {
  				ResLoader.loadRes(url, Laya.Loader.SOUND, (res) => {
  					playEffect();
  				});
  			}
  			else {
  				playEffect();
  			}
  		}
  	}
  	static getUrl(soundId) {
  		let soundData = db.get_sound_db(soundId);
  		let url = soundData.fileName;
  		let type = soundData.type;
  		if (window[`conch`]) {
  			if (type == SOUND_TYPE_MUSIC) {
  				url = url.replace(".ogg", ".mp3");
  			}
  			else {
  				url = url.replace(".mp3", ".ogg");
  			}
  		}
  		else {
  			url = url.replace(".ogg", ".mp3");
  		}
  		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) {
  		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__`] || window[`kwaigame`]) {
  			console.log("---2---setMusicVomue", musicVolume);
  			if (musicVolume == 0) {
  				Laya.SoundManager.musicMuted = true;
  			}
  			else {
  				Laya.SoundManager.musicMuted = false;
  				let soundId = this.playingMusicSoundId;
  				this.playingMusicSoundId = null;
  				soundId && this.play(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.playingMusicSoundId = null;
  mgrSound.musicVolume = 1;
  mgrSound.effectVolume = 1;
  mgrSound.effectCd = 0.1;
  mgrSound.effectPlayStartTime = 0;
  mgrSound.pauseMusicRouters = [];
  mgrSound.pauseEffectRouters = [];
  mgrSound.bPlayedMusic = false;
  mgrSound.soundDurations = {};
  mgrSound._lastSoundPlayTime = Object.create(null);

  const DEBUG = false;
  class mgrGuide extends Manager {
  	static onLoad() {
  		super.onLoad();
  		Global.registerListeners(this, {
  			MSG_GUIDE_EVENT: this.onGuideMsgEvent.bind(this)
  		});
  	}
  	static loadRecord() {
  		super.loadRecord();
  		let record = FileRecord.getData("mgrGuide") || {};
  		this.finishedGuideIds = record.finishedGuideIds || [];
  	}
  	static saveRecord() {
  		super.saveRecord();
  		let record = {
  			finishedGuideIds: this.finishedGuideIds,
  		};
  		FileRecord.setData("mgrGuide", record);
  	}
  	static isFinished(guideId) {
  		if (db.cop_db.b_defaultUnlock == 1) {
  			return true;
  		}
  		return this.finishedGuideIds.indexOf(guideId) >= 0;
  	}
  	static isGuiding() {
  		return !!this.curExecutingGuideId;
  	}
  	static isAllGuideFinished() {
  		return true;
  	}
  	static registerGuideNode(name, node) {
  		let bNewRegister = !this.bindedGuideNode[name] || this.bindedGuideNode[name].destroyed;
  		this.bindedGuideNode[name] = node;
  		bNewRegister && this.tryResumeGuide();
  	}
  	static unregisterGuideNode(name) {
  		this.bindedGuideNode[name] = null;
  	}
  	static startGuide(guideId, bForce = false) {
  		if (db.cop_db.b_defaultUnlock == 1) {
  			return true;
  		}
  		console.log("调用引导", guideId);
  		if (mgrGuide.isFinished(guideId)) {
  			console.log(`引导已完成: ${guideId}, 请勿重复触发!`);
  			return;
  		}
  		if (bForce) {
  			this.endGuide();
  		}
  		if (mgrGuide.isGuiding()) {
  			console.log(`正在执行新手引导: ${this.curExecutingGuideId}`);
  			return;
  		}
  		console.log("调用引导2", guideId);
  		this.curExecutingGuideId = guideId;
  		let guideData = db.get_guide_db(guideId);
  		if (guideData.bindNodeName) {
  			if (!this.bindedGuideNode[guideData.bindNodeName]) {
  				console.log(`当前引导${guideId}所需要的绑定节点尚未注册, 等待...`);
  				return;
  			}
  			if (this.bindedGuideNode[guideData.bindNodeName].destroyed) {
  				console.log(`当前引导${guideId}所需要的绑定节点已失效, 等待...`);
  				return;
  			}
  		}
  		if (guideData.preEventId && guideData.preEventId.length > 0) {
  			let bAllHave = true;
  			for (let index = 0; index < guideData.preEventId.length; index++) {
  				const eventId = guideData.preEventId[index];
  				if (this.finisedEventIds.indexOf(eventId) < 0) {
  					bAllHave = false;
  					console.log(`当前引导的前置事件尚未完成: ${eventId}`);
  					return;
  				}
  			}
  		}
  		this.createGuide();
  	}
  	static tryResumeGuide() {
  		if (this.bStartGuide)
  			return;
  		if (!this.curExecutingGuideId)
  			return;
  		let guideData = db.get_guide_db(this.curExecutingGuideId);
  		if (!guideData.bindNodeName)
  			return;
  		if (!this.bindedGuideNode[guideData.bindNodeName] || this.bindedGuideNode[guideData.bindNodeName].destroyed) {
  			console.log(`尝试恢复失败: ${this.curExecutingGuideId}所需要的绑定节点尚未注册, 等待...`);
  			return;
  		}
  		if (guideData.dragNodeName && guideData.dragNodeName.length > 0) {
  			for (let i = 0; i < guideData.dragNodeName.length; i++) {
  				const dragName = guideData.dragNodeName[i];
  				if (!this.bindedGuideNode[dragName] || this.bindedGuideNode[dragName].destroyed) {
  					console.log(`尝试恢复失败: ${this.curExecutingGuideId}所需要的拖动绑定节点尚未注册, 等待...`);
  					return;
  				}
  			}
  		}
  		if (guideData.preEventId && guideData.preEventId.length > 0) {
  			for (let index = 0; index < guideData.preEventId.length; index++) {
  				const eventId = guideData.preEventId[index];
  				if (this.finisedEventIds.indexOf(eventId) < 0) {
  					console.log(`当前引导的前置事件尚未完成: ${eventId}`);
  					return;
  				}
  			}
  		}
  		this.createGuide();
  	}
  	static createGuide() {
  		if (this.bStartGuide)
  			return;
  		this.bStartGuide = true;
  		this.finisedEventIds = [];
  		console.log(`创建新手引导:${this.curExecutingGuideId}`);
  		let guideId = this.curExecutingGuideId;
  		let guideData = db.get_guide_db(guideId);
  		if (guideData.statisPoint) {
  			GameStatistics.statisOnStageStart(guideData.statisPoint);
  		}
  		guideData.startGuideEvent && Global.sendMsg(guideData.startGuideEvent);
  		let guideNode = this.bindedGuideNode[guideData.bindNodeName || "-1"];
  		let guideDragNodes = [];
  		for (let i = 0; i < guideData.dragNodeName.length; i++) {
  			const dragName = guideData.dragNodeName[i];
  			guideDragNodes.push(this.bindedGuideNode[dragName || "-1"]);
  		}
  		if (guideData.bindNodeName || guideData.tipContent) {
  			console.log(`打开mask弹框:${this.curExecutingGuideId}`);
  			this.guideMaskDialog = Director.openPanel(`PanelGuide`, {
  				target: guideNode,
  				dragTargets: guideDragNodes,
  				extraArena: guideData.nodeExtArena,
  				content: guideData.tipContent,
  				widget: { x: guideData.tipWidgetX, y: guideData.tipWidgetY },
  				type: guideData.tipStyle,
  				tipDelayTime: guideData.tipDelayTime,
  				bScene: guideData.bScene,
  				maskType: guideData.maskType,
  			});
  		}
  		if (guideData.tipDelayTime > 0) {
  			Timer.callLater(guideData.tipDelayTime, () => {
  				if (guideData.soundId)
  					mgrSound.playTalk(guideData.soundId);
  			}, this);
  		}
  		else {
  			if (guideData.soundId)
  				mgrSound.playTalk(guideData.soundId);
  		}
  		this.bWaittingFinishEvent = true;
  	}
  	static onGuideMsgEvent(e) {
  		let id = e.id;
  		let param = e.param;
  		this.finisedEventIds.push(id);
  		if (!this.bWaittingFinishEvent) {
  			return false;
  		}
  		if (!this.curExecutingGuideId) {
  			return false;
  		}
  		if (!this.bStartGuide) {
  			this.tryResumeGuide();
  			return false;
  		}
  		let guideId = this.curExecutingGuideId;
  		let guideData = db.get_guide_db(guideId);
  		for (let index = 0; index < guideData.finishEventId.length; index++) {
  			const eventId = guideData.finishEventId[index];
  			if (this.finisedEventIds.indexOf(eventId) < 0) {
  				console.log(`尝试完成引导:${guideId}: 事件${eventId}尚未完成`);
  				return;
  			}
  		}
  		if (guideData.statisPoint) {
  			GameStatistics.statisOnStageEnd(guideData.statisPoint);
  		}
  		this.guideMaskDialog && this.guideMaskDialog.close();
  		this.guideMaskDialog = null;
  		this.bStartGuide = false;
  		this.bWaittingFinishEvent = false;
  		this.curExecutingGuideId = null;
  		this.finisedEventIds = [];
  		guideData.bSave && this.finishedGuideIds.push(guideId);
  		this.saveRecord();
  		guideData.completeGuideEvent && Global.sendMsg(guideData.completeGuideEvent);
  		if (guideData.nextId) {
  			this.startGuide(guideData.nextId);
  		}
  		else {
  		}
  	}
  	static endGuide() {
  		this.guideMaskDialog && this.guideMaskDialog.close();
  		this.guideMaskDialog = null;
  		this.bStartGuide = false;
  		this.bWaittingFinishEvent = false;
  		this.curExecutingGuideId = null;
  		this.finisedEventIds = [];
  	}
  	static endNotForceGuide() {
  		if (!this.curExecutingGuideId)
  			return;
  		let guideData = db.get_guide_db(this.curExecutingGuideId);
  		if (guideData.bForceGuide)
  			return;
  		this.endGuide();
  	}
  	static sendGuideMsg(id) {
  		Global.sendMsg(`MSG_GUIDE_EVENT`, { id: id });
  	}
  	static resetGuide(guideId) {
  		let nextGuideId = guideId;
  		while (nextGuideId) {
  			let index = this.finishedGuideIds.indexOf(nextGuideId);
  			if (index >= 0) {
  				this.finishedGuideIds.splice(index, 1);
  			}
  			let guideData = db.get_guide_db(nextGuideId);
  			nextGuideId = guideData.nextId;
  		}
  		this.saveRecord();
  	}
  	static forceFinishGuide(guideId) {
  		let nextGuideId = guideId;
  		while (nextGuideId) {
  			let index = this.finishedGuideIds.indexOf(nextGuideId);
  			if (index == -1) {
  				this.finishedGuideIds.push(nextGuideId);
  			}
  			let guideData = db.get_guide_db(nextGuideId);
  			nextGuideId = guideData.nextId;
  		}
  		this.saveRecord();
  	}
  }
  mgrGuide.finishedGuideIds = [];
  mgrGuide.bindedGuideNode = {};
  mgrGuide.finisedEventIds = [];

  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;
  				}
  			}
  			console.log("mgrSdk:postMegadata(data)", data);
  			SDKBridge.sendToSdk("/c/postMegadata", data);
  		}
  	}
  	static statisOnStageStart(stageName, reason = 0, bGuide = (mgrGuide.isGuiding() || !mgrGuide.isAllGuideFinished()), userParams) {
  		console.info("mgrSdk:statisOnStageStart(stageName)", stageName);
  		let data = ["levelStart", stageName + "", reason + "", bGuide ? "1" : "0"];
  		if (userParams && userParams.length > 0) {
  			for (let i = 0; i < userParams.length; i++) {
  				data.push(userParams[i]);
  			}
  		}
  		this.postMegadata(data);
  	}
  	static statisOnStageEnd(stageName, result = 0, reason = 0, bGuide = (mgrGuide.isGuiding() || !mgrGuide.isAllGuideFinished()), userParams) {
  		console.info("mgrSdk:statisOnStageEnd(stageName)", stageName, result, reason);
  		let data = ["levelComplete", stageName + "", result + "", reason + "", '0', '0', '0', '0', '0', bGuide ? "1" : "0"];
  		if (userParams && userParams.length > 0) {
  			for (let i = 0; i < userParams.length; i++) {
  				data.push(userParams[i]);
  			}
  		}
  		this.postMegadata(data);
  	}
  	static statisOnAddItemAmount(itemId, amountDelta, reason, bGuide = (mgrGuide.isGuiding() || !mgrGuide.isAllGuideFinished()), userParams) {
  		let data = ["coinChange", itemId + "", "1", amountDelta + "", reason + "", bGuide ? "1" : "0"];
  		if (userParams && userParams.length > 0) {
  			for (let i = 0; i < userParams.length; i++) {
  				data.push(userParams[i]);
  			}
  		}
  		this.postMegadata(data);
  	}
  	static statisOnSubItemAmount(itemId, amountDelta, reason, bGuide = (mgrGuide.isGuiding() || !mgrGuide.isAllGuideFinished()), userParams) {
  		let data = ["coinChange", itemId + "", "0", amountDelta + "", reason + "", bGuide ? "1" : "0"];
  		if (userParams && userParams.length > 0) {
  			for (let i = 0; i < userParams.length; i++) {
  				data.push(userParams[i]);
  			}
  		}
  		this.postMegadata(data);
  	}
  	static statisOnItemBought(shopId, amount, reason = 0, bGuide = (mgrGuide.isGuiding() || !mgrGuide.isAllGuideFinished()), userParams) {
  		let data = ["itemBuy", shopId + "", Math.abs(amount) + "", reason + "", bGuide ? "1" : "0"];
  		if (userParams && userParams.length > 0) {
  			for (let i = 0; i < userParams.length; i++) {
  				data.push(userParams[i]);
  			}
  		}
  		this.postMegadata(data);
  	}
  	static statisOnBuyAction(reason, shopName, result, bGuide = (mgrGuide.isGuiding() || !mgrGuide.isAllGuideFinished()), userParams) {
  		let data = ["buyAction", reason + "", shopName + "", result + "", bGuide ? "1" : "0"];
  		if (userParams && userParams.length > 0) {
  			for (let i = 0; i < userParams.length; i++) {
  				data.push(userParams[i]);
  			}
  		}
  		this.postMegadata(data);
  	}
  	static statisCommonEvent(id, param1, param2, bGuide = (mgrGuide.isGuiding() || !mgrGuide.isAllGuideFinished()), userParams) {
  		let data = ["commonEvent", id + "", (param1 || 0) + "", (param2 || 0) + "", bGuide ? "1" : "0"];
  		if (userParams && userParams.length > 0) {
  			for (let i = 0; i < userParams.length; i++) {
  				data.push(userParams[i]);
  			}
  		}
  		this.postMegadata(data);
  	}
  	static statisVideoPointEvent(adStatisticsId, state, bGuide = (mgrGuide.isGuiding() || !mgrGuide.isAllGuideFinished()), userParams) {
  		let data = ["videoPointEvent", adStatisticsId, state + "", bGuide ? "1" : "0"];
  		// Advertisement.insertAdverV2();
  		console.info("0000000000000000000000000000000000000000");
  		this.postMegadata(data);
  	}
  	static statisCommonEventOnce(id, bGuide = (mgrGuide.isGuiding() || !mgrGuide.isAllGuideFinished())) {
  		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;

  class mItem extends _mBase {
  	constructor() {
  		super(...arguments);
  		this.uid = "";
  	}
  	onLoad() {
  		this.loadRecord();
  	}
  	onStart() {
  		this.checkItems();
  	}
  	checkItems() {
  		let items = this.m_data;
  		let allItems = db.get_item_db_map();
  		let bChange = false;
  		Tools.forEachMap(allItems, (id, itemDb) => {
  			if (items[id] == null) {
  				bChange = true;
  				items[parseInt(id)] = {
  					amount: itemDb.initCount,
  					bRepeated: false,
  				};
  				if (itemDb.initCount > 0)
  					this.tryActiveUp(parseInt(id));
  			}
  		});
  		if (bChange)
  			this.saveRecord();
  	}
  	loadRecord() {
  		this.m_data = FileRecord.getData("items_data") || {};
  	}
  	saveRecord() {
  		FileRecord.setData("items_data", this.m_data);
  	}
  	getAllItemInBag() {
  		return this.m_data;
  	}
  	getItemByType(type) {
  		let arr = [];
  		let items = this.getAllItemInBag();
  		if (items) {
  			let itemDb;
  			Tools.forEachMap(items, (id, v) => {
  				if (v.amount > 0) {
  					itemDb = db.get_item_db(parseInt(id));
  					if (itemDb.type == type) {
  						arr.push(id);
  					}
  				}
  			});
  		}
  		return arr;
  	}
  	static getAllItem(type) {
  		let arr = [];
  		let items = db.get_item_db_map();
  		if (items) {
  			Tools.forEachMap(items, (id, itemDb) => {
  				if (itemDb.type == type) {
  					arr.push(id);
  				}
  			});
  		}
  		return arr;
  	}
  	getItemCountByType(type) {
  		let total = 0;
  		let items = this.getAllItemInBag();
  		if (items) {
  			let itemDb;
  			Tools.forEachMap(items, (id, v) => {
  				if (v.amount > 0) {
  					itemDb = db.get_item_db(parseInt(id));
  					if (itemDb.type == type) {
  						total++;
  					}
  				}
  			});
  		}
  		return total;
  	}
  	getItemAmount(itemId) {
  		BaseFacade.mAutoIncreaseItem.refresh(itemId);
  		if (!this.m_data[itemId])
  			return 0;
  		return this.m_data[itemId].amount || 0;
  	}
  	isItemRepeated(itemId) {
  		BaseFacade.mAutoIncreaseItem.refresh(itemId);
  		if (!this.m_data[itemId])
  			return false;
  		return this.m_data[itemId].bRepeated || false;
  	}
  	isEnoughItem(itemId, count) {
  		if (count <= 0)
  			return true;
  		return this.getItemAmount(itemId) >= count;
  	}
  	isOwned(itemId) {
  		return this.isEnoughItem(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.getItemAmount(itemId);
  		if (lastCount == 0) {
  			this.tryActiveUp(itemId);
  		}
  		let itemDb = db.get_item_db(itemId);
  		let bAutoSell = false;
  		if (itemDb.autoSell) {
  			if (lastCount == 0) {
  				bAutoSell = this.autoSellItem(itemId, count - 1);
  				count = 1;
  			}
  			else {
  				bAutoSell = this.autoSellItem(itemId, count);
  				this.m_data[itemId].bRepeated = bAutoSell;
  				return bAutoSell;
  			}
  		}
  		let curCount = lastCount + count;
  		this.m_data[itemId] = {
  			amount: curCount,
  			bRepeated: bAutoSell,
  		};
  		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;
  		BaseFacade.mSwitch.active(itemDb.switch);
  		BaseFacade.mGoal.commit(BASE_ACTION_ID.ADD_ITEM, count, itemId);
  		if (reason) {
  			let addSumItemDbMap = db.get_item_add_sub_statis_db_map();
  			let statisIndex = 0;
  			Tools.forEachMap(addSumItemDbMap, (k, v) => {
  				if (v.desc == reason && v.bAddItem) {
  					statisIndex = v.index;
  				}
  			});
  			if (statisIndex > 0) {
  				GameStatistics.statisOnAddItemAmount(itemId, count, statisIndex);
  				Global.sendMsg("MSG_ITEM_CHANGE_STATISTICS", { itemId: itemId, count: count, index: statisIndex });
  			}
  		}
  		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, "AUTO_SELL");
  			return true;
  		}
  		return false;
  	}
  	tryActiveUp(itemId) {
  		return false;
  	}
  	subItem(itemId, count, reason) {
  		if (count <= 0)
  			return true;
  		if (!itemId)
  			return false;
  		let lastCount = this.getItemAmount(itemId);
  		if (lastCount < count)
  			return false;
  		let curCount = lastCount - count;
  		this.m_data[itemId] = {
  			amount: curCount,
  			bRepeated: false,
  		};
  		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;
  		BaseFacade.mGoal.commit(BASE_ACTION_ID.CONSUME_ITME, count, itemId);
  		if (reason != null) {
  			let addSumItemDbMap = db.get_item_add_sub_statis_db_map();
  			let statisIndex = 0;
  			Tools.forEachMap(addSumItemDbMap, (k, v) => {
  				if (v.desc == reason && !v.bAddItem) {
  					statisIndex = v.index;
  				}
  			});
  			if (statisIndex > 0) {
  				GameStatistics.statisOnSubItemAmount(itemId, count, statisIndex);
  				Global.sendMsg("MSG_ITEM_CHANGE_STATISTICS", { itemId: itemId, count: count, index: statisIndex });
  			}
  		}
  		Global.sendMsg(BASE_MSG.ITEM_CHANGE, event);
  		Global.pool.put(event);
  		return true;
  	}
  	sellItem(itemId, count) {
  		if (count == null) {
  			count = this.getItemAmount(itemId);
  		}
  		if (this.subItem(itemId, count, "SELL")) {
  			let itemDb = db.get_item_db(itemId);
  			if (itemDb.sellItemId) {
  				this.addItem(itemDb.sellItemId, itemDb.sellPrice * count, "SELL");
  			}
  		}
  	}
  	setItem(itemId, count) {
  		if (count < 0)
  			return;
  		if (!itemId)
  			return;
  		let lastCount = this.getItemAmount(itemId);
  		if (lastCount == count)
  			return;
  		this.m_data[itemId] = {
  			amount: count,
  			bRepeated: false
  		};
  		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);
  	}
  }

  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") || {};
  		this.autoDayTime = FileRecord.getData("auto_time_data") || Timer.time;
  		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 (!Tools.isOneDay(this.autoDayTime, Timer.time)) {
  			this.autoDayTime = Timer.time;
  			let dbs = db.get_auto_increase_db_map();
  			Tools.forEachMap(dbs, (itemId, autoDb) => {
  				if (autoDb.dayUpdate) {
  					let curCount = BaseFacade.mItem.getItemAmount(parseInt(itemId));
  					let maxCount = this.getMaxCount(parseInt(itemId));
  					if (maxCount > curCount) {
  						BaseFacade.mItem.addItem(parseInt(itemId), maxCount - curCount, "AUTO_INCREASE");
  						this.m_data[itemId].time = Timer.time;
  						bChanged = true;
  					}
  				}
  			});
  		}
  		if (bChanged)
  			this.saveRecord();
  	}
  	saveRecord() {
  		FileRecord.setData("aotu_increase_data", this.m_data);
  		FileRecord.setData("auto_time_data", this.autoDayTime);
  	}
  	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.getItemAmount(itemId);
  		let maxCount = this.getMaxCount(itemId);
  		if (curCount >= maxCount) {
  			lastTime = Timer.time;
  			return lastTime;
  		}
  		let autoDb = db.get_auto_increase_db(itemId);
  		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, "AUTO_INCREASE");
  		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);
  		let maxAmount = 0;
  		if (autoDb && autoDb.maxCheckItemId) {
  			maxAmount = BaseFacade.mItem.getItemAmount(autoDb.maxCheckItemId);
  		}
  		return maxAmount || autoDb.maxAmount || Number.MAX_VALUE;
  	}
  	getNextTime(itemId) {
  		if (this.m_data[itemId]) {
  			let autoDb = db.get_auto_increase_db(itemId);
  			return this.m_data[itemId].time + autoDb.increaseDelta;
  		}
  		return 0;
  	}
  	getCd(itemId) {
  		this.refresh(itemId);
  		let maxAmount = this.getMaxCount(itemId);
  		if (maxAmount <= BaseFacade.mItem.getItemAmount(itemId)) {
  			return 0;
  		}
  		let nextTime = this.getNextTime(itemId);
  		let cd = Math.ceil(nextTime - Timer.time);
  		cd = Math.max(cd, 0);
  		return cd;
  	}
  	getIncreaseDelta(itemId) {
  		if (this.m_data && this.m_data[itemId]) {
  			let autoDb = db.get_auto_increase_db(itemId);
  			return autoDb.increaseDelta;
  		}
  	}
  	isMax(itemId) {
  		let autoDb = db.get_auto_increase_db(itemId);
  		if (autoDb && autoDb.maxCheckItemId) {
  			return BaseFacade.mItem.getItemAmount(itemId) >= BaseFacade.mItem.getItemAmount(autoDb.maxCheckItemId);
  		}
  		else {
  			return false;
  		}
  	}
  	setIncreaseItemAddedPerSec(itemId, addedPerSec) {
  		let data = this.m_data;
  		if (data && data[itemId]) {
  			let itemData = data[itemId];
  			let itemDb = db.get_auto_increase_db(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.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.getItemAmount(itemId);
  		if (cur < max) {
  			count = Math.min(max - cur, count);
  			BaseFacade.mItem.addItem(itemId, count, reason);
  			return true;
  		}
  		else {
  			return false;
  		}
  	}
  }

  class mDrop extends _mBase {
  	constructor() {
  		super(...arguments);
  		this.m_lotteryData = null;
  		this.m_dropData = null;
  	}
  	onLoad() {
  		this.loadRecord();
  	}
  	loadRecord() {
  		this.m_lotteryData = FileRecord.getData("lotter_data") || {};
  		this.m_dropData = FileRecord.getData("drop_data") || {};
  	}
  	saveRecord() {
  		FileRecord.setData("drop_data", this.m_dropData);
  	}
  	getAllDropItems(dropId) {
  		let allItem = [];
  		if (!dropId)
  			return allItem;
  		let dropDb = db.get_drop_db(dropId);
  		if (!dropDb)
  			return allItem;
  		for (let i = 0; i < dropDb.items.length; i++) {
  			const item = dropDb.items[i];
  			allItem.push({
  				itemId: item.id,
  				count: item.max,
  			});
  		}
  		return allItem;
  	}
  	getDropActive(dropId) {
  		let dropDb = db.get_drop_db(dropId);
  		if (!dropDb)
  			return false;
  		return BaseFacade.mSwitch.check(dropDb.switchId);
  	}
  	makeDrop(dropId) {
  		if (!dropId)
  			return [];
  		let dropDb = db.get_drop_db(dropId);
  		if (!dropDb)
  			return [];
  		if (!BaseFacade.mSwitch.check(dropDb.switchId))
  			return [];
  		let items;
  		switch (dropDb.type) {
  			case 1:
  				items = this.makeDrop_singleRate(dropDb);
  				break;
  			case 2:
  				items = this.makeDrop_roundRate(dropDb);
  				break;
  			case 3:
  				items = this.makeLottery(dropId, false);
  				break;
  			default:
  				return [];
  		}
  		BaseFacade.mSwitch.active(dropDb.switchId);
  		return items;
  	}
  	makeDrop_singleRate(dropDb) {
  		let ret = [];
  		let random;
  		let itemList = dropDb.items;
  		let bDrops = dropDb.bDrops;
  		if (itemList) {
  			for (let i = 0; i < itemList.length; i++) {
  				const item = itemList[i];
  				random = Mathf.random(10000);
  				if (random <= item.rate) {
  					let count = Mathf.random(item.min, item.max);
  					if (bDrops[item.idx]) {
  						for (let j = 0; j < count; j++) {
  							let items = this.makeDrop(item.id + "");
  							ret = ret.concat(items);
  						}
  					}
  					else {
  						ret.push({
  							itemId: item.id,
  							count: count,
  							index: i,
  						});
  					}
  				}
  			}
  		}
  		return ret;
  	}
  	makeDrop_roundRate(dropDb) {
  		let itemList = dropDb.items;
  		let bDrops = dropDb.bDrops;
  		if (itemList) {
  			let random = Mathf.random(10000);
  			for (let i = 0; i < itemList.length; i++) {
  				const item = itemList[i];
  				if (random <= item.rate) {
  					let count = Mathf.random(item.min, item.max);
  					if (bDrops[item.idx]) {
  						let items = [];
  						for (let j = 0; j < count; j++) {
  							items = items.concat(this.makeDrop(item.id + ""));
  						}
  						return items;
  					}
  					else {
  						return [{ itemId: item.id, count: count, index: i }];
  					}
  				}
  				random -= item.rate;
  			}
  		}
  		return [];
  	}
  	saveLotteryRecord() {
  		FileRecord.setData("lotter_data", this.m_lotteryData);
  	}
  	getLotteryActive(id) {
  		if (!id)
  			return false;
  		let dropDb = db.get_drop_db(id);
  		if (!dropDb || dropDb.type != 3)
  			return false;
  		if (dropDb.loop == 0) {
  			if (this.getCurLotteryIndex(id) >= dropDb.items.length) {
  				return false;
  			}
  		}
  		return BaseFacade.mSwitch.check(dropDb.switchId);
  	}
  	getCurLotteryIndex(id) {
  		let index = this.m_lotteryData[id];
  		if (index == undefined)
  			return 0;
  		return index;
  	}
  	getLotteryState(id, n) {
  		let active = this.getLotteryActive(id);
  		let index = this.getCurLotteryIndex(id);
  		if (n < index) {
  			return 1;
  		}
  		else if (n == index) {
  			if (active) {
  				return 0;
  			}
  			else {
  				return 2;
  			}
  		}
  		else {
  			return 2;
  		}
  	}
  	makeLottery(id, forPreview = false) {
  		if (!id)
  			return [];
  		let dropDb = db.get_drop_db(id);
  		if (!dropDb || dropDb.type != 3)
  			return [];
  		if (!BaseFacade.mSwitch.check(dropDb.switchId)) {
  			return [];
  		}
  		let index = this.m_lotteryData[id];
  		if (index == undefined)
  			index = 0;
  		if (index < 0)
  			return [];
  		let returnIndex = index;
  		let item = dropDb.items[returnIndex];
  		if (!item)
  			return [];
  		if (!forPreview) {
  			index++;
  			if (index >= dropDb.items.length) {
  				switch (dropDb.loop) {
  					case 0:
  						index = dropDb.items.length;
  						break;
  					case 1:
  						index = 0;
  						break;
  					case 2:
  						index = dropDb.items.length - 1;
  						break;
  					default:
  						console.error(`未知循环类型，lotteryId:[${id}]`);
  						return [];
  				}
  			}
  			this.m_lotteryData[id] = index;
  			this.saveLotteryRecord();
  		}
  		if (dropDb.bDrops[item.idx]) {
  			return this.makeDrop(item.id + "");
  		}
  		else {
  			return [{ itemId: item.id, count: Mathf.random(item.min, item.max), index: returnIndex }];
  		}
  	}
  }

  class DropIcon extends fgui.GLoader {
  	constructor() {
  		super();
  		this.userData = Object.create(null);
  		this.setSize(1, 1);
  		this.setPivot(0.5, 0.5, true);
  		this.touchable = false;
  		this.autoSize = true;
  	}
  	reuse() {
  		this.visible = true;
  	}
  	unuse() {
  		this.visible = false;
  		this._onClick = null;
  		this.alpha = 1;
  		this._itemId = null;
  		if (this.effect) {
  			this.effect.stopFollow();
  			this.effect.stop();
  			this.effect.removeSelf();
  		}
  		cc$1.clearTween(this);
  		this.removeFromParent();
  	}
  	dispose() {
  		if (this.effect) {
  			Global.poolManager.put(this.effect);
  			this.effect = null;
  		}
  		super.dispose();
  	}
  	setAutoAddItem(itemId, count, reason) {
  		this._itemId = itemId;
  		this._itemCount = count;
  		this._reason = reason;
  	}
  	setIcon(icon) {
  		this.url = icon;
  		return this;
  	}
  	showTuowei() {
  		if (this.effect) {
  			Director.scene3deffect.addChild(this.effect);
  			this.effect.play();
  			this.effect.followTarget(this, Director.cameraEffect);
  		}
  	}
  	putBack() {
  		if (this._itemId) {
  			BaseFacade.mItem.addItem(this._itemId, this._itemCount, this._reason);
  			this._itemId = null;
  		}
  		Global.poolManager.put(this);
  	}
  	setEffFinishCallback(func) {
  		this.effFinishCallback = func;
  	}
  	jumpOutAndJumpTo(fromPos, toPos, scale, onFinish, rndFly = false) {
  		let bigScale = scale * 1.5;
  		this.setScale(bigScale, bigScale);
  		let dir = Mathf.randomPlusOrMinus();
  		let midX = fromPos.x + dir * Mathf.random(10, 120);
  		let midY = fromPos.y + Mathf.random(10, 150);
  		let rndTime = Mathf.random(-10, 10) * 0.01;
  		let jumpHeight = Mathf.random(40, 70);
  		let tween = cc$1.tween(this);
  		this.setXY(fromPos.x, fromPos.y);
  		tween.parallel(cc$1.tween().then(cc$1.jumpTo(0.5 + rndTime, midX, midY, jumpHeight, 1)), cc$1.tween().repeat(3, cc$1.tween()
  			.to(0.1, { scaleX: 0.2 * bigScale, scaleY: 1.2 * bigScale })
  			.to(0.1, { scaleX: bigScale, scaleY: bigScale })))
  			.parallel(cc$1.tween().then(cc$1.jumpTo(0.3 + rndTime, midX, midY, jumpHeight / 3, 1)), cc$1.tween()
  				.to(0.15, { scaleX: 0.7 * bigScale, scaleY: 1.2 * bigScale })
  				.to(0.15, { scaleX: bigScale, scaleY: bigScale }))
  			.call(() => {
  				this.showTuowei();
  			});
  		if (rndFly) {
  			tween.delay(Mathf.random(5, 15) / 100);
  		}
  		else {
  			tween.delay(0.1);
  		}
  		tween.parallel(cc$1.tween().then(cc$1.jumpTo(0.6, toPos.x, toPos.y, 50, 1)), cc$1.tween().to(0.6, { scaleX: scale, scaleY: scale }))
  			.to(0.1, cc$1.PROP.ALPHA0)
  			.call(() => {
  				onFinish && onFinish();
  				if (this.effFinishCallback) {
  					this.effFinishCallback();
  					this.effFinishCallback = null;
  				}
  				this.putBack();
  			}).start();
  	}
  	burstOutAndJumpTo(fromPos, toPos, scale, onFinish, rndFly = false) {
  		let bigScale = scale * 1.5;
  		this.setScale(bigScale, bigScale);
  		this.setXY(fromPos.x, fromPos.y);
  		let dir = Mathf.random(Math.PI * 100) / 100;
  		let r = Mathf.random(50, 150);
  		let midPos = { x: fromPos.x + Math.cos(dir) * r, y: fromPos.y + Math.sin(dir) * r };
  		let rndTime = 0.6 + Mathf.random(-10, 10) * 0.02;
  		cc$1.tween(this, true).to(0.2, midPos, cc$1.OPTION.SINE_OUT).parallel(cc$1.tween().then(cc$1.bezierFromTo(rndTime, midPos, toPos, 0.3)), cc$1.tween().to(rndTime, { scaleX: scale, scaleY: scale })).call(() => {
  			onFinish && onFinish();
  			if (this.effFinishCallback) {
  				this.effFinishCallback();
  				this.effFinishCallback = null;
  			}
  			this.putBack();
  		}).start();
  	}
  	playJumpFrom(formX, fromY, onClick, callback, scale = 0.6, params) {
  		this.setXY(formX, fromY);
  		this.setScale(scale, scale);
  		let x, y;
  		if (params) {
  			x = formX + params.offsetX;
  			y = fromY + params.offsetY;
  		}
  		else {
  			x = formX + Mathf.randomPlusOrMinus() * Mathf.random(10, 120);
  			y = fromY + Mathf.random(10, 100);
  		}
  		let rndTime = Mathf.random(-10, 10) * 0.01;
  		let jumpHeight = Mathf.random(40, 70);
  		let tween = cc$1.tween(this)
  			.parallel(cc$1.tween().then(cc$1.jumpTo(0.5 + rndTime, x, y, jumpHeight, 1)), cc$1.tween().repeat(3, cc$1.tween()
  				.to(0.1, { scaleX: 0.2 * scale, scaleY: 1.2 * scale })
  				.to(0.1, { scaleX: scale, scaleY: scale }))).parallel(cc$1.tween().then(cc$1.jumpTo(0.3 + rndTime, x, y, jumpHeight / 3, 1)), cc$1.tween()
  					.to(0.15, { scaleX: 0.7 * scale, scaleY: 1.2 * scale })
  					.to(0.15, { scaleX: scale, scaleY: scale })).call(() => {
  						callback && callback(this);
  						if (this.effFinishCallback) {
  							this.effFinishCallback();
  							this.effFinishCallback = null;
  						}
  					});
  		tween.start();
  		this._onClick = onClick;
  	}
  	playFlyTo(toX, toY, onFinish) {
  		cc$1.clearTween(this);
  		cc$1.tween(this)
  			.then(cc$1.jumpTo(0.6, toX, toY, 50, 1))
  			.to(0.1, { scaleX: 1.2, scaleY: 1.2, alpha: 0 })
  			.call(() => {
  				onFinish && onFinish();
  				if (this.effFinishCallback) {
  					this.effFinishCallback();
  					this.effFinishCallback = null;
  				}
  				this.putBack.bind(this);
  			})
  			.start();
  	}
  }

  class DebugBanner {
  	static openIfTest() {
  		if (!Global.H5_TEST)
  			return;
  		if (!this.bannerNode) {
  			let bannerNode = new fgui.GComponent();
  			bannerNode.setSize(UIRoot.canvasWidth, 200);
  			let image = new fgui.GGraph();
  			image.setSize(UIRoot.canvasWidth, 200);
  			bannerNode.addChild(image);
  			image.drawRect(0, "", "#ffffff");
  			image.onClick(this, this.close);
  			let label = new fgui.GBasicTextField();
  			label.setPivot(0.5, 0.5, true);
  			bannerNode.addChild(label);
  			label.setXY(UIRoot.canvasWidth / 2, 100);
  			label.text = "假banner";
  			bannerNode.visible = false;
  			Director.getLayer(3).addChild(bannerNode).setXY(0, UIRoot.canvasHeight - 200);
  			this.bannerNode = bannerNode;
  			Global.registerListeners(this, {
  				[BASE_MSG.ADV_CLOSE_NATIVE_BANNER]: this.close.bind(this)
  			});
  		}
  		if (!this.bannerNode.visible) {
  			this.bannerNode.visible = true;
  		}
  	}
  	static close() {
  		if (this.bannerNode) {
  			if (this.bannerNode.visible) {
  				this.bannerNode.visible = false;
  			}
  		}
  	}
  }

  const DEFAULT_ADV_SHOW_DELTA_TIME = 0;
  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),
  		});
  		if (DEBUG_MODE) {
  			Logger.error("广告debug开启，如果了解请忽略。");
  		}
  	}
  	static saveRecord() {
  		FileRecord.setData("KEY_ADV_DATA", this.advData);
  	}
  	static onMsgDailySwitchActive() {
  		this.resetAllCount();
  	}
  	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) {
  			console.log("广告db无效");
  			return false;
  		}
  		if (!this.checkTypeActive(advDb.advType)) {
  			console.log("广告无次数或广告类型CD中");
  			return false;
  		}
  		if (!this.checkCount(adName)) {
  			console.log("广告点无次数");
  			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) {
  		let advDb = this.getAdvDb(advName);
  		if (checkGuide && mgrGuide.isGuiding())
  			return false;
  		if (DEBUG_MODE)
  			return true;
  		if (!this.getActive(advName))
  			return false;
  		if (advDb.advType == "video") {
  			if (!Mathf.randomEnable(this.getCopRatByKey(advDb.copKey, advDb.copIndex, advDb.defaultRate))) {
  				return false;
  			}
  		}
  		else if (advDb.advType == "banner" || advDb.advType == "interstitial") {
  			if (advDb.advType == "banner") {
  				let switchIndex = db.cop_db.ad_banner_switchs.indexOf(advDb.copIndex + 1);
  				if (switchIndex == -1) {
  					console.log("banner广告没有开启");
  					return false;
  				}
  				if (!Mathf.randomEnable(this.getCopRatByKey(advDb.copKey, switchIndex, advDb.defaultRate))) {
  					return false;
  				}
  			}
  			else if (advDb.advType == "interstitial") {
  				let switchIndex = db.cop_db.ad_interstitial_switchs.indexOf(advDb.copIndex + 1);
  				if (switchIndex == -1) {
  					console.log("插屏广告没有开启");
  					return false;
  				}
  				if (!Mathf.randomEnable(this.getCopRatByKey(advDb.copKey, switchIndex, advDb.defaultRate))) {
  					return false;
  				}
  			}
  		}
  		else {
  			if (!Mathf.randomEnable(this.getCopRatByKey(advDb.copKey, advDb.copIndex, advDb.defaultRate))) {
  				return false;
  			}
  		}
  		if (!this.checkCd(advName)) {
  			console.log("广告点CD中");
  			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 resetCD(advName) {
  		let advDb = this.getAdvDb(advName);
  		let info = this.advCnf[advDb.advType];
  		if (info) {
  			info.nextTime = Timer.time + info.deltaTime;
  		}
  		let config = this.advPointCnf[advDb.advName];
  		if (config) {
  			config.nextTime = Timer.time + config.deltaTime;
  		}
  		this.saveRecord();
  	}
  	static dispatchAdv(advName, params = null, ignoreCheck = false, showLoading = false) {
  		// if (!advName)
  		// 	return false;
  		// if (!this.hasAdv(advName))
  		// 	return false;
  		// console.log("调用广告", 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);
  		console.info(advDb);
  		if (advDb.pauseSound && mgrSound.musicEnabled) {
  			this.bSoundPaused = true;
  			mgrSound.pauseSound();
  		}
  		if (advDb.advType == "video") {
  			mgrTip.showMsgTip("看完视频可以获得奖励哟!");
  		}
  		let info = this.advCnf[advDb.advType];
  		if (info) {
  			info.nextTime = Timer.time + info.deltaTime;
  		}
  		let config = this.advPointCnf[advDb.advName];
  		if (config) {
  			config.nextTime = Timer.time + config.deltaTime;
  		}
  		console.info("触发广告", advName);
  		this.statisVideoClick(advName);
  		switch (Global.SDK_VERSION) {
  			case SDK_VERSIONS_VALUE.V6:
  				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.advId,
  			closeType: closeType,
  			userData: userData,
  		});
  	}
  	static statisVideoShow(adName) {
  		let advDb = this.getAdvDb(adName);
  		if (advDb && advDb.tag) {
  			GameStatistics.statisVideoPointEvent(advDb.tag, 1);
  		}
  	}
  	static statisVideoClick(adName) {
  		// console.info("33333333333333333333333333333333333333333333333");
  		let advDb = this.getAdvDb(adName);
  		if (advDb && advDb.tag) {
  			// console.info("2222222222222222222222222222222222222222222222222222");
  			GameStatistics.statisVideoPointEvent(advDb.tag, 2);
  		}
  	}
  	static dispatchToSdk_V5(advName, params) {
  		let advDb = this.getAdvDb(advName);
  		let userData = JSON.stringify({ advName: advName, params: params });
  		let advId = advDb.advId;
  		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) {
  		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.advId;
  		this.sendMsg(`MSG_AD_EVENT_START`, { adEventId: advName });
  		switch (advDb.advType) {
  			case "video":
  				this.sendMsg(BASE_MSG.SDK_VIDEO_VISIBLE, true);
  				if (!this.video_mode.bVideo) {
  					advId = "1";
  				}
  				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: "查看详情"
  					},
  				});
  			});
  		}
  	}
  	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(advName);
  		}
  		let userData = JSON.stringify({ advName: advName });
  		SDKBridge.sendToSdk("/c/closeAdv", {
  			advId: advDb.advId,
  			userData: userData,
  		});
  	}
  	static _openBannerNativeAdv(userData) {
  		console.info("9999999999999999999999999999999999999999999999999999999999");
  		DebugBanner.openIfTest();
  		if (this.panelNativeBanner) {
  			let panelClass = Director.getPanelClass(this.panelNativeBanner);
  			let view = Director.findPanel(panelClass);
  			if (view) {
  				view.visible = true;
  				return;
  			}
  			else {
  				Director.openPanel(this.panelNativeBanner, { userData: userData });
  			}
  		}
  		else {
  			Logger.warn("mgrAdv._openBannerNativeAdv 找不到panelNativeBanner.");
  		}
  	}
  	static _closeBannerNativeAdv(advName) {
  		let panelClass = Director.getPanelClass(this.panelNativeBanner);
  		let view = Director.findPanel(panelClass);
  		if (view) {
  			view.visible = false;
  			view[`fillEmpty`]();
  		}
  		this.closeNativeAdv(advName, false);
  	}
  	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) {
  		let advDb = this.getAdvDb(userData.advName);
  		if (!advDb)
  			return;
  		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) {
  		let advDb = this.getAdvDb(userData.advName);
  		if (!advDb)
  			return;
  		if (advDb.pauseSound && this.bSoundPaused) {
  			this.bSoundPaused = false;
  			mgrSound.resumeSound();
  		}
  		if (advDb.advType == "video") {
  			let fairyTryMode = db.cop_db.video_failed_retry_mode;
  			if (fairyTryMode == 0) {
  				this.sendMsg(BASE_MSG.ADV_SHOW_FAIL, userData);
  				this.sendMsg(BASE_MSG.SDK_VIDEO_VISIBLE, false);
  				msg && this.sendMsg(BASE_MSG.UI_SHOW_TIP, msg);
  			}
  			else if (fairyTryMode == 1) {
  				Director.openPanel(`PanelAdRetryDialog`, {
  					bShowAd: true,
  					cancelCallBack: () => {
  						this.sendMsg(BASE_MSG.ADV_SHOW_FAIL, userData);
  						this.sendMsg(BASE_MSG.SDK_VIDEO_VISIBLE, false);
  						msg && this.sendMsg(BASE_MSG.UI_SHOW_TIP, msg);
  					},
  					sureCallback: () => {
  						console.info("5555555555555555555555555555555555555");
  						
  						this.dispatchAdv(advDb.advName, userData, true);
  					}
  				});
  			}
  			else if (fairyTryMode == 2) {
  				Director.openPanel(`PanelAdRetryDialog`, {
  					bShowAd: false,
  					cancelCallBack: () => {
  						this.sendMsg(BASE_MSG.ADV_SHOW_FAIL, userData);
  						this.sendMsg(BASE_MSG.SDK_VIDEO_VISIBLE, false);
  						msg && this.sendMsg(BASE_MSG.UI_SHOW_TIP, msg);
  					},
  					sureCallback: () => {
  						console.info("5555555555555555555555555555555555555");
  						this.dispatchAdv(advDb.advName, userData, true);
  					}
  				});
  			}
  		}
  		else {
  			this.sendMsg(BASE_MSG.ADV_SHOW_FAIL, userData);
  		}
  	}
  	static openNativeAdvResult(data) {
  		// Advertisement.insertAdverV2();
  		console.info("9999999999999999999999999999999999999999999999999999999999");
  		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 {
  					let panelClass = Director.getPanelClass(this.panelNativeBanner);
  					let view = Director.findPanel(panelClass);
  					if (view) {
  						view.callIfLoaded(() => {
  							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) {
  		// Advertisement.insertAdverV2();
  		console.info("99999999999999999999999999999999999999999999999");
  		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.advId,
  			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);
  	}
  	static getAdvReward(advName) {
  		let advData = db.get_adv_db(advName);
  		let itemId = advData.rewardItemId || 1;
  		let amount = advData.rewardAmount || 0;
  		return {
  			itemId: itemId,
  			amount: amount,
  		};
  	}
  	static getGreyModelVideoComboGuideInfo(actionText) {
  		let infoArr = [
  			{ bDefaultChecked: true, desc: "需要", giveupBtnText: "确定", bCheckedTriggerAd: true },
  			{ bDefaultChecked: false, desc: "需要", giveupBtnText: "确定", bCheckedTriggerAd: true },
  			{ bDefaultChecked: true, desc: "不需要", giveupBtnText: "确定", bCheckedTriggerAd: false },
  			{ bDefaultChecked: false, desc: "不需要", giveupBtnText: "确定", bCheckedTriggerAd: false },
  		];
  		let info = Tools.deepCopy(Tools.randomGotOneArrayData(infoArr));
  		info.desc = `${info.desc}${actionText || ""}`;
  		return info;
  	}
  	static tryTriggerAdWhenClickNativeInsertClose() {
  		if (!db.cop_db.b_native_insert_close_click_trigger_ad) {
  			return false;
  		}
  		let lastTriggerTime = this.advData["_last_click_native_insert_close_trigger_ad_time"] || 0;
  		if ((Timer.now - lastTriggerTime) < db.cop_db.b_native_insert_close_click_trigger_ad_gap) {
  			return false;
  		}
  		if (!Tools.isOneDay(lastTriggerTime, Timer.now)) {
  			this.advData["_click_native_insert_close_triggered_ad_count"] = 0;
  		}
  		let triggeredAdCount = this.advData["_click_native_insert_close_triggered_ad_count"] || 0;
  		if (triggeredAdCount >= db.cop_db.b_native_insert_close_click_trigger_ad_daily_count) {
  			return false;
  		}
  		this.advData["_last_click_native_insert_close_trigger_ad_time"] = Timer.now;
  		this.advData["_click_native_insert_close_triggered_ad_count"] = this.advData["_click_native_insert_close_triggered_ad_count"] || 0;
  		this.advData["_click_native_insert_close_triggered_ad_count"]++;
  		this.saveRecord();
  		return true;
  	}
  }
  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;

  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);
  		effect.play(pos, time, stopDelay, Director.scene3deffect);
  		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("PanelPromptDialog", context);
  	}
  	static alertNotEnough(itemId, bShowTip = true, bSkip = false) {
  		let itemData = db.get_item_db(itemId);
  		bShowTip && mgrTip.showMsgTip(`${itemData.name}不足!`);
  		if (itemId == 3) {
  			let bTriggerAd = mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelVideoFreeEnergy_energy);
  			if (bTriggerAd) {
  				Director.openPanel(`PanelVideoFreeEnergy`);
  				return;
  			}
  		}
  	}
  	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}${item.count > 0 ? "+" : "-"}${Math.abs(item.count)}`;
  				}
  				else {
  					str = `${str}, ${itemDb.name}${item.count > 0 ? "+" : "-"}${Math.abs(item.count)}`;
  				}
  			}
  		}
  		else {
  			let itemDb = db.get_item_db(items.itemId);
  			str = `${itemDb.name}${items.count > 0 ? "+" : "-"}${Math.abs(items.count)}`;
  		}
  		this.showMsgTip(str);
  		callback && callback();
  	}
  	static alertSingleItem(item, bAdv = true, onClose) {
  		Director.openPanelByWait("PanelItemGet", { item: 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 playIconTo(worldPos, count = 1, view, toPos, scale = 0.5, rndFly = false, allFinishCall) {
  		if (!toPos)
  			return;
  		let items = [];
  		for (var i = 0; i < count; i++) {
  			let icon = Global.poolManager.get(DropIcon);
  			if (icon) {
  				items.push(icon);
  				let layer = Director.getLayer(2);
  				layer.addChild(icon);
  				icon.setIcon(view).burstOutAndJumpTo(worldPos, toPos, scale);
  			}
  		}
  		if (!!allFinishCall && items && items.length > 0) {
  			let tmp = items[items.length - 1];
  			tmp.setEffFinishCallback(() => {
  				allFinishCall && allFinishCall();
  			});
  		}
  		return items;
  	}
  	static addGotItemTip(itemId, amount, amountSteps, customerContext) {
  		let orderOfQueue = this.defaultGotItemQueue.length;
  		if (this.gotItemDialogShowingFlags[0] == true) {
  			orderOfQueue++;
  		}
  		this.defaultGotItemQueue.push({
  			itemId: itemId,
  			amount: amount,
  			amountSteps: amountSteps,
  			customerContext: customerContext,
  			orderOfQueue: orderOfQueue,
  		});
  		this._tryShowGotItemDialog();
  	}
  	static insertGotItemTip(itemId, amount, amountSteps, customerContext) {
  		this.defaultGotItemQueue.unshift({
  			itemId: itemId,
  			amount: amount,
  			amountSteps: amountSteps,
  			customerContext: customerContext,
  		});
  		this._tryShowGotItemDialog();
  	}
  	static addGotItemTipGroup(datas) {
  		let queue = null;
  		for (let i = 0; i < this.gotItemQueues.length; i++) {
  			const v = this.gotItemQueues[i];
  			if (v != this.defaultGotItemQueue && v.length <= 0) {
  				queue = v;
  			}
  		}
  		if (!queue) {
  			queue = [];
  			this.gotItemQueues.push(queue);
  		}
  		for (let i = 0; i < datas.length; i++) {
  			const v = datas[i];
  			queue.push(v);
  		}
  		this._tryShowGotItemDialog();
  	}
  	static isShowingGotItem() {
  		let bShowing = false;
  		Tools.forEachMap(this.gotItemDialogShowingFlags, (k, v) => {
  			if (v == true) {
  				bShowing = true;
  				return true;
  			}
  		});
  		return bShowing;
  	}
  	static _tryShowGotItemDialog() {
  		for (let queueIndex = 0; queueIndex < this.gotItemQueues.length; queueIndex++) {
  			const queue = this.gotItemQueues[queueIndex];
  			if (!this.gotItemDialogShowingFlags[queueIndex]) {
  				if (queue.length > 0) {
  					this.gotItemDialogShowingFlags[queueIndex] = true;
  					let v = queue.shift();
  					if (v.amount < 0) {
  						Director.openPanel(`PanelItemAmountTip`, {
  							itemId: v.itemId,
  							amount: v.amount,
  							fOnClose: () => {
  								this.gotItemDialogShowingFlags[queueIndex] = false;
  								this._tryShowGotItemDialog();
  							}
  						});
  					}
  					else {
  						let needShowItemIds = [
  							3,
  							2,
  							1,
  							4
  						];
  						if (needShowItemIds.indexOf(v.itemId) < 0 && v.itemId < 100) {
  							this.gotItemDialogShowingFlags[queueIndex] = false;
  							this._tryShowGotItemDialog();
  							return;
  						}
  						let viewName = `PanelPartGotDialog`;
  						let context = {};
  						if (v.customerContext) {
  							Tools.forEachMap(v.customerContext, (k, v) => {
  								context[k] = v;
  							});
  						}
  						context.orderOfQueue = v.orderOfQueue;
  						context.itemId = v.itemId;
  						context.amount = v.amount;
  						context.amountSteps = v.amountSteps;
  						context.fOnClose = () => {
  							this.gotItemDialogShowingFlags[queueIndex] = false;
  							if (v.customerContext && v.customerContext.fOnClose instanceof Function) {
  								v.customerContext.fOnClose();
  							}
  							this._tryShowGotItemDialog();
  						};
  						Director.openPanel(viewName, context);
  					}
  				}
  			}
  		}
  	}
  	static isPart(itemId) {
  		return false;
  	}
  	static doubleAdTip(advId, itemId, amount, callback) {
  		Director.openPanel(`PanelVideoDoubleReward`, {
  			advId: advId,
  			itemId: itemId,
  			callback: callback,
  			amount: amount,
  		});
  	}
  	static showBadgeWithNumber(node, count, offset = new Laya.Point(5, 5)) {
  		if (count > 0) {
  			return this.showBadge(node, offset);
  		}
  		else {
  			this.hideBadge(node);
  			return false;
  		}
  	}
  	static showBadge(node, offset = new Laya.Point(5, 5)) {
  		let badge = node["__badge"];
  		if (!badge) {
  			badge = new Laya.Sprite();
  			badge.size(18, 18);
  			badge.pivotX = 9;
  			badge.pivotY = 9;
  			badge.loadImage("res/redpoint.png");
  			node["__badge"] = badge;
  			node.addChild(badge);
  			cc$1.tween(badge)
  				.repeatForever(cc$1.tween()
  					.to(0.5, { scaleX: 1.25, scaleY: 1.25 })
  					.to(0.5, { scaleX: 1, scaleY: 1 }))
  				.start();
  			badge.pos(node.width - offset.x, offset.y);
  			return true;
  		}
  		badge.pos(node.width - offset.x, offset.y);
  		return false;
  	}
  	static hideBadge(node) {
  		if (node["__badge"]) {
  			node.removeChild(node["__badge"]);
  			node["__badge"] = null;
  		}
  	}
  	static waitGotItemClear(caller, callback) {
  		Timer.callLoop(0.016, (timer) => {
  			if (this.isShowingGotItem())
  				return;
  			timer.stop();
  			callback && callback();
  		}, caller);
  	}
  }
  mgrTip.defaultGotItemQueue = [];
  mgrTip.gotItemQueues = [mgrTip.defaultGotItemQueue];
  mgrTip.gotItemDialogShowingFlags = {};

  class mgrChannel extends Manager {
  	static 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),
  			[BASE_MSG.SDK_VIDEO_SHARE_SUC]: this.onMsgSdkVideoShareSuc.bind(this),
  			[BASE_MSG.SDK_VIDEO_SHARE_FAIL]: this.onMsgSdkVideoShareFail.bind(this),
  			[BASE_MSG.SDK_SHARE_SUC]: this.onMsgSdkShareSuc.bind(this),
  			[BASE_MSG.SDK_INSTALL_SHORTCUT_SUC]: this.onMsgSdkInstallShortcutSuc.bind(this),
  		});
  		super.onLoad();
  	}
  	static loadRecord() {
  		let data = FileRecord.getData("mgrChannel") || {};
  		this._userOpenVideoRecord = data._userOpenVideoRecord || true;
  		this._bVibrate = data._bVibrate || true;
  	}
  	static saveRecord() {
  		let record = {
  			_userOpenVideoRecord: this._userOpenVideoRecord,
  			_bVibrate: this._bVibrate,
  		};
  		FileRecord.setData("mgrChannel", record);
  	}
  	static onMsgSdkInstallShortcutSuc() {
  		if (mgrSdk.isInstallShortcut)
  			return;
  	}
  	static onMsgSdkAddItem(e) {
  		BaseFacade.mItem.addItem(e.itemId, e.count, `${e.reason}`);
  		mgrTip.addGotItemTip(e.itemId, e.count);
  	}
  	static onMsgPrePay(payId) {
  		let items = BaseFacade.mPay._onGetGoods(payId, "BEFORE_PAY");
  		mgrTip.alertItems(items);
  	}
  	static onMsgExitGame() {
  		if (this.bShowingExiting)
  			return;
  		this.bShowingExiting = true;
  		mgrTip.alertPrompt("要离开游戏了吗？", "提示", () => {
  			console.log("退出游戏");
  			this.bShowingExiting = false;
  			if (window[`conch`])
  				window[`conch`].exit();
  		}, () => {
  			this.bShowingExiting = false;
  		}, "离开", "继续");
  	}
  	static isSupportVibrate() {
  		return this._isSupportVibrate;
  	}
  	static set vibrateEnable(value) {
  		this._bVibrate = value;
  		this.saveRecord();
  	}
  	static get vibrateEnable() {
  		return this._bVibrate;
  	}
  	static getRecordRewardAmount() {
  		if (BaseFacade.mItem.getItemAmount(996) <= 0)
  			return 0;
  		if (!this.canUseVideoRecord())
  			return 0;
  		return BaseFacade.mItem.getItemAmount(997);
  	}
  	static setUserOpenVideoRecord(isOpen) {
  		this._userOpenVideoRecord = !!isOpen;
  		this.saveRecord();
  	}
  	static getUserOpenVideoRecord() {
  		return this._userOpenVideoRecord;
  	}
  	static haveVideoRecord() {
  		return db.cop_db.isSupportRecordShare;
  	}
  	static canUseVideoRecord() {
  		return this.haveVideoRecord() && this._userOpenVideoRecord;
  	}
  	static onMsgSdkVideoShareSuc(e) {
  		mgrTip.showMsgTip("录屏分享成功!");
  	}
  	static onMsgSdkVideoShareFail(e) {
  		mgrTip.showMsgTip("录屏分享失败!");
  	}
  	static getShareRewardAmount() {
  		if (BaseFacade.mItem.getItemAmount(994) <= 0)
  			return 0;
  		if (!this.canShare())
  			return 0;
  		return BaseFacade.mItem.getItemAmount(995);
  	}
  	static canShare() {
  		return db.cop_db.some_function[db.get_sub_cop(`b_share`).idx] == 1;
  	}
  	static onMsgSdkShareSuc(e) {
  	}
  }
  mgrChannel._bVibrate = true;
  mgrChannel.bShowingExiting = false;

  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_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;
  					}
  				}
  			}
  		}
  		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 = `http://${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;
  			Timer.callLater(0.016, () => {
  				this.downloadPatchByIndexed();
  			});
  		}
  		else {
  			this.startGame(true);
  		}
  	}
  	downloadPatchByIndexed() {
  		console.log("downloadPatchByIndexed:" + this.patchIdx);
  		let patchInfo = this.patchInfo;
  		let patch = this.patchs[this.patchIdx];
  		let patchFile = patch.pid + ".zip";
  		let packageUrl = `http://${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) {
  		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";

  const RECORD_VIDEO_KEY = "RecordVideioEnabled";
  const RECORD_ADD_GAME = "RecordAddGame";
  const RECORD_INSTALL_SHORTCUT = "RecordShortcut";
  let DEBUG_MODE$1 = false;
  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/getBaseChannelInfoResult", this.sdkback_getBaseChannelInfoResult.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/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/showPointDebugInfo", this.onShowPointDebugInfo.bind(this));
  				SDKBridge.registerCmd("/c/changePatchInfo", this.onChangePatchInfo.bind(this));
  				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();
  		if (DEBUG_MODE$1) {
  			Logger.error("SDK debug开启，如果了解请忽略。");
  		}
  	}
  	static setVersion(chnData) {
  		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", {});
  					break;
  				case SDK_VERSIONS_VALUE.V6:
  					SDKBridge.sendToSdk("/c/setVersion", {});
  					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.pop_review_ratio = Tools.safeParseInt(data.pop_review_ratio, 0);
  		mgrChannel._isSupportVibrate = !!data.isSupportVibrate;
  		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 getBaseChannelInfo() {
  		return this.baseChannelInfo;
  	}
  	static requestBaseChannelInfo() {
  		SDKBridge.sendToSdk("/c/getBaseChannelInfo");
  	}
  	static sdkback_getBaseChannelInfoResult(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 || "",
  				isStartGameByTouch: data.isStartGameByTouch || false,
  			};
  			this.sendMsg("MSG_SDK_BASE_CHANNEL_INFO_CHANGED");
  		}
  	}
  	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.msg, 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);
  				if (Global.H5_TEST)
  					Global.sendMsg(BASE_MSG.UI_SHOW_TIP, `[debug]:分享成功`);
  				this._lastShareData = null;
  			}
  		}
  	}
  	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: 1, count: 1 }, { goodsid: 1, 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"];
  				let count = v["count"];
  				this.tryAddItem(itemid, count, "CDKEY");
  			}
  		}
  		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 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 openAdvancedSetting() {
  		SDKBridge.sendToSdk("/c/openAdvancedSetting", {});
  	}
  	static onExtraBonus(data) {
  		if (data && data.code == 1) {
  			if (!FileRecord.getData("extraBonusReward")) {
  				console.log(`msg:${data.msg}  isInitGame:${data.isInitGame}`);
  				this.tryAddItem(1, 40, "GZH");
  				FileRecord.setData("extraBonusReward", true);
  			}
  		}
  	}
  	static openJump(type, count = 0) {
  		SDKBridge.sendToSdk("/c/openJump", {
  			gameIndex: Global.GAME_ID,
  			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], "JUMP_OTHER_GAME");
  			}
  			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) {
  			}
  		}
  	}
  	huaweiMsg(fn) {
  		const msg = Laya.LocalStorage.getItem("huaweiMsg");
  		if (!msg) {
  			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", {});
  					view.close();
  					// YYGMiniGames.showBanner()
  				});
  			}));
  		}
  	}
  	static installShortcut(userData = "") {
  		console.info("tianjiazhuomianbianyinsizhengce");
  		const msg = null;
  		// Laya.LocalStorage.getItem("huaweiMsg");
  		// if (!msg) {
  			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", {})
  					view.close();
  					// YYGMiniGames.showBanner()
  				});
  			}));
  		// }
  		// 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 onInstallShortcutResult(data) {
  		let userData = data.userData;
  		let msg = data.msg;
  		if (data.code == 1 || data.code == 2) {
  			Global.sendMsg(BASE_MSG.SDK_INSTALL_SHORTCUT_SUC, userData);
  			FileRecord.setData(RECORD_INSTALL_SHORTCUT, true);
  		}
  		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 tryStartRecord() {
  		if (!db.cop_db.isSupportRecordShare)
  			return;
  		this.startRecordVideo();
  	}
  	static resetRecordState() {
  		if (!db.cop_db.isSupportRecordShare)
  			return;
  		this.stopRecordVideo();
  		this.clearShareVideo();
  	}
  	static startRecordVideo(type = 2) {
  		if (!db.cop_db.isSupportRecordShare)
  			return;
  		if (this._isVideoRecording) {
  			this.stopRecordVideo();
  		}
  		this._isVideoRecording = true;
  		this._videoRecordTime = Timer.time;
  		SDKBridge.sendToSdk("/c/recorderGameVideo", { action: "start", durationTime: 120, type: type.toString() });
  	}
  	static pauseRecordVideo() {
  		SDKBridge.sendToSdk("/c/recorderGameVideo", { action: "pause", durationTime: 120, });
  	}
  	static resumeRecordVideo() {
  		SDKBridge.sendToSdk("/c/recorderGameVideo", { action: "resume", durationTime: 120, });
  	}
  	static stopRecordVideo() {
  		if (!db.cop_db.isSupportRecordShare)
  			return;
  		if (!this._isVideoRecording)
  			return;
  		this._isVideoRecording = false;
  		this._videoRecordTime = Timer.time - this._videoRecordTime;
  		SDKBridge.sendToSdk("/c/recorderGameVideo", { action: "stop", durationTime: 120, });
  	}
  	static onRecorderGameVideoResult(data) {
  		if (data) {
  			let code = data.code;
  			let type = data.type;
  			if (type == 2) {
  				this.min_record_time = 15;
  			}
  			else {
  				this.min_record_time = 3;
  			}
  			switch (code) {
  				case 0:
  					break;
  				case 1:
  					break;
  				case 2:
  					break;
  				case 3:
  					break;
  				case 4:
  					this._isVideoRecording = false;
  					this._videoRecordTime = Timer.time - this._videoRecordTime;
  					break;
  				default:
  					return;
  			}
  		}
  	}
  	static get isVideoAutoRecordable() {
  		return db.cop_db.isSupportRecordShare && !this._isVideoRecording;
  	}
  	static get isVideoShareable() {
  		return db.cop_db.isSupportRecordShare && !this._isVideoRecording && this._videoRecordTime > this.min_record_time;
  	}
  	static get isVideoRecording() {
  		return db.cop_db.isSupportRecordShare && this._isVideoRecording;
  	}
  	static showVideoRecordDialog(texture2d, tScaleY, fOnClose) {
  		if (mgrGuide.isGuiding()) {
  			fOnClose && fOnClose();
  			return;
  		}
  		if (this._isVideoRecording) {
  			fOnClose && fOnClose();
  			return;
  		}
  		;
  		if (this._videoRecordTime < this.min_record_time) {
  			fOnClose && fOnClose();
  			return;
  		}
  		;
  		if (this._videoRecordTime >= 180) {
  			fOnClose && fOnClose();
  			return;
  		}
  		;
  		Director.openPanel(`PanelVideoRecordDialog`, {
  			texture2d: texture2d,
  			tScaleY: tScaleY,
  			fOnClose: fOnClose
  		});
  	}
  	static shareVideo(userData = "") {
  		if (this._isVideoRecording)
  			return;
  		if (this._videoRecordTime > this.min_record_time) {
  			SDKBridge.sendToSdk("/c/shareGameVideo", { userData: userData });
  			if (Global.H5_TEST || DEBUG_MODE$1) {
  				Timer.callLater(1, () => {
  					this.onShareGameVideoResult({ code: 1, userData: userData });
  					Global.sendMsg(BASE_MSG.UI_SHOW_TIP, `[debug]:视频分享成功`);
  				});
  			}
  		}
  		else {
  			Global.sendMsg(BASE_MSG.UI_SHOW_TIP, `视频分享失败`);
  			console.log("录屏时长不够!");
  		}
  	}
  	static clearShareVideo() {
  		this._videoRecordTime = 0;
  	}
  	static onShareGameVideoResult(data) {
  		if (data) {
  			if (data.code == 1) {
  				console.log("分享视频成功");
  				Global.sendMsg(BASE_MSG.SDK_VIDEO_SHARE_SUC);
  			}
  			else {
  				console.log("分享视频失败");
  				Global.sendMsg(BASE_MSG.SDK_VIDEO_SHARE_FAIL);
  			}
  		}
  	}
  	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;
  		Global.sendMsg(BASE_MSG.SDK_LOGIN_RESULT, this.isUserLogin);
  	}
  	static openCrossRecommend(left, top, typeId = 0) {
  		if (!db.cop_db.isSupportRecommendationBtn)
  			return;
  		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 openGrid(x, y, userData, type = "single", width, height) {
  		console.log("mgrsdk openGrid====", x, y, type);
  		SDKBridge.sendToSdk("/c/openGridAd", {
  			userData: { userData },
  			style: {
  				x: x,
  				y: y,
  				width: width,
  				height: height,
  			},
  			type: type,
  		});
  	}
  	static openNativeWxAdv(layout, tag = 1, userData) {
  		SDKBridge.sendToSdk("/c/openAdv", { advId: 6, tag: tag, layout: layout, userData: userData || `{}` });
  	}
  	static closeNativeWxAdv(tag) {
  		SDKBridge.sendToSdk("/c/closeAdv", {
  			advId: 6,
  			tag: tag,
  			userData: {}
  		});
  	}
  	static closeGridAd(type = "single") {
  		console.log("mgrsdk closeGridAd===", type);
  		SDKBridge.sendToSdk("/c/closeGridAd", {
  			userData: {},
  			type: type,
  		});
  	}
  	static onFollowOfficialAccountResult(data) {
  		let code = data.code;
  		if (code == 1) {
  			this.followState = 1;
  			Global.sendMsg(BASE_MSG.SDK_FOLLOW_OFFICIAL_ACCOUNT_SUC, data);
  		}
  		else {
  			this.followState = 2;
  			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 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 onShowPointDebugInfo(data) {
  		let state = data.state;
  		console.log("打点状态", state);
  		this.sendMsg("MSG_SHOW_POINT_DEBUG_INFO", data);
  	}
  	static vibrate(type = "short", intensity = "light", userData = null) {
  		SDKBridge.sendToSdk("/c/phoneVibrate", {
  			type: type,
  			intensity: intensity,
  			userData: userData,
  		});
  	}
  }
  mgrSdk.COP_INFO = "";
  mgrSdk.isChnResult = false;
  mgrSdk.isInstallShortcutHasPrompt = false;
  mgrSdk.isSupportJumpList = false;
  mgrSdk.isUserLogin = false;
  mgrSdk.h5_channel = "";
  mgrSdk.baseChannelInfo = null;
  mgrSdk.packageVersion = "0";
  mgrSdk.ulsdkVersion = "0";
  mgrSdk.isMusicEnable = false;
  mgrSdk.findmeImageUrl = "";
  mgrSdk.followState = 2;
  mgrSdk.uuid = "0";
  mgrSdk.gameName = "";
  mgrSdk.licenceInfo = "";
  mgrSdk.bMgrLoaded = false;
  mgrSdk.allMgrLoadedMsgs = [];
  mgrSdk._testJumpInfo = [];
  mgrSdk._isVideoRecording = false;
  mgrSdk._videoRecordTime = 0;
  mgrSdk.min_record_time = 3;

  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, reason, callback, 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 == 999) {
  					mgrSdk.openPay(payDb.payCode, payId, (suc, msg, timeout) => {
  						let items;
  						if (suc) {
  							items = this._onGetGoods(payId, undefined, true);
  						}
  						else {
  							Global.sendMsg(BASE_MSG.UI_SHOW_TIP, msg);
  						}
  						callback(suc, items);
  					});
  					return;
  				}
  				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);
  		let allitems = [];
  		if (payDb.getItemId) {
  			BaseFacade.mItem.addItem(payDb.getItemId, payDb.getCount, reason);
  			allitems.push({
  				itemId: payDb.getItemId,
  				count: payDb.getCount,
  			});
  		}
  		if (payDb.dropId) {
  			let items = BaseFacade.mDrop.getAllDropItems(payDb.dropId);
  			for (let i = 0; i < items.length; i++) {
  				const element = items[i];
  				BaseFacade.mItem.addItem(element.itemId, element.count, reason);
  			}
  			allitems.concat(items);
  		}
  		Global.sendMsg(BASE_MSG.PAY_SUC, payId);
  		if (payDb.statistics) {
  			GameStatistics.statisOnItemBought(payDb.statistics, 1);
  		}
  		return allitems;
  	}
  	isCostEnough(payId) {
  		let payDb = db.get_pay_db(payId);
  		if (!payDb) {
  			return false;
  		}
  		if (payDb.costItemId == 999) {
  			return true;
  		}
  		else {
  			if (payDb.firstCostItemId)
  				return BaseFacade.mItem.isEnoughItem(payDb.firstCostItemId, payDb.firstCostCount);
  			return BaseFacade.mItem.isEnoughItem(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.mGoal = this.createMgr(mGoal);
  		this.mSwitch = this.createMgr(mSwitch);
  		this.mItem = this.createMgr(mItem);
  		this.mAutoIncreaseItem = this.createMgr(mAutoIncreaseItem);
  		this.mDrop = this.createMgr(mDrop);
  		this.mPay = this.createMgr(mPay);
  		this.initAll();
  		this._isLoaded = true;
  	}
  	static createMgr(mgrClass) {
  		let mgr = new mgrClass(new MsgHandler());
  		this._mgrs.push(mgr);
  		return mgr;
  	}
  	static initAll() {
  		for (let i = 0; i < this._mgrs.length; i++) {
  			this._mgrs[i].onLoad();
  		}
  		for (let i = 0; i < this._mgrs.length; i++) {
  			this._mgrs[i].onStart();
  		}
  	}
  }
  BaseFacade._isLoaded = false;
  BaseFacade._mgrs = [];

  var Keyboard = Laya.Keyboard;
  class mgrDebug extends Manager {
  	static onLoad() {
  		Laya.stage.on(Laya.Event.KEY_DOWN, this, this.onKeyDown);
  		Laya.stage.on(Laya.Event.KEY_UP, this, this.onKeyUp);
  		super.onLoad();
  		Global.registerListeners(this, {
  			["MSG_SHOW_POINT_DEBUG_INFO"]: this.onMsgShowPointDebugInfo.bind(this),
  		});
  	}
  	static onKeyUp(e) {
  		this.bCtrl = e.ctrlKey;
  		this.bShift = e.shiftKey;
  		this.bAlt = e.altKey;
  	}
  	static onKeyDown(e) {
  		this.bCtrl = e.ctrlKey;
  		this.bShift = e.shiftKey;
  		this.bAlt = e.altKey;
  		switch (e.keyCode) {
  			case Keyboard.A:
  				break;
  			case Keyboard.B:
  				break;
  			case Keyboard.D:
  				break;
  			case Keyboard.C:
  				if (e.altKey) {
  					let context = {
  						desc: "是否清除存档?\n(下次启动有效)",
  						confirm: () => {
  							FileRecord.deletAllData(false);
  						},
  						cancel: () => { }
  					};
  					mgrTip.alertPrompt(context);
  				}
  				break;
  			case Keyboard.Q:
  				if (e.ctrlKey) {
  					Director.openPanelWithSingleton(`DebugMain`);
  				}
  				break;
  			case Keyboard.T:
  				Director.hideWait();
  				break;
  			case Keyboard.L:
  				break;
  			case Keyboard.G:
  				if (e.ctrlKey) {
  					mgrGuide.endGuide();
  				}
  				break;
  			case Keyboard.I:
  				break;
  			default:
  				break;
  		}
  	}
  	static onMsgShowPointDebugInfo(e) {
  		this.bShowStatisticsInfo = !!e.state;
  		if (this.bShowStatisticsInfo) {
  			this.uiTipInfoDialog = Director.openPanel("PanelUiTipInfoDialog");
  		}
  		else {
  			if (!!this.uiTipInfoDialog && !this.uiTipInfoDialog.destroyed) {
  				this.uiTipInfoDialog.close(true);
  				this.uiTipInfoDialog = null;
  			}
  		}
  	}
  }
  mgrDebug.bShowStatisticsInfo = false;

  class mgrDynamicBone extends Manager {
  	static onLoad() {
  		this.loadEditorData(() => {
  			super.onLoad();
  		});
  	}
  	static loadEditorData(callback) {
  		ResLoader.loadRes("res/cfg/dynamicBone.json", Laya.Loader.JSON, (data) => {
  			this.dynamicEditorData = data;
  			callback();
  		});
  	}
  	static getDynamicConfig(key) {
  		if (this.dynamicEditorData[key]) {
  			return Tools.deepCopy(this.dynamicEditorData[key]);
  		}
  		return null;
  	}
  	static setDynamicConfig(key, config) {
  		if (config == null) {
  			delete this.dynamicEditorData[key];
  		}
  		else {
  			this.dynamicEditorData[key] = config;
  		}
  		this.recordDynamicConfig();
  	}
  	static recordDynamicConfig() {
  		if (!GameRemoteRouter.instance) {
  			Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "未链接存档服务器,尝试重新连接!");
  		}
  		else {
  			GameRemoteRouter.instance.sendMsgToServer({
  				route: "keepInFile",
  				data: {
  					filePath: `res/cfg/dynamicBone.json`,
  					data: this.dynamicEditorData,
  				},
  			});
  		}
  	}
  }
  mgrDynamicBone.dynamicEditorData = {};

  var ROLE_EXP_TYPE;
  (function (ROLE_EXP_TYPE) {
  	ROLE_EXP_TYPE[ROLE_EXP_TYPE["trial"] = 0] = "trial";
  	ROLE_EXP_TYPE[ROLE_EXP_TYPE["theature"] = 1] = "theature";
  	ROLE_EXP_TYPE[ROLE_EXP_TYPE["beaut"] = 2] = "beaut";
  	ROLE_EXP_TYPE[ROLE_EXP_TYPE["diy"] = 3] = "diy";
  })(ROLE_EXP_TYPE || (ROLE_EXP_TYPE = {}));
  class mgrRole extends Manager {
  	static onLoad() {
  		super.onLoad();
  	}
  	static loadRecord() {
  		let data = FileRecord.getData("mgrRole") || {};
  		this.property1Value = data.property1Value || 0;
  		this.property2Value = data.property2Value || 0;
  		this.property3Value = data.property3Value || 0;
  		this.property4Value = data.property4Value || 0;
  		this.playerRoleId = data.playerRoleId || 0;
  		this.bBornedOnce = !!data.bBornedOnce;
  		this.arrivedRoleIdDict = data.arrivedRoleIdDict || {};
  		this.activedRoleIdDict = data.activedRoleIdDict || {};
  		this.historyGotProperty1 = data.historyGotProperty1 || 0;
  		this.historyGotProperty2 = data.historyGotProperty2 || 0;
  		this.historyGotProperty3 = data.historyGotProperty3 || 0;
  		this.historyGotProperty4 = data.historyGotProperty4 || 0;
  		this.gotPropertyExtrnalLevel = data.gotPropertyExtrnalLevel || 0;
  		this.bornCount = data.bornCount || 0;
  		this.bCompletedGrownupLineSelect = data.bCompletedGrownupLineSelect || false;
  		this.currentUsingGrownupLine = data.currentUsingGrownupLine || 0;
  		this.nextResultQuestionId = data.nextResultQuestionId || 0;
  		this.answeredQuestionIdDict = data.answeredQuestionIdDict || {};
  		this.arrivedGrownupLineDict = data.arrivedGrownupLineDict || {};
  		let validDict = {};
  		for (let k in this.arrivedRoleIdDict) {
  			let roleId = parseInt(k);
  			let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(roleId);
  			if (!roleData) {
  				continue;
  			}
  			validDict[parseInt(k)] = true;
  		}
  		this.arrivedRoleIdDict = validDict;
  	}
  	static saveRecord() {
  		let record = {
  			property1Value: this.property1Value || 0,
  			property2Value: this.property2Value || 0,
  			property3Value: this.property3Value || 0,
  			property4Value: this.property4Value || 0,
  			playerRoleId: this.playerRoleId,
  			bBornedOnce: !!this.bBornedOnce,
  			arrivedRoleIdDict: this.arrivedRoleIdDict || {},
  			activedRoleIdDict: this.activedRoleIdDict || {},
  			historyGotProperty1: this.historyGotProperty1,
  			historyGotProperty2: this.historyGotProperty2,
  			historyGotProperty3: this.historyGotProperty3,
  			historyGotProperty4: this.historyGotProperty4,
  			gotPropertyExtrnalLevel: this.gotPropertyExtrnalLevel,
  			bornCount: this.bornCount,
  			bCompletedGrownupLineSelect: this.bCompletedGrownupLineSelect || false,
  			currentUsingGrownupLine: this.currentUsingGrownupLine,
  			nextResultQuestionId: this.nextResultQuestionId,
  			answeredQuestionIdDict: this.answeredQuestionIdDict,
  			arrivedGrownupLineDict: this.arrivedGrownupLineDict,
  		};
  		FileRecord.setData("mgrRole", record);
  	}
  	static resetGameUserRecord() {
  		FileRecord.setData("mgrRole", {});
  		this.loadRecord();
  	}
  	static isAnsweredQuestionId(qId) {
  		return !!this.answeredQuestionIdDict[qId];
  	}
  	static markAnsweredQuestionId(qId) {
  		this.answeredQuestionIdDict[qId] = true;
  		this.saveRecord();
  	}
  	static getNextResultQuestionId() {
  		return this.nextResultQuestionId;
  	}
  	static setNextResultQuestionId(qId) {
  		this.nextResultQuestionId = qId;
  		this.saveRecord();
  	}
  	static getUsingGrownupLine() {
  		return this.currentUsingGrownupLine || 0;
  	}
  	static setUsingGrownupLine(grownupLine) {
  		let oldLine = this.currentUsingGrownupLine || 0;
  		this.currentUsingGrownupLine = grownupLine || 0;
  		if (oldLine && this.currentUsingGrownupLine && oldLine != this.currentUsingGrownupLine) {
  			this.nextResultQuestionId = 0;
  		}
  		this.arrivedGrownupLineDict[oldLine] = true;
  		this.arrivedGrownupLineDict[this.currentUsingGrownupLine] = true;
  		this.saveRecord();
  	}
  	static isArrivedGrownupLine(growupLine) {
  		return !!this.arrivedGrownupLineDict[growupLine];
  	}
  	static upgradeGotPropertyExtrnalLevel() {
  		let data = db.get_ggg_extra_item_property_template_db((this.gotPropertyExtrnalLevel || 0) + 1);
  		if (!data) {
  			return;
  		}
  		GameStatistics.statisCommonEvent(data.statisPointId, 0, data.level);
  		this.gotPropertyExtrnalLevel++;
  		this.saveRecord();
  	}
  	static setGotPropertyExtrnalLevel(level) {
  		this.gotPropertyExtrnalLevel = level;
  		let data = db.get_ggg_extra_item_property_template_db((this.gotPropertyExtrnalLevel || 0) + 1);
  		if (!data) {
  			return;
  		}
  		GameStatistics.statisCommonEvent(data.statisPointId, 1, data.level);
  		this.saveRecord();
  	}
  	static getGotPropertyExtrnalLevel() {
  		return this.gotPropertyExtrnalLevel || 0;
  	}
  	static isMaxGotPropertyExtrnalLevel() {
  		let data = db.get_ggg_extra_item_property_template_db((this.gotPropertyExtrnalLevel || 0) + 1);
  		if (!data) {
  			return true;
  		}
  		return false;
  	}
  	static getCurrLevelGotPropertyExtrnalValue() {
  		let data = db.get_ggg_extra_item_property_template_db(this.gotPropertyExtrnalLevel || 0) || {};
  		return data.count || 0;
  	}
  	static getNextLevelGotPropertyExtrnalValue() {
  		let data = db.get_ggg_extra_item_property_template_db((this.gotPropertyExtrnalLevel || 0) + 1) || {};
  		return data.count || 0;
  	}
  	static getNextLevelGotPropertyExtrnalUpgradeCostItemId() {
  		let data = db.get_ggg_extra_item_property_template_db(this.gotPropertyExtrnalLevel || 0) || {};
  		return data.upgradeCostItemId || 2;
  	}
  	static getNextLevelGotPropertyExtrnalUpgradeCostItemAmount() {
  		let data = db.get_ggg_extra_item_property_template_db(this.gotPropertyExtrnalLevel || 0) || {};
  		return data.upgradeCostItemAmount || 10;
  	}
  	static isCurrLevelUseAdUpgradeGotPropertyExtrnal() {
  		let data = db.get_ggg_extra_item_property_template_db(this.gotPropertyExtrnalLevel || 0) || {};
  		return !!data.bAdCost;
  	}
  	static tryAddArrivedRoleId(roleId) {
  		this.arrivedRoleIdDict[roleId] = true;
  		this.saveRecord();
  	}
  	static isArrivedRoleId(roleId) {
  		return !!this.arrivedRoleIdDict[roleId];
  	}
  	static getAllArrivedRoleIdArr() {
  		let arr = [];
  		for (let k in this.arrivedRoleIdDict) {
  			let roleId = parseInt(k);
  			let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(roleId);
  			if (!roleData || !roleData.grownupLine) {
  				continue;
  			}
  			arr.push(parseInt(k));
  		}
  		return arr;
  	}
  	static getAllCanBornRoleIdArr(grownupLine) {
  		let arrData = [];
  		for (let k in this.arrivedRoleIdDict) {
  			let roleId = parseInt(k);
  			let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(roleId);
  			if (!roleData || !roleData.grownupLine) {
  				continue;
  			}
  			if (!!grownupLine && roleData.grownupLine != grownupLine) {
  				continue;
  			}
  			arrData.push(roleData);
  		}
  		arrData = Tools.sortArrayByField(arrData, "-level");
  		let arr = [];
  		for (let k in arrData) {
  			arr.push(arrData[k].id);
  		}
  		return arr;
  	}
  	static getAllActivedRoleIdArr() {
  		let arr = [];
  		for (let k in this.activedRoleIdDict) {
  			arr.push(parseInt(k));
  		}
  		return arr;
  	}
  	static isActivedRoleId(roleId) {
  		if (!this.arrivedRoleIdDict[roleId]) {
  			return false;
  		}
  		return !!this.activedRoleIdDict[roleId];
  	}
  	static addActivedRoleId(roleId) {
  		this.activedRoleIdDict[roleId] = true;
  		this.saveRecord();
  	}
  	static isCompletedGrownupLineSelect() {
  		return this.bCompletedGrownupLineSelect;
  	}
  	static markCompletedGrownupLineSelect() {
  		this.bCompletedGrownupLineSelect = true;
  		this.saveRecord();
  	}
  	static isBornOnce() {
  		return !!this.bBornedOnce;
  	}
  	static markBornOnce() {
  		this.bBornedOnce = true;
  		this.bornCount++;
  		this.saveRecord();
  	}
  	static getCurrentPropertyRoleId(bUsingRoleIdAsDefault) {
  		return this.getPlayerRoleIdByProperty(this.property1Value, this.property2Value, this.property3Value, this.property4Value, bUsingRoleIdAsDefault);
  	}
  	static setUsingPlayerRoleId(roleId) {
  		if (!!roleId && this.playerRoleId != roleId) {
  			Global.sendMsg("MSG_USING_PLAYER_ROLE_CHANGED");
  		}
  		this.playerRoleId = roleId;
  		let roleDataUsing = db.get_amaze_cloth_crossing_property_to_logic_role(roleId);
  		if (!!roleDataUsing.grownupLine) {
  			mgrRole.setUsingGrownupLine(roleDataUsing.grownupLine);
  		}
  		this.saveRecord();
  	}
  	static getUsingPlayerRoleId() {
  		return this.playerRoleId || this.getCurrentPropertyRoleId(true);
  	}
  	static addPropertyValue(p1, p2, p3, p4) {
  		this.property1Value += (p1 || 0);
  		this.property2Value += (p2 || 0);
  		this.property3Value += (p3 || 0);
  		this.property4Value += (p4 || 0);
  		this.saveRecord();
  	}
  	static setPropertyValue(p1, p2, p3, p4) {
  		this.property1Value = (p1 || 0);
  		this.property2Value = (p2 || 0);
  		this.property3Value = (p3 || 0);
  		this.property4Value = (p4 || 0);
  		this.saveRecord();
  	}
  	static setPropertyValueByGrownunLine(grownupLine, value) {
  		this[`property${grownupLine}Value`] = (value || 0);
  		this.saveRecord();
  	}
  	static getPropertyValueByGrownunLine(grownupLine) {
  		return this[`property${grownupLine}Value`] || 0;
  	}
  	static getProperty1() {
  		return this.property1Value;
  	}
  	static getProperty2() {
  		return this.property2Value;
  	}
  	static getProperty3() {
  		return this.property3Value;
  	}
  	static getProperty4() {
  		return this.property4Value;
  	}
  	static getMaxProperty() {
  		let maxType = 1;
  		let maxValue = 0;
  		for (let i = 0; i < 4; i++) {
  			let temp = this["getProperty" + (i + 1)]();
  			if (temp > maxValue) {
  				maxValue = temp;
  				maxType = (i + 1);
  			}
  		}
  		return [maxType, maxValue];
  	}
  	static getBornPlayerRoleIdIgnoreGrownup(p1, p2, p3, p4) {
  		let dbMap = db.get_amaze_cloth_crossing_property_to_logic_role_map();
  		let dbArr = [];
  		for (let k in dbMap) {
  			let data = dbMap[k];
  			dbArr.push(data);
  		}
  		dbArr = Tools.sortArrayByField(dbArr, [`-level`]);
  		let allP = p1 + p2 + p3 + p4;
  		for (let i = 0; i < dbArr.length; i++) {
  			let data = dbArr[i];
  			if (p1 >= data.property_1 && p2 >= data.property_2 && p3 >= data.property_3 && p4 >= data.property_4 && allP >= data.property_1_2_3_4 && data.level != 0) {
  				return data.id;
  			}
  		}
  		let index2ValueDict = {
  			[1]: p1,
  			[2]: p2,
  			[3]: p3,
  			[4]: p4,
  		};
  		let index1 = p1 > p2 ? 1 : 2;
  		let index2 = p3 > p4 ? 3 : 4;
  		let index = index2ValueDict[index1] > index2ValueDict[index2] ? index1 : index2;
  		dbArr = Tools.sortArrayByField(dbArr, [`level`]);
  		for (let i = 0; i < dbArr.length; i++) {
  			let data = dbArr[i];
  			if (!data["property_" + index]) {
  				continue;
  			}
  			return data.id;
  		}
  		return 0;
  	}
  	static getSortedPropertyIndexArr(p1, p2, p3, p4) {
  		let propertyInfoArr = [
  			{ propertyIndex: 1, propertyValue: p1 },
  			{ propertyIndex: 2, propertyValue: p2 },
  			{ propertyIndex: 3, propertyValue: p3 },
  			{ propertyIndex: 4, propertyValue: p4 },
  		];
  		propertyInfoArr = Tools.sortArrayByField(propertyInfoArr, "-propertyValue");
  		return propertyInfoArr;
  	}
  	static getPlayerRoleIdByProperty(p1, p2, p3, p4, bUsingRoleIdAsDefault) {
  		let usingGrownupLine = this.getUsingGrownupLine();
  		let propertyIndexArr = this.getSortedPropertyIndexArr(p1, p2, p3, p4);
  		let dbMap = db.get_amaze_cloth_crossing_property_to_logic_role_map();
  		let dbArr = [];
  		for (let k in dbMap) {
  			let data = dbMap[k];
  			if (usingGrownupLine && data.grownupLine && usingGrownupLine != data.grownupLine) {
  				continue;
  			}
  			if ((!!data.property_1 && p1 >= data.property_1) ||
  				(!!data.property_2 && p2 >= data.property_2) ||
  				(!!data.property_3 && p3 >= data.property_3) ||
  				(!!data.property_4 && p4 >= data.property_4)) {
  				data["__property_value"] = data.property_1 || data.property_2 || data.property_3 || data.property_4 || 0;
  				for (let tmp = 0; tmp < propertyIndexArr.length; tmp++) {
  					let tmpData = propertyIndexArr[tmp];
  					if (!!data["property_" + tmpData.propertyIndex]) {
  						data["__rank_order"] = tmp;
  						break;
  					}
  				}
  				dbArr.push(data);
  			}
  		}
  		dbArr = Tools.sortArrayByField(dbArr, [`-level`, `__rank_order`, `-__property_value`]);
  		if (!dbArr || dbArr.length == 0) {
  			if (bUsingRoleIdAsDefault) {
  				return this.getUsingPlayerRoleId();
  			}
  			else {
  				return 0;
  			}
  		}
  		return dbArr[0].id;
  	}
  	static getArrivedMaxLevelRoleIdByGrownline(grownupLine) {
  		let ids = this.getAllCanBornRoleIdArr(grownupLine);
  		if (!ids || ids.length == 0) {
  			return 0;
  		}
  		return ids[0];
  	}
  	static getRoleDataByGrownlineAndLevel(grownupLine, level) {
  		let dbMap = db.get_amaze_cloth_crossing_property_to_logic_role_map();
  		for (let k in dbMap) {
  			let data = dbMap[k];
  			if (grownupLine == data.grownupLine && data.level == level) {
  				return data;
  			}
  		}
  		return null;
  	}
  	static getMaxLevelRoleDataByGrownline(grownupLine) {
  		let dbMap = db.get_amaze_cloth_crossing_property_to_logic_role_map();
  		let dbArr = [];
  		for (let k in dbMap) {
  			let data = dbMap[k];
  			if (grownupLine != data.grownupLine) {
  				continue;
  			}
  			dbArr.push(data);
  		}
  		dbArr = Tools.sortArrayByField(dbArr, [`-level`]);
  		if (!dbArr || dbArr.length == 0) {
  			return null;
  		}
  		return dbArr[0];
  	}
  	static getMaxLevelRoleIdByGrownline(grownupLine) {
  		let roleData = this.getMaxLevelRoleDataByGrownline(grownupLine);
  		if (!roleData || !roleData) {
  			return 0;
  		}
  		return roleData.id;
  	}
  	static getMaxLevelByGrownline(grownupLine) {
  		let data = this.getMaxLevelRoleDataByGrownline(grownupLine);
  		if (!data) {
  			return 0;
  		}
  		return data.level;
  	}
  	static getMinLevelRoleDataByGrownline(grownupLine) {
  		let dbMap = db.get_amaze_cloth_crossing_property_to_logic_role_map();
  		let dbArr = [];
  		for (let k in dbMap) {
  			let data = dbMap[k];
  			if (grownupLine != data.grownupLine) {
  				continue;
  			}
  			dbArr.push(data);
  		}
  		dbArr = Tools.sortArrayByField(dbArr, [`level`]);
  		if (!dbArr || dbArr.length == 0) {
  			return null;
  		}
  		return dbArr[0];
  	}
  	static getMinLevelRoleIdByGrownline(grownupLine) {
  		let roleData = this.getMinLevelRoleDataByGrownline(grownupLine);
  		if (!roleData || !roleData) {
  			return 0;
  		}
  		return roleData.id;
  	}
  	static getMinLevelByGrownline(grownupLine) {
  		let data = this.getMinLevelRoleDataByGrownline(grownupLine);
  		if (!data) {
  			return 0;
  		}
  		return data.level;
  	}
  	static getMaxLevelByRoleId(roleId) {
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(roleId);
  		let dbMap = db.get_amaze_cloth_crossing_property_to_logic_role_map();
  		let dbArr = [];
  		for (let k in dbMap) {
  			let data = dbMap[k];
  			if (roleData.grownupLine != data.grownupLine) {
  				continue;
  			}
  			dbArr.push(data);
  		}
  		dbArr = Tools.sortArrayByField(dbArr, [`-level`]);
  		if (!dbArr || dbArr.length == 0) {
  			return 0;
  		}
  		return dbArr[0].level;
  	}
  	static getPropertyIndexByRoleId(roleId) {
  		let data = db.get_amaze_cloth_crossing_property_to_logic_role(roleId);
  		let tmpIndex1 = data.property_1 > data.property_2 ? 1 : 2;
  		let tmpIndex2 = data.property_3 > data.property_4 ? 3 : 4;
  		let tmpIndex3 = data["property_" + tmpIndex1] > data["property_" + tmpIndex2] ? tmpIndex1 : tmpIndex2;
  		return tmpIndex3;
  	}
  }
  mgrRole.bodyIdList = [];
  mgrRole.bodyNameList = [];
  mgrRole.bodyRoleList = [];
  mgrRole.property1Value = 0;
  mgrRole.property2Value = 0;
  mgrRole.property3Value = 0;
  mgrRole.property4Value = 0;
  mgrRole.playerRoleId = 0;
  mgrRole.bBornedOnce = false;
  mgrRole.arrivedRoleIdDict = {};
  mgrRole.activedRoleIdDict = {};
  mgrRole.historyGotProperty1 = 0;
  mgrRole.historyGotProperty2 = 0;
  mgrRole.historyGotProperty3 = 0;
  mgrRole.historyGotProperty4 = 0;
  mgrRole.gotPropertyExtrnalLevel = 0;
  mgrRole.bCompletedGrownupLineSelect = false;
  mgrRole.currentUsingGrownupLine = 0;
  mgrRole.nextResultQuestionId = 0;
  mgrRole.bornCount = 0;

  const DEBUG$1 = true;
  class mgrAlertRouter extends Manager {
  	static onLoad() {
  		super.onLoad();
  		console.log("初始化alertRouter");
  		this.loadRecord();
  	}
  	static loadRecord() {
  		super.loadRecord();
  		let record = FileRecord.getData("alertRouter") || {};
  		this.lastAlertTimeLog = record.lastAlertTimeLog || {};
  		let alert_router_db_map = db.get_alert_router_db_map();
  		Tools.forEachMap(alert_router_db_map, (k, v) => {
  			for (let i = 0; i < v.length; i++) {
  				const data = v[i];
  				if (!data.bRecordLastAlertTime) {
  					this.setLastAlertTime(data.routerId, data.index, 0);
  				}
  			}
  		});
  		this.saveRecord();
  	}
  	static saveRecord() {
  		super.saveRecord();
  		let record = {
  			lastAlertTimeLog: this.lastAlertTimeLog
  		};
  		FileRecord.setData("alertRouter", record);
  	}
  	static getLastAlertTime(routerId, index) {
  		let v = this.lastAlertTimeLog[routerId];
  		if (!v)
  			return 0;
  		return v[index] || 0;
  	}
  	static setLastAlertTime(routerId, index, time) {
  		if (!this.lastAlertTimeLog[routerId]) {
  			this.lastAlertTimeLog[routerId] = {};
  		}
  		this.lastAlertTimeLog[routerId][index] = time;
  		console.log("查看lastAlertTimeLog", this.lastAlertTimeLog);
  	}
  	static isCanOpenSign(routerData) {
  		return false;
  	}
  	static openSign(routerData) {
  		Director.openPanel("PanelSignEx");
  	}
  	static isCanOpenAdRoleUp(routerData) {
  		return false;
  	}
  	static openAdRoleUP(routerData) {
  		Director.openPanel(`PanelBianshenDialog`);
  	}
  	static calcRouterDatas(routerId) {
  		let datas = [];
  		let alert_router_db = db.get_alert_router_db_map();
  		let rawDatas = alert_router_db[routerId];
  		console.log("查看rawDatas", rawDatas);
  		if (DEBUG$1) {
  			console.log("mgrAlertRouter.calcRouterDatas", routerId);
  			console.log("  rawDatas", rawDatas);
  		}
  		for (let i = 0; i < rawDatas.length; i++) {
  			const data = Tools.deepCopy(rawDatas[i]);
  			data.weight = mgrSdk.getSubCop(data.weightFromCopKey);
  			data.order = mgrSdk.getSubCop(data.orderFromCopKey);
  			data.cd = mgrSdk.getSubCop(data.cdFromCopKey);
  			if (DEBUG$1)
  				console.log("  check", data);
  			if (data.weight <= 0)
  				continue;
  			if (data.conditionFunctionName) {
  				if (this[data.conditionFunctionName] instanceof Function) {
  					if (!this[data.conditionFunctionName](data)) {
  						if (DEBUG$1)
  							console.log("  条件未通过");
  						continue;
  					}
  				}
  				else {
  					console.warn("mgrAlertRouter conditionFunction not found", routerId, data.index, data.conditionFunctionName);
  				}
  			}
  			else {
  			}
  			if (!data.openViewFunctionName || !(this[data.openViewFunctionName] instanceof Function)) {
  				console.warn("mgrAlertRouter openViewFunction not found", routerId, data.index, data.openViewFunctionName);
  				continue;
  			}
  			let lastAlertTime = this.getLastAlertTime(routerId, data.index);
  			if (DEBUG$1)
  				console.log("lastAlertTime", lastAlertTime, Timer.time, lastAlertTime);
  			if (Timer.time - lastAlertTime <= data.cd) {
  				continue;
  			}
  			datas.push(data);
  		}
  		datas = Tools.sortArrayByField(datas, ["order", "index"]);
  		if (DEBUG$1)
  			console.log("  datas", datas);
  		return datas;
  	}
  	static tryAlertView(routerId) {
  		if (mgrGuide.isGuiding())
  			return;
  		if (!mgrGuide.isAllGuideFinished())
  			return;
  		let routerDatas = this.calcRouterDatas(routerId);
  		if (!routerDatas)
  			return;
  		console.log("查看routerDatas", routerDatas);
  		let totalWeight = 0;
  		for (let i = 0; i < routerDatas.length; i++) {
  			const v = routerDatas[i];
  			totalWeight += v.weight;
  		}
  		let r = Mathf.random(Math.min(totalWeight, 100));
  		let routerData = null;
  		for (let i = 0; i < routerDatas.length; i++) {
  			const data = routerDatas[i];
  			if (r <= data.weight) {
  				routerData = data;
  				break;
  			}
  			r -= data.weight;
  		}
  		if (routerData && routerData.openViewFunctionName && this[routerData.openViewFunctionName] instanceof Function) {
  			this[routerData.openViewFunctionName](routerData);
  			this.setLastAlertTime(routerData.routerId, routerData.index, Timer.time);
  			this.saveRecord();
  		}
  	}
  	static tryAlertJump(jumpIndex, panelName) {
  		if (panelName == `PanelJumpOtherGameDialog`)
  			return;
  		if (!mgrGuide.isAllGuideFinished() || mgrGuide.isGuiding()) {
  			return;
  		}
  		let cd = db.cop_db.jump_alert_cd || 0;
  		let state = db.cop_db.jump_other_game_switchs.indexOf(jumpIndex) >= 0 ? 1 : 0;
  		console.log("查看jumpAlertTime", this.jumpAlertTime);
  		if (Timer.time > (this.jumpAlertTime + cd) && state == 1) {
  			this.jumpAlertTime = Timer.time;
  			Director.openPanel("PanelJumpOtherGameDialog");
  			this.saveRecord();
  		}
  	}
  	static tryAlertTryGoldDialog() {
  		if (!mgrGuide.isAllGuideFinished() || mgrGuide.isGuiding()) {
  			return;
  		}
  		let cd = db.cop_db.try_add_gold_cd || 0;
  		let state = Mathf.random(0, 100) <= db.cop_db.try_add_gold_ratio ? 1 : 0;
  		if (Timer.time > (this.try_add_gold_time + cd) && state == 1) {
  			this.try_add_gold_time = Timer.time;
  			Director.openPanel("PanelPromptTryGold");
  			this.saveRecord();
  		}
  	}
  }
  mgrAlertRouter.jumpAlertTime = 0;
  mgrAlertRouter.try_add_gold_time = 0;

  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 (Mathf.random(0, 100) > db.cop_db.pop_review_ratio)
  			return;
  		if (!window[`conch`]) {
  			return;
  		}
  		let os = window[`conchConfig`].getOS();
  		if (os != "Conch-ios") {
  			console.log("[warn] mgrReview.tryShowReviewDialog mgrSdk.bHasReviewModule is false");
  			return;
  		}
  		if (this.lastReviewTime != 0) {
  			console.log("[warn] mgrReview.tryShowReviewDialog already reviewd");
  			return;
  		}
  		if (Tools.isOneDay(Timer.now, this.lastAlertTime || 0)) {
  			console.log("[warn] mgrReview.tryShowReviewDialog today already alerted");
  			return;
  		}
  		this.showReviewDialog();
  	}
  	static isShowInviteButton() {
  		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 (BaseFacade.mItem.getItemAmount(900) > 0) {
  			return false;
  		}
  		if (Tools.isOneDay(Timer.now, this.lastAlertTime || 0)) {
  			console.log("[warn] mgrReview.tryShowReviewDialog today already alerted");
  			return false;
  		}
  		return true;
  	}
  	static showReviewDialog() {
  		this.lastAlertTime = Timer.now;
  		this.lastReviewTime = 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 mgrCrossStage extends Manager {
  	static onLoad() {
  		super.onLoad();
  	}
  	static loadRecord() {
  		let data = FileRecord.getData("mgrCrossStage") || {};
  		console.log("初始化mgrCrossStage");
  		this.playedStageIdDict = data.playedStageIdDict || {};
  		this.currStageId = data.currStageId || 1;
  		this.lastShowChestTime = data.lastShowChestTime || 0;
  		this.freeLevelUpData = data.freeLevelUpData || { curCount: [0, 0, 0], timer: 0 };
  		if (!Tools.isOneDay(this.freeLevelUpData.timer, Timer.now)) {
  			this.freeLevelUpData = { curCount: [0, 0, 0], timer: Timer.now };
  		}
  		this.showLevelUpDatas = data.showLevelUpDatas || [];
  		this.saveRecord();
  	}
  	static saveRecord() {
  		let record = {
  			currStageId: this.currStageId,
  			playedStageIdDict: this.playedStageIdDict,
  			lastShowChestTime: this.lastShowChestTime,
  			freeLevelUpData: this.freeLevelUpData,
  			showLevelUpDatas: this.showLevelUpDatas,
  		};
  		FileRecord.setData("mgrCrossStage", record);
  	}
  	static resetGameUserRecord() {
  		FileRecord.setData("mgrCrossStage", {});
  		this.loadRecord();
  	}
  	static finishStage(stageId) {
  		if (stageId < this.currStageId) {
  			return;
  		}
  		this.playedStageIdDict[this.currStageId] = true;
  		this.currStageId += 1;
  		this.saveRecord();
  	}
  	static isPlayedStage(stageId) {
  		if (stageId > 24) {
  			let template = db.get_amaze_cloth_crossing_stage_db(stageId);
  			if (!template || !!template.bLoopStage) {
  				return true;
  			}
  		}
  		return !!this.playedStageIdDict[stageId];
  	}
  	static setCurrStage(stageId) {
  		this.currStageId = stageId;
  		this.saveRecord();
  	}
  	static getCurrStageId() {
  		return this.currStageId;
  	}
  	static getCurrRealStageId(specialStageId) {
  		let tempalte = db.get_amaze_cloth_crossing_stage_db(specialStageId || 0);
  		if (tempalte && !tempalte.bLoopStage) {
  			return specialStageId;
  		}
  		let arr = [];
  		let dbmap = db.get_amaze_cloth_crossing_stage_db_map();
  		for (let k in dbmap) {
  			let data = dbmap[k];
  			if (data.bLoopStage) {
  				arr.push(data);
  			}
  		}
  		let stageId = specialStageId || this.getCurrStageId() || 0;
  		if (stageId <= 12) {
  			return stageId;
  		}
  		if (arr.length == 0) {
  			return 2;
  		}
  		let tmpStageId = stageId - 12 - 1;
  		let index = tmpStageId % (arr.length || 1);
  		return arr[index].id;
  	}
  	static tryShowChestDialog() {
  		let bOpen = db.cop_db.b_open_chest == 1;
  		let cd = db.cop_db.chest_cd;
  		let lastTime = this.lastShowChestTime;
  		let bOverCd = Timer.time - lastTime >= cd;
  		if (bOpen && bOverCd) {
  			Director.openPanel(`PanelChestDialog`);
  			this.lastShowChestTime = Timer.time;
  			this.saveRecord();
  			return true;
  		}
  		return false;
  	}
  	static tryShowFreeLevelUpDialog(advId, copIdx = 0) {
  		if (!mgrAdv.checkActive(advId)) {
  			return false;
  		}
  		if (this.freeLevelUpData.curCount[copIdx] >= db.cop_db.free_level_up_day_count[copIdx]) {
  			return false;
  		}
  		if (Timer.now - this.lastOpenLevelUpTime[copIdx] < db.cop_db.free_level_up_cd[copIdx]) {
  			return false;
  		}
  		if (db.cop_db.free_level_up_ratio[copIdx] < Mathf.random(1, 100)) {
  			return false;
  		}
  		this.lastOpenLevelUpTime[copIdx] = Timer.now;
  		this.saveRecord();
  		Director.openPanel("PanelFreeLevelUpDialog", { advId: advId, copIdx, type: 1 });
  		return true;
  	}
  	static addFreeLevelUpDialogCount(copIdx) {
  		this.freeLevelUpData.curCount[copIdx]++;
  		this.saveRecord();
  	}
  	static isShowLevelUpDialog(copIdx, level) {
  		if (this.showLevelUpDatas[copIdx] && this.showLevelUpDatas[copIdx].indexOf(level) != -1) {
  			return true;
  		}
  		return false;
  	}
  	static setShowLevelUpDatas(copIdx, level) {
  		if (!this.showLevelUpDatas[copIdx]) {
  			this.showLevelUpDatas[copIdx] = [];
  		}
  		this.showLevelUpDatas[copIdx].push(level);
  		this.saveRecord();
  	}
  }
  mgrCrossStage.freeLevelUpData = { curCount: [], timer: 0 };
  mgrCrossStage.showLevelUpDatas = [];
  mgrCrossStage.lastOpenLevelUpTime = [0, 0, 0];
  mgrCrossStage.lastShowChestTime = 0;

  class mgrRetinue extends Manager {
  	static onLoad() {
  		super.onLoad();
  	}
  	static loadRecord() {
  		let data = FileRecord.getData("mgrRetinue") || {};
  		console.log("初始化mgrRetinue");
  		this.adUpgradeShowedRetinueDict = data.adUpgradeShowedRetinueDict || {};
  		this.retinueInfoDict = data.retinueInfoDict || {};
  		this._followingRetinueId = data._followingRetinueId;
  		this.bShowFreeUpgradeDatas = data.bShowFreeUpgradeDatas || [];
  		this.appearedRetinueIdDict = data.appearedRetinueIdDict || { [10001]: true };
  		this.saveRecord();
  	}
  	static saveRecord() {
  		let record = {
  			adUpgradeShowedRetinueDict: this.adUpgradeShowedRetinueDict,
  			retinueInfoDict: this.retinueInfoDict,
  			_followingRetinueId: this._followingRetinueId,
  			bShowFreeUpgradeDatas: this.bShowFreeUpgradeDatas,
  			appearedRetinueIdDict: this.appearedRetinueIdDict,
  		};
  		FileRecord.setData("mgrRetinue", record);
  	}
  	static addAppearedRetinueId(retinueId) {
  		this.appearedRetinueIdDict[retinueId] = true;
  		this.saveRecord();
  	}
  	static get followingRetinueId() {
  		return this._followingRetinueId;
  	}
  	static set followingRetinueId(value) {
  		this._followingRetinueId = value;
  		this.saveRecord();
  	}
  	static cancelFollowingRetinue() {
  		this._followingRetinueId = null;
  		this.saveRecord();
  	}
  	static isAdUpgradeShowedRetinue(retinueId, level) {
  		let info = this.adUpgradeShowedRetinueDict[retinueId] || {};
  		return !!info[level];
  	}
  	static addAdUpgradeShowedRetinue(retinueId, level) {
  		this.adUpgradeShowedRetinueDict[retinueId] = this.adUpgradeShowedRetinueDict[retinueId] || {};
  		this.adUpgradeShowedRetinueDict[retinueId][level] = true;
  		this.saveRecord();
  	}
  	static getRetinueLevelById(retinueId) {
  		let info = this.retinueInfoDict[retinueId] || {};
  		return (info && info.level) || 0;
  	}
  	static canMustTriggerSkill(retinueId) {
  		let info = this.retinueInfoDict[retinueId] || {};
  		let retinueData = db.get_ggg_retinue_template_db(retinueId, 0);
  		return (info.triggeredSkillCount || 0) >= retinueData.mustTriggerSkillCount ? false : true;
  	}
  	static markTriggeredSkillOnce(retinueId) {
  		let info = this.retinueInfoDict[retinueId] || {};
  		info.triggeredSkillCount = info.triggeredSkillCount || 0;
  		info.triggeredSkillCount++;
  		this.retinueInfoDict[retinueId] = info;
  		this.saveRecord();
  	}
  	static cleanTriggeredSkill() {
  		let dict = this.retinueInfoDict || {};
  		for (let k in dict) {
  			let info = dict[k];
  			if (!info) {
  				continue;
  			}
  			info.triggeredSkillCount = 0;
  		}
  		this.retinueInfoDict = dict;
  		this.saveRecord();
  	}
  	static tryTriggerRetinueSkill(retinueId, level) {
  		level = level || this.getRetinueLevelById(retinueId);
  		let retinueTemplate = db.get_ggg_retinue_template_db(retinueId, level);
  		if (this.canMustTriggerSkill(retinueId)) {
  			this.markTriggeredSkillOnce(retinueId);
  			return { bTriggered: true, param1: retinueTemplate.skillParam };
  		}
  		if (Tools.random(100) < retinueTemplate.triggerRatio) {
  			this.markTriggeredSkillOnce(retinueId);
  			return { bTriggered: true, param1: retinueTemplate.skillParam };
  		}
  		return;
  	}
  	static upgradeLevel(retinueId, bIgnoreCose) {
  		let currLevel = this.getRetinueLevelById(retinueId);
  		let template = db.get_ggg_retinue_template_db(retinueId, currLevel);
  		let templateNext = db.get_ggg_retinue_template_db(retinueId, currLevel + 1);
  		if (!templateNext) {
  			return { bSuccess: false, tipStr: "已达最高级" };
  		}
  		if (!bIgnoreCose) {
  			if (BaseFacade.mItem.isEnoughItem(template.upgradeCostItemId, template.upgradeCostAmount)) {
  				BaseFacade.mItem.subItem(template.upgradeCostItemId, template.upgradeCostAmount, "升级侍从");
  			}
  			else {
  				let templateCost = db.get_item_db(template.upgradeCostItemId);
  				return { bSuccess: false, tipStr: `${templateCost.name}不足` };
  			}
  		}
  		let info = this.retinueInfoDict[retinueId] || {};
  		info.level = templateNext.level;
  		this.retinueInfoDict[retinueId] = info;
  		this.saveRecord();
  		GameStatistics.statisCommonEvent(templateNext.statisPointId);
  		return { bSuccess: true, tipStr: templateNext.level == 1 ? "雇佣成功" : "升级成功" };
  	}
  	static isMaxLevel(retinueId) {
  		let currLevel = this.getRetinueLevelById(retinueId);
  		let templateNext = db.get_ggg_retinue_template_db(retinueId, currLevel + 1);
  		if (!templateNext) {
  			return true;
  		}
  		return false;
  	}
  	static getMaxLevelTemplate(retinueId) {
  		let data = null;
  		let dbMap = db.get_ggg_retinue_template_db_map();
  		for (const key in dbMap) {
  			if (retinueId == parseInt(key)) {
  				data = dbMap[key];
  				break;
  			}
  		}
  		let length = Tools.objLength(data);
  		let templateMax = db.get_ggg_retinue_template_db(retinueId, length - 1);
  		return templateMax;
  	}
  	static getMaxLevel(retinueId) {
  		let data = null;
  		let dbMap = db.get_ggg_retinue_template_db_map();
  		for (const key in dbMap) {
  			if (retinueId == parseInt(key)) {
  				data = dbMap[key];
  				break;
  			}
  		}
  		let length = Tools.objLength(data);
  		let templateMax = db.get_ggg_retinue_template_db(retinueId, length - 1);
  		return templateMax.level;
  	}
  	static isHaveCanTrain() {
  		for (const key in this.retinueInfoDict) {
  			let info = this.retinueInfoDict[key];
  			let bMax = this.isMaxLevel(key);
  			if (info.level > 0 && !bMax) {
  				return true;
  			}
  		}
  		return false;
  	}
  	static bShowLevelUpDialogByLevel(id, level) {
  		for (let i = 0; i < this.bShowFreeUpgradeDatas.length; ++i) {
  			if (this.bShowFreeUpgradeDatas[i].id == id && this.bShowFreeUpgradeDatas[i].levels.indexOf(level) != -1) {
  				return true;
  			}
  		}
  		return false;
  	}
  	static setShowLevelUpDialog(id, level) {
  		for (let i = 0; i < this.bShowFreeUpgradeDatas.length; ++i) {
  			if (this.bShowFreeUpgradeDatas[i].id == id) {
  				this.bShowFreeUpgradeDatas[i].levels.push(level);
  				this.saveRecord();
  				return;
  			}
  		}
  		this.bShowFreeUpgradeDatas.push({ id: id, levels: [level] });
  		this.saveRecord();
  	}
  	static randomOneTrialRetinueId() {
  		let idUnOwnedArr = [];
  		let idOwnedArr = [];
  		let dbMap = db.get_ggg_retinue_template_db_map();
  		for (let k in dbMap) {
  			let retinueId = parseInt(k);
  			let lv = this.getRetinueLevelById(retinueId);
  			let maxLv = this.getMaxLevel(retinueId);
  			if (lv == maxLv) {
  				continue;
  			}
  			if (lv <= 0) {
  				idUnOwnedArr.push(retinueId);
  			}
  			else {
  				idOwnedArr.push(retinueId);
  			}
  		}
  		if (idUnOwnedArr.length > 0) {
  			return Tools.randomGotOneArrayData(idUnOwnedArr);
  		}
  		else if (idUnOwnedArr.length > 0) {
  			return Tools.randomGotOneArrayData(idOwnedArr);
  		}
  		else {
  			return 0;
  		}
  	}
  }
  mgrRetinue.bShowFreeUpgradeDatas = [];

  var SignState;
  (function (SignState) {
  	SignState[SignState["canSign"] = 1] = "canSign";
  	SignState[SignState["signed"] = 2] = "signed";
  	SignState[SignState["signOver"] = 3] = "signOver";
  	SignState[SignState["waitGap"] = 4] = "waitGap";
  	SignState[SignState["invaild"] = 5] = "invaild";
  	SignState[SignState["inFuture"] = 6] = "inFuture";
  })(SignState || (SignState = {}));
  var SkillType;
  (function (SkillType) {
  	SkillType[SkillType["dispelBegger"] = 1] = "dispelBegger";
  	SkillType[SkillType["helpPlayer"] = 2] = "helpPlayer";
  	SkillType[SkillType["questionResult"] = 3] = "questionResult";
  	SkillType[SkillType["stageCoin"] = 4] = "stageCoin";
  })(SkillType || (SkillType = {}));
  var StageType;
  (function (StageType) {
  	StageType[StageType["mainStage"] = 0] = "mainStage";
  	StageType[StageType["goldStage"] = 1] = "goldStage";
  	StageType[StageType["speedStage"] = 2] = "speedStage";
  })(StageType || (StageType = {}));
  var QuestionRewardSpecialType;
  (function (QuestionRewardSpecialType) {
  	QuestionRewardSpecialType[QuestionRewardSpecialType["GoldReward"] = 1] = "GoldReward";
  	QuestionRewardSpecialType[QuestionRewardSpecialType["ExtrnalLevelUp"] = 2] = "ExtrnalLevelUp";
  	QuestionRewardSpecialType[QuestionRewardSpecialType["RetinueLevelUp"] = 3] = "RetinueLevelUp";
  	QuestionRewardSpecialType[QuestionRewardSpecialType["PetLevelUp"] = 4] = "PetLevelUp";
  	QuestionRewardSpecialType[QuestionRewardSpecialType["UnlockGoldStage"] = 5] = "UnlockGoldStage";
  	QuestionRewardSpecialType[QuestionRewardSpecialType["UnlockSpeedStage"] = 6] = "UnlockSpeedStage";
  	QuestionRewardSpecialType[QuestionRewardSpecialType["MaxPropertyReward"] = 7] = "MaxPropertyReward";
  	QuestionRewardSpecialType[QuestionRewardSpecialType["UnlockYard"] = 8] = "UnlockYard";
  })(QuestionRewardSpecialType || (QuestionRewardSpecialType = {}));
  var YardBuildType;
  (function (YardBuildType) {
  	YardBuildType[YardBuildType["Event"] = 1] = "Event";
  	YardBuildType[YardBuildType["Business"] = 2] = "Business";
  	YardBuildType[YardBuildType["Gold"] = 3] = "Gold";
  	YardBuildType[YardBuildType["Lottery"] = 4] = "Lottery";
  })(YardBuildType || (YardBuildType = {}));
  var PartType;
  (function (PartType) {
  	PartType[PartType["hair"] = 1] = "hair";
  	PartType[PartType["dress"] = 2] = "dress";
  	PartType[PartType["sock"] = 3] = "sock";
  	PartType[PartType["shoe"] = 4] = "shoe";
  	PartType[PartType["headDec"] = 5] = "headDec";
  	PartType[PartType["earDec"] = 6] = "earDec";
  	PartType[PartType["neckDec"] = 7] = "neckDec";
  	PartType[PartType["handDec"] = 8] = "handDec";
  	PartType[PartType["backDec"] = 9] = "backDec";
  	PartType[PartType["magicWand"] = 10] = "magicWand";
  	PartType[PartType["face"] = 100] = "face";
  	PartType[PartType["diy"] = 1000] = "diy";
  	PartType[PartType["animation"] = 1001] = "animation";
  	PartType[PartType["hair_color"] = 1002] = "hair_color";
  })(PartType || (PartType = {}));
  const ROLE_QUOTE_MOV = {
  	movIdle: "movIdle",
  	movIdle2: "movIdle2",
  	movIdle3: "movIdle3",
  	movIdle4: "movIdle4",
  	movWalk: "movWalk",
  	movWalk3: "movWalk3",
  	movLoseShow01: "movLoseShow01",
  	movUpgrade: "movUpgrade",
  	movWinShow01: "movWinShow01",
  	movPlayerHited01: "movPlayerHited01",
  	movNpcHited01: "movNpcHited01",
  	movEmbrace: "movEmbrace",
  	movResultEvent1Right: "movResultEvent1Right",
  	movResultEvent1Fault: "movResultEvent1Fault",
  	movResultEvent2RightUpper: "movResultEvent2RightUpper",
  	movResultEvent2RightLower: "movResultEvent2RightLower",
  	movResultEvent2FaultUpper: "movResultEvent2FaultUpper",
  	movResultEvent2FaultLower: "movResultEvent2FaultLower",
  	movResultEvent2Equal: "movResultEvent2Equal",
  	movResultEvent2Equal2: "movResultEvent2Equal2",
  	movResultEvent3Right: "movResultEvent3Right",
  	movResultEvent3Fault: "movResultEvent3Fault",
  	movResultEvent4Right: "movResultEvent4Right",
  	movResultEvent4Fault: "movResultEvent4Fault",
  	movResultEvent5Right: "movResultEvent5Right",
  	movResultEvent5Fault: "movResultEvent5Fault",
  	movResultEvent6Right: "movResultEvent6Right",
  	movResultEvent6Fault: "movResultEvent6Fault",
  	movResultEvent7RightAsPlayer: "movResultEvent7RightAsPlayer",
  	movResultEvent7FaultAsPlayer: "movResultEvent7FaultAsPlayer",
  	movResultEvent7RightAsNpc: "movResultEvent7RightAsNpc",
  	movResultEvent7FaultAsNpc: "movResultEvent7FaultAsNpc",
  	movResultEvent7RightAsNpcHelper: "movResultEvent7RightAsNpcHelper",
  	movResultEvent8NpcKeepGiveGift: "movResultEvent8NpcKeepGiveGift",
  	movResultEvent8ChooseAnswer1AsPlayer: "movResultEvent8ChooseAnswer1AsPlayer",
  	movResultEvent8ChooseAnswer1AsNpc: "movResultEvent8ChooseAnswer1AsNpc",
  	movResultEvent8ChooseAnswer2AsPlayer: "movResultEvent8ChooseAnswer2AsPlayer",
  	movResultEvent8ChooseAnswer2AsNpc: "movResultEvent8ChooseAnswer2AsNpc",
  	movResultEvent9Npc1Idle: "movResultEvent9Npc1Idle",
  	movResultEvent9Npc2Idle: "movResultEvent9Npc2Idle",
  	movResultEvent9Npc1Hited: "movResultEvent9Npc1Hited",
  	movResultEvent9Npc2Hited: "movResultEvent9Npc2Hited",
  	movResultEvent9ChooseAnswer1AsPlayer: "movResultEvent9ChooseAnswer1AsPlayer",
  	movResultEvent9ChooseAnswer1AsNpc1: "movResultEvent9ChooseAnswer1AsNpc1",
  	movResultEvent9ChooseAnswer2AsPlayer: "movResultEvent9ChooseAnswer2AsPlayer",
  	movResultEvent9ChooseAnswer2AsNpc1: "movResultEvent9ChooseAnswer2AsNpc1",
  	movResultEvent9ChooseAnswer2AsNpc2: "movResultEvent9ChooseAnswer2AsNpc2",
  	movResultEvent9ChooseAnswer2AsNpcHelper: "movResultEvent9ChooseAnswer2AsNpcHelper",
  	movResultEvent10Right: "movResultEvent10Right",
  	movSkill1: "movSkill1",
  	movSkill2: "movSkill2",
  	movSkill3: "movSkill3",
  	movTumble: "movTumble",
  	movTumbleHitNpc: "movTumbleHitNpc",
  	movYardEvent1: "movYardEvent1",
  	movYardEvent2: "movYardEvent2",
  	movYardEvent3: "movYardEvent3",
  };
  var NpcMoveType;
  (function (NpcMoveType) {
  	NpcMoveType[NpcMoveType["moveNone"] = 0] = "moveNone";
  	NpcMoveType[NpcMoveType["moveX"] = 1] = "moveX";
  	NpcMoveType[NpcMoveType["moveY"] = 2] = "moveY";
  	NpcMoveType[NpcMoveType["moveZ"] = 3] = "moveZ";
  })(NpcMoveType || (NpcMoveType = {}));
  var NpcHitedActionType;
  (function (NpcHitedActionType) {
  	NpcHitedActionType[NpcHitedActionType["disapper"] = 0] = "disapper";
  	NpcHitedActionType[NpcHitedActionType["playHited"] = 1] = "playHited";
  	NpcHitedActionType[NpcHitedActionType["follow"] = 2] = "follow";
  	NpcHitedActionType[NpcHitedActionType["playHited2"] = 3] = "playHited2";
  })(NpcHitedActionType || (NpcHitedActionType = {}));
  var CNewFlowerType;
  (function (CNewFlowerType) {
  	CNewFlowerType[CNewFlowerType["BAO_ZHUANG"] = 61] = "BAO_ZHUANG";
  	CNewFlowerType[CNewFlowerType["FLOWER"] = 62] = "FLOWER";
  	CNewFlowerType[CNewFlowerType["DEC"] = 63] = "DEC";
  })(CNewFlowerType || (CNewFlowerType = {}));
  const WZ_DATA = [
  	"weizhuang"
  ];
  var GrownupLine;
  (function (GrownupLine) {
  	GrownupLine[GrownupLine["property1"] = 1] = "property1";
  	GrownupLine[GrownupLine["property2"] = 2] = "property2";
  	GrownupLine[GrownupLine["property3"] = 3] = "property3";
  	GrownupLine[GrownupLine["property4"] = 4] = "property4";
  })(GrownupLine || (GrownupLine = {}));
  const FLOWER_SHADOW_TYPE_2_TEXTURE_DICT = {
  	0: "res/icon/shadow_01.png",
  	1: "res/icon/shadow_02.png",
  };
  const PROPERTY_2_TARGET_ICON_DICT = {
  	[1]: "ui://gogogo/iconxinjibig",
  	[2]: "ui://gogogo/iconqibig",
  	[3]: "ui://gogogo/iconmingbig",
  	[4]: "ui://gogogo/iconjiaobig",
  };
  var MSG;
  (function (MSG) {
  	MSG["DEBUG_SELECT_LEVEL"] = "DEBUG_SELECT_LEVEL";
  	MSG["ENTER_GAME"] = "ENTER_GAME";
  	MSG["GAME_SUC"] = "GAME_SUC";
  	MSG["GAME_FAIL"] = "GAME_FAIL";
  	MSG["GAME_ALIVE"] = "GAME_ALIVE";
  	MSG["QIANG_START"] = "QIANG_START";
  	MSG["QIANG_FINISH"] = "QIANG_FINISH";
  	MSG["CAR_FINISH"] = "CAR_FINISH";
  	MSG["UI_SHOW_TAN_HAO"] = "UI_SHOW_TAN_HAO";
  	MSG["UI_SHOW_GAME_MASK"] = "UI_SHOW_GAME_MASK";
  })(MSG || (MSG = {}));
  var FACE_TEX;
  (function (FACE_TEX) {
  	FACE_TEX["E_IDLE"] = "res/_unity/Conventional/Assets/Artist/model/npc/enemy/enemy_lian.jpg";
  	FACE_TEX["E_JINGYA"] = "res/texture/enemy_lian01.png";
  	FACE_TEX["BOSS_IDLE"] = "res/_unity/Conventional/Assets/Artist/model/npc/boss/boss_lian.jpg";
  	FACE_TEX["BOSS_JINGYA"] = "res/texture/boss_lian01.png";
  })(FACE_TEX || (FACE_TEX = {}));
  var STUDENT_SOUND = {
  	[0]: {
  		handup: 364,
  		xingqu1: 370,
  		xingqu2: 371,
  		xingqu4: 376,
  		xingqu5: 372,
  		happy: 126,
  		sadness: 127,
  		sleep: 138,
  		langh: 135,
  	},
  	[1]: {
  		handup: 365,
  		xingqu1: 374,
  		xingqu2: 375,
  		xingqu4: 377,
  		xingqu5: 373,
  		happy: 136,
  		sadness: 137,
  		sleep: 138,
  		langh: 135,
  	}
  };
  var STUDENT_SPEAK = {
  	playGround: [
  		"老师好！",
  		"老师~我想学语文~",
  		"老师你好漂亮！",
  		"太阳当空照。",
  		"花儿对我笑。",
  		"我爱学习！",
  		"勤洗手，多通风。",
  		"好好锻炼，努力学习！",
  		"学而不思则罔，思而不学则殆。",
  		"上课啦！快走！",
  		"新年快乐！",
  		"牛年大吉！",
  	],
  	raise: [
  		"一朵小红花，人人都来夸。",
  		"谢谢老师！",
  		"老师你真棒！",
  		"耶！又可以玩咯！",
  		"牛年行大运。",
  		"我抽屉里有零食~",
  	],
  	punish: [
  		"好想玩哦~",
  		"呜呜呜呜...",
  		"不要啊~",
  		"哼！",
  		"为什么又是我！",
  		"爱干净，讲卫生。",
  	],
  	cleanPunish: [
  		"我终于可以玩啦！",
  		"终于不用扫地了！",
  		"再让我扫地我就走掉！",
  		"食堂！我来了！",
  		"看我把你吃掉！",
  		"我最喜欢学习了！",
  	],
  	classroom: [
  		"好想上花艺课！",
  		"我不喜欢语文课。",
  		"今天谁值日？",
  		"好困！",
  		"作业好多啊~",
  		"我喜欢玩小花仙。",
  		"抓鸭子~",
  		"嘎~",
  		"老师好！",
  		"下课啦！出去玩！",
  		"啦啦啦~噜啦啦",
  		"我也想放假！",
  		"牛气满满！",
  		"少一点假期作业！",
  	],
  	handup: [
  		"这题我会!",
  		"老师，选我!",
  		"选我，选我!",
  		"嘎~",
  	],
  };
  var CHN_DATA = {
  	appName: "toutiao",
  	isShareEnabled: true,
  	isPayEnabled: true,
  	isSupportRecordShare: true,
  	isSupportFindMinigames: true,
  	isSupportInstallShortcut: true,
  	findMinigamesImageUrl: "https://gamesres.ultralisk.cn/h5_games_res/common/find_me/default.png",
  	jumpInfo: [
  		{
  			index: "61", bReceived: false, rewards: [[1001, 10]],
  			url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/61.png",
  		},
  		{
  			index: "64", bReceived: false, rewards: [[1001, 10]],
  			url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/64.png",
  		},
  		{
  			index: "49", bReceived: false, rewards: [[1001, 10]],
  			url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/49.png",
  		},
  		{
  			index: "60", bReceived: false, rewards: [[1001, 10]],
  			url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/60.png",
  		},
  		{
  			index: "61", bReceived: false, rewards: [[1001, 10]],
  			url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/61.png",
  		},
  		{
  			index: "64", bReceived: false, rewards: [[1001, 10]],
  			url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/64.png",
  		},
  		{
  			index: "49", bReceived: false, rewards: [[1001, 10]],
  			url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/49.png",
  		},
  		{
  			index: "60", bReceived: false, rewards: [[1001, 10]],
  			url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/60.png",
  		},
  		{
  			index: "61", bReceived: false, rewards: [[1001, 10]],
  			url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/61.png",
  		},
  		{
  			index: "64", bReceived: false, rewards: [[1001, 10]],
  			url: "https://gamesres.ultralisk.cn/h5_games_res/common/jump_games/64.png",
  		}
  	],
  	copInfo: `{
        "share_rate":"10",

        "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":1,
        "some_function":"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_close_delta_time":1,

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

        
        "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,
        // "game_res_version": 10,
        // "game_res_open_time": 1,
        // "gold_rain_ratios":"100;100",
        // "gold_rain_count":10,
        // "gold_rain_cd":10
    }`
  };

  class mgrChallenge extends Manager {
  	static onLoad() {
  		super.onLoad();
  	}
  	static loadRecord() {
  		let data = FileRecord.getData("mgrChallenge") || {};
  		console.log("初始化mgrChallenge");
  		this.lastRefreshStageTime = data.lastRefreshStageTime || 0;
  		this.challengeTypeStageIdDict = data.challengeTypeStageIdDict || {};
  		this.challengeTypeGuidedDailyCountDict = data.challengeTypeGuidedDailyCountDict || {};
  		Timer.callLoop(60, this.onTimerHandler.bind(this), this);
  		this.onTimerHandler();
  		this.saveRecord();
  	}
  	static saveRecord() {
  		let record = {
  			lastRefreshStageTime: this.lastRefreshStageTime,
  			challengeTypeStageIdDict: this.challengeTypeStageIdDict,
  			challengeTypeGuidedDailyCountDict: this.challengeTypeGuidedDailyCountDict,
  		};
  		FileRecord.setData("mgrChallenge", record);
  	}
  	static onTimerHandler() {
  		if (!this.lastRefreshStageTime || !Tools.isOneDay(Timer.time, this.lastRefreshStageTime)) {
  			this.lastRefreshStageTime = Timer.time;
  			this.regenChallengeStage(StageType.goldStage);
  			this.regenChallengeStage(StageType.speedStage);
  			this.challengeTypeGuidedDailyCountDict = {};
  			this.saveRecord();
  		}
  	}
  	static markChallengeGuided(challengeType) {
  		this.challengeTypeGuidedDailyCountDict[challengeType] = this.challengeTypeGuidedDailyCountDict[challengeType] || 0;
  		this.challengeTypeGuidedDailyCountDict[challengeType]++;
  		this.saveRecord();
  	}
  	static getChallengeGuidedCount(challengeType) {
  		return this.challengeTypeGuidedDailyCountDict[challengeType] || 0;
  	}
  	static regenChallengeStage(challengeType) {
  		let stageTemplateArr = [];
  		let dbMap = db.get_amaze_cloth_crossing_stage_db_map();
  		for (let k in dbMap) {
  			let template = dbMap[k];
  			if (template.stageType != challengeType) {
  				continue;
  			}
  			stageTemplateArr.push(template);
  		}
  		let idArr = [];
  		let stageArr = Tools.randomGotArrayDatas(stageTemplateArr, 3);
  		for (let k in stageArr) {
  			idArr.push(stageArr[k].id);
  		}
  		this.challengeTypeStageIdDict = this.challengeTypeStageIdDict || {};
  		this.challengeTypeStageIdDict[challengeType] = idArr;
  		this.saveRecord();
  	}
  	static isUnlockedType(challengeType) {
  		let config = db.get_ggg_challenge_stage_config(challengeType);
  		if (!config) {
  			return false;
  		}
  		return BaseFacade.mItem.getItemAmount(config.unlockCheckItemId) > 0 ? true : false;
  	}
  	static markChallengeTypeUnlocked(challengeType) {
  		let config = db.get_ggg_challenge_stage_config(challengeType);
  		BaseFacade.mItem.setItem(config.unlockCheckItemId, 1);
  	}
  	static getChallengeStageId(challengeType) {
  		let stageIdArr = this.challengeTypeStageIdDict[challengeType] || [];
  		let stageId = stageIdArr[0];
  		if (!stageId) {
  			this.regenChallengeStage(challengeType);
  		}
  		stageIdArr = this.challengeTypeStageIdDict[challengeType] || [];
  		return stageIdArr[0];
  	}
  	static markChallengeJoined(challengeType) {
  		let stageIdArr = this.challengeTypeStageIdDict[challengeType] || [];
  		stageIdArr.shift();
  		this.challengeTypeStageIdDict[challengeType] = stageIdArr;
  		let challengeType2ItemDict = {
  			[StageType.goldStage]: 981,
  			[StageType.speedStage]: 982,
  		};
  		let flagItemId = challengeType2ItemDict[challengeType];
  		BaseFacade.mItem.subItem(flagItemId, 1, "特殊关卡次数");
  		this.saveRecord();
  	}
  	static getChallengeRemainCount(challengeType) {
  		let challengeType2ItemDict = {
  			[StageType.goldStage]: 981,
  			[StageType.speedStage]: 982,
  		};
  		return BaseFacade.mItem.getItemAmount(challengeType2ItemDict[challengeType]);
  	}
  	static getChallengeAdRemainCount(challengeType) {
  		let challengeType2ItemDict = {
  			[StageType.goldStage]: db.ADV_DB_ADVNAME.video_PanelGoGoGo_gold_challenge,
  			[StageType.speedStage]: db.ADV_DB_ADVNAME.video_PanelGoGoGo_speed_challenge,
  		};
  		return mgrAdv.getLeftCount(challengeType2ItemDict[challengeType]);
  	}
  }

  class mgrPet extends Manager {
  	static onLoad() {
  		super.onLoad();
  	}
  	static loadRecord() {
  		let data = FileRecord.getData("mgrPet") || {};
  		console.log("初始化mgrPet");
  		this.gotPetIdDict = data.gotPetIdDict || {};
  		this._followingPetId = data._followingPetId || 0;
  		this.adUpgradeShowedPetDict = data.adUpgradeShowedPetDict || {};
  		this.bShowFreeUpgradeDatas = data.bShowFreeUpgradeDatas || [];
  		this.appearedPetIdDict = data.appearedPetIdDict || { [10101]: true };
  		this.saveRecord();
  		this.tryOutput();
  	}
  	static saveRecord() {
  		let record = {
  			gotPetIdDict: this.gotPetIdDict,
  			_followingPetId: this._followingPetId,
  			adUpgradeShowedPetDict: this.adUpgradeShowedPetDict,
  			bShowFreeUpgradeDatas: this.bShowFreeUpgradeDatas,
  			appearedPetIdDict: this.appearedPetIdDict,
  		};
  		FileRecord.setData("mgrPet", record);
  	}
  	static get followingPetId() {
  		return this._followingPetId;
  	}
  	static set followingPetId(value) {
  		this._followingPetId = value;
  		this.saveRecord();
  	}
  	static getGotPetIdDict() {
  		return this.gotPetIdDict || {};
  	}
  	static getGotPetIdArr() {
  		let dict = this.gotPetIdDict || {};
  		let arr = [];
  		for (let k in dict) {
  			arr.push(parseInt(k));
  		}
  		return arr;
  	}
  	static isGotPetId(petId) {
  		return !!this.gotPetIdDict[petId];
  	}
  	static getGotPetIdLevel(petId) {
  		return this.gotPetIdDict[petId] || 0;
  	}
  	static addAppearedPetId(petId) {
  		this.appearedPetIdDict[petId] = true;
  		this.saveRecord();
  	}
  	static upgradeLevel(petId, bIgnoreCose) {
  		let currLevel = this.getGotPetIdLevel(petId);
  		let template = db.get_ggg_pet_template_db(petId, currLevel);
  		let templateNext = db.get_ggg_pet_template_db(petId, currLevel + 1);
  		if (!templateNext) {
  			return { bSuccess: false, tipStr: "已达最高级" };
  		}
  		if (!bIgnoreCose) {
  			if (BaseFacade.mItem.isEnoughItem(template.upgradeCostItemId, template.upgradeCostAmount)) {
  				BaseFacade.mItem.subItem(template.upgradeCostItemId, template.upgradeCostAmount, "升级宠物");
  			}
  			else {
  				let templateCost = db.get_item_db(template.upgradeCostItemId);
  				return { bSuccess: false, tipStr: `${templateCost.name}不足` };
  			}
  		}
  		this.gotPetIdDict[petId] = templateNext.level;
  		this.saveRecord();
  		GameStatistics.statisCommonEvent(templateNext.statisPointId);
  		return { bSuccess: true, tipStr: "升级成功" };
  	}
  	static isMaxLevel(petId) {
  		let currLevel = this.getGotPetIdLevel(petId);
  		let templateNext = db.get_ggg_pet_template_db(petId, currLevel + 1);
  		if (!templateNext) {
  			return true;
  		}
  		return false;
  	}
  	static bShowLevelUpDialogByLevel(petId, level) {
  		for (let i = 0; i < this.bShowFreeUpgradeDatas.length; ++i) {
  			if (this.bShowFreeUpgradeDatas[i].petId == petId && this.bShowFreeUpgradeDatas[i].levels.indexOf(level) != -1) {
  				return true;
  			}
  		}
  		return false;
  	}
  	static setShowLevelUpDialog(petId, level) {
  		for (let i = 0; i < this.bShowFreeUpgradeDatas.length; ++i) {
  			if (this.bShowFreeUpgradeDatas[i].petId == petId) {
  				this.bShowFreeUpgradeDatas[i].levels.push(level);
  				this.saveRecord();
  				return;
  			}
  		}
  		this.bShowFreeUpgradeDatas.push({ petId: petId, levels: [level] });
  		this.saveRecord();
  	}
  	static getUnitOutput(petId, level) {
  		let template = db.get_ggg_pet_template_db(petId, level);
  		return template.outputCount;
  	}
  	static tryOutput() {
  		Timer.callLoop(mgrPet.PET_OUTPUT_INTERVAL_TIME, (timer) => {
  			let output = 0;
  			let petIdArr = this.getGotPetIdArr();
  			if (!petIdArr.length) {
  				this.saveRecord();
  				return;
  			}
  			if (!this.lastOutputTime) {
  				this.lastOutputTime = Timer.time;
  				return;
  			}
  			for (let i = 0; i < petIdArr.length; i++) {
  				const petId = petIdArr[i];
  				output += this.gainPetOutputReward(petId, mgrPet.PET_OUTPUT_INTERVAL_TIME, true);
  			}
  			this.lastOutputTime = Timer.time;
  			this.saveRecord();
  			Global.sendMsg("MSG_PET_OUTPUT_COIN", { output: output });
  		}, this);
  	}
  	static gainPetOutputReward(petId, passTime, bIgnoreStatictics) {
  		this.lastOutputTime = this.lastOutputTime || Timer.time;
  		let totalTime = Math.min(mgrPet.PET_OUTPUT_MAX_TIME, passTime || (Timer.time - this.lastOutputTime));
  		let level = this.getGotPetIdLevel(petId);
  		let totalOutput = Math.floor(this.getUnitOutput(petId, level) * totalTime);
  		BaseFacade.mItem.addItem(2, totalOutput, !bIgnoreStatictics ? "宠物铜钱产出" : "");
  		return totalOutput;
  	}
  	static isAdUpgradeShowedPet(petId, level) {
  		let info = this.adUpgradeShowedPetDict[petId] || {};
  		return !!info[level];
  	}
  	static addAdUpgradeShowedPet(petId, level) {
  		this.adUpgradeShowedPetDict[petId] = this.adUpgradeShowedPetDict[petId] || {};
  		this.adUpgradeShowedPetDict[petId][level] = true;
  		this.saveRecord();
  	}
  	static isHaveCanUpgrade() {
  		let arr = this.getGotPetIdArr();
  		for (let i = 0; i < arr.length; i++) {
  			const petId = arr[i];
  			if (this.isHaveCanUpgradeByPetId(petId)) {
  				return true;
  			}
  		}
  		return false;
  	}
  	static isHaveCanUpgradeByPetId(petId) {
  		let level = this.getGotPetIdLevel(petId);
  		if (!level) {
  			return false;
  		}
  		let template = db.get_ggg_pet_template_db(petId, level);
  		let bMax = this.isMaxLevel(petId);
  		let bEnough = BaseFacade.mItem.isEnoughItem(template.upgradeCostItemId, template.upgradeCostAmount);
  		if (!bMax && bEnough) {
  			return true;
  		}
  		return false;
  	}
  }
  mgrPet.lastOutputTime = 0;
  mgrPet.PET_OUTPUT_INTERVAL_TIME = 5;
  mgrPet.PET_OUTPUT_MAX_TIME = 60 * 60;
  mgrPet.bShowFreeUpgradeDatas = [];

  const DEBUG$2 = true;
  class mgrName extends Manager {
  	static onLoad() {
  		super.onLoad();
  	}
  	static loadRecord() {
  		super.loadRecord();
  		let record = FileRecord.getData("player") || {};
  		this._playerName = record.playerName || "";
  		this.uid = record.uid;
  		this.bRenamePlayerName = record.bRenamePlayerName || false;
  		this.saveRecord();
  	}
  	static saveRecord() {
  		super.saveRecord();
  		let record = {
  			playerName: this._playerName,
  			uid: this.uid,
  			bRenamePlayerName: this.bRenamePlayerName
  		};
  		FileRecord.setData("player", record);
  	}
  	static getName() {
  		return this._playerName;
  	}
  	static setName(playerName) {
  		this._playerName = playerName;
  		this.bRenamePlayerName = true;
  		this.saveRecord();
  	}
  	static getUid() {
  		return this.uid || "测试id";
  	}
  	static setUid(uid) {
  		this.uid = uid;
  	}
  }
  mgrName.uid = "";
  mgrName._playerName = "";

  class mgrYard extends Manager {
  	static onLoad() {
  		super.onLoad();
  	}
  	static loadRecord() {
  		let data = FileRecord.getData("mgrYard") || {};
  		console.log("初始化mgrYard");
  		this.lastGoldOutputTime = data.lastGoldOutputTime || 0;
  		this.building2LvDict = data.building2LvDict || {};
  		this.lastEventGenTime = data.lastEventGenTime || 0;
  		this.currNoHandledEventCount = data.currNoHandledEventCount || 0;
  		this.currNoHandledEventQuestionId = data.currNoHandledEventQuestionId || 0;
  		this.lastBusinessGenTime = data.lastBusinessGenTime || 0;
  		this.currNoHandledBusinessCount = data.currNoHandledBusinessCount || 0;
  		this.currNoHandledBusinessQuestionId = data.currNoHandledBusinessQuestionId || 0;
  		this.ownedPrestigeCount = data.ownedPrestigeCount || 0;
  		this.saveRecord();
  		Timer.callLoop(60, this.onTimerLoop.bind(this), this);
  		Global.registerListeners(this, {
  			["MSG_USING_PLAYER_ROLE_CHANGED"]: this.onMsgUsingPlayerRoleChanged.bind(this),
  		});
  	}
  	static saveRecord() {
  		let record = {
  			lastGoldOutputTime: this.lastGoldOutputTime || 0,
  			building2LvDict: this.building2LvDict || {},
  			lastEventGenTime: this.lastEventGenTime || 0,
  			currNoHandledEventCount: this.currNoHandledEventCount,
  			currNoHandledEventQuestionId: this.currNoHandledEventQuestionId,
  			lastBusinessGenTime: this.lastBusinessGenTime || 0,
  			currNoHandledBusinessCount: this.currNoHandledBusinessCount,
  			currNoHandledBusinessQuestionId: this.currNoHandledBusinessQuestionId,
  			ownedPrestigeCount: this.ownedPrestigeCount || 0,
  		};
  		FileRecord.setData("mgrYard", record);
  	}
  	static onTimerLoop() {
  		this.tryGenYardBuildingData();
  	}
  	static onMsgUsingPlayerRoleChanged() {
  		this.currNoHandledEventQuestionId = 0;
  		this.currNoHandledBusinessQuestionId = 0;
  		this.saveRecord();
  	}
  	static getOwnedPrestige() {
  		return this.ownedPrestigeCount || 0;
  	}
  	static addOwnedPrestige(amount) {
  		this.ownedPrestigeCount = Math.max(0, this.ownedPrestigeCount + amount);
  		this.saveRecord();
  	}
  	static exchangeDecreeCount() {
  		let exchangeCount = 0;
  		let count = Math.floor(this.ownedPrestigeCount / 3);
  		if (count != 0) {
  			this.ownedPrestigeCount -= (count * 3);
  			this.saveRecord();
  			let decreeAmountOld = Math.min(10, BaseFacade.mItem.getItemAmount(4));
  			let canAddDecreeAmount = Math.min(10 - decreeAmountOld, count);
  			BaseFacade.mItem.addItem(4, canAddDecreeAmount, "威望兑换");
  			exchangeCount = canAddDecreeAmount;
  		}
  		return exchangeCount;
  	}
  	static isYardUnlocked() {
  		return BaseFacade.mItem.getItemAmount(912) > 0 ? true : false;
  	}
  	static unlockYard() {
  		BaseFacade.mItem.setItem(912, 1);
  	}
  	static tryGenYardBuildingData() {
  		if (this.isYardUnlocked()) {
  			if (!this.lastGoldOutputTime) {
  				this.lastGoldOutputTime = Timer.time;
  				this.saveRecord();
  			}
  			let tryGenEvent = () => {
  				this.currNoHandledEventCount++;
  				this.lastEventGenTime = Timer.time;
  				this.saveRecord();
  			};
  			if ((!this.lastEventGenTime || (Timer.time - this.lastEventGenTime) > 3600) && this.currNoHandledEventCount < this.getMaxEventCumulateCount()) {
  				tryGenEvent();
  			}
  			let tryGenBusiness = () => {
  				this.currNoHandledBusinessCount++;
  				this.lastBusinessGenTime = Timer.time;
  				this.saveRecord();
  			};
  			if ((!this.lastBusinessGenTime || (Timer.time - this.lastBusinessGenTime) > 1200) && this.currNoHandledBusinessCount < this.getMaxBusinessCumulateCount()) {
  				tryGenBusiness();
  			}
  		}
  	}
  	static getEventRewardGoldPerHandle() {
  		return Math.ceil((15 + mgrRole.getCurrLevelGotPropertyExtrnalValue()) * (mgrYard.getEventRewardGoldRatioPerHandle() || 1));
  	}
  	static getEventRewardPropertyRatioPerHandle() {
  		let buildLv = this.getBuildingLvByType(YardBuildType.Event);
  		let template = db.get_ggg_yard_build_template_db(YardBuildType.Event, buildLv);
  		return template.eventRewardPropertyRatio;
  	}
  	static getEventRewardGoldRatioPerHandle() {
  		let buildLv = this.getBuildingLvByType(YardBuildType.Event);
  		let template = db.get_ggg_yard_build_template_db(YardBuildType.Event, buildLv);
  		return template.eventRewardGoldRatio;
  	}
  	static getCurrUnhandledEventQuestiond() {
  		if (!this.currNoHandledEventQuestionId) {
  			this.currNoHandledEventQuestionId = this.randomGetOneEventQuestionId();
  			this.saveRecord();
  		}
  		return this.currNoHandledEventQuestionId;
  	}
  	static randomGetOneEventQuestionId() {
  		let playerRole = db.get_amaze_cloth_crossing_property_to_logic_role(mgrRole.getUsingPlayerRoleId());
  		return Tools.randomGotOneArrayData(playerRole.yardEventQuestionIdArr);
  	}
  	static getUnhandledEventIdCount() {
  		return this.currNoHandledEventCount;
  	}
  	static markUnhandledEventHandledOnce() {
  		this.currNoHandledEventQuestionId = 0;
  		this.currNoHandledEventCount = Math.max(0, this.currNoHandledEventCount - 1);
  		this.saveRecord();
  	}
  	static getMaxEventCumulateCount() {
  		let buildLv = this.getBuildingLvByType(YardBuildType.Business);
  		let template = db.get_ggg_yard_build_template_db(YardBuildType.Business, buildLv);
  		return template.eventMaxCount || 1;
  	}
  	static getBusinessOutputRatio() {
  		let buildLv = this.getBuildingLvByType(YardBuildType.Business);
  		let template = db.get_ggg_yard_build_template_db(YardBuildType.Business, buildLv);
  		return template.businessMaxCount;
  	}
  	static getCurrUnhandledBusinessQuestiond() {
  		if (!this.currNoHandledBusinessQuestionId) {
  			this.currNoHandledBusinessQuestionId = this.randomGetOneBusinessQuestionId();
  			this.saveRecord();
  		}
  		return this.currNoHandledBusinessQuestionId;
  	}
  	static randomGetOneBusinessQuestionId() {
  		let playerRole = db.get_amaze_cloth_crossing_property_to_logic_role(mgrRole.getUsingPlayerRoleId());
  		return Tools.randomGotOneArrayData(playerRole.yardBusinessQuestionIdArr);
  	}
  	static getUnhandledBusinessCount() {
  		return this.currNoHandledBusinessCount;
  	}
  	static markUnhandledBusinessHandledOnce() {
  		this.currNoHandledBusinessQuestionId = 0;
  		this.currNoHandledBusinessCount = Math.max(0, this.currNoHandledBusinessCount - 1);
  		this.saveRecord();
  	}
  	static getMaxBusinessCumulateCount() {
  		let buildLv = this.getBuildingLvByType(YardBuildType.Business);
  		let template = db.get_ggg_yard_build_template_db(YardBuildType.Business, buildLv);
  		return template.businessMaxCount || 1;
  	}
  	static getLastGoldOutputTime() {
  		return this.lastGoldOutputTime || 0;
  	}
  	static getGoldOutputCount() {
  		let buildLv = this.getBuildingLvByType(YardBuildType.Gold);
  		let template = db.get_ggg_yard_build_template_db(YardBuildType.Gold, buildLv);
  		let perSecond = template.goldOutputPerHour / 3600;
  		let lastGoldOutputTime = this.lastGoldOutputTime || Timer.time;
  		return Math.floor(Tools.clamp(Timer.time - lastGoldOutputTime, 0, this.MAX_CUMULATION_GOLD_TIME_SECOND) * perSecond);
  	}
  	static receiveGoldOutput() {
  		let count = this.getGoldOutputCount();
  		BaseFacade.mItem.addItem(2, count, "庭院聚宝盆");
  		this.lastGoldOutputTime = Timer.time;
  		return count;
  	}
  	static markLotteryPlayOnce() {
  		BaseFacade.mItem.subItem(983, 1, "");
  	}
  	static getLotteryRemainCount() {
  		return BaseFacade.mItem.getItemAmount(983);
  	}
  	static getAdLotteryRemainCount() {
  		return mgrAdv.getLeftCount(db.ADV_DB_ADVNAME.video_PanelYardLottery_lottery);
  	}
  	static getLotteryItemInfo() {
  		let buildLv = this.getBuildingLvByType(YardBuildType.Lottery);
  		let arr = [];
  		let dbMap = db.get_ggg_yard_lottery_template_db_map();
  		for (let k in dbMap) {
  			if (dbMap[k].level == buildLv) {
  				arr.push(dbMap[k]);
  			}
  		}
  		let data = Tools.deepCopy(Tools.randomGotOneArrayData(arr));
  		return data;
  	}
  	static getLotteryItemRatio() {
  		let buildLv = this.getBuildingLvByType(YardBuildType.Lottery);
  		let template = db.get_ggg_yard_build_template_db(YardBuildType.Lottery, buildLv);
  		return template.lotteryOutPutRatio || 1;
  	}
  	static getBuildingLvByType(buildingType) {
  		return this.building2LvDict[buildingType] || 0;
  	}
  	static testCanUpgradeLevel(buildingType, bIgnoreCose) {
  		let currLevel = this.getBuildingLvByType(buildingType);
  		let template = db.get_ggg_yard_build_template_db(buildingType, currLevel);
  		let templateNext = db.get_ggg_yard_build_template_db(buildingType, currLevel + 1);
  		if (!templateNext) {
  			return { bSuccess: false, tipStr: "已达最高级" };
  		}
  		if (!bIgnoreCose) {
  			let bEnoughItemId = BaseFacade.mItem.isEnoughItem(template.upgradeCostItemId, template.upgradeCostAmount);
  			let bEnoughItemId2 = BaseFacade.mItem.isEnoughItem(template.upgradeCostItemId2, template.upgradeCostAmount2);
  			if (bEnoughItemId && bEnoughItemId2) {
  			}
  			else if (!bEnoughItemId) {
  				let templateCost = db.get_item_db(template.upgradeCostItemId);
  				return { bSuccess: false, tipStr: `${templateCost.name}不足` };
  			}
  			else {
  				let templateCost = db.get_item_db(template.upgradeCostItemId2);
  				return { bSuccess: false, tipStr: `${templateCost.name}不足` };
  			}
  		}
  		GameStatistics.statisCommonEvent(templateNext.statisPointId);
  		return { bSuccess: true, tipStr: "升级成功" };
  	}
  	static upgradeLevel(buildingType, bIgnoreCose) {
  		let currLevel = this.getBuildingLvByType(buildingType);
  		let template = db.get_ggg_yard_build_template_db(buildingType, currLevel);
  		let templateNext = db.get_ggg_yard_build_template_db(buildingType, currLevel + 1);
  		if (!templateNext) {
  			return { bSuccess: false, tipStr: "已达最高级" };
  		}
  		if (!bIgnoreCose) {
  			let bEnoughItemId = BaseFacade.mItem.isEnoughItem(template.upgradeCostItemId, template.upgradeCostAmount);
  			let bEnoughItemId2 = BaseFacade.mItem.isEnoughItem(template.upgradeCostItemId2, template.upgradeCostAmount2);
  			if (bEnoughItemId && bEnoughItemId2) {
  				BaseFacade.mItem.subItem(template.upgradeCostItemId, template.upgradeCostAmount, "升级庭院建筑");
  				BaseFacade.mItem.subItem(template.upgradeCostItemId2, template.upgradeCostAmount2, "升级庭院建筑");
  			}
  			else if (!bEnoughItemId) {
  				let templateCost = db.get_item_db(template.upgradeCostItemId);
  				return { bSuccess: false, tipStr: `${templateCost.name}不足` };
  			}
  			else {
  				let templateCost = db.get_item_db(template.upgradeCostItemId2);
  				return { bSuccess: false, tipStr: `${templateCost.name}不足` };
  			}
  		}
  		this.building2LvDict[buildingType] = templateNext.level;
  		this.saveRecord();
  		GameStatistics.statisCommonEvent(templateNext.statisPointId);
  		Global.sendMsg("MSG_BUILDING_LEVEL_CHANGED", { buildingType: buildingType });
  		if (buildingType == YardBuildType.Event) {
  			this.currNoHandledEventCount += (templateNext.eventMaxCount - template.eventMaxCount);
  		}
  		else if (buildingType == YardBuildType.Business) {
  			this.currNoHandledBusinessCount += (templateNext.businessMaxCount - template.businessMaxCount);
  		}
  		return { bSuccess: true, tipStr: "升级成功" };
  	}
  	static isMaxLevel(buildingType) {
  		let currLevel = this.getBuildingLvByType(buildingType);
  		let templateNext = db.get_ggg_yard_build_template_db(buildingType, currLevel + 1);
  		if (!templateNext) {
  			return true;
  		}
  		return false;
  	}
  	static hasCanUpgradeBuilding() {
  		for (let buildingId = 1; buildingId <= 5; buildingId++) {
  			let ret = this.testCanUpgradeLevel(buildingId);
  			if (!!ret && ret.bSuccess) {
  				return true;
  			}
  		}
  		return false;
  	}
  	static getBadgeCount() {
  		if (this.currNoHandledEventCount > 0) {
  			return 1;
  		}
  		if (this.currNoHandledBusinessCount > 0) {
  			return 1;
  		}
  		if (mgrYard.getGoldOutputCount() > 10) {
  			return 1;
  		}
  		if ((mgrYard.getLotteryRemainCount() + mgrYard.getAdLotteryRemainCount()) > 0) {
  			return 1;
  		}
  		if (this.hasCanUpgradeBuilding()) {
  			return 1;
  		}
  		return 0;
  	}
  }
  mgrYard.MAX_DECREE_COUNT = 10;
  mgrYard.MAX_CUMULATION_GOLD_TIME_SECOND = 3600 * 5;

  class mgrUiBottom extends Manager {
  	static onLoad() {
  		super.onLoad();
  		this.enterGameTime = Tools.time();
  		console.log("初始化mgrUiBottom");
  		this.loadRecord();
  	}
  	static loadRecord() {
  		super.loadRecord();
  	}
  	static saveRecord() {
  		super.saveRecord();
  	}
  	static checkIfUiBottomRecovery(index) {
  		if (db.cop_db.ui_bottom_recovery_ratio[index] >= Tools.random(1, 100)) {
  			if (this.enterGameTime + db.cop_db.ui_bottom_not_recovery_time < Tools.time()) {
  				if (this.lastUiRecoveryTime + db.cop_db.ui_bottom_recovery_cd < Tools.time()) {
  					return true;
  				}
  			}
  		}
  		return false;
  	}
  	static recordUiRecoveryTime() {
  		this.lastUiRecoveryTime = Tools.time();
  	}
  }
  mgrUiBottom.lastUiRecoveryTime = 0;
  mgrUiBottom.curInBottomViewName = "";

  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();
  		mgrDynamicBone.__init();
  		mgrDebug.__init();
  		mgrTip.__init();
  		mgrSound.__init();
  		mgrMaterial.__init();
  		mgrChannel.__init();
  		mgrRole.__init();
  		mgrAlertRouter.__init();
  		mgrUiBottom.__init();
  		mgrGuide.__init();
  		mgrReview.__init();
  		mgrName.__init();
  		mgrCrossStage.__init();
  		mgrRetinue.__init();
  		mgrChallenge.__init();
  		mgrPet.__init();
  		mgrYard.__init();
  		Manager.loadAllManagers(() => {
  			this.state = 2;
  			Global.sendMsg(BASE_MSG.BASE_MGR_LOADED);
  			callback && callback(true);
  		});
  	}
  }
  ManagerLoader.state = 0;

  class SceneBase {
  }

  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;
  		}
  		this.loadFromText(onCallback);
  		this.loaded = true;
  		Global.sendMsg(BASE_MSG.CFG_LOAD_FINISH);
  	}
  	static loadFromText(callback) {
  		ResLoader.loadRes("res/cfg/allCfgDb.txt", Laya.Loader.BUFFER, (res) => {
  			if (res) {
  				let jsonStr = Tools.decompressArrToStr(Tools.compressArr(res));
  				let allCfgDb = JSON.parse(jsonStr);
  				this.initCfg(allCfgDb);
  			}
  			callback(!!res);
  		});
  	}
  	static initCfg(allCfgDb) {
  		db.setAllDbs(allCfgDb);
  	}
  }
  CfgLoader.loaded = false;

  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;
  	}
  	onMouseDown() {
  		this.bTouchBegin = true;
  		if (!this.bTween || !this._guiNode)
  			return;
  		Laya.Tween.to(this._guiNode, { scaleX: 1.1, scaleY: 1.1 }, 50);
  	}
  	onMouseUp() {
  		this.bTouchBegin = false;
  		if (!this.bTween || !this._guiNode)
  			return;
  		Laya.Tween.to(this._guiNode, { scaleX: 1, scaleY: 1 }, 50, Laya.Ease.backOut);
  	}
  	onMouseOut() {
  		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;
  	}
  	setScale(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;
  	}
  	set width(width) {
  		if (!this.guiNode)
  			return;
  		this.guiNode.width = width;
  	}
  	get width() {
  		if (!this.guiNode)
  			return;
  		return this.guiNode.width;
  	}
  	localToGlobal(x = 0, y = 0) {
  		return this.guiNode.localToGlobal(x, y);
  	}
  	globalToLocal(x = 0, y = 0) {
  		return this.guiNode.globalToLocal(x, y);
  	}
  }

  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();
  	}
  }

  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() {
  		this.destroyed = true;
  		super.dispose();
  	}
  	onCreate() { }
  }

  class CustomComponent extends fgui.GComponent {
  	constructor() {
  		super(...arguments);
  		this.destroyed = false;
  	}
  	constructFromResource() {
  		super.constructFromResource();
  		this.bindObject(this);
  		this.onCreate();
  	}
  	bindObject(object) {
  		ExportViewTool.bindViewToObject(this, object);
  		return this;
  	}
  	dispose() {
  		this.destroyed = true;
  		super.dispose();
  	}
  	onCreate() { }
  }

  var lastClickTime = 0;
  const CLICK_INTERVAL = 0.1;
  var ExportViewTool;
  (function (ExportViewTool) {
  	let default_click_sound = 101;
  	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);
  		checkUpdate(view, object);
  	}
  	ExportViewTool.bindViewToObject = bindViewToObject;
  	function tryShowPointInfo(view, object) {
  		if (!view || !object) {
  			return;
  		}
  		_tryShowPointInfo(view, object);
  	}
  	ExportViewTool.tryShowPointInfo = tryShowPointInfo;
  	function loadExportNode(view, node) {
  		const LAYOUT_PREFIX = [`LLT_`, `LL_`, `LLB_`, `LRT_`, `LR_`, `LRB_`, `LT_`, `LB_`];
  		for (let i = node.numChildren - 1; i >= 0; i--) {
  			let child = node.getChildAt(i);
  			let childName = child.name;
  			for (let __i = 0; __i < LAYOUT_PREFIX.length; __i++) {
  				const prefix = LAYOUT_PREFIX[__i];
  				childName = childName.replace(prefix, "");
  			}
  			if (/cc_/.test(childName.toLowerCase())) {
  				let fieldName = childName.substring(3);
  				view[fieldName] = child;
  				if (/cc_button/.test(childName.toLowerCase()) || /cc_btn/.test(childName.toLowerCase())) {
  					if (child instanceof fgui.GButton || child instanceof CustomButton) {
  					}
  					else {
  						if (child instanceof fgui.GImage) {
  							child.image.mouseEnabled = true;
  						}
  						if (child instanceof CustomComponent) {
  							child.displayObject.addComponent(ScaleButton).setGuiNode(child);
  						}
  						else {
  							view[fieldName] = child.displayObject.addComponent(ScaleButton).setGuiNode(child);
  						}
  					}
  					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);
  				}
  			}
  			if (child instanceof CustomButton || child instanceof CustomComponent)
  				continue;
  			if (child instanceof fgui.GComponent) {
  				loadExportNode(view, child);
  			}
  		}
  	}
  	function _bindClickFunc(view, callbackFuncName, clickSound, node, fieldName) {
  		if (view[callbackFuncName] && typeof view[callbackFuncName] == "function") {
  			let parentViewName = null;
  			if (view["parent"] && !Director.isCustomRootLayer(view["parent"])) {
  				let checkNode = view["parent"];
  				while (checkNode["parent"] && !Director.isCustomRootLayer(checkNode["parent"])) {
  					checkNode = checkNode["parent"];
  				}
  				if (checkNode["parent"] && !!Director.isCustomRootLayer(checkNode["parent"])) {
  					parentViewName = checkNode.name;
  				}
  			}
  			let userParams = [];
  			let statisPointId = 0;
  			let statisKey = `${view.name}_${fieldName}`;
  			if (!!parentViewName) {
  				statisKey = `${statisKey}_${parentViewName}`;
  			}
  			if (db[`_allDbs`] && db.get_ui_statis_button_db(statisKey)) {
  				let statisData = db.get_ui_statis_button_db(statisKey);
  				statisPointId = statisData.index;
  				for (let i = 1; i <= 10; i++) {
  					let fieldName = statisData["followContextFiled" + i];
  					if (!fieldName || fieldName == "") {
  						break;
  					}
  					let fieldValue = this.context[fieldName] || this[fieldName] || (!!this["data"] && this["data"][fieldName]) || "";
  					userParams.push(fieldValue);
  				}
  			}
  			if (mgrDebug.bShowStatisticsInfo && !node.displayObject["__testCustomButtonLabelName"]) {
  				let label = new Laya.Label;
  				label.fontSize = 18;
  				label.color = `#ffffff`;
  				label.stroke = 2;
  				label.strokeColor = `#ff000`;
  				label.anchorX = 0.5;
  				label.anchorY = 0.5;
  				label.text = `${statisPointId || "unknown"}`;
  				label.pos(node.width / 2, node.height / 2, true);
  				label.zOrder = 100;
  				node.displayObject["__testCustomButtonLabelName"] = label;
  				node.displayObject.addChild(label);
  			}
  			node.onClick(view, (e) => {
  				if (Timer.time - lastClickTime < 0)
  					lastClickTime = 0;
  				if (Timer.time - lastClickTime < CLICK_INTERVAL)
  					return;
  				lastClickTime = Timer.time;
  				if (clickSound) {
  					mgrSound.playSoundIfTimeout(clickSound, "default_click", 0.1);
  				}
  				view[callbackFuncName]();
  				statisPointId > 0 && GameStatistics.statisCommonEvent(statisPointId, undefined, undefined, undefined, userParams);
  				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);
  		}
  	}
  	function _tryShowPointInfo(view, node) {
  		if (!node) {
  			return;
  		}
  		let doShowButtonInfo = (view, callbackFuncName, node, fieldName) => {
  			if (view[callbackFuncName] && typeof view[callbackFuncName] == "function") {
  				let parentViewName = null;
  				if (view["parent"] && !Director.isCustomRootLayer(view["parent"])) {
  					let checkNode = view["parent"];
  					while (checkNode["parent"] && !Director.isCustomRootLayer(checkNode["parent"])) {
  						checkNode = checkNode["parent"];
  					}
  					if (checkNode["parent"] && !!Director.isCustomRootLayer(checkNode["parent"])) {
  						parentViewName = checkNode.name;
  					}
  				}
  				let userParams = [];
  				let statisPointId = 0;
  				let statisKey = `${view.name}_${fieldName}`;
  				if (!!parentViewName) {
  					statisKey = `${statisKey}_${parentViewName}`;
  				}
  				if (db[`_allDbs`] && db.get_ui_statis_button_db(statisKey)) {
  					let statisData = db.get_ui_statis_button_db(statisKey);
  					statisPointId = statisData.index;
  					for (let i = 1; i <= 10; i++) {
  						let fieldName = statisData["followContextFiled" + i];
  						if (!fieldName || fieldName == "") {
  							break;
  						}
  						let fieldValue = this.context[fieldName] || this[fieldName] || (!!this["data"] && this["data"][fieldName]) || "";
  						userParams.push(fieldValue);
  					}
  				}
  				if (mgrDebug.bShowStatisticsInfo && !node.displayObject["__testCustomButtonLabelName"]) {
  					let label = new Laya.Label;
  					label.fontSize = 18;
  					label.color = `#ffffff`;
  					label.stroke = 2;
  					label.strokeColor = `#ff000`;
  					label.anchorX = 0.5;
  					label.anchorY = 0.5;
  					label.text = `${statisPointId || "unknown"}`;
  					label.pos(node.width / 2, node.height / 2, true);
  					label.zOrder = 100;
  					node.displayObject["__testCustomButtonLabelName"] = label;
  					node.displayObject.addChild(label);
  				}
  			}
  		};
  		const LAYOUT_PREFIX = [`LLT_`, `LL_`, `LLB_`, `LRT_`, `LR_`, `LRB_`, `LT_`, `LB_`];
  		for (let i = node.numChildren - 1; i >= 0; i--) {
  			let child = node.getChildAt(i);
  			let childName = child.name;
  			for (let __i = 0; __i < LAYOUT_PREFIX.length; __i++) {
  				const prefix = LAYOUT_PREFIX[__i];
  				childName = childName.replace(prefix, "");
  			}
  			if (/cc_/.test(childName.toLowerCase())) {
  				let fieldName = childName.substring(3);
  				if (/cc_button/.test(childName.toLowerCase()) || /cc_btn/.test(childName.toLowerCase())) {
  					var callbackFuncName = `on_click_${fieldName}`;
  					doShowButtonInfo(view, callbackFuncName, child, fieldName);
  				}
  			}
  			if (child instanceof CustomButton || child instanceof CustomComponent)
  				continue;
  			if (child instanceof fgui.GComponent) {
  				_tryShowPointInfo(view, child);
  			}
  		}
  	}
  })(ExportViewTool || (ExportViewTool = {}));

  class ViewBase extends fgui.GComponent {
  	constructor(context) {
  		super();
  		this.destroyed = false;
  		this.exportNodeNames = null;
  		this.context = null;
  		this.delayCalls = [];
  		this.preloadedRess = [];
  		this._needClearTimer = false;
  		this.context = context || {};
  		this._isLoaded = false;
  		this._isLoading = false;
  	}
  	get isLoaded() {
  		return this._isLoaded;
  	}
  	get isLoading() {
  		return this._isLoading;
  	}
  	dispose() {
  		this.destroyed = true;
  		let node = this.resNode;
  		if (node) {
  			if (this._needClearTimer)
  				this.unscheduleAllCallbacks();
  			node.dispose();
  		}
  		for (let i = 0; i < this.preloadedRess.length; i++) {
  			const element = this.preloadedRess[i];
  			if (element.type == "res") {
  				element.res._removeReference();
  			}
  			else if (element.type == "sprite3d") {
  				element.res.destroy();
  			}
  		}
  		if (!this.isDisposed) {
  			super.dispose();
  		}
  	}
  	setContext(context) {
  		this.context = context || {};
  	}
  	create(callback) {
  		if (this._isLoaded) {
  			callback && callback(false);
  			return;
  		}
  		if (this._isLoading) {
  			callback && callback(false);
  			return;
  		}
  		let pName = this.constructor[`sourceName`];
  		if (!pName) {
  			console.error("AsyncObject.create: can't find resourceName.");
  			callback && callback(false);
  			return;
  		}
  		this._isLoading = true;
  		let res = fgui.UIPackage.getItemByURL(this.constructor[`sourceName`]);
  		if (!res) {
  			console.info("异步加载资源:", this.constructor[`sourceName`]);
  			let pkgReg = /ui:\/\/(\S+)\//img;
  			let result = pkgReg.exec(this.constructor[`sourceName`]);
  			if (result) {
  				let pkgName = result[1];
  				fgui.UIPackage.loadPackage(`res/fgui/${pkgName}`, Laya.Handler.create(this, () => {
  					let res = fgui.UIPackage.getItemByURL(this.constructor[`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 preRess = this.getAllPreLoadRes();
  		this.doProloadRes(preRess, () => {
  			if (this.isDisposed) {
  				callback && callback(false);
  				return;
  			}
  			let modelIds = this.getPreLoadModels();
  			if (!!modelIds && modelIds.length != 0) {
  				for (let k in modelIds) {
  					mgrMaterial.precompileShaderByPanelName(modelIds[k]);
  				}
  			}
  			this.onResourceLoaded(node);
  			callback && callback(true);
  			this.onCreate();
  			this.processDelayCalls();
  		});
  	}
  	doProloadResByIds(modelIdArr, animationIdArr, imageArr, spineIdArr, callback) {
  		console.warn("------ViewBase doProloadResByIds=", modelIdArr, animationIdArr, imageArr, spineIdArr);
  		let ress = [];
  		let modelIds = modelIdArr || [];
  		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,
  			});
  			mgrMaterial.precompileShaderByPanelName(modelId);
  		}
  		let images = imageArr || [];
  		for (let i = 0; i < images.length; i++) {
  			const src = images[i];
  			ress.push({
  				url: src,
  				type: RES_TYPE.IMAGE,
  			});
  		}
  		let animations = animationIdArr || [];
  		console.log("animations=========", animations);
  		for (let i = 0; i < animations.length; i++) {
  			const animationId = animations[i];
  			let animationData = db.get_animation_db(animationId);
  			console.log("animationId=========", animationId);
  			console.log("animationData=========", animationData);
  			ress.push({
  				url: animationData.path,
  				type: RES_TYPE.ANIMATIONCLIP,
  			});
  		}
  		let spineIds = spineIdArr || [];
  		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,
  			});
  		}
  		if (ress.length == 0) {
  			callback && callback();
  			return;
  		}
  		this.doProloadRes(ress, callback);
  	}
  	doProloadRes(preRess, callback) {
  		let tsManager = new TaskManager;
  		for (let i = 0; i < preRess.length; i++) {
  			const preRes = preRess[i];
  			tsManager.addCall((resolve) => {
  				ResLoader.loadRes(preRes.url, preRes.type, (res) => {
  					console.log(`预加载资源${preRes.url}${!!res ? '成功' : `失败`}`);
  					if (!this.isDisposed) {
  						if (res[`__addReference`]) {
  							res[`__addReference`]();
  							this.preloadedRess.push({
  								res: res,
  								type: "res"
  							});
  						}
  						else if (res instanceof Laya.Sprite3D) {
  							Director.scene3deffect.addChild(res);
  							res.transform.position = new Laya.Vector3(999, 999, 999);
  							this.preloadedRess.push({
  								res: res,
  								type: "sprite3d"
  							});
  						}
  					}
  					resolve();
  				});
  			});
  		}
  		tsManager.setLoadingCallback((bComplete) => {
  			if (bComplete) {
  				callback && callback();
  			}
  		});
  		tsManager.loadAll(this);
  	}
  	onResourceLoaded(node) {
  		this._isLoading = false;
  		this._isLoaded = true;
  		this.resNode = node;
  		this.setSize(this.resNode.width, this.resNode.height);
  		this.setPivot(node.pivotX, node.pivotY, node.pivotAsAnchor);
  		this.addChild(this.resNode);
  		this.resNode.setXY(this.width * this.pivotX, this.height * this.pivotY);
  		this.bindObject(node);
  	}
  	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 animations = this.getPreloadAnimations();
  		for (let i = 0; i < animations.length; i++) {
  			const animationId = animations[i];
  			let animationData = db.get_animation_db(animationId);
  			ress.push({
  				url: animationData.path,
  				type: RES_TYPE.ANIMATIONCLIP,
  			});
  		}
  		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.constructor[`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.call(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() { }
  	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);
  		}
  	}
  }

  class ReuseSprite extends fgui.GLoader {
  	constructor(key) {
  		super();
  		this.setPivot(0.5, 0.5, true);
  		this.setSize(100, 100);
  		this.autoSize = true;
  	}
  	dispose() {
  		if (this.effect) {
  			Global.poolManager.put(this.effect);
  			this.effect = null;
  		}
  		super.dispose();
  	}
  	reuse() {
  		this.visible = true;
  		if (this.effect) {
  			Director.scene3deffect.addChild(this.effect);
  			this.effect.play();
  		}
  	}
  	unuse() {
  		this.removeFromParent();
  		if (this.effect) {
  			this.effect.stopFollow();
  			this.effect.stop();
  			this.effect.removeSelf();
  		}
  		this.visible = false;
  	}
  	loadUrl(spriteUrl) {
  		this.url = spriteUrl;
  	}
  }

  class UiHelper {
  	static addClickEvent(node, callback, sound, clickDeltaTime = 0.5, scaleAnim = false) {
  		let lastTime = 0;
  		node.on(Laya.Event.CLICK, node, function (e) {
  			callback && callback();
  			// UiHelper.stopEventHandler(e);
  			// sound && mgrSound.playSound(sound);
  			// if (lastTime > Timer.time)
  			// 	return;
  			// if (clickDeltaTime) {
  			// 	lastTime = Timer.time + clickDeltaTime;
  			// }
  			// if (scaleAnim) {
  			// 	cc.tween(node).to(0.05, cc.PROP.SCALE1_2).to(0.05, cc.PROP.SCALE1).start();
  			// }
  			// callback && callback();
  		});
  	}
  	static addUIButtonClick(node, callback, sound) {
  		node.on("uibutton_click", node, function () {
  			sound && mgrSound.playSound(sound);
  			callback();
  		});
  	}
  	static addUIToggleClick(node, callback, sound) {
  		node.on("ui_toggle", node, function (bCheck) {
  			sound && mgrSound.playSound(sound);
  			callback(bCheck);
  		});
  	}
  	static addScrollViewClick(node, callback, sound, scaleAnim) {
  		let bTouch, touchX, touchY;
  		node.on(Laya.Event.MOUSE_DOWN, node, function (event) {
  			bTouch = true;
  			touchX = Laya.stage.mouseX;
  			touchY = Laya.stage.mouseY;
  			if (scaleAnim) {
  				cc$1.tween(node).to(0.05, cc$1.PROP.SCALE1_2).to(0.05, cc$1.PROP.SCALE1).start();
  			}
  		});
  		node.on(Laya.Event.MOUSE_MOVE, node, function (event) {
  			if (!bTouch)
  				return;
  			let curX = Laya.stage.mouseX;
  			let curY = Laya.stage.mouseY;
  			if (Mathf.distanceSqr2(curX - touchX, curY - touchY) > 16) {
  				bTouch = false;
  			}
  			touchX = curX;
  			touchY = curY;
  		});
  		function on_click(event) {
  			sound && mgrSound.playSound(sound);
  			callback();
  			UiHelper.stopEventHandler(event);
  		}
  		node.on(Laya.Event.CLICK, node, function (event) {
  			if (bTouch) {
  				on_click(event);
  			}
  		});
  		node.on("uibutton_click", node, on_click);
  	}
  	static getChildComponent(node, childName, type) {
  		if (!childName || childName == "") {
  			return node.getComponent(type);
  		}
  		else {
  			let child = UITools.getChild(node, childName);
  			return child ? child.getComponent(type) : null;
  		}
  	}
  	static getComponentsInChildren(root, type, out) {
  		out = out || [];
  		for (let i = 0; i < root.numChildren; i++) {
  			let child = root.getChildAt(i);
  			if (child) {
  				let comp = child.getComponent(type);
  				if (comp) {
  					out.push(comp);
  				}
  				this.getComponentsInChildren(child, type, out);
  			}
  		}
  		return out;
  	}
  	static registerTouchEvent(node, callback) {
  		let callbackParam = {
  			stageX: 0,
  			stageY: 0,
  			delta: 0,
  			bBegin: false,
  			bMove: false,
  			bEnd: false,
  			bCancel: false,
  			bClick: false,
  			bRightClick: false,
  			bRightDown: false,
  			bRightUp: false,
  			bWheel: false,
  			deltaX: 0,
  			deltaY: 0,
  			startStageX: 0,
  			startStageY: 0,
  		};
  		let setAllToDefault = (e) => {
  			callbackParam.bBegin = false;
  			callbackParam.bMove = false;
  			callbackParam.bEnd = false;
  			callbackParam.bCancel = false;
  			callbackParam.bClick = false;
  			callbackParam.bRightClick = false;
  			callbackParam.bRightDown = false;
  			callbackParam.bRightUp = false;
  			callbackParam.bWheel = false;
  			callbackParam.stageX = e.stageX;
  			callbackParam.stageY = e.stageY;
  			callbackParam.delta = e.delta;
  			callbackParam.deltaX = 0;
  			callbackParam.deltaY = 0;
  			callbackParam.startStageX = startPos.x;
  			callbackParam.startStageY = startPos.y;
  		};
  		let startPos = new Laya.Vector2;
  		let lastPos = new Laya.Vector2;
  		let startRightPos = new Laya.Vector2;
  		let bBegined = false;
  		let onTouchStart = (e) => {
  			setAllToDefault(e);
  			callbackParam.bBegin = true;
  			startPos.x = e.stageX;
  			startPos.y = e.stageY;
  			lastPos.x = e.stageX;
  			lastPos.y = e.stageY;
  			bBegined = true;
  			callback && callback(callbackParam);
  		};
  		let onTouchMove = (e) => {
  			if (!bBegined) {
  				return;
  			}
  			setAllToDefault(e);
  			callbackParam.bMove = true;
  			callbackParam.deltaX = e.stageX - lastPos.x;
  			callbackParam.deltaY = e.stageY - lastPos.y;
  			lastPos.x = e.stageX;
  			lastPos.y = e.stageY;
  			callback && callback(callbackParam);
  		};
  		let onTouchEnd = (e) => {
  			if (!bBegined) {
  				return;
  			}
  			setAllToDefault(e);
  			callbackParam.bEnd = true;
  			callbackParam.deltaX = e.stageX - lastPos.x;
  			callbackParam.deltaY = e.stageY - lastPos.y;
  			if (Math.abs(startPos.x - e.stageX) < 20 && Math.abs(startPos.y - e.stageY) < 20) {
  				callbackParam.bClick = true;
  			}
  			else {
  				callbackParam.bClick = false;
  			}
  			lastPos.x = e.stageX;
  			lastPos.y = e.stageY;
  			callback && callback(callbackParam);
  		};
  		let onTouchCancel = (e) => {
  			callback && callback(callbackParam);
  			// if (!bBegined) {
  			// 	return;
  			// }
  			// setAllToDefault(e);
  			// callbackParam.bCancel = true;
  			// callbackParam.deltaX = e.stageX - lastPos.x;
  			// callbackParam.deltaY = e.stageY - lastPos.y;
  			// lastPos.x = e.stageX;
  			// lastPos.y = e.stageY;
  			// callback && callback(callbackParam);
  		};
  		let onRightDown = (e) => {
  			setAllToDefault(e);
  			callbackParam.bRightDown = true;
  			startRightPos.x = e.stageX;
  			startRightPos.y = e.stageY;
  			callbackParam.deltaX = e.stageX - lastPos.x;
  			callbackParam.deltaY = e.stageY - lastPos.y;
  			lastPos.x = e.stageX;
  			lastPos.y = e.stageY;
  			callbackParam.startStageX = startRightPos.x;
  			callbackParam.startStageY = startRightPos.y;
  			bBegined = true;
  			callback && callback(callbackParam);
  		};
  		let onRightUp = (e) => {
  			if (!bBegined) {
  				return;
  			}
  			setAllToDefault(e);
  			callbackParam.bRightUp = true;
  			callbackParam.deltaX = e.stageX - lastPos.x;
  			callbackParam.deltaY = e.stageY - lastPos.y;
  			if (Math.abs(startRightPos.x - e.stageX) < 20 && Math.abs(startRightPos.y - e.stageY) < 20) {
  				callbackParam.bRightClick = true;
  			}
  			else {
  				callbackParam.bRightClick = false;
  			}
  			lastPos.x = e.stageX;
  			lastPos.y = e.stageY;
  			callback && callback(callbackParam);
  		};
  		let onMouseWheel = (e) => {
  			setAllToDefault(e);
  			callbackParam.bWheel = true;
  			callbackParam.deltaX = e.stageX - lastPos.x;
  			callbackParam.deltaY = e.stageY - lastPos.y;
  			lastPos.x = e.stageX;
  			lastPos.y = e.stageY;
  			callback && callback(callbackParam);
  		};
  		node.on(Laya.Event.MOUSE_DOWN, this, onTouchStart);
  		node.on(Laya.Event.MOUSE_MOVE, this, onTouchMove);
  		node.on(Laya.Event.MOUSE_UP, this, onTouchEnd);
  		node.on(Laya.Event.MOUSE_OUT, this, onTouchCancel);
  		node.on(Laya.Event.RIGHT_MOUSE_UP, this, onRightUp);
  		node.on(Laya.Event.RIGHT_MOUSE_DOWN, this, onRightDown);
  		node.on(Laya.Event.MOUSE_WHEEL, this, onMouseWheel);
  	}
  	static unregisterTouchEvent(node) {
  		if (node instanceof fgui.GObject) {
  			node.displayObject.offAll(Laya.Event.MOUSE_DOWN);
  			node.displayObject.offAll(Laya.Event.MOUSE_UP);
  			node.displayObject.offAll(Laya.Event.MOUSE_MOVE);
  			node.displayObject.offAll(Laya.Event.MOUSE_OUT);
  			node.displayObject.offAll(Laya.Event.CLICK);
  		}
  		else {
  			node.offAll(Laya.Event.MOUSE_DOWN);
  			node.offAll(Laya.Event.MOUSE_UP);
  			node.offAll(Laya.Event.MOUSE_MOVE);
  			node.offAll(Laya.Event.MOUSE_OUT);
  			node.offAll(Laya.Event.CLICK);
  		}
  	}
  	static calcRecursiveScale(node) {
  		let scale = 1;
  		do {
  			scale *= node.scaleX;
  			node = node.parent;
  		} while (node != null);
  		return scale;
  	}
  	static formatLastTime(time) {
  		let curTime = Timer.now * 1000;
  		let deltaHour = (curTime - time) / 3600 / 1000;
  		if (deltaHour > 24) {
  			return Tools.formatDate(time);
  		}
  		else {
  			if (deltaHour >= 1) {
  				return `${Math.round(deltaHour)}小时前`;
  			}
  			else {
  				let deltaMin = deltaHour * 60;
  				if (deltaMin >= 1) {
  					return `${Math.round(deltaMin)}分钟前`;
  				}
  				else {
  					return "刚刚";
  				}
  			}
  		}
  	}
  	static playBigSmallOnce(node, smallScale, bigScale, time = 0.1) {
  		cc$1.tween(node).to(time, { scaleX: bigScale, scaleY: bigScale }).to(time, { scaleX: smallScale, scaleY: smallScale }).start();
  	}
  	static playBreathe(node, smallScale = 0.9, bigScale = 1.1, time = 0.8) {
  		cc$1.tween(node, false).repeatForever(cc$1.tween().to(time, { scaleX: bigScale, scaleY: bigScale }).to(time, { scaleX: smallScale, scaleY: smallScale })).start();
  	}
  	static removeBreathe(node) {
  		cc$1.clearTween(node);
  		node.scale(1, 1, true);
  	}
  	static playScaleOneByOne(delay, delta, ...sprites) {
  		for (var i = 0, count = sprites.length; i < count; i++) {
  			var item = sprites[i];
  			if (item) {
  				this.playScaleOnce(item, delay);
  				delay += delta;
  			}
  		}
  	}
  	static playScaleOnce(sprite, delay = 0, time = 0.2) {
  		let originAlpha = sprite.alpha;
  		let originX = sprite.scaleX;
  		let originY = sprite.scaleY;
  		sprite.alpha = 0;
  		sprite.scaleX = 0;
  		sprite.scaleY = 0;
  		Laya.Tween.to(sprite, { scaleX: originX, scaleY: originY, alpha: originAlpha }, time * 1000, Laya.Ease.backOut, null, delay * 1000);
  	}
  	static playRotShake(sprite, time = 1, callback) {
  		let rot = sprite.rotation;
  		let delta = 0.06;
  		cc$1.tween(sprite).repeat(time / delta / 2, cc$1.tween()
  			.to(delta, { rotation: rot - 10 })
  			.to(delta, { rotation: rot + 10 })).to(delta / 2, { rotation: rot }).call(callback).start();
  	}
  	static playTipRot(sprite) {
  		cc$1.tween(sprite, true).repeatForever(cc$1.tween().repeat(2, cc$1.tween().to(0.2, { rotation: 15 }, cc$1.OPTION.SINE_IN_OUT).to(0.2, { rotation: -15 }, cc$1.OPTION.SINE_IN_OUT)).to(0.1, { rotation: 0 }).delay(2)).start();
  	}
  	static playRotCycle(node) {
  		cc$1.tween(node).repeatForever(cc$1.tween()
  			.to(0.05, { rotation: 10 })
  			.to(0.1, { rotation: -10 })
  			.to(0.1, { rotation: 10 })
  			.to(0.1, { rotation: -10 })
  			.to(0.05, { rotation: 0 })
  			.delay(1)).start();
  	}
  	static playFadein(sprite, delay = 0) {
  		if (sprite) {
  			sprite.alpha = 0;
  			Laya.Tween.to(sprite, cc$1.PROP.ALPHA1, 200, null, null, delay * 1000);
  		}
  	}
  	static playAlert(sprite, breathAnim) {
  		sprite.scale(0, 0, true);
  		cc$1.clearTween(sprite);
  		let alertTween = cc$1.tween(sprite)
  			.to(0.2, { scaleX: 0.2, scaleY: 1.2 })
  			.to(0.2, { scaleX: 1.1, scaleY: 0.9 }, { easing: cc$1.Ease.quadOut })
  			.to(0.1, { scaleX: 0.9, scaleY: 1.1 }, { easing: cc$1.Ease.quadOut })
  			.to(0.1, { scaleX: 1, scaleY: 1 }, { easing: cc$1.Ease.backOut });
  		if (breathAnim) {
  			alertTween = alertTween.call(function () {
  				cc$1.tween(sprite).repeatForever(cc$1.tween().to(0.8, { y: 60 }).to(0.8, { y: 74 })).start();
  			});
  		}
  		alertTween.start();
  	}
  	static playMoveOut(sprite, to, time = 0.3) {
  		cc$1.tween(sprite, true).to(time, { x: to }, cc$1.OPTION.SINE_OUT).hide().start();
  	}
  	static playMoveOutX(sprite, to, time = 0.3) {
  		cc$1.tween(sprite, true).to(time, { x: to }, cc$1.OPTION.SINE_OUT).hide().start();
  	}
  	static playMoveOutY(sprite, to, time = 0.3) {
  		cc$1.tween(sprite, true).to(time, { y: to }, cc$1.OPTION.SINE_OUT).hide().start();
  	}
  	static playMoveIn(sprite, to = 0, time = 0.3, delay = 0) {
  		cc$1.tween(sprite, true).show().delay(delay).to(time, { x: to }, cc$1.OPTION.BACK_OUT).start();
  	}
  	static playMoveInX(sprite, to = 0, time = 0.5, delay = 0) {
  		cc$1.tween(sprite, true).show().delay(delay).to(time, { x: to }, cc$1.OPTION.BACK_OUT).start();
  	}
  	static playMoveInY(sprite, to = 0, time = 0.5, delay = 0) {
  		cc$1.tween(sprite, true).show().delay(delay).to(time, { y: to }, cc$1.OPTION.BACK_OUT).start();
  	}
  	static getCircleConverter(height, width, bDown = true) {
  		let x0, y0, r2;
  		width /= 2;
  		let r = (height * height + width * width) / (2 * height);
  		x0 = width;
  		y0 = r - height;
  		r2 = r * r;
  		return function (x) {
  			let y;
  			if (bDown)
  				y = -(-Math.sqrt(r2 - Math.pow(x - x0, 2)) + y0);
  			else
  				y = -Math.sqrt(r2 - Math.pow(x - x0, 2)) + y0 + height;
  			return y;
  		};
  	}
  	static screenShootUI(width, height, offsetX, offsetY) {
  		let cavas = Laya.stage.drawToCanvas(width, height, offsetX, offsetY);
  		return cavas;
  	}
  	static saveToTempFile(tempCanvas) {
  		let tt = window['tt'] || window[`wx`];
  		if (!tt) {
  			return;
  		}
  		let data = {
  			x: 0,
  			y: 0,
  			width: tempCanvas.width,
  			height: tempCanvas.height,
  			destWidth: tempCanvas.width,
  			destHeight: tempCanvas.height,
  			fileType: 'png',
  			quality: 1
  		};
  		let tempFilePath = tempCanvas.toTempFilePathSync(data);
  		console.log(`Capture file success!${tempFilePath}`);
  		return tempFilePath;
  	}
  	static saveToPhotosAlbum(tempFilePath, tex, callback) {
  		let tt = window['tt'] || window[`wx`];
  		tt.saveImageToPhotosAlbum({
  			filePath: tempFilePath,
  			success: (res) => {
  				console.log(`saveImageToPhotosAlbum调用成功`);
  				callback && callback(0);
  			},
  			fail(res) {
  				console.log(`saveImageToPhotosAlbum调用失败`);
  				callback && callback(1);
  			},
  		});
  	}
  	static screenShot(camera, width, height) {
  		width = Math.floor(width);
  		height = Math.floor(height);
  		let newCamera = new Laya.Camera(camera.aspectRatio, camera.nearPlane, camera.farPlane);
  		newCamera.clearFlag = camera.clearFlag;
  		newCamera.cullingMask = camera.cullingMask;
  		newCamera.fieldOfView = camera.fieldOfView;
  		camera.parent.addChild(newCamera);
  		newCamera.transform.position = camera.transform.position;
  		newCamera.transform.rotation = camera.transform.rotation;
  		let rtx = new Laya.RenderTexture(width, height);
  		newCamera.renderTarget = rtx;
  		newCamera.render();
  		newCamera.destroy();
  		let bitmap = new Uint8Array(width * height * 4);
  		rtx.getData(0, 0, width, height, bitmap);
  		rtx.destroy();
  		let tex2d = new Laya.Texture2D(width, height, undefined, false, true);
  		tex2d.setPixels(bitmap);
  		return tex2d;
  	}
  	static testPlayPhoto(tex2d) {
  		let sprite = new Laya.Sprite();
  		let tex = Laya.Texture.create(tex2d, 0, 0, tex2d.width, tex2d.height);
  		sprite.size(tex2d.width, tex2d.height).pivot(tex2d.width / 2, tex2d.height / 2);
  		sprite.texture = tex;
  		Director.getLayer(5).displayObject.addChild(sprite);
  		sprite.pos(Global.canvasWidth / 2, Global.canvasHeight / 2, true);
  		cc$1.tween(sprite).delay(2).to(0.5, { scaleX: 0.3, scaleY: 0.3, alpha: 0 }).call(function () {
  			sprite.destroy();
  		}).start();
  	}
  	static playPhotoFlash() {
  		let sprite = new Laya.Sprite();
  		sprite.texture = UITools.WHITE_TEXTURE;
  		sprite.size(Global.canvasWidth, Global.canvasHeight);
  		sprite.alpha = 0;
  		Director.getLayer(5).displayObject.addChild(sprite);
  		cc$1.tween(sprite).to(0.08, cc$1.PROP.ALPHA1).to(0.5, cc$1.PROP.ALPHA0).call(() => {
  			sprite.destroy();
  		}).start();
  	}
  	static spriteScreenShot(sprite, reverse = true) {
  		let width = sprite.width;
  		let height = sprite.height;
  		if (!width || !height) {
  			Logger.error("sprite 必须要有尺寸");
  			return;
  		}
  		let rtTex = new Laya.RenderTexture2D(width, height, Laya.RenderTexture2D.FORMAT_R8G8B8A8);
  		sprite.drawToTexture(width, height, 0, 0, rtTex);
  		let bitmap = rtTex.getData(0, 0, width, height);
  		rtTex.destroy();
  		let tex2d = new Laya.Texture2D(width, height, Laya.Texture2D.FORMAT_R8G8B8A8, false);
  		if (reverse) {
  			tex2d.setPixels(Tools.reverseBitmap(bitmap, width, height));
  		}
  		else {
  			tex2d.setPixels(bitmap);
  		}
  		return tex2d;
  	}
  	static addFilterWithSingleton(target, filter) {
  		var filters = target.filters || [];
  		if (filters.indexOf(filter) >= 0)
  			return;
  		filters.push(filter);
  		target.filters = filters;
  	}
  	static addMaskFilter(sprite) {
  		if (!this._maskFilter) {
  			this._maskFilter = new Laya.ColorFilter();
  			this._maskFilter.adjustContrast(-100);
  		}
  		this.addFilterWithSingleton(sprite, this._maskFilter);
  	}
  	static removeColorMaskFilter(sprite) {
  		Laya.UIUtils.clearFilter(sprite, Laya.ColorFilter);
  	}
  	static addMaskFilter2(sprite) {
  		if (!this._maskFilter2) {
  			this._maskFilter2 = new Laya.ColorFilter();
  			this._maskFilter2.adjustContrast(-80);
  		}
  		this.addFilterWithSingleton(sprite, this._maskFilter2);
  	}
  	static playImageScaleAndJump(url, from, to, callback) {
  		let parent = Director.getLayer(2);
  		let sprite = Global.poolManager.get(ReuseSprite);
  		parent.addChild(sprite);
  		sprite.loadUrl(url);
  		sprite.setXY(from.x, from.y);
  		sprite.setScale(1, 1);
  		sprite.alpha = 1;
  		this.playScaleAndJump(sprite, to, 1, 1, 1, function () {
  			Global.poolManager.put(sprite);
  			callback && callback();
  		});
  	}
  	static playScaleAndJump(newSprite, toPos, toScaleX = 1, toScaleY = 1, toAlpha = 1, callback) {
  		callback = callback || Global.EMPTY_FUN;
  		let dis = Mathf.distance2(newSprite.x - toPos.x, newSprite.y - toPos.y);
  		let time = Mathf.lerpFromInverseLerp(0.3, 1, 100, 800, dis);
  		cc$1.tween(newSprite)
  			.to(0.3, { scaleX: newSprite.scaleX * 1, scaleY: newSprite.scaleY * 1 }, { easing: cc$1.Ease.backOut })
  			.delay(0.1)
  			.parallel(cc$1.tween().to(time, { scaleX: toScaleX, scaleY: toScaleY }), cc$1.tween().delay(time * 0.5).to(time * 0.5, { alpha: toAlpha }), cc$1.tween().then(cc$1.jumpTo(time, toPos.x, toPos.y, 100, 1)))
  			.call(callback).start();
  	}
  	static playMoveTo(newSprite, toPos, toScale, callback) {
  		callback = callback || Global.EMPTY_FUN;
  		cc$1.tween(newSprite)
  			.delay(0.2)
  			.to(1, { scaleX: toScale, scaleY: toScale, x: toPos.x, y: toPos.y }, { easing: cc$1.Ease.sineInOut })
  			.call(callback).start();
  	}
  	static playScaleAndMoveTo(newSprite, toPos, bigScale, toScale, callback) {
  		callback = callback || Global.EMPTY_FUN;
  		cc$1.tween(newSprite)
  			.delay(0.2)
  			.to(0.2, { scaleX: bigScale, scaleY: bigScale }, { easing: cc$1.Ease.backOut })
  			.to(1, { scaleX: toScale, scaleY: toScale, x: toPos.x, y: toPos.y }, { easing: cc$1.Ease.sineInOut })
  			.call(callback).start();
  	}
  	static playStampEffect(sprite, callback) {
  		let node;
  		let autoRemove = false;
  		if (typeof sprite == "string") {
  			node = new Laya.Sprite();
  			node.loadImage(sprite);
  			autoRemove = true;
  		}
  		else {
  			node = sprite;
  		}
  		if (node.texture.getIsReady()) {
  			playEffect();
  		}
  		else {
  			node.texture.once(Laya.Event.LOADED, this, playEffect);
  		}
  		function playEffect() {
  			node.pivot(node.width / 2, node.height / 2);
  			node.scale(3, 3, true);
  			let tween = cc$1.tween(node)
  				.to(0.2, cc$1.PROP.SCALE1)
  				.call(function () {
  					let node2 = new Laya.Sprite();
  					if (node instanceof Laya.Image) {
  						node2.texture = node.source;
  					}
  					else {
  						node2.texture = node.texture;
  					}
  					node.parent.addChild(node);
  					node2.pivot(node.pivotX, node.pivotY);
  					node2.pos(node.x, node.y, true);
  					cc$1.tween(node2).to(0.2, { scaleX: 1.4, scaleY: 1.4, alpha: 0 }).removeSelf(true).start();
  				})
  				.delay(2);
  			if (autoRemove) {
  				tween = tween.to(0.2, cc$1.PROP.ALPHA0).call(function () {
  					node.destroy(true);
  				});
  			}
  			tween.call(callback).start();
  		}
  	}
  	static debug_sprite(source, autoDestory = false) {
  		var tex2d;
  		var texture;
  		if (source instanceof Laya.Texture2D) {
  			texture = Laya.Texture.create(source, 0, 0, source.width, source.height);
  		}
  		else if (source instanceof Laya.RenderTexture) {
  			tex2d = new Laya.Texture2D(source.width, source.height, undefined, false, true);
  			var out = new Uint8Array(source.width * source.height * 4);
  			tex2d.setPixels(source.getData(0, 0, source.width, source.height, out));
  			texture = Laya.Texture.create(tex2d, 0, 0, source.width, source.height);
  		}
  		else {
  			tex2d = new Laya.Texture2D(source.width, source.height, undefined, false, true);
  			tex2d.setPixels(source.getData(0, 0, source.width, source.height));
  			texture = Laya.Texture.create(tex2d, 0, 0, source.width, source.height);
  		}
  		let sprite = new Laya.Sprite().size(source.width, source.height);
  		sprite.texture = texture;
  		let node = Director.getLayer(5).displayObject;
  		node.addChild(sprite);
  		sprite.pivot(source.width / 2, source.height / 2).pos(Global.canvasWidth / 2, Global.canvasHeight / 2, true);
  		cc$1.tween(sprite).to(2, { scaleX: 1.5, scaleY: 1.5 }).call(function () {
  			texture.destroy();
  			if (tex2d)
  				tex2d.destroy();
  			sprite.destroy();
  			if (autoDestory) {
  				source.destroy();
  			}
  		}).start();
  	}
  	static debug_line(scene, start, end) {
  		let lineSprite = scene.addChild(new Laya.PixelLineSprite3D(1));
  		lineSprite.addLine(start, end, Laya.Color.RED, Laya.Color.RED);
  	}
  	static tweenCamera(camera, time, toPos, rot, fov, easing, callback) {
  		cc$1.tween(camera, true).to(time, { fieldOfView: fov }).start();
  		let posFrom = Global.pool.get(Laya.Vector3);
  		camera.transform.localPosition.cloneTo(posFrom);
  		let rotFrom = Global.pool.get(Laya.Quaternion);
  		camera.transform.localRotation.cloneTo(rotFrom);
  		let posValue = Global.pool.get(Laya.Vector3);
  		let rotValue = Global.pool.get(Laya.Quaternion);
  		cc$1.tween(camera.transform, true).to(time, {}, {
  			easing: easing,
  			onUpdate: (tran, t) => {
  				Laya.Vector3.lerp(posFrom, toPos, t, posValue);
  				tran.localPosition = posValue;
  				Laya.Quaternion.lerp(rotFrom, rot, t, rotValue);
  				tran.localRotation = rotValue;
  			}
  		}).call(function () {
  			Global.pool.put(posFrom);
  			Global.pool.put(rotFrom);
  			Global.pool.put(posValue);
  			Global.pool.put(rotValue);
  			callback && callback();
  		}).start();
  	}
  	static tweenPosition(from, to, time, easing, delay = 0, callback) {
  		let posFrom = Global.pool.get(Laya.Vector3);
  		from.transform.localPosition.cloneTo(posFrom);
  		let posValue = Global.pool.get(Laya.Vector3);
  		cc$1.tween(from.transform, true).delay(delay).to(time, {}, {
  			easing: easing,
  			onUpdate: (tran, t) => {
  				Laya.Vector3.lerp(posFrom, to.transform.localPosition, t, posValue);
  				tran.localPosition = posValue;
  			}
  		}).call(function () {
  			Global.pool.put(posFrom);
  			Global.pool.put(posValue);
  			callback && callback();
  		}).start();
  	}
  	static tweenTransform(from, to, time, easing, delay = 0, callback) {
  		let posFrom = Global.pool.get(Laya.Vector3);
  		from.transform.localPosition.cloneTo(posFrom);
  		let rotFrom = Global.pool.get(Laya.Quaternion);
  		from.transform.localRotation.cloneTo(rotFrom);
  		let posValue = Global.pool.get(Laya.Vector3);
  		let rotValue = Global.pool.get(Laya.Quaternion);
  		cc$1.tween(from.transform, true).delay(delay).to(time, {}, {
  			easing: easing,
  			onUpdate: (tran, t) => {
  				Laya.Vector3.lerp(posFrom, to.transform.localPosition, t, posValue);
  				tran.localPosition = posValue;
  				Laya.Quaternion.lerp(rotFrom, to.transform.localRotation, t, rotValue);
  				tran.localRotation = rotValue;
  			}
  		}).call(function () {
  			Global.pool.put(posFrom);
  			Global.pool.put(rotFrom);
  			Global.pool.put(posValue);
  			Global.pool.put(rotValue);
  			callback && callback();
  		}).start();
  	}
  	static drawToRtx(sprite, offsetX, offsetY, rt, ctx) {
  		offsetX -= sprite.x;
  		offsetY -= sprite.y;
  		offsetX |= 0;
  		offsetY |= 0;
  		ctx["_targets"] = rt;
  		rt.start();
  		let _renderType = sprite["_renderType"];
  		Laya.RenderSprite.renders[_renderType]._fun(sprite, ctx, offsetX, offsetY);
  		ctx.flush();
  		rt.end();
  		rt.restore();
  		ctx["_targets"] = null;
  	}
  	static playPopup(res, worldPos) {
  		ResLoader.loadRes(res, RES_TYPE.IMAGE, function (res) {
  			let sprite = new Laya.Sprite();
  			sprite.texture = res;
  			sprite.pivot(res.width / 2, res.height / 2).pos(worldPos.x, worldPos.y, true).scale(0, 0, true);
  			let node = Director.getLayer(2).displayObject;
  			node.addChild(sprite);
  			cc$1.tween(sprite).parallel(cc$1.tween().to(0.3, { scaleX: 1, scaleY: 1 }, { easing: cc$1.Ease.backOut }), cc$1.tween().by(1, { y: -100 }), cc$1.tween().delay(0.5).to(0.2, { alpha: 0 })).call(function () {
  				sprite.destroy();
  			}).start();
  		});
  	}
  	static playJumpTo(sprite, time, to, callback) {
  		sprite.alpha = 0;
  		sprite.scale(0, 0, true);
  		cc$1.tween(sprite).parallel(cc$1.tween().then(cc$1.jumpTo(time, to.x, to.y, 200, 1)), cc$1.tween().to(time, { alpha: 1, scaleX: 1, scaleY: 1 })).call(callback).start();
  	}
  	static playBezierTo(image, from, to, time, scale = 1, callback) {
  		let sprite = Global.poolManager.get(ReuseSprite);
  		Director.getLayer(2).addChild(sprite);
  		sprite.loadUrl(image);
  		sprite.setXY(from.x, from.y);
  		sprite.setScale(scale, scale);
  		cc$1.tween(sprite, true).then(cc$1.bezierFromTo(time, from, to)).call(function () {
  			callback && callback();
  			Global.poolManager.put(sprite);
  		}).start();
  	}
  	static isTouched(obj, r) {
  		let p = new Laya.Point();
  		UITools.getSelfGlobalPos(obj, p);
  		return p.distance(Laya.stage.mouseX, Laya.stage.mouseY) < r;
  	}
  	static getSelfGlobalPos(sprite, outPos, globalNode) {
  		outPos = outPos || new Laya.Point();
  		if (sprite.parent) {
  			outPos.setTo(sprite.x, sprite.y);
  			sprite.parent.localToGlobal(outPos, false, globalNode);
  		}
  		return outPos;
  	}
  }
  UiHelper.point_temp = new Laya.Point();
  UiHelper.stopEventHandler = function stopEventFunc(e) {
  	e && e.stopPropagation && e.stopPropagation();
  };

  class ViewJumpGameSingle extends ViewBase {
  	constructor() {
  		super(...arguments);
  		this.JUMP_TYPE = "single";
  	}
  	onCreate() {
  		Global.registerListeners(this, {
  			[BASE_MSG.SDK_OPEN_JUMP_RESULT]: this.onMsgOpenJumpResult.bind(this),
  		});
  		UiHelper.registerTouchEvent(this, (e) => {
  			if (!e.bClick)
  				return;
  			mgrSdk.jumpOtherGame(this.datas[0].index, this.JUMP_TYPE);
  		});
  		this.visible = false;
  		mgrSdk.openJump(this.JUMP_TYPE);
  		cc$1.tween(this.loaderIcon)
  			.repeatForever(cc$1.tween()
  				.delay(1)
  				.to(0.2 / 2, { rotation: 5 })
  				.to(0.2, { rotation: -5 })
  				.to(0.2, { rotation: 5 })
  				.to(0.2 / 2, { rotation: 0 })
  				.delay(1)
  				.call(() => {
  					mgrSdk.openJump(this.JUMP_TYPE);
  				}))
  			.start();
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgOpenJumpResult(e) {
  		if (e.type == this.JUMP_TYPE) {
  			let datas = e.jumpInfo;
  			this.fillData(datas);
  		}
  	}
  	fillData(datas) {
  		if (!datas || datas.length == 0) {
  			this.visible = false;
  			return;
  		}
  		else {
  			this.visible = true;
  		}
  		this.datas = datas;
  		this.loaderIcon.url = datas[0].url;
  	}
  }
  ViewJumpGameSingle.sourceName = "ui://channel/ViewJumpGameSingle";

  class ViewMoreGameBanner extends ViewBase {
  	constructor() {
  		super(...arguments);
  		this.JUMP_TYPE = "list";
  	}
  	onCreate() {
  		this.listGames.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			obj.fillData(this.datas[idx].url);
  		});
  		this.listGames.on(fgui.Events.CLICK_ITEM, this, (obj) => {
  			let idx = obj[`idx`];
  			let gameData = this.datas[idx];
  			mgrSdk.jumpOtherGame(gameData.index, this.JUMP_TYPE);
  		});
  		this.listGames.numItems = 0;
  		Global.registerListeners(this, {
  			[BASE_MSG.SDK_OPEN_JUMP_RESULT]: this.onMsgOpenJumpResult.bind(this),
  		});
  		this.visible = false;
  		mgrSdk.openJump(this.JUMP_TYPE);
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgOpenJumpResult(e) {
  		if (e.type == this.JUMP_TYPE) {
  			if (!e || !e.jumpInfo || e.jumpInfo.length == 0) {
  				this.visible = false;
  				return;
  			}
  			else {
  				this.visible = true;
  			}
  			let datas = e.jumpInfo;
  			this.datas = datas;
  			this.listGames.numItems = this.datas.length;
  			let tween = cc$1.tween();
  			for (let i = 0; i < this.datas.length - 6; i++) {
  				tween.delay(2).call(() => {
  					this.listGames.scrollToView(i, true, true);
  				});
  			}
  			for (let i = this.datas.length - 7; i >= 0; i--) {
  				tween.delay(2).call(() => {
  					this.listGames.scrollToView(i, true, true);
  				});
  			}
  			cc$1.tween(this)
  				.repeatForever(tween)
  				.start();
  		}
  	}
  }
  ViewMoreGameBanner.sourceName = "ui://channel/ViewMoreGameBanner";

  class ViewMoreGameLeft extends ViewBase {
  	constructor() {
  		super(...arguments);
  		this.JUMP_TYPE = "list";
  	}
  	onCreate() {
  		Global.registerListeners(this, {
  			[BASE_MSG.SDK_OPEN_JUMP_RESULT]: this.onMsgOpenJumpResult.bind(this),
  		});
  		this.visible = false;
  		mgrSdk.openJump(this.JUMP_TYPE);
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgOpenJumpResult(e) {
  		if (e.type == this.JUMP_TYPE) {
  			if (!e || !e.jumpInfo || e.jumpInfo.length == 0) {
  				this.visible = false;
  				return;
  			}
  			else {
  				this.visible = true;
  			}
  			let datas = e.jumpInfo;
  			this.datas = datas;
  			this.fillData();
  		}
  	}
  	fillData() {
  		this.listGames.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			obj.fillData(this.datas[idx].url);
  		});
  		this.listGames.on(fgui.Events.CLICK_ITEM, this, (obj) => {
  			let idx = obj[`idx`];
  			let gameData = this.datas[idx];
  			mgrSdk.jumpOtherGame(gameData.index, this.JUMP_TYPE);
  		});
  		this.listGames.numItems = this.datas.length;
  		let tween = cc$1.tween();
  		for (let i = 0; i < this.datas.length - 6; i++) {
  			tween.delay(2).call(() => {
  				this.listGames.scrollToView(i, true, true);
  			});
  		}
  		for (let i = this.datas.length - 7; i >= 0; i--) {
  			tween.delay(2).call(() => {
  				this.listGames.scrollToView(i, true, true);
  			});
  		}
  		cc$1.tween(this.listGames)
  			.repeatForever(tween)
  			.start();
  	}
  }
  ViewMoreGameLeft.sourceName = "ui://channel/ViewMoreGameLeft";

  const DEBUG$3 = false;
  class GridAdv extends Laya.Sprite {
  	constructor(panelName) {
  		super();
  		this.bOpened = false;
  		this.bEnabled = true;
  		this.bshowGridad = false;
  		this.bShowGrid = true;
  		this.forceShowGrid = false;
  		this.size(80, 120);
  		this.panelName = panelName;
  		this.onCreateComplete();
  	}
  	onCreateComplete() {
  		Timer.callLoop(1, () => {
  			this.refreshState();
  		}, this);
  	}
  	destroy() {
  		super.destroy();
  		this.closeGridAd();
  	}
  	refreshState() {
  		if (!this.bEnabled)
  			return;
  		if (this.destroyed)
  			return;
  		if (DEBUG$3)
  			console.log("GridAdv.refreshState", this.panelName);
  		let topViewName = this.getTopViewName();
  		let bFocus = (this.panelName == topViewName) && this.bShowGrid;
  		this.onFocus(bFocus);
  	}
  	getTopViewName() {
  		let viewStack = Director.getDialogViewStack();
  		console.log(viewStack);
  		if (!viewStack || viewStack.length <= 0)
  			return "";
  		let topView = viewStack[viewStack.length - 1];
  		if (!topView)
  			return "";
  		if (DEBUG$3)
  			console.log("当前最上层的view名字是" + topView.name);
  		return topView.name;
  	}
  	onFocus(focus) {
  		if (DEBUG$3)
  			console.log("GridAdv.onFocus", focus, this.panelName);
  		if (!this.bEnabled)
  			return;
  		if (focus || this.forceShowGrid) {
  			this.openGridAd();
  		}
  		else {
  			this.closeGridAd();
  		}
  	}
  	openGridAd() {
  		if (DEBUG$3)
  			console.log("GridAdv.openGridAd", this.panelName, this.bOpened);
  		if (this.bOpened)
  			return;
  		this.bOpened = true;
  		Timer.callLoop(0.1, (timer) => {
  			if (this.destroyed || !this.bOpened) {
  				timer.stop();
  				return;
  			}
  			if (DEBUG$3)
  				console.log("GridAdv.on call loop");
  			if (this._tryOpenGridAd()) {
  				timer.stop();
  			}
  		}, this);
  	}
  	closeGridAd() {
  		if (DEBUG$3)
  			console.log("GridAdv.closeGridAd", this.panelName, this.bOpened);
  		if (!this.bOpened)
  			return;
  		this.bOpened = false;
  		if (DEBUG$3)
  			console.log("  call /c/closeGridAd");
  		mgrSdk.closeGridAd();
  	}
  	_tryOpenGridAd() {
  		if (DEBUG$3)
  			console.log("GridAdv._tryOpenGridAd", this.panelName);
  		if (this.destroyed)
  			return true;
  		let gPos = this.localToGlobal(new Laya.Point(0, this.height));
  		let ccx = gPos.x / Laya.stage.width;
  		let ccy = 1.0 - gPos.y / Laya.stage.height;
  		if (DEBUG$3)
  			console.log("  call /c/openGridAd", ccx, ccy);
  		mgrSdk.openGrid(ccx, ccy, this.panelName, undefined, Laya.stage.width, Laya.stage.height);
  		return true;
  	}
  }

  const DEBUG$4 = true;
  class NativeWxAdv extends Laya.Sprite {
  	constructor(w, h, tag, panelName) {
  		super();
  		this.bOpened = false;
  		this.bEnabled = true;
  		this.bShowNativeWxAdv = true;
  		this.forceShowGrid = false;
  		this.size(w, h);
  		this.tag = tag;
  		this.pivotX = 0;
  		this.pivotY = h;
  		this.panelName = panelName;
  		this.onCreateComplete();
  	}
  	onCreateComplete() {
  		Timer.callLoop(1, () => {
  			this.refreshState();
  		}, this);
  	}
  	destroy() {
  		super.destroy();
  		this.closeNativeWxAdv();
  	}
  	refreshState() {
  		if (!this.bEnabled)
  			return;
  		if (this.destroyed)
  			return;
  		if (DEBUG$4)
  			console.log("NativeWxAdv.refreshState", this.panelName);
  		let topViewName = this.getTopViewName();
  		let bFocus = (this.panelName == topViewName) && this.bShowNativeWxAdv;
  		this.onFocus(bFocus);
  	}
  	getTopViewName() {
  		let viewStack = Director.getDialogViewStack();
  		console.log(viewStack);
  		if (!viewStack || viewStack.length <= 0)
  			return "";
  		let topView = viewStack[viewStack.length - 1];
  		if (!topView)
  			return "";
  		if (DEBUG$4)
  			console.log("当前最上层的view名字是" + topView.name);
  		return topView.name;
  	}
  	onFocus(focus) {
  		if (DEBUG$4)
  			console.log("NativeWxAdv.onFocus", focus, this.panelName);
  		if (!this.bEnabled)
  			return;
  		if (focus || this.forceShowGrid) {
  			this.openNativeWxAdv();
  		}
  		else {
  			this.closeNativeWxAdv();
  		}
  	}
  	openNativeWxAdv() {
  		if (DEBUG$4)
  			console.log("NativeWxAdv.openNativeWxAdv", this.panelName, this.bOpened);
  		if (this.bOpened)
  			return;
  		this.bOpened = true;
  		Timer.callLoop(0.1, (timer) => {
  			if (this.destroyed || !this.bOpened) {
  				timer.stop();
  				return;
  			}
  			if (DEBUG$4)
  				console.log("NativeWxAdv.on call loop");
  			if (this._tryOpenNativeWxAdv()) {
  				timer.stop();
  			}
  		}, this);
  	}
  	closeNativeWxAdv() {
  		if (DEBUG$4)
  			console.log("NativeWxAdv.closeNativeWxAdv", this.panelName, this.bOpened);
  		if (!this.bOpened)
  			return;
  		this.bOpened = false;
  		if (DEBUG$4)
  			console.log("  call /c/closeNativeWxAdv");
  		mgrSdk.closeNativeWxAdv(this.tag);
  	}
  	_tryOpenNativeWxAdv() {
  		if (DEBUG$4)
  			console.log("NativeWxAdvs._tryOpenNativeWxAdv", this.panelName);
  		if (this.destroyed)
  			return true;
  		let gPos = this.localToGlobal(new Laya.Point(0, this.height));
  		let ccx = gPos.x / Laya.stage.width;
  		let ccy = 1.0 - gPos.y / Laya.stage.height;
  		let ccw = this.width / Laya.stage.width;
  		let cch = this.height / Laya.stage.height;
  		if (DEBUG$4)
  			console.log("call/c/openNativeWxAdv", ccx, ccy, ccw, cch);
  		mgrSdk.openNativeWxAdv({ x: ccx, y: ccy, width: ccw, height: cch }, this.tag);
  		return true;
  	}
  }

  class PanelBase extends ViewBase {
  	constructor() {
  		super(...arguments);
  		this.panelLayer = 1;
  		this.panelStyle = 2;
  		this.bFocus = false;
  		this.bResetRootNode = true;
  		this.bShowMask = true;
  		this.bMaskClose = false;
  		this.panelMaskAlpha = 0.7;
  	}
  	dispose() {
  		super.dispose();
  	}
  	create(callback) {
  		this.makeFullScreen();
  		if (this.bShowMask) {
  			let mask = new fgui.GGraph();
  			this.panelMask = mask;
  			this.addChild(mask);
  			mask.makeFullScreen();
  			mask.drawRect(0, "", "#000000");
  			mask.alpha = 0;
  			Laya.Tween.to(mask, { alpha: this.panelMaskAlpha }, 300);
  			if (this.bMaskClose) {
  				UiHelper.registerTouchEvent(mask, (e) => {
  					if (e.bClick) {
  						this.close();
  					}
  				});
  			}
  		}
  		Director.addPanel(this);
  		super.create(callback);
  	}
  	onCreate() {
  		if (this.bResetRootNode) {
  			this.setPivot(0.5, 0.5, true);
  			this.x = this.parent.width / 2;
  			this.y = this.parent.height / 2;
  			this.resNode.setPivot(0.5, 0.5, true);
  			this.resNode.x = this.width / 2;
  			this.resNode.y = this.height / 2;
  			if (this.panelMask) {
  				this.panelMask.setPivot(0.5, 0.5, true);
  				this.panelMask.x = this.width / 2;
  				this.panelMask.y = this.height / 2;
  			}
  		}
  		const LAYOUT_PREFIX = [
  			{
  				prefix: `LLT_`,
  				fun: UITools.widgetLeftTopMC.bind(UITools),
  			},
  			{
  				prefix: `LL_`,
  				fun: UITools.widgetLeftMC.bind(UITools),
  			},
  			{
  				prefix: `LLB_`,
  				fun: UITools.widgetLeftBottomMC.bind(UITools),
  			},
  			{
  				prefix: `LRT_`,
  				fun: UITools.widgetRightTopMC.bind(UITools),
  			},
  			{
  				prefix: `LR_`,
  				fun: UITools.widgetRightMC.bind(UITools),
  			},
  			{
  				prefix: `LRB_`,
  				fun: UITools.widgetRightBottomMC.bind(UITools),
  			},
  			{
  				prefix: `LT_`,
  				fun: UITools.widgetTopMC.bind(UITools),
  			},
  			{
  				prefix: `LB_`,
  				fun: UITools.widgetBottomMC.bind(UITools),
  			},
  		];
  		for (let i = 0; i < LAYOUT_PREFIX.length; i++) {
  			const info = LAYOUT_PREFIX[i];
  			let nodes = Tools.findAllNodeReg(info.prefix, this.resNode);
  			for (let __i = 0; __i < nodes.length; __i++) {
  				const node = nodes[__i];
  				info.fun(node);
  			}
  		}
  		this.adapt4399Mask();
  		this.adaptAdTag();
  		this.adaptJumpOtherGame();
  		this.adaptInsertAdv();
  		this.adaptFuncStatics();
  		this.onLoaded();
  		if (this.bOpenAndCloseAnim || this.bOpenAnim) {
  			this.onPanelOpenAnim(this.onOpenComplete.bind(this));
  		}
  		else {
  			this.onOpenComplete();
  		}
  		Global.registerListeners(this, {
  			[BASE_MSG.MSG_STATISTICS_BUTTON_FOCUS]: (repName) => {
  				let node = Tools.findNodeReg(repName, this);
  				if (node && node.displayObject) {
  					let sp = node.displayObject;
  					cc$1.tween(sp)
  						.to(0.15, { scaleX: 1.2, scaleY: 1.2 })
  						.to(0.15, { scaleX: 1, scaleY: 1 })
  						.union()
  						.repeat(3)
  						.start();
  				}
  			},
  			["MSG_SHOW_VIEW_BUTTON_INFO"]: () => {
  				this.adaptStatisDuration();
  				ExportViewTool.tryShowPointInfo(this, this.resNode);
  			}
  		});
  	}
  	adapt4399Mask() {
  		if (!db.cop_db.is4399Watermark)
  			return;
  		let sprite = new Laya.Sprite;
  		sprite.size(165, 37);
  		sprite.loadImage("res/print_4399.png");
  		this.displayObject.addChild(sprite);
  		let localPos = this.displayObject.globalToLocal(new Laya.Point(0, 50));
  		sprite.x = localPos.x;
  		sprite.y = localPos.y;
  	}
  	adaptAdTag() {
  		Timer.callLoopFrame(1, () => {
  			let nodes = Tools.findAllNodeReg("loaderAdTag", this.resNode);
  			switch (db.cop_db.ad_flag_style) {
  				case 0:
  					for (let i = 0; i < nodes.length; i++) {
  						const loader = nodes[i];
  						loader.url = "ui://base/icon_adv_normal_yellow";
  					}
  					break;
  				case 1:
  					for (let i = 0; i < nodes.length; i++) {
  						const loader = nodes[i];
  						loader.url = "ui://base/icon_adv_headline_yellow";
  					}
  					break;
  				default:
  					break;
  			}
  			nodes = Tools.findAllNodeReg("imageNativeBannerButtonTag", this.resNode);
  			for (let i = 0; i < nodes.length; i++) {
  				const node = nodes[i];
  				node.visible = db.cop_db.ad_banner_button_tag == 1;
  			}
  		}, this);
  	}
  	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++;
  				if (/\./.test(staticsData.methodName)) {
  					let arr = staticsData.methodName.split("\.");
  					if (arr) {
  						let managerName = arr[0];
  						let manager = Manager.managerMap[managerName];
  						if (!!manager) {
  							let funcName = arr[1];
  							if (!manager[`${funcName}_b_overreload`]) {
  								let temp = manager[funcName].bind(manager);
  								manager[funcName] = (...args) => {
  									temp(...args);
  									for (let i = PanelBase.staticsManagerFuncQueue[managerName].length - 1; i >= 0; i--) {
  										const element = PanelBase.staticsManagerFuncQueue[managerName][i];
  										if (!element.caller.destroyed) {
  											element.func();
  										}
  										else {
  											PanelBase.staticsManagerFuncQueue[managerName].splice(i, 1);
  										}
  									}
  								};
  								manager[`${funcName}_b_overreload`] = true;
  							}
  							if (!PanelBase.staticsManagerFuncQueue[managerName]) {
  								PanelBase.staticsManagerFuncQueue[managerName] = [];
  							}
  							PanelBase.staticsManagerFuncQueue[managerName].push({
  								caller: this,
  								func: () => {
  									GameStatistics.statisCommonEvent(staticsData.pointEventId);
  								}
  							});
  						}
  					}
  				}
  				else {
  					let temp = this[staticsData.methodName].bind(this);
  					this[staticsData.methodName] = (...args) => {
  						temp(...args);
  						GameStatistics.statisCommonEvent(staticsData.pointEventId);
  						console.log("人工打点：" + staticsData.pointEventId);
  					};
  				}
  			}
  			else {
  				break;
  			}
  		}
  	}
  	adaptInsertAdv() {
  		if (!db[`_allDbs`])
  			return;
  		let adbannerIntUiData = db.get_ad_banner_int_ui_db(this.name);
  		if (!adbannerIntUiData)
  			return;
  		if (db.cop_db.b_inst_in_guide == 0 && (!mgrGuide.isAllGuideFinished() || mgrGuide.isGuiding())) {
  			return;
  		}
  		mgrAdv.dispatchAdv(adbannerIntUiData.intEventId);
  		console.info("5555555555555555555555555555555555555");
  	}
  	adaptJumpOtherGame() {
  		if (!db[`_allDbs`])
  			return;
  		let jumpData = db.get_jump_point_event_db(this.name);
  		if (!jumpData)
  			return;
  		if (!mgrGuide.isAllGuideFinished())
  			return;
  		let bJumpSingleEnable = mgrSdk.getSubCop(`b_jump_other_game`) == 1 && db.cop_db.jump_single_switchs.indexOf(jumpData.index) >= 0;
  		if (bJumpSingleEnable && this[`comJumpSingle`]) {
  			let single = new ViewJumpGameSingle;
  			single.create();
  			this[`comJumpSingle`].addChild(single);
  			single.x = this[`comJumpSingle`].width / 2;
  			single.y = this[`comJumpSingle`].height / 2;
  		}
  		let bJumpBannerEnable = mgrSdk.getSubCop(`b_jump_other_game_banner`) == 1 && db.cop_db.jump_banner_switchs.indexOf(jumpData.index) >= 0;
  		if (bJumpBannerEnable) {
  			let banner = new ViewMoreGameBanner;
  			banner.create();
  			this.resNode.addChild(banner);
  			banner.callIfLoaded(() => {
  				banner.x = this.resNode.width / 2;
  				banner.y = this.resNode.height;
  				UITools.widgetBottomMC(banner);
  				banner.y -= 200;
  				banner.y += jumpData.bJumpBannerOffsetY || 0;
  			});
  		}
  		let bJumpSideEnable = mgrSdk.getSubCop(`b_jump_other_game_left`) == 1 && db.cop_db.jump_left_switchs.indexOf(jumpData.index) >= 0;
  		if (bJumpSideEnable && this[`comJumpBanner`]) {
  			let sideBanner = new ViewMoreGameLeft;
  			sideBanner.create();
  			this[`comJumpBanner`].addChild(sideBanner);
  			sideBanner.x = this[`comJumpBanner`].width / 2;
  			sideBanner.y = this[`comJumpBanner`].height / 2;
  		}
  		mgrAlertRouter.tryAlertJump(jumpData.index, this.name);
  		let gridIndex = db.cop_db.grid_ad_switchs.indexOf(jumpData.index);
  		if (this[`comGridAdv`] && gridIndex >= 0) {
  			let ratio = db.cop_db.grid_ad_ratios[gridIndex] || 0;
  			if (Mathf.random(0, 100) <= ratio) {
  				let grid = new GridAdv(this.name);
  				this[`comGridAdv`].displayObject.addChild(grid);
  			}
  		}
  		let nativeIndex = db.cop_db.native_wx_ad_switchs.indexOf(jumpData.index);
  		if (this[`commNativeWx`] && nativeIndex >= 0) {
  			let grid = new NativeWxAdv(this[`commNativeWx`].initWidth, this[`commNativeWx`].initHeight, jumpData.index + 10000, this.name);
  			this[`commNativeWx`].displayObject.addChild(grid);
  		}
  	}
  	onLoaded() { }
  	onOpenComplete() {
  	}
  	onFocus(focus) {
  		this.bFocus = focus;
  		this.adaptBannerAdv();
  		this.adaptStatisDuration();
  	}
  	adaptBannerAdv() {
  		if (!db[`_allDbs`])
  			return;
  		PanelBase.NATIVE_BANNER_REFRESH_INTERVALE = db.cop_db.ad_banner_refresh_cd;
  		Timer.callLoopFrame(1, () => {
  			if (!this[`buttonNativeBannerGo`])
  				return;
  			let adbannerIntUiData = db.get_ad_banner_int_ui_db(this.name);
  			if (!adbannerIntUiData) {
  				this[`buttonNativeBannerGo`].visible = false;
  				return;
  			}
  			if (db.cop_db.ad_banner_button_switchs.indexOf(adbannerIntUiData.index) == -1) {
  				this[`buttonNativeBannerGo`].visible = false;
  				return;
  			}
  			this[`on_click_buttonNativeBannerGo`] = () => {
  				mgrAdv.onNativeAdvClick(PanelBase.showingBannerAdvId, null);
  			};
  			let panelClass = Director.getPanelClass(`PanelNativeBanner`);
  			let view = Director.findPanel(panelClass);
  			this[`buttonNativeBannerGo`].visible = view && view.visible && view.resNode && view.resNode.visible;
  		}, this);
  		if (this.bFocus && this.panelLayer == 1) {
  			let bCanShowBanner = true;
  			let adbannerIntUiData = db.get_ad_banner_int_ui_db(this.name);
  			if (!adbannerIntUiData) {
  				bCanShowBanner = false;
  			}
  			if (bCanShowBanner && db.cop_db.b_banner_in_guide == 0 && (!mgrGuide.isAllGuideFinished() || mgrGuide.isGuiding())) {
  				bCanShowBanner = false;
  			}
  			if (bCanShowBanner && !mgrAdv.checkActive(adbannerIntUiData.bannerEventId)) {
  				bCanShowBanner = false;
  			}
  			console.log("查看curInBottomViewName", mgrUiBottom.curInBottomViewName, this.name);
  			if (bCanShowBanner && this.name == mgrUiBottom.curInBottomViewName) {
  				bCanShowBanner = false;
  			}
  			if (bCanShowBanner == true) {
  				if (PanelBase.showingBannerAdvId && Timer.time - PanelBase.lastShowingNativeBannerTime < PanelBase.NATIVE_BANNER_REFRESH_INTERVALE) {
  					return;
  				}
  				PanelBase.showingBannerAdvId && mgrAdv.closeAdv(PanelBase.showingBannerAdvId);
  				PanelBase.showingBannerAdvId = null;
  				console.info("5555555555555555555555555555555555555");
  				if (mgrAdv.dispatchAdv(adbannerIntUiData.bannerEventId, undefined, true)) {
  					PanelBase.showingBannerAdvId = adbannerIntUiData.bannerEventId;
  					PanelBase.lastShowingNativeBannerTime = Timer.time;
  				}
  			}
  			else {
  				this.tryCloseBannerAdv();
  			}
  		}
  	}
  	tryCloseBannerAdv() {
  		if (!PanelBase.showingBannerAdvId) {
  			return;
  		}
  		mgrAdv.closeAdv(PanelBase.showingBannerAdvId);
  		PanelBase.showingBannerAdvId = null;
  	}
  	adaptStatisDuration() {
  		if (!db[`_allDbs`])
  			return;
  		let statisDurationData = db.get_ui_statis_duration_db(this.name);
  		if (!statisDurationData)
  			return;
  		if (this.bFocus) {
  			GameStatistics.statisOnStageStart(statisDurationData.index);
  		}
  		else {
  			GameStatistics.statisOnStageEnd(statisDurationData.index);
  		}
  		Global.sendMsg("MSG_VIEW_STATISTICS", { viewName: this.name, panelName: this.PANEL_NAME, bFocus: this.bFocus });
  	}
  	close(imm) {
  		Timer.callLaterFrame(1, () => {
  			if (!imm && (this.bOpenAndCloseAnim || this.bCloseAnim)) {
  				if (this.panelMask) {
  					Laya.Tween.to(this.panelMask, PanelBase.CLOSE_PROP_MASK, 150);
  				}
  				this.onPanelCloseAnim(this._close.bind(this));
  			}
  			else {
  				this._close();
  			}
  		}, this);
  	}
  	_close() {
  		this.context.fOnClose && this.context.fOnClose();
  		if (this.isLoaded)
  			Director.closePanel(this);
  		else
  			this.dispose();
  		Global.sendMsg(BASE_MSG.UI_PANEL_CLOSED, this);
  	}
  	onPanelOpenAnim(onComplete) {
  		this.resNode.setScale(0, 0);
  		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);
  		this.scheduleOnce(0.2, onComplete);
  	}
  	setTop() {
  		if (this.parent) {
  			this.parent.setChildIndex(this, this.parent.numChildren - 1);
  			Director.setPanelToTop(this);
  		}
  	}
  	setBottom() {
  		if (this.parent) {
  			this.parent.setChildIndex(this, 0);
  			Director.setPanelToBottom(this);
  		}
  	}
  	resetResolution(width, height) {
  		UIRoot.instance.standardShort = width;
  		UIRoot.instance.standardLong = height;
  		UIRoot.instance.maxRate = width / height;
  		UIRoot.instance.uiMinRate = width / height;
  		UIRoot.instance.canvasMinRate = width / height;
  		UIRoot.instance.onAwake();
  		this.parent.width = Laya.stage.width;
  		this.parent.height = Laya.stage.height;
  		this.x = this.parent.width / 2;
  		this.y = this.parent.height / 2;
  	}
  }
  PanelBase.OPEN_PROP_PANEL = { scaleX: 1, scaleY: 1, alpha: 1 };
  PanelBase.CLOSE_PROP_MASK = { alpha: 0 };
  PanelBase.CLOSE_PROP_PANEL = { scaleX: 0, scaleY: 0, alpha: 0 };
  PanelBase.staticsManagerFuncQueue = {};
  PanelBase.showingBannerAdvId = null;
  PanelBase.lastShowingNativeBannerTime = 0;
  PanelBase.NATIVE_BANNER_REFRESH_INTERVALE = 0;

  var Keyboard$1 = 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$1.W:
  			case Keyboard$1.S:
  			case Keyboard$1.A:
  			case Keyboard$1.D:
  				var prop = this.props[e.keyCode];
  				if (prop) {
  					this.updateValue1(prop[0], prop[1]);
  				}
  				break;
  			case Keyboard$1.UP:
  			case Keyboard$1.DOWN:
  			case Keyboard$1.LEFT:
  			case Keyboard$1.RIGHT:
  				var prop = this.props[e.keyCode];
  				if (prop) {
  					this.updateValue2(prop[0], prop[1]);
  				}
  				break;
  			case Keyboard$1.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$1.W, key, step);
  		return this;
  	}
  	down(key, step = 1) {
  		this.setProp(Keyboard$1.S, key, step);
  		return this;
  	}
  	left(key, step = -1) {
  		this.setProp(Keyboard$1.A, key, step);
  		return this;
  	}
  	right(key, step = 1) {
  		this.setProp(Keyboard$1.D, key, step);
  		return this;
  	}
  	up2(key, step = -1) {
  		this.setProp(Keyboard$1.UP, key, step);
  		return this;
  	}
  	down2(key, step = 1) {
  		this.setProp(Keyboard$1.DOWN, key, step);
  		return this;
  	}
  	left2(key, step = -1) {
  		this.setProp(Keyboard$1.LEFT, key, step);
  		return this;
  	}
  	right2(key, step = 1) {
  		this.setProp(Keyboard$1.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$2 = 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 = {}));
  class CameraFollow extends Laya.Script3D {
  	constructor() {
  		super();
  		this.__node = null;
  		this.lerpValuePosZ = 0;
  		this.lerpValuePosX = 0;
  		this.minTargetX = 0;
  		this.maxTargetX = 0;
  		this.bEnableXClamp = false;
  		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 target(t) {
  		this.__target = t;
  	}
  	get target() {
  		return this.__target;
  	}
  	get destroyed() {
  		return super.destroyed || this.owner.destroyed || !this.owner.displayedInStage;
  	}
  	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;
  	}
  	set bAverageSpeed(value) {
  		this._bAverage = value;
  		this.originRotation = this.__node.transform.rotationEuler.clone();
  		this.originPosition = this.__node.transform.position.clone();
  		this._startTime = Timer.time;
  	}
  	enableClampX(minValue, maxValue) {
  		this.bEnableXClamp = true;
  		this.minTargetX = minValue;
  		this.maxTargetX = maxValue;
  	}
  	disableClampX() {
  		this.bEnableXClamp = false;
  		this.minTargetX = -9999;
  		this.maxTargetX = 9999;
  	}
  	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._bAverage) {
  			let factor = (Timer.time - this._startTime) / this.lerpValue;
  			factor = Mathf.clamp(factor, 0, 1);
  			if (factor == 1)
  				this._bAverage = false;
  			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 curPosition = this.__node.transform.position.clone();
  			let curRotation = this.__node.transform.rotationEuler.clone();
  			this.__node.transform.rotationEuler = this.endRotation;
  			let forward = new Laya.Vector3;
  			this.__node.transform.getForward(forward);
  			Laya.Vector3.normalize(forward, forward);
  			Laya.Vector3.scale(forward, -this._new_diatance, forward);
  			let outPos = new Laya.Vector3();
  			Laya.Vector3.add(targetPos, forward, outPos);
  			Laya.Vector3.add(outPos, this._new_offset, outPos);
  			Laya.Vector3.lerp(curPosition, outPos, this.lerpValue, outPos);
  			let usePos = outPos;
  			if (this.lerpValuePosX || this.lerpValuePosZ) {
  				let outTmpPos = new Laya.Vector3();
  				Laya.Vector3.add(targetPos, forward, outTmpPos);
  				Laya.Vector3.add(outTmpPos, this._new_offset, outTmpPos);
  				if (!!this.lerpValuePosZ) {
  					Laya.Vector3.lerp(curPosition, outTmpPos, this.lerpValuePosZ, outTmpPos);
  					usePos.z = outTmpPos.z;
  				}
  				if (!!this.lerpValuePosX) {
  					Laya.Vector3.lerp(curPosition, outTmpPos, this.lerpValuePosX, outTmpPos);
  					usePos.x = outTmpPos.x;
  				}
  			}
  			this.__node.transform.position = new Laya.Vector3(!!this.bEnableXClamp ? Tools.clamp(usePos.x, this.minTargetX, this.maxTargetX) : usePos.x, usePos.y, usePos.z);
  			Laya.Vector3.lerp(curRotation, this.endRotation, this.lerpValue, outPos);
  			this.__node.transform.rotationEuler = 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;
  		}
  	}
  	setToEnd() {
  		let oldLerpValue = this.lerpValue;
  		this.lerpValue = 1;
  		this.onLateUpdate();
  		this.lerpValue = oldLerpValue;
  	}
  	onMsgKeyDown(e) {
  		if (this.__node && !this.__node.destroyed && this.__node.scene)
  			switch (e.keyCode) {
  				case Keyboard$2.NUMBER_1:
  					this.distance += 0.05;
  					break;
  				case Keyboard$2.NUMBER_2:
  					this.distance -= 0.05;
  					break;
  				case Keyboard$2.NUMBER_7:
  					this.fov += 1;
  					break;
  				case Keyboard$2.NUMBER_8:
  					this.fov -= 1;
  					break;
  				case Keyboard$2.I:
  					if (this.lookMode == E_CAMERA_MODE.targetDistance) {
  						this.offset.y += 0.02;
  					}
  					else {
  						this.position.y += 0.02;
  					}
  					break;
  				case Keyboard$2.K:
  					if (this.lookMode == E_CAMERA_MODE.targetDistance) {
  						this.offset.y -= 0.02;
  					}
  					else {
  						this.position.y -= 0.02;
  					}
  					break;
  				case Keyboard$2.J:
  					if (this.lookMode == E_CAMERA_MODE.targetDistance) {
  						this.offset.x -= 0.02;
  					}
  					else {
  						this.position.x -= 0.02;
  					}
  					break;
  				case Keyboard$2.L:
  					if (this.lookMode == E_CAMERA_MODE.targetDistance) {
  						this.offset.x += 0.02;
  					}
  					else {
  						this.position.x += 0.02;
  					}
  					break;
  				case Keyboard$2.U:
  					if (this.lookMode == E_CAMERA_MODE.targetDistance) {
  						this.offset.z -= 0.02;
  					}
  					else {
  						this.position.z -= 0.02;
  					}
  					break;
  				case Keyboard$2.O:
  					if (this.lookMode == E_CAMERA_MODE.targetDistance) {
  						this.offset.z += 0.02;
  					}
  					else {
  						this.position.z += 0.02;
  					}
  					break;
  				case Keyboard$2.UP:
  					this.endRotation.x += 1;
  					break;
  				case Keyboard$2.DOWN:
  					this.endRotation.x -= 1;
  					break;
  				case Keyboard$2.LEFT:
  					this.endRotation.y += 1;
  					break;
  				case Keyboard$2.RIGHT:
  					this.endRotation.y -= 1;
  					break;
  				case Keyboard$2.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}`);
  					console.log(`pos:${this.position.x}:${this.position.y}:${this.position.z}`);
  			}
  	}
  }

  const EFFTYPE = {
  	static: "staticEff_",
  	dynamic: "dynamicEff_",
  	custom: "customEff_",
  };
  class PanelBase3D extends PanelBase {
  	constructor() {
  		super(...arguments);
  		this.needUpdateFrontEffect = [];
  		this.staticEffList = [];
  		this.customEffList = [];
  		this.dynamicEffList = [];
  		this.bFirstCreateScene = true;
  		this._linkModels = {};
  	}
  	onCreate() {
  		let staticNodes = Tools.findAllNodeReg("staticEff_", this.resNode);
  		for (let i = 0; i < staticNodes.length; i++) {
  			const node = staticNodes[i];
  			this.staticEffList.push({
  				node: node,
  				name: node.name.replace("staticEff_", ""),
  			});
  		}
  		for (let i = 0; i < this.staticEffList.length; i++) {
  			const element = this.staticEffList[i];
  			console.warn(`自动添加静态特效:${element.name}`);
  			let name = element.name;
  			let index = name.lastIndexOf("_");
  			if (index >= 0) {
  				name = name.slice(0, index);
  			}
  			this.addEffect(name, element.node);
  		}
  		let customNodes = Tools.findAllNodeReg("customEff_", this.resNode);
  		for (let i = 0; i < customNodes.length; i++) {
  			const node = customNodes[i];
  			this.customEffList.push({
  				node: node,
  				name: node.name.replace("customEff_", ""),
  			});
  		}
  		let dynamicNodes = Tools.findAllNodeReg("dynamicEff_", this.resNode);
  		for (let i = 0; i < dynamicNodes.length; i++) {
  			const node = dynamicNodes[i];
  			this.dynamicEffList.push({
  				node: node,
  				name: node.name.replace("dynamicEff_", ""),
  			});
  		}
  		this.checkEffNameVaild(this.staticEffList, EFFTYPE.static);
  		this.checkEffNameVaild(this.customEffList, EFFTYPE.custom);
  		this.checkEffNameVaild(this.dynamicEffList, EFFTYPE.dynamic);
  		super.onCreate();
  	}
  	checkEffNameVaild(list, type) {
  		let nameMap = {};
  		for (let i = 0; i < list.length; i++) {
  			const element = list[i];
  			if (/[^A-z0-9_]/.test(element.node.name)) {
  				console.error("非法命名", element.node.name);
  				continue;
  			}
  			const LAYOUT_PREFIX = [`LLT_`, `LL_`, `LLB_`, `LRT_`, `LR_`, `LRB_`, `LT_`, `LB_`];
  			for (let i = 0; i < LAYOUT_PREFIX.length; i++) {
  				const prefix = LAYOUT_PREFIX[i];
  				if (element.node.name.startsWith(prefix)) {
  					element.node.name = element.node.name.replace(prefix, "");
  					break;
  				}
  			}
  			if (!element.node.name.startsWith(type)) {
  				console.error("非法命名", element.node.name);
  				continue;
  			}
  			let lastIndex = element.name.lastIndexOf(`_`);
  			let name = element.name.slice(0, lastIndex);
  			if (/[0-9]/.test(name[0])) {
  				name = "_" + name;
  			}
  			if (db.MODEL_DB_ID[name] == null) {
  				console.error("特效表不匹配", name);
  				continue;
  			}
  			if (!nameMap[element.node.name]) {
  				nameMap[element.node.name] = true;
  			}
  			else {
  				console.error("名字重复", element.node.name);
  			}
  		}
  	}
  	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;
  		}
  		if (this.needUpdateFrontEffect) {
  			for (let i = 0; i < this.needUpdateFrontEffect.length; i++) {
  				const element = this.needUpdateFrontEffect[i];
  				Global.poolManager.put(element.model);
  			}
  			this.needUpdateFrontEffect = [];
  		}
  		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.scene3DBack.addChild(this.createLight());
  			if (mgrMaterial.globalShadowConfig.shadowMode != Laya.ShadowMode.None) {
  				if (window[`conch`]) {
  				}
  				else {
  					this.lightBack.shadowMode = mgrMaterial.globalShadowConfig.shadowMode;
  					this.lightBack.shadowDistance = mgrMaterial.globalShadowConfig.shadowDistance;
  					this.lightBack.shadowNearPlane = mgrMaterial.globalShadowConfig.shadowNearPlane;
  					this.lightBack.shadowResolution = mgrMaterial.globalShadowConfig.shadowResolution;
  					this.lightBack.shadowStrength = mgrMaterial.globalShadowConfig.shadowStrength;
  					this.lightBack.shadowDepthBias = mgrMaterial.globalShadowConfig.shadowDepthBias;
  				}
  			}
  			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.2, 0);
  			let rotation = mgrMaterial.lightRotation || new Laya.Vector3(-10, -11, 25);
  			this.lightBack.transform.localRotationEuler = new Laya.Vector3(rotation.x, rotation.y, rotation.z);
  		}
  	}
  	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() {
  		if (this.scene3DEffect)
  			return;
  		this.scene3DEffect = this.createScene3D(1000);
  		var camera = this.scene3DEffect.addChild(new Laya.Camera(0, 0.1, 100));
  		camera.clearFlag = Laya.CameraClearFlags.DepthOnly;
  		camera.orthographic = true;
  		camera.orthographicVerticalSize *= Global.canvasHeight / 1024;
  		this.cameraEffect = camera;
  		this.panelEffects = [];
  		this.needUpdateFrontEffect = [];
  		Timer.callLoop(0.016, () => {
  			let needDeleteIndexs = [];
  			for (let index = this.needUpdateFrontEffect.length - 1; index >= 0; index--) {
  				const element = this.needUpdateFrontEffect[index];
  				if (element.model && !element.model.destroyed && element.model.parent && !element.linkSprite.destroyed && element.linkSprite.visible) {
  					this.update3DEffect(element.model, element.linkSprite, element.scale, element.offsetX, element.offsetY);
  				}
  				else {
  					Global.poolManager.put(element.model);
  					needDeleteIndexs.push(index);
  				}
  			}
  			for (let i = 0; i < needDeleteIndexs.length; i++) {
  				let index = needDeleteIndexs[i];
  				this.needUpdateFrontEffect.splice(index, 1);
  			}
  		}, this);
  	}
  	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();
  		if (this.bFirstCreateScene) {
  			for (let i = 0; i < this.resNode.numChildren; i++) {
  				let child = this.resNode.getChildAt(i);
  				child.displayObject.zOrder = i;
  			}
  			this.bFirstCreateScene = false;
  		}
  		for (let i = 0; i < this.resNode.numChildren; i++) {
  			let child = this.resNode.getChildAt(i);
  			if (child instanceof Laya.Scene3D)
  				continue;
  			if (child.displayObject instanceof Laya.Scene3D)
  				continue;
  			if (child.displayObject.zOrder >= idx) {
  				child.displayObject.zOrder = child.displayObject.zOrder + 1;
  			}
  			else {
  				child.displayObject.zOrder = child.displayObject.zOrder;
  			}
  		}
  		this.resNode.displayObject.addChild(scene);
  		scene.zOrder = idx;
  		return scene;
  	}
  	createLight() {
  		let dlight = new Laya.DirectionLight();
  		dlight.transform.localRotationEuler = new Laya.Vector3(mgrMaterial.lightRotation[0], mgrMaterial.lightRotation[1], mgrMaterial.lightRotation[2]);
  		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(modelId, pos, duration = 0, scale = 1, offsetX = 0, offsetY = 0) {
  		this.createScene3DEffect();
  		let x = 0;
  		let y = 0;
  		let scaleX = scale;
  		let scaleY = scale;
  		let scaleZ = scale;
  		if (pos instanceof fgui.GObject) {
  			let _temp = pos.localToGlobal();
  			x = _temp.x + offsetX;
  			y = _temp.y + offsetY;
  			scaleX = pos.scaleX * scale;
  			scaleY = pos.scaleY * scale;
  		}
  		else if (pos[`pivotX`] != null) {
  			let sprite = pos;
  			let _temp = sprite.localToGlobal(new Laya.Point(sprite.pivotX, sprite.pivotY));
  			x = _temp.x + offsetY;
  			y = _temp.y + offsetY;
  			scaleX = sprite.scaleX * scale;
  			scaleY = sprite.scaleY * scale;
  		}
  		else {
  			x = pos.x;
  			y = pos.y;
  		}
  		let outPos = new Laya.Vector3;
  		this.cameraEffect.convertScreenCoordToOrthographicCoord(new Laya.Vector3(x, y, 0), outPos);
  		let mode = null;
  		if (typeof (modelId) == "string") {
  			mode = Global.poolManager.get(Particle, modelId);
  			mode.resetTrail && mode.resetTrail();
  		}
  		else {
  			mode = modelId;
  		}
  		this.scene3DEffect.addChild(mode);
  		mode.transform.position = outPos;
  		Tools.setWorldLossyScale(mode, scaleX, scaleY, scaleZ);
  		duration > 0 && Timer.callLater(duration, () => {
  			this.unlinkEffect(mode);
  		}, this);
  		if (pos instanceof fgui.GObject || pos[`pivotX`] != null) {
  			this.needUpdateFrontEffect.push({
  				model: mode,
  				linkSprite: pos,
  				scale: scale,
  				offsetX: offsetX,
  				offsetY: offsetY,
  			});
  		}
  		else {
  			this.panelEffects.push(mode);
  		}
  		return mode;
  	}
  	linkEffect(model, linkSprite, offsetX = 0, offsetY = 0) {
  		this.createScene3DEffect();
  		this.scene3DEffect.addChild(model);
  		this.needUpdateFrontEffect.push({
  			model: model,
  			linkSprite: linkSprite,
  			scale: 1,
  			offsetX: offsetX,
  			offsetY: offsetY,
  		});
  	}
  	unlinkEffect(model) {
  		for (let i = this.needUpdateFrontEffect.length - 1; i >= 0; i--) {
  			const element = this.needUpdateFrontEffect[i];
  			if (element.model == model) {
  				this.needUpdateFrontEffect.splice(i, 1);
  				if (element.model instanceof Model) {
  					Global.poolManager.put(element.model);
  				}
  				else {
  					element.model.destroy();
  				}
  				return;
  			}
  		}
  		for (let i = 0; i < this.panelEffects.length; i++) {
  			const element = this.panelEffects[i];
  			if (element == model) {
  				if (element instanceof Model) {
  					Global.poolManager.put(element);
  				}
  				else {
  					element.destroy();
  				}
  				return;
  			}
  		}
  	}
  	hasEffectAtFront(linkSprite) {
  		for (let i = this.needUpdateFrontEffect.length - 1; i >= 0; i--) {
  			const element = this.needUpdateFrontEffect[i];
  			if (element.linkSprite == linkSprite) {
  				return true;
  			}
  		}
  		return false;
  	}
  	removeEffectByOwner(linkSprite) {
  		for (let i = this.needUpdateFrontEffect.length - 1; i >= 0; i--) {
  			const element = this.needUpdateFrontEffect[i];
  			if (element.linkSprite == linkSprite) {
  				this.needUpdateFrontEffect.splice(i, 1);
  				if (element.model instanceof Model) {
  					Global.poolManager.put(element.model);
  				}
  				else {
  					element.model.destroy();
  				}
  				return;
  			}
  		}
  	}
  	update3DEffect(model, pos, scale, offsetX, offsetY) {
  		let x = 0;
  		let y = 0;
  		let scaleX = scale;
  		let scaleY = scale;
  		let scaleZ = scale;
  		let bActive = true;
  		if (pos instanceof fgui.GObject) {
  			let _temp = pos.localToGlobal();
  			x = _temp.x + offsetX;
  			y = _temp.y + offsetY;
  			scaleX = pos.scaleX * scale;
  			scaleY = pos.scaleY * scale;
  			scaleZ = pos.scaleY * scale;
  		}
  		else if (pos[`pivotX`] != null) {
  			let sprite = pos;
  			let _temp = sprite.localToGlobal(new Laya.Point(sprite.pivotX, sprite.pivotY));
  			x = _temp.x + offsetX;
  			y = _temp.y + offsetY;
  			scaleX = sprite.scaleX * scale;
  			scaleY = sprite.scaleY * scale;
  			scaleZ = sprite.scaleY * scale;
  		}
  		else {
  			x = pos.x;
  			y = pos.y;
  		}
  		let outPos = new Laya.Vector3;
  		this.cameraEffect.convertScreenCoordToOrthographicCoord(new Laya.Vector3(x, y, 0), outPos);
  		model.transform.position = outPos;
  		Tools.setWorldLossyScale(model, scaleX, scaleY, scaleZ);
  	}
  	linkModelAtBack(model, root, linkPoint, duration, offsetPos) {
  		if (!model)
  			return null;
  		if (root && (root.destroyed || !root.scene || root.scene != this.scene3DBack))
  			return null;
  		duration = duration || 0;
  		offsetPos = offsetPos || new Laya.Vector3;
  		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);
  		}
  		duration > 0 && Timer.callLater(duration, () => {
  			this.unLinkModelAtBack(realModel);
  		}, realModel);
  		realModel.transform.localPosition = offsetPos;
  		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, bDestory = true) {
  		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 {
  			bDestory && 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 = {};
  	}
  	enableAllRegx(regx, effType = EFFTYPE.custom) {
  		let reg = new RegExp(regx);
  		let list = this.customEffList.concat(this.dynamicEffList);
  		for (let i = 0; i < list.length; i++) {
  			const element = list[i];
  			if (reg.test(element.name)) {
  				this.enableCustomEff(element.name, effType);
  			}
  		}
  	}
  	enableCustomEffByIndex(effName, effType = EFFTYPE.custom, index = 1, scale = 1) {
  		effName += `_${index}`;
  		this.enableCustomEff(effName, effType, scale);
  	}
  	enableCustomEff(effName, effType = EFFTYPE.custom, scale = 1) {
  		if (effType == null)
  			return;
  		for (let i = 0; i < this.needUpdateFrontEffect.length; i++) {
  			const element = this.needUpdateFrontEffect[i];
  			if (element.linkSprite.name == effType + effName) {
  				element.model.active = true;
  				return;
  			}
  		}
  		if (effType == EFFTYPE.custom) {
  			for (let i = 0; i < this.customEffList.length; i++) {
  				const element = this.customEffList[i];
  				if (element.name == effName) {
  					let name = element.name;
  					let index = name.lastIndexOf("_");
  					if (index >= 0) {
  						name = name.slice(0, index);
  					}
  					this.addEffect(name, element.node, 0, scale);
  					return;
  				}
  			}
  		}
  		if (effType == EFFTYPE.dynamic) {
  			for (let i = 0; i < this.dynamicEffList.length; i++) {
  				const element = this.dynamicEffList[i];
  				if (element.name == effName) {
  					let name = element.name;
  					let index = name.lastIndexOf("_");
  					if (index >= 0) {
  						name = name.slice(0, index);
  					}
  					this.addEffect(name, element.node);
  					return;
  				}
  			}
  		}
  		console.error(`特效添加失败: ${effName}`);
  	}
  	disableCustomEff(effName, effType = EFFTYPE.custom) {
  		if (effType == null)
  			return;
  		for (let i = 0; i < this.needUpdateFrontEffect.length; i++) {
  			const element = this.needUpdateFrontEffect[i];
  			if (element.linkSprite.name == effType + effName) {
  				element.model.active = false;
  				return;
  			}
  		}
  	}
  	disableCustomEffByIndex(effName, effType = EFFTYPE.custom, index = 1) {
  		effName += "_" + index;
  		this.disableCustomEff(effName, effType);
  	}
  	playTranslationLoop(node, name) {
  		let trans = node.getTransition(name);
  		if (!trans) {
  			console.error(`没有找到动效: ${name}`);
  			return;
  		}
  		trans.play(null, -1, null, null, null);
  	}
  	stopTranslationLoop(node, name) {
  		let trans = node.getTransition(name);
  		if (!trans) {
  			console.error(`没有找到动效: ${name}`);
  			return;
  		}
  		trans.stop();
  	}
  	playTranslation(node, name, endHookCallback, hookName, hook) {
  		let trans = node.getTransition(name);
  		if (!trans) {
  			console.error(`没有找到动效: ${name}`);
  			return null;
  		}
  		trans.clearHooks();
  		trans.timeScale = 1;
  		trans.play(endHookCallback);
  		if (hook && hookName) {
  			trans.setHook(hookName, hook);
  		}
  		for (let i = 0; i < this.dynamicEffList.length; i++) {
  			const element = this.dynamicEffList[i];
  			let effhookName = element.name;
  			try {
  				trans.setHook(`creEff_${effhookName}`, new Laya.Handler(this, () => {
  					this.enableCustomEff(effhookName, EFFTYPE.dynamic);
  				}));
  			}
  			catch (error) { }
  			try {
  				trans.setHook(`desEff_${effhookName}`, new Laya.Handler(this, () => {
  					this.disableCustomEff(effhookName, EFFTYPE.dynamic);
  				}));
  			}
  			catch (error) { }
  		}
  		return trans;
  	}
  	playTranslationInverse(node, name, endHookCallback, hookName, hook, timeScale = 1) {
  		let trans = node.getTransition(name);
  		if (!trans) {
  			console.error(`没有找到动效: ${name}`);
  			return;
  		}
  		trans.clearHooks();
  		trans.timeScale = timeScale;
  		trans.playReverse(endHookCallback);
  		if (hook && hookName) {
  			trans.setHook(hookName, hook);
  		}
  		for (let i = 0; i < this.dynamicEffList.length; i++) {
  			const element = this.dynamicEffList[i];
  			let effhookName = element.name;
  			try {
  				trans.setHook(`creEff_${effhookName}`, new Laya.Handler(this, () => {
  					this.enableCustomEff(effhookName, EFFTYPE.dynamic);
  				}));
  			}
  			catch (error) { }
  			try {
  				trans.setHook(`desEff_${effhookName}`, new Laya.Handler(this, () => {
  					this.disableCustomEff(effhookName, EFFTYPE.dynamic);
  				}));
  			}
  			catch (error) { }
  		}
  	}
  }

  class PanelWarpWithAnim extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "已废弃";
  		this.panelLayer = 5;
  		this.bOpenAndCloseAnim = false;
  		this.bShowMask = false;
  	}
  	static warp(panelName, context, callback) {
  		Director.openPanelWithSingleton("PanelWarpWithAnim", {
  			willOpenPanel: panelName,
  			willOpenPanelContext: context,
  			bClearOtherPanel: true,
  			callback: callback,
  		});
  	}
  	static open(panelName, context, callback) {
  		Director.openPanelWithSingleton("PanelWarpWithAnim", {
  			willOpenPanel: panelName,
  			willOpenPanelContext: context,
  			bClearOtherPanel: false,
  			callback: callback,
  		});
  	}
  	onLoaded() {
  		this.willOpenPanel = this.context.willOpenPanel;
  		this.willOpenPanelContext = this.context.willOpenPanelContext;
  		this.playLoading(() => {
  			if (this.context.bClearOtherPanel) {
  				Director.openPanelWithClearLayer(this.willOpenPanel, this.willOpenPanelContext, (bSuccess) => {
  					this.playShowing();
  					this.context.callback && this.context.callback();
  				});
  			}
  			else {
  				Director.openPanel(this.willOpenPanel, this.willOpenPanelContext, () => {
  					this.playShowing();
  					this.context.callback && this.context.callback();
  				});
  			}
  		});
  	}
  	dispose() {
  		super.dispose();
  	}
  	playLoading(callback) {
  		callback && callback();
  	}
  	playShowing() {
  		this.close();
  	}
  }
  PanelWarpWithAnim.sourceName = "ui://base/PanelWarpWithAnim";

  class SceneMain extends SceneBase {
  	getTaskManager() {
  		let taskManager = new TaskManager();
  		taskManager.addCall(this.initNative);
  		taskManager.addCall(this.initGameSetting);
  		taskManager.addCall(this.initBaseModule);
  		taskManager.addCall(this.initGameCfg);
  		taskManager.addCall(this.initSdk);
  		taskManager.addCall(this.initManager, 3);
  		taskManager.addCall(this.initBaseRes.bind(this), 5);
  		taskManager.addCall(this.initShader, 3);
  		this.taskManager = taskManager;
  		return taskManager;
  	}
  	initNative(resolve) {
  		SDKBridge.init();
  		mgrSdk.init();
  		Timer.callLoop(0.05, function (timer) {
  			if (mgrNative.isAllowStartGame()) {
  				timer.stop();
  				Global.sendMsg(`MSG_SDK_BASE_CHANNEL_INFO_CHANGED`);
  				mgrSdk.requestBaseChannelInfo();
  				resolve();
  			}
  		}, true);
  	}
  	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);
  		});
  		Laya.stage.on(Laya.Event.MOUSE_WHEEL, this, function (e) {
  			Global.sendMsg(BASE_MSG.SYS_MOUSE_WHEEL, e);
  		});
  		Laya.stage.on(Laya.Event.RIGHT_MOUSE_DOWN, this, function (e) {
  			Global.sendMsg(BASE_MSG.SYS_RIGHT_MOUSE_DOWN, e);
  		});
  		Laya.stage.on(Laya.Event.RIGHT_MOUSE_UP, this, function (e) {
  			Global.sendMsg(BASE_MSG.SYS_RIGHT_MOUSE_UP, e);
  		});
  		resolve();
  	}
  	initGameCfg(resolve) {
  		CfgLoader.init(function (suc) {
  			let questionTitle2Data = {};
  			let dbMapQuestion = db.get_amaze_cloth_crossing_question_db_map();
  			for (let k in dbMapQuestion) {
  				let tmp = dbMapQuestion[k];
  				if (!tmp.imgQuestion || !tmp.imgAnswer1 || !tmp.imgAnswer2 || !tmp.imgAnswer3) {
  					continue;
  				}
  				let existTmpData = questionTitle2Data[tmp.wordQuestion];
  				if (!existTmpData) {
  					questionTitle2Data[tmp.wordQuestion] = tmp;
  				}
  				else {
  					tmp.imgQuestion = existTmpData.imgQuestion;
  					tmp.imgAnswer1 = existTmpData.imgAnswer1;
  					tmp.imgAnswer2 = existTmpData.imgAnswer2;
  					tmp.imgAnswer3 = existTmpData.imgAnswer3;
  					dbMapQuestion[k] = tmp;
  				}
  			}
  			let itemDbMap = db.get_item_db_map();
  			let dbMapLogicRole = db.get_amaze_cloth_crossing_property_to_logic_role_map();
  			for (let k in dbMapLogicRole) {
  				let template = dbMapLogicRole[k];
  				for (let kk in template.questionArr) {
  					let qid = template.questionArr[kk];
  					if (!db.get_amaze_cloth_crossing_question_db(qid)) {
  						console.warn("-----------------get_amaze_cloth_crossing_property_to_logic_role_map表中questionArr中的问题不存在  LogicRoleId/qid=", template.id, qid);
  					}
  				}
  				for (let kk in template.cornerNoAdQuestionArr) {
  					let qid = template.cornerNoAdQuestionArr[kk];
  					if (!db.get_amaze_cloth_crossing_question_db(qid)) {
  						console.warn("-----------------get_amaze_cloth_crossing_property_to_logic_role_map表中cornerNoAdQuestionArr中的问题不存在  LogicRoleId/qid=", template.id, qid);
  					}
  				}
  				for (let kk in template.cornerAdPropertyQuestionArr) {
  					let qid = template.cornerAdPropertyQuestionArr[kk];
  					if (!db.get_amaze_cloth_crossing_question_db(qid)) {
  						console.warn("-----------------get_amaze_cloth_crossing_property_to_logic_role_map表中cornerAdPropertyQuestionArr中的问题不存在  LogicRoleId/qid=", template.id, qid);
  					}
  				}
  				for (let kk in template.cornerAdRetinueQuestionArr) {
  					let qid = template.cornerAdRetinueQuestionArr[kk];
  					if (!db.get_amaze_cloth_crossing_question_db(qid)) {
  						console.warn("-----------------get_amaze_cloth_crossing_property_to_logic_role_map表中cornerAdRetinueQuestionArr中的问题不存在  LogicRoleId/qid=", template.id, qid);
  					}
  				}
  				for (let kk in template.successResultQuestionArr) {
  					let qid = template.successResultQuestionArr[kk];
  					if (!db.get_amaze_cloth_crossing_question_db(qid)) {
  						console.warn("-----------------get_amaze_cloth_crossing_property_to_logic_role_map表中successResultQuestionArr中的问题不存在  LogicRoleId/qid=", template.id, qid);
  					}
  				}
  			}
  			let dbMapStage = db.get_amaze_cloth_crossing_stage_db_map();
  			for (let k in dbMapStage) {
  				let template = dbMapStage[k];
  				for (let kk in template.stagePool1) {
  					let modelName = template.stagePool1[kk];
  					if (!db.get_model_db(modelName)) {
  						console.warn("-----------------get_amaze_cloth_crossing_stage_db表中stagePool1中的modelId不存在  stageId/modelId=", template.id, modelName);
  					}
  				}
  				for (let kk in template.stagePool2) {
  					let modelName = template.stagePool2[kk];
  					if (!db.get_model_db(modelName)) {
  						console.warn("-----------------get_amaze_cloth_crossing_stage_db表中stagePool2中的modelId不存在  stageId/modelId=", template.id, modelName);
  					}
  				}
  				let modelName = template.firstStageModelId1;
  				if (!!modelName && !db.get_model_db(modelName)) {
  					console.warn("-----------------get_amaze_cloth_crossing_stage_db表中stagePool1中的modelId不存在  stageId/firstStageModelId1=", template.id, modelName);
  				}
  				let modelName2 = template.firstStageModelId2;
  				if (modelName2 && !db.get_model_db(modelName2)) {
  					console.warn("-----------------get_amaze_cloth_crossing_stage_db表中stagePool1中的modelId不存在  stageId/firstStageModelId2=", template.id, modelName2);
  				}
  				if (!!template.firstAdCornerQuestionId && !db.get_amaze_cloth_crossing_question_db(template.firstAdCornerQuestionId)) {
  					console.warn("------------------get_amaze_cloth_crossing_stage_db表中firstAdCornerQuestionId问题不存在  LogicRoleId/firstAdCornerQuestionId=", template.id, template.firstAdCornerQuestionId);
  				}
  				if (!!template.firstResultQuestionId && !db.get_amaze_cloth_crossing_question_db(template.firstResultQuestionId)) {
  					console.warn("------------------get_amaze_cloth_crossing_stage_db表中firstResultQuestionId问题不存在  LogicRoleId/firstResultQuestionId=", template.id, template.firstResultQuestionId);
  				}
  				for (let k in template.afterFirstMustGotAdRetinuePetCornerQuestionIdArr) {
  					let qid = template.afterFirstMustGotAdRetinuePetCornerQuestionIdArr[k];
  					if (!db.get_amaze_cloth_crossing_question_db(qid)) {
  						console.warn("------------------get_amaze_cloth_crossing_stage_db表中afterFirstMustGotAdRetinuePetCornerQuestionIdArr的问题不存在  LogicRoleId/firstResultQuestionId=", template.id, qid);
  					}
  				}
  				for (let k in template.afterFirstMustUnlockStageResultQuestionIdArr) {
  					let qid = template.afterFirstMustUnlockStageResultQuestionIdArr[k];
  					if (!db.get_amaze_cloth_crossing_question_db(qid)) {
  						console.warn("------------------get_amaze_cloth_crossing_stage_db表中afterFirstMustUnlockStageResultQuestionIdArr的问题不存在  LogicRoleId/firstResultQuestionId=", template.id, qid);
  					}
  				}
  			}
  			let dbMapRoleBase = db.get_amaze_cloth_crossing_role_db_map();
  			for (let k in dbMapRoleBase) {
  				let template = dbMapRoleBase[k];
  				let modelName = template.modelId;
  				if (!db.get_model_db(modelName)) {
  					console.warn("-----------------get_amaze_cloth_crossing_role_db表中的modelId不存在  roleId/modelId=", template.id, modelName);
  				}
  				for (let kk in template) {
  					let fieldName = kk;
  					if (!fieldName.startsWith("mov")) {
  						continue;
  					}
  					let fieldValue = template[fieldName];
  					if (fieldValue && !db.get_animation_db(fieldValue)) {
  						console.warn("-----------------get_amaze_cloth_crossing_role_db表中的动作不存在  roleId/animationId=", template.id, fieldName, fieldValue);
  					}
  				}
  			}
  			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;
  			});
  			let dbMap = db.get_amaze_cloth_crossing_item_db_map();
  			for (let k in dbMap) {
  				let tmpData = dbMap[k];
  				if (!db.get_model_db(tmpData.modelId)) {
  					console.warn("-----------------amaze_cloth_crossing_item_db表中modelId不存在  itemId/modelId=", tmpData.id, tmpData.modelId);
  				}
  			}
  			let dbMap2 = db.get_amaze_cloth_crossing_question_db_map();
  			for (let k in dbMap2) {
  				let tmpData = dbMap2[k];
  				if (!!tmpData.modelIdDecoAnswer1 && !db.get_model_db(tmpData.modelIdDecoAnswer1)) {
  					console.warn("-----------------amaze_cloth_crossing_question_db表中modelId不存在 qustionId,modelIdDecoAnswer1=", tmpData.id, tmpData.modelIdDecoAnswer1);
  				}
  				if (!!tmpData.modelIdDecoAnswer2 && !db.get_model_db(tmpData.modelIdDecoAnswer2)) {
  					console.warn("-----------------amaze_cloth_crossing_question_db表中modelId不存在 qustionId,modelIdDecoAnswer2=", tmpData.id, tmpData.modelIdDecoAnswer2);
  				}
  				if (!!tmpData.modelIdDecoAnswer3 && !db.get_model_db(tmpData.modelIdDecoAnswer3)) {
  					console.warn("-----------------amaze_cloth_crossing_question_db表中modelId不存在 qustionId,modelIdDecoAnswer3=", tmpData.id, tmpData.modelIdDecoAnswer3);
  				}
  				if (tmpData.resultHelperRoleId) {
  					if (!db.get_amaze_cloth_crossing_role_db(tmpData.resultHelperRoleId)) {
  						console.warn("-----------------amaze_cloth_crossing_question_db表中resultHelperRoleId不存在 qustionId,modelIdDecoAnswer1=", tmpData.id, tmpData.resultHelperRoleId);
  					}
  				}
  				if (tmpData.relationRoleId) {
  					if (!db.get_amaze_cloth_crossing_role_db(tmpData.relationRoleId)) {
  						console.warn("-----------------amaze_cloth_crossing_question_db表中relationRoleId不存在 qustionId,modelIdDecoAnswer1=", tmpData.id, tmpData.relationRoleId);
  					}
  				}
  				if (tmpData.relationRoleId2) {
  					if (!db.get_amaze_cloth_crossing_role_db(tmpData.relationRoleId2)) {
  						console.warn("-----------------amaze_cloth_crossing_question_db表中relationRoleId2不存在 qustionId,modelIdDecoAnswer1=", tmpData.id, tmpData.relationRoleId2);
  					}
  				}
  				if (tmpData.relationRewardRoleId) {
  					if (!db.get_ggg_pet_template_db(tmpData.relationRewardRoleId, 1) && !db.get_ggg_retinue_template_db(tmpData.relationRewardRoleId, 1)) {
  						console.warn("-----------------amaze_cloth_crossing_question_db表中relationRewardRoleId不存在 qustionId,modelIdDecoAnswer1=", tmpData.id, tmpData.relationRewardRoleId);
  					}
  				}
  			}
  			resolve();
  		});
  	}
  	initBaseModule(resolve) {
  		FileRecord.init();
  		GameStatistics.init();
  		GameStatistics.statisOnStageStart(999);
  		resolve();
  	}
  	initSdk(resolve) {
  		mgrAdv.init();
  		mgrSdk.setVersion(CHN_DATA);
  		Timer.callLoop(0.05, function (timer) {
  			if (mgrSdk.isChnResult) {
  				timer.stop();
  				resolve();
  			}
  		}, true);
  	}
  	initBaseRes(resolve) {
  		resolve();
  	}
  	initManager(resolve) {
  		ManagerLoader.onLoad(resolve);
  	}
  	initShader(resolve) {
  		resolve();
  	}
  	onEnter(params) {
  		if (SceneMain._started) {
  			console.error("SceneMain只能启动一次!");
  		}
  		SceneMain._started = true;
  		console.log("enter scene main");
  		ExportViewTool.setDefaultClickSound(101);
  		GameStatistics.statisOnStageEnd(999);
  		if (db.cop_db.b_defaultUnlock == 1) {
  			BaseFacade.mItem.setItem(2, 9999999);
  			BaseFacade.mItem.setItem(4, 10);
  			let dbRole = db.get_amaze_cloth_crossing_property_to_logic_role_map();
  			for (let k in dbRole) {
  				let role = dbRole[k];
  				if (role.maxLevelResultTimeline && role.maxLevelResultTimeline != "") {
  					mgrRole.tryAddArrivedRoleId(role.id);
  				}
  			}
  		}
  		if (!!db.cop_db.custom_max_energy && db.cop_db.custom_max_energy > 0) {
  			if (db.cop_db.custom_max_energy != BaseFacade.mItem.getItemAmount(9)) {
  				BaseFacade.mItem.setItem(9, db.cop_db.custom_max_energy);
  				if (!mgrRole.isBornOnce()) {
  					BaseFacade.mItem.setItem(3, db.cop_db.custom_max_energy);
  				}
  			}
  		}
  		else {
  			let template = db.get_item_db(9);
  			if (template && template.initCount && template.initCount != BaseFacade.mItem.getItemAmount(9)) {
  				BaseFacade.mItem.setItem(9, template.initCount);
  			}
  		}
  		let bPlayedStageFirst = mgrCrossStage.isPlayedStage(1);
  		if (bPlayedStageFirst && !mgrRole.isCompletedGrownupLineSelect()) {
  			let arrivedMaxLevelRoleId = 0;
  			let tmpMaxLevel = 0;
  			let allArrivedRoleIdArr = mgrRole.getAllArrivedRoleIdArr();
  			for (let k in allArrivedRoleIdArr) {
  				let roleId = allArrivedRoleIdArr[k];
  				let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(roleId);
  				if (roleData.grownupLine >= 1 && roleData.grownupLine <= 4) {
  					if (roleData.level > tmpMaxLevel) {
  						arrivedMaxLevelRoleId = roleData.id;
  						tmpMaxLevel = roleData.level;
  					}
  					break;
  				}
  			}
  			if (!arrivedMaxLevelRoleId) {
  				let getGotPropertyExtrnalLevel = mgrRole.getGotPropertyExtrnalLevel();
  				getGotPropertyExtrnalLevel = Math.min(4, getGotPropertyExtrnalLevel);
  				mgrRole.resetGameUserRecord();
  				mgrCrossStage.resetGameUserRecord();
  				mgrRole.setGotPropertyExtrnalLevel(getGotPropertyExtrnalLevel);
  			}
  			else {
  				let currStageId = mgrCrossStage.getCurrStageId();
  				if (!currStageId || currStageId == 1) {
  					mgrCrossStage.finishStage(1);
  				}
  				let usingRoleId = mgrRole.getUsingPlayerRoleId();
  				let roleDataUsing = db.get_amaze_cloth_crossing_property_to_logic_role(usingRoleId);
  				if (roleDataUsing && roleDataUsing.grownupLine >= 1 && roleDataUsing.grownupLine <= 4) {
  					let currentProperty = mgrRole.getPropertyValueByGrownunLine(roleDataUsing.grownupLine);
  					mgrRole.setPropertyValueByGrownunLine(roleDataUsing.grownupLine, currentProperty);
  				}
  				else {
  					let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(arrivedMaxLevelRoleId);
  					let currentProperty = mgrRole.getPropertyValueByGrownunLine(roleData.grownupLine);
  					mgrRole.setPropertyValueByGrownunLine(roleData.grownupLine, currentProperty);
  				}
  				mgrRole.setUsingGrownupLine(roleDataUsing.grownupLine);
  			}
  			mgrRole.markCompletedGrownupLineSelect();
  		}
  		let questionFierceType = db.cop_db.question_fierce_type || 0;
  		if (!!questionFierceType) {
  			let config = {
  				["amaze_cloth_crossing_stage_db"]: ["resultQuestionIdArr", "assignQuestionArr"],
  				["amaze_cloth_crossing_property_to_logic_role"]: ["successResultQuestionArr", "questionArr"]
  			};
  			for (let dbName in config) {
  				let fieldNames = config[dbName];
  				let dbMap = db[`get_${dbName}_map`]();
  				for (let k in dbMap) {
  					let data = dbMap[k];
  					for (let tmp in fieldNames) {
  						let fName = fieldNames[tmp];
  						data[fName] = data[fName + questionFierceType];
  					}
  				}
  			}
  		}
  		Global.registerListeners(this, {
  			MSG_LOADING_PANEL_FINISHED: () => {
  				PanelWarpWithAnim.warp(`PanelGoGoGo`, {
  					bFromLoading: true,
  				});
  			}
  		});
  	}
  	onExit() {
  	}
  }
  SceneMain._started = false;

  class PanelGreyVideoFreeEnergy extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "免费体力灰包";
  		this.bOpenAndCloseAnim = true;
  	}
  	onLoaded() {
  		let item = mgrAdv.getAdvReward(db.ADV_DB_ADVNAME.video_PanelVideoFreeEnergy_energy);
  		this.labelAmount.text = `*${item.amount}`;
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  		this.buttonGiveup.title = "确定";
  		this.adaptAdTextClose();
  		this.adaptAdRange();
  		this.adaptComboGuide();
  		mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelVideoFreeEnergy_energy);
  	}
  	dispose() {
  		super.dispose();
  	}
  	adaptAdTextClose() {
  	}
  	adaptAdRange() {
  	}
  	adaptComboGuide() {
  		let config = mgrAdv.getGreyModelVideoComboGuideInfo("免费领取");
  		this.labelAdComboGuideDesc.text = config.desc;
  		this.imageAdComboChecked.visible = !!config.bDefaultChecked;
  		this.comboGuideInfo = config;
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName != db.ADV_DB_ADVNAME.video_PanelVideoFreeEnergy_energy)
  			return;
  		this.close();
  		let item = mgrAdv.getAdvReward(db.ADV_DB_ADVNAME.video_PanelVideoFreeEnergy_energy);
  		BaseFacade.mItem.addItem(item.itemId, item.amount, "免费体力");
  		mgrTip.addGotItemTip(item.itemId, item.amount);
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  	on_click_buttonTextClose() {
  		this.on_click_buttonClose();
  	}
  	on_click_buttonAdBodyRange() {
  		this.on_click_buttonAd();
  	}
  	on_click_buttonAdFullScreenRange() {
  		this.on_click_buttonAd();
  	}
  	on_click_buttonAd() {
  		// console.info("5555555555555555555555555555555555555");
  		this.close();
  		let item = mgrAdv.getAdvReward(db.ADV_DB_ADVNAME.video_PanelVideoFreeEnergy_energy);
  		BaseFacade.mItem.addItem(item.itemId, item.amount, "免费体力");
  		mgrTip.addGotItemTip(item.itemId, item.amount);
  		mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelVideoFreeEnergy_energy, undefined, true);
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  	on_click_buttonGiveup() {
  		if (!this.comboGuideInfo) {
  			this.on_click_buttonClose();
  			return;
  		}
  		if ((this.comboGuideInfo.bCheckedTriggerAd && this.imageAdComboChecked.visible) || (!this.imageAdComboChecked.visible && !this.comboGuideInfo.bCheckedTriggerAd)) {
  			this.on_click_buttonAd();
  		}
  		else {
  			this.on_click_buttonClose();
  		}
  	}
  	on_click_buttonAdComboGuide() {
  		this.imageAdComboChecked.visible = !this.imageAdComboChecked.visible;
  	}
  }
  PanelGreyVideoFreeEnergy.sourceName = "ui://adv/PanelGreyVideoFreeEnergy";

  class PanelNativeAdv extends PanelBase {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "原生广告";
  		this.panelStyle = 0;
  		this.panelLayer = 3;
  		this.bOpenAndCloseAnim = true;
  		this.state = 0;
  		this.bInited = false;
  	}
  	onLoaded() {
  		// Advertisement.insertAdverV2();
  		console.log("打开原生广告...");
  		let userData = this.context.userData;
  		this.userData = userData;
  		this.advName = userData.advName;
  		this.fillIcon(this.context.nativeData);
  		this.adaptCloseBtn();
  		Global.registerListeners(this, {
  			[BASE_MSG.NATIVE_ADV_LOADED]: this.onMsgNativeAdvLoaded.bind(this),
  			[BASE_MSG.ADV_CLICK_SUC]: this.onMsgAdvClickSuc.bind(this),
  		});
  	}
  	dispose() {
  		super.dispose();
  	}
  	adaptCloseBtn() {
  		if (!!db.cop_db.native_insert_close_size_wh && db.cop_db.native_insert_close_size_wh > 0) {
  			let wh = Tools.clamp(db.cop_db.native_insert_close_size_wh, 25, 80);
  			this.buttonClose.guiNode.setSize(wh, wh);
  		}
  		if (!!db.cop_db.native_insert_close_show_delay_second && db.cop_db.native_insert_close_show_delay_second > 0) {
  			this.buttonClose.setScale(0, 0);
  			cc$1.tween(this.buttonClose)
  				.delay(db.cop_db.native_insert_close_show_delay_second)
  				.toScale(0.1, 1)
  				.start();
  		}
  		if (!!db.cop_db.b_native_insert_close_blur_mode && db.cop_db.b_native_insert_close_blur_mode > 0) {
  			this.buttonClose.alpha = 0.2;
  		}
  	}
  	onMsgNativeAdvLoaded(data) {
  		console.info("9999999999999999999999999999999999999999999999999999");
  		if (data.userData.advName == this.advName) {
  			this.userData = data.userData;
  			this.loadFromData(data.nativeData);
  		}
  	}
  	onMsgAdvClickSuc(data) {
  		console.info("9999999999999999999999999999999999999999999999999999");
  		console.log("--- > msg onMsgAdvClickSuc");
  		if (data.advName == this.advName) {
  			Timer.callLater(0.05, () => {
  				this.close();
  			});
  		}
  	}
  	loadFromData(nativeData) {
  		this.show();
  		this.fillEmpty();
  		this.fillIcon(nativeData);
  	}
  	initClickType() {
  		if (this.bInited)
  			return;
  		this.bInited = true;
  		switch (db.cop_db.native_insert_mode) {
  			case 4:
  				this.buttonPnlSmall.visible = true;
  				this.buttonPnlBig.visible = false;
  				this.buttonPnlScreen.visible = false;
  				break;
  			case 3:
  				this.buttonPnlBig.visible = false;
  				this.buttonPnlSmall.visible = false;
  				this.buttonPnlScreen.visible = true;
  				break;
  			case 2:
  				this.buttonPnlSmall.visible = false;
  				this.buttonPnlBig.visible = true;
  				this.buttonPnlScreen.visible = false;
  				break;
  			case 0:
  			case 1:
  			default:
  				this.buttonPnlBig.visible = false;
  				this.buttonPnlSmall.visible = false;
  				this.buttonPnlScreen.visible = false;
  				break;
  		}
  	}
  	canFillUi() {
  		return !this.isDisposed && this.bInited;
  	}
  	fillIcon(nativeData) {
  		this.initClickType();
  		if (this.state == 1 || !this.canFillUi())
  			return;
  		if (!nativeData) {
  			console.log("PanelNativeAdv nativeData is nil");
  			this.fillEmpty();
  			return;
  		}
  		this.advIcon.visible = true;
  		this.advIcon.url = nativeData.url;
  		this.advTitle.text = nativeData.title || "";
  		this.advDesc.text = nativeData.desc || "";
  		this.state = 1;
  		console.log("PanelNativeAdv fill native icon");
  	}
  	fillEmpty() {
  		this.initClickType();
  		if (this.state == 2 || !this.canFillUi())
  			return;
  		this.advIcon.visible = false;
  		this.advTitle.text = "";
  		this.advDesc.text = "";
  		this.state = 2;
  		console.log("PanelNativeAdv fill native empty");
  	}
  	on_click_buttonPnlBig() {
  		this.on_click_buttonClick();
  	}
  	on_click_buttonPnlSmall() {
  		this.on_click_buttonClick();
  	}
  	on_click_buttonClose() {
  		if (mgrAdv.tryTriggerAdWhenClickNativeInsertClose()) {
  			this.on_click_buttonClick();
  			return;
  		}
  		this.close();
  	}
  	on_click_buttonClick() {
  		if (this.state != 1)
  			return;
  		mgrAdv.onNativeAdvClick(this.advName, this.userData);
  	}
  	on_click_buttonPnlScreen() {
  		this.on_click_buttonClick();
  	}
  }
  PanelNativeAdv.sourceName = "ui://adv/PanelNativeAdv";

  class PanelNativeBanner extends PanelBase {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "原生banner";
  		this.panelStyle = 0;
  		this.panelLayer = 3;
  		this.bShowMask = false;
  		this.bResetRootNode = false;
  	}
  	onLoaded() {
  		console.log("打开原生baner...");
  		this.setXY(UIRoot.canvasCenterX, UIRoot.canvasHeight);
  		this.onClick(this, this.on_click_btnClick);
  		this.fillEmpty();
  		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),
  		});
  	}
  	dispose() {
  		super.dispose();
  	}
  	closePanelOnly() {
  		super.close();
  		mgrAdv.closeNativeAdv(this.advName, false);
  	}
  	close(bManualClose) {
  		super.close();
  		mgrAdv.closeAdv(this.advName);
  		mgrAdv.closeNativeAdv(this.advName, bManualClose);
  	}
  	onMsgNativeAdvLoaded(data) {
  		console.info("9999999999999999999999999999999999999999999999999999999");
  		this.advName = data.userData.advName;
  		this.userData = data.userData;
  		this.loadFromData(data.nativeData);
  	}
  	onMsgAdvClickSuc(data) {
  		console.info("9999999999999999999999999999999999999999999999999999");
  		console.log("--- > msg onMsgAdvClickSuc");
  		if (data.advName == this.advName) {
  			Timer.callLater(0.01, () => {
  				this.close(false);
  			});
  		}
  	}
  	onMsgCloseBanner() {
  		this.closePanelOnly();
  	}
  	loadFromData(nativeData) {
  		this.fillIcon(nativeData);
  	}
  	fillIcon(nativeData) {
  		if (!nativeData) {
  			console.log("PanelNativeBanner nativeData is nil");
  			this.fillEmpty();
  			return;
  		}
  		this.resNode.visible = true;
  		this.advIcon.url = nativeData.url;
  		this.advTitle.text = nativeData.title;
  		this.advDesc.text = nativeData.desc;
  		console.log("PanelNativeBanner fill native icon");
  	}
  	fillEmpty() {
  		this.resNode.visible = false;
  		console.log("PanelNativeBanner fill native empty");
  	}
  	on_click_btnClick() {
  		if (this.resNode.visible == false)
  			return;
  		mgrAdv.onNativeAdvClick(this.advName, this.userData);
  	}
  	on_click_buttonClose() {
  		this.close(true);
  	}
  }
  PanelNativeBanner.sourceName = "ui://adv/PanelNativeBanner";

  class PanelVideoFreeCopperCoin extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "免费铜钱界面";
  	}
  	onLoaded() {
  		mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelVideoFreeCopperCoin_free);
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName != db.ADV_DB_ADVNAME.video_PanelVideoFreeCopperCoin_free)
  			return;
  		let amount = 1000;
  		BaseFacade.mItem.addItem(2, amount, "免费铜钱");
  		mgrTip.addGotItemTip(2, amount);
  		this.close();
  	}
  	on_click_buttonGiveup() {
  		this.close();
  	}
  	on_click_buttonAd() {
  		// console.info("5555555555555555555555555555555555555");
  		let amount = 1000;
  		BaseFacade.mItem.addItem(2, amount, "免费铜钱");
  		mgrTip.addGotItemTip(2, amount);
  		this.close();
  		mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelVideoFreeCopperCoin_free, {}, true);
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  }
  PanelVideoFreeCopperCoin.sourceName = "ui://adv/PanelVideoFreeCopperCoin";

  class PanelVideoFreeEnergy extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "免费体力";
  		this.bOpenAndCloseAnim = true;
  	}
  	onLoaded() {
  		let item = mgrAdv.getAdvReward(db.ADV_DB_ADVNAME.video_PanelVideoFreeEnergy_energy);
  		this.labelAmount.text = `+${item.amount}`;
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  		this.buttonGiveup.title = "放弃";
  		this.adaptAdTextClose();
  		this.adaptAdRange();
  		mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelVideoFreeEnergy_energy);
  	}
  	dispose() {
  		super.dispose();
  	}
  	adaptAdTextClose() {
  	}
  	adaptAdRange() {
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName != db.ADV_DB_ADVNAME.video_PanelVideoFreeEnergy_energy)
  			return;
  		this.close();
  		let item = mgrAdv.getAdvReward(db.ADV_DB_ADVNAME.video_PanelVideoFreeEnergy_energy);
  		BaseFacade.mItem.addItem(item.itemId, item.amount, "免费体力");
  		mgrTip.addGotItemTip(item.itemId, item.amount);
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  	on_click_buttonTextClose() {
  		this.on_click_buttonClose();
  	}
  	on_click_buttonAdBodyRange() {
  		this.on_click_buttonAd();
  	}
  	on_click_buttonAdFullScreenRange() {
  		this.on_click_buttonAd();
  	}
  	on_click_buttonAd() {
  		// console.info("5555555555555555555555555555555555555");
  		this.close();
  		let item = mgrAdv.getAdvReward(db.ADV_DB_ADVNAME.video_PanelVideoFreeEnergy_energy);
  		BaseFacade.mItem.addItem(item.itemId, item.amount, "免费体力");
  		mgrTip.addGotItemTip(item.itemId, item.amount);
  		mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelVideoFreeEnergy_energy, undefined, true);
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  	on_click_buttonGiveup() {
  		this.on_click_buttonTextClose();
  	}
  }
  PanelVideoFreeEnergy.sourceName = "ui://adv/PanelVideoFreeEnergy";

  class CustomCheck1 extends CustomComponent {
  	onCreate() {
  		UiHelper.registerTouchEvent(this, (e) => {
  			if (!e.bClick)
  				return;
  			this.state = !this.state;
  		});
  	}
  	dispose() {
  		super.dispose();
  	}
  	set state(value) {
  		this.imageFg.visible = value;
  		this.onStateChanged && this.onStateChanged();
  	}
  	get state() {
  		return this.imageFg.visible;
  		this.onStateChanged && this.onStateChanged();
  	}
  }
  CustomCheck1.sourceName = "ui://adv/CustomCheck1";

  class CustomCoinTopBar extends CustomComponent {
  	constructor() {
  		super(...arguments);
  		this.amount = 0;
  	}
  	onCreate() {
  		if (mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelVideoFreeEnergy_energy)) {
  			this.button_add_strength.visible = true;
  		}
  		else {
  			this.button_add_strength.visible = false;
  		}
  		Timer.callLoopFrame(1, () => {
  			if (!this.labelAmount || this.labelAmount.isDisposed) {
  				return;
  			}
  			if (!mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelVideoFreeEnergy_energy)) {
  				this.button_add_strength.visible = false;
  			}
  			let curr = BaseFacade.mItem.getItemAmount(3);
  			let max = BaseFacade.mAutoIncreaseItem.getMaxCount(3);
  			this.labelAmount.text = `${curr}/${max}`;
  			this.comRemainTime.visible = (curr < max ? true : false);
  			if (this.comRemainTime.visible) {
  				let time = BaseFacade.mAutoIncreaseItem.getCd(3);
  				this.labelRemainTime.text = `${Tools.formatTime(time)}`;
  			}
  		}, this);
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_button_add_strength() {
  		if (!mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelVideoFreeEnergy_energy)) {
  			return;
  		}
  		Director.openPanel("PanelVideoFreeEnergy");
  	}
  }
  CustomCoinTopBar.sourceName = "ui://base/CustomCoinTopBar";

  class CustomCoinTopBar2 extends CustomComponent {
  	onCreate() {
  		if (mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelVideoFreeCopperCoin_free)) {
  			this.button_add_coins.visible = true;
  		}
  		else {
  			this.button_add_coins.visible = false;
  		}
  		Timer.callLoopFrame(1, () => {
  			if (!this.labelAmount || this.labelAmount.isDisposed) {
  				return;
  			}
  			let curr = Math.floor(BaseFacade.mItem.getItemAmount(2));
  			this.labelAmount.text = `${curr}`;
  		}, this);
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_button_add_coins() {
  		Director.openPanel("PanelVideoFreeCopperCoin");
  	}
  }
  CustomCoinTopBar2.sourceName = "ui://base/CustomCoinTopBar2";

  class CustomCoinTopBar3 extends CustomComponent {
  	onCreate() {
  		this.button_add_coins.visible = false;
  		Timer.callLoopFrame(2, () => {
  			if (!this.labelAmount || this.labelAmount.isDisposed) {
  				return;
  			}
  			let curr = Math.floor(BaseFacade.mItem.getItemAmount(4));
  			this.labelAmount.text = `${curr}`;
  		}, this);
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_button_add_coins() {
  		Director.openPanel("PanelVideoFreeCopperCoin");
  	}
  }
  CustomCoinTopBar3.sourceName = "ui://base/CustomCoinTopBar3";

  class PanelAdRetryDialog extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "广告失败重试界面";
  		this.bOpenAndCloseAnim = true;
  	}
  	onLoaded() {
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_buttonCancle() {
  		this.close();
  		this.context.cancelCallBack && this.context.cancelCallBack();
  	}
  	on_click_buttonSure() {
  		this.close();
  		this.context.sureCallback && this.context.sureCallback();
  	}
  	on_click_buttonClose() {
  	}
  }
  PanelAdRetryDialog.sourceName = "ui://base/PanelAdRetryDialog";

  var E_GUIDE_MASK_TYPE;
  (function (E_GUIDE_MASK_TYPE) {
  	E_GUIDE_MASK_TYPE[E_GUIDE_MASK_TYPE["mask_click"] = 0] = "mask_click";
  	E_GUIDE_MASK_TYPE[E_GUIDE_MASK_TYPE["mask_noclick"] = 1] = "mask_noclick";
  	E_GUIDE_MASK_TYPE[E_GUIDE_MASK_TYPE["nomask_click"] = 2] = "nomask_click";
  	E_GUIDE_MASK_TYPE[E_GUIDE_MASK_TYPE["nomask_noclick"] = 3] = "nomask_noclick";
  })(E_GUIDE_MASK_TYPE || (E_GUIDE_MASK_TYPE = {}));
  class PanelGuide extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "引导界面";
  		this.bShowMask = false;
  		this.MASK_ALPHA_FACTOR = 0.5;
  	}
  	onLoaded() {
  		this.target = this.context.target;
  		this.dragTargets = this.context.dragTargets;
  		this.extraArena = this.context.extraArena;
  		this.content = this.context.content;
  		this.widget = this.context.widget;
  		this.createGuideInfo();
  		this.registerTouch();
  		this.tryShowTip();
  		this.showGuideHand();
  		this.refresh();
  		Timer.callLoop(0.016, () => { this.refresh(); }, this);
  	}
  	close(imm) {
  		cc$1.tween(this.guideContainer)
  			.to(0.15, { alpha: 0 })
  			.call(() => {
  				this.guideContainer.visible = false;
  				super.close(imm);
  			})
  			.start();
  	}
  	dispose() {
  		super.dispose();
  	}
  	createGuideInfo() {
  		let resNodeHitArena = new Laya.HitArea;
  		this.resNode.displayObject.hitArea = resNodeHitArena;
  		resNodeHitArena.unHit.drawRect(0, 0, this.resNode.width, this.resNode.height, `#000000`);
  		let dialogHitArena = new Laya.HitArea;
  		this.comGuideTip.displayObject.hitArea = dialogHitArena;
  		dialogHitArena.unHit.drawRect(0, 0, this.comGuideTip.width, this.comGuideTip.height, `#000000`);
  		let guideContainer = new Laya.Sprite();
  		guideContainer.name = `guideContainer`;
  		this.guideContainer = guideContainer;
  		guideContainer.size(Laya.stage.width, Laya.stage.height);
  		guideContainer.x = this.width / 2 - Laya.stage.width / 2;
  		guideContainer.y = this.height / 2 - Laya.stage.height / 2;
  		let hitArea = new Laya.HitArea();
  		hitArea.hit.drawRect(0, 0, Laya.stage.width, Laya.stage.height, "#000000");
  		guideContainer.hitArea = hitArea;
  		guideContainer.mouseEnabled = true;
  		this.hitArea = hitArea;
  		guideContainer.cacheAs = "bitmap";
  		this.displayObject.addChildAt(guideContainer, 0);
  		let maskArea = new Laya.Sprite();
  		maskArea.alpha = 0;
  		maskArea.graphics.drawRect(0, 0, Laya.stage.width, Laya.stage.height, "#000000");
  		guideContainer.addChild(maskArea);
  		this.guideMask = maskArea;
  		let interactionArea = new Laya.Sprite();
  		interactionArea.size(Laya.stage.width, Laya.stage.height);
  		interactionArea.blendMode = "destination-out";
  		interactionArea.graphics.drawRect(0, 0, Laya.stage.width, Laya.stage.height, "#000000");
  		guideContainer.addChild(interactionArea);
  		this.interactionArea = interactionArea;
  		this.guideContainer.alpha = 0;
  		cc$1.tween(this.guideContainer).to(0.5, { alpha: 1 }).start();
  	}
  	registerTouch() {
  		UiHelper.registerTouchEvent(this.guideContainer, (e) => {
  			if (e.bClick) {
  				mgrGuide.sendGuideMsg(`clickGuideMask`);
  			}
  			if (e.bBegin) {
  				this["_b_drag_to_right"] = true;
  				this["_turn_count"] = 0;
  				this["_b_poped"] = false;
  				this[`_v_start_pos`] = { x: e.stageX, y: e.stageY };
  			}
  			else if (e.bMove && this[`_v_start_pos`]) {
  				let p0 = this[`_v_start_pos`];
  				let p = { x: e.stageX, y: e.stageY };
  				if (this["_b_drag_to_right"]) {
  					if (p.x < p0.x - 20) {
  						this["_b_drag_to_right"] = false;
  						this["_turn_count"]++;
  						console.log("turn left", this["_turn_count"]);
  					}
  				}
  				else {
  					if (p.x > p0.x + 20) {
  						this["_b_drag_to_right"] = true;
  						this["_turn_count"]++;
  						console.log("turn right", this["_turn_count"]);
  					}
  				}
  				if (!this["_b_poped"]) {
  					if (this["_turn_count"] >= 20) {
  						mgrGuide.endGuide();
  						this["_b_poped"] = true;
  					}
  				}
  			}
  		});
  	}
  	tryShowTip() {
  		this.comGuideTip.setScale(0, 0);
  		cc$1.tween(this.comGuideTip).to(0.3, { scaleX: 1, scaleY: 1 }, { easing: cc$1.Ease.backOut }).start();
  		if (this.content) {
  			this.labelContent.text = this.content;
  			this.comGuideTip.visible = true;
  		}
  		else {
  			this.comGuideTip.visible = false;
  		}
  		this.comGuideTip.x = (this.widget.x || 0.5) * this.width;
  		this.comGuideTip.y = (this.widget.y || 0.5) * this.height;
  	}
  	showGuideHand() {
  		if (this.target && this.target.width > 0) {
  			if (!this.dragTargets || this.dragTargets.length == 0) {
  				let guideHhand = new Laya.Sprite;
  				guideHhand.name = `guideHand`;
  				guideHhand.size(1, 1);
  				this.displayObject.addChild(guideHhand);
  				guideHhand.x = 100000;
  				this.addEffect(db.MODEL_DB_ID._116_ui_loop_finger_01, guideHhand);
  				this.skeleton = guideHhand;
  			}
  			else {
  				let guideHhand = new Laya.Sprite;
  				guideHhand.name = `guideHand`;
  				guideHhand.size(1, 1);
  				this.displayObject.addChild(guideHhand);
  				guideHhand.x = 100000;
  				this.addEffect(db.MODEL_DB_ID._116_ui_loop_finger_02, guideHhand);
  				let localPosStart = this.displayObject.globalToLocal(this.target.localToGlobal(new Laya.Point(this.target.width / 2, this.target.height / 2)));
  				guideHhand.pos(localPosStart.x, localPosStart.y);
  				let localPosEnds = [];
  				for (let i = 0; i < this.dragTargets.length; i++) {
  					const dragTarget = this.dragTargets[i];
  					let point = this.displayObject.globalToLocal(dragTarget.localToGlobal(new Laya.Point(dragTarget.width / 2, dragTarget.height / 2)));
  					localPosEnds.push(point);
  				}
  				let __tween = cc$1.tween();
  				for (let i = 0; i < localPosEnds.length; i++) {
  					const pos = localPosEnds[i];
  					__tween = __tween.to(1, { x: pos.x, y: pos.y });
  				}
  				__tween = __tween.to(0.1, { x: localPosStart.x, y: localPosStart.y });
  				cc$1.tween(guideHhand)
  					.repeatForever(__tween)
  					.start();
  			}
  		}
  	}
  	refresh() {
  		if (this.context.maskType == E_GUIDE_MASK_TYPE.nomask_click || this.context.maskType == E_GUIDE_MASK_TYPE.nomask_noclick) {
  			this.MASK_ALPHA_FACTOR = 0;
  			this.guideMask.alpha = this.MASK_ALPHA_FACTOR;
  			this.interactionArea.visible = false;
  		}
  		else {
  			this.guideMask.alpha = this.MASK_ALPHA_FACTOR;
  			this.interactionArea.visible = true;
  		}
  		this.guideMask.visible = !!this.target;
  		if (!this.target || this.target.destroyed)
  			return;
  		if (Math.abs(this.target.scaleX) <= 0.01 || Math.abs(this.target.scaleY) <= 0.01)
  			return;
  		let minX = 0;
  		let minY = 0;
  		let maxX = 0;
  		let maxY = 0;
  		if (this.dragTargets && this.dragTargets.length > 0) {
  			let globalPos = this.target.localToGlobal(new Laya.Point(0, 0));
  			let localPos = this.displayObject.globalToLocal(globalPos);
  			minX = localPos.x;
  			minY = localPos.y;
  			maxX = localPos.x + this.target.width * Math.abs(this.target.scaleX);
  			maxY = localPos.y + this.target.height * Math.abs(this.target.scaleY);
  			for (let i = 0; i < this.dragTargets.length; i++) {
  				const dragTarget = this.dragTargets[i];
  				let globalDragPos = dragTarget.localToGlobal(new Laya.Point(0, 0));
  				let localDragPos = this.displayObject.globalToLocal(globalDragPos);
  				minX = Math.min(minX, localDragPos.x);
  				minY = Math.min(minY, localDragPos.y);
  				maxX = Math.max(maxX, localDragPos.x + dragTarget.width * dragTarget.scaleX);
  				maxY = Math.max(maxY, localDragPos.y + dragTarget.height * dragTarget.scaleY);
  			}
  		}
  		else {
  			let globalPos = this.target.localToGlobal(new Laya.Point(0, 0));
  			let localPos = this.displayObject.globalToLocal(globalPos);
  			minX = localPos.x;
  			if (this.target.scaleX < 0) {
  				minX += this.target.width * this.target.scaleX;
  			}
  			minY = localPos.y;
  			maxX = minX + this.target.width * Math.abs(this.target.scaleX);
  			maxY = minY + this.target.height * Math.abs(this.target.scaleY);
  		}
  		let startX = minX;
  		let startY = minY;
  		let realWidth = maxX - minX;
  		let realHeight = maxY - minY;
  		this.skeleton && this.skeleton.pos(startX + realWidth / 2, startY + realHeight / 2);
  		let gStartPos = this.displayObject.localToGlobal(new Laya.Point(startX, startY));
  		let lStartPos = this.guideContainer.globalToLocal(gStartPos);
  		startX = lStartPos.x;
  		startY = lStartPos.y;
  		let R = 20;
  		let O1 = {
  			x: startX + realWidth - R,
  			y: startY + realHeight - R
  		};
  		let O2 = {
  			x: startX + R,
  			y: startY + realHeight - R,
  		};
  		let O3 = {
  			x: startX + R,
  			y: startY + R,
  		};
  		let O4 = {
  			x: startX + realWidth - R,
  			y: startY + R,
  		};
  		let points = [];
  		for (let i = 0; i <= 10; i++) {
  			let angle = i * 9;
  			let rads = angle / 180 * Math.PI;
  			let x = O1.x + Math.cos(rads) * R;
  			let y = O1.y + Math.sin(rads) * R;
  			points.push(x);
  			points.push(y);
  		}
  		for (let i = 11; i <= 20; i++) {
  			let angle = i * 9;
  			let rads = angle / 180 * Math.PI;
  			let x = O2.x + Math.cos(rads) * R;
  			let y = O2.y + Math.sin(rads) * R;
  			points.push(x);
  			points.push(y);
  		}
  		for (let i = 21; i <= 30; i++) {
  			let angle = i * 9;
  			let rads = angle / 180 * Math.PI;
  			let x = O3.x + Math.cos(rads) * R;
  			let y = O3.y + Math.sin(rads) * R;
  			points.push(x);
  			points.push(y);
  		}
  		for (let i = 31; i <= 40; i++) {
  			let angle = i * 9;
  			let rads = angle / 180 * Math.PI;
  			let x = O4.x + Math.cos(rads) * R;
  			let y = O4.y + Math.sin(rads) * R;
  			points.push(x);
  			points.push(y);
  		}
  		this.interactionArea.graphics.clear();
  		this.interactionArea.graphics.drawPoly(0, 0, points, `#000000`);
  		if (this.context.maskType == E_GUIDE_MASK_TYPE.mask_click || this.context.maskType == E_GUIDE_MASK_TYPE.nomask_click) {
  			this.hitArea.unHit.clear();
  			this.hitArea.unHit.drawRect(lStartPos.x, lStartPos.y, realWidth, realHeight, "#000000");
  		}
  		else {
  		}
  	}
  }
  PanelGuide.sourceName = "ui://base/PanelGuide";

  class PanelItemAmountTip extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "物品消耗提示";
  		this.bOpenAndCloseAnim = false;
  		this.bShowMask = false;
  		this.bMaskClose = false;
  	}
  	onLoaded() {
  		this.itemId = this.context.itemId;
  		this.amount = this.context.amount;
  		let itemData = db.get_item_db(this.itemId);
  		this.loadIcon.url = itemData.icon;
  		this.labelAmount.text = `${this.amount > 0 ? "+" : ""}${this.amount}`;
  		let trans = this.resNode.getTransition("t0");
  		trans.setHook("end", new Laya.Handler(this, () => {
  			this.close();
  		}));
  	}
  	dispose() {
  		super.dispose();
  	}
  }
  PanelItemAmountTip.sourceName = "ui://base/PanelItemAmountTip";

  class PanelNetworkConnectTip extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "网络链接提示";
  		this.bOpenAndCloseAnim = true;
  		this.panelLayer = 6;
  	}
  	onLoaded() {
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_buttonYes() {
  		this.close();
  	}
  }
  PanelNetworkConnectTip.sourceName = "ui://base/PanelNetworkConnectTip";

  class PanelWarpWithoutAnim extends PanelBase {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "切屏无动画";
  		this.panelLayer = 5;
  		this.bOpenAndCloseAnim = false;
  		this.bShowMask = false;
  	}
  	static warp(panelName, context) {
  		Director.openPanel("PanelWarpWithoutAnim", {
  			willOpenPanel: panelName,
  			willOpenPanelContext: context,
  		});
  	}
  	onLoaded() {
  		this.willOpenPanel = this.context.willOpenPanel;
  		this.willOpenPanelContext = this.context.willOpenPanelContext;
  		this.playLoading(() => {
  			Director.openPanelWithClearLayer(this.willOpenPanel, this.willOpenPanelContext, (bSuccess) => {
  				this.playShowing();
  			});
  		});
  	}
  	dispose() {
  		super.dispose();
  	}
  	playLoading(callback) {
  		callback && callback();
  	}
  	playShowing() {
  		this.close();
  	}
  }
  PanelWarpWithoutAnim.sourceName = "ui://base/PanelWarpWithoutAnim";

  class OffScreenRender extends Laya.Sprite3D {
  	constructor() {
  		super();
  		this.quadPool = [];
  		this.usingQuad = [];
  		this.init();
  	}
  	init() {
  		this.camera = new Laya.Camera;
  		this.addChild(this.camera);
  		this.camera.transform.localPositionZ = 1;
  		this.camera.renderingOrder = 2;
  		this.camera.orthographic = true;
  		this.camera.nearPlane = 0.01;
  		this.camera.farPlane = 10000;
  		this.camera.aspectRatio = 1;
  		this.camera.orthographicVerticalSize = 10;
  		this.transform.position = new Laya.Vector3(10);
  		this.setCulling(5);
  		this.oldRender = this.camera.render.bind(this.camera);
  		this.camera.render = () => { };
  		this.enableIncrementDraw();
  	}
  	enableIncrementDraw() {
  		this.camera.clearFlag = Laya.CameraClearFlags.DepthOnly;
  		this.enableAddDraw();
  	}
  	enableRealTimeDraw() {
  		this.camera.clearFlag = Laya.CameraClearFlags.SolidColor;
  		this.camera.clearColor = new Laya.Vector4;
  		this.enableNormalDraw();
  	}
  	setCulling(layer) {
  		this.cullingLayer = layer;
  		this.camera.cullingMask = 0;
  		this.camera.cullingMask = this.camera.cullingMask | Math.pow(2, layer);
  	}
  	enableAddDraw() {
  		this.curRenderMode = NormalMaterial.RENDERMODE_TRANSPARENT_BLEND_ADD;
  	}
  	enableNormalDraw() {
  		this.curRenderMode = NormalMaterial.RENDERMODE_TRANSPARENT;
  	}
  	getQuadFromPool() {
  		if (this.quadPool.length == 0) {
  			if (!this.quadMesh)
  				this.quadMesh = Laya.PrimitiveMesh.createQuad(1, 1);
  			let quad = new Laya.MeshSprite3D(this.quadMesh);
  			quad.layer = this.cullingLayer;
  			return quad;
  		}
  		return this.quadPool.shift();
  	}
  	recoverQuad(quad) {
  		quad.removeSelf();
  		this.recoverMaterial(quad.meshRenderer.sharedMaterial);
  		this.quadPool.push(quad);
  	}
  	getMaterialFromPool(classObj, bNotReuse) {
  		if (!this.materialPool)
  			this.materialPool = {};
  		if (this.materialPool[classObj.name] == null)
  			this.materialPool[classObj.name] = [];
  		if (this.materialPool[classObj.name].length == 0) {
  			let material = new classObj;
  			return material;
  		}
  		if (bNotReuse) {
  			let material = new classObj;
  			return material;
  		}
  		else {
  			let mat = this.materialPool[classObj.name].shift();
  			mat[`_bRecover_`] = false;
  			return mat;
  		}
  	}
  	recoverMaterial(material) {
  		if (material[`_bRecover_`])
  			return;
  		material[`_bRecover_`] = true;
  		let className = material.constructor.name;
  		this.materialPool[className].push(material);
  	}
  	destroy() {
  		for (let i = 0; i < this.quadPool.length; i++) {
  			const element = this.quadPool[i];
  			element.destroy();
  		}
  		super.destroy();
  	}
  	recoverAllUsingQuad() {
  		for (let i = 0; i < this.usingQuad.length; i++) {
  			const element = this.usingQuad[i];
  			this.recoverQuad(element);
  		}
  		this.usingQuad = [];
  	}
  	draw(drawObj, renderTarget) {
  		this.drawSprites([drawObj], renderTarget);
  	}
  	drawSprites(drawObjs, renderTarget, bShareMaterial = false) {
  		this.camera.renderTarget = renderTarget;
  		if (!this.camera.renderTarget)
  			return;
  		let sharedMat = null;
  		if (bShareMaterial) {
  			sharedMat = this.getMaterialFromPool(NormalMaterial);
  		}
  		for (let i = 0; i < drawObjs.length; i++) {
  			const drawObj = drawObjs[i];
  			this.createQuadWithDrawObj(drawObj, sharedMat);
  		}
  		this.oldRender();
  		this.recoverAllUsingQuad();
  	}
  	createQuadWithDrawObj(drawObj, sharedMat) {
  		let quad = this.getQuadFromPool();
  		quad.transform.localPositionZ = drawObj.sprite.zOrder - 1001 || -1;
  		let scaleX = drawObj.sprite.width / this.camera.renderTarget.width * drawObj.sprite.scaleX * this.camera.orthographicVerticalSize;
  		let scaleY = drawObj.sprite.height / this.camera.renderTarget.height * drawObj.sprite.scaleY * this.camera.orthographicVerticalSize;
  		quad.transform.localScaleX = scaleX;
  		quad.transform.localScaleY = scaleY;
  		let posX = (-0.5 + drawObj.offsetX / this.camera.renderTarget.width) * this.camera.orthographicVerticalSize;
  		let posY = (0.5 - drawObj.offsetY / this.camera.renderTarget.height) * this.camera.orthographicVerticalSize;
  		quad.transform.localPositionX = posX;
  		quad.transform.localPositionY = posY;
  		quad.transform.localRotationEulerZ = drawObj.sprite.rotation;
  		quad.transform.localRotationEulerZ = -drawObj.sprite.rotation;
  		if (!drawObj.shaderClass) {
  			let material = sharedMat || this.getMaterialFromPool(NormalMaterial);
  			material.renderMode = this.curRenderMode;
  			material.albedoTexture = drawObj.sprite.texture.bitmap;
  			material.alpha = drawObj.sprite.alpha;
  			quad.meshRenderer.sharedMaterial = material;
  		}
  		else {
  			let material = this.getMaterialFromPool(drawObj.shaderClass, drawObj.shaderParam.bNotReuse);
  			for (const k in drawObj.shaderParam) {
  				let param = drawObj.shaderParam[k];
  				material[k] = param;
  			}
  			material.alpha && (material.alpha = drawObj.sprite.alpha);
  			quad.meshRenderer.sharedMaterial = material;
  		}
  		this.addChild(quad);
  		this.usingQuad.push(quad);
  	}
  }

  class PaintBrush extends Laya.Sprite3D {
  	constructor() {
  		super();
  		this.brushPools = {};
  		this.bInitedBrush = false;
  		this.bRealTimeRender = false;
  		this.drawObjs = [];
  		this.bRecorderPersent = true;
  		this.initPaintContext();
  		this.initPaintBrush();
  		Timer.callLoop(0.032, this.update.bind(this), this);
  	}
  	initPaintContext() {
  		this.offScreenRender = new OffScreenRender;
  		this.addChild(this.offScreenRender);
  	}
  	initPaintBrush() {
  		this.clearBrush = PaintBrush.createClearBrush(2, 2);
  		this.whiteBrush = PaintBrush.createWhiteBrush(2, 2);
  		this.setCurBrushFlowRate(1);
  		let count = 0;
  		this.setbrush(1, "res/paint/paint_brush/brush01.png", 200, 200, () => {
  			count++;
  			if (count == 2)
  				this.bInitedBrush = true;
  		});
  		this.setbrush(2, "res/paint/paint_brush/brush02.png", 100, 100, () => {
  			count++;
  			if (count == 2)
  				this.bInitedBrush = true;
  		});
  	}
  	callIfLoaded(callback, caller) {
  		if (this.bInitedBrush)
  			callback();
  		else {
  			Timer.callLoopFrame(1, (timer) => {
  				if (this.bInitedBrush) {
  					callback();
  					timer.stop();
  				}
  			}, caller);
  		}
  	}
  	destroy() {
  		this.curBrush = null;
  		this.offScreenRender.destroy();
  		super.destroy();
  	}
  	setbrush(key, url, width, height, callback) {
  		if (this.brushPools[key]) {
  			this.curBrush = this.brushPools[key];
  			this.curBrush.width = width || this.curBrush.width;
  			this.curBrush.height = height || this.curBrush.height;
  			callback && callback();
  			return;
  		}
  		ResLoader.loadRes(url, RES_TYPE.IMAGE, (res) => {
  			let sprite = new Laya.Sprite;
  			sprite.width = width || res.width;
  			sprite.height = height || res.height;
  			sprite.texture = res;
  			res.bitmap.lock = true;
  			this.brushPools[key] = sprite;
  			sprite[`url`] = url;
  			sprite[`key`] = key;
  			this.curBrush = sprite;
  			callback && callback();
  		});
  	}
  	setBrushSprite(key, sprite) {
  		sprite[`key`] = key;
  		this.brushPools[key] = sprite;
  		this.curBrush = sprite;
  	}
  	modifyCurBrushSize(width, height) {
  		if (!this.curBrush)
  			return;
  		this.curBrush.width = width;
  		this.curBrush.height = height;
  	}
  	randomRotateBrush() {
  		if (!this.curBrush)
  			return;
  		this.curBrush.rotation = Mathf.random(0, 360);
  	}
  	setCurBrushFlowRate(rate) {
  		rate = Mathf.clamp(rate, 0, 1);
  		this.curFlowRate = rate;
  	}
  	draw(uv, bRandomOffset = false) {
  		if (!this.bInitedBrush)
  			return;
  		if (!this.curBrush)
  			return;
  		if (!this.paintCavas)
  			return;
  		if (this.destroyed)
  			return;
  		if (!this.scene)
  			return;
  		this.curBrush.alpha = this.curFlowRate;
  		let ofx = bRandomOffset ? Math.random() * 4 - 2 : 0;
  		let ofy = bRandomOffset ? Math.random() * 4 - 2 : 0;
  		this.offScreenRender.draw({
  			sprite: this.curBrush,
  			offsetX: uv.x * this.paintCavas.width + ofx,
  			offsetY: uv.y * this.paintCavas.height + ofy,
  		}, this.paintCavas);
  		this.bRecorderPersent && this.paintCavas.updateDrawState(this.curBrush, this.curFlowRate, uv);
  	}
  	drawUvs(uvs) {
  		if (!this.bInitedBrush)
  			return;
  		if (!this.curBrush)
  			return;
  		if (!this.paintCavas)
  			return;
  		if (this.destroyed)
  			return;
  		if (!this.scene)
  			return;
  		this.curBrush.alpha = this.curFlowRate;
  		let offobjs = [];
  		for (let i = 0; i < uvs.length; i++) {
  			const uv = uvs[i];
  			offobjs.push({
  				sprite: this.curBrush,
  				offsetX: uv.x * this.paintCavas.width,
  				offsetY: uv.y * this.paintCavas.height,
  			});
  			this.bRecorderPersent && this.paintCavas.updateDrawState(this.curBrush, this.curFlowRate, uv);
  		}
  		this.offScreenRender.drawSprites(offobjs, this.paintCavas, true);
  	}
  	drawCavas(uv, cavas) {
  		if (!this.paintCavas)
  			return;
  		if (this.destroyed)
  			return;
  		if (!this.scene)
  			return;
  		let sprite = new Laya.Sprite;
  		sprite.size(cavas.width, cavas.height);
  		let drawObj = {
  			sprite: sprite,
  			offsetX: uv.x * this.paintCavas.width,
  			offsetY: uv.y * this.paintCavas.height,
  			shaderClass: NormalMaterial,
  			shaderParam: {
  				renderMode: NormalMaterial.RENDERMODE_TRANSPARENT,
  				albedoTexture: cavas,
  			}
  		};
  		this.offScreenRender.enableRealTimeDraw();
  		this.offScreenRender.draw(drawObj, this.paintCavas);
  		!this.bRealTimeRender && this.offScreenRender.enableIncrementDraw();
  	}
  	drawSetedObjects() {
  		if (!this.paintCavas)
  			return;
  		if (this.destroyed)
  			return;
  		if (!this.scene)
  			return;
  		this.offScreenRender.drawSprites(this.drawObjs, this.paintCavas);
  	}
  	reset(cavas) {
  		this.clearBrush.width = cavas.width;
  		this.clearBrush.height = cavas.height;
  		this.offScreenRender.enableRealTimeDraw();
  		this.offScreenRender.draw({
  			sprite: this.clearBrush,
  			offsetX: cavas.width / 2,
  			offsetY: cavas.height / 2,
  		}, cavas);
  		!this.bRealTimeRender && this.offScreenRender.enableIncrementDraw();
  	}
  	clearTexturePass(cavas, tempCavas, pass) {
  		this.resetWithTexture2d(tempCavas, cavas);
  		this.paintCavas = cavas;
  		let sprite = new Laya.Sprite;
  		sprite.size(cavas.width, cavas.height);
  		let tilling = new Laya.Vector4(1, 1, 0, 0);
  		let drawObj = {
  			sprite: sprite,
  			offsetX: cavas.width / 2,
  			offsetY: cavas.height / 2,
  			shaderClass: PaintMaterial,
  			shaderParam: {
  				pageBase: this.clearBrush.texture.bitmap,
  				paintMask: this.whiteBrush.texture.bitmap,
  				paintTexture: tempCavas,
  				paintTilingOffset: tilling,
  				bBlendR: pass.r == 1,
  				bBlendG: pass.g == 1,
  				bBlendB: pass.b == 1,
  				bBlendA: pass.a == 1,
  			}
  		};
  		this.setDrawObjs([drawObj]);
  		this.drawSetedObjects();
  	}
  	fillTexturePass(cavas, tempCavas, pass) {
  		this.resetWithTexture2d(tempCavas, cavas);
  		this.paintCavas = cavas;
  		let sprite = new Laya.Sprite;
  		sprite.size(cavas.width, cavas.height);
  		let tilling = new Laya.Vector4(1, 1, 0, 0);
  		let drawObj = {
  			sprite: sprite,
  			offsetX: cavas.width / 2,
  			offsetY: cavas.height / 2,
  			shaderClass: PaintMaterial,
  			shaderParam: {
  				pageBase: tempCavas,
  				paintMask: this.whiteBrush.texture.bitmap,
  				paintTexture: this.whiteBrush.texture.bitmap,
  				paintTilingOffset: tilling,
  				bBlendR: pass.r == 1,
  				bBlendG: pass.g == 1,
  				bBlendB: pass.b == 1,
  				bBlendA: pass.a == 1,
  			}
  		};
  		this.setDrawObjs([drawObj]);
  		this.drawSetedObjects();
  	}
  	static reset(cavas, offrender) {
  		let clearBrush = this.createClearBrush(cavas.width, cavas.height);
  		offrender.enableRealTimeDraw();
  		offrender.draw({
  			sprite: clearBrush,
  			offsetX: cavas.width / 2,
  			offsetY: cavas.height / 2,
  		}, cavas);
  	}
  	resetWidthWhite(cavas) {
  		this.whiteBrush.width = cavas.width;
  		this.whiteBrush.height = cavas.height;
  		this.offScreenRender.enableRealTimeDraw();
  		this.offScreenRender.draw({
  			sprite: this.whiteBrush,
  			offsetX: cavas.width / 2,
  			offsetY: cavas.height / 2,
  		}, cavas);
  		!this.bRealTimeRender && this.offScreenRender.enableIncrementDraw();
  	}
  	resetWithTexture2d(cavas, texture) {
  		let sprite = new Laya.Sprite;
  		sprite.texture = new Laya.Texture(texture);
  		sprite.width = cavas.width;
  		sprite.height = cavas.height;
  		this.offScreenRender.enableRealTimeDraw();
  		this.offScreenRender.draw({
  			sprite: sprite,
  			offsetX: cavas.width / 2,
  			offsetY: cavas.height / 2,
  		}, cavas);
  		!this.bRealTimeRender && this.offScreenRender.enableIncrementDraw();
  	}
  	enableRealTimeRender() {
  		this.offScreenRender.enableRealTimeDraw();
  		this.bRealTimeRender = true;
  	}
  	setDrawObjs(drawObjs) {
  		this.drawObjs = drawObjs;
  	}
  	disableRealTimerRender() {
  		this.offScreenRender.enableIncrementDraw();
  		this.bRealTimeRender = false;
  	}
  	update() {
  		if (!this.bRealTimeRender)
  			return;
  		if (!this.paintCavas)
  			return;
  		if (this.destroyed)
  			return;
  		if (!this.scene)
  			return;
  		this.offScreenRender.drawSprites(this.drawObjs, this.paintCavas);
  	}
  	static createPureColorTexture(color) {
  		let pixels = new Uint8Array(16);
  		for (let i = 0; i < 4; i++) {
  			pixels[i * 4 + 0] = color.r * 255;
  			pixels[i * 4 + 1] = color.g * 255;
  			pixels[i * 4 + 2] = color.b * 255;
  			pixels[i * 4 + 3] = color.a * 255;
  		}
  		let tex2d = new Laya.Texture2D(2, 2, Laya.TextureFormat.R8G8B8A8);
  		tex2d.setPixels(pixels);
  		let texture = new Laya.Texture(tex2d);
  		return texture;
  	}
  	static createClearBrush(width, height) {
  		let pixels = new Uint8Array(16);
  		for (let i = 0; i < 4; i++) {
  			pixels[i * 4 + 0] = 0;
  			pixels[i * 4 + 1] = 0;
  			pixels[i * 4 + 2] = 0;
  			pixels[i * 4 + 3] = 0;
  		}
  		let tex2d = new Laya.Texture2D(2, 2, Laya.TextureFormat.R8G8B8A8);
  		tex2d.setPixels(pixels);
  		let texture = new Laya.Texture(tex2d);
  		let sprite = new Laya.Sprite;
  		sprite.size(width, height);
  		sprite.texture = texture;
  		return sprite;
  	}
  	static createWhiteBrush(width, height) {
  		let pixels = new Uint8Array(16);
  		for (let i = 0; i < 4; i++) {
  			pixels[i * 4 + 0] = 255;
  			pixels[i * 4 + 1] = 255;
  			pixels[i * 4 + 2] = 255;
  			pixels[i * 4 + 3] = 255;
  		}
  		let tex2d = new Laya.Texture2D(2, 2, Laya.TextureFormat.R8G8B8A8);
  		tex2d.setPixels(pixels);
  		let texture = new Laya.Texture(tex2d);
  		let sprite = new Laya.Sprite;
  		sprite.size(width, height);
  		sprite.texture = texture;
  		return sprite;
  	}
  	drawWithPaint(cavas, base, mask, paintTexture, tilling, bBlendR, bBlendG, bBlendB, bBlendA, rotation, scale, uv = new Laya.Vector2(0.5, 0.5), blendMask = "r") {
  		this.paintCavas = cavas;
  		let sprite = new Laya.Sprite;
  		sprite.rotation = rotation;
  		sprite.scale(scale, scale);
  		sprite.size(cavas.width, cavas.height);
  		let drawObj = {
  			sprite: sprite,
  			offsetX: cavas.width * uv.x,
  			offsetY: cavas.height * uv.y,
  			shaderClass: PaintMaterial,
  			shaderParam: {
  				pageBase: base,
  				paintMask: mask,
  				paintTexture: paintTexture,
  				paintTilingOffset: tilling,
  				bBlendR: bBlendR,
  				bBlendG: bBlendG,
  				bBlendB: bBlendB,
  				bBlendA: bBlendA,
  				bBlendMaskR: blendMask == "r",
  				bBlendMaskG: blendMask == "g",
  				bBlendMaskB: blendMask == "b",
  				bBlendMaskA: blendMask == "a",
  			}
  		};
  		this.setDrawObjs([drawObj]);
  		this.drawSetedObjects();
  	}
  }

  class PanelWarpWithWhite extends PanelBase {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "切屏白屏";
  		this.panelLayer = 5;
  		this.bShowMask = false;
  	}
  	static warp(panelName, context, callback) {
  		Director.openPanelWithSingleton("PanelWarpWithWhite", {
  			willOpenPanel: panelName,
  			willOpenPanelContext: context,
  			bClearOtherPanel: true,
  			callback: callback,
  		});
  	}
  	static open(panelName, context, callback) {
  		Director.openPanelWithSingleton("PanelWarpWithWhite", {
  			willOpenPanel: panelName,
  			willOpenPanelContext: context,
  			bClearOtherPanel: false,
  			callback: callback,
  		});
  	}
  	onLoaded() {
  		this.willOpenPanel = this.context.willOpenPanel;
  		this.willOpenPanelContext = this.context.willOpenPanelContext;
  		this.playLoading(() => {
  			if (this.context.bClearOtherPanel) {
  				Director.openPanelWithClearLayer(this.willOpenPanel, this.willOpenPanelContext, (bSuccess) => {
  					this.playShowing();
  					this.context.callback && this.context.callback();
  				});
  			}
  			else {
  				Director.openPanel(this.willOpenPanel, this.willOpenPanelContext, () => {
  					this.playShowing();
  					this.context.callback && this.context.callback();
  				});
  			}
  		});
  	}
  	dispose() {
  		super.dispose();
  	}
  	playLoading(callback) {
  		let sprite = new Laya.Sprite;
  		sprite.size(Laya.stage.width, Laya.stage.height);
  		sprite.texture = PaintBrush.createPureColorTexture(new Laya.Color(1, 1, 1, 1));
  		this.displayObject.addChild(sprite);
  		sprite.pivotX = sprite.width / 2;
  		sprite.pivotY = sprite.height / 2;
  		sprite.x = this.displayObject.width / 2;
  		sprite.y = this.displayObject.height / 2;
  		sprite.alpha = 0;
  		cc$1.tween(sprite)
  			.to(0.25, { alpha: 1 })
  			.call(() => {
  				callback && callback();
  			})
  			.start();
  		this.whiteSprite = sprite;
  	}
  	playShowing() {
  		cc$1.tween(this.whiteSprite)
  			.to(0.25, { alpha: 0 })
  			.call(() => {
  				this.close();
  			})
  			.start();
  	}
  }
  PanelWarpWithWhite.sourceName = "ui://base/PanelWarpWithWhite";

  class ViewGuideTip extends ViewBase {
  	onCreate() {
  	}
  	dispose() {
  		super.dispose();
  	}
  }
  ViewGuideTip.sourceName = "ui://base/ViewGuideTip";

  class ViewRedPoint extends ViewBase {
  	onCreate() {
  		UiHelper.playBreathe(this.imageRedPoint);
  	}
  	dispose() {
  		super.dispose();
  	}
  }
  ViewRedPoint.sourceName = "ui://base/ViewRedPoint";

  let max_size = 4;
  let start_y = -150;
  let delta_y = -70;
  let offset_y = -88;
  class ViewTipItem extends ViewBase {
  	constructor() {
  		super();
  		this.m_isDone = true;
  		this.m_text = "";
  		this.m_count = 0;
  		this.create();
  	}
  	static init() {
  		if (!this.centerNode) {
  			this.centerNode = new fgui.GComponent();
  			let layer = Director.getLayer(5);
  			layer.addChild(this.centerNode);
  			this.centerNode.setXY(UIRoot.canvasCenterX, UIRoot.canvasCenterY);
  			Global.registerListeners(this, {
  				[BASE_MSG.UI_SHOW_TIP]: this.onMsgUiShowTip.bind(this),
  			});
  		}
  	}
  	static onMsgUiShowTip(text) {
  		if (!text || text == "") {
  			return;
  		}
  		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;
  		if (this.textLabel.width >= Laya.stage.width) {
  			let scaleFactor = Laya.stage.width / this.textLabel.width;
  			this.textLabel.setScale(scaleFactor, scaleFactor);
  		}
  		else {
  			this.textLabel.setScale(1, 1);
  		}
  	}
  	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 = [];
  ViewTipItem.sourceName = "ui://base/ViewTipItem";

  class CustomGameIconItem extends CustomButton {
  	onCreate() {
  	}
  	dispose() {
  		super.dispose();
  	}
  	setGameInfo(url, rewards, bGeted) {
  		this.loaderIcon.url = url;
  		this.awardCount.text = `*${rewards[0][1]}`;
  		this.imageGeted.visible = bGeted;
  	}
  }
  CustomGameIconItem.sourceName = "ui://channel/CustomGameIconItem";

  class CustomGameIconItem2 extends CustomButton {
  	onCreate() {
  	}
  	dispose() {
  		super.dispose();
  	}
  	fillData(url) {
  		this.loaderIcon.url = url;
  	}
  }
  CustomGameIconItem2.sourceName = "ui://channel/CustomGameIconItem2";

  class CustomMoreGameIcon extends CustomComponent {
  	onCreate() {
  	}
  	dispose() {
  		super.dispose();
  	}
  	fillData(url) {
  		this.loaderIcon.url = url;
  	}
  }
  CustomMoreGameIcon.sourceName = "ui://channel/CustomMoreGameIcon";

  class PanelAddToDesktopDouyin extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "抖音添加到桌面";
  		this.bOpenAndCloseAnim = true;
  	}
  	onLoaded() {
  		this.loaderIcon.url = mgrSdk.findmeImageUrl;
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  }
  PanelAddToDesktopDouyin.sourceName = "ui://channel/PanelAddToDesktopDouyin";

  class PanelFindMeBaidu extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "找到我百度";
  		this.bOpenAndCloseAnim = true;
  	}
  	onLoaded() {
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  }
  PanelFindMeBaidu.sourceName = "ui://channel/PanelFindMeBaidu";

  class PanelFindMeDouyin extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "找到我抖音";
  		this.bOpenAndCloseAnim = true;
  	}
  	onLoaded() {
  		this.loaderIcon.url = mgrSdk.findmeImageUrl;
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  }
  PanelFindMeDouyin.sourceName = "ui://channel/PanelFindMeDouyin";

  class PanelFindMeToutiao extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "找到我头条";
  		this.bOpenAndCloseAnim = true;
  	}
  	onLoaded() {
  		this.loaderIcon1.url = mgrSdk.findmeImageUrl;
  		this.loaderIcon2.url = mgrSdk.findmeImageUrl;
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  }
  PanelFindMeToutiao.sourceName = "ui://channel/PanelFindMeToutiao";

  class PanelFindMeWeixin extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "找到我微信";
  		this.bOpenAndCloseAnim = true;
  	}
  	onLoaded() {
  		this.loaderIcon1.url = mgrSdk.findmeImageUrl;
  		this.loaderIcon2.url = mgrSdk.findmeImageUrl;
  		this.loaderIcon3.url = mgrSdk.findmeImageUrl;
  		this.loaderIcon4.url = mgrSdk.findmeImageUrl;
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  }
  PanelFindMeWeixin.sourceName = "ui://channel/PanelFindMeWeixin";

  class PanelFollowDouyin extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "抖音关注";
  		this.bOpenAndCloseAnim = true;
  	}
  	onLoaded() {
  		if (mgrSdk.followState == 2) {
  			this.buttonSure.title = "关注有礼";
  		}
  		else {
  			this.buttonSure.title = "已关注";
  		}
  		Global.registerListeners(this, {
  			SDK_FOLLOW_OFFICIAL_ACCOUNT_SUC: this.onMsgFollowSuc.bind(this)
  		});
  		if (mgrSdk.followState == 1) {
  			this.getFollowReward();
  		}
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgFollowSuc() {
  		this.close();
  		this.getFollowReward();
  	}
  	getFollowReward() {
  		let config = db.get_douyin_follow_config(1);
  		for (let i = 0; i < config.partIds.length; i++) {
  			const partId = config.partIds[i];
  			if (BaseFacade.mItem.getItemAmount(partId) > 0)
  				continue;
  			BaseFacade.mItem.addItem(partId, 1, "关注有礼");
  			mgrTip.addGotItemTip(partId, 1);
  		}
  	}
  	on_click_buttonSure() {
  		mgrSdk.followOfficialAccount();
  	}
  	on_click_buttonSure1() {
  		this.on_click_buttonSure();
  	}
  }
  PanelFollowDouyin.sourceName = "ui://channel/PanelFollowDouyin";

  class PanelJumpOtherGameDialog extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "互推弹窗";
  		this.bOpenAndCloseAnim = true;
  	}
  	onLoaded() {
  		Global.registerListeners(this, {
  			[BASE_MSG.SDK_OPEN_JUMP_RESULT]: this.onMsgOpenJumpResult.bind(this),
  		});
  		mgrSdk.openJump("single");
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgOpenJumpResult(e) {
  		if (this.destroyed || !this.loaderGame) {
  			return;
  		}
  		if (e.type == "single") {
  			let datas = e.jumpInfo;
  			this.fillData(datas);
  		}
  	}
  	fillData(datas) {
  		this.datas = datas;
  		this.loaderGame.url = datas[0].url;
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  	on_click_buttonJump() {
  		if (!this.datas)
  			return;
  		mgrSdk.jumpOtherGame(this.datas[0].index, "single");
  	}
  }
  PanelJumpOtherGameDialog.sourceName = "ui://channel/PanelJumpOtherGameDialog";

  class PanelMoreGameDialog extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "更多游戏";
  		this.bOpenAndCloseAnim = true;
  		this.JUMP_TYPE = "list";
  	}
  	onLoaded() {
  		this.listGames.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			obj.fillData(this.datas[idx].url);
  		});
  		this.listGames.on(fgui.Events.CLICK_ITEM, this, (obj) => {
  			let idx = obj[`idx`];
  			let gameData = this.datas[idx];
  			mgrSdk.jumpOtherGame(gameData.index, this.JUMP_TYPE);
  		});
  		this.listGames.numItems = 0;
  		Global.registerListeners(this, {
  			[BASE_MSG.SDK_OPEN_JUMP_RESULT]: this.onMsgOpenJumpResult.bind(this),
  		});
  		mgrSdk.openJump(this.JUMP_TYPE);
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgOpenJumpResult(e) {
  		if (e.type == this.JUMP_TYPE) {
  			if (!e || !e.jumpInfo || e.jumpInfo.length == 0) {
  				return;
  			}
  			else {
  			}
  			let datas = e.jumpInfo;
  			this.datas = datas;
  			this.listGames.numItems = this.datas.length;
  			let tween = cc$1.tween();
  			for (let i = 0; i < this.datas.length - 6; i++) {
  				tween.delay(2).call(() => {
  					this.listGames.scrollToView(i, true, true);
  				});
  			}
  			for (let i = this.datas.length - 7; i >= 0; i--) {
  				tween.delay(2).call(() => {
  					this.listGames.scrollToView(i, true, true);
  				});
  			}
  			cc$1.tween(this)
  				.repeatForever(tween)
  				.start();
  		}
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  }
  PanelMoreGameDialog.sourceName = "ui://channel/PanelMoreGameDialog";

  class PanelMoreGameLeft extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "侧边更多游戏";
  		this.JUMP_TYPE = "list";
  	}
  	onLoaded() {
  		this.listGames.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			obj.fillData(this.datas[idx].url);
  		});
  		this.listGames.on(fgui.Events.CLICK_ITEM, this, (obj) => {
  			let idx = obj[`idx`];
  			let gameData = this.datas[idx];
  			mgrSdk.jumpOtherGame(gameData.index, this.JUMP_TYPE);
  		});
  		this.datas = this.context.datas;
  		this.listGames.numItems = this.datas.length;
  		let tween = cc$1.tween();
  		for (let i = 0; i < this.datas.length - 6; i++) {
  			tween.delay(2).call(() => {
  				this.listGames.scrollToView(i, true, true);
  			});
  		}
  		for (let i = this.datas.length - 7; i >= 0; i--) {
  			tween.delay(2).call(() => {
  				this.listGames.scrollToView(i, true, true);
  			});
  		}
  		cc$1.tween(this.listGames)
  			.repeatForever(tween)
  			.start();
  		let x = this.comLeft.x;
  		this.comLeft.x -= 300;
  		cc$1.tween(this.comLeft)
  			.to(0.3, { x: x })
  			.start();
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_buttonClose() {
  		let x = this.comLeft.x - 300;
  		cc$1.tween(this.comLeft)
  			.to(0.3, { x: x })
  			.call(() => {
  				this.close();
  			})
  			.start();
  	}
  }
  PanelMoreGameLeft.sourceName = "ui://channel/PanelMoreGameLeft";

  class PanelShareDialog extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "分享界面";
  		this.bOpenAndCloseAnim = true;
  	}
  	onLoaded() {
  		this.comRewardContainer.visible = false;
  		Global.registerListeners(this, {
  			[BASE_MSG.SDK_SHARE_SUC]: this.onMsgShareSuc.bind(this),
  		});
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgShareSuc(e) {
  		this.close();
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  	on_click_buttonShare() {
  		mgrSdk.share();
  	}
  }
  PanelShareDialog.sourceName = "ui://channel/PanelShareDialog";

  class PanelSmallProgramDouyin extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "抖音小程序";
  		this.bOpenAndCloseAnim = true;
  	}
  	onLoaded() {
  		this.loaderIcon.url = mgrSdk.findmeImageUrl;
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  }
  PanelSmallProgramDouyin.sourceName = "ui://channel/PanelSmallProgramDouyin";

  class PanelTryGame extends PanelBase {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "有奖互推";
  		this.bOpenAndCloseAnim = true;
  		this.JUMP_TYPE = "reward";
  	}
  	onLoaded() {
  		this.listGames.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			obj.setGameInfo(this.datas[idx].url, this.datas[idx].rewards, this.datas[idx].bReceived);
  		});
  		this.listGames.numItems = 0;
  		this.listGames.on(fgui.Events.CLICK_ITEM, this, this.onClickItem.bind(this));
  		mgrSdk.openJump(this.JUMP_TYPE);
  		Global.registerListeners(this, {
  			[BASE_MSG.SDK_OPEN_JUMP_RESULT]: this.onMsgOpenJumpResult.bind(this),
  		});
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgOpenJumpResult(e) {
  		if (e.type == this.JUMP_TYPE) {
  			let datas = e.jumpInfo;
  			this.fillData(datas);
  		}
  	}
  	fillData(datas) {
  		if (this.datas)
  			return;
  		this.datas = datas;
  		this.listGames.numItems = this.datas.length;
  	}
  	onClickItem(obj) {
  		let idx = obj[`idx`];
  		let data = this.datas[idx];
  		mgrSdk.jumpOtherGame(data.index, this.JUMP_TYPE);
  		this.close();
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  }
  PanelTryGame.sourceName = "ui://channel/PanelTryGame";

  class PanelVideoRecordDialog extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "录屏分享";
  		this.bOpenAndCloseAnim = true;
  		this.bClosing = false;
  	}
  	onLoaded() {
  		this.texture2d = this.context.texture2d;
  		if (this.texture2d) {
  			if (typeof (this.texture2d) == "string") {
  				let sp = new Laya.Sprite;
  				sp.width = this.loaderPicture.width;
  				sp.height = this.loaderPicture.height;
  				sp.pivot(sp.width / 2, sp.height / 2);
  				sp.x = sp.width / 2;
  				sp.y = sp.height / 2;
  				this.loaderPicture.displayObject.addChild(sp);
  				sp.loadImage(this.texture2d, new Laya.Handler(this, () => {
  					sp.texture.bitmap.lock = true;
  				}));
  			}
  			else {
  				let texture = new Laya.Texture(this.texture2d, undefined, this.texture2d.width, this.texture2d.height);
  				let sp = new Laya.Sprite;
  				sp.width = this.loaderPicture.width;
  				sp.height = this.loaderPicture.height;
  				this.loaderPicture.displayObject.addChild(sp);
  				sp.graphics.drawImage(texture, 0, 0, sp.width, sp.height);
  			}
  		}
  		this.loaderPicture.scaleY = this.context.tScaleY || 1;
  		let mode = db.cop_db.video_share_mode;
  		if (mode == 0) {
  			this.buttonClose.visible = true;
  		}
  		else {
  			this.buttonClose.visible = false;
  			let delayTime = db.cop_db.video_share_delay_time;
  		}
  		this.comRewardContainer.visible = false;
  		Global.registerListeners(this, {
  			[BASE_MSG.SDK_VIDEO_SHARE_SUC]: this.onMsgSdkVideoShareSuc.bind(this),
  		});
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgSdkVideoShareSuc() {
  		Timer.callLater(0.01, () => {
  			this.close();
  		}, this);
  	}
  	on_click_buttonClose() {
  		if (this.bClosing)
  			return;
  		this.bClosing = true;
  		this.close();
  	}
  	on_click_buttonShare() {
  		mgrSdk.shareVideo();
  	}
  	on_click_buttonTextClose() {
  		this.on_click_buttonClose();
  	}
  }
  PanelVideoRecordDialog.sourceName = "ui://channel/PanelVideoRecordDialog";

  class PanelChestDialog extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "宝箱弹窗";
  		this.bOpenAndCloseAnim = true;
  		this.bOver = false;
  	}
  	onLoaded() {
  		this.progressChest.value = 0;
  		let spine = Spine.create(db.SPINE_DB_ID.ui_lihe);
  		spine.playAnimation("idle1");
  		this.spine = spine;
  		this.nodeSpine.displayObject.addChild(spine);
  	}
  	dispose() {
  		super.dispose();
  	}
  	update() {
  		if (this.progressChest.value > 0 && !this.bOver) {
  			let value = 0.003;
  			this.progressChest.value -= value * 100;
  		}
  	}
  	addProgress() {
  		let value = 0.1;
  		this.progressChest.value += value * 100;
  		if (this.judgeOver()) {
  			this.bOver = true;
  			this.buttonOpen.visible = false;
  			this.addEffect(db.MODEL_DB_ID._130_ui_once_openbox_01, { x: 284, y: 500 }, 1, 1.7);
  			this.close();
  			BaseFacade.mItem.addItem(3, 1, "宝箱得体力");
  			mgrTip.addGotItemTip(3, 1, null, { fOnClose: this.context.fOnClose });
  		}
  	}
  	judgeOver() {
  		let overProgress = Tools.random(85, 100);
  		if (this.progressChest.value >= overProgress) {
  			return true;
  		}
  		return false;
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  	on_click_buttonOpen() {
  		this.buttonClose.visible = false;
  		this.spine.playAnimation("idle2", false);
  		this.addProgress();
  	}
  }
  PanelChestDialog.sourceName = "ui://common_dialog/PanelChestDialog";

  class PanelFreeLevelUpDialog extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "免费升级";
  	}
  	onLoaded() {
  		if (this.context.advId) {
  			mgrAdv.statisVideoShow(this.context.advId);
  		}
  		this.adaptComboGuide(!!this.context.advId);
  	}
  	dispose() {
  		super.dispose();
  	}
  	adaptComboGuide(bValidAd) {
  		let bComboGuide = (!!bValidAd && db.cop_db.b_grey_mode && db.cop_db.b_grey_mode == 1) ? true : false;
  		this.groupAdComboGuide.visible = bComboGuide;
  		if (!bComboGuide) {
  			return;
  		}
  		let config = mgrAdv.getGreyModelVideoComboGuideInfo("视频奖励");
  		this.labelAdComboGuideDesc.text = config.desc;
  		this.imageAdComboChecked.visible = !!config.bDefaultChecked;
  		this.comboGuideInfo = config;
  		this.buttonGiveup.title = config.giveupBtnText || this.buttonGiveup.title;
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  	on_click_buttonGiveup() {
  		if (!this.comboGuideInfo) {
  			this.on_click_buttonClose();
  			return;
  		}
  		if ((this.comboGuideInfo.bCheckedTriggerAd && this.imageAdComboChecked.visible) || (!this.imageAdComboChecked.visible && !this.comboGuideInfo.bCheckedTriggerAd)) {
  			this.on_click_buttonAd();
  		}
  		else {
  			this.on_click_buttonClose();
  		}
  	}
  	on_click_buttonAd() {
  		if (this.context && this.context.advId)
  			console.info("5555555555555555555555555555555555555");
  			mgrAdv.dispatchAdv(this.context.advId, { type: !!this.context.type ? 1 : 0 }, true);
  		this.close();
  	}
  	on_click_buttonAdComboGuide() {
  		this.imageAdComboChecked.visible = !this.imageAdComboChecked.visible;
  	}
  }
  PanelFreeLevelUpDialog.sourceName = "ui://common_dialog/PanelFreeLevelUpDialog";

  class PanelPartGotDialog extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "物品获得";
  		this.recommendDatas = [];
  		this.curCheckMode = 0;
  	}
  	onLoaded() {
  		let deltaY = (Global.canvasHeight - 1024) / 2;
  		if (db.cop_db.ui_bottom_mode_switch[4]) {
  			mgrUiBottom.curInBottomViewName = "PanelPartGotDialog";
  			this.adaptBannerAdv();
  			let originY = this.resNode.y;
  			this.resNode.y = originY + 160 + deltaY;
  			if (mgrUiBottom.checkIfUiBottomRecovery(4)) {
  				let delayTime = db.cop_db.ui_bottom_delay_time[4];
  				Timer.callLater(delayTime, () => {
  					mgrUiBottom.recordUiRecoveryTime();
  					mgrUiBottom.curInBottomViewName = "";
  					this.resNode.y = originY;
  					this.adaptBannerAdv();
  				}, this);
  			}
  		}
  		mgrSound.play(102);
  		this.itemId = this.context.itemId;
  		this.amount = this.context.amount;
  		this.bFragment = false;
  		this.buttonSure.title = "确定";
  		this.fillData();
  		let bTriggerAd = mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelPartGotDialog_extral, true) && !this.context.bFromAd;
  		if (bTriggerAd) {
  			this.buttonSure.visible = false;
  			this.comExtraReward.visible = true;
  			mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelPartGotDialog_extral);
  			let adEventData = db.get_adv_db(db.ADV_DB_ADVNAME.video_PanelPartGotDialog_extral);
  			this.labelExtraReward.text = `${adEventData.rewardAmount}`;
  			this.loaderExtraIcon.url = db.get_item_db(adEventData.rewardItemId).icon;
  		}
  		else {
  			this.buttonSure.visible = true;
  			this.comExtraReward.visible = false;
  		}
  		this.comSureContainer.setScale(0.0001, 0.0001);
  		this.comSureContainer.alpha = 0;
  		this.comSureContainer.visible = true;
  		cc$1.tween(this.comSureContainer).delay(0.2).toScale(0, 1).toAlpha(0.1, 1).start();
  		mgrGuide.registerGuideNode(`PanelPartGotDialog.buttonSure`, this.buttonSure.displayObject);
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  	}
  	dispose() {
  		mgrUiBottom.curInBottomViewName = "";
  		super.dispose();
  	}
  	fadeIn() {
  		this.buttonSure.setScale(0, 0);
  	}
  	randomButton() {
  	}
  	adaptAdTextClose() {
  		let bTriggerAd = this.context.orderOfQueue == 0 && !this.context.bFromAd && mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelPartGotDialog_extral, true);
  		this.bTriggerAd = bTriggerAd;
  		if (!bTriggerAd) {
  			this.buttonSure.visible = true;
  		}
  		else {
  			mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelPartGotDialog_extral);
  			this.buttonSure.visible = false;
  			let advData = db.get_adv_db(db.ADV_DB_ADVNAME.video_PanelPartGotDialog_extral);
  			let advDelay = db.cop_db.video_ad_close_delay || 0;
  			if (advDelay > 0) {
  			}
  			mgrAdv.resetCD(db.ADV_DB_ADVNAME.video_PanelPartGotDialog_extral);
  		}
  	}
  	adaptCheckAd() {
  		let bTriggerAd = this.bTriggerAd;
  		if (!bTriggerAd) {
  		}
  		else {
  			let check_mode = db.cop_db.check_mode;
  			if (check_mode != 0) {
  				check_mode = Mathf.random(1, 4);
  			}
  			this.curCheckMode = check_mode;
  			if (check_mode == 0) {
  			}
  			else if (check_mode == 1) {
  				this.buttonSure.visible = true;
  			}
  			else if (check_mode == 2) {
  				this.buttonSure.visible = true;
  			}
  			else if (check_mode == 3) {
  				this.buttonSure.visible = true;
  			}
  			else if (check_mode == 4) {
  				this.buttonSure.visible = true;
  			}
  		}
  	}
  	adaptAdRange() {
  	}
  	fillData() {
  		let template = db.get_item_db(this.itemId);
  		this.labelName.text = "";
  		this.loaderPartIcon.url = template.icon;
  		this.ctrlItemType = this.comTrans013.getController("itemType");
  		let bgHeight = 0;
  		this.ctrlItemType.setSelectedIndex(0);
  		this.labelNum.text = `+${this.amount}`;
  		this.buttonSure.y += bgHeight;
  		this.comExtraReward.y += bgHeight;
  		this.imageGeted.visible = false;
  		this.playTranslation(this.resNode, "in", new Laya.Handler(this, () => {
  		}));
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName != db.ADV_DB_ADVNAME.video_PanelPartGotDialog_extral)
  			return;
  		this.comExtraReward.visible = false;
  		this.close();
  		let advData = db.get_adv_db(db.ADV_DB_ADVNAME.video_PanelPartGotDialog_extral);
  		let itemId = advData.rewardItemId;
  		let amount = advData.rewardAmount;
  		BaseFacade.mItem.addItem(itemId, amount, "额外奖励");
  		mgrTip.addGotItemTip(itemId, amount, undefined, { bFromAd: true });
  	}
  	on_click_buttonExtraAd() {
  		// console.info("5555555555555555555555555555555555555");
  		this.comExtraReward.visible = false;
  		this.close();
  		let advData = db.get_adv_db(db.ADV_DB_ADVNAME.video_PanelPartGotDialog_extral);
  		let itemId = advData.rewardItemId;
  		let amount = advData.rewardAmount;
  		BaseFacade.mItem.addItem(itemId, amount, "额外奖励");
  		mgrTip.addGotItemTip(itemId, amount, undefined, { bFromAd: true });
  		mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelPartGotDialog_extral, undefined, true);
  	}
  	on_click_buttonSure() {
  		this.close();
  		mgrGuide.sendGuideMsg(`PanelPartGotDialog.clickButtonSure`);
  		return;
  	}
  	on_click_buttonGiveUp() {
  		this.close();
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  }
  PanelPartGotDialog.sourceName = "ui://common_dialog/PanelPartGotDialog";

  class PanelPromptDialog extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "通用二级提示弹窗";
  		this.panelLayer = 2;
  		this.bOpenAndCloseAnim = true;
  	}
  	onLoaded() {
  		let context = this.context;
  		let desc = context.desc || "None";
  		this.labelDesc.text = desc;
  		if (context.title) {
  			this.labelTitile.text = context.title;
  		}
  		if (context.confirmText) {
  			this.buttonSure.guiNode.getChild("title").text = context.confirmText;
  		}
  		if (context.cancelText) {
  			this.buttonCancle.guiNode.getChild("title").text = context.cancelText;
  		}
  		if (!context.cancelText) {
  			this.buttonCancle.visible = false;
  		}
  		if (!context.close) {
  			this.buttonClose.visible = false;
  		}
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_buttonSure() {
  		this.close();
  		if (this.context["confirm"]) {
  			this.context["confirm"]();
  		}
  	}
  	on_click_buttonCancle() {
  		this.close();
  		if (this.context["cancel"]) {
  			this.context["cancel"]();
  		}
  	}
  	on_click_buttonClose() {
  	}
  }
  PanelPromptDialog.sourceName = "ui://common_dialog/PanelPromptDialog";

  class PanelRandomName extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "取名";
  		this.bOpenAndCloseAnim = true;
  	}
  	onLoaded() {
  		this.on_click_buttonRand();
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_buttonRand() {
  	}
  	on_click_buttonOk() {
  		this.close();
  	}
  }
  PanelRandomName.sourceName = "ui://common_dialog/PanelRandomName";

  class PanelRestartDialog extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "人生重开提示";
  	}
  	onLoaded() {
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  	on_click_buttonCancle() {
  		this.close();
  	}
  	on_click_buttonSure() {
  		if (this.context && this.context.fOnSure) {
  			this.context.fOnSure();
  		}
  		this.close();
  	}
  }
  PanelRestartDialog.sourceName = "ui://common_dialog/PanelRestartDialog";

  class PanelUiTipInfoDialog extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "打点展示界面";
  		this.panelLayer = 5;
  		this.bOpenAndCloseAnim = false;
  		this.bShowMask = false;
  		this.openedViewCount = 0;
  		this.closedViewCount = 0;
  		this.triggeredVideoCount = 0;
  		this.itemChangeStatisticsCount = 0;
  		this.EXPORT_VIEW_NAME_DICT = {
  			["PanelWait"]: true
  		};
  	}
  	onLoaded() {
  		Global.registerListeners(this, {
  			["MSG_VIEW_STATISTICS"]: this.onMsgViewStatistics.bind(this),
  			["MSG_AD_EVENT_START"]: this.onMsgAdEventStart.bind(this),
  			["MSG_ITEM_CHANGE_STATISTICS"]: this.onMsgItemChangeStatistics.bind(this)
  		});
  		this.touchable = false;
  		Global.sendMsg("MSG_SHOW_VIEW_BUTTON_INFO");
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgViewStatistics(e) {
  		if (this.EXPORT_VIEW_NAME_DICT[e.viewName]) {
  			return;
  		}
  		if (e.bFocus) {
  			this.openedViewCount++;
  			let arr = [];
  			let str = this.labelViewNameStart.text;
  			if (!!this.labelViewNameStart.text) {
  				arr = this.labelViewNameStart.text.split("\n");
  				if (arr.length > 3) {
  					str = "";
  					for (let i = arr.length - 3 - 1; i < arr.length; i++) {
  						str += arr[i];
  						if (i != (arr.length - 1)) {
  							str += "\n";
  						}
  					}
  				}
  				str += "\n";
  			}
  			let viewIndex = -1;
  			let statisDurationData = db.get_ui_statis_duration_db(e.viewName);
  			if (!!statisDurationData) {
  				viewIndex = statisDurationData.index;
  			}
  			this.labelViewNameStart.text = !!str ? `${str}${this.openedViewCount}-${viewIndex}` : `${this.openedViewCount}-${viewIndex}`;
  			this.showCurrViewPointContent(e.viewName, e.panelName);
  			let jumpData = db.get_ad_banner_int_ui_db(e.viewName);
  			this.labelCurrViewJumpPointEvent.text = `${!!jumpData ? jumpData.index : "无"}`;
  		}
  		else {
  			this.closedViewCount++;
  			let arr = [];
  			let str = this.labelViewNameEnd.text;
  			if (!!this.labelViewNameEnd.text) {
  				arr = this.labelViewNameEnd.text.split("\n");
  				if (arr.length > 3) {
  					str = "";
  					for (let i = arr.length - 3 - 1; i < arr.length; i++) {
  						str += arr[i];
  						if (i != (arr.length - 1)) {
  							str += "\n";
  						}
  					}
  				}
  				str += "\n";
  			}
  			let viewIndex = -1;
  			let statisDurationData = db.get_ui_statis_duration_db(e.viewName);
  			if (!!statisDurationData) {
  				viewIndex = statisDurationData.index;
  			}
  			this.labelViewNameEnd.text = !!str ? `${str}${this.closedViewCount}-${viewIndex}` : `${this.closedViewCount}-${viewIndex}`;
  		}
  	}
  	showCurrViewPointContent(viewName, panelName) {
  		let pointIdStr = "video\n";
  		let dbMap = db.get_adv_db_map();
  		for (let k in dbMap) {
  			let v = dbMap[k];
  			if (v.advName.startsWith("video_") && v.advName.indexOf(`_${viewName}_`) >= 0) {
  				pointIdStr += `${v.tag}\n`;
  			}
  		}
  		dbMap = db.get_adv_banner_int_db_map();
  		pointIdStr += "\nint\n";
  		for (let k in dbMap) {
  			let v = dbMap[k];
  			if (v.advName.startsWith("int_") && v.advName.indexOf(`_${viewName}_`) >= 0) {
  				pointIdStr += `${v.tag}\n`;
  			}
  		}
  		pointIdStr += "\nbanner\n";
  		for (let k in dbMap) {
  			let v = dbMap[k];
  			if (v.advName.startsWith("banner_") && v.advName.indexOf(`_${viewName}_`) >= 0) {
  				pointIdStr += `${v.tag}\n`;
  			}
  		}
  		this.labelCurrViewPoints.text = pointIdStr || "Unknow";
  	}
  	onMsgAdEventStart(e) {
  		if (!e || !e.adEventId) {
  			return;
  		}
  		let adEventId = e.adEventId;
  		let adEventData = db.get_adv_db(adEventId);
  		this.triggeredVideoCount++;
  		let arr = [];
  		let str = this.labelTriggerVideoAd.text;
  		if (!!this.labelTriggerVideoAd.text) {
  			arr = this.labelTriggerVideoAd.text.split("\n");
  			if (arr.length > 3) {
  				str = "";
  				for (let i = arr.length - 3 - 1; i < arr.length; i++) {
  					str += arr[i];
  					if (i != (arr.length - 1)) {
  						str += "\n";
  					}
  				}
  			}
  			str += "\n";
  		}
  		this.labelTriggerVideoAd.text = !!str ? `${str}${this.triggeredVideoCount}-${adEventData.tag || "Unknow"}` : `${this.triggeredVideoCount}-${adEventData.tag || "Unknow"}`;
  	}
  	onMsgItemChangeStatistics(e) {
  		this.itemChangeStatisticsCount++;
  		let arr = [];
  		let str = this.labelCurrItemChangePoints.text;
  		if (!!this.labelCurrItemChangePoints.text) {
  			arr = this.labelCurrItemChangePoints.text.split("\n");
  			if (arr.length > 3) {
  				str = "";
  				for (let i = arr.length - 3 - 1; i < arr.length; i++) {
  					str += arr[i];
  					if (i != (arr.length - 1)) {
  						str += "\n";
  					}
  				}
  			}
  			str += "\n";
  		}
  		this.labelCurrItemChangePoints.text = !!str ? `${str}${this.itemChangeStatisticsCount}-${e.itemId}-${e.index}` : `${this.itemChangeStatisticsCount}-${e.itemId}-${e.index}`;
  	}
  	on_click_buttonClose() {
  	}
  }
  PanelUiTipInfoDialog.sourceName = "ui://common_dialog/PanelUiTipInfoDialog";

  class CustomEditorCheckBox extends CustomComponent {
  	constructor() {
  		super(...arguments);
  		this._bClicked_ = false;
  	}
  	get bClicked() {
  		return this._bClicked_;
  	}
  	onCreate() {
  		UiHelper.registerTouchEvent(this, (e) => {
  			if (e.bClick) {
  				this._bClicked_ = !this._bClicked_;
  				this.refresh();
  			}
  		});
  		this.refresh();
  	}
  	dispose() {
  		super.dispose();
  	}
  	refresh() {
  		this.imageGou.visible = this._bClicked_;
  	}
  }
  CustomEditorCheckBox.sourceName = "ui://debug/CustomEditorCheckBox";

  class CustomEditorColor extends CustomComponent {
  	onCreate() {
  		this.onClick(this, this.onClickColor);
  	}
  	dispose() {
  		super.dispose();
  	}
  	onClickColor() {
  		Director.openPanel("EditorSelectorColor", { onChange: this.onColorChange.bind(this), value: this._value });
  	}
  	onColorChange(color) {
  		this.setValue(color);
  		if (this._callback) {
  			this._callback(color);
  		}
  	}
  	set title(str) {
  		this.titleText.text = str;
  	}
  	init() {
  	}
  	setValue(hexColor) {
  		this._value = hexColor;
  		if (hexColor) {
  			this.colorGraph.drawRect(0, "", hexColor);
  		}
  	}
  	getValue() {
  		return this._value;
  	}
  	onChangeCallback(callback) {
  		this._callback = callback;
  	}
  }
  CustomEditorColor.sourceName = "ui://debug/CustomEditorColor";

  class CustomEditorInput extends CustomComponent {
  	onCreate() {
  	}
  	dispose() {
  		super.dispose();
  	}
  	set title(str) {
  		this.titleText.text = str;
  	}
  	get title() {
  		return this.titleText.text;
  	}
  	init() {
  	}
  	setValue(text) {
  		this.input.text = text;
  		this._value = text;
  	}
  	getValue() {
  		return this._value;
  	}
  	onChangeCallback(callback) {
  		this.input.on(Laya.Event.CHANGE, this, () => {
  			this._value = this.input.text;
  			if (callback)
  				callback(this._value);
  		});
  	}
  }
  CustomEditorInput.sourceName = "ui://debug/CustomEditorInput";

  class CustomEditorOption extends CustomComponent {
  	constructor() {
  		super(...arguments);
  		this._options = [];
  	}
  	onCreate() {
  	}
  	dispose() {
  		super.dispose();
  	}
  	set title(str) {
  		this.titleText.text = str;
  	}
  	init(options) {
  		let tabItems = [];
  		for (let i = 0; i < options.length; i++) {
  			const element = options[i];
  			tabItems.push(element.desc);
  		}
  		this.tab.items = tabItems;
  		this._options = options;
  	}
  	setValue(value) {
  		if (value != null) {
  			this._value = value;
  			for (let i = 0; i < this._options.length; i++) {
  				if (this._options[i].value == value) {
  					this.tab.selectedIndex = i;
  				}
  			}
  		}
  	}
  	getValue() {
  		return this._value;
  	}
  	onChangeCallback(callback) {
  		this.tab.on(fgui.Events.STATE_CHANGED, this, () => {
  			this._value = this._options[this.tab.selectedIndex].value;
  			if (callback) {
  				callback(this._value);
  			}
  		});
  	}
  }
  CustomEditorOption.sourceName = "ui://debug/CustomEditorOption";

  class CustomEditorSlider extends CustomComponent {
  	onCreate() {
  	}
  	dispose() {
  		super.dispose();
  	}
  	set title(str) {
  		this.titleText.text = str;
  	}
  	init(min, max, digits = 2) {
  		this.slider.min = min;
  		this.slider.max = max;
  		this.digits = digits;
  	}
  	setValue(cur) {
  		this.slider.value = cur;
  		this._value = cur;
  	}
  	getValue() {
  		return this._value;
  	}
  	onChangeCallback(callback) {
  		this.slider.on(fgui.Events.STATE_CHANGED, this, () => {
  			let value = Mathf.round(this.slider.value, this.digits);
  			this.setValue(value);
  			if (callback) {
  				callback(value);
  			}
  		});
  	}
  }
  CustomEditorSlider.sourceName = "ui://debug/CustomEditorSlider";

  class CustomEditorTextrue extends CustomComponent {
  	onCreate() {
  		this.onClick(this, this.onClickTextrue);
  	}
  	dispose() {
  		super.dispose();
  	}
  	onClickTextrue() {
  		if (this._options)
  			Director.openPanel("EditorSelectorTexture", { options: this._options, onChange: this.onTextureChange.bind(this) });
  	}
  	onTextureChange(option) {
  		this.setValue(option.value);
  		if (this._callback) {
  			this._callback(option.value);
  		}
  	}
  	set title(str) {
  		this.titleText.text = str;
  	}
  	init(options) {
  		let urls = [];
  		for (let i = 0; i < options.length; i++) {
  			const element = options[i];
  			urls.push(element.value);
  		}
  		this._options = options;
  	}
  	setValue(url) {
  		this._value = url;
  		this.texture.url = url;
  	}
  	getValue() {
  		return this._value;
  	}
  	onChangeCallback(callback) {
  		this._callback = callback;
  	}
  }
  CustomEditorTextrue.sourceName = "ui://debug/CustomEditorTextrue";

  class DebugBase extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.panelLayer = 3;
  		this.panelStyle = 0;
  		this.PANEL_NAME = "";
  	}
  }

  class DebugCrossStagePreview extends DebugBase {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "spine预览";
  		this.stageIds = [];
  		this.aniIds = [];
  	}
  	onLoaded() {
  		let spineDbMap = db.get_amaze_cloth_crossing_stage_db_map();
  		Tools.forEachMap(spineDbMap, (k, v) => {
  			this.stageIds.push(v.id);
  		});
  		this.spineList.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			obj.title = `${this.stageIds[idx]}`;
  		});
  		this.spineList.on(fgui.Events.CLICK_ITEM, this, this.onClickItem.bind(this));
  		this.spineList.numItems = this.stageIds.length;
  	}
  	dispose() {
  		super.dispose();
  	}
  	onClickItem(obj) {
  		if (this.spine) {
  			this.spine.destroy();
  		}
  		let idx = obj[`idx`];
  		let stageId = this.stageIds[idx];
  		Global.sendMsg("MSG_DEBUG_CROSS_STAGE_START", { stageId: stageId });
  		this.close();
  	}
  	on_click_btnClose() {
  		this.close();
  	}
  	on_click_spineList() {
  	}
  	on_click_aniList() {
  	}
  	on_click_buttonTo99() {
  		mgrCrossStage.setCurrStage(99);
  		mgrCrossStage.finishStage(99);
  		mgrTip.showMsgTip("设置成功");
  	}
  	on_click_buttonTo199() {
  		mgrCrossStage.setCurrStage(199);
  		mgrCrossStage.finishStage(199);
  		mgrTip.showMsgTip("设置成功");
  	}
  }
  DebugCrossStagePreview.sourceName = "ui://debug/DebugCrossStagePreview";

  class DebugItem extends DebugBase {
  	constructor() {
  		super(...arguments);
  		this._itemTypes = [
  			{ desc: "货币", value: 1 },
  			{ desc: "物品", value: 2 },
  			{ desc: "掉落", value: 3 }
  		];
  	}
  	onLoaded() {
  		this.itemScroll.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			let itemId = this._allItems[idx];
  			let itemDb = db.get_item_db(itemId);
  			obj.text = `[${itemDb.id}]${itemDb.name}    ${BaseFacade.mItem.getItemAmount(itemDb.id)}`;
  			obj.onClick(this, this.onClickItem, [itemId]);
  		});
  		this.options.title = "物品类型";
  		this.options.init(this._itemTypes);
  		this.options.onChangeCallback(this.onSelectType.bind(this));
  		this.onSelectType(0);
  	}
  	dispose() {
  		super.dispose();
  	}
  	onSelectType(idx) {
  		this._curItemType = idx + 1;
  		let items = [];
  		let allItem = db.get_item_db_map();
  		Tools.forEachMap(allItem, (id, itemDb) => {
  			if (itemDb.type == this._curItemType) {
  				items.push(id);
  			}
  		});
  		this._allItems = items;
  		this.itemScroll.numItems = items.length;
  	}
  	onClickItem(itemId) {
  		this._curSelectItem = itemId;
  		Global.sendMsg(BASE_MSG.UI_SHOW_TIP, `选中[${db.get_item_db(itemId).id}]`);
  	}
  	on_click_btnClose() {
  		this.close();
  	}
  	on_click_btnAdd() {
  		let count = parseInt(this.inputBox.text);
  		if (this._curSelectItem) {
  			if (count) {
  				if (count > 0) {
  					BaseFacade.mItem.addItem(this._curSelectItem, count, "GM");
  				}
  				else {
  					BaseFacade.mItem.subItem(this._curSelectItem, -count, "GM");
  				}
  				Global.sendMsg(BASE_MSG.UI_SHOW_TIP, `改变[${this._curSelectItem}]数量${count}`);
  				this.onSelectType(this._curItemType);
  			}
  			else {
  				Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "物品数量错误.");
  			}
  		}
  		else {
  			Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "先选择一个物品.");
  		}
  	}
  	on_click_itemScroll() {
  	}
  }
  DebugItem.sourceName = "ui://debug/DebugItem";

  class DebugMain extends DebugBase {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "测试入口";
  		this.btnInfos = [
  			{
  				name: "sate面板", callback: () => {
  					Laya.Stat.show();
  				}
  			},
  			{
  				name: "删除存档", callback: () => {
  					this.close();
  					FileRecord.deletAllData(false);
  				}
  			},
  			{
  				name: "记录变体", callback: () => {
  					Director.closeLayer(1);
  					let modelDbMap = db.get_model_db_map();
  					let allModelIds = [];
  					Tools.forEachMap(modelDbMap, (k, v) => {
  						allModelIds.push(v.id);
  					});
  					let _findPs = (node, out) => {
  						for (var i = node.numChildren - 1; i >= 0; i--) {
  							var child = node.getChildAt(i);
  							if (child.particleSystem) {
  								child.particleSystem.playOnAwake = false;
  								out.push(child.particleSystem);
  							}
  							_findPs(child, out);
  						}
  					};
  					let getMaxTime = (model) => {
  						let ps = [];
  						_findPs(model, ps);
  						let maxTime = 0;
  						for (let i = 0; i < ps.length; i++) {
  							let p = ps[i];
  							let deltaTime = Math.max(p.startDelayMin, p.startDelayMax);
  							let totalTime = Math.max(p.startLifetimeConstantMin, p.startLifetimeConstantMax) + deltaTime;
  							if (totalTime > 20) {
  								totalTime = 10;
  							}
  							maxTime = Math.max(maxTime, totalTime);
  						}
  						return maxTime;
  					};
  					let recordAllCompileInfo = () => {
  						if (allModelIds.length > 0) {
  							let modelId = allModelIds.shift();
  							console.error(`ULLog: 开始记录模型: ${modelId}`);
  							try {
  								mgrMaterial.startRecordModelCompileInfo();
  								let model = this.linkModelAtBack(modelId);
  								model.callIfLoaded(() => {
  									Timer.callLater(getMaxTime(model), () => {
  										this.unLinkModelAtBack(model);
  										mgrMaterial.endRecordModelCompileInfo(modelId);
  										recordAllCompileInfo();
  									}, this);
  								}, this);
  							}
  							catch (error) {
  							}
  						}
  						else {
  							console.error("ULLog: 记录变体完成!");
  						}
  					};
  					recordAllCompileInfo();
  				}
  			},
  			{
  				name: "spine预览", callback: () => {
  					this.close();
  					Director.openPanel("DebugSpinePreview");
  				}
  			},
  			{
  				name: "Timeline预览", callback: () => {
  					this.close();
  					Director.openPanel("DebugTimelinePreview");
  				}
  			},
  			{
  				name: "声音测试", callback: () => {
  					this.close();
  					Director.openPanel("DebugSoundIdPreview");
  				}
  			},
  			{
  				name: "声音时长", callback: () => {
  					var data = {};
  					var record = () => {
  						if (!GameRemoteRouter.instance) {
  							Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "未链接存档服务器,尝试重新连接!");
  						}
  						else {
  							GameRemoteRouter.instance.sendMsgToServer({
  								route: "keepInFile",
  								data: {
  									filePath: `res/cfg/soundDuration.json`,
  									data: data,
  								},
  							});
  						}
  					};
  					let soundDb = db.get_sound_db_map();
  					let totalCount = Tools.objLength(soundDb);
  					let curCount = 0;
  					Tools.forEachMap(soundDb, (k, v) => {
  						let url = Laya.URL.formatURL(v.fileName);
  						let audio = new Audio(url);
  						audio.load();
  						audio.oncanplay = () => {
  							data[v.id] = audio.duration;
  							curCount++;
  							if (totalCount == curCount) {
  								record();
  							}
  						};
  					});
  				}
  			},
  			{
  				name: "shader编辑", callback: () => {
  					this.close();
  					Director.openPanel("EditorModelMaterial");
  				}
  			},
  			{
  				name: "动态骨骼1", callback: () => {
  					this.close();
  					PanelWarpWithoutAnim.warp(`EditorDynamicBone`);
  				}
  			},
  			{
  				name: "捏身体", callback: () => {
  					this.close();
  					PanelWarpWithoutAnim.warp(`EditorHumanBone`);
  				}
  			},
  			{
  				name: "添加金币", callback: () => {
  					this.close();
  					BaseFacade.mItem.addItem(1, 88888, `测试`);
  					BaseFacade.mItem.addItem(2, 88888, `测试`);
  					BaseFacade.mItem.setItem(3, 99);
  				}
  			},
  			{
  				name: "获得全部宠物", callback: () => {
  					this.close();
  					let dbMap = db.get_ggg_pet_template_db_map();
  					for (let k in dbMap) {
  						mgrPet.upgradeLevel(parseInt(k));
  					}
  				}
  			},
  			{
  				name: "获得全部侍从", callback: () => {
  					this.close();
  					let dbMap = db.get_ggg_retinue_template_db_map();
  					for (let k in dbMap) {
  						mgrRetinue.upgradeLevel(parseInt(k));
  					}
  				}
  			},
  			{
  				name: "增加金币", callback: () => {
  					this.close();
  					BaseFacade.mItem.addItem(2, 5000, "测试");
  					BaseFacade.mItem.addItem(3, 500, "测试");
  					mgrTip.addGotItemTip(2, 5000, undefined, { bFromAd: false });
  					mgrTip.addGotItemTip(3, 500, undefined, { bFromAd: false });
  				}
  			},
  			{
  				name: "配置检测", callback: () => {
  				}
  			},
  			{
  				name: "提示", callback: () => {
  					mgrTip.showMsgTip("我啊大撒旦发生的地方就爱上了对方开具按时;阿斯蒂芬就;阿斯蒂芬就爱上对方阿斯顿发射点阿斯顿就");
  					this.close();
  				}
  			},
  			{
  				name: "物品消耗测试", callback: () => {
  					mgrTip.addGotItemTip(1, -10);
  					this.close();
  				}
  			},
  			{
  				name: "3d文字", callback: () => {
  					let mesh = Laya.PrimitiveMesh.createQuad(1, 0.3);
  					let quad = new Laya.MeshSprite3D(mesh);
  					quad.transform.localScaleY = -1;
  					this.linkModelAtBack(quad);
  					quad.transform.localPositionY = 0.3;
  					let mat = new Laya.UnlitMaterial;
  					quad.meshRenderer.sharedMaterial = mat;
  					let text = new Laya.Text();
  					Laya.stage.addChild(text);
  					text.fontSize = 24;
  					text.size(100, 30);
  					text.align = "center";
  					text.valign = "middle";
  					text.text = "测试";
  					text.color = "#ff0000";
  					window[`quad`] = quad;
  					let rt = new Laya.RenderTexture2D(100, 30, Laya.RenderTexture2D.FORMAT_R8G8B8A8);
  					Timer.callLoopFrame(1, () => {
  						text.drawToTexture(100, 30, text.x, text.y, rt);
  					}, this);
  					mat.albedoTexture = rt;
  				}
  			},
  			{
  				name: "取名", callback: () => {
  					Director.openPanel(`PanelRandomName`);
  					this.close();
  				}
  			},
  			{
  				name: "测试签到", callback: () => {
  					Director.openPanel(`PanelSignEx`);
  					this.close();
  				}
  			},
  			{
  				name: "设置界面", callback: () => {
  					Director.openPanel(`PanelSetting`);
  					this.close();
  				}
  			},
  			{
  				name: "设置货币为0", callback: () => {
  					BaseFacade.mItem.setItem(2, 1);
  					this.close();
  				}
  			},
  			{
  				name: "部件获得", callback: () => {
  					BaseFacade.mItem.addItem(18005, 1, "测试");
  					mgrTip.addGotItemTip(18005, 1);
  					this.close();
  				}
  			},
  			{
  				name: "金币雨", callback: () => {
  					Director.openPanel(`PanelMoneyTree`);
  				}
  			},
  			{
  				name: "关卡预览", callback: () => {
  					this.close();
  					Director.openPanel("DebugCrossStagePreview");
  				}
  			},
  			{
  				name: "解锁官职", callback: () => {
  					let dbMap = db.get_amaze_cloth_crossing_property_to_logic_role_map();
  					for (let k in dbMap) {
  						let template = dbMap[k];
  						mgrRole.tryAddArrivedRoleId(template.id);
  					}
  					mgrTip.showMsgTip("所有官职已达成");
  				}
  			},
  		];
  	}
  	onLoaded() {
  		GameRemoteRouter.instance;
  		this.showCopInfo();
  		this.listBtn.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			let btnInfo = this.btnInfos[idx];
  			obj.text = btnInfo.name;
  			obj.onClick(this, btnInfo.callback);
  		});
  		this.listBtn.numItems = this.btnInfos.length;
  	}
  	dispose() {
  		super.dispose();
  	}
  	update() {
  		this.fpsText.text = "fps:" + Global.FPS;
  	}
  	showCopInfo() {
  		let textField = this.scrollInfo.getChild("text").asTextField;
  		try {
  			let cop = JSON.parse(mgrSdk.COP_INFO);
  			let str = "";
  			for (const key in cop) {
  				str += `${key}:${cop[key]}\n\n`;
  			}
  			let failedRess = Laya.loader["_failRes"] || {};
  			Tools.forEachMap(failedRess, (url, count) => {
  				str += `失败资源: ${url}\n: ${count}`;
  			});
  			textField.text = str;
  		}
  		catch (err) {
  			textField.text = "COP解析错误:" + Logger.getErrorStr(err);
  		}
  	}
  	on_click_btnClose() {
  		this.close();
  	}
  }
  DebugMain.sourceName = "ui://debug/DebugMain";

  class UVPickerByMesh {
  	static pick(ray, meshSprite3d, bCullingBack = false, meshIdxs) {
  		this.ray.origin = ray.origin.clone();
  		this.ray.direction = ray.direction.clone();
  		ray = this.ray;
  		let mesh = meshSprite3d.meshFilter.sharedMesh;
  		let poss = [];
  		let bNeedTrans = false;
  		if (meshSprite3d instanceof Laya.MeshSprite3D) {
  			bNeedTrans = true;
  			mesh.getPositions(poss);
  			let matrix = meshSprite3d.transform.worldMatrix;
  			let inverseMatrix = new Laya.Matrix4x4;
  			matrix.invert(inverseMatrix);
  			Laya.Vector3.transformCoordinate(ray.origin, inverseMatrix, ray.origin);
  			Laya.Vector3.TransformNormal(ray.direction, inverseMatrix, ray.direction);
  		}
  		else {
  			bNeedTrans = false;
  			this.calcSkinnedMeshVerts(meshSprite3d, meshIdxs);
  			poss = this.getVertsWorldLocationCache(meshSprite3d);
  		}
  		let uvs = [];
  		mesh.getUVs(uvs);
  		let normals = [];
  		mesh.getNormals(normals);
  		let indices = mesh.getIndices();
  		let results = [];
  		for (let i = 0; i < indices.length / 3; i++) {
  			let p1idx = indices[i * 3 + 0];
  			let p2idx = indices[i * 3 + 1];
  			let p3idx = indices[i * 3 + 2];
  			let PA = poss[p1idx];
  			let PB = poss[p2idx];
  			let PC = poss[p3idx];
  			Laya.Vector3.subtract(PA, PB, this.tempVec31);
  			Laya.Vector3.subtract(PA, PC, this.tempVec32);
  			Laya.Vector3.cross(this.tempVec32, this.tempVec31, this.planeNormal);
  			if (bCullingBack && Laya.Vector3.dot(ray.direction, this.planeNormal) > 0)
  				continue;
  			let A = this.planeNormal.x;
  			let B = this.planeNormal.y;
  			let C = this.planeNormal.z;
  			let xp = PA.x;
  			let yp = PA.y;
  			let zp = PA.z;
  			let xl = ray.origin.x;
  			let yl = ray.origin.y;
  			let zl = ray.origin.z;
  			let m = ray.direction.x;
  			let n = ray.direction.y;
  			let p = ray.direction.z;
  			let t = (A * xp - A * xl + B * yp - B * yl + C * zp - C * zl) / (A * m + B * n + C * p);
  			let x = xl + m * t;
  			let y = yl + n * t;
  			let z = zl + p * t;
  			this.crossPointDir.x = x - ray.origin.x;
  			this.crossPointDir.y = y - ray.origin.y;
  			this.crossPointDir.z = z - ray.origin.z;
  			if (Laya.Vector3.dot(ray.direction, this.crossPointDir) <= 0)
  				continue;
  			this.crossPoint.x = x;
  			this.crossPoint.y = y;
  			this.crossPoint.z = z;
  			let P = this.crossPoint;
  			this.soluteWeightByPos123(PA, PB, PC, P, this.tempVec31);
  			let u = this.tempVec31.x;
  			let v = this.tempVec31.y;
  			let w = this.tempVec31.z;
  			if (u == Infinity || v == Infinity || w == Infinity)
  				continue;
  			if (isNaN(u) || isNaN(v) || isNaN(w))
  				continue;
  			if (u < 0 || v < 0 || w < 0)
  				continue;
  			let uvA = uvs[p1idx];
  			let uvB = uvs[p2idx];
  			let uvC = uvs[p3idx];
  			if (bNeedTrans) {
  				Laya.Vector3.transformCoordinate(P, meshSprite3d.transform.worldMatrix, this.outPoint);
  			}
  			else {
  				this.outPoint = P;
  			}
  			results.push({
  				bHit: true,
  				point: this.outPoint.clone(),
  				uv: this.soluteUVByWeight(u, v, w, uvA, uvB, uvC),
  				dis: Laya.Vector3.distance(this.outPoint, ray.origin),
  				normal: this.planeNormal,
  				allResult: [],
  			});
  		}
  		results = results.sort((a, b) => {
  			if (a.dis < b.dis) {
  				return -1;
  			}
  			else if (a.dis == b.dis) {
  				return 0;
  			}
  			else {
  				return 1;
  			}
  		});
  		if (results[0]) {
  			results[0].allResult = results;
  		}
  		return results[0] || { bHit: false, point: null, uv: null, dis: null, normal: null, allResult: null };
  	}
  	static soluteWeightByPos123_ex(orig, dir, v0, v1, v2, rec) {
  		let t = 0;
  		let u = 0;
  		let v = 0;
  		let E1 = this.TEMP_VEC3S[0];
  		Laya.Vector3.subtract(v1, v0, E1);
  		let E2 = this.TEMP_VEC3S[1];
  		Laya.Vector3.subtract(v2, v0, E2);
  		let P = this.TEMP_VEC3S[2];
  		Laya.Vector3.cross(dir, E2, P);
  		let det = Laya.Vector3.dot(E1, P);
  		let T = this.TEMP_VEC3S[3];
  		if (det > 0) {
  			Laya.Vector3.subtract(orig, v0, T);
  		}
  		else {
  			Laya.Vector3.subtract(v0, orig, T);
  			det = -det;
  		}
  		if (det <= 0)
  			return false;
  		u = Laya.Vector3.dot(T, P);
  		if (u < 0 || u > det)
  			return false;
  		let Q = this.TEMP_VEC3S[4];
  		Laya.Vector3.cross(T, E1, Q);
  		v = Laya.Vector3.dot(dir, Q);
  		if (v < 0 || u + v > det)
  			return false;
  		t = Laya.Vector3.dot(E2, Q);
  		if (rec) {
  			let fInvDet = 1 / det;
  			t *= fInvDet;
  			u *= fInvDet;
  			v *= fInvDet;
  			rec.t = t;
  			let pos = dir.clone();
  			Laya.Vector3.scale(pos, t, pos);
  			Laya.Vector3.add(orig, pos, pos);
  			rec.p = pos;
  		}
  		return true;
  	}
  	static soluteWeightByPos123(p1, p2, p3, p, out) {
  		this.solute3eleEquation(p1.x, p2.x, p3.x, p.x, p1.y, p2.y, p3.y, p.y, p1.z, p2.z, p3.z, p.z, out);
  	}
  	static soluteUVByWeight(u, v, w, uv1, uv2, uv3) {
  		let uv = new Laya.Vector2(uv1.x * u + uv2.x * v + uv3.x * w, uv1.y * u + uv2.y * v + uv3.y * w);
  		return uv;
  	}
  	static solute3eleEquation(a11, a12, a13, a14, a21, a22, a23, a24, a31, a32, a33, a34, out) {
  		if (a31 == 0 &&
  			a32 == 0 &&
  			a33 == 0) {
  			a31 = 1;
  			a32 = 1;
  			a33 = 1;
  			a34 = 1;
  		}
  		let d = this.solute3rdOrderDeterminant(a11, a12, a13, a21, a22, a23, a31, a32, a33);
  		let dx = this.solute3rdOrderDeterminant(a14, a12, a13, a24, a22, a23, a34, a32, a33);
  		let dy = this.solute3rdOrderDeterminant(a11, a14, a13, a21, a24, a23, a31, a34, a33);
  		let dz = this.solute3rdOrderDeterminant(a11, a12, a14, a21, a22, a24, a31, a32, a34);
  		out.x = dx / d;
  		out.y = dy / d;
  		out.z = dz / d;
  	}
  	static solute3rdOrderDeterminant(a1, b1, c1, a2, b2, c2, a3, b3, c3) {
  		return a1 * b2 * c3 + a2 * b3 * c1 + a3 * b1 * c2 - a3 * b2 * c1 - a2 * b1 * c3 - a1 * b3 * c2;
  	}
  	static isSameSide(PA, PB, PC, P) {
  		let AP = new Laya.Vector3(P.x - PA.x, P.y - PA.y, P.z - PA.z);
  		let BP = new Laya.Vector3(P.x - PB.x, P.y - PB.y, P.z - PB.z);
  		let AC = new Laya.Vector3(PC.x - PA.x, PC.y - PA.y, PC.z - PA.z);
  		let BC = new Laya.Vector3(PC.x - PB.x, PC.y - PB.y, PC.z - PB.z);
  		let crossABP = new Laya.Vector3;
  		Laya.Vector3.cross(AP, BP, crossABP);
  		let crossABC = new Laya.Vector3;
  		Laya.Vector3.cross(AC, BC, crossABC);
  		if (Laya.Vector3.dot(crossABC, crossABP) <= 0)
  			return false;
  		return true;
  	}
  	static calcSkinnedMeshVerts(meshSprite, meshIdxs, ignoreDeltaTime = false) {
  		var bCalc = ignoreDeltaTime || this._lastWorldPosCalcTime <= Date.now();
  		if (!bCalc)
  			return;
  		function clearMatrix(mat4) {
  			for (var i = 0; i < 16; i++) {
  				mat4.elements[i] = 0;
  			}
  		}
  		function addDataToMatrix(data, offset, weight, out) {
  			for (var i = 0; i < 16; i++) {
  				out.elements[i] += data[offset + i] * weight;
  			}
  		}
  		let each_prop = ["x", "y", "z", "w"];
  		let temp_mat = this._temp_mat4;
  		var boneIndices = this.getBoneIndices(meshSprite);
  		var boneWeights = this.getBoneWeights(meshSprite);
  		var positions = this.getVerts(meshSprite);
  		var worldPosition = this.getVertsWorldLocationCache(meshSprite);
  		function calcBoneMatrix(vertIdx, subData) {
  			clearMatrix(temp_mat);
  			var bIds = boneIndices[vertIdx];
  			var weights = boneWeights[vertIdx];
  			for (var i = 0; i < 4; i++) {
  				var idx = each_prop[i];
  				var boneIdx = bIds[idx];
  				addDataToMatrix(subData, boneIdx * 16, weights[idx], temp_mat);
  			}
  			return temp_mat;
  		}
  		function calcWorldPos(vertIdx, subData) {
  			var vert = positions[vertIdx];
  			var mat = calcBoneMatrix(vertIdx, subData);
  			Laya.Vector3.transformCoordinate(vert, mat, worldPosition[vertIdx]);
  		}
  		let meshCount = meshSprite.meshFilter.sharedMesh.subMeshCount;
  		for (let meshIdx = 0; meshIdx < meshCount; meshIdx++) {
  			if (meshIdxs == null || ~meshIdxs.indexOf(meshIdx)) {
  				var subMesh = meshSprite.meshFilter.sharedMesh.getSubMesh(meshIdx);
  				var subMeshBoneIndices = subMesh["_boneIndicesList"];
  				var subDatas = meshSprite.skinnedMeshRenderer["_skinnedData"][meshIdx];
  				for (var subIdx = 0; subIdx < subMeshBoneIndices.length; subIdx++) {
  					var indices = this.getSkinnedMeshSubMeshSubVertIndices(meshSprite, meshIdx, subIdx);
  					var _subData = subDatas[subIdx];
  					for (var i = 0, n = indices.length; i < n; i++) {
  						var vIdx = indices[i];
  						calcWorldPos(vIdx, _subData);
  					}
  				}
  			}
  		}
  		this._lastWorldPosCalcTime = Date.now() + this.skinnedVertsWorldPosCalcDeltaTime * 1000;
  	}
  	static getSkinnedMeshNearestVertInfo(meshSprite, ray, radius = 0.1, meshIdxs) {
  		let a = ray.origin.clone();
  		let b = ray.direction.clone();
  		Laya.Vector3.add(a, b, b);
  		this.calcSkinnedMeshVerts(meshSprite, meshIdxs);
  		var worldPosition = this.getVertsWorldLocationCache(meshSprite);
  		let meshCount = meshSprite.meshFilter.sharedMesh.subMeshCount;
  		var outPos = new Laya.Vector3();
  		var minPos = new Laya.Vector3(0, 0, 0);
  		var minIdx = -1;
  		for (let meshIdx = 0; meshIdx < meshCount; meshIdx++) {
  			if (meshIdxs == null || ~meshIdxs.indexOf(meshIdx)) {
  				var subMesh = meshSprite.meshFilter.sharedMesh.getSubMesh(meshIdx);
  				var subMeshBoneIndices = subMesh["_boneIndicesList"];
  				for (var subIdx = 0; subIdx < subMeshBoneIndices.length; subIdx++) {
  					var indices = this.getSkinnedMeshSubMeshSubVertIndices(meshSprite, meshIdx, subIdx);
  					for (var i = 0, n = indices.length; i < n; i++) {
  						var vIdx = indices[i];
  						worldPosition[vIdx].cloneTo(outPos);
  						var dis = this.point2line(a, b, outPos);
  						if (dis > radius) {
  							continue;
  						}
  						radius = dis;
  						minIdx = vIdx;
  						outPos.cloneTo(minPos);
  					}
  				}
  			}
  		}
  		if (minIdx < 0) {
  			return null;
  		}
  		else {
  			return {
  				pos: minPos,
  				index: minIdx,
  			};
  		}
  	}
  	static getBoneIndices(model) {
  		if (model["_bone_indices"]) {
  			return model["_bone_indices"];
  		}
  		else {
  			let arr = [];
  			model.meshFilter.sharedMesh.getBoneIndices(arr);
  			model["_bone_indices"] = arr;
  			return arr;
  		}
  	}
  	static getBoneWeights(model) {
  		if (model["_bone_weights"]) {
  			return model["_bone_weights"];
  		}
  		else {
  			let arr = [];
  			model.meshFilter.sharedMesh.getBoneWeights(arr);
  			model["_bone_weights"] = arr;
  			return arr;
  		}
  	}
  	static getVerts(model) {
  		if (model["_vert_key"]) {
  			return model["_vert_key"];
  		}
  		else {
  			let verts = [];
  			model.meshFilter.sharedMesh.getPositions(verts);
  			model["_vert_key"] = verts;
  			return verts;
  		}
  	}
  	static getVertsWorldLocationCache(model) {
  		if (model["_vert_world_key"]) {
  			return model["_vert_world_key"];
  		}
  		else {
  			let verts = [];
  			model.meshFilter.sharedMesh.getPositions(verts);
  			model["_vert_world_key"] = verts;
  			return verts;
  		}
  	}
  	static getSkinnedMeshSubMeshSubVertIndices(meshSprite, meshIdx, subIdx) {
  		var allMeshVert = meshSprite["_all_mesh_vert"];
  		if (!allMeshVert) {
  			allMeshVert = [];
  			meshSprite["_all_mesh_vert"] = allMeshVert;
  		}
  		var allSubMeshVert = allMeshVert[meshIdx];
  		if (!allSubMeshVert) {
  			allSubMeshVert = [];
  			allMeshVert[meshIdx] = allSubMeshVert;
  			let subMesh = meshSprite.meshFilter.sharedMesh.getSubMesh(meshIdx);
  			var subMeshBoneIndices = subMesh["_boneIndicesList"];
  			var subIndexBufferCount = subMesh["_subIndexBufferCount"];
  			var indices = this.getIndicesInSubMesh(meshSprite, meshIdx);
  			for (var _subIdx = 0; _subIdx < subMeshBoneIndices.length; _subIdx++) {
  				var allVertIdxMap = {};
  				var start = _subIdx == 0 ? 0 : end;
  				var end = start + subIndexBufferCount[_subIdx];
  				for (var i = start; i < end; i += 3) {
  					allVertIdxMap[indices[i]] = true;
  					allVertIdxMap[indices[i + 1]] = true;
  					allVertIdxMap[indices[i + 2]] = true;
  				}
  				var allVertIdx = Object.keys(allVertIdxMap);
  				var subList = [];
  				for (var i = allVertIdx.length - 1; i >= 0; i--) {
  					subList.push(parseInt(allVertIdx[i]));
  				}
  				allSubMeshVert[_subIdx] = subList;
  			}
  		}
  		return allSubMeshVert[subIdx];
  	}
  	static getIndicesInSubMesh(model, subIndex) {
  		let indicesGroup = model["_indices_group"];
  		if (!indicesGroup) {
  			indicesGroup = [];
  			model["_indices_group"] = indicesGroup;
  		}
  		if (indicesGroup[subIndex]) {
  			return indicesGroup[subIndex];
  		}
  		else {
  			let indices = model.meshFilter.sharedMesh.getSubMesh(subIndex).getIndices();
  			indicesGroup[subIndex] = indices;
  			return indices;
  		}
  	}
  	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;
  	}
  }
  UVPickerByMesh.planeNormal = new Laya.Vector3;
  UVPickerByMesh.crossPointDir = new Laya.Vector3;
  UVPickerByMesh.crossPoint = new Laya.Vector3;
  UVPickerByMesh.outPoint = new Laya.Vector3;
  UVPickerByMesh.tempVec41 = new Laya.Vector4;
  UVPickerByMesh.tempVec42 = new Laya.Vector4;
  UVPickerByMesh.tempVec43 = new Laya.Vector4;
  UVPickerByMesh.tempVec31 = new Laya.Vector3;
  UVPickerByMesh.tempVec32 = new Laya.Vector3;
  UVPickerByMesh.tempVec33 = new Laya.Vector3;
  UVPickerByMesh.tempVec34 = new Laya.Vector3;
  UVPickerByMesh.ray = new Laya.Ray(new Laya.Vector3, new Laya.Vector3);
  UVPickerByMesh.TEMP_VEC3S = [
  	new Laya.Vector3(),
  	new Laya.Vector3(),
  	new Laya.Vector3(),
  	new Laya.Vector3(),
  	new Laya.Vector3(),
  ];
  UVPickerByMesh.skinnedVertsWorldPosCalcDeltaTime = 0.1;
  UVPickerByMesh._lastWorldPosCalcTime = 0;
  UVPickerByMesh._temp_mat4 = new Laya.Matrix4x4();

  class DebugMeshUvPicker extends DebugBase {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "测试uvpickerbyMesh";
  	}
  	onLoaded() {
  		let model = Global.poolManager.get(Model, db.MODEL_DB_ID.baozuo);
  		this.linkModelAtBack(model);
  		let cf = this.camera.getComponent(CameraFollow);
  		cf.offset = new Laya.Vector3;
  		model.callIfLoaded(() => {
  			UiHelper.registerTouchEvent(this, (e) => {
  				if (e.bBegin) {
  					let ray = Tools.createRayFromScreenPos(this.camera, new Laya.Vector2(e.stageX, e.stageY));
  					let meshSp = model.resNode.getChildAt(1);
  					let startTime = Timer.now;
  					let result = UVPickerByMesh.pick(ray, meshSp);
  					mgrTip.showMsgTip(`耗时: ${(Timer.now - startTime) * 1000}`);
  					console.log(result);
  					if (result.bHit) {
  						let ballMesh = Laya.PrimitiveMesh.createSphere(0.1);
  						let ball = new Laya.MeshSprite3D(ballMesh);
  						let mat = new Laya.UnlitMaterial;
  						ball.meshRenderer.sharedMaterial = mat;
  						mat.albedoColor = new Laya.Vector4(1, 0, 0, 1);
  						ball.transform.position = result.point;
  						this.linkModelAtBack(ball);
  						Timer.callLater(1, () => { ball.destroy(); }, this);
  					}
  				}
  			});
  		}, this);
  	}
  	dispose() {
  		super.dispose();
  	}
  }
  DebugMeshUvPicker.sourceName = "ui://debug/DebugMeshUvPicker";

  class NodeOperate extends MsgHandler {
  	constructor(touchNode, moveNode, rotNode, screenToWorldRate = 0.002) {
  		super();
  		this.destroyed = false;
  		this._enable = true;
  		this.bTouched = false;
  		this.touchX = 0;
  		this.touchY = 0;
  		this.deltaX = 0;
  		this.deltaY = 0;
  		this.bRot = false;
  		this.x = 0;
  		this.y = 0;
  		this.z = 0;
  		this.moveNode = moveNode;
  		this.rotNode = rotNode;
  		this.screenToWorldRate = screenToWorldRate;
  		UiHelper.registerTouchEvent(touchNode, (e) => {
  			if (e.bBegin) {
  				this.onTouchStart();
  			}
  			else if (e.bMove) {
  				this.onTouchMove();
  			}
  			else if (e.bEnd || e.bCancel) {
  				this.onTouchEnd();
  			}
  		});
  		Global.registerListeners(this.moveNode, {
  			[BASE_MSG.SYS_RIGHT_MOUSE_DOWN]: this.onMsgRightMouseDown.bind(this),
  			[BASE_MSG.SYS_RIGHT_MOUSE_UP]: this.onMsgRightMouseUp.bind(this),
  			[BASE_MSG.SYS_MOUSE_WHEEL]: this.onMsgSysMouseWheel.bind(this),
  		});
  		this.startProcMsg();
  	}
  	set enable(value) {
  		if (this.destroyed)
  			return;
  		this._enable = value;
  		if (!value) {
  			this.onTouchEnd();
  		}
  	}
  	get enable() {
  		return this._enable;
  	}
  	dispose() {
  		this.destroyed = true;
  		this.stopProcMsg();
  	}
  	onMsgRightMouseDown() {
  		this.bRigthDown = true;
  		this.bTouched = true;
  	}
  	onMsgRightMouseUp() {
  		this.bRigthDown = false;
  		this.bTouched = false;
  	}
  	onMsgSysMouseWheel(e) {
  		this.moveNode.transform.localPositionZ += e.delta / 20;
  	}
  	onTouchStart() {
  		if (!this._enable)
  			return;
  		this.touchX = Laya.stage.mouseX;
  		this.touchY = Laya.stage.mouseY;
  		this.bTouched = true;
  	}
  	onTouchMove() {
  		if (!this._enable)
  			return;
  		if (!this.bTouched)
  			return;
  		if (!this.rotNode || this.rotNode.destroyed)
  			return;
  		this.deltaX = Laya.stage.mouseX - this.touchX;
  		this.deltaY = Laya.stage.mouseY - this.touchY;
  		this.touchX = Laya.stage.mouseX;
  		this.touchY = Laya.stage.mouseY;
  		if (this.bRigthDown) {
  			this.rotMove();
  		}
  		else {
  			this.moveMove();
  		}
  	}
  	onTouchEnd() {
  		if (!this.bTouched)
  			return;
  		this.bTouched = false;
  	}
  	moveMove() {
  		let x = this.deltaX * this.screenToWorldRate;
  		let y = -this.deltaY * this.screenToWorldRate;
  		this.moveNode.transform.translate(new Laya.Vector3(x, y, 0), true);
  	}
  	rotMove() {
  		let quaternion = new Laya.Quaternion;
  		Laya.Quaternion.createFromAxisAngle(new Laya.Vector3(0, 1, 0), Mathf.clamp(this.deltaX, -100, 100) / 300 * Math.PI, quaternion);
  		Laya.Quaternion.multiply(quaternion, this.rotNode.transform.rotation, quaternion);
  		this.rotNode.transform.rotation = quaternion;
  	}
  }

  class EditorList extends DebugBase {
  	static openPanel(items, onSelect, width, onCancel) {
  		Director.openPanel("EditorList", { items: items, onSelect: onSelect, width: width, onCancel: onCancel });
  	}
  	onLoaded() {
  		this.allItems = this.context.items;
  		let width = this.context.width || 500;
  		let columnCount = Math.max(1, (500 / width) | 0);
  		let itemWidth = 500 / columnCount;
  		this.scrollList.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			let data = this.curItems[idx];
  			obj.text = data;
  			obj.setSize(itemWidth, 50);
  			obj["userData"] = idx;
  		});
  		this.scrollList.on(fgui.Events.CLICK_ITEM, this, (item) => {
  			let idx = item["userData"];
  			this.close();
  			if (this.context.onSelect) {
  				this.context.onSelect(idx);
  			}
  		});
  		this.scrollList.setVirtual();
  		this.scrollList.columnCount = columnCount;
  		this.curItems = this.allItems.slice();
  		this.scrollList.numItems = this.curItems.length;
  		this.input.on(Laya.Event.INPUT, this, this.onInput);
  	}
  	dispose() {
  		super.dispose();
  	}
  	onInput() {
  		let inputStr = this.input.text;
  		if (inputStr) {
  			let arr = [];
  			this.allItems.forEach(function (item) {
  				if (~item.indexOf(inputStr)) {
  					arr.push(item);
  				}
  			});
  			this.curItems = arr;
  		}
  		else {
  			this.curItems = this.allItems.slice();
  		}
  		this.scrollList.numItems = this.curItems.length;
  	}
  	on_click_btnClose() {
  		this.close();
  		if (this.context.onCancel) {
  			this.context.onCancel();
  		}
  	}
  	on_click_scrollList() {
  	}
  }
  EditorList.sourceName = "ui://debug/EditorList";

  class DebugModelAnim extends DebugBase {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = `测试`;
  	}
  	onLoaded() {
  		this.speedSliderNode.init(0, 1, 2);
  		this.speedSliderNode.onChangeCallback(this.onSliderChange.bind(this));
  		this.createScene3DBack(1, 30);
  		this.camera.transform.localPosition = new Laya.Vector3(0, 2, 12);
  		this.camera.transform.localRotationEuler = new Laya.Vector3(-15, 0, 0);
  		this.rootNode = this.scene3DBack.addChild(new Laya.Sprite3D);
  		this.roleRoot = this.rootNode.addChild(new Laya.Sprite3D);
  		this.nodeOpt = new NodeOperate(this.resNode.displayObject, this.rootNode, this.roleRoot);
  	}
  	dispose() {
  		this.clearModel();
  		if (this.nodeOpt)
  			this.nodeOpt.dispose();
  		super.dispose();
  	}
  	clearModel() {
  		if (this.curModel) {
  			Global.poolManager.put(this.curModel);
  			this.curModel = null;
  		}
  	}
  	onSliderChange(value) {
  		if (this.curModel) {
  			this.curModel.setSpeed(value);
  		}
  	}
  	updateAnim() {
  		if (this.curModel) {
  			this.modelIdText.text = this.curModel.modelId;
  		}
  		else {
  			this.modelIdText.text = "";
  		}
  		if (this.curAnimName1) {
  			this.animIdText1.text = this.curAnimName1;
  		}
  		else {
  			this.animIdText1.text = "";
  		}
  		if (this.curAnimName2) {
  			this.animIdText2.text = this.curAnimName2;
  		}
  		else {
  			this.animIdText2.text = "";
  		}
  		let speed = this.speedSliderNode.getValue();
  		this.speedText.text = `播放速度:${speed}`;
  		if (this.curModel && this.curAnimName1) {
  			this.curModel.setSpeed(speed);
  			if (this.curAnimName2) {
  				this.curModel.playAnims(0, [this.curAnimName1, this.curAnimName2], this.btnLoop.selected);
  			}
  			else {
  				this.curModel.playAnim(this.curAnimName1, 0, this.btnLoop.selected);
  			}
  		}
  	}
  	on_click_btnClose() {
  		this.close();
  	}
  	on_click_btnSelectModel() {
  		let allModels = Object.keys(db.get_model_db_map());
  		EditorList.openPanel(allModels, (idx) => {
  			this.clearModel();
  			this.curModel = Global.poolManager.get(Model, allModels[idx]);
  			this.curModel.initAnimator();
  			this.roleRoot.addChild(this.curModel);
  			this.updateAnim();
  		}, 150, () => {
  			this.clearModel();
  		});
  	}
  	on_click_btnSelectAnim1() {
  		let allAnims = Object.keys(db.get_animation_db_map());
  		EditorList.openPanel(allAnims, (idx) => {
  			this.curAnimName1 = allAnims[idx];
  			this.updateAnim();
  		}, 150, () => {
  			this.curAnimName1 = "";
  			this.updateAnim();
  		});
  	}
  	on_click_btnSelectAnim2() {
  		let allAnims = Object.keys(db.get_animation_db_map());
  		EditorList.openPanel(allAnims, (idx) => {
  			this.curAnimName2 = allAnims[idx];
  			this.updateAnim();
  		}, 150, () => {
  			this.curAnimName2 = "";
  			this.updateAnim();
  		});
  	}
  	on_click_btnPlay() {
  		this.updateAnim();
  	}
  	on_click_btnLoop() {
  		this.updateAnim();
  	}
  	on_click_btnSelectEffect() {
  	}
  	on_click_btnPlayEffect() {
  		if (this.curEffect)
  			this.curEffect.play();
  	}
  	on_click_btnStopEffect() {
  		if (this.curEffect)
  			this.curEffect.stop();
  	}
  }
  DebugModelAnim.sourceName = "ui://debug/DebugModelAnim";

  class PaintCavas extends Laya.RenderTexture {
  	constructor(...args) {
  		super(args[0], args[1], args[2], args[3]);
  		this.uvStates = [];
  		this.drawHistorys = [];
  		this.initDrawState([{
  			startUv: new Laya.Vector2(0, 0),
  			endUv: new Laya.Vector2(1, 1),
  		}], 5);
  	}
  	initDrawState(uvBounds, splicSize) {
  		for (let i = 0; i < uvBounds.length; i++) {
  			const element = uvBounds[i];
  			let uvBound = {
  				startUv: element.startUv.clone(),
  				endUv: element.endUv.clone(),
  			};
  			uvBound.startUv.x = Math.floor(uvBound.startUv.x * this.width);
  			uvBound.startUv.y = Math.floor(uvBound.startUv.y * this.height);
  			uvBound.endUv.x = Math.floor(uvBound.endUv.x * this.width);
  			uvBound.endUv.y = Math.floor(uvBound.endUv.y * this.height);
  			this.uvStates.push({
  				uvBound: uvBound,
  				size: splicSize,
  				uvState: {},
  				persent: 0,
  				width: Math.ceil((uvBound.endUv.x - uvBound.startUv.x) / splicSize),
  				height: Math.ceil((uvBound.endUv.y - uvBound.startUv.y) / splicSize),
  			});
  		}
  	}
  	getDrawPersent() {
  		let totalBlock = 0;
  		let curBlock = 0;
  		for (let i = 0; i < this.uvStates.length; i++) {
  			const element = this.uvStates[i];
  			let width = element.width;
  			let height = element.height;
  			totalBlock += width * height;
  			curBlock += element.persent;
  		}
  		return curBlock / totalBlock;
  	}
  	updateDrawState(brush, flowRate, uv) {
  		let startX = uv.x * this.width - brush.width / 2;
  		let startY = uv.y * this.height - brush.width / 2;
  		let endX = uv.x * this.width + brush.width / 2;
  		let endY = uv.y * this.height + brush.width / 2;
  		for (let i = 0; i < this.uvStates.length; i++) {
  			const element = this.uvStates[i];
  			let newStartX = Math.max(startX, element.uvBound.startUv.x) - element.uvBound.startUv.x;
  			let newStartY = Math.max(startY, element.uvBound.startUv.y) - element.uvBound.startUv.y;
  			let newEndX = Math.min(endX, element.uvBound.endUv.x) - element.uvBound.startUv.x;
  			let newEndY = Math.min(endY, element.uvBound.endUv.y) - element.uvBound.startUv.y;
  			let mapStartX = Math.ceil(newStartX / element.size);
  			let mapStartY = Math.ceil(newStartY / element.size);
  			let mapEndX = Math.ceil(newEndX / element.size);
  			let mapEndY = Math.ceil(newEndY / element.size);
  			for (let indexX = mapStartX; indexX <= mapEndX; indexX++) {
  				for (let indexY = mapStartY; indexY <= mapEndY; indexY++) {
  					let mapIndex = indexY * element.width + indexX;
  					if (!element.uvState[mapIndex])
  						element.uvState[mapIndex] = 0;
  					let maxDelta = 1 - element.uvState[mapIndex];
  					let delta = Math.min(flowRate, maxDelta);
  					element.uvState[mapIndex] += delta;
  					element.persent += delta;
  					this.recordDrawHistory({
  						index: mapIndex,
  						url: brush.texture.url,
  						flowRate: flowRate,
  						width: brush.width,
  						height: brush.height,
  					});
  				}
  			}
  		}
  	}
  	recordDrawHistory(history) {
  		let oldHistoryIndex = -1;
  		for (let i = 0; i < this.drawHistorys.length; i++) {
  			const element = this.drawHistorys[i];
  			if (element.index == history.index) {
  				oldHistoryIndex = i;
  				break;
  			}
  		}
  		if (oldHistoryIndex >= 0) {
  			this.drawHistorys.splice(oldHistoryIndex, 1);
  			this.drawHistorys.push(history);
  			return;
  		}
  		if (this.drawHistorys.length > 100) {
  			this.drawHistorys.shift();
  		}
  		this.drawHistorys.push(history);
  	}
  	getDrawHistory() {
  		return Tools.deepCopy(this.drawHistorys);
  	}
  	updateState(brush, flowRate, uv) {
  		this.updateDrawState(brush, flowRate, uv);
  	}
  	static createCavas(width = 256, height = 256) {
  		let cavas = PaintCavas.getFromPool(width, height);
  		cavas.width = width;
  		cavas.height = height;
  		cavas.lock = true;
  		return cavas;
  	}
  	static createWhiteCavas(brush, width = 256, height = 256) {
  		let cavas = PaintCavas.getFromPool(width, height);
  		cavas.width = width;
  		cavas.height = height;
  		cavas.lock = true;
  		brush.resetWidthWhite(cavas);
  		return cavas;
  	}
  	static getFromPool(width, height) {
  		let key = `${width}_${height}`;
  		if (!this.cavasPool[key])
  			this.cavasPool[key] = [];
  		let pool = this.cavasPool[key];
  		if (pool.length == 0) {
  			this.allocCount++;
  			let cavas = new PaintCavas(width, height, Laya.TextureFormat.R8G8B8A8);
  			cavas.lock = true;
  			console.error(`警告: 增加分配rendertexture 用于绘制!: ${this.allocCount}`);
  			return cavas;
  		}
  		return pool.shift();
  	}
  	static recoverCavas(cavas) {
  		let width = cavas.width;
  		let height = cavas.height;
  		let key = `${width}_${height}`;
  		if (!this.cavasPool[key])
  			this.cavasPool[key] = [];
  		let pool = this.cavasPool[key];
  		pool.push(cavas);
  		console.error(`还原rendertexture: ${pool.length}/${this.allocCount}`);
  	}
  }
  PaintCavas.cavasPool = {};
  PaintCavas.allocCount = 0;

  class DebugOffScreenRender extends DebugBase {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = `测试离屏绘制`;
  	}
  	onLoaded() {
  		let cavas = PaintCavas.createCavas();
  		let quadMesh = Laya.PrimitiveMesh.createQuad();
  		let quad = new Laya.MeshSprite3D(quadMesh);
  		let material = new Laya.UnlitMaterial;
  		material.renderMode = Laya.UnlitMaterial.RENDERMODE_TRANSPARENT;
  		quad.meshRenderer.sharedMaterial = material;
  		material.albedoTexture = cavas;
  		this.linkModelAtBack(quad);
  		let sprite = new Laya.Sprite;
  		sprite.size(200, 200);
  		ResLoader.loadRes(`res/brush.png`, RES_TYPE.IMAGE, () => {
  			let aaaa = PaintCavas.createCavas(512, 512);
  			let brush = new PaintBrush();
  			this.linkModelAtBack(brush);
  			brush.reset(aaaa);
  			material.albedoTexture = aaaa;
  			sprite.texture = PaintBrush.createPureColorTexture(new Laya.Color(0, 1, 1, 0.5));
  			let offScreen = new OffScreenRender();
  			this.linkModelAtBack(offScreen);
  			let drawObj = {
  				sprite: sprite,
  				offsetX: 128,
  				offsetY: 128,
  			};
  			offScreen.draw(drawObj, cavas);
  		});
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_btnClose() {
  	}
  }
  DebugOffScreenRender.sourceName = "ui://debug/DebugOffScreenRender";

  class DebugSoundIdPreview extends DebugBase {
  	constructor() {
  		super(...arguments);
  		this.soundIds = [];
  	}
  	onLoaded() {
  		let soundDbMap = db.get_sound_db_map();
  		Tools.forEachMap(soundDbMap, (k, v) => {
  			this.soundIds.push(v.id);
  		});
  		this.spineList.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			let soundId = this.soundIds[idx];
  			let soundData = db.get_sound_db(soundId);
  			obj.title = `${soundId}:${soundData.fileName}`;
  		});
  		this.spineList.on(fgui.Events.CLICK_ITEM, this, this.onClickItem.bind(this));
  		this.spineList.numItems = this.soundIds.length;
  		this.inputSearch.on(Laya.Event.INPUT, this, this.onInputSearch.bind(this));
  	}
  	dispose() {
  		super.dispose();
  	}
  	onClickItem(obj) {
  		mgrSound.stopAll();
  		let idx = obj[`idx`];
  		let soundId = this.soundIds[idx];
  		mgrSound.play(soundId);
  	}
  	onInputSearch() {
  		this.soundIds = [];
  		let regStr = this.inputSearch.text;
  		let regx = new RegExp(regStr);
  		let soundDbMap = db.get_sound_db_map();
  		Tools.forEachMap(soundDbMap, (k, v) => {
  			if (regx.test(v.id.toString())) {
  				this.soundIds.push(v.id);
  			}
  		});
  		this.spineList.numItems = this.soundIds.length;
  	}
  	on_click_btnClose() {
  		this.close();
  	}
  }
  DebugSoundIdPreview.sourceName = "ui://debug/DebugSoundIdPreview";

  class DebugSpinePreview extends DebugBase {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "spine预览";
  		this.spineIds = [];
  		this.aniIds = [];
  	}
  	onLoaded() {
  		let spineDbMap = db.get_spine_db_map();
  		Tools.forEachMap(spineDbMap, (k, v) => {
  			this.spineIds.push(v.id);
  		});
  		this.spineList.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			obj.title = `${this.spineIds[idx]}`;
  		});
  		this.spineList.on(fgui.Events.CLICK_ITEM, this, this.onClickItem.bind(this));
  		this.spineList.numItems = this.spineIds.length;
  		this.aniList.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			obj.title = this.aniIds[idx];
  		});
  		this.aniList.on(fgui.Events.CLICK_ITEM, this, this.onClickAni.bind(this));
  		this.inputSearch.on(Laya.Event.INPUT, this, this.onInputSearch.bind(this));
  	}
  	dispose() {
  		super.dispose();
  	}
  	onClickItem(obj) {
  		if (this.spine) {
  			this.spine.destroy();
  		}
  		let idx = obj[`idx`];
  		let spineId = this.spineIds[idx];
  		this.spine = Spine.create(spineId);
  		this.displayObject.addChild(this.spine);
  		this.spine.x = this.displayObject.width / 2;
  		this.spine.y = this.displayObject.height / 5 * 4;
  		this.aniIds = [];
  		let spineData = db.get_spine_db(spineId);
  		this.spine.playAnimation(spineData.l1);
  		for (let i = 1; i <= 100; i++) {
  			if (spineData[`l${i}`]) {
  				this.aniIds.push(spineData[`l${i}`]);
  			}
  		}
  		this.aniList.numItems = this.aniIds.length;
  	}
  	onClickAni(obj) {
  		let idx = obj[`idx`];
  		this.spine.playAnimation(this.aniIds[idx]);
  	}
  	on_click_btnClose() {
  		this.close();
  	}
  	on_click_spineList() {
  	}
  	on_click_aniList() {
  	}
  	onInputSearch() {
  		this.spineIds = [];
  		let regStr = this.inputSearch.text;
  		let regx = new RegExp(regStr);
  		let spineDbMap = db.get_spine_db_map();
  		Tools.forEachMap(spineDbMap, (k, v) => {
  			if (regx.test(v.id)) {
  				this.spineIds.push(v.id);
  			}
  		});
  		this.spineList.numItems = this.spineIds.length;
  	}
  }
  DebugSpinePreview.sourceName = "ui://debug/DebugSpinePreview";

  class DebugTest extends DebugBase {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "测试测试";
  	}
  	onLoaded() {
  	}
  	dispose() {
  		super.dispose();
  	}
  }
  DebugTest.sourceName = "ui://debug/DebugTest";

  class NpcAnimStateScript extends Laya.AnimatorStateScript {
  	constructor() {
  		super(...arguments);
  		this._callbackList = [];
  	}
  	addCallback(callback) {
  		this._callbackList.push(callback);
  	}
  	clearCallback() {
  		this._callbackList = [];
  	}
  	setEventData(layer, animId) {
  		this._layer = layer;
  		this._animId = animId;
  		this.onStateEnter();
  	}
  	onStateEnter() {
  		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();
  				if (callInfo.count > 0) {
  					callInfo.count--;
  					if (callInfo.count == 0) {
  						this._callbackList.splice(i, 1);
  					}
  				}
  			}
  		}
  	}
  	onStateExit() {
  		for (let i = this._callbackList.length - 1; i >= 0; i--) {
  			const callInfo = this._callbackList[i];
  			if (callInfo) {
  				callInfo.callback();
  			}
  		}
  		this._callbackList = [];
  	}
  }
  class NpcAvatar extends Laya.Sprite3D {
  	constructor(baseRoleId, refObj) {
  		super();
  		this.unloadedPartIds = {};
  		this.loadingPartIds = {};
  		this.loadEndCallBacks = [];
  		this.allLoadEndCallBacks = [];
  		this.linkedModels = [];
  		this.linkedModel2Point = {};
  		this.originMainBonesMap = {};
  		this.originMainBones = [];
  		this.newBonesMap = {};
  		this.originBonesForModelUid = {};
  		this.__renderLayer__ = 0;
  		this.bUseTempDiy = false;
  		this.bUseForceMagicWand = false;
  		this.bShowAfterLoadedMain = false;
  		this.allAnimStateScripts = [];
  		this.instanceObjs = [];
  		this.refObj = null;
  		this.name = "role";
  		console.warn("----NpcAvatar  baseRoleId=", baseRoleId);
  		this.roleId = baseRoleId || 1;
  		this.roleData = db.get_amaze_cloth_crossing_role_db(this.roleId);
  		this.refObj = refObj;
  		this.parts = {};
  		this.loadDefault();
  		Timer.callLoopFrame(1, this.updateState.bind(this), this);
  	}
  	set renderLayer(value) {
  		this.__renderLayer__ = value;
  		Tools.setSprite3dLayer(this, value);
  	}
  	get renderLayer() {
  		return this.__renderLayer__;
  	}
  	get bLoading() {
  		return this.bLoadingNakedness || this.bLoadingPart || Tools.objLength(this.unloadedPartIds) > 0;
  	}
  	removeAllLinkModel() {
  		for (let i = this.linkedModels.length - 1; i >= 0; i--) {
  			const element = this.linkedModels[i];
  			this.unlinkModel(element);
  		}
  		this.linkedModels = [];
  		this.linkedModel2Point = {};
  	}
  	destroy() {
  		this.clearAllAniCallBack();
  		for (let i = 0; i < this.instanceObjs.length; i++) {
  			const element = this.instanceObjs[i];
  			element.destroy();
  		}
  		this.instanceObjs = [];
  		this.removeAllLinkModel();
  		for (const k in this.parts) {
  			let partInfo = this.parts[k];
  			if (!partInfo)
  				continue;
  			let nodeInfos = partInfo.nodes;
  			for (let i = 0; i < nodeInfos.length; i++) {
  				const nodeInfo = nodeInfos[i];
  				this.recoverModelSafe(nodeInfo.node);
  			}
  		}
  		this.parts = {};
  		if (this.baseBody) {
  			this.recoverModelSafe(this.baseBody);
  		}
  		super.destroy(false);
  	}
  	clearAllAniCallBack() {
  		for (let i = 0; i < this.allAnimStateScripts.length; i++) {
  			const element = this.allAnimStateScripts[i];
  			element.clearCallback();
  		}
  	}
  	loadDefault() {
  		this.bLoadingNakedness = true;
  		let preModelIds = [this.roleData.modelId];
  		if (this.roleData.headDecoId) {
  			let headDecoTemplate = db.get_amaze_cloth_crossing_role_head_deco_db(this.roleData.headDecoId);
  			preModelIds.push(headDecoTemplate.modelId);
  		}
  		let taskManager = new TaskManager();
  		for (let index = 0; index < preModelIds.length; index++) {
  			const modelId = preModelIds[index];
  			let modelData = db.get_model_db(modelId);
  			taskManager.addRes(modelData.resPath, RES_TYPE.PREFAB3D);
  		}
  		let loadEndCallback = () => {
  			for (let i = 0; i < preModelIds.length; i++) {
  				const modelId = preModelIds[i];
  				if (modelId == this.roleData.modelId) {
  					let mode = Global.poolManager.get(Model, modelId);
  					let animator = mode.getAnimator();
  					this.baseBody = mode;
  					this.baseBodyAnimator = animator;
  					this.baseBodyAnimator.speed = 1;
  					this.addChild(mode);
  					this.shadow = Tools.findNode("shadow", this.baseBody);
  					this.bip001 = Tools.findNode("Bip001", this.baseBody);
  					Tools.setSprite3dLayer(mode, this.renderLayer);
  				}
  				;
  			}
  			if (this.roleData.headDecoId) {
  				let headDecoTemplate = db.get_amaze_cloth_crossing_role_head_deco_db(this.roleData.headDecoId);
  				this.headDecoModel = Global.poolManager.get(Model, headDecoTemplate.modelId);
  				this.linMode2LinkPoint(this.headDecoModel, headDecoTemplate.linkPointName);
  			}
  			let skinMeshRenderForMain = Tools.findAllSkinnedMeshRenderers(this.baseBody, undefined, true)[0];
  			this.originMainBones = skinMeshRenderForMain.bones;
  			if (this.refObj) {
  				this.baseBodyAnimator.enabled = false;
  				skinMeshRenderForMain[`_bones`] = this.refObj.originMainBones;
  			}
  			else {
  				this.baseBodyAnimator.enabled = true;
  				let recuriveFindAllBone = (root) => {
  					this.originMainBonesMap[root.name] = { node: root };
  					for (let i = 0; i < root.numChildren; i++) {
  						let child = root.getChildAt(i);
  						recuriveFindAllBone(child);
  					}
  				};
  				recuriveFindAllBone(this.baseBody.resNode.getChildAt(0));
  			}
  			this.bLoadingNakedness = false;
  		};
  		taskManager.setLoadingCallback((bComplete) => {
  			if (bComplete) {
  				loadEndCallback();
  			}
  		});
  		taskManager.loadAll(this);
  	}
  	registerLoadEndCallback(callback) {
  		this.loadEndCallBacks.push(callback);
  		return this;
  	}
  	registerAllLoadEndCallback(callback) {
  		this.allLoadEndCallBacks.push(callback);
  		return this;
  	}
  	setShowAfterLoadedMain() {
  		this.bShowAfterLoadedMain = true;
  		this.active = false;
  	}
  	updateState() {
  		this.refreshShadow();
  		if (!!this.baseBody) {
  			if (this.loadEndCallBacks && this.loadEndCallBacks.length > 0) {
  				for (let index = 0; index < this.loadEndCallBacks.length; index++) {
  					const callback = this.loadEndCallBacks[index];
  					callback && callback();
  				}
  				this.loadEndCallBacks = [];
  			}
  			if (this.allLoadEndCallBacks && this.allLoadEndCallBacks.length > 0) {
  				for (let index = 0; index < this.allLoadEndCallBacks.length; index++) {
  					const callback = this.allLoadEndCallBacks[index];
  					callback && callback();
  				}
  				this.allLoadEndCallBacks = [];
  			}
  		}
  	}
  	refreshShadow() {
  		if (this.shadow && this.bip001) {
  			this.shadow.transform.position = new Laya.Vector3(this.bip001.transform.position.x, this.shadow.transform.position.y, this.bip001.transform.position.z);
  		}
  	}
  	isPlayFinished() {
  		if (!this.baseBodyAnimator || this.baseBodyAnimator.destroyed || !this.baseBodyAnimator.getControllerLayer(0)) {
  			return;
  		}
  		let playState = this.baseBodyAnimator.getControllerLayer(0).getCurrentPlayState();
  		let time = playState.normalizedTime;
  		return time >= 1;
  	}
  	playIdle(mixFactor = 0.1, callback) {
  		this.playAnimation(this.roleData.movIdle, mixFactor, () => {
  			callback && callback();
  		}, undefined, true);
  	}
  	getAvatarRealAnimationIdArr(quoteMovArr) {
  		let arr = [];
  		for (let i = 0; i < quoteMovArr.length; i++) {
  			let name = this.roleData[quoteMovArr[i]];
  			if (!name || name == "") {
  				console.log("---arr-对应的角色没有此动作", this.roleData.id, quoteMovArr[i]);
  				continue;
  			}
  			arr.push(name);
  		}
  		return arr;
  	}
  	getAvatarRealAnimationId(quoteMov) {
  		let name = this.roleData[quoteMov];
  		if (!name || name == "") {
  			console.log("----对应的角色没有此动作", this.roleData.id, quoteMov);
  			return;
  		}
  		return name;
  	}
  	getHeadDecoRealAnimationId(quoteMov) {
  		if (!this.roleData.headDecoId) {
  			return null;
  		}
  		let headDecoTemplate = db.get_amaze_cloth_crossing_role_head_deco_db(this.roleData.headDecoId);
  		let name = headDecoTemplate[quoteMov];
  		if (!name || name == "") {
  			console.log("----对应的头饰没有此动作", headDecoTemplate.id, quoteMov);
  			return;
  		}
  		return name;
  	}
  	playAnimationsQuote(quoteAnims, callback) {
  		console.log("-----------playAnimationsQuote---quoteAnims=", quoteAnims);
  		quoteAnims = Tools.deepCopy(quoteAnims);
  		if (quoteAnims.length == 0) {
  			callback && callback();
  			return;
  		}
  		let quote = quoteAnims.shift();
  		this.playAnimationQuote(quote, 0.05, undefined, () => {
  			this.playAnimationsQuote(quoteAnims, callback);
  		}, true, false);
  	}
  	playAnimations(anims, callback) {
  		anims = Tools.deepCopy(anims);
  		if (anims.length == 0) {
  			callback && callback();
  			return;
  		}
  		let anim = anims.shift();
  		this.playAnimation(anim, 0.05, undefined, () => {
  			this.playAnimations(anims, callback);
  		}, true, false);
  	}
  	playAnimationQuote(quoteAnimationId, mixFactor = 0.1, loadEndCallback, playEndCallback, bCanRepeat = true, bIdle = true, startNormalizedTime) {
  		console.log("-----------playAnimationQuote---quoteAnim=", quoteAnimationId);
  		if (this.headDecoModel && !this.headDecoModel.destroyed) {
  			let animationId = this.getHeadDecoRealAnimationId(quoteAnimationId);
  			if (!!animationId) {
  				mgrMaterial.playAnimation(this.headDecoModel.resNode.getComponent(Laya.Animator), animationId, 0);
  			}
  		}
  		let animationId = this.getAvatarRealAnimationId(quoteAnimationId);
  		this.playAnimation(animationId, mixFactor, loadEndCallback, playEndCallback, bCanRepeat, bIdle);
  	}
  	playAnimation(animationId, mixFactor = 0.1, loadEndCallback, playEndCallback, bCanRepeat = true, bIdle = true, startNormalizedTime) {
  		console.log("----------------playAnimation name=", animationId);
  		let animationData = db.get_animation_db(animationId);
  		if (!animationData) {
  			console.log("----【ERROR】------------no this animation name=", animationId);
  			loadEndCallback && loadEndCallback(0);
  			playEndCallback && playEndCallback();
  			return;
  		}
  		if (bCanRepeat) {
  			bIdle = false;
  		}
  		this.curAnimationId = animationId;
  		console.log(`NpcAvatar playAnimation: ${animationId}`);
  		this.registerLoadEndCallback(() => {
  			if (!this.baseBodyAnimator || this.baseBodyAnimator.destroyed || !this.baseBodyAnimator.getControllerLayer(0)) {
  				loadEndCallback && loadEndCallback(0);
  				playEndCallback && playEndCallback();
  				return;
  			}
  			let playAnimState = (animatorState) => {
  				let clip = animatorState.clip;
  				let layer = this.baseBodyAnimator.getControllerLayer(0);
  				let currentPlayState = layer && layer.getCurrentPlayState();
  				let state = currentPlayState && currentPlayState.animatorState;
  				if (state && state.name == animationId && (clip.islooping == true || !bCanRepeat)) {
  					loadEndCallback && loadEndCallback(0);
  					playEndCallback && playEndCallback();
  					return;
  				}
  				this._playerAnimationLoaded(animatorState, animationId, clip, mixFactor, playEndCallback, bIdle, startNormalizedTime);
  				loadEndCallback && loadEndCallback(clip.islooping ? 0 : clip.duration() / this.timeScale);
  			};
  			let animatorState = this.baseBodyAnimator.getControllerLayer(0).getAnimatorState(animationId);
  			if (!animatorState) {
  				Laya.AnimationClip.load(animationData.path, new Laya.Handler(this, (clip) => {
  					if (!this.baseBodyAnimator || this.baseBodyAnimator.destroyed || !this.baseBodyAnimator.getControllerLayer(0)) {
  						loadEndCallback && loadEndCallback(0);
  						playEndCallback && playEndCallback();
  						return;
  					}
  					animatorState = this.baseBodyAnimator.getControllerLayer(0).getAnimatorState(animationId);
  					if (animatorState) {
  						playAnimState(animatorState);
  						return;
  					}
  					;
  					animatorState = new Laya.AnimatorState();
  					animatorState.clip = clip;
  					animatorState.clip.islooping = !!bCanRepeat;
  					animatorState.clipStart = 0;
  					animatorState.clipEnd = 1;
  					animatorState.name = animationId;
  					this.baseBodyAnimator.getControllerLayer(0).addState(animatorState);
  					let script = animatorState.addScript(NpcAnimStateScript);
  					this.allAnimStateScripts.push(script);
  					playAnimState(animatorState);
  				}));
  			}
  			else {
  				playAnimState(animatorState);
  			}
  		});
  	}
  	isPlayingQuote(quoteAnimationId) {
  		let animationId = this.getAvatarRealAnimationId(quoteAnimationId);
  		return this.isPlayingAnimationId(animationId);
  	}
  	isPlayingAnimationId(animationId) {
  		if (this.destroyed)
  			return;
  		if (!this.baseBodyAnimator)
  			return;
  		if (!this.baseBodyAnimator || this.baseBodyAnimator.destroyed || !this.baseBodyAnimator.getControllerLayer(0)) {
  			return;
  		}
  		let currName = this.baseBodyAnimator.getControllerLayer(0).getCurrentPlayState().animatorState.name;
  		return currName == animationId;
  	}
  	_playerAnimationLoaded(animatorState, animationId, clip, mixFactor, playEndCallback, bIdle = true, startNormalizedTime) {
  		if (animationId != this.curAnimationId) {
  			playEndCallback && playEndCallback();
  			return;
  		}
  		this.clearAllAniCallBack();
  		if (mixFactor == 0) {
  			this.baseBodyAnimator.play(animationId, 0, startNormalizedTime || 0);
  		}
  		else {
  			this.baseBodyAnimator.crossFade(animationId, mixFactor, 0, startNormalizedTime || 0);
  		}
  		let script = animatorState.getScript(NpcAnimStateScript);
  		script.setEventData(this.baseBodyAnimator.getControllerLayer(0), animationId);
  		script.addCallback({
  			time: Math.max(0.01, (clip.duration() / this.timeScale) - 0.1),
  			count: 1,
  			callback: () => {
  				playEndCallback && playEndCallback();
  				bIdle && this.playIdle();
  			}
  		});
  	}
  	reload() {
  		if (this.bLoading)
  			return;
  		this.recoverModelSafe(this.baseBody);
  		this.parts = [];
  		this.loadDefault();
  	}
  	clear(bDefaultPart = true) {
  		if (this.bLoading)
  			return;
  		this.unloadedPartIds = {};
  	}
  	linMode2Bip001LHand(mode) {
  		this.linkModel(mode, `Guadian_Bip001LHand`);
  	}
  	linMode2Bip001RHand(mode) {
  		this.linkModel(mode, `Guadian_Bip001RHand`);
  	}
  	linMode2Bip001Spine1(mode) {
  		this.linkModel(mode, `Guadian_Bip001Spine1`);
  	}
  	linMode2LinkPoint(mode, linkPointName) {
  		this.linkModel(mode, linkPointName);
  	}
  	linkMode2BaseBody(model) {
  		this.linkModel(model, this.baseBody.name);
  	}
  	linkModel(model, linkPointName) {
  		if (!model || model.destroyed)
  			return;
  		if (this.linkedModels.indexOf(model) >= 0 && this.linkedModel2Point[model.id] == linkPointName) {
  			this.unlinkModel(model);
  		}
  		this.linkedModels.push(model);
  		this.linkedModel2Point[model.id] = linkPointName;
  		if (this.refObj) {
  			Tools.link2Node(linkPointName, this.refObj.baseBody, model);
  		}
  		else {
  			Tools.link2Node(linkPointName, this.baseBody, model);
  		}
  	}
  	unlinkModel(model) {
  		if (!model)
  			return false;
  		let index = this.linkedModels.indexOf(model);
  		if (index == -1)
  			return false;
  		this.linkedModels.splice(index, 1);
  		if (model instanceof Model) {
  			Global.poolManager.put(model);
  		}
  		else {
  			model.destroy();
  		}
  		return true;
  	}
  	recoverModelSafe(model) {
  		if (model.id === this.baseBody.id) {
  			let mainMeshRender = Tools.findAllSkinnedMeshRenderers(model, undefined, true)[0];
  			mainMeshRender[`_bones`] = this.originMainBones;
  			Global.poolManager.put(model);
  		}
  		else {
  			if (this.refObj) {
  				this.refObj.recoverModelSafe(model);
  			}
  			else {
  				let originBonesForModelUid = this.originBonesForModelUid;
  				let newBonesMap = this.newBonesMap;
  				let originBones = originBonesForModelUid[model.id];
  				delete originBonesForModelUid[model.id];
  				let allNeedDeleteKeys = [];
  				if (originBones) {
  					for (let i = 0; i < originBones.renders.length; i++) {
  						const meshRender = originBones.renders[i];
  						meshRender[`_bones`] = originBones.bones[i];
  					}
  					for (let ii = 0; ii < originBones.allRefBones.length; ii++) {
  						const bone = originBones.allRefBones[ii];
  						let newBone = newBonesMap[bone.name];
  						newBone.refCount--;
  						if (newBone.refCount <= 0) {
  							allNeedDeleteKeys.push(bone.name);
  							newBone.node.destroy();
  						}
  					}
  				}
  				for (let i = 0; i < allNeedDeleteKeys.length; i++) {
  					const key = allNeedDeleteKeys[i];
  					delete this.newBonesMap[key];
  				}
  				Global.poolManager.put(model);
  			}
  		}
  	}
  	hideShadow() {
  	}
  	showShadow() {
  	}
  	pause() {
  		this.baseBodyAnimator.speed = 0;
  	}
  	resume() {
  		this.baseBodyAnimator.speed = 1;
  	}
  	set timeScale(value) {
  		this.baseBodyAnimator.speed = value;
  	}
  	get timeScale() {
  		return this.baseBodyAnimator.speed;
  	}
  	instantiate() {
  		let avatar = new NpcAvatar(this.roleId, this);
  		this.instanceObjs.push(avatar);
  		return avatar;
  	}
  	offBoneManager() {
  	}
  	onBoneManager() {
  	}
  	enableFakeShadow() {
  		this.shadow && (this.shadow.active = true);
  	}
  	disableShadow() {
  		this.shadow && (this.shadow.active = false);
  	}
  	setLocalPositionZ100() {
  		this.transform.localPositionZ = 100;
  	}
  	setLocalPositionZ0() {
  		this.transform.localPositionZ = 0;
  	}
  }

  class DebugTimelinePreview extends DebugBase {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "timeline预览";
  		this.spineIds = [];
  		this.aniIds = [];
  	}
  	onLoaded() {
  		let spineDbMap = db.get_timeline_db_map();
  		Tools.forEachMap(spineDbMap, (k, v) => {
  			this.spineIds.push(v.id);
  		});
  		this.spineList.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			obj.title = `${this.spineIds[idx]}`;
  		});
  		this.spineList.on(fgui.Events.CLICK_ITEM, this, this.onClickItem.bind(this));
  		this.spineList.numItems = this.spineIds.length;
  		this.inputSearch.on(Laya.Event.INPUT, this, this.onInputSearch.bind(this));
  		this.comChat.setScale(0, 0);
  	}
  	dispose() {
  		super.dispose();
  	}
  	onClickItem(obj) {
  		if (this.spine) {
  			this.spine.destroy();
  		}
  		let idx = obj[`idx`];
  		let spineId = this.spineIds[idx];
  		if (spineId != "tongyong") {
  			this.playTimeline(spineId, (clearBefore) => {
  				clearBefore();
  			});
  		}
  		else {
  			this.playResultCommonTimeline("tongyong", (clearBefore) => {
  				clearBefore();
  			});
  		}
  	}
  	showMovieWordPanelVisible() {
  		if (!this.comChat.visible) {
  			this.comChat.visible = true;
  		}
  		cc$1.tween(this.comChat, true)
  			.toScale(0.1, 1)
  			.delay(3)
  			.toScale(0.1, 0)
  			.start();
  	}
  	playTimeline(tilelineName, callback) {
  		Director.showWait("load_timeline");
  		let director = new PlayableDirector();
  		director.stopUpdateOnlyWhenFinish = true;
  		let template = db.get_timeline_db(tilelineName);
  		director.load(template.resPath, () => {
  			Director.hideWait("load_timeline");
  			this.linkModelAtBack(director);
  			this.camera.active = false;
  			director.play();
  			let timeSoundDbMap = db.get_ggg_timeline_movie_word_db_map();
  			let soundArr = [];
  			for (let k in timeSoundDbMap) {
  				let tmp = timeSoundDbMap[k];
  				if (tmp.timelineName == tilelineName) {
  					soundArr.push(tmp);
  				}
  			}
  			if (soundArr.length > 0) {
  				soundArr = Tools.sortArrayByField(soundArr, "frameNum");
  				for (let i = 0; i < soundArr.length; i++) {
  					const element = soundArr[i];
  					let frameNum = element.frameNum;
  					Timer.callLater(frameNum / 30, () => {
  						mgrSound.playSound(element.soundId);
  						if (!!element.word) {
  							let labelName = this.comChat.getChild("chatName");
  							let labelContent = this.comChat.getChild("chatContent");
  							labelContent.text = element.word;
  							labelName.text = element.playerName;
  							this.showMovieWordPanelVisible();
  						}
  					}, this);
  				}
  			}
  			let oldBgSoundId = mgrSound.playingMusicSoundId;
  			let config = db.get_ggg_timeline_config_db(tilelineName);
  			if (!!config && config.bgSoundId) {
  				mgrSound.play(config.bgSoundId);
  			}
  			director.on("STOPPED", this, () => {
  				let clearBefore = () => {
  					if (this.isDisposed || this.resNode.isDisposed) {
  						return;
  					}
  				};
  				mgrSound.playSound(oldBgSoundId);
  				this.camera.active = true;
  				director.removeSelf();
  				director.destroy();
  				callback && callback(clearBefore);
  			});
  		});
  	}
  	playResultCommonTimeline(tilelineName, callbackComplete) {
  		Director.showWait("load_timeline");
  		let arr = [];
  		let dbMap = db.get_amaze_cloth_crossing_property_to_logic_role_map();
  		for (let k in dbMap) {
  			arr.push(dbMap[k].id);
  		}
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(Tools.randomGotOneArrayData(arr));
  		let avatar = new NpcAvatar(roleData.roleId);
  		avatar["_bCustomAvatar"] = true;
  		avatar.registerAllLoadEndCallback(() => {
  			let director = new PlayableDirector();
  			director.stopUpdateOnlyWhenFinish = true;
  			let template = db.get_timeline_db(tilelineName);
  			director.load(template.resPath, () => {
  				let avatarNode = director.findChild("ggx05");
  				avatarNode.addChild(avatar);
  				avatar.playIdle();
  				Director.hideWait("load_timeline");
  				this.linkModelAtBack(director);
  				this.camera.active = false;
  				director.play();
  				let aniArr = [
  					{ frameNum: 31, mov: ROLE_QUOTE_MOV.movResultEvent2RightLower },
  					{ frameNum: 103, mov: ROLE_QUOTE_MOV.movResultEvent2RightLower },
  					{ frameNum: 179, mov: ROLE_QUOTE_MOV.movIdle },
  				];
  				for (let i = 0; i < aniArr.length; i++) {
  					const element = aniArr[i];
  					let frameNum = element.frameNum;
  					Timer.callLater(frameNum / 30, () => {
  						avatar.playAnimationQuote(element.mov, 0, null, null, false, true);
  					}, this);
  				}
  				let timeSoundDbMap = db.get_ggg_timeline_movie_word_db_map();
  				let soundArr = [];
  				for (let k in timeSoundDbMap) {
  					let tmp = timeSoundDbMap[k];
  					if (tmp.timelineName == tilelineName) {
  						soundArr.push(tmp);
  					}
  				}
  				if (soundArr.length > 0) {
  					soundArr = Tools.sortArrayByField(soundArr, "frameNum");
  					for (let i = 0; i < soundArr.length; i++) {
  						const element = soundArr[i];
  						let frameNum = element.frameNum;
  						Timer.callLater(frameNum / 30, () => {
  							mgrSound.playSound(element.soundId);
  							if (!!element.word) {
  								let labelName = this.comChat.getChild("chatName");
  								let labelContent = this.comChat.getChild("chatContent");
  								labelContent.text = element.word;
  								labelName.text = element.playerName;
  								this.showMovieWordPanelVisible();
  							}
  						}, this);
  					}
  				}
  				let oldBgSoundId = mgrSound.playingMusicSoundId;
  				let config = db.get_ggg_timeline_config_db(tilelineName);
  				if (!!config && config.bgSoundId) {
  					mgrSound.play(config.bgSoundId);
  				}
  				director.on("STOPPED", this, () => {
  					let clearBefore = () => {
  						if (this.isDisposed || this.resNode.isDisposed) {
  							return;
  						}
  					};
  					mgrSound.playSound(oldBgSoundId);
  					this.camera.active = true;
  					let avatarNode = director.findChild("ggx05");
  					let numChildren = avatarNode.numChildren;
  					for (let i = (numChildren - 1); i >= 0; i--) {
  						let node = avatarNode.getChildAt(i);
  						node.destroy();
  					}
  					director.removeSelf();
  					director.destroy();
  					callbackComplete && callbackComplete(clearBefore);
  				});
  			});
  		});
  	}
  	on_click_btnClose() {
  		this.close();
  	}
  	on_click_spineList() {
  	}
  	on_click_aniList() {
  	}
  	onInputSearch() {
  		this.spineIds = [];
  		let regStr = this.inputSearch.text;
  		let regx = new RegExp(regStr);
  		let spineDbMap = db.get_timeline_db_map();
  		Tools.forEachMap(spineDbMap, (k, v) => {
  			if (regx.test(v.id)) {
  				this.spineIds.push(v.id);
  			}
  		});
  		this.spineList.numItems = this.spineIds.length;
  	}
  }
  DebugTimelinePreview.sourceName = "ui://debug/DebugTimelinePreview";

  class EditorBoneSearch extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "";
  		this.bOpenAndCloseAnim = true;
  		this.panelLayer = 2;
  		this.allSearchedRouters = [];
  		this.allSelectedRouters = [];
  	}
  	onLoaded() {
  		this.rootBone = this.context.rootBone;
  		this.allSelectedRouters = this.context.allSelectedRouters || [];
  		this.inputSearch.on(Laya.Event.INPUT, this, this.onInputSearch.bind(this));
  		this.listRepxRouters.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			obj.title = this.allSearchedRouters[idx];
  			obj.titleFontSize = 14;
  		});
  		this.listRepxRouters.on(fgui.Events.CLICK_ITEM, this, this.onClickSearchRouters.bind(this));
  		this.listSelectedRouters.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			obj.title = this.allSelectedRouters[idx];
  			obj.titleFontSize = 14;
  		});
  		this.listSelectedRouters.on(fgui.Events.CLICK_ITEM, this, this.onClickSelectedRouters.bind(this));
  		this.listSelectedRouters.numItems = this.allSelectedRouters.length;
  		this.inputSearch.text = `qunbai`;
  		this.onInputSearch();
  	}
  	dispose() {
  		super.dispose();
  	}
  	onInputSearch() {
  		this.allSearchedRouters = [];
  		let repxStr = this.inputSearch.text;
  		if (repxStr.length == 0)
  			return;
  		let repx = new RegExp(repxStr);
  		let recuriveSearch = (root) => {
  			if (repx.test(root.name)) {
  				let router = this.traceToFindRouter(this.rootBone.name, root);
  				if (this.allSelectedRouters.indexOf(router) == -1) {
  					this.allSearchedRouters.push(router);
  				}
  			}
  			else {
  				for (let i = 0; i < root.numChildren; i++) {
  					let child = root.getChildAt(i);
  					recuriveSearch(child);
  				}
  			}
  		};
  		recuriveSearch(this.rootBone);
  		this.listRepxRouters.numItems = this.allSearchedRouters.length;
  	}
  	traceToFindRouter(rootName, cursorNode) {
  		let router = "/";
  		while (cursorNode.name !== rootName) {
  			router = "/" + cursorNode.name + router;
  			cursorNode = cursorNode.parent;
  		}
  		return router;
  	}
  	onClickSearchRouters(obj) {
  		let idx = obj.idx;
  		this.allSelectedRouters.push(this.allSearchedRouters[idx]);
  		this.allSearchedRouters.splice(idx, 1);
  		this.listRepxRouters.numItems = this.allSearchedRouters.length;
  		this.listSelectedRouters.numItems = this.allSelectedRouters.length;
  	}
  	onClickSelectedRouters(obj) {
  		let idx = obj.idx;
  		this.allSearchedRouters.push(this.allSelectedRouters[idx]);
  		this.allSelectedRouters.splice(idx, 1);
  		this.listRepxRouters.numItems = this.allSearchedRouters.length;
  		this.listSelectedRouters.numItems = this.allSelectedRouters.length;
  	}
  	on_click_buttonApply() {
  		this.close();
  		this.context.callback && this.context.callback(this.allSelectedRouters);
  	}
  	on_click_buttonAddAll() {
  		this.allSelectedRouters = this.allSelectedRouters.concat(this.allSearchedRouters);
  		this.allSearchedRouters = [];
  		this.listRepxRouters.numItems = 0;
  		this.listSelectedRouters.numItems = this.allSelectedRouters.length;
  	}
  	on_click_listRepxRouters() {
  	}
  	on_click_listSelectedRouters() {
  	}
  }
  EditorBoneSearch.sourceName = "ui://debug/EditorBoneSearch";

  class EditorDiy extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "diy策划界面";
  		this.colorIds = [];
  		this.printIds = [];
  		this.hangingIds = [];
  	}
  	onLoaded() {
  		this.listColor.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			obj.text = `${this.colorIds[idx]}`;
  			obj.titleColor = parseInt(obj.text) == this.curSelectColorId ? "#00ff00" : `#000000`;
  		});
  		this.listColor.on(fgui.Events.CLICK_ITEM, this, this.onClickColor.bind(this));
  		this.listColor.numItems = this.colorIds.length;
  		this.listPrint.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			obj.text = `${this.printIds[idx]}`;
  			obj.titleColor = parseInt(obj.text) == this.curSelectPrintId ? "#00ff00" : `#000000`;
  		});
  		this.listPrint.on(fgui.Events.CLICK_ITEM, this, this.onClickPrint.bind(this));
  		this.listPrint.numItems = this.printIds.length;
  		this.listHanging.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			obj.text = `${this.hangingIds[idx]}`;
  			obj.titleColor = parseInt(obj.text) == this.curSelectHangingId ? "#00ff00" : `#000000`;
  		});
  		this.listHanging.on(fgui.Events.CLICK_ITEM, this, this.onClickHanging.bind(this));
  		this.listHanging.numItems = this.hangingIds.length;
  		let cf = this.camera.getComponent(CameraFollow);
  		cf.fov = 52;
  		cf.distance = 1.3;
  		cf.offset = new Laya.Vector3(0, 0.6, 0);
  	}
  	dispose() {
  		super.dispose();
  	}
  	onClickColor(obj) {
  		let idx = obj[`idx`];
  		this.curSelectColorId = this.colorIds[idx];
  		this.listColor.numItems = this.colorIds.length;
  	}
  	onClickPrint(obj) {
  		let idx = obj[`idx`];
  		this.curSelectPrintId = this.printIds[idx];
  		this.listPrint.numItems = this.printIds.length;
  	}
  	onClickHanging(obj) {
  		let idx = obj[`idx`];
  		if (this.hangingModel) {
  			this.unLinkModelAtBack(this.hangingModel);
  		}
  		if (this.curSelectHangingId == this.hangingIds[idx])
  			return;
  		this.curSelectHangingId = this.hangingIds[idx];
  		this.listHanging.numItems = this.hangingIds.length;
  	}
  	on_click_btnClose() {
  		this.close();
  	}
  }
  EditorDiy.sourceName = "ui://debug/EditorDiy";

  class PropEditorBase {
  	constructor(obj, editorName, propName) {
  		this.isChanged = false;
  		this.uiObject = obj;
  		this.uiObject.title = editorName;
  		this.editorName = editorName;
  		this.propName = propName;
  		obj.onChangeCallback((value) => {
  			this.isChanged = true;
  			this.owner && this.owner.event(PROPE_DITOR_MSG.DATA_CHANGED);
  			this.onChangeCallback(value);
  		});
  		Timer.callLoop(0.1, () => {
  			if (this.uiObject && this.uiObject[`parent`])
  				this.onRefreshUi();
  		}, obj);
  	}
  	setObject(material, materialData) {
  		this.material = material;
  		this.materialData = materialData;
  		this.onRefreshUi();
  	}
  	onRefreshUi() {
  	}
  }
  class ColorEditor extends PropEditorBase {
  	constructor(obj, editorName, propName, colorType) {
  		super(obj, editorName, propName);
  		this.colorType = colorType || "vec4";
  		obj.init();
  	}
  	onChangeCallback(hexColor) {
  		if (this.colorType == "vec4") {
  			let color = Tools.toLayaColor(hexColor);
  			let colorV4 = new Laya.Vector4(color.r, color.g, color.b, 1.0);
  			this.material[this.propName] = colorV4;
  			this.materialData[this.propName] = colorV4;
  		}
  		else {
  			this.material[this.propName] = hexColor;
  			this.materialData[this.propName] = hexColor;
  		}
  		this.onRefreshUi();
  	}
  	onRefreshUi() {
  		if (this.colorType == "vec4") {
  			this.uiObject.setValue(this.convertVecToColor(this.material[this.propName]));
  		}
  		else {
  			this.uiObject.setValue(this.material[this.propName]);
  		}
  		super.onRefreshUi();
  	}
  	convertColorToArr(color) {
  		return [Mathf.round(color.x, 4), Mathf.round(color.y, 4), Mathf.round(color.z, 4), Mathf.round(color.w, 4)];
  	}
  	convertVecToColor(vec) {
  		if (vec)
  			return Tools.toHexColor(new Laya.Color(vec.x, vec.y, vec.z, vec.w));
  		else
  			return "#ffffff";
  	}
  }
  class SliderEditor extends PropEditorBase {
  	constructor(obj, editorName, propName, params = [0, 1, 4]) {
  		super(obj, editorName, propName);
  		let min = params[0];
  		let max = params[1];
  		let digits = params[2];
  		obj.init(min, max, digits);
  		this.digits = obj.digits;
  	}
  	onChangeCallback(value) {
  		this.material[this.propName] = value;
  		this.materialData[this.propName] = value;
  		this.onRefreshUi();
  	}
  	onRefreshUi() {
  		let value = Mathf.round(this.material[this.propName], this.digits);
  		this.uiObject.title = `${this.editorName}[${value}]`;
  		this.uiObject.setValue(value);
  		super.onRefreshUi();
  	}
  }
  class NumberEditor extends PropEditorBase {
  	constructor(obj, editorName, propName) {
  		super(obj, editorName, propName);
  		obj.init();
  	}
  	onChangeCallback(text) {
  		let value = Mathf.round(Tools.safeParseFloat(text, 0), 2);
  		this.material[this.propName] = value;
  		this.materialData[this.propName] = value;
  		this.onRefreshUi();
  	}
  	onRefreshUi() {
  		let value = Mathf.round(this.material[this.propName], 2);
  		if (this.uiObject.title === `${this.editorName}:${value}`)
  			return;
  		this.uiObject.title = `${this.editorName}:${value}`;
  		this.uiObject.setValue(value + "");
  		super.onRefreshUi();
  	}
  }
  class Vec4Editor extends PropEditorBase {
  	constructor(obj, editorName, propName) {
  		super(obj, editorName, propName);
  		obj.init();
  	}
  	onChangeCallback(text) {
  		let arr = Tools.splitToNumber(text, ",");
  		if (arr.length != 4) {
  			mgrTip.showMsgTip("4维向量格式错误，正确的为：\"a,b,c,d\"");
  			return;
  		}
  		this.material[this.propName] = this.convertArrToVec4(arr);
  		this.materialData[this.propName] = this.convertArrToVec4(arr);
  		this.onRefreshUi();
  	}
  	onRefreshUi() {
  		let value = this.convertVec4ToStr(this.material[this.propName]);
  		if (this.uiObject.title === `${this.editorName}:${value}`)
  			return;
  		this.uiObject.title = `${this.editorName}:${value}`;
  		this.uiObject.setValue(value);
  		super.onRefreshUi();
  	}
  	convertArrToVec4(arr) {
  		return new Laya.Vector4(arr[0], arr[1], arr[2], arr[3]);
  	}
  	convertVec4ToStr(v4) {
  		return `${v4.x},${v4.y},${v4.z},${v4.w}`;
  	}
  }
  class OptionEditor extends PropEditorBase {
  	constructor(obj, editorName, propName, options) {
  		super(obj, editorName, propName);
  		this.uiObject.init(options);
  	}
  	onChangeCallback(value) {
  		this.material[this.propName] = value;
  		this.materialData[this.propName] = value;
  		this.onRefreshUi();
  	}
  	onRefreshUi() {
  		this.uiObject.setValue(this.material[this.propName] || 0);
  		super.onRefreshUi();
  	}
  }
  class TextureEditor extends PropEditorBase {
  	constructor(obj, editorName, propName, options) {
  		super(obj, editorName, propName);
  		obj.init(options);
  	}
  	onChangeCallback(value) {
  		let material = this.material;
  		ResLoader.loadImage(value, (tex) => {
  			let text2d = tex.bitmap;
  			if (text2d && material && !material.destroyed) {
  				Tools.setTexture2dToRepeat(text2d);
  				material[this.propName] = text2d;
  			}
  		});
  		this.materialData[this.propName] = "url://" + value;
  		this.onRefreshUi();
  	}
  	onRefreshUi() {
  		let url = this.materialData[this.propName];
  		if (url && url.startsWith("url://")) {
  			this.uiObject.setValue(url.substr(6));
  		}
  		super.onRefreshUi();
  	}
  }
  var PROPE_DITOR_MSG;
  (function (PROPE_DITOR_MSG) {
  	PROPE_DITOR_MSG["DATA_CHANGED"] = "data_changed";
  })(PROPE_DITOR_MSG || (PROPE_DITOR_MSG = {}));
  class PropEditorGroup extends Laya.EventDispatcher {
  	constructor(list) {
  		super();
  		this.propEditors = [];
  		this.canEditorParamList = [];
  		this.propList = list;
  		this.propList.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			this.createEditorItem(obj, this.canEditorParamList[idx]);
  		});
  		this.propList.itemProvider = new Laya.Handler(this, (idx) => {
  			let prop = this.canEditorParamList[idx];
  			switch (prop.type) {
  				case EditorType.slider:
  					return "ui://debug/CustomEditorSlider";
  				case EditorType.color:
  					return "ui://debug/CustomEditorColor";
  				case EditorType.option:
  					return "ui://debug/CustomEditorOption";
  				case EditorType.vec4:
  					return "ui://debug/CustomEditorInput";
  				case EditorType.num:
  					return "ui://debug/CustomEditorInput";
  				case EditorType.texture2d:
  					return "ui://debug/CustomEditorTextrue";
  				default:
  					console.error(`DebugEditorMaterial 未知EditorType:[${prop.type}]`);
  					break;
  			}
  		});
  	}
  	createEditorItem(uiObject, prop) {
  		var editor;
  		switch (prop.type) {
  			case EditorType.slider:
  				editor = new SliderEditor(uiObject, prop.desc, prop.name, prop.range);
  				break;
  			case EditorType.color:
  				editor = new ColorEditor(uiObject, prop.desc, prop.name, prop.colorType);
  				break;
  			case EditorType.vec4:
  				editor = new Vec4Editor(uiObject, prop.desc, prop.name);
  				break;
  			case EditorType.num:
  				editor = new NumberEditor(uiObject, prop.desc, prop.name);
  				break;
  			case EditorType.option:
  				editor = new OptionEditor(uiObject, prop.desc, prop.name, prop.options);
  				break;
  			case EditorType.texture2d:
  				editor = new TextureEditor(uiObject, prop.desc, prop.name, prop.options);
  				break;
  			default:
  				console.error("DebugEditorMaterial.createEditorItem 未知编辑器类型:", prop.type);
  				break;
  		}
  		editor.owner = this;
  		editor.setObject(this.operateObject, this.saveData);
  		this.propEditors.push(editor);
  	}
  	get isChanged() {
  		for (let i = 0; i < this.propEditors.length; i++) {
  			if (this.propEditors[i].isChanged)
  				return true;
  		}
  		return false;
  	}
  	get visible() {
  		return this.propList.visible;
  	}
  	set visible(value) {
  		this.propList.visible = value;
  	}
  	setObject(canEditorParamList, operateObject, saveData) {
  		if (!canEditorParamList)
  			return;
  		this.canEditorParamList = canEditorParamList;
  		this.operateObject = operateObject;
  		this.saveData = saveData;
  		this.propList.removeChildren(undefined, undefined, true);
  		this.propEditors = [];
  		this.propList.numItems = this.canEditorParamList.length;
  	}
  }

  class FSMObject {
  	constructor() {
  		this.currStateInTimer = 0;
  		this.curState = -1;
  		this.nextState = this.curState;
  		this.lastState = this.curState;
  		this.stateMap = {};
  	}
  	reset() {
  		this.curState = -1;
  		this.nextState = this.curState;
  		this.lastState = this.curState;
  		this.stateMap = {};
  	}
  	registerState(state, enter, execute, leave) {
  		if (enter || execute || leave) {
  			this.stateMap[state] = {
  				enter: enter,
  				execute: execute,
  				leave: leave,
  			};
  		}
  	}
  	registerStateEx(state, enter, execute, leave, caller) {
  		let fenter = caller[enter].bind(caller);
  		let fexecute = caller[execute].bind(caller);
  		let fleave = caller[leave].bind(caller);
  		this.stateMap[state] = {
  			enter: fenter,
  			execute: fexecute,
  			leave: fleave,
  		};
  	}
  	setNextState(state) {
  		this.nextState = state;
  	}
  	update(deltaTime = 0) {
  		let curStateInvokeInfo = this.stateMap[this.curState];
  		let nextStateInvokeInfo = this.stateMap[this.nextState];
  		if (this.nextState != this.curState) {
  			this.lastState = this.curState;
  			this.curState = this.nextState;
  			if (curStateInvokeInfo) {
  				if (curStateInvokeInfo.leave)
  					curStateInvokeInfo.leave();
  			}
  			if (nextStateInvokeInfo) {
  				this.currStateInTimer = Timer.now;
  				if (nextStateInvokeInfo.enter)
  					nextStateInvokeInfo.enter();
  			}
  		}
  		if (nextStateInvokeInfo && nextStateInvokeInfo.execute)
  			nextStateInvokeInfo.execute(deltaTime);
  	}
  	getCurState() {
  		return this.curState;
  	}
  	clear() {
  		this.curState = -1;
  		this.lastState = -1;
  		this.nextState = -1;
  	}
  	getNextState() {
  		return this.nextState;
  	}
  	getLastState() {
  		return this.lastState;
  	}
  	getCurrStateRanTime() {
  		if (!this.currStateInTimer) {
  			return 0;
  		}
  		return (Timer.now - this.currStateInTimer);
  	}
  	startUpdate(caller, extralLoopFunc) {
  		if (!caller || !!this.updateTimer) {
  			return;
  		}
  		this.updateTimer = Timer.callLoop(0.016, () => {
  			let deltaTime = Timer.deltaTime;
  			this.update(deltaTime);
  			if (extralLoopFunc) {
  				extralLoopFunc(deltaTime);
  			}
  		}, caller);
  		this.update(0);
  	}
  	stopUpdate() {
  		if (this.updateTimer) {
  			this.updateTimer.stop();
  			this.updateTimer = null;
  		}
  	}
  }

  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`]);
  		};
  	}
  }

  var Vector3 = Laya.Vector3;
  var Quaternion = Laya.Quaternion;
  var Script3D = Laya.Script3D;
  var BoneColliderPart;
  (function (BoneColliderPart) {
  	BoneColliderPart[BoneColliderPart["NONE"] = 1] = "NONE";
  	BoneColliderPart[BoneColliderPart["UP"] = 2] = "UP";
  	BoneColliderPart[BoneColliderPart["DOWN"] = 3] = "DOWN";
  })(BoneColliderPart || (BoneColliderPart = {}));
  class Bone extends Script3D {
  	constructor() {
  		super(...arguments);
  		this.parm1 = 0.6;
  		this.radius = 0.03;
  		this.part = BoneColliderPart.NONE;
  		this.colliders = [];
  		this.deepth = 0;
  		this.boneLength = 0.1;
  		this.displacementFactor = 0.3;
  		this.maxDisplacement = 0.1;
  		this.wind = new Laya.Vector3;
  		this.gravity = new Laya.Vector3;
  	}
  	onAwake() {
  		this.transform = this.owner.transform;
  		this.originLocalRotation = this.transform.localRotation.clone();
  		this.originLocalPosition = this.transform.localPosition.clone();
  		this.lastWorldRotation = this.transform.rotation.clone();
  		this.lastWorldPosition = this.transform.position.clone();
  		this.deepth = 1;
  		let cursor = this.owner;
  		while (cursor.parent && cursor.getComponent(Bone)) {
  			this.deepth++;
  			cursor = cursor.parent;
  		}
  		let parent = this.owner.parent;
  		if (parent) {
  			this.parent = parent.transform;
  			this.parentBone = this.owner.parent.getComponent(Bone);
  		}
  		if (this.parent) {
  			this.boneLength = Vector3.distance(this.transform.position, this.parent.position);
  		}
  		else {
  			this.boneLength = 0;
  		}
  	}
  	onStart() {
  		this.updateTemplateNormal = new Laya.Vector3;
  	}
  	_ignoreBoneFromNodeToRoot(node) {
  		let boneNode = node.getComponent(Bone);
  		if (boneNode) {
  			if (boneNode.bIgnoredBone) {
  				return;
  			}
  			boneNode.bIgnoredBone = true;
  		}
  		if (!node.parent || node == Laya.stage) {
  			return;
  		}
  		this._ignoreBoneFromNodeToRoot(node.parent);
  	}
  	UpdateBone(dt) {
  		this.transform.localRotation = this.originLocalRotation.clone();
  		this.transform.localPosition = this.originLocalPosition.clone();
  		if (!this.owner || this.destroyed) {
  			return;
  		}
  		if (this.bIgnoredBone || !this.owner.parent) {
  			return;
  		}
  		this.owner.parent["___childBoneIdDict"] = this.owner.parent["___childBoneIdDict"] || {};
  		let count = Tools.objLength(this.owner.parent["___childBoneIdDict"]);
  		if (count >= 2) {
  			let numChildren = this.owner.parent.numChildren;
  			for (let index = 0; index < numChildren; index++) {
  				let nodeChild = this.owner.parent.getChildAt(index);
  				if (!nodeChild) {
  					continue;
  				}
  				this._ignoreBoneFromNodeToRoot(nodeChild);
  			}
  			return;
  		}
  		this.owner.parent["___childBoneIdDict"] = this.owner.parent["___childBoneIdDict"] || {};
  		this.owner.parent["___childBoneIdDict"][this.owner.name] = true;
  		if (!this.parentBone)
  			return;
  		Quaternion.lerp(this.lastWorldRotation, this.transform.rotation, this.parm1, this.lastWorldRotation);
  		this.transform.rotation = this.lastWorldRotation.clone();
  		Laya.Vector3.add(this.transform.position, this.gravity, this.transform.position);
  		Laya.Vector3.lerp(this.lastWorldPosition, this.transform.position, this.displacementFactor, this.lastWorldPosition);
  		Laya.Vector3.subtract(this.lastWorldPosition, this.transform.position, this.updateTemplateNormal);
  		if (Laya.Vector3.scalarLengthSquared(this.updateTemplateNormal) > this.maxDisplacement * this.maxDisplacement) {
  			Laya.Vector3.normalize(this.updateTemplateNormal, this.updateTemplateNormal);
  			Laya.Vector3.scale(this.updateTemplateNormal, this.maxDisplacement, this.updateTemplateNormal);
  			Laya.Vector3.add(this.transform.position, this.updateTemplateNormal, this.lastWorldPosition);
  		}
  		Laya.Vector3.subtract(this.lastWorldPosition, this.parent.position, this.updateTemplateNormal);
  		let node = this.owner;
  		let scaleX = 1;
  		while (node instanceof Laya.Sprite3D) {
  			scaleX *= node.transform.localScaleX;
  			node = node.parent;
  		}
  		let boneLength = this.boneLength * scaleX;
  		if (Laya.Vector3.scalarLengthSquared(this.updateTemplateNormal) > boneLength * boneLength) {
  			Laya.Vector3.normalize(this.updateTemplateNormal, this.updateTemplateNormal);
  			Laya.Vector3.scale(this.updateTemplateNormal, boneLength, this.updateTemplateNormal);
  			Laya.Vector3.add(this.parent.position, this.updateTemplateNormal, this.lastWorldPosition);
  		}
  		for (let i = 0; i < this.colliders.length; i++) {
  			const element = this.colliders[i];
  			let distanceSquared = Laya.Vector3.distanceSquared(element.transform.position, this.lastWorldPosition);
  			let collidernode = element.owner;
  			let colliderscaleX = 1;
  			while (collidernode instanceof Laya.Sprite3D) {
  				colliderscaleX *= collidernode.transform.localScaleX;
  				collidernode = collidernode.parent;
  			}
  			let factor1 = this.transform ? scaleX : 1;
  			let factor2 = colliderscaleX;
  			let radius = this.radius * factor1 + element.radius * factor2;
  			if (distanceSquared <= radius * radius) {
  				Laya.Vector3.subtract(this.lastWorldPosition, element.transform.position, this.updateTemplateNormal);
  				Laya.Vector3.normalize(this.updateTemplateNormal, this.updateTemplateNormal);
  				Laya.Vector3.scale(this.updateTemplateNormal, radius, this.updateTemplateNormal);
  				Laya.Vector3.add(element.transform.position, this.updateTemplateNormal, this.lastWorldPosition);
  			}
  		}
  		this.transform.position = this.lastWorldPosition;
  	}
  }

  var Script3D$1 = Laya.Script3D;
  class BoneCollider extends Script3D$1 {
  	constructor() {
  		super(...arguments);
  		this.radius = 0.08;
  		this.part = BoneColliderPart.NONE;
  	}
  	onAwake() {
  		this.transform = this.owner.transform;
  	}
  	onStart() {
  		this.preRadius = this.radius;
  	}
  	SetScale(scale) {
  	}
  }

  var Script3D$2 = Laya.Script3D;
  class BoneManager extends Script3D$2 {
  	constructor() {
  		super(...arguments);
  		this.bones = [];
  		this.allColliders = [];
  		this._isRefresh = false;
  		this.COLLIDER_REPXS = [/PZD_/];
  		this.B_SHOW_GIMOS = false;
  		this.shareCollierConfig = {
  			c1s: 0.062,
  			c2s: 0.093,
  			c3s: 0.099,
  			c4s: 0.099,
  			c5s: 0.130,
  			c6s: 0.139,
  		};
  		this.originDynamicConfig = {};
  		this.router2ModelKeyMap = {};
  		this.allRouters = {};
  		this.router2IgnoreRename = {};
  		this._1Center = new Laya.Vector3;
  		this._2Center = new Laya.Vector3;
  		this._3Center = new Laya.Vector3;
  	}
  	onAwake() {
  		let root = this.owner;
  		this.AddComponentsInChildren(root, BoneCollider, this.COLLIDER_REPXS);
  		this.allColliders = [];
  		let colliders = this.GetComponentsInChildren(root, BoneCollider);
  		this.allColliders = colliders;
  	}
  	onStart() {
  		this.CheckBone();
  		this.onStarted && this.onStarted();
  	}
  	addDynamicConfig(config, key, bIgnoreRename = false) {
  		this.originDynamicConfig[key] = config;
  		for (let i = 0; i < config.routers.length; i++) {
  			const router = config.routers[i];
  			this.allRouters[router.router] = router;
  			this.router2ModelKeyMap[router.router] = key;
  			this.router2IgnoreRename[router.router] = { bIgnore: bIgnoreRename, key: key };
  		}
  		this.CheckBone();
  	}
  	removeDynamicConfig(key) {
  		let originConfig = this.originDynamicConfig[key];
  		if (!originConfig)
  			return;
  		for (let i = 0; i < originConfig.routers.length; i++) {
  			const element = originConfig.routers[i];
  			delete this.allRouters[element.router];
  			delete this.router2ModelKeyMap[element.router];
  		}
  		delete this.originDynamicConfig[key];
  		this.CheckBone();
  	}
  	isHaveConfig(key) {
  		let originConfig = this.originDynamicConfig[key];
  		return !!originConfig;
  	}
  	CheckBone() {
  		let root = this.owner;
  		let newGeneratedBones = [];
  		Tools.forEachMap(this.allRouters, (k, v) => {
  			let routerRoot = this.findChildByRouter(root, v.router, this.router2IgnoreRename[k].bIgnore, this.router2IgnoreRename[k].key);
  			if (routerRoot) {
  				newGeneratedBones = newGeneratedBones.concat(this.useDynamicBone(v, routerRoot));
  			}
  		});
  		let boneMap = {};
  		for (let i = 0; i < newGeneratedBones.length; i++) {
  			const element = newGeneratedBones[i];
  			boneMap[element.id] = !!element;
  		}
  		if (this.bones) {
  			for (let i = 0; i < this.bones.length; i++) {
  				const bone = this.bones[i];
  				if (!boneMap[bone.id]) {
  					bone.destroy();
  				}
  			}
  		}
  		this.bones = newGeneratedBones;
  		for (let i = 0; i < this.bones.length; i++) {
  			const bone = this.bones[i];
  			bone.colliders = this.allColliders;
  		}
  	}
  	onLateUpdate() {
  		for (let i = 0; i < this.bones.length; i++) {
  			const bone = this.bones[i];
  			if (!!bone) {
  				bone.UpdateBone(Timer.deltaTime);
  			}
  		}
  	}
  	useDynamicBone(router, root) {
  		let allChildrenConfigMap = {};
  		allChildrenConfigMap[root.name] = router.config;
  		for (let i = 0; i < router.children.length; i++) {
  			const childRouter = router.children[i];
  			let name = this.getRouterLastKey(childRouter.router);
  			allChildrenConfigMap[name] = router.config;
  		}
  		let key = this.router2ModelKeyMap[router.router];
  		allChildrenConfigMap[root.parent.name] = this.originDynamicConfig[key].gBoneConfig;
  		let allBones = [];
  		let recurive = (root) => {
  			if (!root)
  				return;
  			let bone = root.getComponent(Bone);
  			if (!bone) {
  				bone = root.addComponent(Bone);
  			}
  			allBones.push(bone);
  			let keys = [`parm1`, `radius`, `gravity`, `displacementFactor`, `maxDisplacement`];
  			for (let i = 0; i < keys.length; i++) {
  				const key = keys[i];
  				this.useBoneParamWithParamMap(bone, root, key, allChildrenConfigMap);
  			}
  			recurive(root.getChildAt(0));
  		};
  		recurive(root);
  		return allBones;
  	}
  	set forceMaxDisplacement(value) {
  		for (let i = 0; i < this.bones.length; i++) {
  			const element = this.bones[i];
  			if (element.destroyed)
  				continue;
  			element.maxDisplacement = value;
  		}
  	}
  	useBoneParamWithParamMap(bone, cursorNode, key, paramMap) {
  		let name = cursorNode.name;
  		let config = paramMap[name] || {};
  		let value = config[key];
  		if (value == null) {
  			this.useBoneParamWithParamMap(bone, cursorNode.parent, key, paramMap);
  		}
  		else {
  			switch (key) {
  				case "parm1":
  					bone.parm1 = value;
  					break;
  				case "radius":
  					bone.radius = value;
  					break;
  				case "displacementFactor":
  					bone.displacementFactor = value;
  					break;
  				case "maxDisplacement":
  					bone.maxDisplacement = value;
  					break;
  				case "gravity":
  					bone.gravity = new Laya.Vector3(0, -value, 0);
  					break;
  			}
  		}
  	}
  	getRouterLastKey(router) {
  		if (router[0] == "/")
  			router = router.slice(1, router.length);
  		if (router[router.length - 1] == "/")
  			router = router.slice(0, router.length - 1);
  		let strs = router.split("/");
  		return strs[strs.length - 1];
  	}
  	getRouterDeepth(router) {
  		if (router[0] == "/")
  			router = router.slice(1, router.length);
  		if (router[router.length - 1] == "/")
  			router = router.slice(0, router.length - 1);
  		let strs = router.split("/");
  		return strs.length;
  	}
  	findChildByRouter(root, router, bIgnoreRename = false, key = "") {
  		while (true) {
  			if (router[0] == "/")
  				router = router.slice(1, router.length);
  			let index = router.indexOf("/");
  			if (index >= 0) {
  				let childName = router.slice(0, index);
  				if (bIgnoreRename) {
  					childName = childName.replace(`_${key}`, "");
  				}
  				router = router.slice(index, router.length);
  				let node = root.getChildByName(childName);
  				if (node) {
  					root = node;
  				}
  				else {
  					return null;
  				}
  			}
  			else {
  				return root;
  			}
  		}
  	}
  	GetComponentsInChildren(root, type) {
  		let components = [];
  		for (let i = 0; i < root.numChildren; i++) {
  			let child = root.getChildAt(i);
  			if (!!child) {
  				let comp = child.getComponent(type);
  				if (!!comp) {
  					components.push(comp);
  				}
  				let comps = this.GetComponentsInChildren(child, type);
  				for (let j = 0; j < comps.length; j++) {
  					const comp = comps[j];
  					components.push(comp);
  				}
  			}
  		}
  		return components;
  	}
  	AddComponentsInChildren(root, type, regexps, param) {
  		for (let i = 0; i < root.numChildren; i++) {
  			let child = root.getChildAt(i);
  			if (!!child) {
  				let bTested = false;
  				for (let i_rep = 0; i_rep < regexps.length; i_rep++) {
  					const regexp = regexps[i_rep];
  					bTested = bTested || regexp.test(child.name);
  				}
  				if (bTested) {
  					let comp = child.addComponent(type);
  					if (param) {
  						for (const k in param) {
  							!!param[k] && (comp[k] = param[k]);
  						}
  					}
  				}
  				this.AddComponentsInChildren(child, type, regexps, param);
  			}
  		}
  	}
  	onUpdate() {
  	}
  	setColliderRidus(radius) {
  		for (let i = 0; i < this.allColliders.length; i++) {
  			const element = this.allColliders[i];
  			element && (element.radius = radius);
  		}
  	}
  	setDisplacementFactor(factor) {
  		factor = parseFloat(factor);
  		for (let i = 0; i < this.bones.length; i++) {
  			const bone = this.bones[i];
  			bone.displacementFactor = factor;
  		}
  	}
  	setMaxDisplacement(param) {
  		param = parseFloat(param);
  		for (let i = 0; i < this.bones.length; i++) {
  			const bone = this.bones[i];
  			bone.maxDisplacement = param;
  		}
  	}
  	set c1s(param) {
  		for (let i = 0; i < this.allColliders.length; i++) {
  			const collider = this.allColliders[i];
  			if (/1/.test(collider.owner.name)) {
  			}
  		}
  	}
  	get c1s() {
  		for (let i = 0; i < this.allColliders.length; i++) {
  			const collider = this.allColliders[i];
  			if (/1/.test(collider.owner.name)) {
  				return collider.radius;
  			}
  		}
  		return -1;
  	}
  	set c2s(param) {
  		for (let i = 0; i < this.allColliders.length; i++) {
  			const collider = this.allColliders[i];
  			if (/2/.test(collider.owner.name)) {
  			}
  		}
  	}
  	get c2s() {
  		for (let i = 0; i < this.allColliders.length; i++) {
  			const collider = this.allColliders[i];
  			if (/2/.test(collider.owner.name)) {
  				return collider.radius;
  			}
  		}
  		return -1;
  	}
  	set c3s(param) {
  		for (let i = 0; i < this.allColliders.length; i++) {
  			const collider = this.allColliders[i];
  			if (/3/.test(collider.owner.name)) {
  			}
  		}
  	}
  	get c3s() {
  		for (let i = 0; i < this.allColliders.length; i++) {
  			const collider = this.allColliders[i];
  			if (/3/.test(collider.owner.name)) {
  				return collider.radius;
  			}
  		}
  		return -1;
  	}
  	set c4s(param) {
  		for (let i = 0; i < this.allColliders.length; i++) {
  			const collider = this.allColliders[i];
  			if (/4/.test(collider.owner.name)) {
  			}
  		}
  	}
  	get c4s() {
  		for (let i = 0; i < this.allColliders.length; i++) {
  			const collider = this.allColliders[i];
  			if (/4/.test(collider.owner.name)) {
  				return collider.radius;
  			}
  		}
  		return -1;
  	}
  	set c5s(param) {
  		for (let i = 0; i < this.allColliders.length; i++) {
  			const collider = this.allColliders[i];
  			if (/5/.test(collider.owner.name)) {
  			}
  		}
  	}
  	get c5s() {
  		for (let i = 0; i < this.allColliders.length; i++) {
  			const collider = this.allColliders[i];
  			if (/5/.test(collider.owner.name)) {
  				return collider.radius;
  			}
  		}
  		return -1;
  	}
  	set c6s(param) {
  		for (let i = 0; i < this.allColliders.length; i++) {
  			const collider = this.allColliders[i];
  			if (/6/.test(collider.owner.name)) {
  			}
  		}
  	}
  	get c6s() {
  		for (let i = 0; i < this.allColliders.length; i++) {
  			const collider = this.allColliders[i];
  			if (/6/.test(collider.owner.name)) {
  				return collider.radius;
  			}
  		}
  		return -1;
  	}
  	setCurentEditorRouter(router, key) {
  		this.curEditorRouter = router;
  		this.curEditorKey = key;
  	}
  	getRoutersByCurEditorRouter() {
  		if (this.curEditorRouter == "/") {
  			return this.originDynamicConfig[this.curEditorKey].routers;
  		}
  		else {
  			let routers = [];
  			for (let i = 0; i < this.originDynamicConfig[this.curEditorKey].routers.length; i++) {
  				const element = this.originDynamicConfig[this.curEditorKey].routers[i];
  				if (this.curEditorRouter.indexOf(element.router) >= 0) {
  					if (this.curEditorRouter == element.router) {
  						routers.push(element);
  					}
  					else {
  						let bFindChild = false;
  						let childRouter = this.curEditorRouter.replace(element.router, "");
  						for (let i = 0; i < element.children.length; i++) {
  							const child = element.children[i];
  							if (child.router == childRouter) {
  								routers.push(child);
  								bFindChild = true;
  							}
  						}
  						if (!bFindChild) {
  							element.children.push({
  								router: childRouter,
  							});
  						}
  					}
  				}
  			}
  			return routers;
  		}
  	}
  	set parm1(p) {
  		if (!p)
  			return;
  		if (this.curEditorRouter == "/") {
  			this.originDynamicConfig[this.curEditorKey].gBoneConfig.parm1 = p;
  			this.CheckBone();
  		}
  		else {
  			let routerDatas = this.getRoutersByCurEditorRouter();
  			for (let i = 0; i < routerDatas.length; i++) {
  				const element = routerDatas[i];
  				element.config = element.config || {};
  				element.config.parm1 = p;
  			}
  			this.CheckBone();
  		}
  	}
  	get parm1() {
  		if (this.curEditorRouter == "/") {
  			return this.originDynamicConfig[this.curEditorKey].gBoneConfig.parm1;
  		}
  		else {
  			let boneRoot = this.findChildByRouter(this.owner, this.curEditorRouter);
  			let bone = boneRoot.getComponent(Bone);
  			return bone.parm1;
  		}
  	}
  	set radius(p) {
  		if (!p)
  			return;
  		if (this.curEditorRouter == "/") {
  			this.originDynamicConfig[this.curEditorKey].gBoneConfig.radius = p;
  			this.CheckBone();
  		}
  		else {
  			let routerDatas = this.getRoutersByCurEditorRouter();
  			for (let i = 0; i < routerDatas.length; i++) {
  				const element = routerDatas[i];
  				element.config = element.config || {};
  				element.config.radius = p;
  			}
  			this.CheckBone();
  		}
  	}
  	get radius() {
  		if (this.curEditorRouter == "/") {
  			return this.originDynamicConfig[this.curEditorKey].gBoneConfig.radius;
  		}
  		else {
  			let boneRoot = this.findChildByRouter(this.owner, this.curEditorRouter);
  			let bone = boneRoot.getComponent(Bone);
  			return bone.radius;
  		}
  	}
  	set displacementFactor(p) {
  		if (!p)
  			return;
  		if (this.curEditorRouter == "/") {
  			this.originDynamicConfig[this.curEditorKey].gBoneConfig.displacementFactor = p;
  			this.CheckBone();
  		}
  		else {
  			let routerDatas = this.getRoutersByCurEditorRouter();
  			for (let i = 0; i < routerDatas.length; i++) {
  				const element = routerDatas[i];
  				element.config = element.config || {};
  				element.config.displacementFactor = p;
  			}
  			this.CheckBone();
  		}
  	}
  	get displacementFactor() {
  		if (this.curEditorRouter == "/") {
  			return this.originDynamicConfig[this.curEditorKey].gBoneConfig.displacementFactor;
  		}
  		else {
  			let boneRoot = this.findChildByRouter(this.owner, this.curEditorRouter);
  			let bone = boneRoot.getComponent(Bone);
  			return bone.displacementFactor;
  		}
  	}
  	set maxDisplacement(p) {
  		if (!p)
  			return;
  		if (this.curEditorRouter == "/") {
  			this.originDynamicConfig[this.curEditorKey].gBoneConfig.maxDisplacement = p;
  			this.CheckBone();
  		}
  		else {
  			let routerDatas = this.getRoutersByCurEditorRouter();
  			for (let i = 0; i < routerDatas.length; i++) {
  				const element = routerDatas[i];
  				element.config = element.config || {};
  				element.config.maxDisplacement = p;
  			}
  			this.CheckBone();
  		}
  	}
  	get maxDisplacement() {
  		if (this.curEditorRouter == "/") {
  			return this.originDynamicConfig[this.curEditorKey].gBoneConfig.maxDisplacement;
  		}
  		else {
  			let boneRoot = this.findChildByRouter(this.owner, this.curEditorRouter);
  			let bone = boneRoot.getComponent(Bone);
  			return bone.maxDisplacement;
  		}
  	}
  	set gravity(p) {
  		if (!p)
  			return;
  		if (this.curEditorRouter == "/") {
  			this.originDynamicConfig[this.curEditorKey].gBoneConfig.gravity = p;
  			this.CheckBone();
  		}
  		else {
  			let routerDatas = this.getRoutersByCurEditorRouter();
  			for (let i = 0; i < routerDatas.length; i++) {
  				const element = routerDatas[i];
  				element.config = element.config || {};
  				element.config.gravity = p;
  			}
  			this.CheckBone();
  		}
  	}
  	get gravity() {
  		if (this.curEditorRouter == "/") {
  			return this.originDynamicConfig[this.curEditorKey].gBoneConfig.gravity;
  		}
  		else {
  			let boneRoot = this.findChildByRouter(this.owner, this.curEditorRouter);
  			let bone = boneRoot.getComponent(Bone);
  			return -bone.gravity.y;
  		}
  	}
  }

  const mutixPartTypes = {
  	[PartType.dress]: [PartType.diy],
  	[PartType.diy]: [PartType.dress],
  };
  class AnimStateScript$1 extends Laya.AnimatorStateScript {
  	constructor() {
  		super(...arguments);
  		this._callbackList = [];
  	}
  	addCallback(callback) {
  		this._callbackList.push(callback);
  	}
  	clearCallback() {
  		this._callbackList = [];
  	}
  	setEventData(layer, animId) {
  		this._layer = layer;
  		this._animId = animId;
  	}
  	onStateEnter() {
  		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();
  				if (callInfo.count > 0) {
  					callInfo.count--;
  					if (callInfo.count == 0) {
  						this._callbackList.splice(i, 1);
  					}
  				}
  			}
  		}
  	}
  	onStateExit() {
  		for (let i = this._callbackList.length - 1; i >= 0; i--) {
  			const callInfo = this._callbackList[i];
  			if (callInfo) {
  				callInfo.callback();
  			}
  		}
  		this._callbackList = [];
  	}
  }
  class RoleAvatar extends Laya.Sprite3D {
  	constructor(roleId, refObj, partIds) {
  		super();
  		this.unloadedPartIds = {};
  		this.loadingPartIds = {};
  		this.loadEndCallBacks = [];
  		this.allLoadEndCallBacks = [];
  		this.linkedModels = [];
  		this.linkedModel2Point = {};
  		this.originMainBonesMap = {};
  		this.originMainBones = [];
  		this.newBonesMap = {};
  		this.originBonesForModelUid = {};
  		this.otherBoneManagers = {};
  		this.__renderLayer__ = 0;
  		this.bUseTempDiy = false;
  		this.bUseForceMagicWand = false;
  		this.bShowAfterLoadedMain = false;
  		this.allAnimStateScripts = [];
  		this.instanceObjs = [];
  		this.refObj = null;
  		this.OffsetXYZ = new Laya.Vector3;
  		this.name = "role";
  		this.roleId = roleId || 1;
  		this.refObj = refObj;
  		this.parts = {};
  		this.loadDefault(partIds);
  		Timer.callLoopFrame(1, this.updateState.bind(this), this);
  	}
  	set renderLayer(value) {
  		this.__renderLayer__ = value;
  		Tools.setSprite3dLayer(this, value);
  	}
  	get renderLayer() {
  		return this.__renderLayer__;
  	}
  	get bLoading() {
  		return this.bLoadingNakedness || this.bLoadingPart || Tools.objLength(this.unloadedPartIds) > 0;
  	}
  	removeAllLinkModel() {
  		for (let i = this.linkedModels.length - 1; i >= 0; i--) {
  			const element = this.linkedModels[i];
  			this.unlinkModel(element);
  		}
  		this.linkedModels = [];
  		this.linkedModel2Point = {};
  	}
  	destroy() {
  		this.clearAllAniCallBack();
  		for (let i = 0; i < this.instanceObjs.length; i++) {
  			const element = this.instanceObjs[i];
  			element.destroy();
  		}
  		this.instanceObjs = [];
  		this.removeAllLinkModel();
  		for (const k in this.parts) {
  			let partInfo = this.parts[k];
  			if (!partInfo)
  				continue;
  			let nodeInfos = partInfo.nodes;
  			for (let i = 0; i < nodeInfos.length; i++) {
  				const nodeInfo = nodeInfos[i];
  				this.recoverModelSafe(nodeInfo.node);
  			}
  		}
  		this.parts = {};
  		if (this.baseBody) {
  			this.recoverModelSafe(this.baseBody);
  		}
  		super.destroy(false);
  	}
  	clearAllAniCallBack() {
  		for (let i = 0; i < this.allAnimStateScripts.length; i++) {
  			const element = this.allAnimStateScripts[i];
  			element.clearCallback();
  		}
  	}
  	loadDefault(partIds = []) {
  		this.bLoadingNakedness = true;
  		let preModelIds = [RoleAvatar.baseBodyModelId];
  		let taskManager = new TaskManager();
  		for (let index = 0; index < preModelIds.length; index++) {
  			const modelId = preModelIds[index];
  			let modelData = db.get_model_db(modelId);
  			taskManager.addRes(modelData.resPath, RES_TYPE.PREFAB3D);
  		}
  		let loadEndCallback = () => {
  			for (let i = 0; i < preModelIds.length; i++) {
  				const modelId = preModelIds[i];
  				let mode = Global.poolManager.get(Model, modelId);
  				let animator = mode.getAnimator();
  				if (modelId == RoleAvatar.baseBodyModelId) {
  					this.baseBody = mode;
  					this.baseBodyAnimator = animator;
  					this.baseBodyAnimator.speed = 1;
  					this.addChild(mode);
  					let materials = this.useCartonMaterial(mode, RoleAvatar.baseBodyModelId);
  					this.baseBodyMaterials = materials;
  					this.boneManager = mode.resNode.getChildAt(0).getComponent(BoneManager);
  					if (!this.boneManager) {
  						this.boneManager = mode.resNode.getChildAt(0).addComponent(BoneManager);
  					}
  					else {
  						this.boneManager.enabled = true;
  					}
  					this.shadow = Tools.findNode("shadow", this.baseBody);
  					this.bip001 = Tools.findNode("Bip001", this.baseBody);
  					let clickNames = [`Click_body`, `Click_head`, `Click_leftFoot`, `Click_rightFoot`];
  					for (let i = 0; i < clickNames.length; i++) {
  						const name = clickNames[i];
  						let __temp = Tools.findNode(name, this);
  						if (__temp) {
  							__temp.meshRenderer.enable = false;
  						}
  					}
  					HumanBone.allHumanBoneScaleInfo[`shenti`] = HumanBone.allHumanBoneScaleInfo[`shenti`] || {};
  				}
  				;
  				Tools.setSprite3dLayer(mode, this.renderLayer);
  			}
  			let skinMeshRenderForMain = Tools.findAllSkinnedMeshRenderers(this.baseBody, undefined, true)[0];
  			this.originMainBones = skinMeshRenderForMain.bones;
  			if (this.refObj) {
  				this.baseBodyAnimator.enabled = false;
  				skinMeshRenderForMain[`_bones`] = this.refObj.originMainBones;
  			}
  			else {
  				this.baseBodyAnimator.enabled = true;
  				let recuriveFindAllBone = (root) => {
  					this.originMainBonesMap[root.name] = { node: root };
  					for (let i = 0; i < root.numChildren; i++) {
  						let child = root.getChildAt(i);
  						recuriveFindAllBone(child);
  					}
  				};
  				recuriveFindAllBone(this.baseBody.resNode.getChildAt(0));
  			}
  			this.fillByPartIds(partIds);
  			this.bLoadingNakedness = false;
  		};
  		taskManager.setLoadingCallback((bComplete) => {
  			if (bComplete) {
  				loadEndCallback();
  			}
  		});
  		taskManager.loadAll(this);
  	}
  	fillByPartIds(partIds, callback) {
  	}
  	removePart(partId) {
  	}
  	setDefaultByType(partType) {
  		if (partType == PartType.diy) {
  			partType = PartType.dress;
  		}
  	}
  	isPartUsed(partId) {
  		return false;
  	}
  	registerLoadEndCallback(callback) {
  		this.loadEndCallBacks.push(callback);
  		return this;
  	}
  	registerAllLoadEndCallback(callback) {
  		this.allLoadEndCallBacks.push(callback);
  		return this;
  	}
  	setShowAfterLoadedMain() {
  		this.bShowAfterLoadedMain = true;
  		this.active = false;
  	}
  	updateState() {
  		this.loadPart();
  		this.refreshShadow();
  		this.refreshMagicWand();
  	}
  	refreshMagicWand() {
  	}
  	refreshShadow() {
  		if (this.shadow && this.bip001) {
  			this.shadow.transform.position = new Laya.Vector3(this.bip001.transform.position.x, this.shadow.transform.position.y, this.bip001.transform.position.z);
  		}
  	}
  	loadPart() {
  	}
  	replaceLoadedPart(partId) {
  	}
  	replaceDressByModel(mode) {
  		let removeTypes = [PartType.dress];
  		if (mutixPartTypes[PartType.dress]) {
  			removeTypes = removeTypes.concat(mutixPartTypes[PartType.dress]);
  		}
  		for (let i = 0; i < removeTypes.length; i++) {
  			const type = removeTypes[i];
  			let oldPartInfo = this.parts[type];
  			if (oldPartInfo) {
  				console.log(`移除部件: ${oldPartInfo.partId}`);
  				for (let index = 0; index < oldPartInfo.nodes.length; index++) {
  					const element = oldPartInfo.nodes[index];
  					this.recoverModelSafe(element.node);
  				}
  			}
  		}
  		let oldPartId = this.parts[PartType.dress].partId;
  		this.parts[PartType.dress] = {
  			partId: oldPartId,
  			nodes: []
  		};
  		Tools.setSprite3dLayer(mode, this.renderLayer);
  		let animator = mode.resNode.getComponent(Laya.Animator);
  		if (!animator) {
  			animator = mode.resNode.addComponent(Laya.Animator);
  		}
  		this.addChild(mode);
  		this.__buildLinkWithMainBody(mode, oldPartId, mode.modelId);
  		if (this.bEnableDynamic) {
  			let dyConfig = mgrDynamicBone.getDynamicConfig(mode.modelId);
  			if (dyConfig)
  				this.boneManager.addDynamicConfig(dyConfig, mode.modelId);
  		}
  		this.parts[PartType.dress].nodes.push({
  			node: mode,
  			animator: animator,
  			materials: [],
  		});
  	}
  	__buildLinkWithMainBody(mode, partId, modelId) {
  		if (this.refObj) {
  			this.refObj.__buildLinkWithMainBody(mode, partId, modelId);
  			return;
  		}
  		let bRenameBone = mode[`__bRenameBone__`];
  		if (!bRenameBone) {
  			mode[`__bRenameBone__`] = true;
  			let rootPart = mode.resNode.getChildAt(0);
  			let recuriveRename = (rootPart) => {
  				for (let i = 0; i < rootPart.numChildren; i++) {
  					let childPart = rootPart.getChildAt(i);
  					if (!this.originMainBonesMap[childPart.name]) {
  						childPart.name = `${childPart.name}_${mode[`modelId`]}`;
  					}
  					recuriveRename(childPart);
  				}
  			};
  			recuriveRename(rootPart);
  		}
  		let meshRenders = Tools.findAllSkinnedMeshRenderers(mode, null, true);
  		let originBoneGroups = [];
  		let boneCounts = [];
  		for (let i = 0; i < meshRenders.length; i++) {
  			const element = meshRenders[i];
  			originBoneGroups.push(element.bones);
  			boneCounts.push(element.bones.length);
  		}
  		this.originBonesForModelUid[mode.id] = {
  			renders: meshRenders,
  			bones: originBoneGroups,
  			partId: partId,
  			boneCounts: boneCounts,
  			extraBones: [],
  			allRefBones: [],
  		};
  		let modeBoneRoot = mode.resNode.getChildAt(0);
  		this.recuriveBuildNewBone(modeBoneRoot, this.originBonesForModelUid[mode.id].allRefBones, partId);
  		for (let i = 0; i < originBoneGroups.length; i++) {
  			let group = originBoneGroups[i];
  			let newBones = [];
  			for (let _ii = 0; _ii < group.length; _ii++) {
  				const originBone = group[_ii];
  				newBones.push((this.newBonesMap[originBone.name] || this.originMainBonesMap[originBone.name]).node);
  			}
  			meshRenders[i][`_bones`] = newBones;
  		}
  	}
  	recuriveBuildNewBone(modeBoneRoot, refBones, partId) {
  		for (let i = 0; i < modeBoneRoot.numChildren; i++) {
  			let child = modeBoneRoot.getChildAt(i);
  			let newBoneName = child.name;
  			if (this.originMainBonesMap[newBoneName]) {
  			}
  			else if (this.newBonesMap[newBoneName]) {
  				this.newBonesMap[newBoneName].refCount++;
  				refBones.push(this.newBonesMap[newBoneName].node);
  			}
  			else {
  				let parent = (this.originMainBonesMap[child.parent.name] || this.newBonesMap[child.parent.name]).node;
  				let newNode = new Laya.Sprite3D;
  				newNode.name = newBoneName;
  				parent.addChild(newNode);
  				newNode.transform.localPosition = child.transform.localPosition.clone();
  				newNode.transform.localRotation = child.transform.localRotation.clone();
  				newNode.transform.localScale = child.transform.localScale.clone();
  				this.newBonesMap[newBoneName] = {
  					node: newNode,
  					refCount: 1,
  					partId: partId,
  				};
  				refBones.push(newNode);
  			}
  			this.recuriveBuildNewBone(child, refBones, partId);
  		}
  	}
  	isPlayFinished() {
  		if (!this.baseBodyAnimator || this.baseBodyAnimator.destroyed || !this.baseBodyAnimator.getControllerLayer(0)) {
  			return;
  		}
  		let playState = this.baseBodyAnimator.getControllerLayer(0).getCurrentPlayState();
  		let time = playState.normalizedTime;
  		return time >= 1;
  	}
  	playIdle(mixFactor = 0.1, callback) {
  	}
  	playPose(callback) {
  	}
  	playAnimations(anims, callback) {
  		anims = Tools.deepCopy(anims);
  		if (anims.length == 0) {
  			callback && callback();
  			return;
  		}
  		let anim = anims.shift();
  		this.playAnimation(anim, 0.05, undefined, () => {
  			this.playAnimations(anims, callback);
  		}, true, false);
  	}
  	playAnimation(animationId, mixFactor = 0.1, loadEndCallback, playEndCallback, bCanRepeat = true, bIdle = true) {
  		let animationData = db.get_animation_db(animationId);
  		if (!animationData) {
  			console.log("----------------no this animation name=", animationId);
  			loadEndCallback && loadEndCallback(0);
  			playEndCallback && playEndCallback();
  			return;
  		}
  		this.curAnimationId = animationId;
  		console.log(`RoleAvatar playAnimation: ${animationId}`);
  		this.registerLoadEndCallback(() => {
  			if (!this.baseBodyAnimator || this.baseBodyAnimator.destroyed || !this.baseBodyAnimator.getControllerLayer(0)) {
  				loadEndCallback && loadEndCallback(0);
  				playEndCallback && playEndCallback();
  				return;
  			}
  			let playAnimState = (animatorState) => {
  				let clip = animatorState.clip;
  				let layer = this.baseBodyAnimator.getControllerLayer(0);
  				let currentPlayState = layer && layer.getCurrentPlayState();
  				let state = currentPlayState && currentPlayState.animatorState;
  				if (state && state.name == animationId && (clip.islooping == true || !bCanRepeat)) {
  					loadEndCallback && loadEndCallback(0);
  					playEndCallback && playEndCallback();
  					return;
  				}
  				this._playerAnimationLoaded(animatorState, animationId, clip, mixFactor, playEndCallback, bIdle);
  				loadEndCallback && loadEndCallback(clip.islooping ? 0 : clip.duration() / this.timeScale);
  			};
  			let animatorState = this.baseBodyAnimator.getControllerLayer(0).getAnimatorState(animationId);
  			if (!animatorState) {
  				Laya.AnimationClip.load(animationData.path, new Laya.Handler(this, (clip) => {
  					if (!this.baseBodyAnimator || this.baseBodyAnimator.destroyed || !this.baseBodyAnimator.getControllerLayer(0)) {
  						loadEndCallback && loadEndCallback(0);
  						playEndCallback && playEndCallback();
  						return;
  					}
  					animatorState = this.baseBodyAnimator.getControllerLayer(0).getAnimatorState(animationId);
  					if (animatorState) {
  						playAnimState(animatorState);
  						return;
  					}
  					;
  					animatorState = new Laya.AnimatorState();
  					animatorState.clip = clip;
  					animatorState.clipStart = 0;
  					animatorState.clipEnd = 1;
  					animatorState.name = animationId;
  					this.baseBodyAnimator.getControllerLayer(0).addState(animatorState);
  					let script = animatorState.addScript(AnimStateScript$1);
  					this.allAnimStateScripts.push(script);
  					playAnimState(animatorState);
  				}));
  			}
  			else {
  				playAnimState(animatorState);
  			}
  		});
  	}
  	get baseFaceAnimator() {
  		return this.parts[PartType.face].nodes[0].animator;
  	}
  	playBuildInFaceAnim(animName) {
  		if (!this.parts[PartType.face])
  			return;
  		let animator = this.parts[PartType.face].nodes[0].animator;
  		if (!animator || !animator.getControllerLayer(0))
  			return;
  		let state = animator.getControllerLayer(0).getAnimatorState(animName);
  		if (state) {
  			animator.play(animName, 0, 0);
  		}
  	}
  	isCurAnimationId(animationId) {
  		if (this.destroyed)
  			return;
  		if (!this.baseBodyAnimator)
  			return;
  		if (!this.baseBodyAnimator || this.baseBodyAnimator.destroyed || !this.baseBodyAnimator.getControllerLayer(0)) {
  			return;
  		}
  		return this.baseBodyAnimator.getControllerLayer(0).getCurrentPlayState().animatorState.name == animationId;
  	}
  	_playerAnimationLoaded(animatorState, animationId, clip, mixFactor, playEndCallback, bIdle = true) {
  		if (animationId != this.curAnimationId) {
  			playEndCallback && playEndCallback();
  			return;
  		}
  		this.clearAllAniCallBack();
  		if (mixFactor == 0) {
  			this.baseBodyAnimator.play(animationId, 0, 0);
  		}
  		else {
  			this.baseBodyAnimator.crossFade(animationId, mixFactor);
  		}
  		let script = animatorState.getScript(AnimStateScript$1);
  		script.setEventData(this.baseBodyAnimator.getControllerLayer(0), animationId);
  		if (!clip.islooping) {
  			script.addCallback({
  				time: 10000,
  				count: 1,
  				callback: () => {
  					playEndCallback && playEndCallback();
  					bIdle && this.playIdle();
  				}
  			});
  		}
  		else {
  			playEndCallback && playEndCallback();
  		}
  	}
  	useCartonMaterial(model, modelId) {
  		let materials = mgrMaterial.useEditedMaterial(model);
  		for (let i = 0; i < materials.length; i++) {
  			const element = materials[i];
  		}
  		return materials;
  	}
  	reload() {
  		if (this.bLoading)
  			return;
  		let oldPartIds = [];
  		for (const k in this.parts) {
  			let element = this.parts[k];
  			oldPartIds.push(element.partId);
  			let nodes = element.nodes;
  			for (let index = 0; index < nodes.length; index++) {
  				const node = nodes[index];
  				this.recoverModelSafe(node.node);
  			}
  		}
  		this.recoverModelSafe(this.baseBody);
  		this.parts = [];
  		this.loadDefault(oldPartIds);
  	}
  	clear(bDefaultPart = true) {
  		if (this.bLoading)
  			return;
  	}
  	getPartIdByTye(partType) {
  		let info = this.parts[partType];
  		if (!info)
  			return null;
  		return info.partId;
  	}
  	getPartIds(bAll = false) {
  	}
  	linkMode2UpperArm(model) {
  		this.linkModel(model, "Bip001 R UpperArm");
  	}
  	linkMode2RHand(model) {
  		this.linkModel(model, "Guadian_RHand");
  	}
  	linkMode2LHand(model) {
  		this.linkModel(model, "Guadian_LHand");
  	}
  	linkMode2RFoot(model) {
  		this.linkModel(model, "Bip001 R Foot");
  	}
  	linkMode2LFoot(model) {
  		this.linkModel(model, "Bip001 L Foot");
  	}
  	linkMode2FoodLeft(model) {
  		this.linkModel(model, "FoodLeft");
  	}
  	linkMode2FoodRight(model) {
  		this.linkModel(model, "FoodRight");
  	}
  	linMode2LeftToe(mode) {
  		this.linkModel(mode, `Bip001 L Toe0`);
  	}
  	linMode2RightToe(mode) {
  		this.linkModel(mode, `Bip001 R Toe0`);
  	}
  	linMode2HeadTop(mode) {
  		this.linkModel(mode, `Head_top`);
  	}
  	linkMode2BaseBody(model) {
  		this.linkModel(model, this.baseBody.name);
  	}
  	linkModel(model, linkPointName) {
  		if (!model || model.destroyed)
  			return;
  		if (this.linkedModels.indexOf(model) >= 0 && this.linkedModel2Point[model.id] == linkPointName) {
  			this.unlinkModel(model);
  		}
  		this.linkedModels.push(model);
  		this.linkedModel2Point[model.id] = linkPointName;
  		if (this.refObj) {
  			Tools.link2Node(linkPointName, this.refObj.baseBody, model);
  		}
  		else {
  			Tools.link2Node(linkPointName, this.baseBody, model);
  		}
  	}
  	unlinkModel(model) {
  		if (!model)
  			return false;
  		let index = this.linkedModels.indexOf(model);
  		if (index == -1)
  			return false;
  		this.linkedModels.splice(index, 1);
  		if (model instanceof Model) {
  			Global.poolManager.put(model);
  		}
  		else {
  			model.destroy();
  		}
  		return true;
  	}
  	recoverModelSafe(model) {
  		if (model.id === this.baseBody.id) {
  			let mainMeshRender = Tools.findAllSkinnedMeshRenderers(model, undefined, true)[0];
  			mainMeshRender[`_bones`] = this.originMainBones;
  			Global.poolManager.put(model);
  		}
  		else {
  			if (this.refObj) {
  				this.refObj.recoverModelSafe(model);
  			}
  			else {
  				let originBonesForModelUid = this.originBonesForModelUid;
  				let newBonesMap = this.newBonesMap;
  				let originBones = originBonesForModelUid[model.id];
  				delete originBonesForModelUid[model.id];
  				let allNeedDeleteKeys = [];
  				if (originBones) {
  					for (let i = 0; i < originBones.renders.length; i++) {
  						const meshRender = originBones.renders[i];
  						meshRender[`_bones`] = originBones.bones[i];
  					}
  					for (let ii = 0; ii < originBones.allRefBones.length; ii++) {
  						const bone = originBones.allRefBones[ii];
  						let newBone = newBonesMap[bone.name];
  						newBone.refCount--;
  						if (newBone.refCount <= 0) {
  							allNeedDeleteKeys.push(bone.name);
  							newBone.node.destroy();
  						}
  					}
  				}
  				for (let i = 0; i < allNeedDeleteKeys.length; i++) {
  					const key = allNeedDeleteKeys[i];
  					delete this.newBonesMap[key];
  				}
  				Global.poolManager.put(model);
  			}
  		}
  		this.boneManager.isHaveConfig(model.modelId) && this.boneManager.removeDynamicConfig(model.modelId);
  	}
  	getRFoot() {
  		return Tools.findNode(`Bip001 R Foot`, this.baseBody);
  	}
  	getLFoot() {
  		return Tools.findNode(`Bip001 L Foot`, this.baseBody);
  	}
  	hideShadow() {
  	}
  	showShadow() {
  	}
  	pause() {
  		this.baseBodyAnimator.speed = 0;
  	}
  	resume() {
  		this.baseBodyAnimator.speed = 1;
  	}
  	set timeScale(value) {
  		this.baseBodyAnimator.speed = value;
  	}
  	get timeScale() {
  		return this.baseBodyAnimator.speed;
  	}
  	getNodeByType(type) {
  		let info = this.parts[type];
  		return info.nodes[0].node;
  	}
  	instantiate() {
  		let avatar = new RoleAvatar(this.roleId, this);
  		this.instanceObjs.push(avatar);
  		return avatar;
  	}
  	set instancePosition(value) {
  		if (!this.refObj)
  			return;
  		let setInsPos = () => {
  			let OffsetXYZ = new Laya.Vector3;
  			this.OffsetXYZ = OffsetXYZ;
  			Laya.Vector3.subtract(value, this.refObj.transform.position, OffsetXYZ);
  			Tools.forEachMap(this.parts, (k, v) => {
  				for (let i = 0; i < v.nodes.length; i++) {
  					let nodeInfo = v.nodes[i];
  					for (let _ii = 0; _ii < nodeInfo.materials.length; _ii++) {
  						const element = nodeInfo.materials[_ii];
  					}
  				}
  			});
  			for (let i = 0; i < this.baseBodyMaterials.length; i++) {
  				const element = this.baseBodyMaterials[i];
  			}
  		};
  		if (this.bLoading) {
  			this.registerAllLoadEndCallback(() => {
  				setInsPos();
  			});
  		}
  		else {
  			setInsPos();
  		}
  	}
  	setRoleId(roleId) {
  		this.roleId = roleId;
  		this.clear();
  		this.setRoleBodyShape(roleId);
  		this.setIdleId();
  	}
  	setRoleBodyShape(roleId) {
  	}
  	setIdleId(bodyIdle, faceIdle, bPlayNow) {
  		if (bPlayNow) {
  			this.playDefaultIdleAnimation();
  		}
  	}
  	playDefaultIdleAnimation() {
  	}
  	offBoneManager() {
  		this.boneManager && (this.boneManager.forceMaxDisplacement = 0.01);
  	}
  	onBoneManager() {
  		this.boneManager && (this.boneManager.CheckBone());
  	}
  	enableFakeShadow() {
  		this.shadow && (this.shadow.active = true);
  	}
  	disableShadow() {
  		this.shadow && (this.shadow.active = false);
  	}
  }
  RoleAvatar.baseBodyModelId = null;

  class Master extends RoleAvatar {
  	constructor(roleId, refObj, partIds) {
  		super(roleId, refObj, partIds);
  		this.STATE_IDLE = 1;
  		this.STATE_THINGKING = 2;
  		this.STATE_INTERACTION = 3;
  		this.STATE_COMMANDING = 4;
  		this.STATE_DANCEING = 5;
  		this.STATE_POSE = 6;
  		this.bTitleVisible = true;
  		this.bPetVisible = true;
  		this.bLevelVisible = true;
  		this.indexSprites = {};
  		this.meshSprite3dPool = [];
  		this.identityQuation = new Laya.Quaternion;
  		this.FSM = new FSMObject;
  		this.FSM.registerStateEx(this.STATE_IDLE, "inIdle", "exeIdle", "outIdle", this);
  		this.FSM.registerStateEx(this.STATE_THINGKING, "inThinking", "exeThinking", "outThinking", this);
  		this.FSM.registerStateEx(this.STATE_INTERACTION, "inInteraction", "exeInteraction", "outInteraction", this);
  		this.FSM.registerStateEx(this.STATE_COMMANDING, "inCommand", "exeCommand", "outCommand", this);
  		this.FSM.registerStateEx(this.STATE_DANCEING, "inDanceing", "exeDanceing", "outDanceing", this);
  		this.FSM.registerStateEx(this.STATE_POSE, "inPose", "exePose", "outPose", this);
  		let script = this.addComponent(Laya.Script);
  		script.onLateUpdate = this.update.bind(this);
  		this.FSM.setNextState(this.STATE_IDLE);
  		this.updateTitle();
  	}
  	updateTitle() {
  	}
  	updateLevel(root, progress) {
  		if (!this.levelSprite3D) {
  			let mesh = Laya.PrimitiveMesh.createQuad(1.2, 1.2);
  			this.levelSprite3D = new Laya.MeshSprite3D(mesh);
  			this.levelSprite3D.transform.localScale = new Laya.Vector3(0.25, 0.25, 0.25);
  			this.addChild(this.levelSprite3D);
  			this.levelSprite3D.meshRenderer.enable = false;
  		}
  		for (let i = 0; i < root.numChildren; i++) {
  			let child = root.getChildAt(i);
  			this.createQuadByObj(child, root, i);
  		}
  		this.progressMat && (this.progressMat.mprogress = progress);
  	}
  	createQuadByObj(obj, root, index) {
  		if (obj instanceof fgui.Image) {
  			if (this.indexSprites[index])
  				return;
  			let x = (obj.x + obj.width / 2 - root.width / 2) / 100;
  			let y = -(obj.y + obj.height / 2 - root.height / 2) / 100;
  			let height = obj.height / 100;
  			let width = obj.width / 100;
  			let text2d = obj.texture.bitmap;
  			let uvrect = new Laya.Vector4(obj.texture.uvrect[0], obj.texture.uvrect[1], obj.texture.uvrect[2], obj.texture.uvrect[3]);
  			let [sp, mat] = this.createQuad(this.levelSprite3D, x, y, width, height, text2d, uvrect, index);
  			if (index == 1) {
  				this.progressMat = mat;
  			}
  			this.indexSprites[index] = [sp];
  		}
  		else {
  			this.indexSprites[index] = this.indexSprites[index] || [];
  			for (let i = 0; i < this.indexSprites[index].length; i++) {
  				const element = this.indexSprites[index][i];
  				this.recoverMeshSprite3dToPool(element);
  			}
  			this.indexSprites[index] = [];
  			let cmds = obj[`_graphics`][`_cmds`];
  			for (let i = 0; i < cmds.length; i++) {
  				const cmd = cmds[i];
  				let x = (obj.x + cmd.x + cmd.width / 2 - root.width / 2) / 100;
  				let y = -(obj.y + cmd.y + cmd.height / 2 - root.height / 2) / 100;
  				let width = cmd.width / 100;
  				let height = cmd.height / 100;
  				let tex2d = cmd.texture.bitmap;
  				let uvrect = new Laya.Vector4(cmd.texture.uvrect[0], cmd.texture.uvrect[1], cmd.texture.uvrect[2], cmd.texture.uvrect[3]);
  				let [sp, mat] = this.createQuad(this.levelSprite3D, x, y, width, height, tex2d, uvrect, index);
  				this.indexSprites[index].push(sp);
  			}
  		}
  	}
  	getMeshFromPool() {
  		if (this.meshSprite3dPool.length > 0) {
  			return this.meshSprite3dPool.shift();
  		}
  		console.error("create mesh sprite3d");
  		let mesh = Laya.PrimitiveMesh.createQuad(1, 1);
  		let sprite = new Laya.MeshSprite3D(mesh);
  		let mat = new NormalMaterial;
  		mat.renderMode = NormalMaterial.RENDERMODE_TRANSPARENT;
  		sprite.meshRenderer.sharedMaterial = mat;
  		return sprite;
  	}
  	recoverMeshSprite3dToPool(mesh) {
  		this.meshSprite3dPool.push(mesh);
  	}
  	createQuad(root, x, y, width, height, tex2d, uvrect, zOrder) {
  		let sprite = this.getMeshFromPool();
  		root.addChild(sprite);
  		let mat = sprite.meshRenderer.sharedMaterial;
  		sprite.transform.localPositionX = x;
  		sprite.transform.localPositionY = y;
  		sprite.transform.localPositionZ = zOrder * 0.05;
  		sprite.transform.localScaleX = width;
  		sprite.transform.localScaleY = height;
  		mat.albedoTexture = tex2d;
  		mat.uvrect = uvrect;
  		mat.bInversePremul = true;
  		return [sprite, mat];
  	}
  	update() {
  		this.FSM.update();
  		let headTop = Tools.findNode("Head_top", this);
  		if (this.title && headTop) {
  			this.title.transform.position = new Laya.Vector3(headTop.transform.position.x, headTop.transform.position.y + 0.05, headTop.transform.position.z);
  			this.title.transform.rotation = this.identityQuation;
  			this.title.active = this.bTitleVisible;
  		}
  		if (this.levelSprite3D && headTop) {
  			this.levelSprite3D.transform.position = new Laya.Vector3(headTop.transform.position.x, headTop.transform.position.y + 0.3, headTop.transform.position.z);
  			this.levelSprite3D.transform.rotation = this.identityQuation;
  			this.levelSprite3D.active = this.bLevelVisible;
  		}
  		this.levelSprite3D && (this.levelSprite3D.active = this.bLevelVisible);
  	}
  	destroy() {
  		this.title && Global.poolManager.put(this.title);
  		this.title = null;
  		super.destroy();
  	}
  	inIdle() {
  		this.playIdle();
  		Timer.callLater(Mathf.random(3, 5), () => {
  			if (this.FSM.getCurState() == this.STATE_IDLE) {
  				let states = [this.STATE_POSE];
  				this.FSM.setNextState(Tools.randomOne(states));
  			}
  		}, this);
  	}
  	exeIdle() {
  	}
  	outIdle() {
  	}
  	inThinking() {
  	}
  	exeThinking() {
  	}
  	outThinking() {
  	}
  	inInteraction() { }
  	exeInteraction() { }
  	outInteraction() { }
  	inCommand() { }
  	exeCommand() { }
  	outCommand() { }
  	inDanceing() {
  	}
  	exeDanceing() { }
  	outDanceing() { }
  	inPose() {
  		this.playPose((bSuccessFul) => {
  			if (bSuccessFul) {
  				if (this.FSM.getCurState() == this.STATE_POSE) {
  					this.FSM.setNextState(this.STATE_IDLE);
  				}
  			}
  		});
  	}
  	exePose() { }
  	outPose() { }
  	commanding() {
  		this.FSM.setNextState(this.STATE_COMMANDING);
  	}
  	freedom() {
  		this.FSM.setNextState(this.STATE_IDLE);
  	}
  	playInMain(loadEndCallback, callback) {
  	}
  	clickHead(bBackIdle = true) {
  		if (this.FSM.getCurState() == this.STATE_INTERACTION)
  			return;
  		this.commanding();
  		let animations = [];
  		let index = Mathf.random(0, animations.length - 1);
  		let animationId = animations[index];
  		this.playAnimation(animationId, 0.1, null, () => {
  			bBackIdle && this.FSM.setNextState(this.STATE_IDLE);
  		});
  		BaseFacade.mGoal.commit(BASE_ACTION_ID.CLICK_ROLE, 1, 1);
  		let soundIds = [101, 352, 353, 354];
  		mgrSound.play(soundIds[Mathf.random(0, soundIds.length - 1)]);
  	}
  	clickBody(bBackIdle = true) {
  		if (this.FSM.getCurState() == this.STATE_INTERACTION)
  			return;
  		this.commanding();
  		let animations = [];
  		let index = Mathf.random(0, animations.length - 1);
  		let animationId = animations[index];
  		this.playAnimation(animationId, 0.1, null, () => {
  			bBackIdle && this.FSM.setNextState(this.STATE_IDLE);
  		});
  		BaseFacade.mGoal.commit(BASE_ACTION_ID.CLICK_ROLE, 1, 2);
  		let soundIds = [101, 352, 353, 354];
  		mgrSound.play(soundIds[Mathf.random(0, soundIds.length - 1)]);
  	}
  	clickFoot(bBackIdle = true) {
  		if (this.FSM.getCurState() == this.STATE_INTERACTION)
  			return;
  		this.commanding();
  		let animations = [];
  		let index = Mathf.random(0, animations.length - 1);
  		let animationId = animations[index];
  		this.playAnimation(animationId, 0.1, null, () => {
  			bBackIdle && this.FSM.setNextState(this.STATE_IDLE);
  		});
  		BaseFacade.mGoal.commit(BASE_ACTION_ID.CLICK_ROLE, 1, 3);
  		let soundIds = [101, 352, 353, 354];
  		mgrSound.play(soundIds[Mathf.random(0, soundIds.length - 1)]);
  	}
  	setAvatarTarget(target, callback, bezierValue = new Laya.Vector3) {
  		let maxTime = Laya.Vector3.distance(this.transform.position, target) / 0.5;
  		let pos = new Laya.Vector3(target.x, this.transform.position.y, target.z);
  		let oldRotation = this.transform.rotation.clone();
  		let delta = new Laya.Vector3;
  		Laya.Vector3.subtract(this.transform.position, pos, delta);
  		Laya.Vector3.add(this.transform.position, delta, delta);
  		this.transform.lookAt(delta, new Laya.Vector3(0, 1, 0), false);
  		let newRoataion = this.transform.rotation.clone();
  		this.transform.rotation = oldRotation.clone();
  		if (bezierValue.x == 0 && bezierValue.y == 0 && bezierValue.z == 0) {
  			cc$1.tween(this.transform)
  				.parallel(cc$1.tween().to(maxTime, { localPositionX: target.x, localPositionY: target.y, localPositionZ: target.z }, { easing: cc$1.Ease.sineIn })
  					.call(() => {
  						callback && callback();
  					}), cc$1.tween().to(0.15, {}, {
  						onUpdate: (target, progress) => {
  							let end = new Laya.Quaternion;
  							Laya.Quaternion.lerp(oldRotation, newRoataion, progress, end);
  							this.transform.rotation = end;
  						}
  					}))
  				.start();
  		}
  		else {
  			let p1 = this.transform.position.clone();
  			let p3 = target.clone();
  			let p2 = new Laya.Vector3((p3.x + p1.x) / 2 + bezierValue.x, (p3.y + p1.y) / 2 + bezierValue.y, (p3.z + p1.z) / 2 + bezierValue.z);
  			cc$1.tween(this.transform)
  				.parallel(cc$1.tween().then(cc$1.bezierV3To(maxTime, [p1, p2, p3]).easing(cc$1.Ease.sineOut))
  					.call(() => {
  						callback && callback();
  					}), cc$1.tween().to(0.15, {}, {
  						onUpdate: (target, progress) => {
  							let end = new Laya.Quaternion;
  							Laya.Quaternion.lerp(oldRotation, newRoataion, progress, end);
  							this.transform.rotation = end;
  						}
  					}))
  				.start();
  		}
  	}
  }

  var Keyboard$3 = Laya.Keyboard;
  class EditorDynamicBone extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "";
  		this.allModelNames = [];
  		this.allRegEModelNames = [];
  		this.partModelMap = {};
  	}
  	onLoaded() {
  		UITools.widgetLeftTopMC(this.btnClose);
  		UITools.widgetLeftTopMC(this.propList);
  		UITools.widgetLeftTopMC(this.colliderPropList);
  		UITools.widgetRightTopMC(this.comRight);
  		this.avatar = new Master;
  		this.linkModelAtBack(this.avatar);
  		this.initTouch();
  		this.editorObject = new PropEditorGroup(this.propList);
  		this.editorObject.visible = false;
  		this.editorObject.on(PROPE_DITOR_MSG.DATA_CHANGED, this, () => {
  			mgrDynamicBone.setDynamicConfig(this.curSelectedModelId, this.curEditorData);
  		});
  		this.editorColliderObj = new PropEditorGroup(this.colliderPropList);
  		this.editorColliderObj.visible = false;
  		this.editorColliderObj.on(PROPE_DITOR_MSG.DATA_CHANGED, this, () => {
  			mgrDynamicBone.setDynamicConfig(this.curSelectedModelId, this.curEditorData);
  		});
  		this.listModels.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			if (this.allRegEModelNames.length > 0) {
  				obj.text = this.allRegEModelNames[idx];
  			}
  			else {
  				obj.text = this.allModelNames[idx];
  			}
  			obj.titleColor = obj.text == this.curSelectedModelId ? "#00ff00" : `#ffffff`;
  		});
  		this.listModels.on(fgui.Events.CLICK_ITEM, this, this.onClickModel.bind(this));
  		this.listModels.numItems = this.allModelNames.length;
  		this.inputSearchModel.on(Laya.Event.INPUT, this, this.onInputSearch.bind(this));
  		this.buttonAddDynamicBone.visible = false;
  		this.buttonApplyDynamicBone.visible = false;
  		this.buttonRemoveDynamicBone.visible = false;
  		this.listRouters.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			let router = this.curEditorData.routers[idx];
  			let texts = router.router.split("/");
  			obj.title = texts[texts.length - 2];
  			obj.titleColor = idx == this.curRouterIndex ? "#00ff00" : `#ffffff`;
  		});
  		this.listRouters.on(fgui.Events.CLICK_ITEM, this, this.onClickRouter.bind(this));
  		this.listChilds.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			let childs = this.childrens;
  			let child = childs[idx];
  			obj.title = child.name;
  			obj.titleColor = idx == this.curChildIdx ? "#00ff00" : `#ffffff`;
  		});
  		this.listChilds.on(fgui.Events.CLICK_ITEM, this, this.onClickChild.bind(this));
  		Global.registerListeners(this, {
  			[BASE_MSG.SYS_KEY_DOWN]: this.onKeyDown.bind(this),
  		});
  	}
  	dispose() {
  		this.nodeOpt && this.nodeOpt.dispose();
  		super.dispose();
  	}
  	onKeyDown(e) {
  		if (!this.bFocus)
  			return;
  		switch (e.keyCode) {
  			case Keyboard$3.C:
  				if (e.ctrlKey) {
  					if (!this.curEditorData) {
  						mgrTip.showMsgTip("没有选中任何动态骨骼");
  						return;
  					}
  					this.clipbordColliderData = Tools.deepCopy(this.curEditorData.gColliderConfig);
  					if (this.curRouterIndex < 0) {
  						this.clipbordBoneData = Tools.deepCopy(this.curEditorData.gBoneConfig);
  						mgrTip.showMsgTip("拷贝主体信息");
  						return;
  					}
  					if (this.curChildIdx < 0) {
  						let config = this.curEditorData.routers[this.curRouterIndex].config;
  						if (!config) {
  							mgrTip.showMsgTip("拷贝router信息, 不存在");
  							return;
  						}
  						this.clipbordBoneData = Tools.deepCopy(config);
  						mgrTip.showMsgTip("拷贝router信息");
  						return;
  					}
  					let config = this.curEditorData.routers[this.curRouterIndex].children[this.curChildIdx].config;
  					this.clipbordBoneData = Tools.deepCopy(config);
  					mgrTip.showMsgTip("拷贝子节点信息");
  				}
  				break;
  			case Keyboard$3.V:
  				if (e.ctrlKey) {
  					if (!this.curEditorData) {
  						mgrTip.showMsgTip("没有选中任何动态骨骼");
  						return;
  					}
  					if (!this.clipbordBoneData) {
  						mgrTip.showMsgTip("先使用ctrl+C拷贝碰撞信息和骨骼信息");
  						return;
  					}
  					if (this.curRouterIndex < 0) {
  						this.curEditorData.gBoneConfig = Tools.deepCopy(this.clipbordBoneData);
  						mgrTip.showMsgTip("粘贴到主体骨骼信息");
  						mgrDynamicBone.setDynamicConfig(this.curSelectedModelId, this.curEditorData);
  						this.refreshEditorPanel();
  						this.refresModelData();
  						return;
  					}
  					if (this.curChildIdx < 0) {
  						this.curEditorData.routers[this.curRouterIndex].config = Tools.deepCopy(this.clipbordBoneData);
  						mgrTip.showMsgTip("粘贴到router骨骼信息");
  						mgrDynamicBone.setDynamicConfig(this.curSelectedModelId, this.curEditorData);
  						this.refreshEditorPanel();
  						this.refresModelData();
  						return;
  					}
  					this.curEditorData.routers[this.curRouterIndex].children[this.curChildIdx].config = Tools.deepCopy(this.clipbordBoneData);
  					mgrTip.showMsgTip("粘贴到子节点骨骼信息");
  					mgrDynamicBone.setDynamicConfig(this.curSelectedModelId, this.curEditorData);
  					this.refreshEditorPanel();
  					this.refresModelData();
  				}
  				break;
  			case Keyboard$3.X:
  				if (e.ctrlKey) {
  					if (!this.curEditorData) {
  						mgrTip.showMsgTip("没有选中任何动态骨骼");
  						return;
  					}
  					if (!this.clipbordColliderData) {
  						mgrTip.showMsgTip("先使用ctrl+C拷贝碰撞信息和骨骼信息");
  						return;
  					}
  					this.curEditorData.gColliderConfig = Tools.deepCopy(this.clipbordColliderData);
  					mgrTip.showMsgTip("粘贴共享碰撞信息");
  					mgrDynamicBone.setDynamicConfig(this.curSelectedModelId, this.curEditorData);
  					this.refreshEditorPanel();
  					this.refresModelData();
  				}
  				break;
  			default:
  				break;
  		}
  	}
  	onClickModel(obj) {
  		let idx = obj.idx;
  		this.curSelectedModelIndex = idx;
  		let modelId = this.allRegEModelNames[idx] || this.allModelNames[idx];
  		this.__onClickModel(modelId);
  	}
  	__onClickModel(modelId) {
  		this.curSelectedModelId = modelId;
  		mgrTip.showMsgTip(`选中模型:${modelId}`);
  		this.curRouterIndex = -1;
  		this.curChildIdx = -1;
  		this.childrens = [];
  		this.listModels.numItems = this.listModels.numItems;
  		this.createModel(() => {
  			this.refresModelData();
  		});
  	}
  	refresModelData() {
  		let editorData = mgrDynamicBone.getDynamicConfig(this.curSelectedModelId);
  		this.curEditorData = editorData;
  		if (!editorData) {
  			this.buttonApplyDynamicBone.visible = true;
  			this.buttonRemoveDynamicBone.visible = false;
  			this.buttonAddDynamicBone.visible = false;
  			this.listRouters.numItems = 0;
  			this.listChilds.numItems = 0;
  			this.propList.numItems = 0;
  			this.colliderPropList.numItems = 0;
  		}
  		else {
  			this.buttonApplyDynamicBone.visible = false;
  			this.buttonRemoveDynamicBone.visible = true;
  			this.buttonAddDynamicBone.visible = true;
  			this.listRouters.numItems = editorData.routers.length;
  			this.useDynamicData(() => {
  				this.curEditorSingleData = editorData.gBoneConfig;
  				this.curEditorColliderData = editorData.gColliderConfig;
  				this.boneManager.setCurentEditorRouter("/", this.curSelectedModelId);
  				this.refreshEditorPanel();
  			});
  		}
  	}
  	onClickRouter(obj) {
  		let idx = obj.idx;
  		this.curRouterIndex = idx;
  		this.listRouters.numItems = this.listRouters.numItems;
  		this.curChildIdx = -1;
  		let root = this.boneManager.findChildByRouter(this.boneManager.owner, this.curEditorData.routers[this.curRouterIndex].router);
  		this.childrens = [];
  		while (root.getChildAt(0)) {
  			this.childrens.push(root.getChildAt(0));
  			root = root.getChildAt(0);
  		}
  		this.listChilds.numItems = this.childrens.length;
  		let config = this.curEditorData.routers[this.curRouterIndex].config;
  		if (!config) {
  			config = this.curEditorData.routers[this.curRouterIndex].config = {};
  		}
  		this.curEditorSingleData = config;
  		this.boneManager.setCurentEditorRouter(this.curEditorData.routers[this.curRouterIndex].router, this.curSelectedModelId);
  		this.refreshEditorPanel();
  	}
  	onClickChild(obj) {
  		let idx = obj.idx;
  		this.curChildIdx = idx;
  		this.listChilds.numItems = this.listChilds.numItems;
  		let child = this.childrens[idx];
  		let router = this.curEditorData.routers[this.curRouterIndex];
  		let childConfig = null;
  		for (let i = 0; i < router.children.length; i++) {
  			const element = router.children[i];
  			if (element.router.indexOf(child.name) >= 0) {
  				childConfig = element;
  				break;
  			}
  		}
  		if (!childConfig) {
  			let childRouter = "";
  			let recurive = (root) => {
  				if (router.router.indexOf(root.name) == -1) {
  					childRouter = root.name + "/" + childRouter;
  					recurive(root.parent);
  				}
  			};
  			recurive(child);
  			childConfig = {
  				router: childRouter,
  				config: {},
  			};
  			router.children.push(childConfig);
  		}
  		this.curEditorSingleData = childConfig.config;
  		this.boneManager.setCurentEditorRouter(router.router + childConfig.router, this.curSelectedModelId);
  		this.refreshEditorPanel();
  	}
  	onInputSearch() {
  		this.allRegEModelNames = [];
  		let regStr = this.inputSearchModel.text;
  		let regx = new RegExp(regStr);
  		for (let i = 0; i < this.allModelNames.length; i++) {
  			const modelName = this.allModelNames[i];
  			if (regx.test(modelName)) {
  				this.allRegEModelNames.push(modelName);
  			}
  		}
  		this.listModels.numItems = this.allRegEModelNames.length;
  	}
  	refreshEditorPanel() {
  		let propsList = [
  			{ name: `parm1`, desc: `一级:软 <------> 硬`, type: EditorType.slider, range: [0, 1] },
  			{ name: `displacementFactor`, desc: `二级:软 <------> 硬`, type: EditorType.slider, range: [0, 1] },
  			{ name: `maxDisplacement`, desc: `限制:小 <------> 大`, type: EditorType.slider, range: [0, 1] },
  			{ name: `radius`, desc: `碰撞半径`, type: EditorType.slider, range: [0, 0.2] },
  			{ name: `gravity`, desc: `重力`, type: EditorType.slider, range: [0, 1] },
  		];
  		this.editorObject.visible = true;
  		this.editorObject.setObject(propsList, this.boneManager, this.curEditorSingleData);
  		let propsColliderList = [
  			{ name: `c1s`, desc: `<---1级--->`, type: EditorType.slider, range: [0, 0.2] },
  			{ name: `c2s`, desc: `<---2级--->`, type: EditorType.slider, range: [0, 0.2] },
  			{ name: `c3s`, desc: `<---3级--->`, type: EditorType.slider, range: [0, 0.2] },
  			{ name: `c4s`, desc: `<---4级--->`, type: EditorType.slider, range: [0, 0.2] },
  			{ name: `c5s`, desc: `<---5级--->`, type: EditorType.slider, range: [0, 0.2] },
  			{ name: `c6s`, desc: `<---6级--->`, type: EditorType.slider, range: [0, 0.2] },
  		];
  		this.editorColliderObj.visible = true;
  		this.editorColliderObj.setObject(propsColliderList, this.boneManager, this.curEditorColliderData);
  	}
  	createModel(callback) {
  		let partId = this.partModelMap[this.curSelectedModelId];
  		if (!partId) {
  			let model = Global.poolManager.get(Model, this.curSelectedModelId);
  			model.callIfLoaded(() => {
  				mgrMaterial.useEditedMaterial(model);
  				this.avatar.replaceDressByModel(model);
  				this.boneManager = this.avatar.boneManager;
  				callback && callback();
  			}, this);
  			this.model = model;
  		}
  		else {
  			this.avatar.fillByPartIds([partId]);
  			this.avatar.registerAllLoadEndCallback(() => {
  				callback && callback();
  			});
  		}
  	}
  	initTouch() {
  		this.nodeOpt = new NodeOperate(this.resNode.displayObject, this.avatar, this.avatar);
  	}
  	useDynamicData(callback) {
  		this.boneManager.addDynamicConfig(this.curEditorData, this.curSelectedModelId);
  		this.boneManager.c1s = this.curEditorData.gColliderConfig.c1s;
  		this.boneManager.c2s = this.curEditorData.gColliderConfig.c2s;
  		this.boneManager.c3s = this.curEditorData.gColliderConfig.c3s;
  		this.boneManager.c4s = this.curEditorData.gColliderConfig.c4s;
  		this.boneManager.c5s = this.curEditorData.gColliderConfig.c5s;
  		this.boneManager.c6s = this.curEditorData.gColliderConfig.c6s;
  		callback && callback();
  	}
  	on_click_btnClose() {
  		this.close();
  	}
  	on_click_buttonApplyDynamicBone() {
  		let config = {
  			gBoneConfig: {
  				parm1: 0.15,
  				tansRatio: 1,
  				radius: 0.03,
  				displacementFactor: 0.5,
  				maxDisplacement: 0.1,
  				gravity: 0,
  			},
  			gColliderConfig: {
  				c1s: 0.05,
  				c2s: 0.05,
  				c3s: 0.05,
  				c4s: 0.05,
  				c5s: 0.05,
  				c6s: 0.05,
  			},
  			routers: [],
  		};
  		this.curEditorData = config;
  		mgrDynamicBone.setDynamicConfig(this.curSelectedModelId, this.curEditorData);
  		this.__onClickModel(this.curSelectedModelId);
  	}
  	on_click_buttonAddDynamicBone() {
  		let routers = [];
  		let routerMap = {};
  		for (let i = 0; i < this.curEditorData.routers.length; i++) {
  			const element = this.curEditorData.routers[i];
  			routers.push(element.router);
  			routerMap[element.router] = element;
  		}
  		let root = null;
  		for (let i = 0; i < this.model.resNode.numChildren; i++) {
  			let child = this.model.resNode.getChildAt(i);
  			if (child.name == `toufa` || child.name == `Bip001` || child.name == `beibu`) {
  				root = child;
  				break;
  			}
  		}
  		Director.openPanel("EditorBoneSearch", {
  			rootBone: root,
  			allSelectedRouters: routers,
  			callback: (routerList) => {
  				let newRouters = [];
  				for (let i = 0; i < routerList.length; i++) {
  					const element = routerList[i];
  					if (routerMap[element]) {
  						newRouters.push(routerMap[element]);
  					}
  					else {
  						newRouters.push({
  							router: element,
  							children: [],
  						});
  					}
  				}
  				this.curEditorData.routers = newRouters;
  				mgrDynamicBone.setDynamicConfig(this.curSelectedModelId, this.curEditorData);
  				this.refresModelData();
  			}
  		});
  	}
  	on_click_buttonRemoveDynamicBone() {
  		mgrDynamicBone.setDynamicConfig(this.curSelectedModelId, null);
  		this.boneManager.removeDynamicConfig(this.curSelectedModelId);
  		this.refresModelData();
  	}
  	on_click_listModels() {
  	}
  	on_click_listRouters() {
  	}
  	on_click_listChilds() {
  	}
  	on_click_propList() {
  	}
  	on_click_colliderPropList() {
  	}
  }
  EditorDynamicBone.sourceName = "ui://debug/EditorDynamicBone";

  var Keyboard$4 = Laya.Keyboard;
  class EditorDynamicBoneElse extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "动态骨骼编辑器";
  		this.allModelNames = [];
  		this.allRegEModelNames = [];
  	}
  	onLoaded() {
  		UITools.widgetLeftTopMC(this.btnClose);
  		UITools.widgetLeftTopMC(this.propList);
  		UITools.widgetLeftTopMC(this.colliderPropList);
  		UITools.widgetRightTopMC(this.comRight);
  		this.modelRoot = new Laya.Sprite3D;
  		this.modelRoot.name = `modelRoot`;
  		this.linkModelAtBack(this.modelRoot);
  		this.initTouch();
  		let modelDbMap = db.get_model_db_map();
  		Tools.forEachMap(modelDbMap, (k, v) => {
  			this.allModelNames.push(v.id);
  		});
  		this.editorObject = new PropEditorGroup(this.propList);
  		this.editorObject.visible = false;
  		this.editorObject.on(PROPE_DITOR_MSG.DATA_CHANGED, this, () => {
  			mgrDynamicBone.setDynamicConfig(this.curSelectedModelId, this.curEditorData);
  		});
  		this.editorColliderObj = new PropEditorGroup(this.colliderPropList);
  		this.editorColliderObj.visible = false;
  		this.editorColliderObj.on(PROPE_DITOR_MSG.DATA_CHANGED, this, () => {
  			mgrDynamicBone.setDynamicConfig(this.curSelectedModelId, this.curEditorData);
  		});
  		this.listModels.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			if (this.allRegEModelNames.length > 0) {
  				obj.text = this.allRegEModelNames[idx];
  			}
  			else {
  				obj.text = this.allModelNames[idx];
  			}
  			obj.titleColor = obj.text == this.curSelectedModelId ? "#00ff00" : `#ffffff`;
  		});
  		this.listModels.on(fgui.Events.CLICK_ITEM, this, this.onClickModel.bind(this));
  		this.listModels.numItems = this.allModelNames.length;
  		this.inputSearchModel.on(Laya.Event.INPUT, this, this.onInputSearch.bind(this));
  		this.buttonAddDynamicBone.visible = false;
  		this.buttonApplyDynamicBone.visible = false;
  		this.buttonRemoveDynamicBone.visible = false;
  		this.listRouters.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			let router = this.curEditorData.routers[idx];
  			let texts = router.router.split("/");
  			obj.title = texts[texts.length - 2];
  			obj.titleColor = idx == this.curRouterIndex ? "#00ff00" : `#ffffff`;
  		});
  		this.listRouters.on(fgui.Events.CLICK_ITEM, this, this.onClickRouter.bind(this));
  		this.listChilds.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			let childs = this.childrens;
  			let child = childs[idx];
  			obj.title = child.name;
  			obj.titleColor = idx == this.curChildIdx ? "#00ff00" : `#ffffff`;
  		});
  		this.listChilds.on(fgui.Events.CLICK_ITEM, this, this.onClickChild.bind(this));
  		Global.registerListeners(this, {
  			[BASE_MSG.SYS_KEY_DOWN]: this.onKeyDown.bind(this),
  		});
  	}
  	dispose() {
  		this.nodeOpt && this.nodeOpt.dispose();
  		super.dispose();
  	}
  	onKeyDown(e) {
  		switch (e.keyCode) {
  			case Keyboard$4.C:
  				if (e.ctrlKey) {
  					if (!this.curEditorData) {
  						mgrTip.showMsgTip("没有选中任何动态骨骼");
  						return;
  					}
  					this.clipbordColliderData = Tools.deepCopy(this.curEditorData.gColliderConfig);
  					if (this.curRouterIndex < 0) {
  						this.clipbordBoneData = Tools.deepCopy(this.curEditorData.gBoneConfig);
  						mgrTip.showMsgTip("拷贝主体信息");
  						return;
  					}
  					if (this.curChildIdx < 0) {
  						let config = this.curEditorData.routers[this.curRouterIndex].config;
  						if (!config) {
  							mgrTip.showMsgTip("拷贝router信息, 不存在");
  							return;
  						}
  						this.clipbordBoneData = Tools.deepCopy(config);
  						mgrTip.showMsgTip("拷贝router信息");
  						return;
  					}
  					let config = this.curEditorData.routers[this.curRouterIndex].children[this.curChildIdx].config;
  					this.clipbordBoneData = Tools.deepCopy(config);
  					mgrTip.showMsgTip("拷贝子节点信息");
  				}
  				break;
  			case Keyboard$4.V:
  				if (e.ctrlKey) {
  					if (!this.curEditorData) {
  						mgrTip.showMsgTip("没有选中任何动态骨骼");
  						return;
  					}
  					if (!this.clipbordBoneData) {
  						mgrTip.showMsgTip("先使用ctrl+C拷贝碰撞信息和骨骼信息");
  						return;
  					}
  					if (this.curRouterIndex < 0) {
  						this.curEditorData.gBoneConfig = Tools.deepCopy(this.clipbordBoneData);
  						mgrTip.showMsgTip("粘贴到主体骨骼信息");
  						mgrDynamicBone.setDynamicConfig(this.curSelectedModelId, this.curEditorData);
  						this.refreshEditorPanel();
  						this.refresModelData();
  						return;
  					}
  					if (this.curChildIdx < 0) {
  						this.curEditorData.routers[this.curRouterIndex].config = Tools.deepCopy(this.clipbordBoneData);
  						mgrTip.showMsgTip("粘贴到router骨骼信息");
  						mgrDynamicBone.setDynamicConfig(this.curSelectedModelId, this.curEditorData);
  						this.refreshEditorPanel();
  						this.refresModelData();
  						return;
  					}
  					this.curEditorData.routers[this.curRouterIndex].children[this.curChildIdx].config = Tools.deepCopy(this.clipbordBoneData);
  					mgrTip.showMsgTip("粘贴到子节点骨骼信息");
  					mgrDynamicBone.setDynamicConfig(this.curSelectedModelId, this.curEditorData);
  					this.refreshEditorPanel();
  					this.refresModelData();
  				}
  				break;
  			case Keyboard$4.X:
  				if (e.ctrlKey) {
  					if (!this.curEditorData) {
  						mgrTip.showMsgTip("没有选中任何动态骨骼");
  						return;
  					}
  					if (!this.clipbordColliderData) {
  						mgrTip.showMsgTip("先使用ctrl+C拷贝碰撞信息和骨骼信息");
  						return;
  					}
  					this.curEditorData.gColliderConfig = Tools.deepCopy(this.clipbordColliderData);
  					mgrTip.showMsgTip("粘贴共享碰撞信息");
  					mgrDynamicBone.setDynamicConfig(this.curSelectedModelId, this.curEditorData);
  					this.refreshEditorPanel();
  					this.refresModelData();
  				}
  				break;
  			default:
  				break;
  		}
  	}
  	onClickModel(obj) {
  		let idx = obj.idx;
  		this.curSelectedModelIndex = idx;
  		let modelId = this.allRegEModelNames[idx] || this.allModelNames[idx];
  		this.__onClickModel(modelId);
  	}
  	__onClickModel(modelId) {
  		this.curSelectedModelId = modelId;
  		mgrTip.showMsgTip(`选中模型:${modelId}`);
  		this.curRouterIndex = -1;
  		this.curChildIdx = -1;
  		this.childrens = [];
  		this.listModels.numItems = this.listModels.numItems;
  		this.createModel(() => {
  			this.refresModelData();
  		});
  	}
  	refresModelData() {
  		let editorData = mgrDynamicBone.getDynamicConfig(this.curSelectedModelId);
  		this.curEditorData = editorData;
  		if (!editorData) {
  			this.buttonApplyDynamicBone.visible = true;
  			this.buttonRemoveDynamicBone.visible = false;
  			this.buttonAddDynamicBone.visible = false;
  			this.listRouters.numItems = 0;
  			this.listChilds.numItems = 0;
  			this.propList.numItems = 0;
  			this.colliderPropList.numItems = 0;
  		}
  		else {
  			this.buttonApplyDynamicBone.visible = false;
  			this.buttonRemoveDynamicBone.visible = true;
  			this.buttonAddDynamicBone.visible = true;
  			this.listRouters.numItems = editorData.routers.length;
  			this.useDynamicData(() => {
  				this.curEditorSingleData = editorData.gBoneConfig;
  				this.curEditorColliderData = editorData.gColliderConfig;
  				this.boneManager.setCurentEditorRouter("/", this.curSelectedModelId);
  				this.refreshEditorPanel();
  			});
  		}
  	}
  	onClickRouter(obj) {
  		let idx = obj.idx;
  		this.curRouterIndex = idx;
  		this.listRouters.numItems = this.listRouters.numItems;
  		this.curChildIdx = -1;
  		let root = this.boneManager.findChildByRouter(this.boneManager.owner, this.curEditorData.routers[this.curRouterIndex].router);
  		this.childrens = [];
  		while (root.getChildAt(0)) {
  			this.childrens.push(root.getChildAt(0));
  			root = root.getChildAt(0);
  		}
  		this.listChilds.numItems = this.childrens.length;
  		let config = this.curEditorData.routers[this.curRouterIndex].config;
  		if (!config) {
  			config = this.curEditorData.routers[this.curRouterIndex].config = {};
  		}
  		this.curEditorSingleData = config;
  		this.boneManager.setCurentEditorRouter(this.curEditorData.routers[this.curRouterIndex].router, this.curSelectedModelId);
  		this.refreshEditorPanel();
  	}
  	onClickChild(obj) {
  		let idx = obj.idx;
  		this.curChildIdx = idx;
  		this.listChilds.numItems = this.listChilds.numItems;
  		let child = this.childrens[idx];
  		let router = this.curEditorData.routers[this.curRouterIndex];
  		let childConfig = null;
  		for (let i = 0; i < router.children.length; i++) {
  			const element = router.children[i];
  			if (element.router.indexOf(child.name) >= 0) {
  				childConfig = element;
  				break;
  			}
  		}
  		if (!childConfig) {
  			let childRouter = "";
  			let recurive = (root) => {
  				if (router.router.indexOf(root.name) == -1) {
  					childRouter = root.name + "/" + childRouter;
  					recurive(root.parent);
  				}
  			};
  			recurive(child);
  			childConfig = {
  				router: childRouter,
  				config: {},
  			};
  			router.children.push(childConfig);
  		}
  		this.curEditorSingleData = childConfig.config;
  		this.boneManager.setCurentEditorRouter(router.router + childConfig.router, this.curSelectedModelId);
  		this.refreshEditorPanel();
  	}
  	onInputSearch() {
  		this.allRegEModelNames = [];
  		let regStr = this.inputSearchModel.text;
  		let regx = new RegExp(regStr);
  		for (let i = 0; i < this.allModelNames.length; i++) {
  			const modelName = this.allModelNames[i];
  			if (regx.test(modelName)) {
  				this.allRegEModelNames.push(modelName);
  			}
  		}
  		this.listModels.numItems = this.allRegEModelNames.length;
  	}
  	refreshEditorPanel() {
  		let propsList = [
  			{ name: `parm1`, desc: `一级:软 <------> 硬`, type: EditorType.slider, range: [0, 1] },
  			{ name: `displacementFactor`, desc: `二级:软 <------> 硬`, type: EditorType.slider, range: [0, 1] },
  			{ name: `maxDisplacement`, desc: `限制:小 <------> 大`, type: EditorType.slider, range: [0, 1] },
  			{ name: `radius`, desc: `碰撞半径`, type: EditorType.slider, range: [0, 0.2] },
  			{ name: `gravity`, desc: `重力`, type: EditorType.slider, range: [0, 1] },
  		];
  		this.editorObject.visible = true;
  		this.editorObject.setObject(propsList, this.boneManager, this.curEditorSingleData);
  		let propsColliderList = [
  			{ name: `c1s`, desc: `<---1级--->`, type: EditorType.slider, range: [0, 0.2] },
  			{ name: `c2s`, desc: `<---2级--->`, type: EditorType.slider, range: [0, 0.2] },
  			{ name: `c3s`, desc: `<---3级--->`, type: EditorType.slider, range: [0, 0.2] },
  			{ name: `c4s`, desc: `<---4级--->`, type: EditorType.slider, range: [0, 0.2] },
  			{ name: `c5s`, desc: `<---5级--->`, type: EditorType.slider, range: [0, 0.2] },
  			{ name: `c6s`, desc: `<---6级--->`, type: EditorType.slider, range: [0, 0.2] },
  		];
  		this.editorColliderObj.visible = true;
  		this.editorColliderObj.setObject(propsColliderList, this.boneManager, this.curEditorColliderData);
  	}
  	createModel(callback) {
  		this.model = this.linkModelAtBack(this.curSelectedModelId, this.modelRoot, this.modelRoot.name);
  		this.model.callIfLoaded(() => {
  			this.boneManager = this.model.addComponent(BoneManager);
  			callback && callback();
  		}, this);
  	}
  	initTouch() {
  		this.nodeOpt = new NodeOperate(this.resNode.displayObject, this.modelRoot, this.modelRoot);
  	}
  	useDynamicData(callback) {
  		this.boneManager.addDynamicConfig(this.curEditorData, this.curSelectedModelId);
  		this.boneManager.c1s = this.curEditorData.gColliderConfig.c1s;
  		this.boneManager.c2s = this.curEditorData.gColliderConfig.c2s;
  		this.boneManager.c3s = this.curEditorData.gColliderConfig.c3s;
  		this.boneManager.c4s = this.curEditorData.gColliderConfig.c4s;
  		this.boneManager.c5s = this.curEditorData.gColliderConfig.c5s;
  		this.boneManager.c6s = this.curEditorData.gColliderConfig.c6s;
  		callback && callback();
  	}
  	on_click_btnClose() {
  		this.close();
  	}
  	on_click_buttonApplyDynamicBone() {
  		let config = {
  			gBoneConfig: {
  				parm1: 0.15,
  				tansRatio: 1,
  				radius: 0.03,
  				displacementFactor: 0.5,
  				maxDisplacement: 0.1,
  				gravity: 0,
  			},
  			gColliderConfig: {
  				c1s: 0.05,
  				c2s: 0.05,
  				c3s: 0.05,
  				c4s: 0.05,
  				c5s: 0.05,
  				c6s: 0.05,
  			},
  			routers: [],
  		};
  		this.curEditorData = config;
  		mgrDynamicBone.setDynamicConfig(this.curSelectedModelId, this.curEditorData);
  		this.__onClickModel(this.curSelectedModelId);
  	}
  	on_click_buttonAddDynamicBone() {
  		let routers = [];
  		let routerMap = {};
  		for (let i = 0; i < this.curEditorData.routers.length; i++) {
  			const element = this.curEditorData.routers[i];
  			routers.push(element.router);
  			routerMap[element.router] = element;
  		}
  		let root = null;
  		for (let i = 0; i < this.model.resNode.numChildren; i++) {
  			let child = this.model.resNode.getChildAt(i);
  			if (child.name == `toufa` || child.name == `Bip001` || child.name == `beibu`) {
  				root = child;
  				break;
  			}
  		}
  		Director.openPanel("EditorBoneSearch", {
  			rootBone: root,
  			allSelectedRouters: routers,
  			callback: (routerList) => {
  				let newRouters = [];
  				for (let i = 0; i < routerList.length; i++) {
  					const element = routerList[i];
  					if (routerMap[element]) {
  						newRouters.push(routerMap[element]);
  					}
  					else {
  						newRouters.push({
  							router: element,
  							children: [],
  						});
  					}
  				}
  				this.curEditorData.routers = newRouters;
  				mgrDynamicBone.setDynamicConfig(this.curSelectedModelId, this.curEditorData);
  				this.refresModelData();
  			}
  		});
  	}
  	on_click_buttonRemoveDynamicBone() {
  		mgrDynamicBone.setDynamicConfig(this.curSelectedModelId, null);
  		this.boneManager.removeDynamicConfig(this.curSelectedModelId);
  		this.refresModelData();
  	}
  	on_click_listModels() {
  	}
  	on_click_listRouters() {
  	}
  	on_click_listChilds() {
  	}
  	on_click_propList() {
  	}
  	on_click_colliderPropList() {
  	}
  }
  EditorDynamicBoneElse.sourceName = "ui://debug/EditorDynamicBoneElse";

  class EditorHierarchyMenu extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "剧情编辑器 - 层级栏的菜单栏";
  		this.bOpenAndCloseAnim = false;
  		this.panelMaskAlpha = 0.1;
  		this.bMaskClose = true;
  	}
  	static open(menulist) {
  		Director.openPanel(`EditorHierarchyMenu`, {
  			menulist: menulist,
  		});
  	}
  	onLoaded() {
  		let localPos = this.globalToLocal(Laya.stage.mouseX, Laya.stage.mouseY);
  		this.resNode.x = localPos.x + this.width;
  		this.resNode.y = localPos.y + this.height;
  		this.menulist = this.context.menulist;
  		this.listMenu.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			obj.title = this.menulist[idx].name;
  		});
  		this.listMenu.numItems = this.menulist.length;
  		this.listMenu.on(fgui.Events.CLICK_ITEM, this, this.onClickMenu.bind(this));
  	}
  	dispose() {
  		super.dispose();
  	}
  	onClickMenu(obj) {
  		let idx = obj.idx;
  		this.menulist[idx].callback();
  		this.close();
  	}
  }
  EditorHierarchyMenu.sourceName = "ui://debug/EditorHierarchyMenu";

  const FBXNAME = "shenti";
  class EditorHumanBone extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "人形骨骼体型编辑器";
  		this.animNames = [];
  	}
  	getPreLoadResoure() {
  		return [
  			{ url: "res/cfg/face/lian.json", type: RES_TYPE.JSON },
  			{ url: "res/cfg/face/lian_test.json", type: RES_TYPE.JSON }
  		];
  	}
  	onLoaded() {
  		this.resetResolution(1200, 1024);
  		this.allBones = [];
  		this.allRepBones = [];
  		HumanBone.allHumanBoneScaleInfo[FBXNAME] = HumanBone.allHumanBoneScaleInfo[FBXNAME] || {};
  		for (let i = 0; i < mgrRole.bodyIdList.length; i++) {
  			const index = mgrRole.bodyIdList[i];
  			HumanBone.allHumanBoneScaleInfo[FBXNAME][index] = HumanBone.allHumanBoneScaleInfo[FBXNAME][index] || {
  				boneMap: {},
  				wholeRatio: 1,
  			};
  		}
  		this.listIndexs.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			obj.text = `${mgrRole.bodyIdList[idx]}:${mgrRole.bodyNameList[idx]}`;
  			obj.titleColor = idx == this.curSelectIndex ? "#00ff00" : `#ffffff`;
  		});
  		this.listIndexs.numItems = mgrRole.bodyIdList.length;
  		this.listIndexs.on(fgui.Events.CLICK_ITEM, this, this.onClickIndex.bind(this));
  		this.listBones.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			if (this.allRepBones.length > 0) {
  				obj.text = this.allRepBones[idx].name;
  			}
  			else {
  				obj.text = this.allBones[idx].name;
  			}
  			if (this.curSelectBone) {
  				obj.titleColor = obj.text == this.curSelectBone.name ? "#00ff00" : `#ffffff`;
  			}
  		});
  		this.listBones.numItems = 0;
  		this.listBones.on(fgui.Events.CLICK_ITEM, this, this.onClickBone.bind(this));
  		this.listAnims.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj[`idx`] = idx;
  			obj.title = this.animNames[idx];
  		});
  		this.listAnims.numItems = this.animNames.length;
  		this.listAnims.on(fgui.Events.CLICK_ITEM, this, (obj) => {
  			let idx = obj[`idx`];
  			this.scaleAvatar.playAnimation(this.animNames[idx]);
  			this.baseAvatar.playAnimation(this.animNames[idx]);
  		});
  		this.editorObject = new PropEditorGroup(this.proList);
  		this.editorObject.visible = false;
  		this.editorObject.on(PROPE_DITOR_MSG.DATA_CHANGED, this, () => {
  			let nodeNames = [
  				`Bip001`,
  				`Bip001 Pelvis`,
  				`Bip001 L Thigh`,
  				`Bip001 L Calf`,
  				`Bip001 L Foot`,
  				`Bip001 L Toe0`,
  			];
  			let weights = {};
  			for (let i = 0; i < nodeNames.length; i++) {
  				const nodeName = nodeNames[i];
  				if (nodeName == "Bip001") {
  					weights[nodeName] = HumanBone.allHumanBoneConfig[FBXNAME].rootPos.y;
  				}
  				else {
  					weights[nodeName] = HumanBone.allHumanBoneConfig[FBXNAME].rootPos.y;
  					for (let __i = 1; __i < i; __i++) {
  						weights[nodeName] -= HumanBone.allHumanBoneConfig[FBXNAME].boneMap[nodeNames[__i]].x;
  					}
  					weights[nodeName] -= HumanBone.allHumanBoneConfig[FBXNAME].boneMap[nodeName].x;
  				}
  			}
  			Tools.forEachMap(weights, (k, v) => {
  				weights[k] = v / HumanBone.allHumanBoneConfig[FBXNAME].rootPos.y;
  			});
  			let wholeRatio = 1;
  			for (let i = 0; i < nodeNames.length; i++) {
  				const nodeName = nodeNames[i];
  				let info = HumanBone.allHumanBoneScaleInfo[FBXNAME][mgrRole.bodyIdList[this.curSelectIndex]].boneMap[nodeName];
  				if (info) {
  					wholeRatio += weights[nodeName] * (info.scale.x - 1);
  				}
  			}
  			HumanBone.allHumanBoneScaleInfo[FBXNAME][mgrRole.bodyIdList[this.curSelectIndex]].wholeRatio = wholeRatio;
  			if (!GameRemoteRouter.instance) {
  				Global.sendMsg(BASE_MSG.UI_SHOW_TIP, "未链接存档服务器,尝试重新连接!");
  			}
  			else {
  				GameRemoteRouter.instance.sendMsgToServer({
  					route: "keepInFile",
  					data: {
  						filePath: `res/cfg/humanScale.txt`,
  						data: HumanBone.allHumanBoneScaleInfo,
  					},
  				});
  			}
  		});
  		this.inputSearchBone.on(Laya.Event.INPUT, this, this.onInputSearchBibe.bind(this));
  		let bTouch = false;
  		UiHelper.registerTouchEvent(this, (e) => {
  			if (e.bBegin) {
  				bTouch = true;
  			}
  			if (e.bEnd || e.bCancel) {
  				bTouch = false;
  			}
  			if (!bTouch)
  				return;
  			this.baseAvatar && (this.baseAvatar.transform.localRotationEulerY += e.deltaX / 2);
  			this.scaleAvatar && (this.scaleAvatar.transform.localRotationEulerY += e.deltaX / 2);
  		});
  	}
  	dispose() {
  		super.dispose();
  	}
  	onInputSearchBibe() {
  		this.allRepBones = [];
  		let regStr = this.inputSearchBone.text;
  		let regx = new RegExp(regStr);
  		for (let i = 0; i < this.allBones.length; i++) {
  			const menu = this.allBones[i];
  			if (regx.test(menu.name)) {
  				this.allRepBones.push(menu);
  			}
  		}
  		this.listBones.numItems = this.allRepBones.length;
  	}
  	onClickIndex(obj) {
  		let idx = obj[`idx`];
  		this.curSelectIndex = idx;
  		this.listIndexs.numItems = mgrRole.bodyIdList.length;
  		if (!this.baseAvatar) {
  			this.baseAvatar = new Master;
  			this.baseAvatar.commanding();
  			this.linkModelAtBack(this.baseAvatar);
  			this.baseAvatar.transform.localPositionX = -0.3;
  			this.camera.getComponent(CameraFollow).fov = 45;
  			this.camera.getComponent(CameraFollow).distance = 6;
  			this.camera.getComponent(CameraFollow).offset.y = 1.2;
  		}
  		if (!this.scaleAvatar) {
  			this.scaleAvatar = new Master;
  			this.scaleAvatar.commanding();
  			this.linkModelAtBack(this.scaleAvatar);
  			this.scaleAvatar.transform.localPositionX = 0.3;
  		}
  		this.baseAvatar.registerAllLoadEndCallback(() => {
  			this.baseAvatar.baseBodyAnimator[`humanScaleInfo`] = null;
  			this.scaleAvatar.registerAllLoadEndCallback(() => {
  				this.allBones = this.baseAvatar.originMainBones;
  				this.listBones.numItems = this.allBones.length;
  				this.scaleAvatar.baseBodyAnimator[`humanScaleInfo`] = HumanBone.allHumanBoneScaleInfo[FBXNAME][mgrRole.bodyIdList[this.curSelectIndex]];
  			});
  		});
  	}
  	onClickBone(obj) {
  		let idx = obj[`idx`];
  		this.curSelectBone = this.allRepBones.length > 0 ? this.allRepBones[idx] : this.allBones[idx];
  		this.listBones.numItems = this.allRepBones.length > 0 ? this.allRepBones.length : this.allBones.length;
  		this.refreshEditorPanel();
  	}
  	refreshEditorPanel() {
  		if (HumanBone.allHumanBoneScaleInfo[FBXNAME][mgrRole.bodyIdList[this.curSelectIndex]].boneMap[this.curSelectBone.name] == null) {
  			HumanBone.allHumanBoneScaleInfo[FBXNAME][mgrRole.bodyIdList[this.curSelectIndex]].boneMap[this.curSelectBone.name] = {
  				scale: { x: 1, y: 1, z: 1 },
  				pos: { x: 0, y: 0, z: 0 },
  				rotation: { x: 0, y: 0, z: 0, w: 1 },
  			};
  		}
  		let propsList = [
  			{ name: `scaleX`, desc: `x轴缩放`, type: EditorType.num, range: [0, 2] },
  			{ name: `scaleY`, desc: `y轴缩放`, type: EditorType.num, range: [0, 2] },
  			{ name: `scaleZ`, desc: `z轴缩放`, type: EditorType.num, range: [0, 2] },
  			{ name: `posX`, desc: `x轴位移`, type: EditorType.num, range: [0, 2] },
  			{ name: `posY`, desc: `y轴位移`, type: EditorType.num, range: [0, 2] },
  			{ name: `posZ`, desc: `z轴位移`, type: EditorType.num, range: [0, 2] },
  			{ name: `rotationX`, desc: `旋转x`, type: EditorType.num, range: [0, 2] },
  			{ name: `rotationY`, desc: `旋转y`, type: EditorType.num, range: [0, 2] },
  			{ name: `rotationZ`, desc: `旋转z`, type: EditorType.num, range: [0, 2] },
  			{ name: `rotationW`, desc: `旋转w`, type: EditorType.num, range: [0, 2] },
  		];
  		let data = new OperateData(HumanBone.allHumanBoneScaleInfo[FBXNAME][mgrRole.bodyIdList[this.curSelectIndex]].boneMap, this.curSelectBone, () => {
  			return this.comScaleChild.bClicked;
  		});
  		this.editorObject.visible = true;
  		this.editorObject.setObject(propsList, data, data);
  	}
  	on_click_buttonClose() {
  		PanelWarpWithoutAnim.warp(`PanelMain`);
  	}
  	on_click_buttonAdd() {
  	}
  	on_click_buttonRemove() {
  	}
  	on_click_buttonReset() {
  		if (this.curSelectIndex == null || this.curSelectIndex < 0)
  			return;
  		if (!HumanBone.allHumanBoneScaleInfo[FBXNAME])
  			return;
  		if (!HumanBone.allHumanBoneScaleInfo[FBXNAME][mgrRole.bodyIdList[this.curSelectIndex]])
  			return;
  		HumanBone.allHumanBoneScaleInfo[FBXNAME][mgrRole.bodyIdList[this.curSelectIndex]] = {
  			boneMap: {},
  			wholeRatio: 1,
  		};
  		this.onClickIndex({ idx: this.curSelectIndex });
  	}
  }
  EditorHumanBone.sourceName = "ui://debug/EditorHumanBone";
  class OperateData {
  	constructor(data, bone, isChildScale) {
  		this.data = data;
  		this.bone = bone;
  		this.isChildScale = isChildScale;
  		this.unifyData = {};
  		let root = null;
  		let curBone = this.bone;
  		while (true) {
  			if (!curBone.parent || curBone.name == "Bip001") {
  				root = curBone;
  				break;
  			}
  			else {
  				curBone = curBone.parent;
  			}
  		}
  		let recurveAllBone = (bone, scaleX = 1, scaleY = 1, scaleZ = 1) => {
  			if (!this.data[bone.name]) {
  				this.data[bone.name] = {
  					scale: { x: 1, y: 1, z: 1 },
  					pos: { x: 0, y: 0, z: 0 },
  					rotation: { x: 0, y: 0, z: 0, w: 1 },
  				};
  			}
  			this.unifyData[bone.name] = {
  				x: this.data[bone.name].scale.x * scaleX,
  				y: this.data[bone.name].scale.y * scaleY,
  				z: this.data[bone.name].scale.z * scaleZ,
  			};
  			for (let i = 0; i < bone.numChildren; i++) {
  				let child = bone.getChildAt(i);
  				recurveAllBone(child, this.unifyData[bone.name].x, this.unifyData[bone.name].y, this.unifyData[bone.name].z);
  			}
  		};
  		recurveAllBone(root);
  	}
  	get scaleX() {
  		return this.getData(`scale.x`);
  	}
  	set scaleX(value) {
  		this.setData(`scale.x`, value);
  	}
  	get scaleY() {
  		return this.getData(`scale.y`);
  	}
  	set scaleY(value) {
  		this.setData(`scale.y`, value);
  	}
  	get scaleZ() {
  		return this.getData(`scale.z`);
  	}
  	set scaleZ(value) {
  		this.setData(`scale.z`, value);
  	}
  	get posX() {
  		return this.getData(`pos.x`);
  	}
  	set posX(value) {
  		this.setData(`pos.x`, value);
  	}
  	get posY() {
  		return this.getData(`pos.y`);
  	}
  	set posY(value) {
  		this.setData(`pos.y`, value);
  	}
  	get posZ() {
  		return this.getData(`pos.z`);
  	}
  	set posZ(value) {
  		this.setData(`pos.z`, value);
  	}
  	get rotationX() {
  		return this.getData(`rotation.x`);
  	}
  	set rotationX(value) {
  		this.setData(`rotation.x`, value);
  	}
  	get rotationY() {
  		return this.getData(`rotation.y`);
  	}
  	set rotationY(value) {
  		this.setData(`rotation.y`, value);
  	}
  	get rotationZ() {
  		return this.getData(`rotation.z`);
  	}
  	set rotationZ(value) {
  		this.setData(`rotation.z`, value);
  	}
  	get rotationW() {
  		return this.getData(`rotation.w`);
  	}
  	set rotationW(value) {
  		this.setData(`rotation.w`, value);
  	}
  	setData(parmName, value) {
  		let strs = parmName.split(".");
  		let realName = strs[1];
  		if (strs[0] == "scale") {
  			let factor = value / this.unifyData[this.bone.name][realName];
  			this.unifyData[this.bone.name][realName] = value;
  			this.data[this.bone.name].scale[realName] = value / this.unifyData[this.bone.parent.name][realName];
  			if (!this.isChildScale()) {
  				let recurveAllBone = (bone, unifyScale) => {
  					for (let i = 0; i < bone.numChildren; i++) {
  						let child = bone.getChildAt(i);
  						this.data[child.name].scale[realName] = this.unifyData[child.name][realName] / unifyScale;
  						recurveAllBone(child, this.unifyData[child.name][realName]);
  					}
  				};
  				recurveAllBone(this.bone, this.unifyData[this.bone.name][realName]);
  			}
  			else {
  				let recurveAllBone = (bone, unifyScale, factor) => {
  					for (let i = 0; i < bone.numChildren; i++) {
  						let child = bone.getChildAt(i);
  						this.unifyData[child.name][realName] *= factor;
  						this.data[child.name].scale[realName] = this.unifyData[child.name][realName] / unifyScale;
  						recurveAllBone(child, this.unifyData[child.name][realName], factor);
  					}
  				};
  				recurveAllBone(this.bone, this.unifyData[this.bone.name][realName], factor);
  			}
  		}
  		else if (strs[0] == "pos") {
  			this.data[this.bone.name].pos[realName] = value;
  		}
  		else if (strs[0] == "rotation") {
  			this.data[this.bone.name].rotation[realName] = value;
  		}
  	}
  	getData(parmName) {
  		let strs = parmName.split(".");
  		if (/scale/.test(parmName)) {
  			return this.unifyData[this.bone.name][strs[1]];
  		}
  		else if (/pos/.test(parmName)) {
  			return this.data[this.bone.name].pos[strs[1]];
  		}
  		else if (/rotation/.test(parmName)) {
  			return this.data[this.bone.name].rotation[strs[1]];
  		}
  	}
  }

  class EditorModelMaterial extends DebugBase {
  	constructor() {
  		super(...arguments);
  		this.originAllModel = [];
  		this.allMatTypes = [`CartoonHairMaterial`, `CartoonFaceMaterial`, `CartoonBodyMaterial`, `CartoonClothMaterial`, `BagMaterial`, `SkinMaterial`];
  		this.modelList = [];
  	}
  	onLoaded() {
  		UITools.widgetLeftTopMC(this.btnClose);
  		UITools.widgetLeftTopMC(this.matTypeList);
  		UITools.widgetLeftTopMC(this.paramList);
  		UITools.widgetRightTopMC(this.comLeft);
  		UITools.widgetLeftTopMC(this.graphBg);
  		this.createScene3DBack(0, 25);
  		KeyboardDebugTool.remove(this);
  		this.camera.transform.localPosition = new Laya.Vector3(0, 0, 8);
  		this.camera.transform.localRotationEuler = new Laya.Vector3(0, 0, 0);
  		this.camera.getComponent(CameraFollow).destroy();
  		this.input.on(Laya.Event.INPUT, this, this.onInput);
  		let rotation = mgrMaterial.lightRotation || new Laya.Vector3(-10, -11, 25);
  		this.lightBack.transform.localRotationEuler = new Laya.Vector3(rotation.x, rotation.y, rotation.z);
  		let color = mgrMaterial.lightColor || new Laya.Vector3(1, 1, 1);
  		this.lightBack.color = new Laya.Vector3(color.x, color.y, color.z);
  		this.rootNode = this.scene3DBack.addChild(new Laya.Sprite3D);
  		this.roleRoot = this.rootNode.addChild(new Laya.Sprite3D);
  		this.roleRoot.transform.localPositionY = -1;
  		Tools.forEachMap(db.get_model_db_map(), (id, modelDb) => {
  			this.originAllModel.push(id);
  		});
  		this.originAllModel.sort();
  		this.allModels = this.originAllModel.slice();
  		this.modelScroll.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			let modelDb = db.get_model_db(this.allModels[idx]);
  			obj.text = modelDb.id;
  			obj["idx"] = idx;
  			let hasInfo = !!mgrMaterial.materialInfos[modelDb.id];
  			obj.titleColor = (hasInfo ? `#00ff00` : `#ffffff`);
  		});
  		this.modelScroll.on(fgui.Events.CLICK_ITEM, this, this.onClickModel);
  		this.renderScroll.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj.text = this.allRender[idx].node.name;
  			obj["idx"] = idx;
  			let hasInfo = !!(mgrMaterial.materialInfos[this._modelId] && mgrMaterial.materialInfos[this._modelId][this.allRender[idx].router]);
  			obj.titleColor = (hasInfo ? `#00ff00` : `#ffffff`);
  		});
  		this.renderScroll.on(fgui.Events.CLICK_ITEM, this, this.onClickRender);
  		this.matScroll.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj.text = this.allMat[idx];
  			obj["idx"] = idx;
  			if (this._model) {
  				let renderInfo = this.allRender[this._renderIndex];
  				let hasInfo = mgrMaterial.materialInfos[this._modelId] && mgrMaterial.materialInfos[this._modelId][renderInfo.router] && mgrMaterial.materialInfos[this._modelId][renderInfo.router][idx];
  				obj.titleColor = (hasInfo ? `#00ff00` : `#ffffff`);
  			}
  		});
  		this.matScroll.on(fgui.Events.CLICK_ITEM, this, this.onClickMat);
  		this.matTypeList.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj.text = this.allMatTypes[idx];
  			obj[`idx`] = idx;
  			obj.titleColor = (obj.text == this.curSeleclMatType ? `#00ff00` : `#ffffff`);
  		});
  		this.matTypeList.on(fgui.Events.CLICK_ITEM, this, this.onClickMatType);
  		this.editorObject = new PropEditorGroup(this.paramList);
  		this.editorObject.visible = false;
  		this.shadowConfigObj = new PropEditorGroup(this.shadowConfigScroll);
  		this.shadowConfigObj.visible = false;
  		this.lightConfigObj = new PropEditorGroup(this.lightConfigScroll);
  		this.lightConfigObj.setObject([
  			{
  				name: `shadowMode`, desc: "阴影质量", type: EditorType.option, options: [
  					{ desc: "无阴影", value: Laya.ShadowMode.None },
  					{ desc: "硬阴影", value: Laya.ShadowMode.Hard },
  					{ desc: "中阴影", value: Laya.ShadowMode.SoftLow },
  					{ desc: "高阴影", value: Laya.ShadowMode.SoftHigh },
  				],
  			},
  			{ name: `shadowDistance`, desc: "光照距离", type: EditorType.slider, range: [0, 20] },
  			{ name: `shadowNearPlane`, desc: "近平面", type: EditorType.slider, range: [0, 20] },
  			{
  				name: `shadowResolution`, desc: "分辨率", type: EditorType.option, options: [
  					{ desc: "低质量", value: 1024 },
  					{ desc: "中质量", value: 2048 },
  					{ desc: "高质量", value: 4096 },
  				],
  			},
  			{ name: `shadowStrength`, desc: "阴影强度", type: EditorType.slider, range: [0, 1] },
  			{ name: `shadowDepthBias`, desc: "摩尔纹参数", type: EditorType.slider, range: [-5, 5, 4] },
  		], this.lightBack, mgrMaterial.globalShadowConfig);
  		this.modelScroll.numItems = this.allModels.length;
  		this.renderScroll.numItems = 0;
  		this.matScroll.numItems = 0;
  		let lightEditor = new PropEditorGroup(this.lightColorScrool);
  		lightEditor.setObject([{ name: `color`, desc: "全局光颜色", type: EditorType.color }], this.lightBack, mgrMaterial.lightColor);
  		this.initTouch();
  		Global.registerListeners(this, {
  			[BASE_MSG.SYS_KEY_DOWN]: (e) => {
  				let Keyboard = Laya.Keyboard;
  				let keyCode = e.ctrlKey ? Keyboard.CONTROL * e.keyCode : e.keyCode;
  				let quaternion = new Laya.Quaternion;
  				switch (keyCode) {
  					case Keyboard.LEFT:
  						this.lightBack.transform.rotate(new Laya.Vector3(0, 3, 0), false, false);
  						break;
  					case Keyboard.RIGHT:
  						this.lightBack.transform.rotate(new Laya.Vector3(0, -3, 0), false, false);
  						break;
  					case Keyboard.UP:
  						this.lightBack.transform.rotate(new Laya.Vector3(3, 0, 0), false, false);
  						break;
  					case Keyboard.DOWN:
  						this.lightBack.transform.rotate(new Laya.Vector3(-3, 0, 0), false, false);
  						break;
  					case Keyboard.HOME:
  						this.lightBack.transform.localRotationEuler = new Laya.Vector3;
  						break;
  					case Keyboard.NUMBER_8:
  						break;
  					case Keyboard.NUMBER_2:
  						break;
  					case Keyboard.NUMBER_1:
  						break;
  					case Keyboard.NUMBER_3:
  						break;
  					case Keyboard.CONTROL * Keyboard.C:
  						if (!this._modelId)
  							return;
  						if (this._renderIndex == null)
  							return;
  						if (!this.bFocus)
  							return;
  						if (this._matIndex == null)
  							return;
  						this.clipboard = this.allRender[this._renderIndex].renderer.sharedMaterials[this._matIndex];
  						if (!this.clipboard.getCanEditorParamList) {
  							this.clipboard = null;
  							mgrTip.showMsgTip("没有自定义材质");
  							return;
  						}
  						mgrTip.showMsgTip("复制成功!");
  						break;
  					case Keyboard.CONTROL * Keyboard.V:
  						if (!this._modelId)
  							return;
  						if (this._renderIndex == null)
  							return;
  						if (!this.clipboard)
  							return;
  						if (this._matIndex == null)
  							return;
  						if (!this.bFocus)
  							return;
  						mgrTip.showMsgTip("粘贴成功!");
  						mgrMaterial.setEditedMaterialData(this._modelId, this.allRender[this._renderIndex].router, this._matIndex, this.clipboard);
  						this.onSelectMat(this._matIndex);
  						break;
  					case Keyboard.CONTROL * Keyboard.NUMBER_1:
  						let rotation = this.lightBack.transform.localRotationEuler;
  						mgrMaterial.lightRotation = rotation;
  						mgrMaterial.lightColor = this.lightBack.color;
  						let pos = this.rootNode.transform.localPosition;
  						mgrMaterial.editorConfig.camera[this._modelId] = [pos.x, pos.y, pos.z, this.roleRoot.transform.localRotationEulerY];
  						mgrMaterial.saveToLocal();
  						break;
  					case Laya.Keyboard.NUMPAD_8:
  						this.lightBack.transform.localRotationEulerX -= 1;
  						break;
  					case Laya.Keyboard.NUMPAD_2:
  						this.lightBack.transform.localRotationEulerX += 1;
  						break;
  					case Laya.Keyboard.NUMPAD_4:
  						this.lightBack.transform.localRotationEulerY -= 1;
  						break;
  					case Laya.Keyboard.NUMPAD_6:
  						this.lightBack.transform.localRotationEulerY += 1;
  						break;
  					case Laya.Keyboard.ESCAPE:
  						for (let i = 0; i < this.modelList.length; i++) {
  							Global.poolManager.put(this.modelList[i]);
  						}
  						this.modelList.length = 0;
  						this._model = null;
  						this._modelId = null;
  						this.renderScroll.numItems = 0;
  						this.matScroll.numItems = 0;
  						this.editorObject.visible = false;
  						this.matTypeList.numItems = 0;
  						break;
  				}
  			}
  		});
  	}
  	dispose() {
  		if (this.nodeOpt)
  			this.nodeOpt.dispose();
  		super.dispose();
  	}
  	initTouch() {
  		this.nodeOpt = new NodeOperate(this.resNode.displayObject, this.roleRoot, this.roleRoot);
  	}
  	onClickModel(obj) {
  		let idx = obj["idx"];
  		this._model = null;
  		for (let i = 0; i < this.modelList.length; i++) {
  			if (this.modelList[i].modelId == this.allModels[idx]) {
  				this._model = this.modelList[i];
  				break;
  			}
  		}
  		let modelId = this.allModels[idx];
  		this._modelId = modelId;
  		if (!this._model) {
  			let model = Global.poolManager.get(Model, this.allModels[idx]);
  			this._model = model;
  			this.roleRoot.addChild(model);
  			model.callIfLoaded(() => {
  				if (this.destroyed)
  					return;
  				if (model.destroyed)
  					return;
  				mgrMaterial.useEditedMaterial(this._model);
  			}, this);
  		}
  		this.renderScroll.numItems = 0;
  		this.matScroll.numItems = 0;
  		this._renderIndex = null;
  		this._matIndex = null;
  		this._model.callIfLoaded(() => {
  			this.refreshAllSkin(this._model);
  		}, this);
  		let camInfo = mgrMaterial.editorConfig.camera[this._modelId];
  		if (camInfo) {
  			this.rootNode.transform.localPosition.setValue(camInfo[0], camInfo[1], camInfo[2]);
  			this.rootNode.transform.localPosition = this.rootNode.transform.localPosition;
  			this.roleRoot.transform.localRotationEulerY = camInfo[3];
  		}
  		else {
  			this.rootNode.transform.localPosition.setValue(0, 0, 0);
  			this.rootNode.transform.localPosition = this.rootNode.transform.localPosition;
  			this.roleRoot.transform.localRotationEulerY = 0;
  		}
  		this.modelList.push(this._model);
  		this.shadowConfigObj.visible = false;
  	}
  	onClickRender(obj) {
  		let idx = obj["idx"];
  		this._matIndex = null;
  		this.onSelectRender(idx);
  	}
  	onClickMat(obj) {
  		let idx = obj["idx"];
  		this.onSelectMat(idx);
  	}
  	onClickMatType(obj) {
  		let idx = obj["idx"];
  		this.selectMatType(idx);
  	}
  	refreshAllSkin(model) {
  		this.allRender = Tools.findAllRenderers(model);
  		this.renderScroll.numItems = this.allRender.length;
  	}
  	onSelectRender(idx) {
  		this._renderIndex = idx;
  		let render = this.allRender[idx].renderer;
  		let mats = render.sharedMaterials;
  		let matsName = [];
  		for (let i = 0; i < mats.length; i++) {
  			matsName.push(mats[i].name);
  		}
  		this.allMat = matsName;
  		this.matScroll.numItems = matsName.length;
  		if (!mgrMaterial.materialInfos[this._model.modelId]) {
  			mgrMaterial.materialInfos[this._model.modelId] = {};
  		}
  		if (!mgrMaterial.materialInfos[this._model.modelId][this.allRender[idx].router]) {
  			mgrMaterial.materialInfos[this._model.modelId][this.allRender[idx].router] = {
  				matInfos: {},
  				castShadow: false,
  				receiveShadow: false,
  			};
  			render.castShadow = false;
  			render.receiveShadow = false;
  		}
  		this.shadowConfigObj.visible = true;
  		this.shadowConfigObj.setObject([
  			{ name: `castShadow`, desc: "castShadow", type: EditorType.option, options: [{ desc: "true", value: true }, { desc: "false", value: false }] },
  			{ name: `receiveShadow`, desc: "receiveShadow", type: EditorType.option, options: [{ desc: "true", value: true }, { desc: "false", value: false }] }
  		], render, mgrMaterial.materialInfos[this._model.modelId][this.allRender[idx].router]);
  	}
  	onSelectMat(idx) {
  		this._matIndex = idx;
  		let renderInfo = this.allRender[this._renderIndex];
  		let modelId = this._modelId;
  		let materialData = mgrMaterial.getEditedMaterialData(modelId, renderInfo.router, idx);
  		if (materialData) {
  			this.selectMatType(this.allMatTypes.indexOf(materialData.matName));
  		}
  		else {
  			this.editorObject.visible = false;
  			this.curSeleclMatType = null;
  		}
  		this.matTypeList.numItems = this.allMatTypes.length;
  	}
  	selectMatType(idx) {
  		this.curSeleclMatType = this.allMatTypes[idx];
  		this.matTypeList.numItems = this.allMatTypes.length;
  		let renderInfo = this.allRender[this._renderIndex];
  		let modelId = this._modelId;
  		let material = mgrMaterial.__useEditedMaterial(renderInfo.renderer, this._model, this._model.modelId, renderInfo.router)[this._matIndex];
  		if (material.constructor.name == this.curSeleclMatType) {
  		}
  		else {
  			material = mgrMaterial.useMaterialByClass(mgrMaterial.shaderName2Class[this.curSeleclMatType], this._model, this._renderIndex, this._matIndex, {
  				[`albedoTexture`]: true,
  			}, {}, {})[0];
  			let node = Tools.findNode(`face_dir`, this._model);
  			if (node && this.curSeleclMatType == `CartoonFaceMaterial`) {
  				Timer.callLoopFrame(1, () => {
  					const mat = material;
  					let forward = new Laya.Vector3;
  					node.transform.getRight(forward);
  					Laya.Vector3.scale(forward, -1, forward);
  					mat.lightMapForward = forward;
  					let right = new Laya.Vector3;
  					node.transform.getUp(right);
  					Laya.Vector3.scale(right, -1, right);
  					mat.lightMapRight = right;
  				}, this);
  			}
  			mgrMaterial.setEditedMaterialData(this._modelId, this.allRender[this._renderIndex].router, this._matIndex, material);
  		}
  		let data = mgrMaterial.getEditedMaterialData(this._modelId, this.allRender[this._renderIndex].router, this._matIndex);
  		this.editorObject.visible = true;
  		this.editorObject.setObject(material.getCanEditorParamList(), material, data.param);
  	}
  	onInput() {
  		let newModels = [];
  		let text = this.input.text;
  		if (text) {
  			for (let i = 0; i < this.originAllModel.length; i++) {
  				if (~this.originAllModel[i].indexOf(text)) {
  					newModels.push(this.originAllModel[i]);
  				}
  			}
  			this.allModels = newModels;
  		}
  		else {
  			this.allModels = this.originAllModel.slice();
  		}
  		this.modelScroll.numItems = this.allModels.length;
  	}
  	on_click_btnClose() {
  		this.close();
  	}
  }
  EditorModelMaterial.sourceName = "ui://debug/EditorModelMaterial";

  class EditorNumberInput extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "数字输入";
  		this.bMaskClose = false;
  	}
  	static open(inputCallback) {
  		Director.openPanel(`EditorNumberInput`, {
  			inputCallback: inputCallback,
  		});
  	}
  	onLoaded() {
  		Global.registerListeners(this, {
  			[BASE_MSG.SYS_KEY_DOWN]: this.onMsgKeyDown.bind(this)
  		});
  		this.input.requestFocus();
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgKeyDown(e) {
  		switch (e.keyCode) {
  			case Laya.Keyboard.ENTER:
  				if (/[^\.0-9]/.test(this.input.text) || this.input.text.length == 0) {
  					mgrTip.showMsgTip("输入非法字符");
  					return;
  				}
  				this.context.inputCallback && this.context.inputCallback(parseFloat(this.input.text));
  				this.close();
  				break;
  			default:
  				break;
  		}
  	}
  }
  EditorNumberInput.sourceName = "ui://debug/EditorNumberInput";

  class EditorSelectorColor extends DebugBase {
  	constructor() {
  		super(...arguments);
  		this.bShowMask = false;
  	}
  	onLoaded() {
  		this.createColors();
  		this.__fillSideColor();
  		this.mainColor = this.__getSideColorByPos(0, 0);
  		this.curColor = Tools.toHexColor(this.mainColor);
  		this.__fillMainColor();
  		this.__fillCurColor();
  		this.registerTouch();
  		if (this.context.value) {
  			this.colorText.text = this.context.value;
  		}
  		this.colorText.on(Laya.Event.BLUR, this, () => {
  			let layacolor = Tools.toLayaColor(this.colorText.text);
  			if (!layacolor) {
  				mgrTip.showMsgTip("输入的颜色不合规");
  				return;
  			}
  			this.context.onChange(this.colorText.text);
  		});
  	}
  	createColors() {
  		this.spriteMain = new Laya.Sprite();
  		this.resNode.displayObject.addChild(this.spriteMain);
  		this.spriteMain.size(200, 200);
  		this.spriteMain.pos(10, UIRoot.canvasHeight - 260, true);
  		this.spriteSide = new Laya.Sprite();
  		this.resNode.displayObject.addChild(this.spriteSide);
  		this.spriteSide.size(40, 200);
  		this.spriteSide.pos(220, UIRoot.canvasHeight - 260, true);
  		this.spriteColor = new Laya.Sprite();
  		this.resNode.displayObject.addChild(this.spriteColor);
  		this.spriteColor.size(30, 30);
  		this.spriteColor.pos(30, UIRoot.canvasHeight - 40, true);
  	}
  	registerTouch() {
  		this.spriteSide.on(Laya.Event.CLICK, this, (e) => {
  			e.stopPropagation();
  			let localPoint = this.spriteSide.globalToLocal(new Laya.Point(Laya.stage.mouseX, Laya.stage.mouseY));
  			this.mainColor = this.__getSideColorByPos(localPoint.x, localPoint.y);
  			this.__fillMainColor();
  		});
  		let bTouched = false;
  		UiHelper.registerTouchEvent(this.spriteMain, (e) => {
  			if (e.bBegin) {
  				bTouched = true;
  				this.onSelectColor();
  			}
  			if ((e.bEnd || e.bCancel) && bTouched) {
  				bTouched = false;
  				this.onSelectColor();
  			}
  			if (e.bMove && bTouched) {
  				this.onSelectColor();
  			}
  		});
  	}
  	onSelectColor() {
  		let localPoint = this.spriteMain.globalToLocal(new Laya.Point(Laya.stage.mouseX, Laya.stage.mouseY));
  		this.curColor = this.__getMainColorByPos(localPoint.x, localPoint.y);
  		this.__fillCurColor();
  		this.context.onChange && this.context.onChange(this.curColor);
  	}
  	__fillSideColor() {
  		this.spriteSide.graphics.clear(true);
  		for (let x = 0; x <= this.spriteSide.width; x++) {
  			for (let y = 0; y <= this.spriteSide.height; y++) {
  				let color = this.__getSideColorByPos(x, y);
  				let hexColor = Tools.toHexColor(color);
  				this.spriteSide.graphics.drawRect(x, y, 1, 1, hexColor);
  			}
  		}
  	}
  	__fillMainColor() {
  		this.spriteMain.graphics.clear(true);
  		for (let x = 0; x <= this.spriteMain.width; x++) {
  			for (let y = 0; y <= this.spriteMain.height; y++) {
  				let hexColor = this.__getMainColorByPos(x, y);
  				this.spriteMain.graphics.drawRect(x, y, 1, 1, hexColor);
  			}
  		}
  	}
  	__fillCurColor() {
  		this.colorText.text = this.curColor;
  		this.spriteColor.graphics.clear(true);
  		this.spriteColor.graphics.drawRect(0, 0, 30, 30, this.curColor);
  	}
  	__getSideColorByPos(x, y) {
  		let height = this.spriteSide.height;
  		if (y < 0 || y > height)
  			return new Laya.Color(0, 0, 0, 0);
  		let rArray = [1, 1, 0, 0, 0, 1, 1];
  		let gArray = [0, 1, 1, 1, 0, 0, 0];
  		let bArray = [0, 0, 0, 1, 1, 1, 0];
  		let persent = y / height;
  		for (let i = 1; i <= 6; i++) {
  			if (persent <= i / 6) {
  				let localPersent = (persent - (i - 1) / 6) / (1 / 6);
  				return new Laya.Color(Mathf.clamp01(rArray[i - 1] * (1 - localPersent) + rArray[i] * localPersent), Mathf.clamp01(gArray[i - 1] * (1 - localPersent) + gArray[i] * localPersent), Mathf.clamp01(bArray[i - 1] * (1 - localPersent) + bArray[i] * localPersent));
  			}
  		}
  	}
  	__getMainColorByPos(x, y) {
  		let width = this.spriteMain.width;
  		let height = this.spriteMain.height;
  		let xPersent = x / width;
  		let yPersent = y / height;
  		let r = (1 - xPersent) + this.mainColor.r * xPersent;
  		let g = (1 - xPersent) + this.mainColor.g * xPersent;
  		let b = (1 - xPersent) + this.mainColor.b * xPersent;
  		r = r * (1 - yPersent) + 0 * yPersent;
  		g = g * (1 - yPersent) + 0 * yPersent;
  		b = b * (1 - yPersent) + 0 * yPersent;
  		r = Mathf.clamp01(r);
  		g = Mathf.clamp01(g);
  		b = Mathf.clamp01(b);
  		return Tools.toHexColor(new Laya.Color(r, g, b, 1));
  	}
  	on_click_buttonclose() {
  		this.close();
  	}
  }
  EditorSelectorColor.sourceName = "ui://debug/EditorSelectorColor";

  class EditorSelectorTexture extends DebugBase {
  	onLoaded() {
  		this.allOptions = this.context.options;
  		this.scrollList.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			let option = this.curOptions[idx];
  			obj.title = option.desc || "empty";
  			obj.getChild("texture").asLoader.url = option.value;
  			obj["userData"] = option;
  		});
  		this.scrollList.on(fgui.Events.CLICK_ITEM, this, (item) => {
  			let option = item["userData"];
  			this.close();
  			if (this.context.onChange) {
  				this.context.onChange(option);
  			}
  		});
  		this.curOptions = this.allOptions.slice();
  		this.scrollList.numItems = this.curOptions.length;
  		this.input.on(Laya.Event.INPUT, this, this.onInput);
  	}
  	dispose() {
  		super.dispose();
  	}
  	onInput() {
  		let inputStr = this.input.text;
  		if (inputStr) {
  			let arr = [];
  			this.allOptions.forEach(function (option) {
  				if (~option.value.indexOf(inputStr)) {
  					arr.push(option);
  				}
  			});
  			this.curOptions = arr;
  		}
  		else {
  			this.curOptions = this.allOptions.slice();
  		}
  		this.scrollList.numItems = this.curOptions.length;
  	}
  	on_click_btnClose() {
  		this.close();
  	}
  	on_click_scrollList() {
  	}
  }
  EditorSelectorTexture.sourceName = "ui://debug/EditorSelectorTexture";

  class EditorTextInput extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "编辑器文本输入";
  	}
  	static open(inputCallback) {
  		Director.openPanel(`EditorTextInput`, {
  			inputCallback: inputCallback,
  		});
  	}
  	onLoaded() {
  		Global.registerListeners(this, {
  			[BASE_MSG.SYS_KEY_DOWN]: this.onMsgKeyDown.bind(this)
  		});
  		this.input.requestFocus();
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgKeyDown(e) {
  		switch (e.keyCode) {
  			case Laya.Keyboard.ENTER:
  				if (this.input.text.length == 0) {
  					mgrTip.showMsgTip("输入非法字符");
  					return;
  				}
  				this.context.inputCallback && this.context.inputCallback(this.input.text);
  				this.close();
  				break;
  			default:
  				break;
  		}
  	}
  }
  EditorTextInput.sourceName = "ui://debug/EditorTextInput";

  class ViewRelationBaseNode extends ViewBase {
  	onCreate() {
  	}
  	dispose() {
  		super.dispose();
  	}
  }
  ViewRelationBaseNode.sourceName = "ui://debug/ViewRelationBaseNode";

  class mgrAchievement extends Manager {
  	static onLoad() {
  		super.onLoad();
  	}
  	static loadRecord() {
  		let data = FileRecord.getData("mgrAchievement") || {};
  		console.log("初始化mgrAchievement");
  		this.saveRecord();
  	}
  	static saveRecord() {
  		let record = {};
  		FileRecord.setData("mgrAchievement", record);
  	}
  	static getAchievementTargetCount(id) {
  		let template = db.get_ggg_activement_template_db(id);
  		return template.targetCount;
  	}
  }

  class PanelExperience extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "历程界面";
  		this.bOpenAndCloseAnim = true;
  	}
  	onLoaded() {
  		this.playTranslation(this.resNode, "in");
  		this.fillData();
  	}
  	dispose() {
  		super.dispose();
  	}
  	fillData() {
  		let prop1Value = mgrRole.getProperty1();
  		let prop2Value = mgrRole.getProperty2();
  		let prop3Value = mgrRole.getProperty3();
  		let prop4Value = mgrRole.getProperty4();
  		let prop1ValueMax = mgrAchievement.getAchievementTargetCount(1);
  		let prop2ValueMax = mgrAchievement.getAchievementTargetCount(2);
  		let prop3ValueMax = mgrAchievement.getAchievementTargetCount(3);
  		let prop4ValueMax = mgrAchievement.getAchievementTargetCount(4);
  		let prop5ValueMax = mgrAchievement.getAchievementTargetCount(5);
  		this.progressProp1.value = (prop1Value / prop1ValueMax) * 100;
  		this.progressProp2.value = (prop2Value / prop2ValueMax) * 100;
  		this.progressProp3.value = (prop3Value / prop3ValueMax) * 100;
  		this.progressProp4.value = (prop4Value / prop4ValueMax) * 100;
  		this.progress5.value = 0;
  		this.progressProp1.getChild("textProgress").text = prop1Value + "/" + prop1ValueMax;
  		this.progressProp2.getChild("textProgress").text = prop2Value + "/" + prop2ValueMax;
  		this.progressProp3.getChild("textProgress").text = prop3Value + "/" + prop3ValueMax;
  		this.progressProp4.getChild("textProgress").text = prop4Value + "/" + prop4ValueMax;
  		this.progress5.getChild("textProgress").text = mgrRole.getAllActivedRoleIdArr().length + "/" + prop5ValueMax;
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  }
  PanelExperience.sourceName = "ui://experience/PanelExperience";

  class PanelChoosePosition extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "人生重开界面";
  		this.bDisableUiAni = false;
  	}
  	onLoaded() {
  		this.playTranslation(this.comBtnArrived, "in");
  		this.fillListItemsData();
  		this.adaptBtnAdFlag();
  	}
  	dispose() {
  		super.dispose();
  	}
  	fillListItemsData() {
  		let arr = mgrRole.getAllCanBornRoleIdArr(this.context.grownupLine);
  		this.listDataArr = arr;
  		this.currSelectRoleId = arr[0];
  		this.listItems.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj.visible = false;
  			obj[`idx`] = idx;
  			let roleId = this.listDataArr[idx];
  			let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(roleId);
  			obj.getChild("imageEndFlagNormal").visible = (roleData.maxLevelResultTimeline && roleData.maxLevelResultTimeline != "") ? true : false;
  			obj.getChild("textName").text = roleData.name;
  			obj.getChild("loaderPositionIcon").url = roleData.headIcon;
  			obj.getChild("loaderPositionIconBg").visible = false;
  			let propertyInfoArr = mgrRole.getSortedPropertyIndexArr(roleData.property_1, roleData.property_2, roleData.property_3, roleData.property_4);
  			let rolePropertyId = propertyInfoArr[0].propertyIndex;
  			let propertyGroup = obj.getChild("groupProperty1");
  			propertyGroup.visible = !!rolePropertyId;
  			if (propertyGroup.visible) {
  				let propertyIcon = obj.getChild("loaderIcon1");
  				let propertyText = obj.getChild("textAmount1");
  				let propertyData = db.get_amaze_cloth_crossing_role_property(rolePropertyId);
  				propertyIcon.url = propertyData.smallIcon;
  				propertyText.text = `${Math.max(1, roleData["property_" + rolePropertyId] || 0)}`;
  			}
  			obj.getChild("spriteSelected").visible = this.currSelectRoleId == roleId ? true : false;
  			if (!this.bDisableUiAni) {
  				let time = 0.15 * Math.ceil((idx + 1) / 3);
  				Timer.callLater(time, (timer) => {
  					obj.visible = true;
  					this.playTranslation(obj, "in", new Laya.Handler(this, () => {
  						timer.stop();
  						timer = null;
  					}));
  				}, obj);
  			}
  			else {
  				obj.visible = true;
  			}
  			if (idx == this.listDataArr.length - 1) {
  				this.bDisableUiAni = true;
  			}
  		});
  		this.listItems.on(fgui.Events.CLICK_ITEM, this, this.onClickItem.bind(this));
  		this.listItems.numItems = this.listDataArr.length;
  	}
  	onClickItem(obj) {
  		this.bDisableUiAni = true;
  		let idx = obj.idx;
  		this.currSelectRoleId = this.listDataArr[idx];
  		this.listItems.numItems = this.listDataArr.length;
  		this.adaptBtnAdFlag();
  	}
  	adaptBtnAdFlag() {
  		this.buttonAdStart.getChild("loaderAdTag").visible = false;
  	}
  	on_click_buttonAdStart() {
  		this.context.fOnChoosed && this.context.fOnChoosed(this.currSelectRoleId);
  		this.close();
  	}
  	on_click_buttonBack() {
  		this.close();
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  }
  PanelChoosePosition.sourceName = "ui://gogogo/PanelChoosePosition";

  class PanelCrossLine extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "重生选线界面";
  	}
  	onLoaded() {
  		this.initUi();
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName != db.ADV_DB_ADVNAME.video_PanelChoosePosition_start)
  			return;
  		this.doSelectedLine(this.lastSelectLine);
  	}
  	initUi() {
  		let bAdValid = false;
  		if (mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelChoosePosition_start)) {
  			mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelChoosePosition_start);
  			bAdValid = true;
  		}
  		let usingGrownupLine = mgrRole.getUsingGrownupLine();
  		let propertyDb = db.get_amaze_cloth_crossing_role_property_map();
  		for (let k in propertyDb) {
  			let data = propertyDb[k];
  			let btn = this["buttonCrossLine" + data.id];
  			if (!btn) {
  				continue;
  			}
  			let imageCompletedFlag = btn.getChild("imageCompletedFlag");
  			let labelCurrentPositionName = btn.getChild("labelCurrentPositionName");
  			let loaderCurrentPositionIcon = btn.getChild("loaderCurrentPositionIcon");
  			let loaderAdTag = btn.getChild("loaderAdTag");
  			let labelTip = btn.getChild("labelTip");
  			loaderAdTag.visible = (bAdValid && usingGrownupLine != data.id && !mgrRole.isArrivedGrownupLine(data.id)) ? true : false;
  			if (usingGrownupLine == data.id) {
  				labelTip.text = "继续游戏";
  			}
  			else {
  				labelTip.text = "免费穿越";
  			}
  			let arrivedMaxLevelRoleId = mgrRole.getArrivedMaxLevelRoleIdByGrownline(data.id);
  			let maxLevelRoleId = mgrRole.getMaxLevelRoleDataByGrownline(data.id);
  			let arrivedMaxLevelRoleData = db.get_amaze_cloth_crossing_property_to_logic_role(arrivedMaxLevelRoleId);
  			let minLevelRoleData = mgrRole.getMinLevelRoleDataByGrownline(data.id);
  			let showRoleData = arrivedMaxLevelRoleData || minLevelRoleData;
  			imageCompletedFlag.visible = (!!arrivedMaxLevelRoleId && arrivedMaxLevelRoleId == maxLevelRoleId) ? true : false;
  			labelCurrentPositionName.text = showRoleData.name || "";
  			loaderCurrentPositionIcon.url = showRoleData.headIcon;
  		}
  	}
  	doSelectedLine(grownupLine) {
  			let callback = (roleId) => {
  			mgrRole.markBornOnce();
  			let usingRoleId = roleId || 201;
  			let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(usingRoleId);
  			mgrRole.setUsingGrownupLine(grownupLine);
  			mgrRole.setUsingPlayerRoleId(usingRoleId);
  			let propertyValue = roleData[`property_${grownupLine}`] || 0;
  			propertyValue = Math.max(1, propertyValue);
  			mgrRole.setPropertyValueByGrownunLine(grownupLine, propertyValue);
  			Director.openPanel("PanelPositionUpPreview", { fOnChoosed: this.context.fOnChoosed, bResetStage: true });
  			this.close();
  		};
  		let arrivedIdArr = mgrRole.getAllCanBornRoleIdArr(grownupLine);
  		if (arrivedIdArr && arrivedIdArr.length > 1) {
  			Director.openPanel(`PanelChoosePosition`, {
  				grownupLine: grownupLine, fOnChoosed: (roleId) => {
  					callback(roleId || arrivedIdArr[0]);
  				}
  			});
  		}
  		else {
  			callback();
  		}
  	}
  	onClickLine(line) {
  			this.lastSelectLine = line;
  			// this.doSelectedLine(this.lastSelectLine);
  			
  		let usingGrownupLine = mgrRole.getUsingGrownupLine();
  		// if (!!usingGrownupLine && usingGrownupLine != this.lastSelectLine && !mgrRole.isArrivedGrownupLine(this.lastSelectLine)) {
  			// console.info("77777777777777777777777777777777777777777777");
  			// mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelChoosePosition_start, {}, true);
  		if(usingGrownupLine!=this.lastSelectLine)
  		{
  			console.info("88888888888888888888888888888888888888888888888888888");
  			Advertisement.videop=this,
  			Advertisement.videoAdverV(()=>{
  				this.doSelectedLine(this.lastSelectLine);
  			});
  		}
  		else {
  			this.doSelectedLine(this.lastSelectLine);
  		}
  	}
  	on_click_buttonClose() {
  		Director.openPanel("PanelPositionUpPreview", { fOnChoosed: this.context.fOnChoosed, bResetStage: true });
  	}
  	on_click_buttonCrossLine1() {
  		this.onClickLine(1);
  	}
  	on_click_buttonCrossLine2() {
  		this.onClickLine(2);
  	}
  	on_click_buttonCrossLine3() {
  		this.onClickLine(3);
  	}
  	on_click_buttonCrossLine4() {
  		this.onClickLine(4);
  	}
  }
  PanelCrossLine.sourceName = "ui://gogogo/PanelCrossLine";

  class GameCross {
  	constructor(node, type, offset) {
  		this._x = null;
  		this._y = null;
  		this._type = type;
  		Timer.callLater(0.1, () => {
  			this.initPosition(node, offset);
  		});
  	}
  	static create(node, type = 0, offset = 0) {
  		if (!node)
  			return;
  		this._list.push(new GameCross(node, type, offset));
  	}
  	static setVisible(visible) {
  		for (let i = 0; i < this._list.length; i++) {
  			this._list[i].visible = visible;
  		}
  	}
  	static get isEmpty() {
  		return this._list.length == 0;
  	}
  	set visible(value) {
  		this._visible = value;
  		if (value) {
  			if (this._x != null) {
  				mgrSdk.openCrossRecommend(this._x, this._y, this._type);
  			}
  		}
  		else {
  			mgrSdk.closeCrossRecommend();
  		}
  	}
  	initPosition(node, offset) {
  		if (!node || node.isDisposed)
  			return;
  		let worldPos = node.localToGlobal(0, 0);
  		this._x = Math.round(worldPos.x / UIRoot.canvasWidth * Laya.Browser.clientWidth);
  		this._y = Math.round(worldPos.y / UIRoot.canvasHeight * Laya.Browser.clientHeight);
  		if (this._visible) {
  			this.visible = true;
  		}
  	}
  }
  GameCross._list = [];

  class ViewAddExpNumber extends ViewBase {
  	constructor() {
  		super(...arguments);
  		this.amount = 0;
  		this.comboCount = 0;
  		this.luckyCount = 0;
  	}
  	onCreate() {
  		this.touchable = false;
  		if (!!this.context.icon) {
  			this.loaderIcon.url = this.context.icon;
  		}
  		this.setAmount(this.amount, this.comboCount, this.luckyCount);
  		this.playEff();
  	}
  	dispose() {
  		super.dispose();
  	}
  	setAmount(value, comboCount, luckyCount) {
  		this.amount = Math.abs(value);
  		this.comboCount = comboCount || 0;
  		this.luckyCount = luckyCount || 0;
  		if (!!this.labelCount) {
  			this.labelCount.text = `+${this.amount}`;
  		}
  		if (!!this.labelComboCount) {
  			this.labelComboCount.text = `+${this.comboCount || 0}`;
  			this.groupCombo.visible = !!this.comboCount;
  		}
  		if (!!this.labelLuckyCount) {
  			this.labelLuckyCount.text = `+${this.luckyCount || 0}`;
  			this.groupLucky.visible = !!this.luckyCount;
  		}
  	}
  	setStartPos(pos) {
  		this.startPos = pos;
  	}
  	playEff() {
  		let layer = Director.getLayerUI();
  		layer.addChild(this);
  		this.startPos = this.startPos || new Laya.Vector2(Global.canvasWidth / 2 + 100 * (Tools.random(100) > 50 ? 1 : -1), Global.canvasHeight / 2 - 30);
  		this.setXY(this.startPos.x, this.startPos.y - Tools.random(10));
  		this.scaleX = 0;
  		this.scaleY = 0;
  		this.context.flyTargetPos = this.context.flyTargetPos || this.startPos;
  		cc$1.tween(this)
  			.toScale(0.2, 1, cc$1.Ease.backOut)
  			.delay(0.2)
  			.parallel(cc$1.tween().then(cc$1.jumpTo(0.5, this.context.flyTargetPos.x, this.context.flyTargetPos.y, 100, 1)), cc$1.tween().toScale(0.5, 0.3))
  			.call(() => {
  				this.context.fOnCompleted && this.context.fOnCompleted();
  				this.dispose();
  			})
  			.start();
  	}
  	on_click_labelCount() {
  	}
  }
  ViewAddExpNumber.sourceName = "ui://gogogo/ViewAddExpNumber";

  class ViewSubEnergyNumber extends ViewBase {
  	onCreate() {
  		this.pivotX = 0.5;
  		this.pivotY = 0.5;
  		this.touchable = false;
  		if (!!this.context.icon) {
  			this.loaderIcon.url = this.context.icon;
  		}
  		this.setAmount(this.amount);
  		this.playEff();
  	}
  	dispose() {
  		super.dispose();
  	}
  	setAmount(value) {
  		this.amount = Math.abs(value);
  		if (!!this.labelCount) {
  			this.labelCount.text = `-${this.amount}`;
  		}
  	}
  	setStartPos(pos) {
  		this.startPos = pos;
  	}
  	playEff() {
  		let layer = Director.getLayerUI();
  		layer.addChild(this);
  		this.startPos = this.startPos || new Laya.Vector2(Global.canvasWidth / 2 + 30, Global.canvasHeight / 2 - 30);
  		this.setXY(this.startPos.x, this.startPos.y - Tools.random(10));
  		this.scaleX = 0;
  		this.scaleY = 0;
  		cc$1.tween(this)
  			.toScale(0.2, 1, cc$1.Ease.backOut)
  			.delay(0.2)
  			.call(() => {
  				this.dispose();
  			})
  			.start();
  	}
  	on_click_labelCount() {
  	}
  }
  ViewSubEnergyNumber.sourceName = "ui://gogogo/ViewSubEnergyNumber";

  class ViewSubExpNumber extends ViewBase {
  	constructor() {
  		super(...arguments);
  		this.amount = 0;
  		this.comboCount = 0;
  		this.luckyCount = 0;
  	}
  	onCreate() {
  		this.touchable = false;
  		if (!!this.context.icon) {
  			this.loaderIcon.url = this.context.icon;
  		}
  		this.setAmount(this.amount, this.comboCount, this.luckyCount);
  		this.playEff();
  	}
  	dispose() {
  		super.dispose();
  	}
  	setAmount(value, comboCount, luckyCount) {
  		this.amount = Math.abs(value);
  		this.comboCount = Math.abs(comboCount || 0);
  		this.luckyCount = Math.abs(luckyCount || 0);
  		if (!!this.labelCount) {
  			this.labelCount.text = `-${this.amount}`;
  		}
  		if (!!this.labelLuckyCount) {
  			this.labelLuckyCount.text = `-${this.luckyCount || 0}`;
  			this.groupLucky.visible = !!this.luckyCount;
  		}
  	}
  	setStartPos(pos) {
  		this.startPos = pos;
  	}
  	playEff() {
  		let layer = Director.getLayerUI();
  		layer.addChild(this);
  		this.startPos = this.startPos || new Laya.Vector2(Global.canvasWidth / 2 + 100, Global.canvasHeight / 2 - 30);
  		this.setXY(this.startPos.x, this.startPos.y - Tools.random(10));
  		this.scaleX = 0;
  		this.scaleY = 0;
  		this.context.flyTargetPos = this.context.flyTargetPos || this.startPos;
  		cc$1.tween(this)
  			.toScale(0.2, 1, cc$1.Ease.backOut)
  			.delay(0.2)
  			.parallel(cc$1.tween().then(cc$1.jumpTo(0.5, this.context.flyTargetPos.x, this.context.flyTargetPos.y, 100, 1)), cc$1.tween().toScale(0.5, 0.3))
  			.call(() => {
  				this.context.fOnCompleted && this.context.fOnCompleted();
  				this.dispose();
  			})
  			.start();
  	}
  	on_click_labelCount() {
  	}
  }
  ViewSubExpNumber.sourceName = "ui://gogogo/ViewSubExpNumber";

  class PanelGoGoGo extends PanelBase3D {
  	constructor(context) {
  		super(context);
  		this.PANEL_NAME = "跑酷主界面";
  		this.avatarPosCameraDict = {
  			[0]: {
  				avatarData: {
  					pos: new Laya.Vector3(0, 0, 0),
  					rot: new Laya.Vector3(0, 0, 0)
  				},
  				cameraData: {
  					fov: 60,
  					pos: new Laya.Vector3(2.98, 1.8, 0),
  					rot: new Laya.Vector3(-13, 90, 0),
  				}
  			},
  			[1]: {
  				avatarData: {
  					pos: new Laya.Vector3(0, 0, 0),
  					rot: new Laya.Vector3(0, 0, 0)
  				},
  				cameraData: {
  					fov: 60,
  					pos: new Laya.Vector3(0, 5.95, 6.67),
  					rot: new Laya.Vector3(-19, 0, 0),
  					offset: new Laya.Vector3(0, 1.2, -1.06)
  				}
  			},
  			[4]: {
  				avatarData: {
  					pos: new Laya.Vector3(0, 0, 0),
  					rot: new Laya.Vector3(0, 0, 0)
  				},
  				cameraData: {
  					fov: 60,
  					pos: new Laya.Vector3(6.6, 4.26, 0),
  					rot: new Laya.Vector3(-27, 90, 0),
  				}
  			},
  			[5]: {
  				avatarData: {
  					pos: new Laya.Vector3(0, 0, 0),
  					rot: new Laya.Vector3(0, 0, 0)
  				},
  				cameraData: {
  					fov: 45,
  					pos: new Laya.Vector3(4.15, 1.26, 0),
  					rot: new Laya.Vector3(-7, 90, 0),
  				}
  			},
  			[6]: {
  				avatarData: {
  					pos: new Laya.Vector3(0, 0, 0),
  					rot: new Laya.Vector3(0, 0, 0)
  				},
  				cameraData: {
  					fov: 70,
  					pos: new Laya.Vector3(0, 5.95, 6.67),
  					rot: new Laya.Vector3(-5, 0, 0),
  					offset: new Laya.Vector3(0, 1.42, -0.62)
  				}
  			},
  		};
  		this.st_init = 1;
  		this.st_waitStart = 2;
  		this.st_turnReady = 3;
  		this.st_avatarComing = 4;
  		this.st_stageStartTip = 5;
  		this.st_avatarMoving = 6;
  		this.st_arrivedFinishArea = 10;
  		this.st_allArrivedPoint2 = 11;
  		this.st_playerArrivedPoint2 = 12;
  		this.st_zeroPropertyDie = 13;
  		this.st_cleanForRestart = 14;
  		this.st_revivalAndGoon = 15;
  		this.st_reward = 21;
  		this.st_reward2 = 22;
  		this.st_reward3 = 23;
  		this.st_reward4 = 24;
  		this.st_finish = 31;
  		this.PREFAB_ROAD_SEAT_LEN = 4;
  		this.ROAD_MODEL_ID_2_LEN_DICT = {
  			["daolu01"]: 10,
  			["daolu02"]: 30,
  			["daolu03"]: 15.75,
  			["daolu04"]: 15.75,
  			["daolu05"]: 30,
  			["daolu06"]: 30,
  			["daolu07"]: 30,
  			["daolu08"]: 15,
  			["daolu09"]: 15,
  			["daolu10"]: 10,
  			["daolu11"]: 5,
  		};
  		this.ROAD_MODEL_DEFAULT_LEN = 10;
  		this.PART_TYPE_2_Y_OFFSET_DICT = {};
  		this.PART_TYPE_2_SCALE_DICT = {};
  		this.pointNodeArr = [];
  		this.itemsInfoArr = [];
  		this.touchBgBeginAvatarPosX = 0;
  		this.baseRoadX = 0;
  		this.baseRoadY = 0;
  		this.MOVE_FPS = 1;
  		this.ROAD_WH = 4.5;
  		this.ROAD_SMALL_WH = 1;
  		this.SCREEN_TOUCH_TOTAL_WIDTH = 400;
  		this.MIN_USER_TOUCH_SCREEN_WIDTH_RATIO = 0.4;
  		this.MIDDLE_USER_TOUCH_SCREEN_WIDTH_RATIO = 0.7;
  		this.MIN_USER_TOUCH_PERSUIT_X_DIS = 0.04;
  		this.MIDDLE_USER_TOUCH_PERSUIT_X_DIS = 0.08;
  		this.MAX_USER_TOUCH_PERSUIT_X_DIS = 0.2;
  		this.TOUCH_MOVE_WHOTE_GRADUAL_RATIO = 1;
  		this.TOUCH_MOVE_BEGIN_RATIO = 1;
  		this.DISTANCE_ENEMY_WHITH_PLAYER = 1.2;
  		this.DISTANCE_ENEMY_WHITH_PLAYER_SLOW_AREA = 5;
  		this.DISTANCE_PLAYER_WITH_RIGHT_ANGLE_SLOW_SPEED = 8;
  		this.LANDING_POS_X_OFFSET = 0.5;
  		this.DISTANCE_FINISH_PLACE_AREA = 8;
  		this.dressedPartIdDict = {};
  		this.ANGEL_CHANGE_PARTID_ARR = [
  			[12042, 12060], [21042, 21003], [13328, 13329], [16014, 16026]
  		];
  		this.EVIL_CHANGE_PARTID_ARR = [
  			[12058, 12059], [21041, 21012], [13330, 13331], [16225, 16226]
  		];
  		this.lastCameraFarPlaneTargetZ = 0;
  		this.currRightAngleInfoCheckIndex = 0;
  		this.gotCoinValue = 0;
  		this.cornerInfoArr = [];
  		this.currRightAngleInfoCheckIndexEnemy = 0;
  		this.currStageEnemyGotExp = 0;
  		this.sameUserTouchPosAvatarMovingFrameCount = 0;
  		this.sameUserTouchPosIgnoreAvatarFrameCount = 0;
  		this.currentProperty1 = 0;
  		this.currentProperty2 = 0;
  		this.currentProperty3 = 0;
  		this.currentProperty4 = 0;
  		this.playerPosPathArr = [];
  		this.PROPERTY_2_HIT_EFF_NAME_DICT = {
  			[0]: "130_e_once_glow_01",
  			[1]: "130_e_once_glow_green",
  			[2]: "130_e_once_glow_blue",
  			[3]: "130_e_once_glow_purple",
  			[4]: "130_e_once_glow_pink",
  		};
  		this.QUESTION_AREA_SLOW_SPEED_SCALE = 0.5;
  		this.bSuccess = false;
  		this.BIG_ITEM_RATIO = 3;
  		this.BIG_ITEM_SCALE = 2;
  		this.currAvatarFollowerDistance = 0.4;
  		this.AVATAR_FOLLOWER_DISPEL_BEGGER_CHECK_DISTANCE = 3;
  		this.currStageGotGoldAmount = 0;
  		this.currStageGotDecreeAmount = 0;
  		this.ITEM_RANK_ID_GOLD = 102;
  		this.ITEM_RANK_ID_SPEED = 103;
  		this.ITEM_RANK_ID_DECREE = 104;
  		this.ITEM_RANK_ID_LUCKY = 120;
  		this.ITEM_RANK_ID_UNLUCKY = 121;
  		this.MOVE_FPS_SPEED_OFFSET = 3;
  		this.DEFAULT_BG_SOUND_ID = 1;
  		this.bFreeLevelUp = false;
  		this.TRAIL_RETINUE_LV = 10;
  		this.PATH_COUNT = 2;
  		this.cameraRoateValueWhenAllArrived = 0;
  		this.finishAreaTargetLerpValue = 0.1;
  	}
  	onLoaded() {
  		mgrSound.play(this.DEFAULT_BG_SOUND_ID);
  		this.comMask.visible = false;
  		this.comScrollTip.visible = false;
  		this.comPropertyExternamUpgradeTip.setScale(0, 0);
  		this.refreshButtons();
  		this.tryShowChannelInfo();
  		this.comChat.setScale(0, 0);
  		this.comCountDown.visible = false;
  		this.comPetOutput.visible = false;
  		this.comStageGoldGotTip.visible = false;
  		this.comAnswerScoreTip1.visible = false;
  		this.comAnswerScoreTip2.visible = false;
  		this.comAnswerScoreTip3.visible = false;
  		this.comStartGuide.touchable = false;
  		this.comProgressBarStage.touchable = false;
  		this.comEnemyNameContainer.touchable = false;
  		this.comPlayerNameContainer.touchable = false;
  		this.comPlayerNameContainer.alpha = 0;
  		this.comEnemyNameContainer.alpha = 0;
  		this.comTargetProperty.alpha = 0;
  		let initOriginPosNodeArr = [
  			this.buttonIllu, this.buttonPet, this.buttonAttendant,
  			this.comBornCount, this.comBtnKing, this.comBtnKingMother, this.comChannelButtons, this.comCountDown, this.comLevelUp,
  			this.comProperty1, this.comProperty2, this.comProperty3, this.comProperty4,
  			this.comProperty102, this.button_position_up, , this.comProperty104,
  			this.comBtnYard
  		];
  		for (let k in initOriginPosNodeArr) {
  			let node = initOriginPosNodeArr[k];
  			node["_originPos"] = node["_originPos"] || new Laya.Vector2(node.x, node.y);
  		}
  		mgrCrossStage.endPositionWordPos = UITools.getSelfGlobalPos(this.button_position_up.guiNode);
  		this.playBtnsMoveOut();
  		this.playPropBtnsMoveOut();
  		this.buildScene(() => {
  			let config = db.get_amaze_cloth_crossing_config(1);
  			this.SCREEN_TOUCH_TOTAL_WIDTH = config.touchScreenWidth;
  			this.MIN_USER_TOUCH_SCREEN_WIDTH_RATIO = config.minUserTouchWidthRatio;
  			this.MIDDLE_USER_TOUCH_SCREEN_WIDTH_RATIO = config.middleUserTouchWidthRatio;
  			this.MIN_USER_TOUCH_PERSUIT_X_DIS = config.minUserTouchWidthDis;
  			this.MIDDLE_USER_TOUCH_PERSUIT_X_DIS = config.middleUserTouchWidthDis;
  			this.MAX_USER_TOUCH_PERSUIT_X_DIS = config.maxUserTouchWidthDis;
  			this.TOUCH_MOVE_WHOTE_GRADUAL_RATIO = config.wholeGradualRatio;
  			this.stManager = new FSMObject;
  			this.stManager.registerState(this.st_init, this.inInit.bind(this), this.exeInit.bind(this), this.outInit.bind(this));
  			this.stManager.registerState(this.st_waitStart, this.inWaitStart.bind(this), this.exeWaitStart.bind(this), this.outWaitStart.bind(this));
  			this.stManager.registerState(this.st_turnReady, this.inTurnReady.bind(this), this.exeTurnReady.bind(this), this.outTurnReady.bind(this));
  			this.stManager.registerState(this.st_avatarComing, this.inAvatarComing.bind(this), this.exeAvatarComing.bind(this), this.outAvatarComing.bind(this));
  			this.stManager.registerState(this.st_stageStartTip, this.inStageStartTip.bind(this), this.exeStageStartTip.bind(this), this.outStageStartTip.bind(this));
  			this.stManager.registerState(this.st_avatarMoving, this.inAvatarMoving.bind(this), this.exeAvatarMoving.bind(this), this.outAvatarMoving.bind(this));
  			this.stManager.registerState(this.st_playerArrivedPoint2, this.inPlayerArrivedPoint2.bind(this), this.exePlayerArrivedPoint2.bind(this), this.outPlayerArrivedPoint2.bind(this));
  			this.stManager.registerState(this.st_allArrivedPoint2, this.inAllArrivedPoint2.bind(this), this.exeAllArrivedPoint2.bind(this), this.outAllArrivedPoint2.bind(this));
  			this.stManager.registerState(this.st_arrivedFinishArea, this.inArrivedFinishArea.bind(this), this.exeArrivedFinishArea.bind(this), this.outArrivedFinishArea.bind(this));
  			this.stManager.registerState(this.st_zeroPropertyDie, this.inZeroPropertyDie.bind(this), this.exeZeroPropertyDie.bind(this), this.outZeroPropertyDie.bind(this));
  			this.stManager.registerState(this.st_cleanForRestart, this.inCleanForRestart.bind(this), this.exeCleanForRestart.bind(this), this.outCleanForRestart.bind(this));
  			this.stManager.registerState(this.st_revivalAndGoon, this.inRevivalAndGoon.bind(this), this.exeRevivalAndGoon.bind(this), this.outRevivalAndGoon.bind(this));
  			this.stManager.registerState(this.st_reward, this.inReward.bind(this), this.exeReward.bind(this), this.outReward.bind(this));
  			this.stManager.registerState(this.st_reward2, this.inReward2.bind(this), this.exeReward2.bind(this), this.outReward2.bind(this));
  			this.stManager.registerState(this.st_reward3, this.inReward3.bind(this), this.exeReward3.bind(this), this.outReward3.bind(this));
  			this.stManager.registerState(this.st_reward4, this.inReward4.bind(this), this.exeReward4.bind(this), this.outReward4.bind(this));
  			this.stManager.registerState(this.st_finish, this.inFinish.bind(this), this.exeFinish.bind(this), this.outFinish.bind(this));
  			this.stManager.setNextState(this.st_init);
  			this.stManager.startUpdate(this, this.onTimerLoop.bind(this));
  			Global.registerListeners(this, {
  				[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  				["MSG_DEBUG_CROSS_STAGE_START"]: this.onMsgDebugCrossStageStart.bind(this),
  				["MSG_PET_OUTPUT_COIN"]: this.onMsgPetOutputCoin.bind(this),
  				["MSG_PET_FOLLOWING_CHANGED"]: this.onMsgPetFollowingChanged.bind(this),
  				["MSG_GEN_AND_START_STAGE_NOW"]: this.onMsgGenAndStartStageNow.bind(this),
  			});
  		});
  		Advertisement.insertAdverV2();
  	}
  	dispose() {
  		if (!!this.mapSky) {
  			this.mapSky.transform.localRotationEuler = new Laya.Vector3;
  			let yun = this.mapSky.resNode.getChildByName("yun");
  			if (!!yun) {
  				cc$1.tween(yun.transform).stop();
  			}
  			Global.poolManager.put(this.mapSky);
  			this.mapSky = null;
  		}
  		Director.hideWait("preload_stage_res");
  		this.cleanModels();
  		super.dispose();
  	}
  	getPreLoadSpines() {
  		let spines = [
  			"ui_lihe"
  		];
  		return spines;
  	}
  	getPreLoadModels() {
  		let modelIds = [
  			db.MODEL_DB_ID.sky,
  			db.MODEL_DB_ID.skydusk,
  			db.MODEL_DB_ID._130_ui_once_ray_01,
  			"timu",
  			"130_e_once_debuff",
  			"130_e_once_buff",
  			"130_e_once_shengji_01",
  			"men_red",
  			"men_green",
  			"men_blue",
  			"men_pink",
  			"panzi",
  			"zhong"
  		];
  		let dbMap = db.get_amaze_cloth_crossing_result_interactive_db_map();
  		for (let k in dbMap) {
  			let data = dbMap[k];
  			let roleData = db.get_amaze_cloth_crossing_role_db(data.npcRoleId);
  			modelIds.push(roleData.modelId);
  		}
  		return modelIds;
  	}
  	getPreloadAnimations() {
  		let arr = [];
  		let dbMap = db.get_amaze_cloth_crossing_result_interactive_db_map();
  		for (let k in dbMap) {
  			let data = dbMap[k];
  			let roleData = db.get_amaze_cloth_crossing_role_db(data.npcRoleId);
  			arr.push(roleData[data.quoteName]);
  		}
  		return arr;
  	}
  	playBtnsMoveIn() {
  		UiHelper.playMoveInX(this.comChannelButtons, this.comChannelButtons["_originPos"].x);
  		UiHelper.playMoveInX(this.comBornCount, this.comBornCount["_originPos"].x);
  		UiHelper.playMoveInX(this.buttonIllu, this.buttonIllu["_originPos"].x);
  		UiHelper.playMoveInX(this.buttonAttendant, this.buttonAttendant["_originPos"].x);
  		UiHelper.playMoveInX(this.buttonPet, this.buttonPet["_originPos"].x);
  		if (mgrCrossStage.isPlayedStage(1))
  			UiHelper.playMoveInX(this.comBtnKing, this.comBtnKing["_originPos"].x);
  		if (mgrCrossStage.isPlayedStage(1))
  			UiHelper.playMoveInX(this.comBtnKingMother, this.comBtnKingMother["_originPos"].x);
  		UiHelper.playMoveInY(this.comLevelUp, this.comLevelUp["_originPos"].y);
  		if (mgrCrossStage.isPlayedStage(1))
  			UiHelper.playMoveInX(this.comBtnYard, this.comBtnYard["_originPos"].x);
  		UiHelper.playMoveInX(this.button_position_up, this.button_position_up["_originPos"].x);
  		this.comMask.visible = false;
  		this.comScrollTip.visible = false;
  	}
  	playPropBtnsMoveIn() {
  		if (this.stageData.stageType == StageType.goldStage) {
  			this.comProperty102.alpha = 1;
  			UiHelper.playMoveInX(this.comProperty102, this.comProperty102["_originPos"].x);
  		}
  		else if (this.stageData.stageType == StageType.speedStage) {
  		}
  		else {
  			if (mgrCrossStage.getCurrStageId() > 1) {
  				this.comProperty2["_originPos"] = this.comProperty1["_originPos"];
  				this.comProperty3["_originPos"] = this.comProperty1["_originPos"];
  				this.comProperty4["_originPos"] = this.comProperty1["_originPos"];
  				this.comProperty2.y = this.comProperty1.y;
  				this.comProperty3.y = this.comProperty1.y;
  				this.comProperty4.y = this.comProperty1.y;
  				let grownupLine = mgrRole.getUsingGrownupLine();
  				for (let i = 1; i <= 4; i++) {
  					this["comProperty" + i].visible = grownupLine == i ? true : false;
  				}
  			}
  			else {
  				this.comProperty1.visible = true;
  				this.comProperty2.visible = true;
  				this.comProperty3.visible = true;
  				this.comProperty4.visible = true;
  			}
  			this.comProperty1.alpha = 1;
  			this.comProperty2.alpha = 1;
  			this.comProperty3.alpha = 1;
  			this.comProperty4.alpha = 1;
  			if (this.comProperty1.visible)
  				UiHelper.playMoveInX(this.comProperty1, this.comProperty1["_originPos"].x);
  			if (this.comProperty2.visible)
  				UiHelper.playMoveInX(this.comProperty2, this.comProperty2["_originPos"].x);
  			if (this.comProperty3.visible)
  				UiHelper.playMoveInX(this.comProperty3, this.comProperty3["_originPos"].x);
  			if (this.comProperty4.visible)
  				UiHelper.playMoveInX(this.comProperty4, this.comProperty4["_originPos"].x);
  		}
  		if (this.stageData && this.stageData.bShowDecreeProperty) {
  			this.refreshDecreeProperty();
  			this.comProperty104.alpha = 1;
  			UiHelper.playMoveInX(this.comProperty104, this.comProperty104["_originPos"].x);
  		}
  	}
  	playBtnsMoveOut() {
  		UiHelper.playMoveOutX(this.comChannelButtons, this.comChannelButtons["_originPos"].x - 120);
  		UiHelper.playMoveOutX(this.comBornCount, this.comBornCount["_originPos"].x + 120);
  		UiHelper.playMoveOutX(this.buttonIllu, this.buttonIllu["_originPos"].x + 120);
  		UiHelper.playMoveOutX(this.buttonAttendant, this.buttonAttendant["_originPos"].x + 120);
  		UiHelper.playMoveOutX(this.buttonPet, this.buttonPet["_originPos"].x + 120);
  		UiHelper.playMoveOutX(this.comBtnKing, this.comBtnKing["_originPos"].x + 120);
  		UiHelper.playMoveOutX(this.comBtnKingMother, this.comBtnKingMother["_originPos"].x + 120);
  		UiHelper.playMoveOutY(this.comLevelUp, this.comLevelUp["_originPos"].y + 320);
  		UiHelper.playMoveOutX(this.comBtnYard, this.comBtnYard["_originPos"].x + 120);
  		if (db.cop_db.b_show_mask == 1) {
  			this.comMask.visible = true;
  		}
  		else {
  			this.comMask.visible = false;
  		}
  		if (db.cop_db.b_show_rocker_btn == 1) {
  			this.comScrollTip.visible = true;
  		}
  		else {
  			this.comScrollTip.visible = false;
  		}
  	}
  	playPropBtnsMoveOut() {
  		UiHelper.playMoveOutX(this.comProperty1, this.comProperty1["_originPos"].x + 120);
  		UiHelper.playMoveOutX(this.comProperty2, this.comProperty2["_originPos"].x + 120);
  		UiHelper.playMoveOutX(this.comProperty3, this.comProperty3["_originPos"].x + 120);
  		UiHelper.playMoveOutX(this.comProperty4, this.comProperty4["_originPos"].x + 120);
  		UiHelper.playMoveOutX(this.comProperty102, this.comProperty102["_originPos"].x + 120);
  		UiHelper.playMoveOutX(this.button_position_up, this.button_position_up["_originPos"].x - 120);
  		UiHelper.playMoveOutX(this.comProperty104, this.comProperty104["_originPos"].x + 120);
  	}
  	refreshButtons() {
  		let bPlayedStageFirst = mgrCrossStage.isPlayedStage(1);
  		this.comBtnKing.visible = !!bPlayedStageFirst;
  		this.comBtnKingMother.visible = !!bPlayedStageFirst;
  		this.comBtnYard.visible = !!bPlayedStageFirst;
  		this.buttonFindMe.visible = db.cop_db.isSupportFindMinigames && mgrGuide.isAllGuideFinished();
  		this.buttonRewardJump.visible = mgrSdk.getSubCop(`b_reward_more_game`) == 1;
  		this.buttonMoreGame.visible = mgrSdk.getSubCop(`b_more_game`) == 1;
  		this.buttonDesktop.visible = db.cop_db.isSupportInstallShortcut && !mgrSdk.isInstallShortcut;
  		this.buttonSupperEasy && (this.buttonSupperEasy.visible = db.cop_db.isJumpLeisureEnabled && !window[`conch`]);
  		this.buttonSupperEasy_Android && (this.buttonSupperEasy_Android.visible = db.cop_db.isJumpLeisureEnabled && window[`conch`]);
  		let configSpeedStage = db.get_ggg_challenge_stage_config(StageType.speedStage);
  		let configGoldStage = db.get_ggg_challenge_stage_config(StageType.goldStage);
  		this.spritekingLock.visible = (!mgrChallenge.isUnlockedType(StageType.speedStage) && !mgrCrossStage.isPlayedStage(configSpeedStage.unlockYear)) ? true : false;
  		this.spritemotherkingLock.visible = (!mgrChallenge.isUnlockedType(StageType.goldStage) && !mgrCrossStage.isPlayedStage(configGoldStage.unlockYear)) ? true : false;
  		let configYard = db.get_ggg_yard_config(1);
  		this.spriteYardLock.visible = (!mgrYard.isYardUnlocked() && !mgrCrossStage.isPlayedStage(configYard.unlockYear)) ? true : false;
  		this.buttonZQ.visible = !!db.cop_db.b_hub_show_button_zq;
  		if (!!db.cop_db.b_hub_show_button_zq) {
  			if (mgrSdk.h5_channel == "qq") {
  				this.buttonZQqq.visible = true;
  				this.buttonZQ.visible = false;
  			}
  			else {
  				this.buttonZQqq.visible = false;
  				this.buttonZQ.visible = true;
  			}
  		}
  		else {
  			this.buttonZQqq.visible = false;
  			this.buttonZQ.visible = false;
  		}
  		let count = mgrRole.getAllArrivedRoleIdArr().length > 0 && (mgrRole.getAllActivedRoleIdArr().length - mgrRole.getAllArrivedRoleIdArr().length < 0) ? 1 : 0;
  		mgrTip.showBadgeWithNumber(this.buttonIllu.guiNode.displayObject, count, new Laya.Point(10, 10));
  		count = mgrRetinue.isHaveCanTrain() ? 1 : 0;
  		mgrTip.showBadgeWithNumber(this.buttonAttendant.guiNode.displayObject, count, new Laya.Point(10, 10));
  		count = mgrPet.isHaveCanUpgrade() ? 1 : 0;
  		mgrTip.showBadgeWithNumber(this.buttonPet.guiNode.displayObject, count, new Laya.Point(10, 10));
  		count = mgrChallenge.isUnlockedType(StageType.goldStage) ? mgrChallenge.getChallengeRemainCount(StageType.goldStage) + mgrChallenge.getChallengeAdRemainCount(StageType.goldStage) : 0;
  		mgrTip.showBadgeWithNumber(this.comBtnKingMother.displayObject, count, new Laya.Point(50, 10));
  		count = mgrChallenge.isUnlockedType(StageType.speedStage) ? mgrChallenge.getChallengeRemainCount(StageType.speedStage) + mgrChallenge.getChallengeAdRemainCount(StageType.speedStage) : 0;
  		mgrTip.showBadgeWithNumber(this.comBtnKing.displayObject, count, new Laya.Point(50, 10));
  		count = (this.buttonCoinUpgrade.visible && BaseFacade.mItem.isEnoughItem(mgrRole.getNextLevelGotPropertyExtrnalUpgradeCostItemId(), mgrRole.getNextLevelGotPropertyExtrnalUpgradeCostItemAmount())) ? 1 : 0;
  		mgrTip.showBadgeWithNumber(this.buttonCoinUpgrade.displayObject, count, new Laya.Point(5, 5));
  		count = (mgrYard.isYardUnlocked() && mgrYard.getBadgeCount() > 0) ? 1 : 0;
  		mgrTip.showBadgeWithNumber(this.comBtnYard.displayObject, count, new Laya.Point(50, 10));
  		if (!mgrRole.isMaxGotPropertyExtrnalLevel()) {
  			let owenGold = BaseFacade.mItem.getItemAmount(2);
  			let upgradeCostAmount = mgrRole.getNextLevelGotPropertyExtrnalUpgradeCostItemAmount();
  			if (owenGold >= upgradeCostAmount * 2) {
  				if (!this.comPropertyExternamUpgradeTip["_bshowing"]) {
  					this.comPropertyExternamUpgradeTip["_bshowing"] = true;
  					this.comPropertyExternamUpgradeTip.setScale(0, 0);
  					cc$1.tween(this.comPropertyExternamUpgradeTip, true).delay(3).toScale(0.3, 1)
  						.call(() => {
  							cc$1.tween(this.comPropertyExternamUpgradeTip, true).repeatForever(cc$1.tween().delay(5).toScale(0.2, 1.1).toScale(0.2, 1).toScale(0.2, 1.1).toScale(0.2, 1))
  								.start();
  						})
  						.start();
  				}
  			}
  			else {
  				if (!!this.comPropertyExternamUpgradeTip["_bshowing"]) {
  					this.comPropertyExternamUpgradeTip["_bshowing"] = false;
  					cc$1.tween(this.comPropertyExternamUpgradeTip, true).delay(3).toScale(0.3, 0).start();
  				}
  			}
  		}
  	}
  	tryShowChannelInfo() {
  		GameCross.create(this.comCross);
  		GameCross.setVisible(true);
  	}
  	onTimerLoop(deltaTime) {
  		let questionIndex = !!this.bQuestionAreaSlowSpeed ? this.getQuestionSlowSpeedAreaQuestionIndex() : 0;
  		for (let i = 1; i <= this.PATH_COUNT; i++) {
  			let comAnswerScoreTip = this["comAnswerScoreTip" + i];
  			if (!this.bQuestionAreaSlowSpeed) {
  				comAnswerScoreTip.visible = false;
  			}
  			if (!comAnswerScoreTip.visible) {
  				continue;
  			}
  			let info = this.questtionInfoArr[questionIndex];
  			if (!!info) {
  				let holder = info.questionNode.getChildByName(`holder${i}`);
  				let outResult = Tools.tranlateWorld3D2Screen(this.camera, new Laya.Vector3(holder.transform.position.x, holder.transform.position.y + 2, holder.transform.position.z));
  				let nodePos = comAnswerScoreTip.parent.globalToLocal(outResult.outPos.x, outResult.outPos.y);
  				comAnswerScoreTip.setXY(comAnswerScoreTip.parent.width * comAnswerScoreTip.parent.pivotX + nodePos.x, comAnswerScoreTip.parent.height * comAnswerScoreTip.parent.pivotY + nodePos.y);
  			}
  		}
  		let roleId = mgrRole.getCurrentPropertyRoleId(true);
  		if (!!roleId) {
  			let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(roleId);
  			this.loaderLevelUpIcon.url = roleData.headIcon;
  		}
  		if (!mgrRole.isMaxGotPropertyExtrnalLevel()) {
  			this.buttonPropertyExternal.visible = false;
  			this.comLevelUp.getChild("propAmount").text = `+${mgrRole.getCurrLevelGotPropertyExtrnalValue()}`;
  			this.comLevelUp.getChild("level").text = `${mgrRole.getGotPropertyExtrnalLevel()}`;
  			this.buttonCoinUpgrade.visible = true;
  			this.buttonCoinUpgrade.getChild("amount").text = Math.floor(mgrRole.getNextLevelGotPropertyExtrnalUpgradeCostItemAmount()).toString();
  			let loaderTag = this.buttonCoinUpgrade.getChild("loaderTag");
  			loaderTag.url = db.get_item_db(mgrRole.getNextLevelGotPropertyExtrnalUpgradeCostItemId()).icon;
  			this.spritePositonMax.visible = false;
  			if (this.buttonPropertyExternal.visible && !this.bStatisedLvUpExVideoShow) {
  				BaseFacade.mItem.setItem(911, 0);
  				this.bStatisedLvUpExVideoShow = true;
  			}
  			let adUpgradeCountDownTime = BaseFacade.mAutoIncreaseItem.getCd(911);
  			this.textAdUpgradeCountDown.text = "（" + adUpgradeCountDownTime + "s）";
  			if (adUpgradeCountDownTime > 0) {
  				this.buttonPropertyExternal.visible = true;
  				this.buttonCoinUpgrade.visible = false;
  				this.textAdUpgradeCountDown.visible = true;
  			}
  			else {
  				this.buttonCoinUpgrade.visible = true;
  				this.buttonPropertyExternal.visible = false;
  				this.textAdUpgradeCountDown.visible = false;
  			}
  		}
  		else {
  			this.buttonCoinUpgrade.visible = false;
  			this.buttonPropertyExternal.visible = false;
  			this.textAdUpgradeCountDown.visible = false;
  			this.spritePositonMax.visible = true;
  			this.comLevelUp.getChild("groupGetProp").visible = false;
  			this.comLevelUp.getChild("level").text = `${mgrRole.getGotPropertyExtrnalLevel()}`;
  			this.comLevelUp.getChild("propAmount").text = `+${mgrRole.getCurrLevelGotPropertyExtrnalValue()}`;
  		}
  		this.labelBornCount.text = `${Math.max(0, mgrRole.bornCount - 1)}`;
  		let currState = this.stManager.getCurState();
  		if (currState == this.st_reward || currState == this.st_reward2 || currState == this.st_reward3 ||
  			currState == this.st_reward4 || currState == this.st_finish) {
  			this.cameraRoateValueWhenAllArrived -= 0.1;
  			let param = this.avatarPosCameraDict[6].cameraData;
  			this.cameraFollow.endRotation = new Laya.Vector3(param.rot.x, this.cameraRoateValueWhenAllArrived, param.rot.z);
  			this.cameraFollow.distance = Math.max(this.cameraFollow.distance - 0.01, 4);
  		}
  		if (currState == this.st_avatarMoving && this.stageData.stageTime) {
  			this.comCountDown.visible = true;
  			let stageTime = this.stageData.stageTime;
  			let leftTime = Math.ceil(Math.max(0, stageTime - this.stageUsedTime));
  			this.textCountDownTime.text = leftTime.toString();
  		}
  		else {
  			this.comCountDown.visible = false;
  		}
  		this.refreshTitleName();
  		if (!this.bFocus) {
  			return;
  		}
  		this.refreshButtons();
  		this.obstacleHandler();
  		if (currState != this.st_avatarComing
  			&& currState != this.st_avatarMoving
  			&& currState != this.st_arrivedFinishArea
  			&& currState != this.st_playerArrivedPoint2
  			&& currState != this.st_reward) {
  			return;
  		}
  		if (this.lightBack && !this.lightBack.destroyed && this.avatarPlayerNode && !this.avatarPlayerNode.destroyed) {
  			this.lightBack.transform.localPositionZ = this.avatarPlayerNode.transform.localPositionZ;
  		}
  		this.crossQustionSlowSpeedAreaHandle();
  	}
  	refreshTitleName() {
  		let currState = this.stManager.getCurState();
  		if (!this.comEnemyNameContainer.alpha && (currState == this.st_reward ||
  			currState == this.st_reward2 ||
  			currState == this.st_reward3 ||
  			currState == this.st_reward4 ||
  			currState == this.st_finish ||
  			currState == this.st_cleanForRestart ||
  			currState == this.st_allArrivedPoint2 ||
  			currState == this.st_playerArrivedPoint2 ||
  			currState == this.st_init)) {
  			this.comPlayerNameContainer.alpha = 0;
  			return;
  		}
  		let avatarPlayer = null;
  		if (this.avatarPlayerContainer && !this.avatarPlayerContainer.destroyed) {
  			avatarPlayer = this.avatarPlayerContainer.getChildAt(0);
  		}
  		this.comPlayerNameContainer.alpha = (!!this.avatarPlayerContainer && this.stManager.getCurState() != this.st_reward) ? 1 : 0;
  		if (!!avatarPlayer) {
  			let outResult = Tools.tranlateWorld3D2Screen(this.camera, new Laya.Vector3(avatarPlayer.transform.position.x, avatarPlayer.transform.position.y + 2, avatarPlayer.transform.position.z));
  			let nodePos = this.comPlayerNameContainer.parent.globalToLocal(outResult.outPos.x, outResult.outPos.y);
  			this.comPlayerNameContainer.setXY(this.comPlayerNameContainer.parent.width * this.comPlayerNameContainer.parent.pivotX + nodePos.x, this.comPlayerNameContainer.parent.height * this.comPlayerNameContainer.parent.pivotY + nodePos.y);
  		}
  	}
  	refreshPlayerProperty(forcePropertyIndex, count) {
  		let maxPropertyIndex = mgrRole.getUsingGrownupLine() || this._getMaxPropertyValueIndex();
  		let refreshOnePorperty = (pIndex, value) => {
  			let com = this["comProperty" + pIndex];
  			let point = com.getChild("point");
  			point.text = `${value}`;
  		};
  		let refreshMaxStatus = () => {
  			for (let i = 1; i <= 4; i++) {
  				let pIndex = i;
  				let com = this["comProperty" + pIndex];
  				let point = com.getChild("point");
  				if (pIndex == maxPropertyIndex) {
  					com.getChild("maxBg").visible = true;
  					com.getChild("maxCountBg").visible = true;
  					point.color = "#FFF17E";
  				}
  				else {
  					com.getChild("maxBg").visible = false;
  					com.getChild("maxCountBg").visible = false;
  					point.color = "#FFFFFF";
  				}
  			}
  		};
  		if (!!forcePropertyIndex) {
  			refreshOnePorperty(forcePropertyIndex, count);
  			refreshMaxStatus();
  			return;
  		}
  		for (let i = 1; i <= 4; i++) {
  			let value = this["currentProperty" + i];
  			refreshOnePorperty(i, value);
  		}
  		refreshMaxStatus();
  	}
  	refreshGoldProperty(count) {
  		let com = this.comProperty102;
  		com.getChild("point").text = `${count || this.currStageGotGoldAmount || 0}`;
  	}
  	refreshDecreeProperty(count) {
  		let com = this.comProperty104;
  		com.getChild("point").text = `${count || this.currStageGotDecreeAmount || 0}`;
  	}
  	crossQustionSlowSpeedAreaHandle() {
  		let questionIndex = this.getQuestionSlowSpeedAreaQuestionIndex();
  		let avatarUsing = this.getPlayerAvatar();
  		if (questionIndex >= 0) {
  			if (!this.bQuestionAreaSlowSpeed) {
  				let bTriggeredSkill = false;
  				if (this.avatarFollower) {
  					let retinueId = this.avatarFollower["_retinueId"];
  					let level = this.avatarFollower["_retinueLevel"];
  					let retinueTemplate = db.get_ggg_retinue_template_db(retinueId, level);
  					if (retinueTemplate.skillId == SkillType.questionResult) {
  						let result = mgrRetinue.tryTriggerRetinueSkill(retinueId, level);
  						if (!!result && result.bTriggered) {
  							mgrSound.play(retinueTemplate.useSkillSoundId);
  							this.avatarFollower.playAnimationQuote(retinueTemplate.skillMovName, 0, null, null, true, false);
  							this.addPlayerAvatarEff("130_e_skill_gn_01");
  							bTriggeredSkill = true;
  						}
  					}
  				}
  				let info = this.questtionInfoArr[questionIndex];
  				let questionData = db.get_amaze_cloth_crossing_question_db(info.id);
  				for (let i = 1; i <= this.PATH_COUNT; i++) {
  					let holder = info.questionNode.getChildByName(`holder${i}`);
  					holder.transform.localRotationEulerX = -5;
  					let comTip = this["comAnswerScoreTip" + i];
  					comTip.visible = !!bTriggeredSkill;
  					let amount = ((questionData["answerScore" + i] || 0) + mgrRole.getCurrLevelGotPropertyExtrnalValue()) * (questionData.answerScoreRatio || 1);
  					comTip.getChild("title1").text = `+${amount}`;
  					let scoreRank = questionData["answerScorePropertyIndex" + i] || 0;
  					let propertyIndex = mgrRole.getUsingGrownupLine() || this._getPropertyValueIndexByRank(scoreRank);
  					let propertyData = db.get_amaze_cloth_crossing_role_property(propertyIndex);
  					comTip.getChild("loaderIcon").url = propertyData.smallIcon;
  				}
  				this.changeEnvironmentColor(new Laya.Color(0.7, 0.7, 0.7));
  			}
  			this.bQuestionAreaSlowSpeed = true;
  			if (avatarUsing.timeScale > this.QUESTION_AREA_SLOW_SPEED_SCALE) {
  				let targetscaler = this.QUESTION_AREA_SLOW_SPEED_SCALE;
  				avatarUsing.timeScale = targetscaler;
  				if (this.petFollower) {
  					this.petFollower.timeScale = targetscaler;
  				}
  			}
  			let movWalk = ROLE_QUOTE_MOV.movWalk;
  			if (!avatarUsing.isPlayingQuote(movWalk)) {
  				this.playerAvatarPlayAnimationQuote(movWalk, 0, null, null, true, false);
  			}
  			let dis = 0;
  			let info = this.questtionInfoArr[questionIndex];
  			let timu = info.questionNode.getChildByName("timu");
  			if (timu) {
  				let tmpOriginPos = new Laya.Vector3(this.avatarPlayerNode.transform.position.x, 2.7, info.questionNode.transform.position.z);
  				if (Math.abs(this.avatarPlayerNode.transform.position.z - tmpOriginPos.z) <= 3.1 && tmpOriginPos.z >= timu.transform.position.z) {
  					timu.transform.position = tmpOriginPos;
  				}
  				else {
  					timu.transform.position = new Laya.Vector3(tmpOriginPos.x, tmpOriginPos.y, this.avatarPlayerNode.transform.position.z - 3);
  				}
  				dis = Math.abs(this.avatarPlayerNode.transform.position.z - tmpOriginPos.z);
  			}
  			this.showPlayerTitleBarProgress(Math.max(0, (dis - 3) / (9 - 3) * 100));
  		}
  		else {
  			if (this.bQuestionAreaSlowSpeed) {
  				this.showPlayerTitleBarProgress(0);
  				this.removePlayerAvatarEff();
  				this.bQuestionAreaSlowSpeed = false;
  				avatarUsing.timeScale = 1;
  				TweenSystem.timeScale = 1;
  				let movWalk = ROLE_QUOTE_MOV.movWalk;
  				if (!avatarUsing.isPlayingQuote(movWalk)) {
  					this.playerAvatarPlayAnimationQuote(movWalk, 0, null, null, true, false);
  				}
  				if (this.avatarFollower) {
  					this.avatarFollower.timeScale = 1;
  				}
  				if (this.petFollower) {
  					this.petFollower.timeScale = 1;
  				}
  				this.changeEnvironmentColor(new Laya.Color(1, 1, 1));
  				if (this.avatarFollower) {
  					this.avatarFollower.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  				}
  			}
  		}
  	}
  	obstacleHandler() {
  		let arr = this.obstacleInfoArr;
  		if (!arr || arr.length == 0) {
  			return;
  		}
  		for (let i = 0; i < arr.length; i++) {
  			let obstacleInfo = arr[i];
  			if (!!obstacleInfo.bMoveHandled) {
  				continue;
  			}
  			obstacleInfo.bMoveHandled = true;
  			let eventData = db.get_amaze_cloth_crossing_road_event_db(obstacleInfo.eventId);
  			eventData.startMoveDir;
  			let flag = eventData.startMoveDir || (Tools.random(100) > 50 ? 1 : -1);
  			let originValue = 0;
  			let dur = eventData.moveDis / 1.5;
  			switch (eventData.moveType) {
  				case NpcMoveType.moveX: {
  					originValue = obstacleInfo.holder["_originPos"].x;
  					cc$1.tween(obstacleInfo.holder.transform)
  						.repeatForever(cc$1.tween()
  							.to(0, { localPositionX: originValue })
  							.call(() => {
  								obstacleInfo.holder.transform.localRotationEulerY = 90 * flag;
  							})
  							.to(dur, { localPositionX: originValue + eventData.moveDis * flag })
  							.call(() => {
  								obstacleInfo.holder.transform.localRotationEulerY = -90 * flag;
  							})
  							.to(dur, { localPositionX: originValue })
  							.to(dur, { localPositionX: originValue - eventData.moveDis * flag })
  							.call(() => {
  								obstacleInfo.holder.transform.localRotationEulerY = 90 * flag;
  							})
  							.to(dur, { localPositionX: originValue })).start();
  					break;
  				}
  				case NpcMoveType.moveY: {
  					originValue = obstacleInfo.holder["_originPos"].y;
  					cc$1.tween(obstacleInfo.holder.transform)
  						.repeatForever(cc$1.tween()
  							.to(0, { localPositionY: originValue })
  							.to(dur, { localPositionY: originValue + eventData.moveDis * flag })
  							.to(dur, { localPositionY: originValue })
  							.to(dur, { localPositionY: originValue - eventData.moveDis * flag })
  							.to(dur, { localPositionY: originValue })).start();
  					break;
  				}
  				case NpcMoveType.moveZ: {
  					originValue = obstacleInfo.holder["_originPos"].z;
  					cc$1.tween(obstacleInfo.holder.transform)
  						.repeatForever(cc$1.tween()
  							.to(0, { localPositionZ: originValue })
  							.call(() => {
  								obstacleInfo.holder.transform.localRotationEulerY = flag == 1 ? 0 : 180;
  							})
  							.to(dur, { localPositionZ: originValue + eventData.moveDis * flag })
  							.call(() => {
  								obstacleInfo.holder.transform.localRotationEulerY = flag != 1 ? 0 : 180;
  							})
  							.to(dur, { localPositionZ: originValue })
  							.to(dur, { localPositionZ: originValue - eventData.moveDis * flag })
  							.call(() => {
  								obstacleInfo.holder.transform.localRotationEulerY = flag == 1 ? 0 : 180;
  							})
  							.to(dur, { localPositionZ: originValue })).start();
  					break;
  				}
  				default:
  					break;
  			}
  			if (eventData.moveType != NpcMoveType.moveNone && obstacleInfo.npcAvatar) {
  				obstacleInfo.npcAvatar.registerAllLoadEndCallback(() => {
  					obstacleInfo.npcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true);
  				});
  			}
  		}
  	}
  	obstacleHandlerAfterRightAngle() {
  		let arr = this.obstacleInfoArr;
  		if (!arr || arr.length == 0) {
  			return;
  		}
  		for (let i = 0; i < arr.length; i++) {
  			let obstacleInfo = arr[i];
  			if (!obstacleInfo.bMoveHandled) {
  				continue;
  			}
  			let eventData = db.get_amaze_cloth_crossing_road_event_db(obstacleInfo.eventId);
  			if (eventData.moveType != NpcMoveType.moveNone && obstacleInfo.npcAvatar && !obstacleInfo.npcAvatar.destroyed) {
  				obstacleInfo.npcAvatar.registerAllLoadEndCallback(() => {
  					obstacleInfo.npcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true);
  				});
  			}
  		}
  	}
  	recreateMapSky(bDuskSky) {
  		this.scene3DBack.enableFog = true;
  		this.scene3DBack.fogStart = 0;
  		this.scene3DBack.fogRange = 340;
  		if (this.mapSky) {
  			cc$1.tween(this.mapSky.transform).stop();
  			let yun = this.mapSky.resNode.getChildByName("yun");
  			cc$1.tween(yun.transform).stop();
  			Global.poolManager.put(this.mapSky);
  			this.mapSky = null;
  		}
  		if (bDuskSky) {
  			this.mapSky = this.linkModelAtBack(db.MODEL_DB_ID.skydusk);
  			this.scene3DBack.fogColor = new Laya.Vector3(253 / 255, 203 / 255, 135 / 255);
  		}
  		else {
  			this.mapSky = this.linkModelAtBack(db.MODEL_DB_ID.sky);
  			this.scene3DBack.fogColor = new Laya.Vector3(189 / 255, 248 / 255, 243 / 255);
  		}
  		let yun = this.mapSky.resNode.getChildByName("yun");
  		if (!!yun) {
  			cc$1.tween(yun.transform)
  				.repeatForever(cc$1.tween().byLocalRotationEuler3D(30, 0, 10, 0))
  				.start();
  		}
  	}
  	buildScene(callback) {
  		this.snowEffect = this.linkModelAtBack(db.MODEL_DB_ID._130_e_loop_snow_03, this.camera);
  		this.snowEffect.transform.position = new Laya.Vector3(0, 0, 0);
  		this.snowEffect.transform.localRotationEulerY = 180;
  		this.snowEffect.active = false;
  		this.recreateMapSky();
  		this.camera.farPlane = 500;
  		this.cameraFollow = this.camera.getComponent(CameraFollow);
  		this.cameraFollow.lookMode = E_CAMERA_MODE.fixMode;
  		let param = this.avatarPosCameraDict[0].cameraData;
  		this.cameraFollow.position = param.pos.clone();
  		this.cameraFollow.endRotation = param.rot.clone();
  		this.cameraFollow.fov = param.fov;
  		this.cameraFollow.lerpValue = 1;
  		this.cameraFollow.onLateUpdate();
  		let doNext = () => {
  			this.context.stageId = this.context.stageId || mgrCrossStage.getCurrStageId();
  			this.genStageMap(() => {
  				this.camera.farPlane = 500;
  				callback && callback();
  			});
  		};
  		this.tryShowBornChapter(doNext);
  	}
  	tryShowBornChapter(callback) {
  		if (!!mgrRole.isBornOnce()) {
  			let roleId = mgrRole.getCurrentPropertyRoleId(true);
  			if (!!roleId) {
  				let wordPos = UITools.getSelfGlobalPos(this.button_position_up.guiNode);
  				Director.openPanel(mgrCrossStage.getCurrStageId() == 1 ? "PanelPositionUpFirstYearPreview" : "PanelPositionUpPreview", {
  					endPos: wordPos,
  					fOnChoosed: (bResetStage) => {
  						callback && callback();
  					}
  				});
  				return;
  			}
  		}
  		GameStatistics.statisCommonEvent(70001, `${mgrRole.bornCount}_${mgrCrossStage.getCurrStageId() || 0}_${mgrRole.getUsingPlayerRoleId()}`);
  		Director.openPanel("PanelStartBorn", {
  			fOnChoosed: () => {
  				callback && callback();
  			}
  		});
  	}
  	genStageMap(callback) {
  		console.warn("---------genStageMap------this.context.stageId=", mgrCrossStage.getCurrRealStageId(this.context.stageId));
  		this.stageData = db.get_amaze_cloth_crossing_stage_db(mgrCrossStage.getCurrRealStageId(this.context.stageId));
  		let stagePrefab1 = Tools.randomGotOneArrayData(this.stageData.stagePool1);
  		let stagePrefab2 = Tools.randomGotOneArrayData(this.stageData.stagePool2);
  		let stagePrefab3 = null;
  		if (this.stageData.stagePool3) {
  			stagePrefab3 = Tools.randomGotOneArrayData(this.stageData.stagePool3);
  		}
  		let animationIdArr = [];
  		let roleId = mgrRole.getCurrentPropertyRoleId(true);
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(roleId);
  		this.cornerQuestionId = 0;
  		this.bAdCornerQuestion = mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelQuestionEvent_question);
  		if (this.bAdCornerQuestion) {
  			let bDisableCornerVideoAd = db.cop_db[`b_disable_stage_corner_video_ad${this.stageData.id}`];
  			if (bDisableCornerVideoAd) {
  				this.bAdCornerQuestion = false;
  			}
  		}
  		if (!!this.bAdCornerQuestion && !mgrCrossStage.isPlayedStage(this.stageData.id)) {
  			let template = db.get_amaze_cloth_crossing_question_db(this.stageData.firstAdCornerQuestionId);
  			if (!!template) {
  				if ((!!db.get_ggg_retinue_template_db(template.relationRewardRoleId, 1) && !!mgrRetinue.getRetinueLevelById(template.relationRewardRoleId)) ||
  					(!!db.get_ggg_pet_template_db(template.relationRewardRoleId, 1) && !!mgrPet.getGotPetIdLevel(template.relationRewardRoleId))) {
  				}
  				else {
  					this.cornerQuestionId = this.stageData.firstAdCornerQuestionId || this.cornerQuestionId;
  				}
  			}
  		}
  		if (!!this.bAdCornerQuestion && !this.cornerQuestionId) {
  			let validAdRetinueQuestionIdArr = [];
  			let mustAdCornerQidArr = this.stageData.afterFirstMustGotAdRetinuePetCornerQuestionIdArr;
  			for (let k in mustAdCornerQidArr) {
  				let tmpId = mustAdCornerQidArr[k];
  				let template = db.get_amaze_cloth_crossing_question_db(tmpId);
  				if (!template) {
  					continue;
  				}
  				if ((!!db.get_ggg_retinue_template_db(template.relationRewardRoleId, 1) && !!mgrRetinue.getRetinueLevelById(template.relationRewardRoleId)) ||
  					(!!db.get_ggg_pet_template_db(template.relationRewardRoleId, 1) && !!mgrPet.getGotPetIdLevel(template.relationRewardRoleId))) {
  					continue;
  				}
  				validAdRetinueQuestionIdArr.push(tmpId);
  			}
  			if (validAdRetinueQuestionIdArr.length > 0) {
  				this.cornerQuestionId = Tools.randomGotOneArrayData(validAdRetinueQuestionIdArr);
  			}
  		}
  		if (!this.cornerQuestionId) {
  			let bUseAd = Tools.random(100) < this.stageData.positionAdCornerRatio ? true : false;
  			if (!!this.bAdCornerQuestion && bUseAd) {
  				let validAdRetinueQuestionIdArr = [];
  				for (let k in roleData.cornerAdRetinueQuestionArr) {
  					let tmpId = roleData.cornerAdRetinueQuestionArr[k];
  					let template = db.get_amaze_cloth_crossing_question_db(tmpId);
  					if (!template) {
  						continue;
  					}
  					if ((!!db.get_ggg_retinue_template_db(template.relationRewardRoleId, 1) && !!mgrRetinue.getRetinueLevelById(template.relationRewardRoleId)) ||
  						(!!db.get_ggg_pet_template_db(template.relationRewardRoleId, 1) && !!mgrPet.getGotPetIdLevel(template.relationRewardRoleId))) {
  						continue;
  					}
  					validAdRetinueQuestionIdArr.push(tmpId);
  				}
  				let arr = null;
  				if (validAdRetinueQuestionIdArr.length > 0) {
  					arr = Tools.random(100) > 50 ? roleData.cornerAdPropertyQuestionArr : validAdRetinueQuestionIdArr;
  				}
  				else {
  					arr = roleData.cornerAdPropertyQuestionArr;
  				}
  				this.cornerQuestionId = Tools.randomGotOneArrayData(arr);
  			}
  			if (!this.cornerQuestionId && roleData.cornerNoAdQuestionArr && roleData.cornerNoAdQuestionArr.length > 0) {
  				this.cornerQuestionId = Tools.randomGotOneArrayData(roleData.cornerNoAdQuestionArr);
  				this.bAdCornerQuestion = false;
  			}
  		}
  		if (!mgrCrossStage.isPlayedStage(this.stageData.id)) {
  			stagePrefab1 = this.stageData.firstStageModelId1;
  			stagePrefab2 = this.stageData.firstStageModelId2;
  			stagePrefab3 = this.stageData.firstStageModelId3 || stagePrefab3;
  		}
  		stagePrefab1 = stagePrefab1 || Tools.randomGotOneArrayData(this.stageData.stagePool1);
  		stagePrefab2 = stagePrefab2 || Tools.randomGotOneArrayData(this.stageData.stagePool2);
  		let modelIdArr = [stagePrefab1, stagePrefab2];
  		if (!!stagePrefab3) {
  			modelIdArr.push(stagePrefab3);
  		}
  		let roleIdDict = {};
  		roleIdDict[roleId] = roleId;
  		for (let k in roleIdDict) {
  			let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(roleIdDict[k]);
  			let baseRoleData = db.get_amaze_cloth_crossing_role_db(roleData.roleId);
  			animationIdArr.push(baseRoleData.movIdle);
  			animationIdArr.push(baseRoleData.movWalk);
  		}
  		Director.showWait("preload_stage_res");
  		this.doProloadResByIds(modelIdArr, animationIdArr, null, null, () => {
  			if (this.isDisposed) {
  				return;
  			}
  			this.currUsingStagePrefabNameArr = [
  				stagePrefab1,
  				stagePrefab2
  			];
  			if (stagePrefab3) {
  				this.currUsingStagePrefabNameArr.push(stagePrefab3);
  			}
  			this._doGenStageMap(callback);
  		});
  	}
  	_getNodeChildTialAmount(herderStr, node) {
  		let numChildren = node.numChildren;
  		for (let i = 0; i < numChildren; i++) {
  			let nodeTmp = node.getChildAt(i);
  			if (nodeTmp.name.startsWith(herderStr)) {
  				return parseFloat(nodeTmp.name.replace(herderStr, "")) || 0;
  			}
  		}
  		return 0;
  	}
  	_getMaxPropertyValueIndex() {
  		let propertyInfoArr = mgrRole.getSortedPropertyIndexArr(this.currentProperty1, this.currentProperty2, this.currentProperty3, this.currentProperty4);
  		return propertyInfoArr[0].propertyIndex;
  	}
  	_getPropertyValueIndexByRank(rank) {
  		let propertyInfoArr = mgrRole.getSortedPropertyIndexArr(this.currentProperty1, this.currentProperty2, this.currentProperty3, this.currentProperty4);
  		let propertyInfo = propertyInfoArr[rank - 1] || propertyInfoArr[0];
  		return propertyInfo.propertyIndex;
  	}
  	_getItemIdByPropertyRankAndAmount(rank, amount, propertyIndex) {
  		let propertyInfoArr = [
  			{ propertyIndex: 1, propertyValue: this.currentProperty1 },
  			{ propertyIndex: 2, propertyValue: this.currentProperty2 },
  			{ propertyIndex: 3, propertyValue: this.currentProperty3 },
  			{ propertyIndex: 4, propertyValue: this.currentProperty4 },
  		];
  		let property2ItemId = {
  			[1]: { addModleId: "yuanbao", subModleId: "dasuan", addEffName: "", subEffName: "130_e_loop_smoke_02" },
  			[2]: { addModleId: "shanzi", subModleId: "dasuan", addEffName: "", subEffName: "130_e_loop_smoke_02" },
  			[3]: { addModleId: "shuji", subModleId: "dasuan", addEffName: "", subEffName: "130_e_loop_smoke_02" },
  			[4]: { addModleId: "dizi", subModleId: "dasuan", addEffName: "", subEffName: "130_e_loop_smoke_02" },
  			[102]: { addModleId: "tongqian", subModleId: "yuhu", addEffName: "", subEffName: "" },
  			[103]: { addModleId: "sudu", subModleId: "yuhu", addEffName: "", subEffName: "" },
  			[104]: { addModleId: "zhengling", subModleId: "zhengling", addEffName: "", subEffName: "" },
  			[120]: { addModleId: "xingyunfu", subModleId: "xingyunfu", addEffName: "130_e_fuxy_loop_01", subEffName: "130_e_fuxy_loop_01" },
  			[121]: { addModleId: "daomeifu", subModleId: "daomeifu", addEffName: "130_e_fudm_loop_01", subEffName: "130_e_fudm_loop_01" },
  		};
  		if (propertyIndex) {
  			let info = propertyInfoArr[propertyIndex - 1];
  			let itemInfo = property2ItemId[info.propertyIndex];
  			let modelId = amount > 0 ? itemInfo.addModleId : itemInfo.subModleId;
  			let effName = amount > 0 ? itemInfo.addEffName : itemInfo.subEffName;
  			return {
  				modelId: modelId,
  				amount: amount,
  				propertyIndex: info.propertyIndex,
  				itemRankId: rank,
  				effName: effName,
  			};
  		}
  		if (rank > 100) {
  			let dataTmp = property2ItemId[rank];
  			let modelId = amount > 0 ? dataTmp.addModleId : dataTmp.subModleId;
  			let effName = amount > 0 ? dataTmp.addEffName : dataTmp.subEffName;
  			return {
  				modelId: modelId,
  				amount: amount,
  				propertyIndex: 0,
  				itemRankId: rank,
  				effName: effName,
  			};
  		}
  		propertyInfoArr = Tools.sortArrayByField(propertyInfoArr, "-propertyValue");
  		for (let i = 0; i < propertyInfoArr.length; i++) {
  			if ((i + 1) != rank) {
  				continue;
  			}
  			let info = propertyInfoArr[i];
  			let itemInfo = property2ItemId[info.propertyIndex];
  			let modelId = amount > 0 ? itemInfo.addModleId : itemInfo.subModleId;
  			let effName = amount > 0 ? itemInfo.addEffName : itemInfo.subEffName;
  			return {
  				modelId: modelId,
  				amount: amount,
  				propertyIndex: info.propertyIndex,
  				itemRankId: rank,
  				effName: effName,
  			};
  		}
  	}
  	_removeAllMeshRendererChild(node) {
  		let numChildren = node.numChildren;
  		if (!numChildren) {
  			return;
  		}
  		for (let i = (numChildren - 1); i >= 0; i--) {
  			let child = node.getChildAt(i);
  			if (Tools.getMeshRender(child)) {
  				child.removeSelf();
  			}
  		}
  	}
  	_doGenStageMap(callback) {
  		this.currUsingStageNodeArr = [];
  		this.recreateMapSky(this.stageData.bDuskSky);
  		let stageScale = 1;
  		this.mapStage = new Laya.Sprite3D;
  		this.mapStage.transform.setWorldLossyScale(new Laya.Vector3(stageScale, stageScale, stageScale));
  		this.linkModelAtBack(this.mapStage);
  		this.avatarPlayerNode = new Laya.Sprite3D;
  		this.linkModelAtBack(this.avatarPlayerNode);
  		this.avatarPlayerContainer = new Laya.Sprite3D;
  		this.avatarPlayerNode.addChild(this.avatarPlayerContainer);
  		this.avatarPlayerFollowerNode = new Laya.Sprite3D;
  		this.linkModelAtBack(this.avatarPlayerFollowerNode);
  		this.avatarFollowerNode = new Laya.Sprite3D;
  		this.avatarFollowerNode.transform.localPositionZ = 100;
  		this.linkModelAtBack(this.avatarFollowerNode);
  		this.petFollowerNode = new Laya.Sprite3D;
  		this.petFollowerNode.transform.localPositionZ = 100;
  		this.linkModelAtBack(this.petFollowerNode);
  		if (!!this.snowEffect && !this.snowEffect.destroyed) {
  			this.snowEffect.active = (this.stageData && this.stageData.bSnowEffect) ? true : false;
  		}
  		this.avatarPlayerNode.active = !this.bStartStageNowOnce;
  		let stagePrefab1 = this.currUsingStagePrefabNameArr[0];
  		let stageNode = Global.poolManager.get(Model, stagePrefab1);
  		this.mapStage.addChild(stageNode);
  		this.currUsingStageNodeArr.push(stageNode);
  		let road = stageNode.resNode.getChildByName("roads");
  		let crossPathInfoArr = [];
  		let rightAngleInfoArr = [];
  		let questtionInfoArr = [];
  		let obstacleInfoArr = [];
  		let baseYInfoArr = [];
  		let numChildren = road.numChildren;
  		let lastRoadNode = null;
  		let lastRoadNodeLen = 0;
  		for (let i = 0; i < numChildren; i++) {
  			let crossNode = road.getChildAt(i);
  			lastRoadNode = crossNode;
  			let bCross = !!crossNode.getChildByName("crossing");
  			let rotToLeftFlagNode = crossNode.getChildByName("RotToLeftFlag");
  			let rotToRightFlagNode = crossNode.getChildByName("RotToRightFlag");
  			let questionNode = crossNode.getChildByName("question");
  			let baseYNode = crossNode.getChildByName("baseY");
  			let currLen = this._getNodeChildTialAmount("len", crossNode) || this.ROAD_MODEL_DEFAULT_LEN;
  			lastRoadNodeLen = currLen;
  			if (!!baseYNode) {
  				baseYInfoArr.push({ node: baseYNode, len: currLen });
  			}
  			if (bCross) {
  				let crossConfig = {
  					len: currLen,
  					roadNode: crossNode
  				};
  				crossPathInfoArr.push(crossConfig);
  			}
  			else if (!!rotToLeftFlagNode || !!rotToRightFlagNode) {
  				rightAngleInfoArr.push({
  					node: rotToLeftFlagNode || rotToRightFlagNode,
  					bLeft: !!rotToLeftFlagNode
  				});
  			}
  			if (!!questionNode) {
  				let questionId = this._getNodeChildTialAmount("questionId", questionNode) || 0;
  				questtionInfoArr.push({ id: questionId || 0, bCross: bCross, crossNode: crossNode, questionNode: questionNode, bPreloaded: false, bCreatedDoor: false });
  			}
  		}
  		let items = stageNode.resNode.getChildByName("items");
  		if (!!items) {
  			numChildren = items.numChildren;
  			for (let i = 0; i < numChildren; i++) {
  				let combineNode = items.getChildAt(i);
  				let tmpNumChildren = combineNode.numChildren;
  				for (let tmp = 0; tmp < tmpNumChildren; tmp++) {
  					let itemHolder = combineNode.getChildAt(tmp);
  					this._removeAllMeshRendererChild(itemHolder);
  					let propertyIndex = this._getNodeChildTialAmount("property", itemHolder) || 0;
  					if (!!itemHolder.getChildByName("userpty")) {
  						propertyIndex = mgrRole.getUsingGrownupLine();
  					}
  					let rank = this._getNodeChildTialAmount("rank", itemHolder) || 1;
  					let amount = this._getNodeChildTialAmount("count", itemHolder) || 1;
  					let ratio = this._getNodeChildTialAmount("ratio", itemHolder) || 1;
  					let itemInfo = this._getItemIdByPropertyRankAndAmount(rank, amount, propertyIndex);
  					if (!!itemInfo) {
  						let data = {
  							holder: itemHolder,
  							itemModel: Global.poolManager.get(Model, itemInfo.modelId),
  							propertyIndex: itemInfo.propertyIndex,
  							amount: itemInfo.amount,
  							itemRankId: itemInfo.itemRankId,
  							ratio: ratio,
  							itemEffModel: !!itemInfo.effName ? Global.poolManager.get(Model, itemInfo.effName) : null,
  						};
  						itemHolder.addChild(data.itemModel);
  						data.itemModel.transform.localPosition = new Laya.Vector3;
  						if (!!data.itemEffModel) {
  							itemHolder.addChild(data.itemEffModel);
  							data.itemEffModel.transform.localPosition = new Laya.Vector3;
  						}
  						if (Math.abs(ratio) >= this.BIG_ITEM_RATIO) {
  							data.itemModel.transform.setWorldLossyScale(new Laya.Vector3(this.BIG_ITEM_SCALE, this.BIG_ITEM_SCALE, this.BIG_ITEM_SCALE));
  						}
  						else {
  							data.itemModel.transform.setWorldLossyScale(new Laya.Vector3(1, 1, 1));
  						}
  						this.itemsInfoArr.push(data);
  						cc$1.tween(itemHolder.transform)
  							.repeatForever(cc$1.tween().by(2, { localRotationEulerY: 360 }))
  							.start();
  					}
  					else {
  						itemHolder.active = false;
  					}
  				}
  			}
  		}
  		let obstacles = stageNode.resNode.getChildByName("obstacles");
  		if (!!obstacles) {
  			numChildren = obstacles.numChildren;
  			for (let i = 0; i < numChildren; i++) {
  				let obstacle = obstacles.getChildAt(i);
  				let eventid = this._getNodeChildTialAmount("eventid", obstacle);
  				let roleid = this._getNodeChildTialAmount("roleid", obstacle);
  				let ratio = this._getNodeChildTialAmount("ratio", obstacle) || 1;
  				if (!eventid) {
  					obstacle.active = false;
  					continue;
  				}
  				let eventData = db.get_amaze_cloth_crossing_road_event_db(eventid);
  				obstacle.active = true;
  				let npcAvatar = null;
  				if (roleid && db.get_amaze_cloth_crossing_role_db(roleid)) {
  					npcAvatar = new NpcAvatar(roleid);
  					let roleIdHolder = obstacle.getChildByName(`roleid${roleid}`);
  					if (!!eventData && !!eventData.moveType) {
  						roleIdHolder.transform.localPosition = new Laya.Vector3;
  					}
  					if (!!roleIdHolder) {
  						npcAvatar.transform.localPosition = new Laya.Vector3(roleIdHolder.transform.localPosition.x, roleIdHolder.transform.localPosition.y + 0.1, roleIdHolder.transform.localPosition.z);
  					}
  					npcAvatar.registerAllLoadEndCallback(() => {
  						if (eventData.idleQuoteName && eventData.idleQuoteName != "") {
  							npcAvatar.playAnimationQuote(eventData.idleQuoteName, 0, null, null, true);
  						}
  					});
  					obstacle.addChild(npcAvatar);
  				}
  				obstacle["_originPos"] = obstacle.transform.localPosition.clone();
  				let data = {
  					eventId: eventid,
  					roleId: !!npcAvatar ? roleid : null,
  					npcAvatar: npcAvatar,
  					holder: obstacle,
  					bMoveHandled: false,
  					bHited: false,
  					ratio: ratio
  				};
  				obstacleInfoArr.push(data);
  			}
  		}
  		let crossRoadNode1 = !!crossPathInfoArr.length ? crossPathInfoArr[0].roadNode : lastRoadNode;
  		let crossRoadNodeLen1 = !!crossPathInfoArr.length ? 0 : lastRoadNodeLen;
  		let stagePrefab2 = this.currUsingStagePrefabNameArr[1];
  		let stageNode2 = Global.poolManager.get(Model, stagePrefab2);
  		this.currUsingStageNodeArr.push(stageNode2);
  		stageNode2.transform.localPositionZ = -crossRoadNodeLen1;
  		crossRoadNode1.addChild(stageNode2);
  		for (let pathIndex = 1; pathIndex <= this.PATH_COUNT; pathIndex++) {
  			let items = stageNode2.resNode.getChildByName("items" + pathIndex);
  			if (!!items) {
  				numChildren = items.numChildren;
  				for (let i = 0; i < numChildren; i++) {
  					let combineNode = items.getChildAt(i);
  					let tmpNumChildren = combineNode.numChildren;
  					for (let tmp = 0; tmp < tmpNumChildren; tmp++) {
  						let itemHolder = combineNode.getChildAt(tmp);
  						this._removeAllMeshRendererChild(itemHolder);
  					}
  				}
  			}
  		}
  		if (this.currUsingStagePrefabNameArr.length > 2) {
  			for (let i = 1; i < this.currUsingStagePrefabNameArr.length; i++) {
  				let stageNode = this.currUsingStageNodeArr[i];
  				if (!stageNode) {
  					let stagePrefab = this.currUsingStagePrefabNameArr[i];
  					stageNode = Global.poolManager.get(Model, stagePrefab);
  					this.mapStage.addChild(stageNode);
  					stageNode.active = false;
  					this.currUsingStageNodeArr.push(stageNode);
  				}
  				for (let pathIndex = 1; pathIndex <= this.PATH_COUNT; pathIndex++) {
  					let items = stageNode.resNode.getChildByName("items" + pathIndex);
  					if (!!items) {
  						numChildren = items.numChildren;
  						for (let i = 0; i < numChildren; i++) {
  							let combineNode = items.getChildAt(i);
  							let tmpNumChildren = combineNode.numChildren;
  							for (let tmp = 0; tmp < tmpNumChildren; tmp++) {
  								let itemHolder = combineNode.getChildAt(tmp);
  								this._removeAllMeshRendererChild(itemHolder);
  							}
  						}
  					}
  				}
  			}
  		}
  		let questionData = db.get_amaze_cloth_crossing_question_db(this.resultQuestionId);
  		let jiesuantaiModelId = null;
  		if (this.stageData.id == 1 && !mgrCrossStage.isPlayedStage(this.stageData.id)) {
  			jiesuantaiModelId = "jiesuantai2";
  		}
  		else {
  			if (!!this.stageData.jiesuantaiModelIdArr && this.stageData.jiesuantaiModelIdArr.length > 0) {
  				jiesuantaiModelId = Tools.randomGotOneArrayData(this.stageData.jiesuantaiModelIdArr);
  			}
  			else {
  				let jiesuantaiModelIdArr = (!!questionData && questionData.jiesuantaiModelIdArr.length != 0) ? questionData.jiesuantaiModelIdArr : ["jiesuantai", "jiesuantai2", "jiesuantai3", "jiesuantai4"];
  				jiesuantaiModelId = Tools.randomGotOneArrayData(jiesuantaiModelIdArr);
  			}
  		}
  		let pNode = this.currUsingStageNodeArr[this.currUsingStageNodeArr.length - 1];
  		let jiesuantai = Global.poolManager.get(Model, jiesuantaiModelId);
  		pNode.addChild(jiesuantai);
  		jiesuantai.transform.localPositionZ = 1000;
  		this.jiesuantaiModel = jiesuantai;
  		this.crossPathInfoArr = crossPathInfoArr;
  		this.rightAngleInfoArr = rightAngleInfoArr;
  		this.questtionInfoArr = questtionInfoArr;
  		this.obstacleInfoArr = obstacleInfoArr;
  		this.cornerInfoArr = [];
  		this.baseYInfoArr = baseYInfoArr;
  		if (!this.crossPathInfoArr.length) {
  			Timer.callLoop(0.016, (timer) => {
  				if (!this.jiesuantaiModel.resNode) {
  					return;
  				}
  				timer.stop();
  				timer = null;
  				this._initStageNode2DataAfterCrossed(1, undefined, callback);
  			}, this);
  		}
  		else {
  			callback && callback();
  		}
  	}
  	_initStageNode2DataAfterCrossed(stageNodeIndex, pathIndex, callback) {
  		pathIndex = pathIndex || 0;
  		let stageNode = this.currUsingStageNodeArr[stageNodeIndex] || this.currUsingStageNodeArr[this.currUsingStageNodeArr.length - 1];
  		let crossPathInfoArr = this.crossPathInfoArr;
  		let rightAngleInfoArr = this.rightAngleInfoArr;
  		let questtionInfoArr = this.questtionInfoArr;
  		let obstacleInfoArr = this.obstacleInfoArr;
  		let cornerInfoArr = this.cornerInfoArr;
  		let baseYInfoArr = this.baseYInfoArr;
  		let stagePrefabNext = this.currUsingStageNodeArr[stageNodeIndex + 1];
  		if (!stagePrefabNext) {
  			this.jiesuantaiModel.removeSelf();
  			this.jiesuantaiModel.transform.localPosition = new Laya.Vector3;
  			let pNode = stageNode.resNode.getChildByName("jiesuantai" + pathIndex);
  			pNode.addChild(this.jiesuantaiModel);
  			this.finishNode = this.jiesuantaiModel.resNode.getChildByName("finishNode");
  			this.judgeNode2 = this.jiesuantaiModel.resNode.getChildByName("judgeNode2");
  		}
  		let road = stageNode.resNode.getChildByName("roads" + pathIndex);
  		let numChildren = road.numChildren;
  		if (!!stagePrefabNext) {
  			stagePrefabNext.removeSelf();
  			let preStageNodeLastRoadNode = road.getChildAt(numChildren - 1);
  			preStageNodeLastRoadNode.addChild(stagePrefabNext);
  			stagePrefabNext.transform.localPosition = new Laya.Vector3;
  			stagePrefabNext.transform.localRotationEuler = new Laya.Vector3;
  			stagePrefabNext.active = true;
  		}
  		for (let i = 0; i < numChildren; i++) {
  			let crossNode = road.getChildAt(i);
  			let bCross = !!crossNode.getChildByName("crossing");
  			let rotToLeftFlagNode = crossNode.getChildByName("RotToLeftFlag");
  			let rotToRightFlagNode = crossNode.getChildByName("RotToRightFlag");
  			let questionNode = crossNode.getChildByName("question");
  			let baseYNode = crossNode.getChildByName("baseY");
  			let currLen = this._getNodeChildTialAmount("len", crossNode) || this.ROAD_MODEL_DEFAULT_LEN;
  			if (!!baseYNode) {
  				baseYInfoArr.push({ node: baseYNode, len: currLen });
  			}
  			if (bCross) {
  				let crossConfig = {
  					len: currLen,
  					roadNode: crossNode
  				};
  				crossPathInfoArr.push(crossConfig);
  			}
  			else if (!!rotToLeftFlagNode || !!rotToRightFlagNode) {
  				rightAngleInfoArr.push({
  					node: rotToLeftFlagNode || rotToRightFlagNode,
  					bLeft: !!rotToLeftFlagNode
  				});
  			}
  			if (!!questionNode) {
  				questtionInfoArr.push({ id: 0, bCross: bCross, crossNode: crossNode, questionNode: questionNode, bPreloaded: false, bCreatedDoor: false });
  			}
  		}
  		let items = stageNode.resNode.getChildByName("items" + pathIndex);
  		if (!!items) {
  			numChildren = items.numChildren;
  			for (let i = 0; i < numChildren; i++) {
  				let combineNode = items.getChildAt(i);
  				let tmpNumChildren = combineNode.numChildren;
  				for (let tmp = 0; tmp < tmpNumChildren; tmp++) {
  					let itemHolder = combineNode.getChildAt(tmp);
  					this._removeAllMeshRendererChild(itemHolder);
  					let propertyIndex = this._getNodeChildTialAmount("property", itemHolder) || 0;
  					if (!!itemHolder.getChildByName("userpty")) {
  						propertyIndex = mgrRole.getUsingGrownupLine();
  					}
  					let rank = this._getNodeChildTialAmount("rank", itemHolder) || 1;
  					let amount = this._getNodeChildTialAmount("count", itemHolder) || 1;
  					let ratio = this._getNodeChildTialAmount("ratio", itemHolder) || 1;
  					let itemInfo = this._getItemIdByPropertyRankAndAmount(rank, amount, propertyIndex);
  					if (!!itemInfo) {
  						let data = {
  							holder: itemHolder,
  							itemModel: Global.poolManager.get(Model, itemInfo.modelId),
  							propertyIndex: itemInfo.propertyIndex,
  							amount: itemInfo.amount,
  							itemRankId: itemInfo.itemRankId,
  							ratio: ratio,
  							itemEffModel: !!itemInfo.effName ? Global.poolManager.get(Model, itemInfo.effName) : null,
  						};
  						itemHolder.addChild(data.itemModel);
  						data.itemModel.transform.localPosition = new Laya.Vector3;
  						if (!!data.itemEffModel) {
  							itemHolder.addChild(data.itemEffModel);
  							data.itemEffModel.transform.localPosition = new Laya.Vector3;
  						}
  						if (Math.abs(ratio) >= this.BIG_ITEM_RATIO) {
  							data.itemModel.transform.setWorldLossyScale(new Laya.Vector3(this.BIG_ITEM_SCALE, this.BIG_ITEM_SCALE, this.BIG_ITEM_SCALE));
  						}
  						else {
  							data.itemModel.transform.setWorldLossyScale(new Laya.Vector3(1, 1, 1));
  						}
  						this.itemsInfoArr.push(data);
  						cc$1.tween(itemHolder.transform)
  							.repeatForever(cc$1.tween().by(2, { localRotationEulerY: 360 }))
  							.start();
  					}
  					else {
  						itemHolder.active = false;
  					}
  				}
  			}
  		}
  		let obstacles = stageNode.resNode.getChildByName("obstacles" + pathIndex);
  		if (!!obstacles) {
  			numChildren = obstacles.numChildren;
  			for (let i = 0; i < numChildren; i++) {
  				let obstacle = obstacles.getChildAt(i);
  				let eventid = this._getNodeChildTialAmount("eventid", obstacle);
  				let roleid = this._getNodeChildTialAmount("roleid", obstacle);
  				let ratio = this._getNodeChildTialAmount("ratio", obstacle) || 1;
  				if (!eventid) {
  					obstacle.active = false;
  					continue;
  				}
  				let eventData = db.get_amaze_cloth_crossing_road_event_db(eventid);
  				obstacle.active = true;
  				let npcAvatar = null;
  				if (roleid && db.get_amaze_cloth_crossing_role_db(roleid)) {
  					npcAvatar = new NpcAvatar(roleid);
  					let roleIdHolder = obstacle.getChildByName(`roleid${roleid}`);
  					if (!!eventData && !!eventData.moveType) {
  						roleIdHolder.transform.localPosition = new Laya.Vector3;
  					}
  					if (!!roleIdHolder) {
  						npcAvatar.transform.localPosition = new Laya.Vector3(roleIdHolder.transform.localPosition.x, roleIdHolder.transform.localPosition.y + 0.1, roleIdHolder.transform.localPosition.z);
  					}
  					npcAvatar.registerAllLoadEndCallback(() => {
  						if (eventData.idleQuoteName && eventData.idleQuoteName != "") {
  							npcAvatar.playAnimationQuote(eventData.idleQuoteName, 0, null, null, true);
  						}
  					});
  					obstacle.addChild(npcAvatar);
  				}
  				obstacle["_originPos"] = obstacle.transform.localPosition.clone();
  				let data = {
  					eventId: eventid,
  					roleId: !!npcAvatar ? roleid : null,
  					npcAvatar: npcAvatar,
  					holder: obstacle,
  					bMoveHandled: false,
  					bHited: false,
  					bSkillChecked: false,
  					ratio: ratio,
  				};
  				obstacleInfoArr.push(data);
  			}
  		}
  		let corners = stageNode.resNode.getChildByName("corner" + pathIndex);
  		if (!!corners) {
  			numChildren = corners.numChildren;
  			for (let i = 0; i < numChildren; i++) {
  				let corner = corners.getChildAt(i);
  				let questionData = db.get_amaze_cloth_crossing_question_db(this.cornerQuestionId);
  				let roleid = questionData.relationRoleId || 3;
  				let roleid2 = questionData.relationRoleId2;
  				let npcAvatar = null;
  				if (roleid) {
  					let baseRoleData = db.get_amaze_cloth_crossing_role_db(roleid);
  					if (baseRoleData) {
  						npcAvatar = new NpcAvatar(roleid);
  						let roleIdHolder = corner.getChildByName("roleid");
  						npcAvatar.registerAllLoadEndCallback(() => {
  							if (questionData.relationRoleIdleQuoteNameInit && questionData.relationRoleIdleQuoteNameInit != "") {
  								npcAvatar.playAnimationQuote(questionData.relationRoleIdleQuoteNameInit, 0, null, null, true);
  							}
  							else {
  								npcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movIdle, 0, null, null, true);
  							}
  						});
  						corner.addChild(npcAvatar);
  						npcAvatar.transform.localPosition = roleIdHolder.transform.localPosition.clone();
  						npcAvatar.transform.localPositionY += 0.1;
  						npcAvatar.transform.localRotationEuler = roleIdHolder.transform.localRotationEuler.clone();
  					}
  				}
  				let npcAvatar2 = null;
  				if (roleid) {
  					let baseRoleData = db.get_amaze_cloth_crossing_role_db(roleid2);
  					if (baseRoleData) {
  						npcAvatar2 = new NpcAvatar(roleid2);
  						let roleIdHolder = corner.getChildByName("roleid");
  						npcAvatar2.registerAllLoadEndCallback(() => {
  							if (questionData.relationRoleIdleQuoteNameInit && questionData.relationRoleIdleQuoteNameInit != "") {
  								npcAvatar2.playAnimationQuote(questionData.relationRoleIdleQuoteNameInit, 0, null, null, true);
  							}
  							else {
  								npcAvatar2.playAnimationQuote(ROLE_QUOTE_MOV.movIdle, 0, null, null, true);
  							}
  						});
  						corner.addChild(npcAvatar2);
  						npcAvatar2.transform.localPosition = roleIdHolder.transform.localPosition.clone();
  						npcAvatar2.transform.localPositionY += 0.1;
  						npcAvatar2.transform.localRotationEuler = roleIdHolder.transform.localRotationEuler.clone();
  						npcAvatar.transform.localPositionX -= 0.3;
  						npcAvatar2.transform.localPositionX += 0.3;
  						let trialPetTemplateData = db.get_ggg_pet_template_db(questionData.relationRewardRoleId, 0);
  						let scale = trialPetTemplateData.scale || 1;
  						npcAvatar2.transform.setWorldLossyScale(new Laya.Vector3(scale, scale, scale));
  					}
  				}
  				corner["_originPos"] = corner.transform.localPosition.clone();
  				let data = {
  					questionId: questionData.id,
  					npcAvatar: npcAvatar,
  					npcAvatar2: npcAvatar2,
  					holder: corner,
  					bHited: false
  				};
  				cornerInfoArr.push(data);
  			}
  		}
  		if (!!pathIndex) {
  			this.preloadQuestionAndCreateDoor(callback);
  		}
  		else {
  			callback && callback();
  		}
  	}
  	genStageQuestion(callback) {
  		let imagePathDict = {};
  		let modelIdDict = {};
  		for (let k in this.questtionInfoArr) {
  			let info = this.questtionInfoArr[k];
  			if (info.bPreloaded) {
  				continue;
  			}
  			info.bPreloaded = true;
  			let data = db.get_amaze_cloth_crossing_question_db(info.id);
  			imagePathDict[data.imgQuestion] = true;
  			for (let i = 1; i <= this.PATH_COUNT; i++) {
  				modelIdDict[data["modelIdDecoAnswer" + i]] = true;
  				imagePathDict[data["imgAnswer" + i]] = true;
  			}
  		}
  		let dbMap = db.get_amaze_cloth_crossing_question_road_db_map();
  		for (let k in dbMap) {
  			imagePathDict[dbMap[k].texture] = true;
  		}
  		let preRess = [];
  		for (let modelId in modelIdDict) {
  			let modelData = db.get_model_db(modelId);
  			preRess.push({
  				url: modelData.resPath,
  				type: RES_TYPE.PREFAB3D,
  			});
  		}
  		for (let path in imagePathDict) {
  			preRess.push({
  				url: path,
  				type: RES_TYPE.TEXTURE2D,
  			});
  		}
  		let onResLoadSuccessed = () => {
  			for (let k in this.questtionInfoArr) {
  				let info = this.questtionInfoArr[k];
  				if (info.bCreatedDoor) {
  					continue;
  				}
  				info.bCreatedDoor = true;
  				let data = db.get_amaze_cloth_crossing_question_db(info.id);
  				for (let i = 1; i <= this.PATH_COUNT; i++) {
  					let holder = info.questionNode.getChildByName(`holder${i}`);
  					holder["_originPos"] = holder.transform.localPosition.clone();
  					holder.transform.localRotationEulerX = -5;
  					let modelName = data["modelIdDecoAnswer" + i];
  					let model = Global.poolManager.get(Model, modelName);
  					holder.addChild(model);
  					let renderer = null;
  					let tmpNode = model.resNode.getChildByName("wenzi");
  					if (!!tmpNode) {
  						renderer = Tools.getMeshRender(tmpNode);
  					}
  					if (renderer) {
  						let matArr = [];
  						let mat = renderer.sharedMaterials[0].clone();
  						let text2d = null;
  						let texture = ResLoader.getRes(data["imgAnswer" + i]);
  						if (texture instanceof Laya.Texture2D) {
  							text2d = texture;
  						}
  						else {
  							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();
  						text2d.anisoLevel = 4;
  						mat.albedoTexture = text2d;
  						matArr.push(mat);
  						renderer.sharedMaterials = matArr;
  					}
  					if (i == 2) {
  						let model = Global.poolManager.get(Model, "timu");
  						info.questionNode.addChild(model);
  						model.transform.localPositionY = 2.7;
  						let renderer = null;
  						let tmpNode = model.resNode.getChildByName("timu");
  						if (!!tmpNode) {
  							renderer = Tools.getMeshRender(tmpNode);
  						}
  						if (renderer) {
  							let matArr = [];
  							let mat = renderer.sharedMaterials[0].clone();
  							let text2d = null;
  							let texture = ResLoader.getRes(data.imgQuestion);
  							if (texture instanceof Laya.Texture2D) {
  								text2d = texture;
  							}
  							else {
  								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();
  							text2d.anisoLevel = 4;
  							mat.albedoTexture = text2d;
  							matArr.push(mat);
  							renderer.sharedMaterials = matArr;
  						}
  					}
  					holder.transform.localScale = new Laya.Vector3(0.85, 0.85, 0.85);
  				}
  			}
  		};
  		this.doProloadRes(preRess, () => {
  			callback && callback();
  			if (this.isDisposed) {
  				return;
  			}
  			onResLoadSuccessed();
  		});
  	}
  	preloadQuestionAndCreateDoor(callback) {
  		let questionArr = null;
  		if (this.stageData.assignQuestionArr && this.stageData.assignQuestionArr.length > 0) {
  			questionArr = Tools.deepCopy(this.stageData.assignQuestionArr);
  		}
  		else {
  			let data = db.get_amaze_cloth_crossing_property_to_logic_role(this.playerRoleId);
  			questionArr = Tools.deepCopy(data.questionArr);
  		}
  		let questionIdArr = [];
  		questionIdArr = Tools.randomGotArrayDatas(questionArr, this.questtionInfoArr.length);
  		while (questionIdArr.length < this.questtionInfoArr.length) {
  			let tmp = Tools.randomGotOneArrayData(questionArr);
  			questionIdArr.push(tmp);
  		}
  		if (this.nextCrossQuestionId) {
  			questionIdArr[0] = this.nextCrossQuestionId;
  			this.nextCrossQuestionId = null;
  		}
  		let doorModelId = ["men_red",
  			"men_green",
  			"men_blue"];
  		let doorModelIdArr = Tools.randomGotArrayDatas(doorModelId, 3);
  		let tmpIndex = 0;
  		for (let i = 0; i < this.questtionInfoArr.length; i++) {
  			if (!!this.questtionInfoArr[i].id) {
  				continue;
  			}
  			this.questtionInfoArr[i].id = questionIdArr[tmpIndex];
  			tmpIndex++;
  			if (this.stageData.id == 1) {
  				continue;
  			}
  			let dataCopy = Tools.deepCopy(db.get_amaze_cloth_crossing_question_db(questionIdArr[i]));
  			let data = db.get_amaze_cloth_crossing_question_db(questionIdArr[i]);
  			let changeFieldPreNameArr = [
  				"imgAnswer",
  				"modelIdDecoAnswer",
  				"answerScore",
  				"answeredRoadItemId",
  				"questionRoadId",
  				"wordAnsweredTip",
  				"effectNameAnsweredTip",
  				"answerScorePropertyIndex"
  			];
  			let pathArr = [];
  			for (let i = 1; i <= this.PATH_COUNT; i++) {
  				dataCopy["modelIdDecoAnswer" + i] = doorModelIdArr[i - 1] || doorModelIdArr[0];
  				pathArr.push(i);
  			}
  			let indexArr = Tools.randomGotArrayDatas(pathArr, pathArr.length);
  			for (let k in indexArr) {
  				let oIndex = parseInt(k) + 1;
  				let nIndex = indexArr[k];
  				for (let tmp in changeFieldPreNameArr) {
  					let preName = changeFieldPreNameArr[tmp];
  					data[preName + oIndex] = dataCopy[preName + nIndex];
  				}
  			}
  		}
  		this.genStageQuestion(callback);
  	}
  	resetDataOnStart() {
  		mgrRetinue.cleanTriggeredSkill();
  		this.bRecordNextResultQuestion = false;
  		this.nextCrossQuestionId = 0;
  		this.luckyFinishTime = 0;
  		this.unluckyFinishTime = 0;
  		this.samePropertyItemComboCount = 0;
  		this.lastHitedPropertyItemRankId = 0;
  		this.currStageTrialRetinueId = 0;
  		this.lastCrossInfoIndex = -1;
  		this.bStageTimeOver = false;
  		this.bObsacleHiting = false;
  		this.currStageSpeedOffset = 0;
  		this.currStageSpeedOffsetCompletedTime = 0;
  		this.currStageGotGoldAmount = 0;
  		this.currStageGotDecreeAmount = 0;
  		this.successResultShowUsingBaseRoleId = 0;
  		this.bShowedPreview = false;
  		this.MOVE_FPS = this.stageData.moveFps;
  		this.touchMoveBorderAppedXValue = 0;
  		this.comStartGuide.visible = true;
  		this.bTouchedOnce = false;
  		this.currPointNodeIndex = -1;
  		this.baseRoadX = 0;
  		this.bTouchBg = false;
  		this.lastTouchBgPos = null;
  		this.touchBgBeginPos = null;
  		this.touchBgBeginAvatarPosX = 0;
  		this.currRightAngleInfoCheckIndex = 0;
  		this.currRightAngleInfoCheckIndexEnemy = 0;
  		this.gotCoinValue = 0;
  		this.currDisOfEnemyWithPlayer = this.DISTANCE_ENEMY_WHITH_PLAYER;
  		this.currEnemyCrossRightAngleOffsetX = 0;
  		this.currEnemyTouchOffsetXRatio = -1.5 / this.ROAD_WH;
  		this.currEnemyAutoTouchOffsetXRatioTarget = this.currEnemyTouchOffsetXRatio;
  		this.currentEnemyExp = 0;
  		this.currPlayerCrossPathRoadIndex = 0;
  		this.currEnemyCrossPathRoadIndex = 0;
  		this.currPlayerCrossPathPoints = [];
  		this.currEnemyCrossPathPoints = [];
  		this.currPlayerBaseCrossRoadX = 0;
  		this.currEnemyBaseCrossRoadX = 0;
  		this.currPlayerLastTouchResultMapAvatarPositionX = 0;
  		this.nextAutoChangeEnemyTouchOffsetXRatioTime = 0;
  		this.hitedObstacleCountTriggerProtect = 0;
  		this.bEnemyArrived = false;
  		this.bPlayerArrived = false;
  		this.bFinishArea = false;
  		this.sameUserTouchPosAvatarMovingFrameCount = 0;
  		this.sameUserTouchPosIgnoreAvatarFrameCount = 0;
  		this.currStageArrivedPlayerRoleIdDict = {};
  		this.playerPosPathArr = [];
  		this.bPlayerCrossingDoor = false;
  		this.bEnemyPassStage = false;
  		this.bPlayerPassStage = false;
  		this.bJudgeAvatarRepositioned = false;
  		this.bJudgeAvatarJudged = false;
  		this.bChangeCameraParamBeforeArrivedArea = false;
  		this.bQuestionAreaSlowSpeed = false;
  		this.bNeedReAdaptAvatar = false;
  		this.currentProperty1 = mgrRole.getProperty1();
  		this.currentProperty2 = mgrRole.getProperty2();
  		this.currentProperty3 = mgrRole.getProperty3();
  		this.currentProperty4 = mgrRole.getProperty4();
  		this.playerRoleId = mgrRole.getCurrentPropertyRoleId(true);
  		this.startRoleId = this.playerRoleId;
  		this.startProperty1 = this.currentProperty1;
  		this.startProperty2 = this.currentProperty2;
  		this.startProperty3 = this.currentProperty3;
  		this.startProperty4 = this.currentProperty4;
  		this.bAdEventing = false;
  		UiHelper.unregisterTouchEvent(this.graphEvent);
  		this.comScrollTip.visible = false;
  		this.comMask.visible = false;
  	}
  	cleanModels() {
  		this.changeEnvironmentColor(new Laya.Color(1, 1, 1));
  		this.currUsingPlayerAvatar = null;
  		if (!!this.mapSky && !this.mapSky.destroyed) {
  			this.mapSky.transform.localRotationEuler = new Laya.Vector3;
  		}
  		this.changeJiesuanTaiDoor(false, true);
  		if (this.successResultShowNpcAvatar && !this.successResultShowNpcAvatar.destroyed) {
  			this.successResultShowNpcAvatar.destroy();
  			this.successResultShowNpcAvatar = null;
  		}
  		if (this.successResultShowNpcAvatar2 && !this.successResultShowNpcAvatar2.destroyed) {
  			this.successResultShowNpcAvatar2.destroy();
  			this.successResultShowNpcAvatar2 = null;
  		}
  		if (this.successHelpResultShowNpcAvatar && !this.successHelpResultShowNpcAvatar.destroyed) {
  			this.successHelpResultShowNpcAvatar.destroy();
  			this.successHelpResultShowNpcAvatar = null;
  		}
  		if (this.faildNpcAvatar && !this.faildNpcAvatar.destroyed) {
  			this.faildNpcAvatar.destroy();
  			this.faildNpcAvatar = null;
  		}
  		if (this.avatarFollower && !this.avatarFollower.destroyed) {
  			this.avatarFollower.destroy();
  			this.avatarFollower = null;
  		}
  		if (this.avatarFollowerNode && !this.avatarFollowerNode.destroyed) {
  			this.avatarFollowerNode.destroy();
  			this.avatarFollowerNode = null;
  		}
  		if (this.petFollowerNode && !this.petFollowerNode.destroyed) {
  			this.petFollowerNode.destroy();
  			this.petFollowerNode = null;
  		}
  		if (this.currSuccessResultEffect && !this.currSuccessResultEffect.destroyed) {
  			Global.poolManager.put(this.currSuccessResultEffect);
  			this.currSuccessResultEffect = null;
  		}
  		this.removePlayerAvatarEff();
  		this.removePlayerAvatarGroup2Eff();
  		if (!!this.jiesuantaiDoorEffect && !this.jiesuantaiDoorEffect.destroyed) {
  			Global.poolManager.put(this.jiesuantaiDoorEffect);
  			this.jiesuantaiDoorEffect = null;
  		}
  		if (!!this.jiesuantaiModel && !this.jiesuantaiModel.destroyed) {
  			Global.poolManager.put(this.jiesuantaiModel);
  			this.jiesuantaiModel = null;
  		}
  		if (!this.graphEvent.isDisposed) {
  			UiHelper.unregisterTouchEvent(this.graphEvent);
  			this.comScrollTip.visible = false;
  			this.comMask.visible = false;
  		}
  		if (!!this.avatarEnemyContainer && !this.avatarEnemyContainer.destroyed) {
  			let numChildren = this.avatarEnemyContainer.numChildren;
  			if (numChildren > 0) {
  				for (let i = (numChildren - 1); i >= 0; i--) {
  					let child = this.avatarEnemyContainer.getChildAt(i);
  					cc$1.tween(child).stop();
  					child.destroy();
  				}
  			}
  			this.avatarEnemyContainer.destroy();
  			this.avatarEnemyContainer = null;
  		}
  		if (!!this.avatarEnemyNode && !this.avatarEnemyNode.destroyed) {
  			let numChildren = this.avatarEnemyNode.numChildren;
  			if (numChildren > 0) {
  				for (let i = (numChildren - 1); i >= 0; i--) {
  					let child = this.avatarEnemyNode.getChildAt(i);
  					cc$1.tween(child).stop();
  					Global.poolManager.put(child);
  				}
  			}
  			this.avatarEnemyNode.destroy();
  			this.avatarEnemyNode = null;
  		}
  		if (!!this.avatarPlayerFollowerNode && !this.avatarPlayerFollowerNode.destroyed) {
  			let numChildren = this.avatarPlayerFollowerNode.numChildren;
  			if (numChildren > 0) {
  				for (let i = (numChildren - 1); i >= 0; i--) {
  					let avatar = this.avatarPlayerFollowerNode.getChildAt(i);
  					cc$1.tween(avatar.transform).stop();
  					avatar.destroy();
  				}
  			}
  			this.avatarPlayerFollowerNode.destroy();
  			this.avatarPlayerFollowerNode = null;
  		}
  		if (!!this.questtionInfoArr) {
  			for (let k in this.questtionInfoArr) {
  				let info = this.questtionInfoArr[k];
  				let timu = info.questionNode.getChildByName("timu");
  				if (timu) {
  					Global.poolManager.put(timu);
  				}
  				delete info.questionNode["bHited"];
  				for (let i = 1; i <= this.PATH_COUNT; i++) {
  					let holder = info.questionNode.getChildByName(`holder${i}`);
  					if (!holder) {
  						continue;
  					}
  					holder.transform.localPosition = holder["_originPos"] || holder.transform.localPosition;
  					holder.transform.localScale = new Laya.Vector3(1, 1, 1);
  					delete holder["_originPos"];
  					holder.active = true;
  					let numChildren = holder.numChildren;
  					if (numChildren > 0) {
  						for (let i = (numChildren - 1); i >= 0; i--) {
  							let child = holder.getChildAt(i);
  							if (child.resNode) {
  								let tmpNode = child.resNode.getChildByName("wenzi");
  								if (!!tmpNode) {
  									let renderer = Tools.getMeshRender(tmpNode);
  									if (!!renderer) {
  										let mat = renderer.sharedMaterials[0];
  										if (mat && mat.albedoTexture) {
  											mat.albedoTexture = null;
  										}
  									}
  								}
  							}
  							Global.poolManager.put(child);
  						}
  					}
  				}
  			}
  		}
  		if (!!this.cornerInfoArr) {
  			for (let k in this.cornerInfoArr) {
  				let data = this.cornerInfoArr[k];
  				if (!!data.holder && !data.holder.destroyed) {
  					cc$1.tween(data.holder.transform).stop();
  					data.holder.active = true;
  					data.holder.transform.localRotationEuler = new Laya.Vector3;
  				}
  				if (data.npcAvatar && !data.npcAvatar.destroyed) {
  					data.npcAvatar.destroy();
  				}
  				if (data.npcAvatar2 && !data.npcAvatar2.destroyed) {
  					data.npcAvatar.destroy();
  				}
  			}
  			this.cornerInfoArr = [];
  		}
  		if (!!this.itemsInfoArr) {
  			for (let k in this.itemsInfoArr) {
  				let data = this.itemsInfoArr[k];
  				if (!!data.holder && !data.holder.destroyed) {
  					cc$1.tween(data.holder.transform).stop();
  					data.holder.active = true;
  					data.holder.transform.localRotationEuler = new Laya.Vector3;
  				}
  				if (data.itemModel && !data.itemModel.destroyed) {
  					Global.poolManager.put(data.itemModel);
  				}
  				if (data.itemEffModel && !data.itemEffModel.destroyed) {
  					Global.poolManager.put(data.itemEffModel);
  				}
  			}
  			this.itemsInfoArr = [];
  		}
  		if (!!this.obstacleInfoArr) {
  			for (let k in this.obstacleInfoArr) {
  				let data = this.obstacleInfoArr[k];
  				if (!!data.npcAvatar && !data.npcAvatar.destroyed) {
  					cc$1.tween(data.npcAvatar.transform).stop();
  					data.npcAvatar.destroy();
  				}
  				if (!!data.holder && !data.holder.destroyed) {
  					cc$1.tween(data.holder.transform).stop();
  					data.holder.active = true;
  					data.holder.transform.localRotationEuler = new Laya.Vector3;
  					if (data.holder["_originPos"]) {
  						data.holder.transform.localPosition = data.holder["_originPos"];
  						delete data.holder["_originPos"];
  					}
  				}
  			}
  			this.obstacleInfoArr = [];
  		}
  		if (!!this.crossPathInfoArr) {
  			let count = this.crossPathInfoArr.length;
  			for (let i = 0; i < count; i++) {
  				let info = this.crossPathInfoArr[i];
  				if (!info || !info.roadNode || info.roadNode.destroyed) {
  					continue;
  				}
  				delete info.roadNode["_bCrossed"];
  			}
  		}
  		if (!!this.pointNodeArr) {
  			for (let k in this.pointNodeArr) {
  				let node = this.pointNodeArr[k];
  				let numChildren = node.numChildren;
  				if (numChildren > 0) {
  					for (let i = numChildren; i >= 0; i--) {
  						let model = node.getChildAt(i);
  						if (model && !model.destroyed) {
  							cc$1.tween(model).stop();
  							Global.poolManager.put(model);
  						}
  					}
  				}
  			}
  			this.pointNodeArr = [];
  		}
  		if (!!this.flyEffectNode && !this.flyEffectNode.destroyed) {
  			cc$1.tween(this.flyEffectNode).stop();
  			Global.poolManager.put(this.flyEffectNode);
  			this.flyEffectNode = null;
  		}
  		if (!!this.avatarPlayerContainer && !this.avatarPlayerContainer.destroyed) {
  			let numChildren = this.avatarPlayerContainer.numChildren;
  			if (numChildren > 0) {
  				for (let i = (numChildren - 1); i >= 0; i--) {
  					let child = this.avatarPlayerContainer.getChildAt(i);
  					cc$1.tween(child).stop();
  					child.destroy();
  				}
  			}
  			this.avatarPlayerContainer.destroy();
  			this.avatarPlayerContainer = null;
  		}
  		if (!!this.avatarPlayerNode && !this.avatarPlayerNode.destroyed) {
  			let numChildren = this.avatarPlayerNode.numChildren;
  			if (numChildren > 0) {
  				for (let i = (numChildren - 1); i >= 0; i--) {
  					let child = this.avatarPlayerNode.getChildAt(i);
  					cc$1.tween(child).stop();
  					Global.poolManager.put(child);
  				}
  			}
  			this.avatarPlayerNode.destroy();
  			this.avatarPlayerNode = null;
  		}
  		for (let i = this.currUsingStageNodeArr.length - 1; i >= 0; i--) {
  			let stageNode = this.currUsingStageNodeArr[i];
  			Global.poolManager.put(stageNode);
  		}
  		if (!!this.mapStage && !this.mapStage.destroyed) {
  			let numChildren = this.mapStage.numChildren;
  			if (numChildren > 0) {
  				for (let i = (numChildren - 1); i >= 0; i--) {
  					let node = this.mapStage.getChildAt(i);
  					Global.poolManager.put(node);
  				}
  			}
  			this.mapStage.destroy();
  			this.mapStage = null;
  		}
  	}
  	getMoveFps() {
  		if (!!this.currStageSpeedOffset && Timer.time > this.currStageSpeedOffsetCompletedTime) {
  			this.currStageSpeedOffset = 0;
  		}
  		return this.MOVE_FPS + (this.currStageSpeedOffset || 0);
  	}
  	onTouchSpriteBg(e) {
  		if (this.stManager.getCurState() == this.st_turnReady) {
  			return;
  		}
  		if (this.stManager.getCurState() == this.st_waitStart) {
  			if (!this.bTouchedOnce && e.bBegin) {
  				let tryStartFunc = () => {
  					if (BaseFacade.mItem.getItemAmount(3) < 1) {
  						mgrTip.alertNotEnough(3, true);
  						return;
  					}
  					let goFunc = () => {
  						if (this.avatarPlayerNode && !this.avatarPlayerNode.destroyed) {
  							this.avatarPlayerNode.active = true;
  						}
  						this.comStartGuide.visible = false;
  						this.bTouchedOnce = true;
  						if (this.stageData.stageType != StageType.mainStage) {
  							this.button_position_up.setScale(0, 0);
  						}
  						this.stManager.setNextState(this.st_turnReady);
  						let expComponent = new ViewSubEnergyNumber({ icon: "res/icon/icon_tili.png" });
  						expComponent.create();
  						expComponent.setAmount(-1);
  						BaseFacade.mItem.subItem(3, 1, "开始游戏");
  					};
  					let tryTimelineFunc = () => {
  						if (!!this.stageData.startTimeline) {
  							let hideNode3DArr = [
  								this.mapStage,
  								this.avatarPlayerNode,
  								this.petFollowerNode,
  							];
  							for (let i = 0; i < hideNode3DArr.length; i++) {
  								let node = hideNode3DArr[i];
  								node["__tmpOriginPosX"] = node.transform.localPositionX;
  								node.transform.localPositionX = 1000;
  							}
  							let originResNodeX = this.resNode.x;
  							this.resNode.x += 3000;
  							this.comPlayerNameContainer.visible = false;
  							this.comChat.x -= 3000;
  							this.playTimeline(this.stageData.startTimeline, (clearBefore) => {
  								for (let i = 0; i < hideNode3DArr.length; i++) {
  									let node = hideNode3DArr[i];
  									node.transform.localPositionX = node["__tmpOriginPosX"] || 0;
  									delete node["__tmpOriginPosX"];
  								}
  								this.resNode.x = originResNodeX;
  								this.comChat.x += 3000;
  								this.comPlayerNameContainer.visible = true;
  								cc$1.tween(this.comChat).stop();
  								this.comChat.setScale(0, 0);
  								clearBefore();
  								goFunc();
  							}, null);
  						}
  						else {
  							goFunc();
  						}
  					};
  					let tipTrialRetinue = (callback) => {
  						let trialRetinueId = mgrRetinue.randomOneTrialRetinueId();
  						if (!!trialRetinueId && mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelTrail_trial)) {
  							let useCopKey = null;
  							let retinueData = db.get_ggg_retinue_template_db(trialRetinueId, 0);
  							if (retinueData.unlcokYears == this.stageData.id || !!this.stageData.bTrailUseGotRetinueCop) {
  								useCopKey = db.cop_db.pop_trial_retinue_ui_get_year_ratio;
  							}
  							else {
  								useCopKey = db.cop_db.pop_trial_retinue_ui_normal_year_ratio;
  							}
  							if (useCopKey && Tools.random(100) < useCopKey) {
  								Director.openPanel("PanelTrail", {
  									retinueId: trialRetinueId,
  									level: this.TRAIL_RETINUE_LV,
  									confirm: () => {
  										this.currStageTrialRetinueId = trialRetinueId;
  										callback && callback();
  									},
  									cancel: () => {
  										callback && callback();
  									},
  								});
  							}
  							else {
  								callback && callback();
  							}
  						}
  						else {
  							callback && callback();
  						}
  					};
  					tipTrialRetinue(() => {
  						tryTimelineFunc();
  					});
  				};
  				tryStartFunc();
  			}
  			return;
  		}
  		if (this.stManager.getCurState() != this.st_avatarMoving || !!this.bFinishArea) {
  			return;
  		}
  		if (e.bBegin) {
  			this.bTouchBg = true;
  			this.lastTouchBgPos = new Laya.Vector2(e.stageX, e.stageY);
  			this.touchBgBeginPos = new Laya.Vector2(e.stageX, e.stageY);
  			this.touchBgBeginAvatarPosX = this.avatarPlayerNode.transform.localPositionX - this.baseRoadX;
  			this.currPlayerLastTouchResultMapAvatarPositionX = this.touchBgBeginAvatarPosX;
  			this.sameUserTouchPosAvatarMovingFrameCount = 0;
  			this.sameUserTouchPosIgnoreAvatarFrameCount = 0;
  			this.preLastFrameCalculateTouchPos = null;
  			this.lastFrameCalculateTouchPos = null;
  			this.touchMoveBorderAppedXValue = 0;
  			this.comScrollTip.visible = false;
  		}
  		if (!this.bTouchBg) {
  			return;
  		}
  		if (e.bCancel || e.bEnd) {
  			this.bTouchBg = false;
  			this.lastTouchBgPos = null;
  			this.touchBgBeginPos = null;
  			if (db.cop_db.b_show_rocker_btn == 1) {
  				this.comScrollTip.visible = true;
  			}
  			else {
  				this.comScrollTip.visible = false;
  			}
  		}
  		if (!this.touchBgBeginPos) {
  			this.touchBgBeginPos = null;
  			this.lastTouchBgPos = null;
  			this.bTouchBg = false;
  		}
  		if (this.bTouchBg) {
  			this.lastTouchBgPos = new Laya.Vector2(e.stageX, e.stageY);
  		}
  	}
  	inInit() {
  		this.resetDataOnStart();
  		this.imageSpecialIcon.visible = !!this.stageData.bShowSpecialStageWord;
  		mgrSound.play(this.stageData.bgSoundId || this.DEFAULT_BG_SOUND_ID);
  		mgrSound.play(this.stageData.startSoundId);
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.playerRoleId);
  		let soundId = (!!roleData.firstIdSoundIdArr && roleData.firstIdSoundIdArr.length > 0) ? Tools.randomGotOneArrayData(roleData.firstIdSoundIdArr) : 0;
  		mgrSound.play(soundId);
  		this.labelTitleName.text = `第${this.context.stageId || mgrCrossStage.getCurrStageId()}年`;
  		cc$1.tween(this.comTopBar).toAlpha(0.3, 1).start();
  		cc$1.tween(this.comProgressBarStage).toAlpha(0.3, 1).start();
  		this.button_position_up.setScale(1, 1);
  		this.camera.farPlane = 500;
  		this.cameraFollow = this.camera.getComponent(CameraFollow);
  		this.cameraFollow.lookMode = E_CAMERA_MODE.fixMode;
  		let param = this.avatarPosCameraDict[0].cameraData;
  		this.cameraFollow.position = param.pos.clone();
  		this.cameraFollow.endRotation = param.rot.clone();
  		this.cameraFollow.fov = param.fov;
  		this.cameraFollow.lerpValue = 1;
  		this.cameraFollow.onLateUpdate();
  		this.avatarPlayerContainer.transform.localRotationEulerY = 90;
  		let avatarPlayer = new NpcAvatar(roleData.roleId);
  		this.avatarPlayerContainer.addChild(avatarPlayer);
  		avatarPlayer.registerLoadEndCallback(() => {
  			avatarPlayer.playIdle();
  			avatarPlayer.transform.localPosition = new Laya.Vector3(0, 0.1, 0);
  			this.playBtnsMoveIn();
  			this.preloadQuestionAndCreateDoor(() => {
  				this.stManager.setNextState(this.st_waitStart);
  			});
  		});
  		this.refreshPlayerTitleBar();
  		this.refreshPlayerProperty();
  		this.refreshGoldProperty();
  	}
  	exeInit() { }
  	outInit() { }
  	inWaitStart() {
  		Director.hideWait("preload_stage_res");
  		UiHelper.registerTouchEvent(this.graphEvent, this.onTouchSpriteBg.bind(this));
  		this.tryAddPet();
  		if (this.bStartStageNowOnce) {
  			this.bStartStageNowOnce = false;
  			this.onTouchSpriteBg({ bBegin: true });
  			this.onTouchSpriteBg({ bEnd: true });
  		}
  		else {
  			let guideType = 0;
  			if (this.stageData.stageType == StageType.mainStage) {
  				let stageTypeArr = [StageType.speedStage, StageType.goldStage];
  				for (let k in stageTypeArr) {
  					let sType = stageTypeArr[k];
  					if (!mgrChallenge.isUnlockedType(sType)) {
  						continue;
  					}
  					let amount = mgrChallenge.getChallengeAdRemainCount(sType) + mgrChallenge.getChallengeRemainCount(sType);
  					if (amount > 0 && mgrChallenge.getChallengeGuidedCount(sType) <= 0) {
  						mgrChallenge.markChallengeGuided(sType);
  						guideType = sType;
  						break;
  					}
  				}
  			}
  			if (!!guideType) {
  				if (guideType == StageType.goldStage) {
  					console.info("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
  					Director.openPanel("PanelSpecialStagePreview1");
  				}
  				else {
  					console.info("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
  					Director.openPanel("PanelSpecialStagePreview2");
  				}
  			}
  		}
  	}
  	exeWaitStart() { }
  	outWaitStart() {
  		if (this.timerPetShow) {
  			this.timerPetShow.stop();
  			this.timerPetShow = null;
  		}
  	}
  	inTurnReady() {
  		Timer.callLater(0.3, () => {
  			this.stManager.setNextState(this.st_avatarComing);
  		});
  	}
  	exeTurnReady() { }
  	outTurnReady() { }
  	tryComeInRetinue() {
  		if (this.stageData.stageType != StageType.mainStage) {
  			return;
  		}
  		let useRetinueId = this.currStageTrialRetinueId || mgrRetinue.followingRetinueId;
  		if (!!useRetinueId) {
  			let retinueLevel = !!this.currStageTrialRetinueId ? this.TRAIL_RETINUE_LV : mgrRetinue.getRetinueLevelById(useRetinueId);
  			let retinueData = db.get_ggg_retinue_template_db(useRetinueId, retinueLevel);
  			let avatarFollower = new NpcAvatar(retinueData.baseRoleId);
  			avatarFollower.transform.localRotationEulerY = 180;
  			this.avatarFollower = avatarFollower;
  			this.avatarFollower["_retinueId"] = useRetinueId;
  			this.avatarFollower["_retinueLevel"] = retinueLevel;
  			this.avatarFollowerNode.transform.localPosition = new Laya.Vector3(0.3, 0.1, this.currAvatarFollowerDistance);
  			this.avatarFollowerNode.addChild(avatarFollower);
  			avatarFollower.transform.localPosition = new Laya.Vector3(0, 0, 2);
  			avatarFollower.registerLoadEndCallback(() => {
  				avatarFollower.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  			});
  			cc$1.tween(this.avatarFollower.transform).toLocalPos3D(1.2, 0, 0, 0).start();
  		}
  	}
  	tryAddPet() {
  		if (this.timerPetShow) {
  			this.timerPetShow.stop();
  			this.timerPetShow = null;
  		}
  		if (this.stageData.stageType != StageType.mainStage) {
  			return;
  		}
  		if (!!mgrPet.followingPetId) {
  			if (this.petFollower || (!!this.petFollower && !this.petFollower.destroyed)) {
  				this.petFollower.destroy();
  				this.petFollower = null;
  			}
  			let petLevel = mgrPet.getGotPetIdLevel(mgrPet.followingPetId);
  			let petData = db.get_ggg_pet_template_db(mgrPet.followingPetId, petLevel);
  			let petFollower = new NpcAvatar(petData.baseRoleId);
  			petFollower.transform.localRotationEulerY = 90;
  			let scale = petData.scale || 1;
  			petFollower.transform.setWorldLossyScale(new Laya.Vector3(scale, scale, scale));
  			this.petFollower = petFollower;
  			this.petFollower["_petId"] = mgrPet.followingPetId;
  			this.petFollower["_petLevel"] = petLevel;
  			this.petFollowerNode.addChild(petFollower);
  			this.petFollowerNode.transform.localPosition = new Laya.Vector3(-0.4, 0.1, 0.7);
  			let movName = (this.stManager && this.stManager.getCurState() < this.st_avatarComing) ? ROLE_QUOTE_MOV.movIdle : ROLE_QUOTE_MOV.movWalk;
  			petFollower.registerLoadEndCallback(() => {
  				petFollower.playAnimationQuote(movName, 0, null, null, true, false);
  				if (this.stManager.getCurState() == this.st_waitStart) {
  					this.timerPetShow = Timer.callLoop(8, () => {
  						if (this.stManager.getCurState() != this.st_waitStart || !this.petFollower || this.petFollower.destroyed) {
  							if (this.timerPetShow) {
  								this.timerPetShow.stop();
  								this.timerPetShow = null;
  							}
  							return;
  						}
  						if (!this.bFocus) {
  							return;
  						}
  						if (petData.showAniSoundIdArr && petData.showAniSoundIdArr.length > 0) {
  							mgrSound.play(Tools.randomGotOneArrayData(petData.showAniSoundIdArr));
  						}
  						this.petFollower.playAnimationQuote(Tools.randomGotOneArrayData([ROLE_QUOTE_MOV.movIdle2, ROLE_QUOTE_MOV.movIdle3]), 0, null, () => {
  							if (!this.petFollower || this.petFollower.destroyed) {
  								return;
  							}
  							this.petFollower.playAnimationQuote(this.stManager.getCurState() != this.st_waitStart ? ROLE_QUOTE_MOV.movWalk : ROLE_QUOTE_MOV.movIdle, 0, null, null, true, false);
  						}, false, false);
  					}, this);
  				}
  			});
  		}
  	}
  	inAvatarComing() {
  		mgrSdk.startRecordVideo();
  		GameStatistics.statisOnStageStart(this.stageData.statisPointId, undefined, false, [`${mgrRole.bornCount}_${this.playerRoleId}`]);
  		this.adaptBannerAdv();
  		let param = this.avatarPosCameraDict[1].cameraData;
  		this.cameraFollow.lookMode = E_CAMERA_MODE.targetDistance;
  		this.cameraFollow.target = this.avatarPlayerNode;
  		this.cameraFollow.position = param.pos.clone();
  		this.cameraFollow.endRotation = param.rot.clone();
  		this.cameraFollow.fov = param.fov;
  		this.cameraFollow.offset = param.offset;
  		this.cameraFollow.distance = 6;
  		this.cameraFollow.lerpValue = 0.045;
  		this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true);
  		cc$1.tween(this.comTopBar).toAlpha(0.3, 0).start();
  		cc$1.tween(this.comProgressBarStage).toAlpha(0.3, 0).start();
  		this.playBtnsMoveOut();
  		this.refreshPlayerProperty();
  		this.playPropBtnsMoveIn();
  		this.tryComeInRetinue();
  	}
  	exeAvatarComing() {
  		if (!!this.petFollower && !this.petFollower.destroyed) {
  			this.petFollower.transform.localRotationEulerY = Tools.clamp(this.petFollower.transform.localRotationEulerY + 3, 90, 180);
  		}
  		this.avatarPlayerContainer.transform.localRotationEulerY += 1;
  		if (!!this.avatarEnemyContainer && !this.avatarEnemyContainer.destroyed) {
  			this.avatarEnemyContainer.transform.localRotationEulerY += 1;
  		}
  		if (this.avatarPlayerContainer.transform.localRotationEulerY >= 180) {
  			this.stManager.setNextState(this.st_stageStartTip);
  		}
  	}
  	outAvatarComing() {
  		this.avatarPlayerContainer.transform.localRotationEulerY = 180;
  		if (!!this.avatarEnemyContainer && !this.avatarEnemyContainer.destroyed) {
  			this.avatarEnemyContainer.transform.localRotationEulerY = 180;
  		}
  	}
  	inStageStartTip() {
  		if (this.stageData.startTip && this.stageData.startTip != "") {
  			Director.openPanel("PanelStageStartTip", {
  				desc: this.stageData.startTip,
  				fOnClose: () => {
  					this.stManager.setNextState(this.st_avatarMoving);
  				}
  			});
  		}
  		else {
  			this.stManager.setNextState(this.st_avatarMoving);
  		}
  	}
  	exeStageStartTip() {
  	}
  	outStageStartTip() {
  	}
  	inAvatarMoving() {
  		this.adaptBannerAdv();
  		if (this.petFollower) {
  			this.petFollower.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  		}
  		this.stageUsedTime = 0;
  	}
  	exeAvatarMoving(deltaTime) {
  		if (!this.bFocus || !!this.bAdEventing || this.bStageTimeOver) {
  			return;
  		}
  		this.stageUsedTime += deltaTime;
  		if (this.bObsacleHiting) {
  			return;
  		}
  		this.checkRightAngle();
  		this.forwardAvatar(deltaTime);
  		this.tryChangeCurrentPointNodeIndex();
  		this.checkItems(false);
  		this.checkCorner();
  		this.checkQuestion();
  		this.checkObstacle();
  		if (this.bObsacleHiting) {
  			return;
  		}
  		this.checkFinish();
  		this.playerFollowerHandle();
  		this.adaptBaseY();
  		this.checkTimerOver();
  	}
  	outAvatarMoving() {
  		if (!!this.avatarFollower && !this.avatarFollower.destroyed) {
  			this.avatarFollower.playIdle();
  		}
  		if (!!this.petFollower && !this.petFollower.destroyed) {
  			this.petFollower.playIdle();
  		}
  	}
  	getQuestionSlowSpeedAreaQuestionIndex() {
  		if (this.stageData && !!this.stageData.bDisableQuestionSlow) {
  			return -1;
  		}
  		let avatarNode = this.avatarPlayerNode;
  		let count = this.questtionInfoArr.length;
  		for (let i = 0; i < count; i++) {
  			let info = this.questtionInfoArr[i];
  			if (avatarNode.transform.position.z < info.crossNode.transform.position.z + 9 && avatarNode.transform.position.z > info.crossNode.transform.position.z + 0 &&
  				Math.abs(avatarNode.transform.position.x - info.crossNode.transform.position.x) < this.ROAD_WH) {
  				return i;
  			}
  		}
  		return -1;
  	}
  	getCurrentCrossRoadInfoIndex(bEnemy) {
  		let avatarNode = !bEnemy ? this.avatarPlayerNode : this.avatarEnemyNode;
  		let count = this.crossPathInfoArr.length;
  		for (let i = 0; i < count; i++) {
  			let info = this.crossPathInfoArr[i];
  			if (!!info.roadNode["_bCrossed"]) {
  				continue;
  			}
  			if (avatarNode.transform.position.z < info.roadNode.transform.position.z && avatarNode.transform.position.z >= (info.roadNode.transform.position.z - info.len) &&
  				Math.abs(avatarNode.transform.position.x - info.roadNode.transform.position.x) < this.ROAD_WH) {
  				return i;
  			}
  		}
  		return -1;
  	}
  	getCurrentCrossRoadPathPointByIndex(index) {
  		let crossInfoIndex = this.getCurrentCrossRoadInfoIndex();
  		if (crossInfoIndex < 0) {
  			return;
  		}
  		let info = this.crossPathInfoArr[crossInfoIndex];
  		let crossNode = info.roadNode;
  		let pathNode = crossNode.getChildByName("path" + index);
  		if (!pathNode) {
  			return;
  		}
  		let pathPoints = [];
  		let numChildren = pathNode.numChildren;
  		for (let i = 0; i < numChildren; i++) {
  			let node = pathNode.getChildAt(i);
  			if (node.name == "part") {
  				continue;
  			}
  			pathPoints.push(node.transform.position);
  		}
  		return pathPoints;
  	}
  	checkRightAngle() {
  		if (this.bRightAngleRotating) {
  			return;
  		}
  		let crossInfoIndex = this.getCurrentCrossRoadInfoIndex();
  		if (crossInfoIndex >= 0) {
  			return;
  		}
  		let avatarPos = this.avatarPlayerNode.transform.position;
  		let info = this.rightAngleInfoArr[this.currRightAngleInfoCheckIndex];
  		if (!info) {
  			return;
  		}
  		if (Math.abs(info.node.transform.position.x - avatarPos.x) < this.ROAD_WH && Math.abs(info.node.transform.position.z - avatarPos.z) < 0.01) {
  			this.bRightAngleRotating = true;
  			this.currRightAngleInfoCheckIndex++;
  			this.currEnemyCrossRightAngleOffsetX = Tools.random(20) / 10 * (Tools.random(100) > 50 ? -1 : 1);
  			this.currEnemyTouchOffsetXRatio = this.currEnemyCrossRightAngleOffsetX / this.ROAD_WH;
  			this.currDisOfEnemyWithPlayer += this.currEnemyCrossRightAngleOffsetX;
  			this.nextAutoChangeEnemyTouchOffsetXRatioTime = Timer.now + 3;
  			this.avatarPlayerNode.transform.localPositionZ = info.node.transform.position.z;
  			let tmpNode = new Laya.Sprite3D;
  			this.linkModelAtBack(tmpNode);
  			tmpNode.transform.position = this.avatarPlayerNode.transform.position.clone();
  			let oldMapStagePos = this.mapStage.transform.position.clone();
  			let oldMapStageRot = this.mapStage.transform.rotationEuler.clone();
  			this.mapStage.removeSelf();
  			tmpNode.addChild(this.mapStage);
  			this.mapStage.transform.position = oldMapStagePos;
  			this.mapStage.transform.rotationEuler = oldMapStageRot;
  			let rotFlag = (info.bLeft ? -1 : 1);
  			let targetRotY = 90 * rotFlag;
  			let template = db.get_amaze_cloth_crossing_config(1);
  			let dur = template.rightAngleRotateDur || 0.2;
  			let avatarRot = template.avatarSimulateAngle || 45;
  			cc$1.tween(this.mapSky.transform)
  				.to(dur, { localRotationEulerY: targetRotY })
  				.start();
  			cc$1.tween(tmpNode.transform)
  				.to(dur, { localRotationEulerY: targetRotY })
  				.call(() => {
  					oldMapStagePos = this.mapStage.transform.position.clone();
  					oldMapStageRot = this.mapStage.transform.rotationEuler.clone();
  					this.mapStage.removeSelf();
  					this.linkModelAtBack(this.mapStage);
  					this.mapStage.transform.position = oldMapStagePos;
  					this.mapStage.transform.rotationEuler = oldMapStageRot;
  				})
  				.delay(0.01)
  				.call(() => {
  					this.currPlayerLastTouchResultMapAvatarPositionX = 0;
  					this.baseRoadX = this.avatarPlayerNode.transform.localPositionX;
  					if (this.bTouchBg) {
  						this.touchBgBeginPos = this.lastTouchBgPos || new Laya.Vector2(Global.canvasWidth / 2, Global.canvasHeight / 2);
  						this.touchBgBeginAvatarPosX = this.avatarPlayerNode.transform.localPositionX - this.baseRoadX;
  						this.currPlayerLastTouchResultMapAvatarPositionX = this.touchBgBeginAvatarPosX;
  						this.touchMoveBorderAppedXValue = 0;
  						this.preLastFrameCalculateTouchPos = this.touchBgBeginPos.clone();
  						this.lastFrameCalculateTouchPos = this.touchBgBeginPos.clone();
  					}
  					cc$1.tween(tmpNode.transform).stop();
  					tmpNode.destroy();
  					this.obstacleHandlerAfterRightAngle();
  					this.bRightAngleRotating = false;
  				})
  				.start();
  			cc$1.tween(this.avatarPlayerContainer.transform)
  				.to(dur / 2, { localRotationEulerY: 180 - avatarRot * rotFlag })
  				.to(dur / 2, { localRotationEulerY: 180 })
  				.start();
  		}
  	}
  	forwardAvatar(deltaTime) {
  		if (this.bRightAngleRotating) {
  			return;
  		}
  		let crossInfoIndex = this.getCurrentCrossRoadInfoIndex();
  		if (crossInfoIndex < 0) {
  			let targetClampDis = this.ROAD_WH / 2;
  			let currClampDis = this.ROAD_WH / 2;
  			if (!this.cameraFollow.bEnableXClamp) {
  				currClampDis = Math.abs(this.avatarPlayerNode.transform.position.x - this.baseRoadX);
  			}
  			else {
  				let tmp = this.cameraFollow.maxTargetX - this.baseRoadX;
  				if (tmp > targetClampDis) {
  					currClampDis = Math.max(tmp - 0.01, targetClampDis);
  				}
  			}
  			this.cameraFollow.enableClampX(this.baseRoadX - currClampDis, this.baseRoadX + currClampDis);
  			if (!!this.currPlayerCrossPathRoadIndex) {
  				this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true);
  				this.currPlayerBaseCrossRoadX = 0;
  				this.avatarPlayerNode.transform.localPositionX += this.avatarPlayerContainer.transform.localPositionX;
  				this.avatarPlayerContainer.transform.localPositionX = 0;
  				this.currPlayerLastTouchResultMapAvatarPositionX = this.avatarPlayerNode.transform.position.x - this.baseRoadX;
  				if (this.bTouchBg) {
  					this.touchBgBeginPos = this.lastTouchBgPos || new Laya.Vector2(Global.canvasWidth / 2, Global.canvasHeight / 2);
  					this.touchBgBeginAvatarPosX = this.avatarPlayerNode.transform.localPositionX - this.baseRoadX;
  					this.preLastFrameCalculateTouchPos = this.touchBgBeginPos.clone();
  					this.lastFrameCalculateTouchPos = this.touchBgBeginPos.clone();
  				}
  			}
  			if (!this.bChangeCameraParamBeforeArrivedArea) {
  				this.cameraFollow.lerpValue = 0.1;
  			}
  			if (this.bTouchBg && this.lastTouchBgPos && this.touchBgBeginPos) {
  				let movDis = this.lastTouchBgPos.x - this.touchBgBeginPos.x;
  				movDis = Tools.clamp(movDis, -this.SCREEN_TOUCH_TOTAL_WIDTH, this.SCREEN_TOUCH_TOTAL_WIDTH);
  				if (!!this.lastFrameCalculateTouchPos && !!this.lastTouchBgPos) {
  					if (Math.abs(this.touchBgBeginPos.x - this.lastTouchBgPos.x) > 150 &&
  						(this.bMoveToLeft && this.lastFrameCalculateTouchPos.x < this.lastTouchBgPos.x) ||
  						(!this.bMoveToLeft && this.lastFrameCalculateTouchPos.x > this.lastTouchBgPos.x)) {
  						this.bMoveToLeft = !this.bMoveToLeft;
  						this.sameUserTouchPosAvatarMovingFrameCount = 0;
  						this.sameUserTouchPosIgnoreAvatarFrameCount = 0;
  						this.touchBgBeginPos = this.preLastFrameCalculateTouchPos.clone();
  						this.touchBgBeginAvatarPosX = this.avatarPlayerNode.transform.localPositionX - this.baseRoadX;
  						this.currPlayerLastTouchResultMapAvatarPositionX = this.touchBgBeginAvatarPosX;
  						movDis = this.lastTouchBgPos.x - this.lastFrameCalculateTouchPos.x;
  						this.touchMoveBorderAppedXValue = 0;
  						console.log("-----------------反向");
  					}
  				}
  				this.preLastFrameCalculateTouchPos = !!this.lastFrameCalculateTouchPos ? this.lastFrameCalculateTouchPos.clone() : this.lastTouchBgPos.clone();
  				this.lastFrameCalculateTouchPos = this.lastTouchBgPos.clone();
  				if (this.preLastFrameCalculateTouchPos.x != this.lastFrameCalculateTouchPos.x) {
  					this.bMoveToLeft = this.preLastFrameCalculateTouchPos.x > this.lastFrameCalculateTouchPos.x ? true : false;
  				}
  				let origin = Tools.clamp((Math.abs(movDis / this.SCREEN_TOUCH_TOTAL_WIDTH)), 0, 1) * (movDis > 0 ? 1 : -1) * this.ROAD_WH;
  				let newPosX = Tools.clamp(this.touchBgBeginAvatarPosX + origin, -this.ROAD_WH / 2, this.ROAD_WH / 2);
  				if (!this.touchMoveBorderAppedXValue && newPosX != this.currPlayerLastTouchResultMapAvatarPositionX) {
  					this.currPlayerLastTouchResultMapAvatarPositionX = newPosX;
  					this.sameUserTouchPosAvatarMovingFrameCount = 0;
  				}
  				else {
  					this.sameUserTouchPosAvatarMovingFrameCount++;
  					if (this.lastTouchBgPos.x > (Global.canvasWidth - 100) && !this.bMoveToLeft && this.currPlayerLastTouchResultMapAvatarPositionX < this.ROAD_WH / 2) {
  						this.sameUserTouchPosAvatarMovingFrameCount = 0;
  						this.sameUserTouchPosIgnoreAvatarFrameCount = 0;
  						this.touchBgBeginPos = this.lastTouchBgPos.clone();
  						this.touchMoveBorderAppedXValue += Math.min(deltaTime * 5, 0.03 * 5);
  						console.warn("-----------------继续向右走");
  					}
  					else if (this.lastTouchBgPos.x < 100 && this.bMoveToLeft && this.currPlayerLastTouchResultMapAvatarPositionX > -this.ROAD_WH / 2) {
  						this.sameUserTouchPosAvatarMovingFrameCount = 0;
  						this.sameUserTouchPosIgnoreAvatarFrameCount = 0;
  						this.touchBgBeginPos = this.lastTouchBgPos.clone();
  						this.touchMoveBorderAppedXValue -= Math.min(deltaTime * 5, 0.03 * 5);
  						console.warn("-----------------继续向左走");
  					}
  					else {
  						if (this.sameUserTouchPosAvatarMovingFrameCount > 30 && this.touchBgBeginAvatarPosX != this.currPlayerLastTouchResultMapAvatarPositionX) {
  							this.sameUserTouchPosAvatarMovingFrameCount = 0;
  							this.sameUserTouchPosIgnoreAvatarFrameCount = 0;
  							this.touchBgBeginAvatarPosX = this.avatarPlayerNode.transform.localPositionX - this.baseRoadX;
  							this.touchBgBeginPos = this.lastTouchBgPos.clone();
  							this.touchMoveBorderAppedXValue = 0;
  							this.preLastFrameCalculateTouchPos = null;
  							this.lastFrameCalculateTouchPos = null;
  							console.log("-----------------到达清0走");
  						}
  					}
  				}
  			}
  			this.currPlayerLastTouchResultMapAvatarPositionX = Tools.clamp(this.currPlayerLastTouchResultMapAvatarPositionX, -this.ROAD_WH / 2, this.ROAD_WH / 2);
  			this.avatarPlayerNode.transform.localPositionX = Tools.clamp(this.currPlayerLastTouchResultMapAvatarPositionX + this.touchMoveBorderAppedXValue, -this.ROAD_WH / 2, this.ROAD_WH / 2) + this.baseRoadX;
  			this.avatarPlayerNode.transform.localRotationEulerY = 0;
  			this.currPlayerCrossPathPoints = null;
  			delete this.avatarPlayerNode["_tmpPrePos"];
  			this.currPlayerCrossPathRoadIndex = 0;
  		}
  		else {
  			this.cameraFollow.disableClampX();
  			this.cameraFollow.lerpValue = 0.05;
  			let info = this.crossPathInfoArr[crossInfoIndex];
  			let questionInfo = this.questtionInfoArr[crossInfoIndex];
  			let crossNode = info.roadNode;
  			if (!this.currPlayerCrossPathPoints) {
  				this.lastCrossInfoIndex = crossInfoIndex;
  				mgrSound.play(105);
  				let offsetX = this.avatarPlayerNode.transform.position.x - crossNode.transform.position.x;
  				let index = 1;
  				if (offsetX == 0) {
  					index = Tools.randomGotOneArrayData([1, 2]);
  				}
  				else {
  					index = offsetX < 0 ? 1 : 2;
  				}
  				this.currPlayerCrossPathRoadIndex = index;
  				this.currPlayerCrossPathPoints = this.getCurrentCrossRoadPathPointByIndex(index);
  				let questionId = questionInfo.id;
  				let questionData = db.get_amaze_cloth_crossing_question_db(questionId);
  				this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true);
  				let pathNode = crossNode.getChildByName("path" + index);
  				let tmpRotNode = pathNode.getChildAt(pathNode.numChildren - 1);
  				this.rightAngleInfoArr.push({
  					node: tmpRotNode,
  					bLeft: index == 1 ? true : false
  				});
  				this.nextCrossQuestionId = questionData["nextQuestionId" + this.currPlayerCrossPathRoadIndex] || 0;
  				if (!this.stageData.bDisableGetScoreByCross) {
  					let amount = ((questionData["answerScore" + this.currPlayerCrossPathRoadIndex] || 0) + mgrRole.getCurrLevelGotPropertyExtrnalValue()) * (questionData.answerScoreRatio || 1);
  					let scoreRank = questionData["answerScorePropertyIndex" + this.currPlayerCrossPathRoadIndex] || 0;
  					let propertyIndex = null;
  					if (!!questionData.bAnswerScorePropertyIndexIsPropertyId) {
  						propertyIndex = scoreRank;
  					}
  					else {
  						propertyIndex = mgrRole.getUsingGrownupLine() || this._getPropertyValueIndexByRank(scoreRank);
  					}
  					let func = this["addProperty" + propertyIndex].bind(this);
  					func(Math.ceil(amount));
  					mgrRole.markAnsweredQuestionId(questionData.id);
  				}
  				this._initStageNode2DataAfterCrossed(crossInfoIndex + 1, this.currPlayerCrossPathRoadIndex);
  			}
  			let prePos = null;
  			let nextPos = null;
  			let posAvatar = this.avatarPlayerNode.transform.position;
  			for (let i = 0; i < this.currPlayerCrossPathPoints.length; i++) {
  				let pos = this.currPlayerCrossPathPoints[i];
  				if (posAvatar.z >= pos.z) {
  					prePos = this.currPlayerCrossPathPoints[i - 1];
  					nextPos = pos;
  					break;
  				}
  			}
  			if (!!nextPos) {
  				let targetX = 0;
  				let targetY = 0;
  				if (!prePos && !!nextPos) {
  					let tmpPrePos = this.avatarPlayerNode["_tmpPrePos"] = this.avatarPlayerNode["_tmpPrePos"] || this.avatarPlayerNode.transform.position.clone();
  					let ratio = Math.abs(this.avatarPlayerNode.transform.position.z - tmpPrePos.z) / Math.abs(tmpPrePos.z - nextPos.z);
  					targetX = tmpPrePos.x + (nextPos.x - tmpPrePos.x) * ratio;
  					targetY = tmpPrePos.y + (nextPos.y - tmpPrePos.y) * ratio;
  				}
  				else if (!!prePos && !!nextPos) {
  					let ratio = Math.abs(this.avatarPlayerNode.transform.position.z - prePos.z) / Math.abs(prePos.z - nextPos.z);
  					targetX = prePos.x + (nextPos.x - prePos.x) * ratio;
  					targetY = prePos.y + (nextPos.y - prePos.y) * ratio;
  				}
  				else {
  					console.warn("-----------------something wrong");
  				}
  				this.currPlayerBaseCrossRoadX = targetX - this.baseRoadX;
  				this.avatarPlayerNode.transform.localPositionX += (targetX - this.avatarPlayerNode.transform.localPositionX) * Math.min(1, 0.3 * this.getMoveFps());
  				this.avatarPlayerNode.transform.localPositionY = targetY;
  				if (!!prePos) {
  					let rot = Tools.getAngle(prePos.x, prePos.z, nextPos.x, nextPos.z);
  					this.avatarPlayerNode.transform.localRotationEulerY += (rot - this.avatarPlayerNode.transform.localRotationEulerY) / (Math.abs(rot - this.avatarPlayerNode.transform.localRotationEulerY) || 1) * 0.25 * this.getMoveFps();
  				}
  				if (this.bTouchBg && this.lastTouchBgPos && this.touchBgBeginPos) {
  					let smallRoadWidth = this.ROAD_SMALL_WH;
  					let tmpx = (this.lastTouchBgPos.x - this.touchBgBeginPos.x) / (130) * smallRoadWidth;
  					tmpx = Tools.clamp(tmpx, -smallRoadWidth / 2, smallRoadWidth / 2);
  					this.avatarPlayerContainer.transform.localPositionX = tmpx;
  				}
  			}
  		}
  		let rotEffFpsPercentValue = 0.4;
  		let useFps = this.getMoveFps() * (1 - Math.min(Math.abs(this.avatarPlayerNode.transform.localRotationEulerY) / 20, 1) * rotEffFpsPercentValue);
  		if (crossInfoIndex <= 0 && !!this.bQuestionAreaSlowSpeed) {
  			useFps = useFps * this.QUESTION_AREA_SLOW_SPEED_SCALE;
  		}
  		let dis = Math.min(deltaTime * useFps, 0.03 * useFps);
  		this.avatarPlayerNode.transform.localPositionZ -= dis;
  		this.avatarPlayerNode.transform.localPositionY = this.baseRoadY;
  		if (this.rightAngleInfoArr && (this.rightAngleInfoArr.length - 1) >= this.currRightAngleInfoCheckIndex) {
  			let info = this.rightAngleInfoArr[this.currRightAngleInfoCheckIndex];
  			if (info && this.avatarPlayerNode.transform.localPositionZ < info.node.transform.position.z) {
  				this.avatarPlayerNode.transform.localPositionZ = info.node.transform.position.z;
  				if (crossInfoIndex >= 0) {
  					let info = this.crossPathInfoArr[crossInfoIndex];
  					let crossNode = info.roadNode;
  					crossNode["_bCrossed"] = true;
  				}
  			}
  		}
  		if (!!this.currPlayerCrossPathPoints) {
  			this.mapSky.transform.position = this.avatarPlayerNode.transform.position;
  		}
  		else {
  			this.mapSky.transform.position = new Laya.Vector3(this.baseRoadX, this.avatarPlayerNode.transform.position.y, this.avatarPlayerNode.transform.position.z);
  		}
  		if (!this.bStartedFinishRotateCamera) {
  			if (!!this.jiesuantaiModel && !this.bChangeCameraParamBeforeArrivedArea &&
  				Math.abs(this.avatarPlayerNode.transform.position.z - this.jiesuantaiModel.resNode.transform.position.z) < 10 &&
  				Math.abs(this.avatarPlayerNode.transform.position.x - this.jiesuantaiModel.resNode.transform.position.x) < 10) {
  				this.bChangeCameraParamBeforeArrivedArea = true;
  				let param = this.avatarPosCameraDict[6].cameraData;
  				this.cameraFollow.lerpValue = 0.01;
  				this.cameraFollow.offset = new Laya.Vector3(param.offset.x, param.offset.y, param.offset.z);
  				this.cameraFollow.fov = param.fov;
  				this.cameraFollow.lerpValuePosZ = 0.1;
  			}
  			let cameraParamDictIndex = !this.bChangeCameraParamBeforeArrivedArea ? 1 : 6;
  			let param = this.avatarPosCameraDict[cameraParamDictIndex].cameraData;
  			this.cameraFollow.position = new Laya.Vector3(param.pos.x + this.avatarPlayerNode.transform.position.x, param.pos.y + this.avatarPlayerNode.transform.position.y, param.pos.z + this.avatarPlayerNode.transform.position.z);
  			this.cameraFollow.endRotation = new Laya.Vector3(param.rot.x, param.rot.y + this.avatarPlayerNode.transform.localRotationEulerY % 360, param.rot.z);
  		}
  		else {
  		}
  	}
  	tryChangeCurrentPointNodeIndex() {
  		let count = this.pointNodeArr.length;
  		for (let i = count - 1; i >= 0; i--) {
  			let pointNode = this.pointNodeArr[i];
  			if (pointNode.transform.position.z >= this.avatarPlayerNode.transform.position.z) {
  				this.currPointNodeIndex = i;
  				pointNode.active = true;
  				this.cameraFarPlaneTargetZ = Math.min(pointNode.transform.position.z - pointNode["_roadLen"], this.cameraFarPlaneTargetZ);
  				break;
  			}
  		}
  	}
  	refreshPlayerTitleBar() {
  		let loaderNameIcon1 = this.comPlayerNameContainer.getChild("loaderNameIcon1");
  		let progressExp = this.comPlayerNameContainer.getChild("progress");
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.playerRoleId);
  		if (loaderNameIcon1.url != roleData.nameIcon) {
  			loaderNameIcon1.url = roleData.nameIcon;
  		}
  		progressExp.visible = false;
  	}
  	showPlayerTitleBarProgress(value) {
  		let progressExp = this.comPlayerNameContainer.getChild("progress");
  		progressExp.value = value;
  		progressExp.visible = !!value;
  		progressExp.y = -315;
  	}
  	checkItems(bEnemy) {
  		let avatarPos = null;
  		if (bEnemy) {
  			avatarPos = this.avatarEnemyContainer.transform.position;
  		}
  		else {
  			avatarPos = this.avatarPlayerContainer.transform.position;
  		}
  		if (this.itemsInfoArr && this.itemsInfoArr.length > 0) {
  			for (let k in this.itemsInfoArr) {
  				let data = this.itemsInfoArr[k];
  				let model = data.holder;
  				if (!model.active || Math.abs(model.transform.position.z - avatarPos.z) > 0.5) {
  					continue;
  				}
  				if (Math.abs(model.transform.position.x - avatarPos.x) >= 0.5) {
  					continue;
  				}
  				cc$1.tween(model.transform).stop();
  				model.active = false;
  				this.onHitedItem(data);
  			}
  		}
  	}
  	addPlayerAvatarEff(effName, offsetPos) {
  		this.removePlayerAvatarEff();
  		this.currPlayerAvatarEffModel = Global.poolManager.get(Model, effName);
  		this.currPlayerAvatarEffModel.transform.localPosition = offsetPos || new Laya.Vector3(0, 0, 0);
  		this.avatarPlayerNode.addChild(this.currPlayerAvatarEffModel);
  		if (effName == "130_e_once_jiasubuff") {
  			this.currPlayerAvatarJiaSuEffModel = Global.poolManager.get(Model, "130_e_loop_jiasu");
  			this.currPlayerAvatarJiaSuEffModel.transform.localPosition = offsetPos || new Laya.Vector3(0, 0, 0);
  			this.currPlayerAvatarJiaSuEffModel.transform.localRotationEulerY = 180;
  			this.avatarPlayerNode.addChild(this.currPlayerAvatarJiaSuEffModel);
  		}
  	}
  	removePlayerAvatarEff() {
  		if (this.currPlayerAvatarEffModel && !this.currPlayerAvatarEffModel.destroyed) {
  			Global.poolManager.put(this.currPlayerAvatarEffModel);
  			this.currPlayerAvatarEffModel = null;
  		}
  		if (this.currPlayerAvatarJiaSuEffModel && !this.currPlayerAvatarJiaSuEffModel.destroyed) {
  			Global.poolManager.put(this.currPlayerAvatarJiaSuEffModel);
  			this.currPlayerAvatarJiaSuEffModel = null;
  		}
  	}
  	addPlayerAvatarGroup2Eff(effName, offsetPos) {
  		this.removePlayerAvatarGroup2Eff();
  		this.currPlayerAvatarEffGroup2Model = Global.poolManager.get(Model, effName);
  		this.currPlayerAvatarEffGroup2Model.transform.localPosition = offsetPos || new Laya.Vector3(0, 0, 0);
  		this.avatarPlayerNode.addChild(this.currPlayerAvatarEffGroup2Model);
  	}
  	removePlayerAvatarGroup2Eff() {
  		if (this.currPlayerAvatarEffGroup2Model && !this.currPlayerAvatarEffGroup2Model.destroyed) {
  			Global.poolManager.put(this.currPlayerAvatarEffGroup2Model);
  			this.currPlayerAvatarEffGroup2Model = null;
  		}
  	}
  	onHitedItem(itemData) {
  		let bDisableEff = false;
  		if (Math.abs(itemData.ratio) >= this.BIG_ITEM_RATIO) {
  			this.addPlayerAvatarEff("130_e_once_glow_baoji");
  			bDisableEff = true;
  		}
  		if (this.stageData.bComboPropertyItem) {
  			if (!this.lastHitedPropertyItemRankId) {
  				if (itemData.itemRankId && itemData.itemRankId >= 1 && itemData.itemRankId <= 4) {
  					this.lastHitedPropertyItemRankId = itemData.itemRankId;
  					this.samePropertyItemComboCount = 0;
  				}
  			}
  			else if (!!itemData.itemRankId && itemData.itemRankId == this.lastHitedPropertyItemRankId && (itemData.amount * (itemData.ratio || 1)) >= 1) {
  				this.samePropertyItemComboCount++;
  			}
  			else {
  				this.samePropertyItemComboCount = 0;
  				this.lastHitedPropertyItemRankId = 0;
  			}
  		}
  		if (itemData.itemRankId == this.ITEM_RANK_ID_GOLD) {
  			let useAmount = Math.ceil((itemData.amount + mgrRole.getCurrLevelGotPropertyExtrnalValue()) * (itemData.ratio || 1));
  			this.currStageGotGoldAmount = Math.max(0, this.currStageGotGoldAmount + useAmount);
  			if (!bDisableEff) {
  				this.addPlayerAvatarEff("130_e_once_glow_01", new Laya.Vector3(0, 1.2, 0));
  			}
  			let targetNode = this.comProperty102;
  			let worldPosEnd = targetNode.localToGlobal(0, 0);
  			let icon = "ui://base/art11";
  			let classView = null;
  			if (useAmount > 0) {
  				classView = ViewAddExpNumber;
  			}
  			else {
  				classView = ViewSubExpNumber;
  			}
  			let showCount = this.currStageGotGoldAmount;
  			let expComponent = new classView({
  				icon: icon, flyTargetPos: worldPosEnd, fOnCompleted: () => {
  					if (!this.resNode || this.resNode.isDisposed) {
  						return;
  					}
  					cc$1.tween(targetNode).toScale(0.1, 1.3).toScale(0.1, 1).start();
  					this.refreshGoldProperty(showCount);
  				}
  			});
  			expComponent.create();
  			if (useAmount > 0) {
  				mgrSound.play(121);
  			}
  			else {
  				mgrSound.play(123);
  			}
  			expComponent.setAmount(useAmount);
  			if (itemData.amount < 0) {
  				this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movWalk3, 0, null, null, true, false);
  				if (this.timerOnHitItemSlowSpeed) {
  					this.timerOnHitItemSlowSpeed.stop();
  					this.timerOnHitItemSlowSpeed = null;
  				}
  				this.timerOnHitItemSlowSpeed = Timer.callLater(1.5, () => {
  					this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  				}, this);
  			}
  			return;
  		}
  		else if (itemData.itemRankId == this.ITEM_RANK_ID_SPEED) {
  			if (itemData.amount < 0) {
  				if (mgrChannel.vibrateEnable) {
  					mgrSdk.vibrate();
  				}
  			}
  			if (!bDisableEff) {
  				let effName = itemData.amount > 0 ? "130_e_once_jiasubuff" : "130_e_once_jiansubuff";
  				this.addPlayerAvatarEff(effName);
  			}
  			mgrSound.play(itemData.amount > 0 ? 122 : 123);
  			this.currStageSpeedOffset = itemData.amount > 0 ? this.MOVE_FPS_SPEED_OFFSET : -this.MOVE_FPS_SPEED_OFFSET;
  			let delayTime = (itemData.amount > 0 ? 3 : 2);
  			this.currStageSpeedOffsetCompletedTime = Timer.time + delayTime;
  			if (itemData.amount < 0) {
  				this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movWalk3, 0, null, null, true, false);
  				if (this.timerOnHitItemSlowSpeed) {
  					this.timerOnHitItemSlowSpeed.stop();
  					this.timerOnHitItemSlowSpeed = null;
  				}
  				this.timerOnHitItemSlowSpeed = Timer.callLater(delayTime, () => {
  					this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  				}, this);
  			}
  			return;
  		}
  		else if (itemData.itemRankId == this.ITEM_RANK_ID_DECREE) {
  			let useAmount = Math.ceil(itemData.amount * (itemData.ratio || 1));
  			this.currStageGotDecreeAmount = Math.max(0, this.currStageGotDecreeAmount + useAmount);
  			if (!bDisableEff) {
  				this.addPlayerAvatarEff("130_e_once_glow_01", new Laya.Vector3(0, 1.2, 0));
  			}
  			let targetNode = this.comProperty104;
  			let worldPosEnd = targetNode.localToGlobal(0, 0);
  			let icon = "ui://base/art12";
  			let classView = null;
  			if (useAmount > 0) {
  				classView = ViewAddExpNumber;
  			}
  			else {
  				classView = ViewSubExpNumber;
  			}
  			let showCount = this.currStageGotDecreeAmount;
  			let expComponent = new classView({
  				icon: icon, flyTargetPos: worldPosEnd, fOnCompleted: () => {
  					if (!this.resNode || this.resNode.isDisposed) {
  						return;
  					}
  					cc$1.tween(targetNode).toScale(0.1, 1.3).toScale(0.1, 1).start();
  					this.refreshDecreeProperty(showCount);
  				}
  			});
  			expComponent.create();
  			if (useAmount > 0) {
  				mgrSound.play(121);
  			}
  			else {
  				mgrSound.play(123);
  			}
  			expComponent.setAmount(useAmount);
  			if (itemData.amount < 0) {
  				this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movWalk3, 0, null, null, true, false);
  				if (this.timerOnHitItemSlowSpeed) {
  					this.timerOnHitItemSlowSpeed.stop();
  					this.timerOnHitItemSlowSpeed = null;
  				}
  				this.timerOnHitItemSlowSpeed = Timer.callLater(1.5, () => {
  					this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  				}, this);
  			}
  			return;
  		}
  		else if (itemData.itemRankId == this.ITEM_RANK_ID_LUCKY) {
  			this.luckyFinishTime = Timer.time + 10;
  			this.unluckyFinishTime = 0;
  			this.addPlayerAvatarGroup2Eff("130_e_fuxy_loop_02");
  			return;
  		}
  		else if (itemData.itemRankId == this.ITEM_RANK_ID_UNLUCKY) {
  			this.luckyFinishTime = 0;
  			this.unluckyFinishTime = Timer.time + 10;
  			this.addPlayerAvatarGroup2Eff("130_e_fudm_loop_02");
  			return;
  		}
  		if (itemData.amount < 0) {
  			let propertyIndex = mgrRole.getUsingGrownupLine() || this._getMaxPropertyValueIndex();
  			itemData.propertyIndex = propertyIndex;
  			if (mgrChannel.vibrateEnable) {
  				mgrSdk.vibrate();
  			}
  		}
  		let func = this["addProperty" + itemData.propertyIndex].bind(this);
  		if (itemData.amount != 0) {
  			let amount = 0;
  			if (itemData.amount > 0) {
  				amount = (itemData.amount + mgrRole.getCurrLevelGotPropertyExtrnalValue()) * (itemData.ratio || 1);
  			}
  			else {
  				amount = (itemData.amount - mgrRole.getCurrLevelGotPropertyExtrnalValue()) * Math.abs(itemData.ratio || 1);
  			}
  			let bTriggeredSkill = false;
  			if (this.avatarFollower && amount < 0) {
  				let retinueId = this.avatarFollower["_retinueId"];
  				let level = this.avatarFollower["_retinueLevel"];
  				let retinueTemplate = db.get_ggg_retinue_template_db(retinueId, level);
  				if (retinueTemplate.skillId == SkillType.stageCoin) {
  					let result = mgrRetinue.tryTriggerRetinueSkill(retinueId, level);
  					if (!!result && result.bTriggered) {
  						if (!this.avatarFollower.isPlayingQuote(retinueTemplate.skillMovName)) {
  							mgrSound.play(retinueTemplate.useSkillSoundId);
  							this.avatarFollower.playAnimationQuote(retinueTemplate.skillMovName, 0, null, () => {
  								this.avatarFollower.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  							}, true, false);
  						}
  						this.addPlayerAvatarEff("130_e_skill_ty_01");
  						bTriggeredSkill = true;
  					}
  				}
  			}
  			if (!bTriggeredSkill) {
  				let tmpAmount = Math.ceil(amount);
  				let luckAmount = 0;
  				if (tmpAmount > 0) {
  					if (Timer.time < this.luckyFinishTime) {
  						luckAmount = tmpAmount;
  					}
  				}
  				else {
  					if (Timer.time < this.unluckyFinishTime) {
  						luckAmount = tmpAmount;
  					}
  				}
  				func(tmpAmount, bDisableEff, this.samePropertyItemComboCount, luckAmount);
  			}
  		}
  	}
  	checkObstacle() {
  		let arr = this.obstacleInfoArr;
  		if (!arr || arr.length == 0) {
  			return;
  		}
  		let avatarPos = this.avatarPlayerNode.transform.position;
  		for (let i = 0; i < arr.length; i++) {
  			let obstacleInfo = arr[i];
  			if (!!obstacleInfo.bHited) {
  				continue;
  			}
  			let obstaclePos = obstacleInfo.holder.transform.position;
  			if (obstacleInfo.npcAvatar) {
  				if (Math.abs(avatarPos.x - obstaclePos.x) < 0.5 &&
  					Math.abs(avatarPos.y - obstaclePos.y) < 0.5 &&
  					Math.abs(avatarPos.z - obstaclePos.z) < 1) {
  					obstacleInfo.bHited = true;
  					cc$1.tween(obstacleInfo.holder.transform).stop();
  					this._onHitedObstacle(i);
  					break;
  				}
  			}
  			else {
  				if (avatarPos.z < obstaclePos.z &&
  					Math.abs(avatarPos.x - obstaclePos.x) < 0.5 &&
  					Math.abs(avatarPos.y - obstaclePos.y) < 0.5 &&
  					Math.abs(avatarPos.z - obstaclePos.z) < 0.5) {
  					obstacleInfo.bHited = true;
  					cc$1.tween(obstacleInfo.holder.transform).stop();
  					this._onHitedObstacle(i);
  					break;
  				}
  			}
  		}
  	}
  	checkCorner() {
  		let arr = this.cornerInfoArr;
  		if (!arr || arr.length == 0) {
  			return;
  		}
  		let avatarPos = this.avatarPlayerNode.transform.position;
  		for (let i = 0; i < arr.length; i++) {
  			let cornerInfo = arr[i];
  			if (!!cornerInfo.bHited) {
  				continue;
  			}
  			let obstaclePos = cornerInfo.holder.transform.position;
  			if (Math.abs(avatarPos.x - obstaclePos.x) <= (this.ROAD_WH / 2 + 0.5) &&
  				Math.abs(avatarPos.y - obstaclePos.y) < 0.5 &&
  				Math.abs(avatarPos.z - obstaclePos.z) < 1) {
  				cornerInfo.bHited = true;
  				this._onHitedCorner(cornerInfo);
  				break;
  			}
  		}
  	}
  	_onHitedCorner(cornerInfo) {
  		this.bAdEventing = true;
  		cc$1.tween(cornerInfo.holder.transform).stop();
  		let avatarPos = this.avatarPlayerContainer.transform.position;
  		let obstaclePos = cornerInfo.npcAvatar.transform.position;
  		let rotPlayer = Tools.getAngle(avatarPos.x, avatarPos.z, obstaclePos.x, obstaclePos.z);
  		let rotObstacle = Tools.getAngle(obstaclePos.x, obstaclePos.z, avatarPos.x, avatarPos.z);
  		rotObstacle = (180 + rotObstacle) % 360;
  		let cornerRotY = cornerInfo.npcAvatar.transform.localRotationEulerY;
  		let tmpRotY = Math.abs(rotObstacle - cornerRotY) > Math.abs((rotObstacle - 360) - cornerRotY) ? rotObstacle - 360 : rotObstacle;
  		cc$1.tween(this.avatarPlayerContainer.transform).byLocalRotationEuler3D(0.2, 0, rotPlayer, 0).start();
  		cc$1.tween(cornerInfo.npcAvatar.transform).toLocalRotationEuler3D(0.2, 0, tmpRotY, 0).start();
  		if (!!cornerInfo.npcAvatar2) {
  			cc$1.tween(cornerInfo.npcAvatar2.transform).toLocalRotationEuler3D(0.2, 0, tmpRotY, 0).start();
  		}
  		let absHalfRotPlayer = Math.min(10, Math.abs(rotPlayer) / 2);
  		this.cameraFollow.endRotation.y = Tools.clamp(rotPlayer, -absHalfRotPlayer, absHalfRotPlayer);
  		if (this.bAdCornerQuestion) {
  			mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelQuestionEvent_question);
  		}
  		let questionData = db.get_amaze_cloth_crossing_question_db(cornerInfo.questionId);
  		let trialTemplateData = db.get_ggg_retinue_template_db(questionData.relationRewardRoleId, 0) || db.get_ggg_pet_template_db(questionData.relationRewardRoleId, 0);
  		let bTrialQuestion = !!trialTemplateData;
  		if (db.get_ggg_retinue_template_db(questionData.relationRewardRoleId, 0)) {
  			mgrRetinue.addAppearedRetinueId(questionData.relationRewardRoleId);
  		}
  		else if (db.get_ggg_pet_template_db(questionData.relationRewardRoleId, 0)) {
  			mgrPet.addAppearedPetId(questionData.relationRewardRoleId);
  		}
  		this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movIdle, 0, null, null, true, false);
  		let onCornerCompleted = () => {
  			this.cameraFollow.endRotation.y = 0;
  			if (this.avatarFollower) {
  				this.avatarFollower.playAnimationQuote(ROLE_QUOTE_MOV.movWalk);
  			}
  			if (this.petFollower) {
  				this.petFollower.playAnimationQuote(ROLE_QUOTE_MOV.movWalk);
  			}
  			this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  			cc$1.tween(this.avatarPlayerContainer.transform)
  				.byLocalRotationEuler3D(0.1, 0, -rotPlayer, 0)
  				.call(() => {
  					this.bAdEventing = false;
  				})
  				.start();
  		};
  		if (this.avatarFollower) {
  			this.avatarFollower.playAnimationQuote(ROLE_QUOTE_MOV.movIdle);
  		}
  		if (this.petFollower) {
  			this.petFollower.playAnimationQuote(ROLE_QUOTE_MOV.movIdle);
  		}
  		let tryTrialHandle = (bTrialSuccess) => {
  			if (bTrialQuestion && bTrialSuccess) {
  				if (db.get_ggg_retinue_template_db(questionData.relationRewardRoleId, 1)) {
  					mgrRetinue.upgradeLevel(questionData.relationRewardRoleId, true);
  					mgrRetinue.followingRetinueId = questionData.relationRewardRoleId;
  					let retinueLevel = 1;
  					let tryCreateAvatarFollower = () => {
  						if (!this.avatarFollower) {
  							let avatarFollower = new NpcAvatar(trialTemplateData.baseRoleId);
  							this.avatarFollowerNode.addChild(avatarFollower);
  							avatarFollower.transform.localRotationEulerY = 180;
  							this.avatarFollower = avatarFollower;
  						}
  						this.avatarFollower["_retinueId"] = questionData.relationRewardRoleId;
  						this.avatarFollower["_retinueLevel"] = retinueLevel;
  						this.avatarFollower.registerLoadEndCallback(() => {
  							this.avatarFollower.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  						});
  						if (cornerInfo.npcAvatar) {
  							cornerInfo.npcAvatar.destroy();
  							cornerInfo.npcAvatar = null;
  						}
  						if (cornerInfo.npcAvatar2) {
  							cornerInfo.npcAvatar2.destroy();
  							cornerInfo.npcAvatar2 = null;
  						}
  						onCornerCompleted();
  					};
  					let followerLocalRotationEuler = !!this.avatarFollower ? this.avatarFollower.transform.localRotationEuler.clone() : new Laya.Vector3(0, 180, 0);
  					let newComeHereFunc = () => {
  						if (cornerInfo.npcAvatar) {
  							let currPos = cornerInfo.npcAvatar.transform.position.clone();
  							let targetPos = this.avatarPlayerNode.transform.position.clone();
  							cornerInfo.npcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  							cornerInfo.npcAvatar.timeScale = 2;
  							let startTime = Timer.time;
  							let dur = 1;
  							Timer.callLoop(0.016, (timer) => {
  								let percent = Math.min(1, (Timer.time - startTime) / dur);
  								let out = new Laya.Vector3;
  								Laya.Vector3.lerp(currPos, targetPos, percent, out);
  								cornerInfo.npcAvatar.transform.position = out;
  								if (percent >= 1) {
  									timer.stop();
  									timer = null;
  									cornerInfo.npcAvatar.timeScale = 1;
  									cc$1.tween(cornerInfo.npcAvatar.transform)
  										.toLocalRotationEuler3D(0.1, followerLocalRotationEuler.x, followerLocalRotationEuler.y, followerLocalRotationEuler.z)
  										.call(() => {
  											this.avatarFollower = cornerInfo.npcAvatar;
  											this.avatarFollowerNode.addChild(this.avatarFollower);
  											this.avatarFollower.transform.localPosition = new Laya.Vector3;
  											this.avatarFollower.transform.localRotationEuler = followerLocalRotationEuler;
  											cornerInfo.npcAvatar = null;
  											tryCreateAvatarFollower();
  										})
  										.start();
  								}
  							}, this);
  						}
  						else {
  							let avatarFollower = new NpcAvatar(trialTemplateData.baseRoleId);
  							this.avatarFollowerNode.addChild(this.avatarFollower);
  							this.avatarFollower = avatarFollower;
  							this.avatarFollower.transform.localRotationEulerY = 180;
  							tryCreateAvatarFollower();
  						}
  					};
  					if (this.avatarFollower) {
  						this.avatarFollower.transform.localRotationEulerY = 0;
  						this.avatarFollower.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  						this.avatarFollower.timeScale = 3;
  						cc$1.tween(this.avatarFollower.transform)
  							.toLocalRotationEulerY3D(0.1, 0)
  							.toLocalPos3D(0.6, 0, 0, 5)
  							.call(() => {
  								if (this.avatarFollower) {
  									this.avatarFollower.destroy();
  									this.avatarFollower = null;
  								}
  								newComeHereFunc();
  							})
  							.start();
  					}
  					else {
  						newComeHereFunc();
  					}
  					return;
  				}
  				else if (db.get_ggg_pet_template_db(questionData.relationRewardRoleId, 1)) {
  					mgrPet.upgradeLevel(questionData.relationRewardRoleId, true);
  					mgrPet.followingPetId = questionData.relationRewardRoleId;
  					let retinueLevel = 1;
  					let tryCreatePetFollower = () => {
  						if (!this.petFollower) {
  							let petFollower = new NpcAvatar(trialTemplateData.baseRoleId);
  							this.petFollowerNode.addChild(petFollower);
  							petFollower.transform.localRotationEulerY = 180;
  							this.petFollower = petFollower;
  						}
  						this.petFollower["_petId"] = questionData.relationRewardRoleId;
  						this.petFollower["_petLevel"] = retinueLevel;
  						let scale = trialTemplateData["scale"] || 1;
  						this.petFollower.transform.setWorldLossyScale(new Laya.Vector3(scale, scale, scale));
  						this.petFollower.registerLoadEndCallback(() => {
  							this.petFollower.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  						});
  						if (cornerInfo.npcAvatar) {
  							cornerInfo.npcAvatar.destroy();
  							cornerInfo.npcAvatar = null;
  						}
  						if (cornerInfo.npcAvatar2) {
  							cornerInfo.npcAvatar2.destroy();
  							cornerInfo.npcAvatar2 = null;
  						}
  						onCornerCompleted();
  					};
  					let followerLocalRotationEuler = !!this.petFollower ? this.petFollower.transform.localRotationEuler.clone() : new Laya.Vector3(0, 180, 0);
  					let newComeHereFunc = () => {
  						if (cornerInfo.npcAvatar2) {
  							let currPos = cornerInfo.npcAvatar2.transform.position.clone();
  							let targetPos = this.petFollowerNode.transform.position.clone();
  							cornerInfo.npcAvatar2.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  							cornerInfo.npcAvatar2.timeScale = 2;
  							let startTime = Timer.time;
  							let dur = 1;
  							Timer.callLoop(0.016, (timer) => {
  								let percent = Math.min(1, (Timer.time - startTime) / dur);
  								let out = new Laya.Vector3;
  								Laya.Vector3.lerp(currPos, targetPos, percent, out);
  								cornerInfo.npcAvatar2.transform.position = out;
  								if (percent >= 1) {
  									timer.stop();
  									timer = null;
  									cornerInfo.npcAvatar2.timeScale = 1;
  									cc$1.tween(cornerInfo.npcAvatar2.transform)
  										.toLocalRotationEuler3D(0.1, followerLocalRotationEuler.x, followerLocalRotationEuler.y, followerLocalRotationEuler.z)
  										.call(() => {
  											this.petFollower = cornerInfo.npcAvatar2;
  											this.petFollowerNode.addChild(this.petFollower);
  											this.petFollower.transform.localPosition = new Laya.Vector3;
  											this.petFollower.transform.localRotationEuler = followerLocalRotationEuler;
  											cornerInfo.npcAvatar2 = null;
  											tryCreatePetFollower();
  										})
  										.start();
  								}
  							}, this);
  						}
  						else {
  							let petFollower = new NpcAvatar(trialTemplateData.baseRoleId);
  							this.petFollowerNode.addChild(this.petFollower);
  							this.petFollower = petFollower;
  							this.petFollower.transform.localRotationEulerY = 180;
  							tryCreatePetFollower();
  						}
  					};
  					if (this.petFollower) {
  						this.petFollower.transform.localRotationEulerY = 0;
  						this.petFollower.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  						this.petFollower.timeScale = 3;
  						cc$1.tween(this.petFollower.transform)
  							.toLocalRotationEulerY3D(0.1, 0)
  							.toLocalPos3D(0.6, 0, 0, 5)
  							.call(() => {
  								if (this.petFollower) {
  									this.petFollower.destroy();
  									this.petFollower = null;
  								}
  								newComeHereFunc();
  							})
  							.start();
  					}
  					else {
  						newComeHereFunc();
  					}
  					return;
  				}
  			}
  			else {
  				if (this.avatarFollower) {
  					this.avatarFollower.playAnimationQuote(ROLE_QUOTE_MOV.movWalk);
  				}
  				if (this.petFollower) {
  					this.petFollower.playAnimationQuote(ROLE_QUOTE_MOV.movWalk);
  				}
  			}
  			onCornerCompleted();
  		};
  		let sureScoreIndex = 1;
  		let sureScoreRank = questionData["answerScorePropertyIndex" + sureScoreIndex] || 0;
  		let surePropertyIndex = mgrRole.getUsingGrownupLine() || this._getPropertyValueIndexByRank(sureScoreRank);
  		let surePropertyAmount = !questionData["answerScore" + sureScoreIndex] ? 0 : Math.ceil(((questionData["answerScore" + sureScoreIndex] || 0) + mgrRole.getCurrLevelGotPropertyExtrnalValue()) * (questionData.answerScoreRatio || 1));
  		let cancelScoreIndex = 2;
  		let cancelScoreRank = questionData["answerScorePropertyIndex" + cancelScoreIndex] || 0;
  		let cancelPropertyIndex = mgrRole.getUsingGrownupLine() || this._getPropertyValueIndexByRank(cancelScoreRank);
  		let cancelPropertyAmount = !questionData["answerScore" + cancelScoreIndex] ? 0 : Math.ceil(((questionData["answerScore" + cancelScoreIndex] || 0) + mgrRole.getCurrLevelGotPropertyExtrnalValue()) * (questionData.answerScoreRatio || 1));
  		let cancelAmount = 0;
  		if (bTrialQuestion) {
  			cancelAmount = trialTemplateData.upgradeCostAmount;
  		}
  		else {
  			cancelAmount = cancelPropertyAmount;
  		}
  		let sureAmount = !!bTrialQuestion ? 0 : surePropertyAmount;
  		let adEventId = !!this.bAdCornerQuestion ? db.ADV_DB_ADVNAME.video_PanelQuestionEvent_question : null;
  		let context = {
  			adEventId: adEventId,
  			bTrialQuestion: bTrialQuestion,
  			bHighBgMode: questionData.bHighBgMode,
  			bShowClose: bTrialQuestion,
  			cancelAmount: cancelAmount,
  			cancelPropertyIndex: cancelPropertyIndex,
  			surePropertyIndex: surePropertyIndex,
  			sureAmount: sureAmount,
  			desc: questionData.wordQuestion,
  			title: "特殊事件",
  			confirm: () => {
  				if (!bTrialQuestion) {
  					let func = this["addProperty" + surePropertyIndex].bind(this);
  					func(sureAmount);
  				}
  				if (cornerInfo.npcAvatar) {
  					if (!!questionData.relationRoleAnsweredQuoteName1) {
  						cornerInfo.npcAvatar.playAnimationQuote(questionData.relationRoleAnsweredQuoteName1, 0, null, () => {
  							if (!!questionData.relationRoleIdleQuoteNameAnswered) {
  								cornerInfo.npcAvatar.playAnimationQuote(questionData.relationRoleIdleQuoteNameAnswered, 0, null, null, true, false);
  							}
  							else {
  								cornerInfo.npcAvatar.playAnimationQuote(questionData.relationRoleAnsweredQuoteName1, 0, null, null, true, false);
  							}
  							tryTrialHandle(true);
  						}, false, false);
  					}
  					else {
  						if (!!questionData.relationRoleIdleQuoteNameAnswered) {
  							cornerInfo.npcAvatar.playAnimationQuote(questionData.relationRoleIdleQuoteNameAnswered, 0, null, null, true, false);
  						}
  						else {
  							cornerInfo.npcAvatar.playIdle();
  						}
  						tryTrialHandle(true);
  					}
  				}
  				else {
  					tryTrialHandle(true);
  				}
  			},
  			cancel: () => {
  				let bTrialSuccess = false;
  				if (!!bTrialQuestion) {
  					if (!!cancelAmount) {
  						if (!!BaseFacade.mItem.isEnoughItem(2, cancelAmount)) {
  							BaseFacade.mItem.subItem(2, cancelAmount, "拐角解锁侍从宠物");
  							bTrialSuccess = true;
  						}
  						else {
  							mgrTip.alertNotEnough(2, true);
  						}
  					}
  				}
  				else {
  					let func = this["addProperty" + cancelPropertyIndex].bind(this);
  					func(cancelAmount);
  				}
  				if (cornerInfo.npcAvatar) {
  					if (!!questionData.relationRoleAnsweredQuoteName2) {
  						cornerInfo.npcAvatar.playAnimationQuote(questionData.relationRoleAnsweredQuoteName2, 0, null, () => {
  							if (!!questionData.relationRoleIdleQuoteNameAnswered) {
  								cornerInfo.npcAvatar.playAnimationQuote(questionData.relationRoleIdleQuoteNameAnswered, 0, null, null, true, false);
  							}
  							else {
  								cornerInfo.npcAvatar.playAnimationQuote(questionData.relationRoleAnsweredQuoteName2, 0, null, null, true, false);
  							}
  							tryTrialHandle(bTrialSuccess);
  						}, false, false);
  					}
  					else {
  						if (!!questionData.relationRoleIdleQuoteNameAnswered) {
  							cornerInfo.npcAvatar.playAnimationQuote(questionData.relationRoleIdleQuoteNameAnswered, 0, null, null, true, false);
  						}
  						else {
  							cornerInfo.npcAvatar.playIdle();
  						}
  						tryTrialHandle(bTrialSuccess);
  					}
  				}
  				else {
  					tryTrialHandle(bTrialSuccess);
  				}
  			},
  			refuse: () => {
  				if (cornerInfo.npcAvatar) {
  					if (!!questionData.relationRoleAnsweredQuoteName2) {
  						cornerInfo.npcAvatar.playAnimationQuote(questionData.relationRoleAnsweredQuoteName2, 0, null, () => {
  							if (!!questionData.relationRoleIdleQuoteNameAnswered) {
  								cornerInfo.npcAvatar.playAnimationQuote(questionData.relationRoleIdleQuoteNameAnswered, 0, null, null, true, false);
  							}
  							else {
  								cornerInfo.npcAvatar.playAnimationQuote(questionData.relationRoleAnsweredQuoteName3, 0, null, null, true, false);
  							}
  							tryTrialHandle(false);
  						}, false, false);
  					}
  					else {
  						if (!!questionData.relationRoleIdleQuoteNameAnswered) {
  							cornerInfo.npcAvatar.playAnimationQuote(questionData.relationRoleIdleQuoteNameAnswered, 0, null, null, true, false);
  						}
  						else {
  							cornerInfo.npcAvatar.playIdle();
  						}
  						tryTrialHandle(false);
  					}
  				}
  				else {
  					tryTrialHandle(false);
  				}
  			},
  			confirmText: questionData.wordAnswer1,
  			cancelText: questionData.wordAnswer2,
  		};
  		let showPanelFunc = () => {
  			Director.openPanel("PanelQuestionEvent", context);
  		};
  		if (!!questionData.relationRoleIdleQuoteNameHited && questionData.relationRoleIdleQuoteNameHited.indexOf("movIdle") < 0) {
  			cornerInfo.npcAvatar.playAnimationQuote(questionData.relationRoleIdleQuoteNameHited, 0, null, () => {
  				if (questionData.relationRoleIdleQuoteNameInit && questionData.relationRoleIdleQuoteNameInit != "") {
  					cornerInfo.npcAvatar.playAnimationQuote(questionData.relationRoleIdleQuoteNameInit, 0, null, null, true);
  				}
  				else {
  					cornerInfo.npcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movIdle, 0, null, null, true);
  				}
  				showPanelFunc();
  			}, false, false);
  		}
  		else {
  			cornerInfo.npcAvatar.playIdle();
  			showPanelFunc();
  		}
  	}
  	tryShowSuccessResultShow() {
  		let resultQuestion = db.get_amaze_cloth_crossing_question_db(this.resultQuestionId);
  		let successResultShowType = !!resultQuestion ? resultQuestion.resultShowType : 0;
  		let goNextStepFunc = (bRight) => {
  			this.bResultShowSelectIsRight = bRight;
  			let goNextStateFunc = () => {
  				if (this.bSuccess) {
  					switch (successResultShowType) {
  						case 1:
  							if (!bRight) {
  								this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movIdle, 0, null, null, true, false);
  							}
  							else {
  								this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movEmbrace, 0, null, null, true, false);
  							}
  						case 5:
  						case 3:
  							if (bRight) {
  								this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movWinShow01, 0, null, null, true, false);
  							}
  							break;
  						default:
  							if (bRight) {
  								this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movIdle, 0, null, null, true, false);
  							}
  							break;
  					}
  				}
  				Timer.callLater(1, () => {
  					this.stManager.setNextState(this.st_playerArrivedPoint2);
  				}, this);
  			};
  			let bDisableRotationPlayer = !!successResultShowType;
  			if (!!bDisableRotationPlayer) {
  				goNextStateFunc();
  				return;
  			}
  			cc$1.tween(this.avatarPlayerContainer.transform)
  				.to(0.3, { localRotationEulerY: 0 })
  				.call(() => {
  					goNextStateFunc();
  				})
  				.start();
  		};
  		if (!this.bSuccess) {
  			goNextStepFunc(false);
  			return;
  		}
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.playerRoleId);
  		let playerBaseRoleData = db.get_amaze_cloth_crossing_role_db(roleData.roleId);
  		let targetBaseRoleData = db.get_amaze_cloth_crossing_role_db(this.successResultShowUsingBaseRoleId);
  		let questionData = db.get_amaze_cloth_crossing_question_db(this.resultQuestionId);
  		if (!questionData) {
  			goNextStepFunc(false);
  			return;
  		}
  		let tmpNodes = [
  			this.successResultShowNpcAvatar,
  			this.successResultShowNpcAvatar2,
  			this.successHelpResultShowNpcAvatar,
  			this.jiesuantaiModel.resNode.getChildByName("successResultHolder1"),
  			this.jiesuantaiModel.resNode.getChildByName("successResultHolder2")
  		];
  		for (let k in tmpNodes) {
  			let node = tmpNodes[k];
  			if (!!node && !!node.transform) {
  				node.transform.position = new Laya.Vector3(node.transform.position.x, this.getPlayerAvatar(true).transform.position.y, node.transform.position.z);
  			}
  		}
  		let avatarContainerPos = this.avatarPlayerContainer.transform.position;
  		let avatarPos = new Laya.Vector3(avatarContainerPos.x, avatarContainerPos.y + 0.1, avatarContainerPos.z);
  		let obstaclePos = this.successResultShowNpcAvatar.transform.position;
  		let rotPlayerContainer = Tools.getAngle(avatarContainerPos.x, avatarContainerPos.z, obstaclePos.x, obstaclePos.z);
  		let rotObstacle = Tools.getAngle(obstaclePos.x, obstaclePos.z, avatarContainerPos.x, avatarContainerPos.z);
  		if (successResultShowType == 3 || successResultShowType == 5) {
  			let obstaclePos = this.jiesuantaiModel.resNode.getChildByName("successResultHolder1").transform.position;
  			rotPlayerContainer = Tools.getAngle(avatarContainerPos.x, avatarContainerPos.z, obstaclePos.x, obstaclePos.z);
  		}
  		cc$1.tween(this.avatarPlayerContainer.transform).byLocalRotationEuler3D(0.1, 0, rotPlayerContainer, 0).start();
  		cc$1.tween(this.successResultShowNpcAvatar.transform).toLocalRotationEuler3D(0.1, 0, 180 + rotObstacle, 0).start();
  		if (this.successResultShowNpcAvatar2) {
  			let obstaclePos = this.successResultShowNpcAvatar2.transform.position;
  			let rotObstacle = Tools.getAngle(obstaclePos.x, obstaclePos.z, avatarContainerPos.x, avatarContainerPos.z);
  			cc$1.tween(this.successResultShowNpcAvatar2.transform).toLocalRotationEuler3D(0.1, 0, 180 + rotObstacle, 0).start();
  		}
  		this.cameraFollow.disableClampX();
  		this.cameraFollow.lerpValuePosZ = 0;
  		this.cameraFollow.lerpValuePosX = 0;
  		this.cameraFollow.endRotation = new Laya.Vector3(-11, -24, 0);
  		this.cameraFollow.offset = new Laya.Vector3(0.22, 0.32, -1.72);
  		this.cameraFollow.fov = 60;
  		let allCompleted = (bRight) => {
  			if (this.bRecordNextResultQuestion && this.stageData.stageType == StageType.mainStage) {
  				this.nextResultQuestionId = questionData["nextQuestionId" + (bRight ? 1 : 2)] || 0;
  			}
  			if (bRight) {
  				let scoreIndex = 1;
  				let scoreRank = questionData["answerScorePropertyIndex" + scoreIndex] || 0;
  				let propertyIndex = mgrRole.getUsingGrownupLine() || this._getPropertyValueIndexByRank(scoreRank);
  				let func = this["addProperty" + propertyIndex].bind(this);
  				let amount = !questionData["answerScore" + scoreIndex] ? 0 : ((questionData["answerScore" + scoreIndex] || 0) + mgrRole.getCurrLevelGotPropertyExtrnalValue()) * (questionData.answerScoreRatio || 1);
  				func(Math.ceil(amount));
  			}
  			let continueCallbackFunc = () => {
  				goNextStepFunc(bRight);
  			};
  			let rewardSpecialTypeParam = questionData.rewardSpecialTypeParam || 0;
  			switch (questionData.rewardSpecialType) {
  				case QuestionRewardSpecialType.GoldReward:
  					BaseFacade.mItem.addItem(2, rewardSpecialTypeParam, "结算问题奖励");
  					mgrTip.addGotItemTip(2, rewardSpecialTypeParam, null, { fOnClose: () => { continueCallbackFunc(); } });
  					break;
  				case QuestionRewardSpecialType.ExtrnalLevelUp:
  					mgrRole.upgradeGotPropertyExtrnalLevel();
  					mgrTip.showMsgTip("获得属性等级+1");
  					Timer.callLater(0.5, () => { continueCallbackFunc(); });
  					break;
  				case QuestionRewardSpecialType.RetinueLevelUp:
  					if (mgrRetinue.followingRetinueId) {
  						mgrRetinue.upgradeLevel(mgrRetinue.followingRetinueId, true);
  						let template = db.get_ggg_retinue_template_db(mgrRetinue.followingRetinueId, mgrRetinue.getRetinueLevelById(mgrRetinue.followingRetinueId));
  						mgrTip.showMsgTip(`侍从【${template.name}】等级+1`);
  						Timer.callLater(0.5, () => { continueCallbackFunc(); });
  					}
  					else {
  						BaseFacade.mItem.addItem(2, 100 + mgrRole.getCurrLevelGotPropertyExtrnalValue(), "结算问题奖励");
  						mgrTip.addGotItemTip(2, 100 + mgrRole.getCurrLevelGotPropertyExtrnalValue(), null, { fOnClose: () => { continueCallbackFunc(); } });
  					}
  					break;
  				case QuestionRewardSpecialType.PetLevelUp:
  					if (mgrPet.followingPetId) {
  						mgrPet.upgradeLevel(mgrPet.followingPetId, true);
  						let template = db.get_ggg_retinue_template_db(mgrPet.followingPetId, mgrPet.getGotPetIdLevel(mgrPet.followingPetId));
  						mgrTip.showMsgTip(`宠物【${template.name}】等级+1`);
  						Timer.callLater(0.5, () => { continueCallbackFunc(); });
  					}
  					else {
  						BaseFacade.mItem.addItem(2, 100 + mgrRole.getCurrLevelGotPropertyExtrnalValue(), "结算问题奖励");
  						mgrTip.addGotItemTip(2, 100 + mgrRole.getCurrLevelGotPropertyExtrnalValue(), null, { fOnClose: () => { continueCallbackFunc(); } });
  					}
  					break;
  				case QuestionRewardSpecialType.UnlockGoldStage:
  					if (bRight) {
  						if (!mgrChallenge.isUnlockedType(StageType.goldStage)) {
  							mgrChallenge.markChallengeTypeUnlocked(StageType.goldStage);
  							console.info("rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr");
  							Director.openPanel("PanelSpecialStagePreview1", { bUnlockedTipShow: true, fOnClose: () => { continueCallbackFunc(); } });
  						}
  						else {
  							BaseFacade.mItem.addItem(2, 100 + mgrRole.getCurrLevelGotPropertyExtrnalValue(), "结算问题奖励");
  							mgrTip.addGotItemTip(2, 100 + mgrRole.getCurrLevelGotPropertyExtrnalValue(), null, { fOnClose: () => { continueCallbackFunc(); } });
  						}
  					}
  					else {
  						continueCallbackFunc();
  					}
  					break;
  				case QuestionRewardSpecialType.UnlockSpeedStage:
  					if (bRight) {
  						if (!mgrChallenge.isUnlockedType(StageType.speedStage)) {
  							mgrChallenge.markChallengeTypeUnlocked(StageType.speedStage);
  							console.info("rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr");
  							Director.openPanel("PanelSpecialStagePreview2", { bUnlockedTipShow: true, fOnClose: () => { continueCallbackFunc(); } });
  						}
  						else {
  							BaseFacade.mItem.addItem(2, 100 + mgrRole.getCurrLevelGotPropertyExtrnalValue(), "结算问题奖励");
  							mgrTip.addGotItemTip(2, 100 + mgrRole.getCurrLevelGotPropertyExtrnalValue(), null, { fOnClose: () => { continueCallbackFunc(); } });
  						}
  					}
  					else {
  						continueCallbackFunc();
  					}
  					break;
  				case QuestionRewardSpecialType.MaxPropertyReward:
  					let index = mgrRole.getUsingGrownupLine() || this._getMaxPropertyValueIndex();
  					let func = this["addProperty" + index].bind(this);
  					let amount = rewardSpecialTypeParam + mgrRole.getCurrLevelGotPropertyExtrnalValue();
  					func(amount);
  					continueCallbackFunc();
  					break;
  				case QuestionRewardSpecialType.UnlockYard:
  					if (bRight) {
  						if (!mgrYard.isYardUnlocked()) {
  							mgrYard.unlockYard();
  							console.info("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
  							Director.openPanel("PanelYardPreview", { bUnlockedTipShow: true, fOnClose: () => { continueCallbackFunc(); } });
  						}
  						else {
  							BaseFacade.mItem.addItem(2, 100 + mgrRole.getCurrLevelGotPropertyExtrnalValue(), "结算问题奖励");
  							mgrTip.addGotItemTip(2, 100 + mgrRole.getCurrLevelGotPropertyExtrnalValue(), null, { fOnClose: () => { continueCallbackFunc(); } });
  						}
  					}
  					else {
  						continueCallbackFunc();
  					}
  					break;
  				default:
  					continueCallbackFunc();
  					break;
  			}
  		};
  		let getResultPreloadAnimationsFunc = (bRight) => {
  			let animationIdDict = {};
  			let movePlayerFunc = () => {
  				if (successResultShowType != 6) {
  					let aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movWalk3);
  					if (!!aniId)
  						animationIdDict[aniId] = true;
  				}
  				else {
  					let aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movIdle);
  					if (!!aniId)
  						animationIdDict[aniId] = true;
  				}
  			};
  			let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.playerRoleId);
  			let baseRoleData = db.get_amaze_cloth_crossing_role_db(roleData.roleId);
  			let aniId = null;
  			switch (successResultShowType) {
  				case 2:
  					if (targetBaseRoleData.level > playerBaseRoleData.level) {
  						if (bRight) {
  							aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent2RightUpper);
  							if (!!aniId)
  								animationIdDict[aniId] = true;
  							aniId = baseRoleData[ROLE_QUOTE_MOV.movResultEvent2RightLower];
  							animationIdDict[aniId] = true;
  						}
  						else {
  							aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent2FaultUpper);
  							if (!!aniId)
  								animationIdDict[aniId] = true;
  							aniId = baseRoleData[ROLE_QUOTE_MOV.movResultEvent2FaultLower];
  							animationIdDict[aniId] = true;
  						}
  					}
  					else if (targetBaseRoleData.level < playerBaseRoleData.level) {
  						if (bRight) {
  							aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent2FaultLower);
  							if (!!aniId)
  								animationIdDict[aniId] = true;
  							aniId = baseRoleData[ROLE_QUOTE_MOV.movResultEvent2FaultUpper];
  							animationIdDict[aniId] = true;
  						}
  						else {
  							aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent2RightLower);
  							if (!!aniId)
  								animationIdDict[aniId] = true;
  							aniId = baseRoleData[ROLE_QUOTE_MOV.movResultEvent2RightUpper];
  							animationIdDict[aniId] = true;
  						}
  					}
  					else {
  						if (bRight) {
  							aniId = baseRoleData[ROLE_QUOTE_MOV.movResultEvent2Equal2];
  							animationIdDict[aniId] = true;
  							aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent2Equal);
  							if (!!aniId)
  								animationIdDict[aniId] = true;
  						}
  						else {
  							aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent2FaultLower);
  							if (!!aniId)
  								animationIdDict[aniId] = true;
  							aniId = baseRoleData[ROLE_QUOTE_MOV.movResultEvent2FaultUpper];
  							animationIdDict[aniId] = true;
  						}
  					}
  					break;
  				case 3:
  					if (bRight) {
  						movePlayerFunc();
  						aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent3Right);
  						if (!!aniId)
  							animationIdDict[aniId] = true;
  						aniId = baseRoleData[ROLE_QUOTE_MOV.movResultEvent3Right];
  						animationIdDict[aniId] = true;
  					}
  					else {
  						aniId = baseRoleData[ROLE_QUOTE_MOV.movIdle3];
  						animationIdDict[aniId] = true;
  						aniId = baseRoleData[ROLE_QUOTE_MOV.movResultEvent3Fault];
  						animationIdDict[aniId] = true;
  						movePlayerFunc();
  						aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent3Fault);
  						if (!!aniId)
  							animationIdDict[aniId] = true;
  						aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movIdle2);
  						if (!!aniId)
  							animationIdDict[aniId] = true;
  					}
  					break;
  				case 4:
  					aniId = baseRoleData[ROLE_QUOTE_MOV.movResultEvent4Right];
  					animationIdDict[aniId] = true;
  					aniId = baseRoleData[!!bRight ? ROLE_QUOTE_MOV.movIdle : ROLE_QUOTE_MOV.movIdle3];
  					animationIdDict[aniId] = true;
  					if (bRight) {
  						aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent4Right);
  						if (!!aniId)
  							animationIdDict[aniId] = true;
  					}
  					else {
  						aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent4Fault);
  						if (!!aniId)
  							animationIdDict[aniId] = true;
  						aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movIdle2);
  						if (!!aniId)
  							animationIdDict[aniId] = true;
  					}
  					break;
  				case 5:
  					{
  						if (bRight) {
  							aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent5Right);
  							if (!!aniId)
  								animationIdDict[aniId] = true;
  							movePlayerFunc();
  							aniId = baseRoleData[ROLE_QUOTE_MOV.movResultEvent5Right];
  							animationIdDict[aniId] = true;
  						}
  						else {
  							aniId = baseRoleData[ROLE_QUOTE_MOV.movIdle3];
  							animationIdDict[aniId] = true;
  							aniId = baseRoleData[ROLE_QUOTE_MOV.movResultEvent5Fault];
  							animationIdDict[aniId] = true;
  							aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent5Fault);
  							if (!!aniId)
  								animationIdDict[aniId] = true;
  							aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movIdle2);
  							if (!!aniId)
  								animationIdDict[aniId] = true;
  							movePlayerFunc();
  						}
  						break;
  					}
  				case 6:
  					{
  						if (bRight) {
  							aniId = baseRoleData[ROLE_QUOTE_MOV.movResultEvent6Right];
  							animationIdDict[aniId] = true;
  							aniId = baseRoleData[ROLE_QUOTE_MOV.movIdle];
  							animationIdDict[aniId] = true;
  							aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent6Right);
  							if (!!aniId)
  								animationIdDict[aniId] = true;
  						}
  						else {
  							aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent6Fault);
  							if (!!aniId)
  								animationIdDict[aniId] = true;
  							aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movIdle2);
  							if (!!aniId)
  								animationIdDict[aniId] = true;
  							aniId = baseRoleData[ROLE_QUOTE_MOV.movResultEvent6Fault];
  							animationIdDict[aniId] = true;
  							aniId = baseRoleData[ROLE_QUOTE_MOV.movIdle3];
  							animationIdDict[aniId] = true;
  						}
  						break;
  					}
  				case 7:
  					if (bRight) {
  						aniId = this.successHelpResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent7RightAsNpcHelper);
  						if (!!aniId)
  							animationIdDict[aniId] = true;
  						aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent7FaultAsNpc);
  						if (!!aniId)
  							animationIdDict[aniId] = true;
  						aniId = baseRoleData[ROLE_QUOTE_MOV.movResultEvent7RightAsPlayer];
  						animationIdDict[aniId] = true;
  					}
  					else {
  						aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent7RightAsNpc);
  						if (!!aniId)
  							animationIdDict[aniId] = true;
  						aniId = baseRoleData[ROLE_QUOTE_MOV.movResultEvent7FaultAsPlayer];
  						animationIdDict[aniId] = true;
  					}
  					break;
  				case 8:
  					if (bRight) {
  						aniId = baseRoleData[ROLE_QUOTE_MOV.movResultEvent8ChooseAnswer1AsPlayer];
  						if (!!aniId)
  							animationIdDict[aniId] = true;
  						aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent8ChooseAnswer1AsNpc);
  						if (!!aniId)
  							animationIdDict[aniId] = true;
  					}
  					else {
  						aniId = baseRoleData[ROLE_QUOTE_MOV.movResultEvent8ChooseAnswer2AsPlayer];
  						if (!!aniId)
  							animationIdDict[aniId] = true;
  						aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent8ChooseAnswer2AsNpc);
  						if (!!aniId)
  							animationIdDict[aniId] = true;
  					}
  					break;
  				default:
  					if (bRight) {
  						aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movWalk);
  						if (!!aniId)
  							animationIdDict[aniId] = true;
  						aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movEmbrace);
  						if (!!aniId)
  							animationIdDict[aniId] = true;
  						aniId = baseRoleData[ROLE_QUOTE_MOV.movEmbrace];
  						animationIdDict[aniId] = true;
  						aniId = baseRoleData[ROLE_QUOTE_MOV.movResultEvent1Right];
  						animationIdDict[aniId] = true;
  					}
  					else {
  						aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movResultEvent1Fault);
  						if (!!aniId)
  							animationIdDict[aniId] = true;
  						aniId = this.successResultShowNpcAvatar.getAvatarRealAnimationId(ROLE_QUOTE_MOV.movIdle2);
  						if (!!aniId)
  							animationIdDict[aniId] = true;
  						aniId = baseRoleData[ROLE_QUOTE_MOV.movResultEvent1Fault];
  						animationIdDict[aniId] = true;
  					}
  					break;
  			}
  			let arr = [];
  			for (let k in animationIdDict) {
  				arr.push(k);
  			}
  			return arr;
  		};
  		let onChoosed = (bRight) => {
  			mgrRole.markAnsweredQuestionId(questionData.id);
  			GameStatistics.statisCommonEvent(questionData.statisPointId, !!bRight ? 1 : 0);
  			let movePlayerFunc = (moveEndCall) => {
  				let targetPos = this.jiesuantaiModel.resNode.getChildByName("successResultHolder1").transform.position.clone();
  				targetPos.y = avatarPos.y;
  				if (successResultShowType != 6) {
  					this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  				}
  				else {
  					this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movIdle, 0, null, null, true, false);
  				}
  				cc$1.tween(this.successResultShowNpcAvatar.transform).toLocalPos3D(3, targetPos.x, targetPos.y, targetPos.z)
  					.call(() => {
  						let obstaclePos = this.successResultShowNpcAvatar.transform.position;
  						let rotObstacle = Tools.getAngle(obstaclePos.x, obstaclePos.z, avatarPos.x, avatarPos.z);
  						this.successResultShowNpcAvatar.transform.localRotationEulerY = 180 + rotObstacle;
  						moveEndCall && moveEndCall();
  					}).start();
  			};
  			let showChooseTipMsg = (bRealRight) => {
  				this.showMovieWordPanelVisible(bRealRight ? questionData.wordAnsweredTip1 : questionData.wordAnsweredTip2, undefined, 5);
  			};
  			this.successResultShowNpcAvatar.transform.position = new Laya.Vector3(this.successResultShowNpcAvatar.transform.position.x, avatarPos.y, this.successResultShowNpcAvatar.transform.position.z);
  			switch (successResultShowType) {
  				case 2:
  					this.comEnemyNameContainer.alpha = 0;
  					if (targetBaseRoleData.level > playerBaseRoleData.level) {
  						if (bRight) {
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2RightUpper, 0, null, null, false, true);
  							this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2RightLower, 0, null, () => {
  								allCompleted(true);
  							}, false, false);
  							showChooseTipMsg(true);
  						}
  						else {
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2FaultUpper, 0, null, () => {
  							}, false, true);
  							this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2FaultLower, 0, null, () => {
  								allCompleted(false);
  							}, false, false);
  							showChooseTipMsg(false);
  						}
  					}
  					else if (targetBaseRoleData.level < playerBaseRoleData.level) {
  						if (bRight) {
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2RightLower, 0, null, null, false, true);
  							this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2RightUpper, 0, null, () => {
  								allCompleted(false);
  							}, false, false);
  							showChooseTipMsg(false);
  						}
  						else {
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2FaultLower, 0, null, () => {
  							}, false, true);
  							this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2FaultUpper, 0, null, () => {
  								allCompleted(true);
  							}, false, false);
  							showChooseTipMsg(true);
  						}
  					}
  					else {
  						showChooseTipMsg(bRight);
  						if (bRight) {
  							let needMoveNodes = [
  								{ node: this.avatarPlayerNode, offset: new Laya.Vector3(-0.19, 0, -0.1) },
  								{ node: this.successResultShowNpcAvatar, offset: new Laya.Vector3(0.19, 0, 0.1) }
  							];
  							for (let k in needMoveNodes) {
  								let info = needMoveNodes[k];
  								let out = new Laya.Vector3;
  								Laya.Vector3.add(info.node.transform.localPosition, info.offset, out);
  								info.node.transform.localPosition = out;
  							}
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2Equal, 0, null, null, false, true);
  							this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2Equal2, 0, null, () => {
  								allCompleted(bRight);
  							}, false, false);
  						}
  						else {
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2FaultLower, 0, null, () => {
  							}, false, true);
  							this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2FaultLower, 0, null, () => {
  								allCompleted(false);
  							}, false, false);
  						}
  					}
  					break;
  				case 3:
  					let effName = bRight ? questionData.effectNameAnsweredTip1 : questionData.effectNameAnsweredTip2;
  					this.linkModelAtBack(effName, this.avatarPlayerNode, undefined, 5, new Laya.Vector3(0, 1.2));
  					if (bRight) {
  						movePlayerFunc(() => {
  							showChooseTipMsg(true);
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent3Right, 0, null, () => {
  								allCompleted(true);
  							}, false, true);
  						});
  						this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent3Right, 0, null, () => {
  						}, true, false);
  					}
  					else {
  						movePlayerFunc(() => {
  							showChooseTipMsg(false);
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent3Fault, 0, null, () => {
  								this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movIdle3, 0, null, () => {
  								}, true, false);
  								this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movIdle2, 0, null, () => {
  								}, true, false);
  								Timer.callLater(0.8, () => {
  									allCompleted(false);
  								}, this);
  							}, false, false);
  						});
  						this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent3Fault, 0, null, () => {
  						}, true, false);
  					}
  					break;
  				case 4:
  					{
  						let model = Global.poolManager.get(Model, !!bRight ? "panzi" : "zhong");
  						this.getPlayerAvatar().linMode2Bip001RHand(model);
  						this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent4Right, 0, () => {
  							Timer.callLater(1.6, () => {
  								this.getPlayerAvatar().unlinkModel(model);
  							}, this);
  						}, () => {
  							this.playerAvatarPlayAnimationQuote(!!bRight ? ROLE_QUOTE_MOV.movIdle : ROLE_QUOTE_MOV.movIdle3, 0, null, () => {
  							}, true, false);
  							allCompleted(bRight);
  						}, false, false);
  						if (bRight) {
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent4Right, 0, null, null, false, true);
  						}
  						else {
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent4Fault, 0, null, () => {
  								this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movIdle2, 0, null, () => {
  								}, true, false);
  							}, false, false);
  						}
  						showChooseTipMsg(bRight);
  						break;
  					}
  				case 5:
  					{
  						let effName = bRight ? questionData.effectNameAnsweredTip1 : questionData.effectNameAnsweredTip2;
  						this.linkModelAtBack(effName, this.avatarPlayerNode, undefined, 5, new Laya.Vector3(0, 1.2));
  						if (bRight) {
  							movePlayerFunc(() => {
  								showChooseTipMsg(true);
  								this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent5Right, 0, null, () => {
  									allCompleted(true);
  								}, false, true);
  							});
  							this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent5Right, 0, null, () => {
  							}, true, false);
  						}
  						else {
  							movePlayerFunc(() => {
  								showChooseTipMsg(false);
  								this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent5Fault, 0, null, () => {
  									this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movIdle3, 0, null, () => {
  									}, true, false);
  									this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movIdle2, 0, null, () => {
  									}, true, false);
  									Timer.callLater(0.8, () => {
  										allCompleted(false);
  									}, this);
  								}, false, false);
  							});
  							this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent5Fault, 0, null, () => {
  							}, true, false);
  						}
  						break;
  					}
  				case 6:
  					{
  						if (bRight) {
  							let model = Global.poolManager.get(Model, "zhong");
  							this.getPlayerAvatar().linMode2Bip001RHand(model);
  							this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent6Right, 0, () => {
  								Timer.callLater(1.6, () => {
  									this.getPlayerAvatar().unlinkModel(model);
  								}, this);
  							}, () => {
  								this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movIdle, 0, null, () => {
  								}, true, false);
  								allCompleted(bRight);
  							}, false, false);
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent6Right, 0, null, null, false, true);
  						}
  						else {
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent6Fault, 0, null, () => {
  								this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movIdle2, 0, null, () => {
  								}, true, false);
  							}, false, false);
  							this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent6Fault, 0, null, () => {
  								this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movIdle3, 0, null, () => {
  								}, true, false);
  								allCompleted(bRight);
  							}, false, false);
  						}
  						showChooseTipMsg(bRight);
  						break;
  					}
  				case 7:
  					if (bRight) {
  						if (this.successHelpResultShowNpcAvatar && !!this.successResultShowNpcAvatar) {
  							this.successHelpResultShowNpcAvatar.active = true;
  							this.successHelpResultShowNpcAvatar.transform.position = this.successResultShowNpcAvatar.transform.position.clone();
  							this.successHelpResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent7RightAsNpcHelper, 0, null, () => {
  								if (!!this.successHelpResultShowNpcAvatar && !this.successHelpResultShowNpcAvatar.destroyed) {
  									this.successHelpResultShowNpcAvatar.active = false;
  								}
  							}, false, false);
  						}
  						this.successResultShowNpcAvatar.transform.localRotationEuler = new Laya.Vector3;
  						this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent7FaultAsNpc, 0, null, () => {
  							if (!!this.successResultShowNpcAvatar && !this.successResultShowNpcAvatar.destroyed) {
  								this.successResultShowNpcAvatar.active = false;
  							}
  						}, false, false);
  						this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent7RightAsPlayer, 0, null, () => {
  							allCompleted(true);
  						}, false, false);
  						showChooseTipMsg(true);
  					}
  					else {
  						this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent7RightAsNpc, 0, null, null, false, true);
  						this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent7FaultAsPlayer, 0, null, () => {
  							allCompleted(false);
  						}, false, false);
  						showChooseTipMsg(false);
  					}
  					break;
  				case 8:
  					{
  						if (bRight) {
  							this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent8ChooseAnswer1AsPlayer, 0, null, null, false, false);
  							if (!!this.successResultShowNpcAvatar.roleData.nextLevelId) {
  								let newNpc = new NpcAvatar(this.successResultShowNpcAvatar.roleData.nextLevelId);
  								newNpc.registerAllLoadEndCallback(() => {
  									this.successResultShowNpcAvatar.parent.addChild(newNpc);
  									newNpc.transform.localPosition = this.successResultShowNpcAvatar.transform.localPosition.clone();
  									newNpc.transform.localRotationEuler = this.successResultShowNpcAvatar.transform.localRotationEuler.clone();
  									this.linkModelAtBack("130_e_once_shengji_01", newNpc, undefined, 3);
  									this.successResultShowNpcAvatar.destroy();
  									this.successResultShowNpcAvatar = newNpc;
  									this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movUpgrade, 0, null, () => {
  										this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent8ChooseAnswer1AsNpc, 0, null, () => {
  											allCompleted(bRight);
  										}, false, false);
  									}, false, false);
  								});
  							}
  							else {
  								this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent8ChooseAnswer1AsNpc, 0, null, () => {
  									allCompleted(bRight);
  								}, false, false);
  							}
  						}
  						else {
  							this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent8ChooseAnswer2AsPlayer, 0, null, null, false, false);
  							if (this.successHelpResultShowNpcAvatar && !!this.successResultShowNpcAvatar) {
  								this.successHelpResultShowNpcAvatar.active = true;
  								this.successHelpResultShowNpcAvatar.transform.position = this.successResultShowNpcAvatar.transform.position.clone();
  								this.successHelpResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent9ChooseAnswer2AsNpcHelper, 0, null, () => {
  									if (!!this.successHelpResultShowNpcAvatar && !this.successHelpResultShowNpcAvatar.destroyed) {
  										this.successHelpResultShowNpcAvatar.active = false;
  									}
  								}, false, false);
  							}
  							this.successResultShowNpcAvatar.transform.localRotationEuler = new Laya.Vector3;
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent9ChooseAnswer2AsNpc2, 0, null, () => {
  								if (!!this.successResultShowNpcAvatar && !this.successResultShowNpcAvatar.destroyed) {
  									allCompleted(bRight);
  									this.successResultShowNpcAvatar.active = false;
  								}
  							}, false, false);
  						}
  						showChooseTipMsg(bRight);
  						break;
  					}
  				case 9: {
  					if (bRight) {
  						this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent9ChooseAnswer1AsPlayer, 0, null, null, false, false);
  						this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent9ChooseAnswer1AsNpc1, 0, null, null, false, false);
  						this.successResultShowNpcAvatar2.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  						this.successResultShowNpcAvatar2.transform.localRotationEulerY = -90;
  						cc$1.tween(this.successResultShowNpcAvatar2.transform)
  							.byLocalPos3D(3, -5, 0, 0)
  							.call(() => {
  								allCompleted(bRight);
  								this.successResultShowNpcAvatar2.active = false;
  							})
  							.start();
  					}
  					else {
  						if (this.successHelpResultShowNpcAvatar && !!this.successResultShowNpcAvatar2) {
  							this.successHelpResultShowNpcAvatar.active = true;
  							this.successHelpResultShowNpcAvatar.transform.position = this.successResultShowNpcAvatar2.transform.position.clone();
  							this.successHelpResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent9ChooseAnswer2AsNpcHelper, 0, null, () => {
  								if (!!this.successHelpResultShowNpcAvatar && !this.successHelpResultShowNpcAvatar.destroyed) {
  									this.successHelpResultShowNpcAvatar.active = false;
  								}
  							}, false, false);
  						}
  						this.successResultShowNpcAvatar2.transform.localRotationEuler = new Laya.Vector3;
  						this.successResultShowNpcAvatar2.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent9ChooseAnswer2AsNpc2, 0, null, () => {
  							if (!!this.successResultShowNpcAvatar2 && !this.successResultShowNpcAvatar2.destroyed) {
  								this.successResultShowNpcAvatar2.active = false;
  							}
  						}, false, false);
  						Timer.callLater(4, () => {
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent9ChooseAnswer2AsNpc1, 0, null, () => {
  								this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  								this.successResultShowNpcAvatar.transform.localRotationEulerY = -90;
  								cc$1.tween(this.successResultShowNpcAvatar.transform)
  									.byLocalPos3D(3, -5, 0, 0)
  									.call(() => {
  										allCompleted(bRight);
  										this.successResultShowNpcAvatar.active = false;
  									})
  									.start();
  							}, false, false);
  						}, this);
  						this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent9ChooseAnswer2AsPlayer, 0, null, () => {
  						}, false, false);
  					}
  					showChooseTipMsg(bRight);
  					break;
  				}
  				case 10:
  					{
  						if (bRight) {
  							this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent10Right, 0, null, () => {
  								this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movIdle, 0, null, () => {
  								}, true, false);
  								allCompleted(bRight);
  							}, false, false);
  						}
  						else {
  							allCompleted(bRight);
  						}
  						showChooseTipMsg(bRight);
  						break;
  					}
  				case 11:
  					this.comEnemyNameContainer.alpha = 0;
  					if (targetBaseRoleData.level > playerBaseRoleData.level) {
  						if (bRight) {
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2RightUpper, 0, null, null, false, true);
  							this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2RightLower, 0, null, () => {
  								allCompleted(true);
  							}, false, false);
  							showChooseTipMsg(true);
  						}
  						else {
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2FaultUpper, 0, null, () => {
  							}, false, true);
  							this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2FaultLower, 0, null, () => {
  								allCompleted(false);
  							}, false, false);
  							showChooseTipMsg(false);
  						}
  					}
  					else if (targetBaseRoleData.level < playerBaseRoleData.level) {
  						if (bRight) {
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2RightLower, 0, null, null, false, true);
  							this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2RightUpper, 0, null, () => {
  								allCompleted(false);
  							}, false, false);
  							showChooseTipMsg(false);
  						}
  						else {
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2FaultLower, 0, null, () => {
  							}, false, true);
  							this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2FaultUpper, 0, null, () => {
  								allCompleted(true);
  							}, false, false);
  							showChooseTipMsg(true);
  						}
  					}
  					else {
  						showChooseTipMsg(bRight);
  						if (bRight) {
  							let needMoveNodes = [
  								{ node: this.avatarPlayerNode, offset: new Laya.Vector3(-0.19, 0, -0.1) },
  								{ node: this.successResultShowNpcAvatar, offset: new Laya.Vector3(0.19, 0, 0.1) }
  							];
  							for (let k in needMoveNodes) {
  								let info = needMoveNodes[k];
  								let out = new Laya.Vector3;
  								Laya.Vector3.add(info.node.transform.localPosition, info.offset, out);
  								info.node.transform.localPosition = out;
  							}
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2Equal, 0, null, null, false, true);
  							this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2Equal2, 0, null, () => {
  								allCompleted(bRight);
  							}, false, false);
  						}
  						else {
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2FaultLower, 0, null, () => {
  							}, false, true);
  							this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent2FaultLower, 0, null, () => {
  								allCompleted(false);
  							}, false, false);
  						}
  					}
  					break;
  				default:
  					if (bRight) {
  						this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  						cc$1.tween(this.successResultShowNpcAvatar.transform).toLocalPos3D(0.3, avatarPos.x, avatarPos.y, avatarPos.z)
  							.call(() => {
  								this.avatarPlayerContainer.transform.localRotationEuler = this.successResultShowNpcAvatar.transform.localRotationEuler.clone();
  								this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movEmbrace, 0, null, null, true, false);
  								this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movEmbrace, 0, null, () => {
  									allCompleted(bRight);
  								}, false, false);
  							})
  							.start();
  						this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent1Right, 0, null, null, false, false);
  						showChooseTipMsg(bRight);
  					}
  					else {
  						this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent1Fault, 0, null, () => {
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movIdle2, 0, null, null, true, false);
  						}, false, false);
  						this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movResultEvent1Fault, 0, null, () => {
  							allCompleted(bRight);
  						}, false, false);
  						showChooseTipMsg(bRight);
  					}
  					break;
  			}
  		};
  		let onChoosedPrehande = (bRight) => {
  			if (showTargetNameTimer) {
  				showTargetNameTimer.stop();
  				showTargetNameTimer = null;
  			}
  			let animationIdArr = getResultPreloadAnimationsFunc(bRight);
  			if (!!animationIdArr && animationIdArr.length > 0) {
  				Director.showWait("preload_stage_res");
  				this.doProloadResByIds([], animationIdArr, null, null, () => {
  					if (this.isDisposed) {
  						return;
  					}
  					Director.hideWait("preload_stage_res");
  					onChoosed(bRight);
  				});
  			}
  			else {
  				onChoosed(bRight);
  			}
  		};
  		this.playPropBtnsMoveOut();
  		this.button_position_up.setScale(0, 0);
  		this.comTargetProperty.alpha = 0;
  		let showTargetNameTimer = null;
  		if (successResultShowType == 2) {
  			this.comEnemyNameContainer.alpha = 1;
  			let loaderNameIcon1 = this.comEnemyNameContainer.getChild("loaderNameIcon1");
  			let progressExp = this.comEnemyNameContainer.getChild("progress");
  			if (loaderNameIcon1.url != targetBaseRoleData.nameIcon) {
  				loaderNameIcon1.url = targetBaseRoleData.nameIcon;
  			}
  			progressExp.visible = false;
  			showTargetNameTimer = Timer.callLoop(0.16, () => {
  				let outResult = Tools.tranlateWorld3D2Screen(this.camera, new Laya.Vector3(this.successResultShowNpcAvatar.transform.position.x, this.successResultShowNpcAvatar.transform.position.y + 2, this.successResultShowNpcAvatar.transform.position.z));
  				let nodePos = this.comEnemyNameContainer.parent.globalToLocal(outResult.outPos.x, outResult.outPos.y);
  				this.comEnemyNameContainer.setXY(this.comEnemyNameContainer.parent.width * this.comEnemyNameContainer.parent.pivotX + nodePos.x, this.comEnemyNameContainer.parent.height * this.comEnemyNameContainer.parent.pivotY + nodePos.y);
  			}, this);
  		}
  		let context = {
  			bHighBgMode: questionData.bHighBgMode,
  			desc: questionData.wordQuestion,
  			confirm: () => {
  				onChoosedPrehande(true);
  			},
  			cancel: () => {
  				onChoosedPrehande(false);
  			},
  			confirmText: questionData.wordAnswer1,
  			cancelText: questionData.wordAnswer2,
  		};
  		let showPanelFunc = () => {
  			if (questionData.rewardSpecialType == QuestionRewardSpecialType.UnlockGoldStage ||
  				questionData.rewardSpecialType == QuestionRewardSpecialType.UnlockSpeedStage) {
  				let rewardSpecialType2StageType = {
  					[QuestionRewardSpecialType.UnlockGoldStage]: StageType.goldStage,
  					[QuestionRewardSpecialType.UnlockSpeedStage]: StageType.speedStage,
  				};
  				let stageType = rewardSpecialType2StageType[questionData.rewardSpecialType];
  				let template = db.get_ggg_challenge_stage_config(stageType);
  				let cancelAmount = template.unlockCostGoldAmount || 0;
  				if (!mgrChallenge.isUnlockedType(stageType)) {
  					let config = db.get_ggg_challenge_stage_config(stageType);
  					let adEventId = config.unlockAdEventId || db.ADV_DB_ADVNAME.video_PanelQuestionEvent_question;
  					let bAdActive = mgrAdv.checkActive(adEventId);
  					if (bAdActive) {
  						mgrAdv.statisVideoShow(adEventId);
  					}
  					else {
  						adEventId = null;
  					}
  					let context = {
  						adEventId: adEventId,
  						bTrialQuestion: true,
  						bHighBgMode: questionData.bHighBgMode,
  						bShowClose: true,
  						cancelAmount: cancelAmount,
  						sureAmount: cancelAmount,
  						desc: questionData.wordQuestion,
  						title: "特殊事件",
  						confirm: () => {
  							onChoosedPrehande(true);
  						},
  						cancel: () => {
  							let bCostSuccess = false;
  							if (!!cancelAmount) {
  								if (!!BaseFacade.mItem.isEnoughItem(2, cancelAmount)) {
  									BaseFacade.mItem.subItem(2, cancelAmount, "结算解锁特殊关卡");
  									bCostSuccess = true;
  								}
  								else {
  									mgrTip.alertNotEnough(2, true);
  								}
  							}
  							onChoosedPrehande(bCostSuccess);
  						},
  						refuse: () => {
  							onChoosedPrehande(false);
  						},
  						confirmText: questionData.wordAnswer1,
  						cancelText: questionData.wordAnswer2,
  					};
  					Director.openPanel("PanelQuestionEvent", context);
  					return;
  				}
  			}
  			else if (questionData.rewardSpecialType == QuestionRewardSpecialType.UnlockYard) {
  				let config = db.get_ggg_yard_config(1);
  				let cancelAmount = config.unlockCostGoldAmount || 0;
  				if (!mgrYard.isYardUnlocked()) {
  					let adEventId = config.unlockAdEventId || db.ADV_DB_ADVNAME.video_PanelQuestionEvent_question;
  					let bAdActive = mgrAdv.checkActive(adEventId);
  					if (bAdActive) {
  						mgrAdv.statisVideoShow(adEventId);
  					}
  					else {
  						adEventId = null;
  					}
  					let context = {
  						adEventId: adEventId,
  						bTrialQuestion: true,
  						bHighBgMode: questionData.bHighBgMode,
  						bShowClose: true,
  						cancelAmount: cancelAmount,
  						sureAmount: cancelAmount,
  						desc: questionData.wordQuestion,
  						title: "特殊事件",
  						confirm: () => {
  							onChoosedPrehande(true);
  						},
  						cancel: () => {
  							let bCostSuccess = false;
  							if (!!cancelAmount) {
  								if (!!BaseFacade.mItem.isEnoughItem(2, cancelAmount)) {
  									BaseFacade.mItem.subItem(2, cancelAmount, "结算解锁特殊关卡");
  									bCostSuccess = true;
  								}
  								else {
  									mgrTip.alertNotEnough(2, true);
  								}
  							}
  							onChoosedPrehande(bCostSuccess);
  						},
  						refuse: () => {
  							onChoosedPrehande(false);
  						},
  						confirmText: questionData.wordAnswer1,
  						cancelText: questionData.wordAnswer2,
  					};
  					Director.openPanel("PanelQuestionEvent", context);
  					return;
  				}
  			}
  			Director.openPanel("PanelResultQuestionEvent", context);
  		};
  		this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movIdle, 0, null, null, true, false);
  		switch (successResultShowType) {
  			case 8:
  				let model = Global.poolManager.get(Model, Tools.random(100) > 50 ? "panzi" : "zhong");
  				this.successResultShowNpcAvatar["__giftModel"] = model;
  				this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent8NpcKeepGiveGift, 0, () => {
  					this.successResultShowNpcAvatar.linMode2Bip001RHand(model);
  				}, () => {
  					let model = this.successResultShowNpcAvatar["__giftModel"];
  					if (!!model && !model.destroyed) {
  						this.successResultShowNpcAvatar.unlinkModel(model);
  					}
  					showPanelFunc();
  				}, false, false);
  				break;
  			case 9:
  				this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent9Npc1Hited, 0, null, null, false, false);
  				if (this.successResultShowNpcAvatar2) {
  					this.successResultShowNpcAvatar2.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent9Npc2Hited, 0, null, null, false, false);
  				}
  				Timer.callLater(0.6, () => {
  					showPanelFunc();
  				}, this);
  				break;
  			default:
  				if (!!questionData.relationRoleIdleQuoteNameHited && questionData.relationRoleIdleQuoteNameHited.indexOf("movIdle") < 0) {
  					this.successResultShowNpcAvatar.playAnimationQuote(questionData.relationRoleIdleQuoteNameHited, 0, null, () => {
  						if (questionData.relationRoleIdleQuoteNameInit && questionData.relationRoleIdleQuoteNameInit != "") {
  							this.successResultShowNpcAvatar.playAnimationQuote(questionData.relationRoleIdleQuoteNameInit, 0, null, null, true);
  						}
  						else {
  							this.successResultShowNpcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movIdle, 0, null, null, true);
  						}
  						showPanelFunc();
  					}, false, false);
  				}
  				else {
  					showPanelFunc();
  				}
  				break;
  		}
  	}
  	_onHitedObstacle(hitedObstacleInfoIndex) {
  		if (this.bObsacleHiting) {
  			return;
  		}
  		if (mgrChannel.vibrateEnable) {
  			mgrSdk.vibrate();
  		}
  		let bTriggeredSkill = false;
  		let info = this.obstacleInfoArr[hitedObstacleInfoIndex];
  		let eventData = db.get_amaze_cloth_crossing_road_event_db(info.eventId);
  		let tryChangePropertyFunc = () => {
  			if (!!eventData.effectValue && !bTriggeredSkill) {
  				let propertyIndex = mgrRole.getUsingGrownupLine() || this._getMaxPropertyValueIndex();
  				let func = this["addProperty" + propertyIndex].bind(this);
  				let amount = 0;
  				if (eventData.effectValue > 0) {
  					amount = (eventData.effectValue + mgrRole.getCurrLevelGotPropertyExtrnalValue()) * (info.ratio || 1);
  				}
  				else {
  					amount = (eventData.effectValue - mgrRole.getCurrLevelGotPropertyExtrnalValue()) * Math.abs(info.ratio || 1);
  				}
  				func(amount);
  			}
  		};
  		if (eventData.hitedActionType == NpcHitedActionType.playHited2) {
  			if (info.npcAvatar && !info.npcAvatar.destroyed) {
  				cc$1.tween(info.npcAvatar.transform).stop();
  				info.npcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movNpcHited01, 0, null, () => {
  				}, false, true);
  			}
  			tryChangePropertyFunc();
  			return;
  		}
  		if (this.avatarFollower && (eventData.hitedActionType == NpcHitedActionType.disapper || eventData.hitedActionType == NpcHitedActionType.playHited)) {
  			let retinueId = this.avatarFollower["_retinueId"];
  			let level = this.avatarFollower["_retinueLevel"];
  			let retinueTemplate = db.get_ggg_retinue_template_db(retinueId, level);
  			if (retinueTemplate.skillId == SkillType.helpPlayer && !info.npcAvatar) {
  				let result = mgrRetinue.tryTriggerRetinueSkill(retinueId, level);
  				if (!!result && result.bTriggered) {
  					mgrSound.play(retinueTemplate.useSkillSoundId);
  					this.avatarFollower.playAnimationQuote(retinueTemplate.skillMovName, 0, null, () => {
  						this.avatarFollower.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  					}, false, false);
  					this.addPlayerAvatarEff("130_e_skill_mm_01");
  					bTriggeredSkill = true;
  				}
  			}
  			else if (retinueTemplate.skillId == SkillType.dispelBegger && info.npcAvatar) {
  				let result = mgrRetinue.tryTriggerRetinueSkill(retinueId, level);
  				if (!!result && result.bTriggered) {
  					mgrSound.play(retinueTemplate.useSkillSoundId);
  					this.avatarFollower.playAnimationQuote(retinueTemplate.skillMovName, 0, null, () => {
  						this.avatarFollower.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  					}, false, false);
  					this.addPlayerAvatarEff("130_e_skill_sw_01");
  					bTriggeredSkill = true;
  				}
  			}
  		}
  		if (eventData.bShowHitEffect) {
  			this.linkModelAtBack("130_e_loop_smoke_01", this.avatarPlayerNode, null, 3, new Laya.Vector3(0, 1.2, 0));
  		}
  		if (this.timerOnHitObstacleResetFlag) {
  			this.timerOnHitObstacleResetFlag.stop();
  			this.timerOnHitObstacleResetFlag = null;
  		}
  		if (!bTriggeredSkill) {
  			this.bObsacleHiting = true;
  			this.samePropertyItemComboCount = 0;
  			this.lastHitedPropertyItemRankId = 0;
  			if (this.avatarFollower) {
  				this.avatarFollower.playAnimationQuote(ROLE_QUOTE_MOV.movIdle);
  			}
  			if (this.petFollower) {
  				this.petFollower.playAnimationQuote(ROLE_QUOTE_MOV.movIdle);
  			}
  			mgrSound.play(eventData.hitedSoundId);
  		}
  		let playWalkFunc = () => {
  			this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true);
  			if (this.avatarFollower) {
  				this.avatarFollower.playAnimationQuote(ROLE_QUOTE_MOV.movWalk);
  			}
  			if (this.petFollower) {
  				this.petFollower.playAnimationQuote(ROLE_QUOTE_MOV.movWalk);
  			}
  		};
  		if (!!bTriggeredSkill) {
  			this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movPlayerHited01, 0, null, () => {
  				playWalkFunc();
  			}, false, false);
  		}
  		switch (eventData.hitedActionType) {
  			case NpcHitedActionType.disapper: {
  				info.holder.active = false;
  				if (!bTriggeredSkill) {
  					this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movTumble, 0, null, null, false, false);
  					Timer.callLater(0.8, () => {
  						tryChangePropertyFunc();
  					}, this);
  					this.timerOnHitObstacleResetFlag = Timer.callLater(0.8, () => {
  						if (this.timerOnHitObstacleResetFlag) {
  							this.timerOnHitObstacleResetFlag.stop();
  							this.timerOnHitObstacleResetFlag = null;
  						}
  						playWalkFunc();
  						this.bObsacleHiting = false;
  					}, this);
  				}
  				else {
  				}
  				break;
  			}
  			case NpcHitedActionType.playHited: {
  				if (!bTriggeredSkill) {
  					this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movTumbleHitNpc, 0, null, null, false, false);
  					Timer.callLater(0.8, () => {
  						tryChangePropertyFunc();
  					}, this);
  					this.timerOnHitObstacleResetFlag = Timer.callLater(0.8, () => {
  						if (this.timerOnHitObstacleResetFlag) {
  							this.timerOnHitObstacleResetFlag.stop();
  							this.timerOnHitObstacleResetFlag = null;
  						}
  						playWalkFunc();
  						this.bObsacleHiting = false;
  					}, this);
  				}
  				else {
  					info.holder.active = false;
  				}
  				if (info.npcAvatar && !info.npcAvatar.destroyed) {
  					info.npcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movNpcHited01, 0, null, () => {
  					}, false, true);
  				}
  				break;
  			}
  			default:
  				tryChangePropertyFunc();
  				break;
  		}
  	}
  	checkQuestion() {
  		if (!this.stageData.bDisableGetScoreByCross) {
  			if (!this.currPlayerCrossPathRoadIndex) {
  				return;
  			}
  		}
  		let avatarPos = this.avatarPlayerNode.transform.position;
  		let pathIndex = this.currPlayerCrossPathRoadIndex || 0;
  		for (let k in this.questtionInfoArr) {
  			let info = this.questtionInfoArr[k];
  			if (!info.questionNode["bHited"] &&
  				Math.abs(avatarPos.z - info.questionNode.transform.position.z) < 1 &&
  				Math.abs(avatarPos.x - info.questionNode.transform.position.x) <= this.ROAD_WH) {
  				info.questionNode["bHited"] = true;
  				if (!pathIndex) {
  					let tmpIndex = 0;
  					let minXDis = 999999;
  					for (let i = 1; i <= this.PATH_COUNT; i++) {
  						let holderTmp = info.questionNode.getChildByName(`holder${i}`);
  						if (Math.abs(holderTmp.transform.position.x - avatarPos.x) < minXDis) {
  							tmpIndex = i;
  							minXDis = Math.abs(holderTmp.transform.position.x - avatarPos.x);
  						}
  					}
  					pathIndex = tmpIndex;
  					let questionData = db.get_amaze_cloth_crossing_question_db(info.id);
  					let amount = ((questionData["answerScore" + pathIndex] || 0) + mgrRole.getCurrLevelGotPropertyExtrnalValue()) * (questionData.answerScoreRatio || 1);
  					let scoreRank = questionData["answerScorePropertyIndex" + pathIndex] || 0;
  					let propertyIndex = mgrRole.getUsingGrownupLine() || this._getPropertyValueIndexByRank(scoreRank);
  					let func = this["addProperty" + propertyIndex].bind(this);
  					func(Math.ceil(amount));
  				}
  				let holder = info.questionNode.getChildByName(`holder${pathIndex}`);
  				holder.active = false;
  				let timu = info.questionNode.getChildByName("timu");
  				if (timu) {
  					timu.active = false;
  				}
  				break;
  			}
  		}
  	}
  	playerFollowerHandle() {
  		if (!!this.playerPosPathArr && this.playerPosPathArr.length > 100) {
  			this.playerPosPathArr.splice(0, this.playerPosPathArr.length - 100);
  		}
  		let avatarPos = this.avatarPlayerNode.transform.position;
  		if (!this.bRightAngleRotating) {
  			this.playerPosPathArr.push(this.avatarPlayerNode.transform.position.clone());
  		}
  		if (!!this.avatarFollowerNode) {
  			let followerZ = avatarPos.z + this.currAvatarFollowerDistance;
  			let posCount = this.playerPosPathArr.length;
  			let minDisZ = 999999999;
  			let minPos = null;
  			for (let i = posCount - 1; i >= 0; i--) {
  				let pos = this.playerPosPathArr[i];
  				if (Math.abs(followerZ - pos.z) < minDisZ) {
  					minDisZ = Math.abs(followerZ - pos.z);
  					minPos = pos;
  				}
  			}
  			minPos = minPos || new Laya.Vector3;
  			this.avatarFollowerNode.transform.localPosition = new Laya.Vector3(Tools.clamp(minPos.x + 0.3, -this.ROAD_WH / 2 + this.baseRoadX, this.ROAD_WH / 2 + this.baseRoadX), minPos.y, followerZ);
  		}
  		if (!!this.petFollowerNode) {
  			let followerZ = avatarPos.z + this.currAvatarFollowerDistance + 0.2;
  			let posCount = this.playerPosPathArr.length;
  			let minDisZ = 999999999;
  			let minPos = null;
  			for (let i = posCount - 1; i >= 0; i--) {
  				let pos = this.playerPosPathArr[i];
  				if (Math.abs(followerZ - pos.z) < minDisZ) {
  					minDisZ = Math.abs(followerZ - pos.z);
  					minPos = pos;
  				}
  			}
  			minPos = minPos || new Laya.Vector3;
  			this.petFollowerNode.transform.localPosition = new Laya.Vector3(Tools.clamp(minPos.x - 0.4, -this.ROAD_WH / 2 + this.baseRoadX - 0.2, this.ROAD_WH / 2 + this.baseRoadX + 0.2), minPos.y, followerZ);
  		}
  	}
  	adaptBaseY() {
  		let avatarPos = this.avatarPlayerNode.transform.position;
  		let count = this.baseYInfoArr.length;
  		for (let i = 0; i < count; i++) {
  			let info = this.baseYInfoArr[i];
  			if (avatarPos.z < info.node.transform.position.z && avatarPos.z >= (info.node.transform.position.z - info.len) &&
  				Math.abs(avatarPos.x - info.node.transform.position.x) < this.ROAD_WH) {
  				let numChildren = info.node.numChildren;
  				for (let i = 0; i < numChildren; i++) {
  					let child = info.node.getChildAt(i);
  					let startNode = null;
  					let endNode = null;
  					if (avatarPos.z > child.transform.position.z) {
  						endNode = child;
  						startNode = (info.node.getChildAt(i - 1) || info.node);
  						let ratio = Math.abs(avatarPos.z - startNode.transform.position.z) / (Math.abs(endNode.transform.position.z - startNode.transform.position.z) || 0.0001);
  						this.baseRoadY = startNode.transform.position.y + (endNode.transform.position.y - startNode.transform.position.y) * ratio;
  						return;
  					}
  				}
  				return;
  			}
  		}
  	}
  	checkTimerOver() {
  		if (!!this.stageData.stageTime && this.stageUsedTime > this.stageData.stageTime) {
  			this.bStageTimeOver = true;
  			Director.openPanel("PanelSpecialStageFail2", {
  				fOnConfirm: () => {
  					this.stageUsedTime = Math.max(0, this.stageUsedTime - 20);
  					this.bStageTimeOver = false;
  				},
  				fOnCancel: () => {
  					this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movIdle, 0, null, null, true, false);
  					this.stManager.setNextState(this.st_reward);
  				},
  			});
  		}
  	}
  	checkFinish() {
  		if (!this.bFinishArea && this.isFinishArea()) {
  			this.bFinishArea = true;
  			this.stManager.setNextState(this.st_arrivedFinishArea);
  		}
  	}
  	isFinishArea() {
  		if (!this.jiesuantaiModel) {
  			return false;
  		}
  		if (Math.abs(this.avatarPlayerNode.transform.position.z - this.jiesuantaiModel.resNode.transform.position.z) < 1 &&
  			Math.abs(this.baseRoadX - this.jiesuantaiModel.resNode.transform.position.x) < 1) {
  			return true;
  		}
  		else {
  			return false;
  		}
  	}
  	inPlayerArrivedPoint2() {
  		this.stManager.setNextState(this.st_allArrivedPoint2);
  	}
  	exePlayerArrivedPoint2() {
  	}
  	outPlayerArrivedPoint2() { }
  	changeJiesuanTaiDoor(bOpen, bImmi) {
  		let needOpenDoorName = "jiesuantai2";
  		if (!this.jiesuantaiModel.resNode.getChildByName(needOpenDoorName)) {
  			return;
  		}
  		let menLeftNode = this.jiesuantaiModel.resNode.getChildByName(needOpenDoorName).getChildByName("men1");
  		let menRightNode = this.jiesuantaiModel.resNode.getChildByName(needOpenDoorName).getChildByName("men2");
  		if (!menLeftNode) {
  			return;
  		}
  		let rotLeft = menLeftNode.transform.localRotationEuler;
  		let rotRight = menRightNode.transform.localRotationEuler;
  		menLeftNode["_originLocalRotationEuler"] = menLeftNode["_originLocalRotationEuler"] || rotLeft.clone();
  		menRightNode["_originLocalRotationEuler"] = menRightNode["_originLocalRotationEuler"] || rotRight.clone();
  		if (bImmi) {
  			if (bOpen) {
  				menLeftNode.transform.localRotationEuler = new Laya.Vector3(rotLeft.x, 90, rotLeft.z);
  				menRightNode.transform.localRotationEuler = new Laya.Vector3(rotRight.x, -90, rotRight.z);
  			}
  			else {
  				menLeftNode.transform.localRotationEuler = menLeftNode["_originLocalRotationEuler"];
  				menRightNode.transform.localRotationEuler = menRightNode["_originLocalRotationEuler"];
  			}
  			return;
  		}
  		if (bOpen) {
  			cc$1.tween(menLeftNode.transform).toLocalRotationEulerY3D(1, 90).start();
  			cc$1.tween(menRightNode.transform).toLocalRotationEulerY3D(1, -90).start();
  			mgrSound.play(109);
  		}
  		else {
  			cc$1.tween(menLeftNode.transform).toLocalRotationEulerY3D(1, menLeftNode["_originLocalRotationEuler"].y).start();
  			cc$1.tween(menRightNode.transform).toLocalRotationEulerY3D(1, menRightNode["_originLocalRotationEuler"].y).start();
  		}
  	}
  	inAllArrivedPoint2() {
  		let param = this.avatarPosCameraDict[6].cameraData;
  		this.cameraFollow.endRotation.x = param.rot.x;
  		this.cameraFollow.fov = param.fov;
  		this.cameraRoateValueWhenAllArrived = this.cameraFollow.endRotation.y;
  		this.cameraFollow.target = this.judgeNode2;
  		this.cameraFollow.offset = param.offset;
  		this.cameraFollow.lerpValue = 1;
  		this.cameraFollow.lerpValuePosZ = 0;
  		if (this.bSuccess) {
  			this.currSuccessResultEffect = Global.poolManager.get(Model, !!this.bResultShowSelectIsRight ? "130_e_loop_shengli_01" : "130_e_loop_shibai_01");
  			this.linkModelAtBack(this.currSuccessResultEffect);
  			this.currSuccessResultEffect.transform.localRotationEulerY = 180;
  			this.currSuccessResultEffect.transform.position = new Laya.Vector3(this.avatarPlayerNode.transform.position.x - 1.5, this.avatarPlayerNode.transform.position.y + 4, this.avatarPlayerNode.transform.position.z);
  		}
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.playerRoleId);
  		if (this.bSuccess) {
  			Timer.callLater(0.5, () => {
  				this.stManager.setNextState(this.st_reward);
  			}, this);
  		}
  		else {
  			let playerAvatarGoout = () => {
  				let pos = this.avatarPlayerNode.transform.localPosition.clone();
  				cc$1.tween(this.avatarPlayerNode.transform).toLocalPos3D(5, pos.x - 5, pos.y, pos.z).start();
  				cc$1.tween(this.avatarPlayerContainer.transform).toLocalRotationEuler3D(0.2, 0, -90, 0).start();
  			};
  			let animationId = this.currTurnResultFieldData[1];
  			if (animationId == "movLoseShow03") {
  				let model = Global.poolManager.get(Model, "jiasuo");
  				this.getPlayerAvatar().linMode2Bip001Spine1(model);
  				playerAvatarGoout();
  			}
  			else if (animationId == "movLoseShow04") {
  				let model = Global.poolManager.get(Model, "baoguo");
  				this.getPlayerAvatar().linMode2Bip001LHand(model);
  				playerAvatarGoout();
  			}
  			this.playerAvatarPlayAnimationQuote(animationId, 0, () => {
  				if (this.faildNpcAvatar) {
  					this.faildNpcAvatar.transform.position = this.avatarPlayerNode.transform.position.clone();
  					this.faildNpcAvatar.playAnimationQuote(animationId, 0, null, () => {
  						this.faildNpcAvatar.active = false;
  					}, this.bSuccess, false);
  				}
  			}, () => {
  				if (this.faildNpcAvatar) {
  					this.avatarPlayerNode.active = false;
  				}
  				this.stManager.setNextState(this.st_reward);
  			}, this.bSuccess, false);
  		}
  	}
  	exeAllArrivedPoint2() {
  		this.cameraFollow.distance = Math.max(this.cameraFollow.distance - 0.01, 4);
  	}
  	outAllArrivedPoint2() { }
  	tryInitSuccessResultAvatar() {
  		if (!this.bSuccess) {
  			return;
  		}
  		let isValidResultQuestion = (qId) => {
  			let template = db.get_amaze_cloth_crossing_question_db(qId);
  			if (!template) {
  				return false;
  			}
  			switch (template.rewardSpecialType) {
  				case QuestionRewardSpecialType.ExtrnalLevelUp:
  					if (mgrRole.isMaxGotPropertyExtrnalLevel()) {
  						return false;
  					}
  					break;
  				case QuestionRewardSpecialType.RetinueLevelUp:
  					if (!mgrRetinue.followingRetinueId || mgrRetinue.isMaxLevel(mgrRetinue.followingRetinueId)) {
  						return false;
  					}
  					break;
  				case QuestionRewardSpecialType.PetLevelUp:
  					if (!mgrPet.followingPetId || mgrPet.isMaxLevel(mgrPet.followingPetId)) {
  						return false;
  					}
  					break;
  				case QuestionRewardSpecialType.UnlockGoldStage:
  					if (!!mgrChallenge.isUnlockedType(StageType.goldStage)) {
  						return false;
  					}
  					break;
  				case QuestionRewardSpecialType.UnlockSpeedStage:
  					if (!!mgrChallenge.isUnlockedType(StageType.speedStage)) {
  						return false;
  					}
  					break;
  				case QuestionRewardSpecialType.UnlockYard:
  					if (!!mgrYard.isYardUnlocked()) {
  						return false;
  					}
  					break;
  				default:
  					break;
  			}
  			return true;
  		};
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.playerRoleId);
  		this.resultQuestionId = 0;
  		let validUnlockResultQuestionIdArr = [];
  		let mustAdResultQidArr = this.stageData.afterFirstMustUnlockStageResultQuestionIdArr;
  		for (let k in mustAdResultQidArr) {
  			let tmpId = mustAdResultQidArr[k];
  			let template = db.get_amaze_cloth_crossing_question_db(tmpId);
  			if (!template) {
  				continue;
  			}
  			if (template.rewardSpecialType == QuestionRewardSpecialType.UnlockGoldStage || template.rewardSpecialType == QuestionRewardSpecialType.UnlockSpeedStage) {
  				let rewardSpecialType2StageType = {
  					[QuestionRewardSpecialType.UnlockGoldStage]: StageType.goldStage,
  					[QuestionRewardSpecialType.UnlockSpeedStage]: StageType.speedStage,
  				};
  				if (!mgrChallenge.isUnlockedType(rewardSpecialType2StageType[template.rewardSpecialType])) {
  					validUnlockResultQuestionIdArr.push(tmpId);
  				}
  			}
  			else if (template.rewardSpecialType == QuestionRewardSpecialType.UnlockYard) {
  				if (!mgrYard.isYardUnlocked()) {
  					validUnlockResultQuestionIdArr.push(tmpId);
  				}
  			}
  		}
  		if (validUnlockResultQuestionIdArr.length > 0) {
  			this.resultQuestionId = Tools.randomGotOneArrayData(validUnlockResultQuestionIdArr);
  		}
  		else {
  			this.resultQuestionId = 0;
  		}
  		this.bRecordNextResultQuestion = (!this.resultQuestionId && this.stageData.stageType == StageType.mainStage) ? true : false;
  		if (!this.resultQuestionId && !!mgrRole.getNextResultQuestionId()) {
  			this.resultQuestionId = mgrRole.getNextResultQuestionId();
  		}
  		if (!this.resultQuestionId) {
  			let validStageResultQuestionArr = [];
  			for (let k in this.stageData.resultQuestionIdArr) {
  				let qId = this.stageData.resultQuestionIdArr[k];
  				if (isValidResultQuestion(qId)) {
  					validStageResultQuestionArr.push(qId);
  				}
  			}
  			let validResultQuestionArr = [];
  			for (let k in roleData.successResultQuestionArr) {
  				let qId = roleData.successResultQuestionArr[k];
  				if (isValidResultQuestion(qId)) {
  					validResultQuestionArr.push(qId);
  				}
  			}
  			if (!!validStageResultQuestionArr && validStageResultQuestionArr.length > 0) {
  				this.resultQuestionId = Tools.randomGotOneArrayData(validStageResultQuestionArr);
  			}
  			else if (!!validResultQuestionArr && validResultQuestionArr.length > 0) {
  				let unAnsweredQidArr = [];
  				for (let i = 0; i < validResultQuestionArr.length; i++) {
  					let qId = validResultQuestionArr[i];
  					if (!mgrRole.isAnsweredQuestionId(qId)) {
  						unAnsweredQidArr.push(qId);
  					}
  				}
  				if (unAnsweredQidArr.length > 0) {
  					this.resultQuestionId = unAnsweredQidArr[0];
  				}
  				else {
  					this.resultQuestionId = Tools.randomGotOneArrayData(validResultQuestionArr);
  				}
  			}
  		}
  		let resultQuestion = db.get_amaze_cloth_crossing_question_db(this.resultQuestionId);
  		if (!resultQuestion) {
  			return;
  		}
  		let successResultShowType = !!resultQuestion ? resultQuestion.resultShowType : 0;
  		let idleQuoteName = ROLE_QUOTE_MOV.movIdle2;
  		let roleid = resultQuestion.relationRoleId || 3;
  		this.successResultShowUsingBaseRoleId = roleid;
  		if (successResultShowType == 2) {
  			let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.playerRoleId);
  			let arr = [];
  			for (let k in roleData.resultShowTypeTargetRoleIdArr) {
  				let tmpId = roleData.resultShowTypeTargetRoleIdArr[k];
  				if (tmpId != this.playerRoleId) {
  					arr.push(tmpId);
  				}
  			}
  			this.successResultShowUsingBaseRoleId = Tools.randomGotOneArrayData(arr);
  			roleid = this.successResultShowUsingBaseRoleId;
  		}
  		if (successResultShowType == 7 || successResultShowType == 8 || successResultShowType == 9) {
  			let helpNpcAvatar = null;
  			helpNpcAvatar = new NpcAvatar(resultQuestion.resultHelperRoleId);
  			helpNpcAvatar.registerAllLoadEndCallback(() => {
  				this.linkModelAtBack(helpNpcAvatar);
  				let nodeHolder = this.jiesuantaiModel.resNode.getChildByName("successResultHolder1");
  				helpNpcAvatar.transform.position = nodeHolder.transform.position.clone();
  				helpNpcAvatar.active = false;
  			});
  			this.successHelpResultShowNpcAvatar = helpNpcAvatar;
  		}
  		let npcAvatar = null;
  		if (roleid && db.get_amaze_cloth_crossing_role_db(roleid)) {
  			npcAvatar = new NpcAvatar(roleid);
  			npcAvatar.registerAllLoadEndCallback(() => {
  				this.linkModelAtBack(npcAvatar);
  				let nodeHolder = ((successResultShowType == 3 || successResultShowType == 5) ? this.jiesuantaiModel.resNode.getChildByName("successResultHolder2") : this.jiesuantaiModel.resNode.getChildByName("successResultHolder1"));
  				npcAvatar.transform.position = new Laya.Vector3(nodeHolder.transform.position.x, nodeHolder.transform.position.y + 0.1, nodeHolder.transform.position.z);
  				if (idleQuoteName && idleQuoteName != "") {
  					npcAvatar.playAnimationQuote(idleQuoteName, 0, null, null, true);
  				}
  			});
  		}
  		this.successResultShowNpcAvatar = npcAvatar;
  		if (successResultShowType == 9) {
  			let roleid = resultQuestion.relationRoleId2 || 3;
  			let npcAvatar = null;
  			if (roleid && db.get_amaze_cloth_crossing_role_db(roleid)) {
  				npcAvatar = new NpcAvatar(roleid);
  				npcAvatar.registerAllLoadEndCallback(() => {
  					this.linkModelAtBack(npcAvatar);
  					let nodeHolder = this.jiesuantaiModel.resNode.getChildByName("successResultHolder1");
  					npcAvatar.transform.position = new Laya.Vector3(nodeHolder.transform.position.x + 0.3, nodeHolder.transform.position.y + 0.1, nodeHolder.transform.position.z - 0.3);
  					npcAvatar.playIdle();
  					npcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movResultEvent9Npc2Idle, 0, null, null, true);
  				});
  			}
  			this.successResultShowNpcAvatar2 = npcAvatar;
  		}
  	}
  	inArrivedFinishArea() {
  		this.comMask.visible = false;
  		this.comScrollTip.visible = false;
  		this.bTouchBg = false;
  		this.touchBgBeginPos = null;
  		this.lastTouchBgPos = null;
  		this.MOVE_FPS = 2;
  		this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  		if (!!this.snowEffect && !this.snowEffect.destroyed) {
  			this.snowEffect.active = false;
  		}
  		this.removePlayerAvatarEff();
  		this.removePlayerAvatarGroup2Eff();
  		if (!!this.obstacleInfoArr) {
  			for (let k in this.obstacleInfoArr) {
  				let data = this.obstacleInfoArr[k];
  				if (data.holder.transform.position.z < this.avatarPlayerNode.transform.position.z) {
  					continue;
  				}
  				if (!!data.npcAvatar && !data.npcAvatar.destroyed) {
  					cc$1.tween(data.npcAvatar.transform).stop();
  					data.npcAvatar.destroy();
  				}
  				if (!!data.holder && !data.holder.destroyed) {
  					cc$1.tween(data.holder.transform).stop();
  					data.holder.transform.localRotationEuler = new Laya.Vector3;
  					if (data.holder["_originPos"]) {
  						data.holder.transform.localPosition = data.holder["_originPos"];
  						delete data.holder["_originPos"];
  					}
  				}
  			}
  		}
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.playerRoleId);
  		this.bPlayerPassStage = true;
  		this.bSuccess = true;
  		let level = mgrRole.getMaxLevelByRoleId(roleData.id);
  		if (level == roleData.level) {
  			this.bPlayerPassStage = true;
  			this.bSuccess = true;
  		}
  		if (!this.bSuccess) {
  			let validFaildIndexArr = [];
  			for (let i = 1; i < 10; i++) {
  				let data = roleData["resultFaild" + i];
  				if (data && data.length > 0) {
  					validFaildIndexArr.push(i);
  				}
  			}
  			if (!this.currTurnResultFieldData) {
  				let fieldResultIndex = Tools.randomGotOneArrayData(validFaildIndexArr);
  				this.currTurnResultFieldData = roleData["resultFaild" + fieldResultIndex];
  			}
  			let animationId = this.currTurnResultFieldData[1];
  			let tmpData = db.get_amaze_cloth_crossing_result_interactive_db(animationId);
  			if (!!tmpData) {
  				this.faildNpcAvatar = new NpcAvatar(tmpData.npcRoleId);
  				this.linkModelAtBack(this.faildNpcAvatar);
  				this.faildNpcAvatar.transform.localPositionZ = 100;
  			}
  		}
  		let targetPlayerX = !!this.avatarEnemyContainer ? this.baseRoadX - 0.5 : this.baseRoadX;
  		cc$1.tween(this.avatarPlayerNode.transform).to(1, { localPositionX: targetPlayerX }).start();
  		this.tryInitSuccessResultAvatar();
  		this.changeJiesuanTaiDoor(true);
  	}
  	exeArrivedFinishArea(deltaTime) {
  		if (this.cameraFollow.lerpValue < this.finishAreaTargetLerpValue) {
  			this.cameraFollow.lerpValue = Tools.clamp(this.cameraFollow.lerpValue + 0.0003, 0.01, this.finishAreaTargetLerpValue);
  		}
  		if (!this.bFocus) {
  			return;
  		}
  		if (!this.bPlayerArrived) {
  			let dis = Math.min(deltaTime * this.getMoveFps(), 0.03 * this.getMoveFps());
  			this.avatarPlayerNode.transform.localPositionZ -= dis;
  			let upstairStartNode = this.jiesuantaiModel.resNode.getChildByName("upstairStart");
  			let upstairCompleteNode = this.jiesuantaiModel.resNode.getChildByName("upstairComplete");
  			if (this.avatarPlayerNode.transform.position.z > upstairStartNode.transform.position.z) {
  				this.avatarPlayerNode.transform.localPositionY = upstairStartNode.transform.localPositionY;
  			}
  			else if (this.avatarPlayerNode.transform.position.z < upstairCompleteNode.transform.position.z) {
  				this.avatarPlayerNode.transform.localPositionY = upstairCompleteNode.transform.localPositionY;
  			}
  			else {
  				let disUpstair = Math.abs(upstairCompleteNode.transform.position.z - upstairStartNode.transform.position.z);
  				let disUpstairMoved = Math.abs(upstairStartNode.transform.position.z - this.avatarPlayerNode.transform.position.z);
  				let ratioZ = disUpstairMoved / disUpstair;
  				this.avatarPlayerNode.transform.localPositionY = upstairStartNode.transform.localPositionY + (upstairCompleteNode.transform.localPositionY - upstairStartNode.transform.localPositionY) * ratioZ;
  			}
  			this.mapSky.transform.position = new Laya.Vector3(this.baseRoadX, this.avatarPlayerNode.transform.position.y, this.avatarPlayerNode.transform.position.z);
  			let param = this.avatarPosCameraDict[6].cameraData;
  			this.cameraFollow.position = new Laya.Vector3(param.pos.x + this.baseRoadX, param.pos.y + this.avatarPlayerNode.transform.position.y, param.pos.z + this.avatarPlayerNode.transform.position.z);
  			this.cameraFollow.endRotation = new Laya.Vector3(param.rot.x, param.rot.y + this.avatarPlayerNode.transform.localRotationEulerY % 360, param.rot.z);
  			if (this.avatarPlayerNode.transform.position.z < this.judgeNode2.transform.position.z) {
  				this.avatarPlayerNode.transform.position = this.judgeNode2.transform.position.clone();
  				this.bPlayerArrived = true;
  				this.bObsacleHiting = false;
  				this.tryShowSuccessResultShow();
  			}
  		}
  	}
  	outArrivedFinishArea() { }
  	inZeroPropertyDie() {
  		this.bTouchBg = false;
  		this.touchBgBeginPos = null;
  		this.lastTouchBgPos = null;
  		this.MOVE_FPS = 2;
  		this.removePlayerAvatarEff();
  		this.removePlayerAvatarGroup2Eff();
  		this.bPlayerPassStage = false;
  		this.bSuccess = this.bPlayerPassStage;
  		if (!this.bSuccess) {
  			let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.playerRoleId);
  		}
  		this.stManager.setNextState(this.st_reward);
  	}
  	exeZeroPropertyDie(deltaTime) {
  	}
  	outZeroPropertyDie() { }
  	inCleanForRestart() {
  		Timer.callLater(0.01, () => {
  			this.cleanModels();
  			if (this.mapStage) {
  				this.mapStage.destroy();
  				this.mapStage = null;
  			}
  			if (this.avatarPlayerNode) {
  				this.avatarPlayerNode.destroy();
  				this.avatarPlayerNode = null;
  			}
  			this.mapSky.transform.position = new Laya.Vector3(0, 0, 0);
  			let doNext = () => {
  				this.context.stageId = this.context.stageId || mgrCrossStage.getCurrStageId();
  				this.genStageMap(() => {
  					this.stManager.setNextState(this.st_init);
  				});
  			};
  			if (!!this.context.stageId) {
  				doNext();
  			}
  			else {
  				this.tryShowBornChapter(doNext);
  			}
  		}, this);
  	}
  	exeCleanForRestart() { }
  	outCleanForRestart() {
  		mgrCrossStage.tryShowChestDialog();
  	}
  	inRevivalAndGoon() {
  		this.stManager.setNextState(this.st_cleanForRestart);
  	}
  	exeRevivalAndGoon() { }
  	outRevivalAndGoon() { }
  	inReward() {
  		GameStatistics.statisOnStageEnd(this.stageData.statisPointId, this.bSuccess ? 1 : 0, undefined, false, [`${mgrRole.bornCount}_${this.playerRoleId}`]);
  		let decreeAmountOld = Math.min(10, BaseFacade.mItem.getItemAmount(4));
  		let canAddDecreeAmount = Math.min(10 - decreeAmountOld, this.currStageGotDecreeAmount || 0);
  		BaseFacade.mItem.addItem(4, canAddDecreeAmount, "关卡中获得");
  		this.playPropBtnsMoveOut();
  		this.comTargetProperty.alpha = 0;
  		this.comEnemyNameContainer.alpha = 0;
  		mgrRole.markCompletedGrownupLineSelect();
  		mgrRole.setUsingPlayerRoleId(this.playerRoleId);
  		let grownupLine = mgrRole.getUsingGrownupLine() || this._getMaxPropertyValueIndex();
  		mgrRole.setUsingGrownupLine(grownupLine);
  		let propertyValue = this[`currentProperty${grownupLine}`] || 0;
  		propertyValue = Math.max(1, propertyValue);
  		mgrRole.setPropertyValueByGrownunLine(grownupLine, propertyValue);
  		if (this.stageData.stageType == StageType.mainStage) {
  			let startRoleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.startRoleId);
  			let currRoleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.playerRoleId);
  			if (currRoleData.level < startRoleData.level) {
  				mgrRole.setNextResultQuestionId(0);
  			}
  			else {
  				let questionData = db.get_amaze_cloth_crossing_question_db(this.resultQuestionId);
  				if (questionData &&
  					questionData.rewardSpecialType != QuestionRewardSpecialType.UnlockGoldStage &&
  					questionData.rewardSpecialType != QuestionRewardSpecialType.UnlockSpeedStage &&
  					questionData.rewardSpecialType != QuestionRewardSpecialType.UnlockYard) {
  					mgrRole.setNextResultQuestionId(this.nextResultQuestionId || 0);
  				}
  			}
  			mgrCrossStage.finishStage(this.context.stageId);
  		}
  		else if (this.stageData.stageType == StageType.goldStage) {
  			mgrChallenge.markChallengeJoined(this.stageData.stageType);
  			let rewardSpecialTypeStage = QuestionRewardSpecialType.GoldReward;
  			let rewardSpecialTypeParamStage = this.stageData.rewardSpecialTypeParamArr[rewardSpecialTypeStage - 1] || 1;
  			let rewardSpecialTypeRatioStage = this.stageData.rewardSpecialRatioArr[rewardSpecialTypeStage - 1] || 1;
  			let stageCoinCount = Math.ceil(rewardSpecialTypeParamStage * rewardSpecialTypeRatioStage);
  			Director.openPanel("PanelSpecialStageSuccess1", {
  				itemId: 2, itemAmount: (this.currStageGotGoldAmount + stageCoinCount), fOnClose: () => {
  					this.stManager.setNextState(this.st_finish);
  					return;
  				}
  			});
  			return;
  		}
  		else {
  			let bTimeOver = this.stageUsedTime > this.stageData.stageTime ? true : false;
  			mgrChallenge.markChallengeJoined(this.stageData.stageType);
  			if (bTimeOver) {
  				this.stManager.setNextState(this.st_finish);
  			}
  			else {
  				let arr = [];
  				for (let i = 0; i < this.stageData.rewardSpecialTypeWeightArr.length; i++) {
  					let weight = this.stageData.rewardSpecialTypeWeightArr[i];
  					arr.push({ weight: weight, rewardSpecialType: i + 1 });
  				}
  				let rewardSpecialTypeInfo = Tools.RoundTableProbability(arr, "weight");
  				let rewardSpecialType = (!!arr && !!rewardSpecialTypeInfo) ? rewardSpecialTypeInfo.rewardSpecialType : 1;
  				let rewardSpecialTypeParam = this.stageData.rewardSpecialTypeParamArr[rewardSpecialType - 1] || 1;
  				if (rewardSpecialType == QuestionRewardSpecialType.GoldReward || rewardSpecialType == QuestionRewardSpecialType.MaxPropertyReward) {
  					let rewardSpecialTypeRatio = this.stageData.rewardSpecialRatioArr[rewardSpecialType - 1] || 1;
  					rewardSpecialTypeParam = Math.ceil(rewardSpecialTypeParam * rewardSpecialTypeRatio);
  				}
  				console.warn("-----------rewardSpecialType=", rewardSpecialType, rewardSpecialTypeParam);
  				Director.openPanel("PanelSpecialStageSuccess2", {
  					stageGotGoldAmount: Math.max(0, this.currStageGotGoldAmount || 0),
  					rewardSpecialType: rewardSpecialType,
  					rewardSpecialTypeParam: rewardSpecialTypeParam,
  					passedTime: this.stageUsedTime,
  					fOnClose: () => {
  						this.stManager.setNextState(this.st_finish);
  						return;
  					}
  				});
  			}
  			return;
  		}
  		if (this.startRoleId != this.playerRoleId && this.bResultShowSelectIsRight) {
  			let paramsPanelScroll = {
  				oldRoleId: this.startRoleId,
  				newRoleId: this.playerRoleId,
  				fOnClose: () => {
  					this.stManager.setNextState(this.st_reward2);
  				}
  			};
  			Director.openPanel("PanelScroll", paramsPanelScroll);
  		}
  		else {
  			this.stManager.setNextState(this.st_reward2);
  		}
  	}
  	exeReward() {
  	}
  	outReward() {
  	}
  	inReward2() {
  		Director.openPanel("PanelSettlement", {
  			propertyChangedAmount1: this.currentProperty1 - this.startProperty1,
  			propertyChangedAmount2: this.currentProperty2 - this.startProperty2,
  			propertyChangedAmount3: this.currentProperty3 - this.startProperty3,
  			propertyChangedAmount4: this.currentProperty4 - this.startProperty4,
  			oldRoleId: this.startRoleId,
  			newRoleId: this.playerRoleId,
  			fOnClose: () => {
  				this.stManager.setNextState(this.st_reward3);
  			}
  		});
  	}
  	exeReward2() { }
  	outReward2() { }
  	inReward3() {
  		this.stManager.setNextState(this.st_reward4);
  	}
  	exeReward3() { }
  	outReward3() { }
  	inReward4() {
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.playerRoleId);
  		let maxLevel = mgrRole.getMaxLevelByGrownline(roleData.grownupLine);
  		let bMaxLevel = maxLevel == roleData.level ? true : false;
  		let playTimeLineFunc = (tmlName) => {
  			if (!tmlName || tmlName == "") {
  				return false;
  			}
  			let originMapStageZ = this.mapStage.transform.localPositionZ;
  			if (tmlName != "tongyong") {
  				this.playTimeline(roleData.maxLevelResultTimeline, (clearBefore) => {
  					clearBefore();
  					this.mapSky.active = true;
  					this.mapStage.transform.localPositionZ = originMapStageZ;
  					this.stManager.setNextState(this.st_finish);
  				}, () => {
  					this.mapStage.transform.localPositionZ -= 1000;
  					this.mapSky.active = false;
  				});
  			}
  			else {
  				this.playResultCommonTimeline("tongyong", (clearBefore) => {
  					clearBefore();
  					this.mapSky.active = true;
  					this.mapStage.transform.localPositionZ = originMapStageZ;
  					this.stManager.setNextState(this.st_finish);
  				}, () => {
  					this.mapStage.transform.localPositionZ -= 1000;
  					this.mapSky.active = false;
  				});
  			}
  			return true;
  		};
  		let bPlayedTml = false;
  		if (this.playerRoleId == this.startRoleId) {
  		}
  		else {
  			bPlayedTml = playTimeLineFunc(roleData.maxLevelResultTimeline);
  			if (!!bPlayedTml) {
  				return;
  			}
  		}
  		this.stManager.setNextState(this.st_finish);
  	}
  	exeReward4() {
  	}
  	outReward4() { }
  	inFinish() {
  		this.showVideoRecord(() => {
  			this.context.stageId = null;
  			this.stManager.setNextState(this.st_cleanForRestart);
  		});
  	}
  	exeFinish() {
  	}
  	outFinish() { }
  	showMovieWordPanelVisible(word, name, stayTime) {
  		if (!word || word == "") {
  			return;
  		}
  		if (!this.comChat.visible) {
  			this.comChat.visible = true;
  		}
  		let labelName = this.comChat.getChild("chatName");
  		let labelContent = this.comChat.getChild("chatContent");
  		labelContent.text = word;
  		labelName.text = name || " ";
  		cc$1.tween(this.comChat, true)
  			.toScale(0.1, 1)
  			.delay(stayTime || 3)
  			.toScale(0.1, 0)
  			.start();
  	}
  	hideMovieWordPanelNode() {
  		if (!this.comChat.visible) {
  			return;
  		}
  		cc$1.tween(this.comChat, true)
  			.toScale(0.1, 0)
  			.start();
  	}
  	playTimeline(tilelineName, callbackComplete, onLoadedCallback) {
  		Director.showWait("load_timeline");
  		let director = new PlayableDirector();
  		director.stopUpdateOnlyWhenFinish = true;
  		let template = db.get_timeline_db(tilelineName);
  		director.load(template.resPath, () => {
  			onLoadedCallback && onLoadedCallback();
  			Director.hideWait("load_timeline");
  			this.linkModelAtBack(director);
  			this.camera.active = false;
  			director.play();
  			let timeSoundDbMap = db.get_ggg_timeline_movie_word_db_map();
  			let soundArr = [];
  			for (let k in timeSoundDbMap) {
  				let tmp = timeSoundDbMap[k];
  				if (tmp.timelineName == tilelineName) {
  					soundArr.push(tmp);
  				}
  			}
  			if (soundArr.length > 0) {
  				soundArr = Tools.sortArrayByField(soundArr, "frameNum");
  				for (let i = 0; i < soundArr.length; i++) {
  					const element = soundArr[i];
  					let frameNum = element.frameNum;
  					Timer.callLater(frameNum / 30, () => {
  						mgrSound.playSound(element.soundId);
  						this.showMovieWordPanelVisible(element.word, element.playerName);
  					}, this);
  				}
  			}
  			let oldBgSoundId = mgrSound.playingMusicSoundId;
  			let config = db.get_ggg_timeline_config_db(tilelineName);
  			if (!!config && config.bgSoundId) {
  				mgrSound.play(config.bgSoundId);
  			}
  			director.on("STOPPED", this, () => {
  				let clearBefore = () => {
  					if (this.isDisposed || this.resNode.isDisposed) {
  						return;
  					}
  				};
  				this.hideMovieWordPanelNode();
  				mgrSound.playSound(oldBgSoundId);
  				this.camera.active = true;
  				director.removeSelf();
  				director.destroy();
  				callbackComplete && callbackComplete(clearBefore);
  			});
  		});
  	}
  	playResultCommonTimeline(tilelineName, callbackComplete, onLoadedCallback) {
  		Director.showWait("load_timeline");
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.playerRoleId);
  		let avatar = new NpcAvatar(roleData.roleId);
  		avatar["_bCustomAvatar"] = true;
  		avatar.registerAllLoadEndCallback(() => {
  			let director = new PlayableDirector();
  			director.stopUpdateOnlyWhenFinish = true;
  			let template = db.get_timeline_db(tilelineName);
  			director.load(template.resPath, () => {
  				onLoadedCallback && onLoadedCallback();
  				let avatarNode = director.findChild("ggx05");
  				avatarNode.addChild(avatar);
  				avatar.playIdle();
  				Director.hideWait("load_timeline");
  				this.linkModelAtBack(director);
  				this.camera.active = false;
  				director.play();
  				let aniArr = [
  					{ frameNum: 31, mov: ROLE_QUOTE_MOV.movResultEvent2RightLower },
  					{ frameNum: 103, mov: ROLE_QUOTE_MOV.movResultEvent2RightLower },
  					{ frameNum: 179, mov: ROLE_QUOTE_MOV.movIdle },
  				];
  				for (let i = 0; i < aniArr.length; i++) {
  					const element = aniArr[i];
  					let frameNum = element.frameNum;
  					Timer.callLater(frameNum / 30, () => {
  						avatar.playAnimationQuote(element.mov, 0, null, null, false, true);
  					}, this);
  				}
  				let timeSoundDbMap = db.get_ggg_timeline_movie_word_db_map();
  				let soundArr = [];
  				for (let k in timeSoundDbMap) {
  					let tmp = timeSoundDbMap[k];
  					if (tmp.timelineName == tilelineName) {
  						soundArr.push(tmp);
  					}
  				}
  				if (soundArr.length > 0) {
  					soundArr = Tools.sortArrayByField(soundArr, "frameNum");
  					for (let i = 0; i < soundArr.length; i++) {
  						const element = soundArr[i];
  						let frameNum = element.frameNum;
  						Timer.callLater(frameNum / 30, () => {
  							mgrSound.playSound(element.soundId);
  							this.showMovieWordPanelVisible(element.word, element.playerName);
  						}, this);
  					}
  				}
  				let oldBgSoundId = mgrSound.playingMusicSoundId;
  				let config = db.get_ggg_timeline_config_db(tilelineName);
  				if (!!config && config.bgSoundId) {
  					mgrSound.play(config.bgSoundId);
  				}
  				director.on("STOPPED", this, () => {
  					let clearBefore = () => {
  						if (this.isDisposed || this.resNode.isDisposed) {
  							return;
  						}
  					};
  					this.hideMovieWordPanelNode();
  					mgrSound.playSound(oldBgSoundId);
  					this.camera.active = true;
  					let avatarNode = director.findChild("ggx05");
  					let numChildren = avatarNode.numChildren;
  					for (let i = (numChildren - 1); i >= 0; i--) {
  						let node = avatarNode.getChildAt(i);
  						node.destroy();
  					}
  					director.removeSelf();
  					director.destroy();
  					callbackComplete && callbackComplete(clearBefore);
  				});
  			});
  		});
  	}
  	prepareForRestart() {
  		this.cleanModels();
  	}
  	getPlayerAvatar(bDisableAdapt) {
  		if (!this.bNeedReAdaptAvatar && !!this.currUsingPlayerAvatar) {
  			return this.currUsingPlayerAvatar;
  		}
  		this.bNeedReAdaptAvatar = false;
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.playerRoleId);
  		let numChildren = this.avatarPlayerContainer.numChildren;
  		let findedAvatar = null;
  		for (let i = 0; i < numChildren; i++) {
  			let avatar = this.avatarPlayerContainer.getChildAt(i);
  			if (avatar.bLoadingNakedness) {
  				continue;
  			}
  			if (avatar.roleId == roleData.roleId) {
  				findedAvatar = avatar;
  			}
  			else if (!bDisableAdapt) {
  				avatar.active = false;
  			}
  		}
  		findedAvatar = findedAvatar || this.currUsingPlayerAvatar || this.avatarPlayerContainer.getChildAt(0);
  		if (!findedAvatar.active) {
  			findedAvatar.active = true;
  		}
  		this.currUsingPlayerAvatar = findedAvatar;
  		return findedAvatar;
  	}
  	tryAddPlayerAvatar() {
  		let currRoleId = this.playerRoleId;
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(currRoleId);
  		let numChildren = this.avatarPlayerContainer.numChildren;
  		for (let i = 0; i < numChildren; i++) {
  			let avatar = this.avatarPlayerContainer.getChildAt(i);
  			if (avatar.roleId == roleData.roleId) {
  				this.bNeedReAdaptAvatar = true;
  				this.playerAvatarPlayAnimationQuote(!this.bPlayerArrived ? ROLE_QUOTE_MOV.movWalk : ROLE_QUOTE_MOV.movIdle, 0, null, null, true, false);
  				return;
  			}
  		}
  		let avatar = new NpcAvatar(roleData.roleId);
  		avatar.transform.localPosition = new Laya.Vector3(0, 0.1, 0);
  		this.avatarPlayerContainer.addChild(avatar);
  		avatar.setLocalPositionZ100();
  		avatar.registerAllLoadEndCallback(() => {
  			let oldAvatar = this.getPlayerAvatar(true);
  			avatar.setLocalPositionZ0();
  			avatar.active = false;
  			Timer.callLoop(0.016, (timer) => {
  				if (!oldAvatar.active || !oldAvatar.isPlayingQuote(ROLE_QUOTE_MOV.movUpgrade)) {
  					timer.stop();
  					timer = null;
  					this.bNeedReAdaptAvatar = true;
  					if (oldAvatar.active) {
  						this.playerAvatarPlayAnimationQuote(!this.bPlayerArrived ? ROLE_QUOTE_MOV.movWalk : ROLE_QUOTE_MOV.movIdle, 0, null, null, true, false);
  					}
  				}
  			}, this);
  		});
  	}
  	playerAvatarPlayAnimationQuote(quoteAnimationId, mixFactor = 0.1, loadEndCallback, playEndCallback, bCanRepeat = true, bIdle = true) {
  		this.getPlayerAvatar().playAnimationQuote(quoteAnimationId, mixFactor, loadEndCallback, playEndCallback, bCanRepeat, bIdle);
  	}
  	addProperty1(value, bDisableEff, comboCount, luckyCount) {
  		value = Math.ceil(value);
  		if (value == 0) {
  			return;
  		}
  		mgrSound.play(value > 0 ? 103 : 112);
  		comboCount = comboCount || 0;
  		luckyCount = luckyCount || 0;
  		this.currentProperty1 = Math.max(this.currentProperty1 + value + comboCount + luckyCount, -99);
  		this._onPropertyChangedByType(1, this.currentProperty1);
  		this._showPropertyChangeEffect(1, value, bDisableEff, comboCount, luckyCount);
  		this.refreshPlayerTitleBar();
  	}
  	addProperty2(value, bDisableEff, comboCount, luckyCount) {
  		value = Math.ceil(value);
  		if (value == 0) {
  			return;
  		}
  		mgrSound.play(value > 0 ? 103 : 112);
  		comboCount = comboCount || 0;
  		luckyCount = luckyCount || 0;
  		this.currentProperty2 = Math.max(this.currentProperty2 + value + comboCount + luckyCount, -99);
  		this._onPropertyChangedByType(2, this.currentProperty2);
  		this._showPropertyChangeEffect(2, value, bDisableEff, comboCount, luckyCount);
  		this.refreshPlayerTitleBar();
  	}
  	addProperty3(value, bDisableEff, comboCount, luckyCount) {
  		value = Math.ceil(value);
  		if (value == 0) {
  			return;
  		}
  		mgrSound.play(value > 0 ? 103 : 112);
  		comboCount = comboCount || 0;
  		luckyCount = luckyCount || 0;
  		this.currentProperty3 = Math.max(this.currentProperty3 + value + comboCount + luckyCount, -99);
  		this._onPropertyChangedByType(3, this.currentProperty3);
  		this._showPropertyChangeEffect(3, value, bDisableEff, comboCount, luckyCount);
  		this.refreshPlayerTitleBar();
  	}
  	addProperty4(value, bDisableEff, comboCount, luckyCount) {
  		value = Math.ceil(value);
  		if (value == 0) {
  			return;
  		}
  		mgrSound.play(value > 0 ? 103 : 112);
  		comboCount = comboCount || 0;
  		luckyCount = luckyCount || 0;
  		this.currentProperty4 = Math.max(this.currentProperty4 + value + comboCount + luckyCount, -99);
  		this._onPropertyChangedByType(4, this.currentProperty4);
  		this._showPropertyChangeEffect(4, value, bDisableEff, comboCount, luckyCount);
  		this.refreshPlayerTitleBar();
  	}
  	_showPropertyChangeEffect(propertyIndex, propertyValue, bDisableEff, comboCount, luckyCount) {
  		console.log("-----_showPropertyChangeEffect---------", propertyIndex, propertyValue);
  		if (!bDisableEff) {
  			let effName = propertyValue <= 0 ? "130_e_once_debuff" : "130_e_once_buff";
  			this.addPlayerAvatarEff(effName, new Laya.Vector3(0, 1.2, 0));
  		}
  		let targetNode = this["comProperty" + propertyIndex];
  		let worldPosEnd = targetNode.localToGlobal(0, 0);
  		let propertyData = db.get_amaze_cloth_crossing_role_property(propertyIndex);
  		let icon = propertyData.smallIcon;
  		let classView = null;
  		if (propertyValue > 0) {
  			classView = ViewAddExpNumber;
  		}
  		else {
  			classView = ViewSubExpNumber;
  		}
  		let showCount = this["currentProperty" + propertyIndex];
  		let expComponent = new classView({
  			icon: icon, flyTargetPos: worldPosEnd, fOnCompleted: () => {
  				if (!this.resNode || this.resNode.isDisposed) {
  					return;
  				}
  				cc$1.tween(targetNode).toScale(0.1, 1.3).toScale(0.1, 1).start();
  				this.refreshPlayerProperty(propertyIndex, showCount);
  			}
  		});
  		expComponent.create();
  		expComponent.setAmount(propertyValue, comboCount, luckyCount);
  	}
  	_onPropertyChangedByType(propertyIndex, propertyValue) {
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.playerRoleId);
  		let propertyRoleId = mgrRole.getPlayerRoleIdByProperty(this.currentProperty1, this.currentProperty2, this.currentProperty3, this.currentProperty4);
  		let propertyRoleData = db.get_amaze_cloth_crossing_property_to_logic_role(propertyRoleId);
  		if (!!propertyRoleData && propertyRoleData.id != this.playerRoleId) {
  			this._onPlayerChanged(this.playerRoleId, propertyRoleData.id, propertyRoleData.level >= roleData.level);
  		}
  	}
  	_onPlayerChanged(oldRoleId, newRoleId, bLvUp) {
  		let template = db.get_amaze_cloth_crossing_property_to_logic_role(newRoleId);
  		if (template) {
  			GameStatistics.statisCommonEvent(template.statisPointId);
  		}
  		this.playerRoleId = newRoleId;
  		mgrRole.tryAddArrivedRoleId(newRoleId);
  		if (!bLvUp) {
  			this.tryAddPlayerAvatar();
  			return;
  		}
  		this.currStageArrivedPlayerRoleIdDict[newRoleId] = true;
  		this.linkModelAtBack("130_e_once_shengji_01", this.avatarPlayerNode, null, 3);
  		mgrSound.play(104);
  		this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movUpgrade, 0, null, () => {
  			if (!this.bObsacleHiting) {
  				this.playerAvatarPlayAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  			}
  		}, false, false);
  		this.tryAddPlayerAvatar();
  	}
  	_getCurrStageArrivedRoleIdArr() {
  		let arr = [];
  		for (let k in this.currStageArrivedPlayerRoleIdDict) {
  			arr.push(parseInt(k));
  		}
  		return arr;
  	}
  	getPlayerRoleLevel() {
  		let roleId = this.playerRoleId;
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(roleId);
  		return roleData.level;
  	}
  	changeEnvironmentColor(color) {
  		if (!this.mapStage || this.mapStage.destroyed) {
  			return;
  		}
  		let renders = Tools.findAllMeshRenderers(this.mapStage, null, true);
  		if (!!renders && renders.length > 0) {
  			for (let i = 0; i < renders.length; i++) {
  				let rendrer = renders[i];
  				if (rendrer["_owner"] && (rendrer["_owner"].name.indexOf("men") >= 0 || rendrer["_owner"].name.indexOf("timu") >= 0 || rendrer["_owner"].name.indexOf("wenzi") >= 0)) {
  					continue;
  				}
  				for (let tmp in rendrer.sharedMaterials) {
  					let mat = rendrer.sharedMaterials[tmp];
  					mat.albedoColor = new Laya.Vector4(color.r, color.g, color.b, 1);
  				}
  				rendrer.sharedMaterials = rendrer.sharedMaterials;
  			}
  		}
  	}
  	changeItemEnvironmentColor(color, model) {
  		let renders = Tools.findAllMeshRenderers(model, null, true);
  		if (!!renders && renders.length > 0) {
  			for (let i = 0; i < renders.length; i++) {
  				let rendrer = renders[i];
  				if (rendrer["_owner"] && (rendrer["_owner"].name.indexOf("men") >= 0 || rendrer["_owner"].name.indexOf("timu") >= 0 || rendrer["_owner"].name.indexOf("wenzi") >= 0)) {
  					continue;
  				}
  				for (let tmp in rendrer.sharedMaterials) {
  					let mat = rendrer.sharedMaterials[tmp];
  					mat.albedoColor = new Laya.Vector4(color.r, color.g, color.b, 1);
  				}
  				rendrer.sharedMaterials = rendrer.sharedMaterials;
  			}
  		}
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName == db.ADV_DB_ADVNAME.video_PanelGoGoGo_lvup_external) {
  			if (e.params && e.params.type == 1) {
  				mgrCrossStage.addFreeLevelUpDialogCount(0);
  			}
  			this.bStatisedLvUpExVideoShow = false;
  			mgrRole.upgradeGotPropertyExtrnalLevel();
  			BaseFacade.mItem.setItem(911, 1);
  			this.addEffect(db.MODEL_DB_ID._130_ui_once_ray_01, { x: this.comLevelUp.x - 20, y: this.comLevelUp.y - 50 });
  		}
  	}
  	onMsgDebugCrossStageStart(e) {
  		this.context.stageId = e.stageId;
  		this.stManager.setNextState(this.st_cleanForRestart);
  	}
  	onMsgGenAndStartStageNow(e) {
  		this.bStartStageNowOnce = true;
  		this.context.stageId = e.stageId;
  		this.stManager.setNextState(this.st_cleanForRestart);
  	}
  	adaptBannerAdv() {
  		if (!!db.cop_db.b_adapt_go_ui_banner_when_start_go) {
  			if (!this.stManager) {
  				if (this.bFocus) {
  					this.tryCloseBannerAdv();
  				}
  				return;
  			}
  			if (this.stManager.getCurState() != this.st_avatarComing && this.stManager.getCurState() != this.st_avatarMoving) {
  				if (this.bFocus) {
  					this.tryCloseBannerAdv();
  				}
  				return;
  			}
  		}
  		super.adaptBannerAdv();
  	}
  	onFocus(bFocus) {
  		super.onFocus(bFocus);
  		if (this.bFocus) {
  			GameCross.setVisible(true);
  		}
  		else {
  			GameCross.setVisible(false);
  		}
  		if (this.stManager) {
  			let currState = this.stManager.getCurState();
  			let showStateDict = {
  				[this.st_avatarComing]: true,
  				[this.st_stageStartTip]: true,
  				[this.st_avatarMoving]: true,
  			};
  			for (let i = 1; i <= 4; i++) {
  				let comProperty = this["comProperty" + i];
  				if (!comProperty || comProperty.isDisposed) {
  					continue;
  				}
  				comProperty.alpha = bFocus && !!showStateDict[currState] ? 1 : 0;
  			}
  		}
  		!!this.comProgressBarStage && !this.comProgressBarStage.isDisposed && (this.comProgressBarStage.alpha = !!bFocus ? 1 : 0);
  		!!this.comStartGuide && !this.comStartGuide.isDisposed && (this.comStartGuide.alpha = !!bFocus ? 1 : 0);
  	}
  	onMsgPetFollowingChanged(e) {
  		this.tryAddPet();
  	}
  	onMsgPetOutputCoin(e) {
  		if (!e.output) {
  			return;
  		}
  		if (!this.petFollower || this.petFollower.destroyed || (this.stManager && this.stManager.getCurState() >= this.st_avatarComing)) {
  			return;
  		}
  		this.comPetOutput.visible = true;
  		let petData = db.get_ggg_pet_template_db(mgrPet.followingPetId, 1);
  		let apeendHeight = petData.bodyHeight * (petData.scale || 1);
  		let outResult = Tools.tranlateWorld3D2Screen(this.camera, new Laya.Vector3(this.petFollower.transform.position.x, this.petFollower.transform.position.y + apeendHeight, this.petFollower.transform.position.z));
  		let nodePos = this.comPetOutput.parent.globalToLocal(outResult.outPos.x, outResult.outPos.y);
  		this.comPetOutput.setXY(this.comPetOutput.parent.width * this.comPetOutput.parent.pivotX + nodePos.x, this.comPetOutput.parent.height * this.comPetOutput.parent.pivotY + nodePos.y);
  		this.comPetOutput.setScale(1, 1);
  		let useAmount = e.output || 0;
  		this.comPetOutput.getChild("title2").text = `${useAmount >= 0 ? "+" : "-"}${Math.abs(useAmount)}`;
  		cc$1.tween(this.comPetOutput)
  			.parallel(cc$1.tween().byPos(1, 0, -100), cc$1.tween().toScale(0.6, 1.2).toScale(0.2, 0))
  			.start();
  	}
  	showVideoRecord(callback) {
  		// console.info("zhehsijiangli");
  		// callback && callback();
  		if (mgrChannel.canUseVideoRecord()) {
  			mgrSdk.stopRecordVideo();
  			Tools.takeAPhoto(340 * 2, 340 * 2, this.camera, (tex2d) => {
  				mgrSdk.showVideoRecordDialog(tex2d, 1, () => {
  					mgrTip.waitGotItemClear(this, () => {
  						callback && callback();
  					});
  				});
  			});
  			return;
  		}
  		callback && callback();
  	}
  	playPetAni(index, petId) {
  	}
  	on_click_buttonBack() {
  	}
  	on_click_buttonDesktop() {
  		mgrSdk.installShortcut();
  	}
  	on_click_buttonFindMe() {
  		if (mgrSdk.h5_channel == "baidu") {
  			Director.openPanel(`PanelFindMeBaidu`);
  		}
  		else if (mgrSdk.h5_channel == "douyin") {
  			Director.openPanel(`PanelFindMeDouyin`);
  		}
  		else if (mgrSdk.h5_channel == "toutiao") {
  			Director.openPanel(`PanelFindMeToutiao`);
  		}
  		else if (mgrSdk.h5_channel == "weixin") {
  			Director.openPanel(`PanelFindMeWeixin`);
  		}
  		else if (mgrSdk.h5_channel == "ulsdkdemo") {
  			Director.openPanel(`PanelFindMeToutiao`);
  			Director.openPanel(`PanelFindMeDouyin`);
  			Director.openPanel(`PanelFindMeBaidu`);
  			Director.openPanel(`PanelFindMeWeixin`);
  		}
  	}
  	on_click_buttonMoreGame() {
  		if (!window[`conch`]) {
  			Director.openPanel(`PanelMoreGameDialog`);
  		}
  		else {
  			mgrSdk.openUlMoreGame();
  		}
  	}
  	on_click_buttonRewardJump() {
  		Director.openPanel(`PanelTryGame`);
  	}
  	on_click_buttonSupperEasy() {
  		mgrSdk.openMoreWonderful();
  	}
  	on_click_buttonChangeProperty() {
  	}
  	on_click_buttonExperience() {
  		Director.openPanel(`PanelExperience`);
  	}
  	on_click_buttonAttendant() {
  		Director.openPanel(`PanelAttendant`);
  	}
  	on_click_buttonIllu() {
  		Director.openPanel(`PanelIllu`);
  	}
  	on_click_buttonPropertyExternal() {
  		mgrCrossStage.addFreeLevelUpDialogCount(0);
  		this.bStatisedLvUpExVideoShow = false;
  		mgrRole.upgradeGotPropertyExtrnalLevel();
  		BaseFacade.mItem.setItem(911, 1);
  		this.addEffect(db.MODEL_DB_ID._130_ui_once_ray_01, { x: this.comLevelUp.x - 20, y: this.comLevelUp.y - 50 });
  		// console.info("5555555555555555555555555555555555555");
  		mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelGoGoGo_lvup_external, { bGoUi: true }, true);
  	}
  	on_click_buttonPetUpgrade01() {
  		let petId = mgrPet.getGotPetIdArr()[0];
  		let currLevel = mgrPet.getGotPetIdLevel(petId);
  		let petTemplate = db.get_ggg_pet_template_db(petId, currLevel);
  		let result = mgrPet.upgradeLevel(petId);
  		mgrTip.showMsgTip(result.tipStr);
  	}
  	on_click_buttonPetUpgrade02() {
  		let petId = mgrPet.getGotPetIdArr()[1];
  		let currLevel = mgrPet.getGotPetIdLevel(petId);
  		let petTemplate = db.get_ggg_pet_template_db(petId, currLevel);
  		let result = mgrPet.upgradeLevel(petId);
  		mgrTip.showMsgTip(result.tipStr);
  	}
  	on_click_buttonPet() {
  		Director.openPanel("PanelPet");
  	}
  	on_click_buttonking() {
  		// console.info("tttttttttttttttttttttttttttttttttttttttttttttttttttt");
  		// mgrChallenge.markChallengeTypeUnlocked(StageType.speedStage);
  		// PanelSpecialStagePreview2.adaptUnlockedUi();
  		Director.openPanel("PanelSpecialStagePreview2");
  	}
  	on_click_buttonkingmother() {
  		// console.info("tttttttttttttttttttttttttttttttttttttttttttttttttttt");
  		// mgrChallenge.markChallengeTypeUnlocked(StageType.goldStage);
  		// PanelSpecialStagePreview1.adaptUnlockedUi();
  		Director.openPanel("PanelSpecialStagePreview1");
  	}
  	on_click_buttonCoinUpgrade() {
  		if (!mgrCrossStage.tryShowFreeLevelUpDialog(db.ADV_DB_ADVNAME.video_PanelGoGoGo_lvup_external, 0)) {
  			let costItemId = mgrRole.getNextLevelGotPropertyExtrnalUpgradeCostItemId();
  			let costAmount = mgrRole.getNextLevelGotPropertyExtrnalUpgradeCostItemAmount();
  			if (BaseFacade.mItem.isEnoughItem(costItemId, costAmount)) {
  				BaseFacade.mItem.subItem(costItemId, costAmount, "升级获得属性");
  				mgrRole.upgradeGotPropertyExtrnalLevel();
  				this.addEffect(db.MODEL_DB_ID._130_ui_once_ray_01, { x: this.comLevelUp.x - 20, y: this.comLevelUp.y - 50 });
  			}
  			else {
  				let templateCost = db.get_item_db(costItemId);
  				mgrTip.showMsgTip(`${templateCost.name}不足`);
  			}
  		}
  	}
  	on_click_buttonSetting() {
  		Director.openPanel("PanelSetting");
  	}
  	on_click_button_position_up() {
  		let wordPos = UITools.getSelfGlobalPos(this.button_position_up.guiNode);
  		Director.openPanel(mgrCrossStage.getCurrStageId() == 1 ? "PanelPositionUpFirstYearPreview" : "PanelPositionUpPreview", {
  			type: 1, roleId: this.playerRoleId, endPos: wordPos,
  			propertys: [this.currentProperty1, this.currentProperty2, this.currentProperty3, this.currentProperty4]
  		});
  	}
  	on_click_buttonZQ() {
  		mgrSdk.openAdvancedSetting();
  	}
  	on_click_buttonYard() {
  		if (mgrYard.isYardUnlocked()) {
  			PanelWarpWithAnim.warp("PanelYard");
  			return;
  		}
  		console.info("rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr");
  		// mgrYard.unlockYard();
  		Director.openPanel("PanelYardPreview");
  	}
  	on_click_buttonZQqq() {
  		mgrSdk.openAdvancedSetting();
  	}
  }
  PanelGoGoGo.sourceName = "ui://gogogo/PanelGoGoGo";

  class PanelPositionUpFirstYearPreview extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "第一年官职进阶预览界面";
  		this.bOpenAndCloseAnim = true;
  		this.currentProperty1 = 0;
  		this.currentProperty2 = 0;
  		this.currentProperty3 = 0;
  		this.currentProperty4 = 0;
  	}
  	onLoaded() {
  		mgrSound.play(107);
  		this.ctrlPositionState = this.comLines.getController("c2");
  		this.type = this.comBtnPreview.getController("type");
  		this.gameType = this.resNode.getController("type");
  		if (this.context && this.context.type == 1) {
  			this.type.setSelectedIndex(1);
  		}
  		else {
  			this.type.setSelectedIndex(0);
  		}
  		this.gameType.setSelectedIndex(1);
  		this.fillPositionData();
  		mgrTip.showBadgeWithNumber(this.buttonStart.displayObject, 1, new Laya.Point(5, 5));
  		this.currentProperty1 = this.context && this.context.propertys ? this.context.propertys[0] : mgrRole.getProperty1();
  		this.currentProperty2 = this.context && this.context.propertys ? this.context.propertys[1] : mgrRole.getProperty2();
  		this.currentProperty3 = this.context && this.context.propertys ? this.context.propertys[2] : mgrRole.getProperty3();
  		this.currentProperty4 = this.context && this.context.propertys ? this.context.propertys[3] : mgrRole.getProperty4();
  		this.refreshPlayerProperty();
  	}
  	dispose() {
  		super.dispose();
  	}
  	_getMaxPropertyValueIndex() {
  		let propertyInfoArr = mgrRole.getSortedPropertyIndexArr(this.currentProperty1, this.currentProperty2, this.currentProperty3, this.currentProperty4);
  		return propertyInfoArr[0].propertyIndex;
  	}
  	refreshPlayerProperty(forcePropertyIndex, count) {
  		let maxPropertyIndex = this._getMaxPropertyValueIndex();
  		let refreshOnePorperty = (pIndex, value) => {
  			let com = this["comProperty" + pIndex];
  			let point = com.getChild("point");
  			point.text = `${value}`;
  		};
  		let refreshMaxStatus = () => {
  			for (let i = 1; i <= 4; i++) {
  				let pIndex = i;
  				let com = this["comProperty" + pIndex];
  				let point = com.getChild("point");
  				if (pIndex == maxPropertyIndex) {
  					com.getChild("maxBg").visible = true;
  					com.getChild("maxCountBg").visible = true;
  					point.color = "#FFF17E";
  				}
  				else {
  					com.getChild("maxBg").visible = false;
  					com.getChild("maxCountBg").visible = false;
  					point.color = "#FFFFFF";
  				}
  			}
  		};
  		if (!!forcePropertyIndex) {
  			refreshOnePorperty(forcePropertyIndex, count);
  			refreshMaxStatus();
  			return;
  		}
  		for (let i = 1; i <= 4; i++) {
  			let value = this["currentProperty" + i];
  			refreshOnePorperty(i, value);
  		}
  		refreshMaxStatus();
  	}
  	fillPositionData() {
  		let yearStr = "第1年";
  		let stageData = db.get_amaze_cloth_crossing_stage_db(mgrCrossStage.getCurrStageId());
  		if (stageData) {
  			yearStr = `第${mgrCrossStage.getCurrStageId()}年`;
  		}
  		this.textYears.text = yearStr;
  		let roleId = mgrRole.getCurrentPropertyRoleId(true);
  		if (this.context && this.context.type == 1) {
  			roleId = this.context.roleId;
  		}
  		console.log("当前官职", roleId);
  		this.showingRoleId = roleId;
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(roleId);
  		let comBasePosition = this.comPosition.getChild("basePosition");
  		let baseSpriteSel = comBasePosition.getChild("spriteSelected");
  		baseSpriteSel.visible = false;
  		let baseLoaderPositionIcon = comBasePosition.getChild("loaderPositionIcon");
  		baseLoaderPositionIcon.url = roleData.headIcon;
  		let baseTextName = comBasePosition.getChild("textName");
  		comBasePosition.getChild("tip").visible = false;
  		baseTextName.text = roleData.name;
  		let baseLoaderPositionIconBg = comBasePosition.getChild("loaderPositionIconBg");
  		baseLoaderPositionIconBg.visible = false;
  		comBasePosition.getChild("imageEndFlagNormal").visible = (roleData.maxLevelResultTimeline && roleData.maxLevelResultTimeline != "") ? true : false;
  		let loaderPositionBase = comBasePosition.getChild("loaderPositionGrade");
  		loaderPositionBase.url = roleData.positionGradeIcon;
  		if (roleData.positionGradeIcon && roleData.positionGradeIcon != "") {
  			loaderPositionBase.visible = true;
  			loaderPositionBase.url = roleData.positionGradeIcon;
  		}
  		else {
  			loaderPositionBase.visible = false;
  		}
  		let propertyInfoArr = mgrRole.getSortedPropertyIndexArr(roleData.property_1, roleData.property_2, roleData.property_3, roleData.property_4);
  		let rolePropertyId = propertyInfoArr[0].propertyIndex;
  		let propertyGroup = comBasePosition.getChild("groupProperty1");
  		propertyGroup.visible = !!rolePropertyId;
  		if (propertyGroup.visible) {
  			let propertyIcon = comBasePosition.getChild("loaderIcon1");
  			let propertyText = comBasePosition.getChild("textAmount1");
  			let propertyData = db.get_amaze_cloth_crossing_role_property(rolePropertyId);
  			propertyIcon.url = propertyData.smallIcon;
  			propertyText.text = `${Math.max(1, roleData["property_" + rolePropertyId] || 0)}`;
  		}
  		let comAdvancePositionArr = [];
  		let count = 0;
  		for (let i = 0; i < 4; i++) {
  			let comAdvancePosition = this.comPosition.getChild("advancePosition" + (i + 1));
  			let roleIdNext = roleData.nextPossibleRoleIdArr[i];
  			if (!roleIdNext) {
  				comAdvancePosition.visible = false;
  				continue;
  			}
  			let roleDataNext = db.get_amaze_cloth_crossing_property_to_logic_role(roleIdNext);
  			if (!roleDataNext) {
  				comAdvancePosition.visible = false;
  				continue;
  			}
  			comAdvancePosition.scaleX = 0;
  			comAdvancePositionArr.push(comAdvancePosition);
  			count++;
  			let advanceSpriteSel = comAdvancePosition.getChild("spriteSelected");
  			advanceSpriteSel.visible = false;
  			let advanceLoaderPositionIcon = comAdvancePosition.getChild("loaderPositionIcon");
  			advanceLoaderPositionIcon.url = roleDataNext.headIcon;
  			advanceLoaderPositionIcon.color = mgrRole.isArrivedRoleId(roleDataNext.id) ? "#FFFFFF" : "#000000";
  			advanceLoaderPositionIcon.alpha = mgrRole.isArrivedRoleId(roleDataNext.id) ? 1 : 0.3;
  			let advanceTextName = comAdvancePosition.getChild("textName");
  			let loaderPositionBg = comAdvancePosition.getChild("loaderPositionBg");
  			let loaderPositionIconBg = comAdvancePosition.getChild("loaderPositionIconBg");
  			loaderPositionIconBg.visible = false;
  			if (mgrRole.isArrivedRoleId(roleDataNext.id)) {
  				advanceTextName.text = roleDataNext.name;
  				comAdvancePosition.getChild("tip").visible = false;
  			}
  			else {
  				advanceTextName.text = "";
  				comAdvancePosition.getChild("tip").visible = true;
  			}
  			loaderPositionBg.url = mgrRole.isArrivedRoleId(roleDataNext.id) ? "res/ui/common/sprite_dik1.png" : "res/ui/common/sprite_dik1unlock.png";
  			loaderPositionIconBg.url = mgrRole.isArrivedRoleId(roleDataNext.id) ? "res/ui/common/image_head0.png" : "res/ui/common/image_head0unlock.png";
  			advanceTextName.strokeColor = mgrRole.isArrivedRoleId(roleDataNext.id) ? "#DC6237" : "#7AA190";
  			comAdvancePosition.getChild("imageEndFlagNormal").visible = (roleDataNext.maxLevelResultTimeline && roleDataNext.maxLevelResultTimeline != "") ? true : false;
  			let loaderPositionGradeAdvance = comAdvancePosition.getChild("loaderPositionGrade");
  			if (roleDataNext.positionGradeIcon && roleDataNext.positionGradeIcon != "") {
  				loaderPositionGradeAdvance.visible = true;
  				loaderPositionGradeAdvance.url = roleDataNext.positionGradeIcon;
  			}
  			else {
  				loaderPositionGradeAdvance.visible = false;
  			}
  			let loaderLineIcon = comAdvancePosition.getChild("loaderLineIcon");
  			let propertyData = db.get_amaze_cloth_crossing_role_property(roleDataNext.grownupLine);
  			loaderLineIcon.visible = !!propertyData;
  			if (!!propertyData) {
  				loaderLineIcon.url = propertyData.grownupLineIcon;
  			}
  			let propertyInfoArr = mgrRole.getSortedPropertyIndexArr(roleDataNext.property_1, roleDataNext.property_2, roleDataNext.property_3, roleDataNext.property_4);
  			let rolePropertyId = propertyInfoArr[0].propertyIndex;
  			let propertyGroup = comAdvancePosition.getChild("groupProperty1");
  			propertyGroup.visible = !!rolePropertyId;
  			if (propertyGroup.visible) {
  				let propertyIcon = comAdvancePosition.getChild("loaderIcon1");
  				let propertyText = comAdvancePosition.getChild("textAmount1");
  				propertyText.strokeColor = mgrRole.isArrivedRoleId(roleDataNext.id) ? "#DC6237" : "#7AA190";
  				let propertyData = db.get_amaze_cloth_crossing_role_property(rolePropertyId);
  				propertyIcon.url = propertyData.smallIcon;
  				propertyText.text = `${roleDataNext["property_" + rolePropertyId] || 0}`;
  			}
  		}
  		comBasePosition.scaleX = 0;
  		Timer.callLater(0.2, () => {
  			cc$1.tween(comBasePosition).toScale(0.3, 0.95).call(() => {
  				this.playTranslation(this.comLines, "line" + (count - 1), new Laya.Handler(this, () => {
  					for (let i = 0; i < comAdvancePositionArr.length; i++) {
  						const comAdvancePosition = comAdvancePositionArr[i];
  						cc$1.tween(comAdvancePosition).toScale(0.3, 0.9).start();
  					}
  				}));
  				this.ctrlPositionState.setSelectedIndex(count - 1);
  			}).start();
  		}, this);
  	}
  	closeDialogAnimation() {
  		if (!this.context || !this.context.endPos) {
  			this.context.endPos = mgrCrossStage.endPositionWordPos;
  		}
  		if (!this.context.endPos) {
  			this.close();
  			return;
  		}
  		let selfWord = UITools.getSelfGlobalPos(this.resNode);
  		let endWord = this.context.endPos;
  		let offx = selfWord.x - endWord.x;
  		let offy = selfWord.y - endWord.y;
  		let endPosX = this.resNode.x - offx;
  		let endPosY = this.resNode.y - offy;
  		cc$1.tween(this.resNode).to(0.3, { scaleX: 0.05, scaleY: 0.05, x: endPosX, y: endPosY })
  			.call(() => {
  				this.close();
  			}).start();
  	}
  	on_click_buttonStart() {
  		if (!mgrRole.isArrivedRoleId(this.showingRoleId)) {
  			let template = db.get_amaze_cloth_crossing_property_to_logic_role(this.showingRoleId);
  			if (template) {
  				GameStatistics.statisCommonEvent(template.statisPointId);
  			}
  		}
  		mgrRole.tryAddArrivedRoleId(this.showingRoleId);
  		this.context.fOnChoosed && this.context.fOnChoosed(this.context.bResetStage);
  		this.closeDialogAnimation();
  	}
  	on_click_textYears() {
  	}
  	on_click_buttonSure() {
  		this.closeDialogAnimation();
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  }
  PanelPositionUpFirstYearPreview.sourceName = "ui://gogogo/PanelPositionUpFirstYearPreview";

  class PanelPositionUpPreview extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "当前官职进阶预览界面";
  		this.bOpenAndCloseAnim = true;
  		this.currentProperty = 0;
  	}
  	onLoaded() {
  		mgrSound.play(107);
  		this.typeController = this.comPa.getController("c1");
  		let deltaY = (Global.canvasHeight - 1024) / 2;
  		if (db.cop_db.ui_bottom_mode_switch[1]) {
  			mgrUiBottom.curInBottomViewName = "PanelPositionUpPreview";
  			this.adaptBannerAdv();
  			this.comPa.y = 790 + deltaY;
  			if (mgrUiBottom.checkIfUiBottomRecovery(1)) {
  				let delayTime = db.cop_db.ui_bottom_delay_time[1];
  				Timer.callLater(delayTime, () => {
  					mgrUiBottom.recordUiRecoveryTime();
  					mgrUiBottom.curInBottomViewName = "";
  					this.comPa.y = 587;
  					this.adaptBannerAdv();
  				}, this);
  			}
  		}
  		if (this.context && this.context.type == 1) {
  			this.typeController.setSelectedIndex(1);
  		}
  		else {
  			this.typeController.setSelectedIndex(0);
  		}
  		this.fillPositionData();
  		mgrTip.showBadgeWithNumber(this.buttonStart.displayObject, 1, new Laya.Point(5, 5));
  		this.currentProperty = this.context && this.context.propertyValue ? this.context.propertyValue : mgrRole.getPropertyValueByGrownunLine(mgrRole.getUsingGrownupLine());
  		this.refreshPlayerProperty();
  	}
  	dispose() {
  		mgrUiBottom.curInBottomViewName = "";
  		super.dispose();
  	}
  	refreshPlayerProperty() {
  		let refreshOnePorperty = (value) => {
  			let com = this.comPropertyCurrent;
  			let point = com.getChild("point");
  			point.text = `${value}`;
  		};
  		let refreshMaxStatus = () => {
  			let com = this.comPropertyCurrent;
  			let point = com.getChild("point");
  			com.getChild("maxBg").visible = false;
  			com.getChild("maxCountBg").visible = false;
  			point.color = "#FFFFFF";
  		};
  		refreshOnePorperty(this.currentProperty);
  		refreshMaxStatus();
  	}
  	fillPositionData() {
  		let yearStr = `第${mgrCrossStage.getCurrStageId() || 1}年`;
  		this.textYears.text = yearStr;
  		let roleId = mgrRole.getCurrentPropertyRoleId(true);
  		if (this.context && this.context.type == 1) {
  			roleId = this.context.roleId;
  		}
  		console.log("当前官职", roleId);
  		this.showingRoleId = roleId;
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(roleId);
  		for (let i = 1; i <= 4; i++) {
  			this["imageLineFlag" + i].visible = (i == mgrRole.getUsingGrownupLine() ? true : false);
  		}
  		let propertyData = db.get_amaze_cloth_crossing_role_property(mgrRole.getUsingGrownupLine());
  		let loaderPropertyIcon = this.comPropertyCurrent.getChild("loaderPropertyIcon");
  		loaderPropertyIcon.url = propertyData.bigIcon;
  		let comBasePosition = this.currentComPosition;
  		let baseSpriteSel = comBasePosition.getChild("spriteSelected");
  		baseSpriteSel.visible = false;
  		let baseLoaderPositionIcon = comBasePosition.getChild("loaderPositionIcon");
  		baseLoaderPositionIcon.url = roleData.headIcon;
  		let baseTextName = comBasePosition.getChild("textName");
  		comBasePosition.getChild("tip").visible = false;
  		baseTextName.text = roleData.name;
  		comBasePosition.getChild("imageEndFlagNormal").visible = (roleData.maxLevelResultTimeline && roleData.maxLevelResultTimeline != "") ? true : false;
  		let loaderLineIcon = comBasePosition.getChild("loaderLineIcon");
  		loaderLineIcon.visible = true;
  		loaderLineIcon.url = propertyData.grownupLineIcon;
  		let loaderPositionGrade = comBasePosition.getChild("loaderPositionGrade");
  		if (roleData.positionGradeIcon) {
  			loaderPositionGrade.url = roleData.positionGradeIcon;
  		}
  		else {
  			loaderPositionGrade.visible = false;
  		}
  		let rolePropertyId = mgrRole.getUsingGrownupLine();
  		let propertyGroup = comBasePosition.getChild("groupProperty1");
  		propertyGroup.visible = !!rolePropertyId;
  		if (propertyGroup.visible) {
  			let propertyIcon = comBasePosition.getChild("loaderIcon1");
  			let propertyText = comBasePosition.getChild("textAmount1");
  			let propertyData = db.get_amaze_cloth_crossing_role_property(rolePropertyId);
  			propertyIcon.url = propertyData.smallIcon;
  			propertyText.text = `${Math.max(1, roleData["property_" + rolePropertyId] || 0)}`;
  		}
  		let comAdvancePosition = this.nextComPosition;
  		let roleIdNext = 0;
  		if (!roleData.grownupLine) {
  			roleIdNext = mgrRole.getMinLevelRoleIdByGrownline(mgrRole.getUsingGrownupLine());
  		}
  		else {
  			roleIdNext = roleData.nextPossibleRoleIdArr[0];
  		}
  		if (!roleIdNext) {
  			comAdvancePosition.visible = false;
  			this.imageTopFlag.visible = true;
  			this.imageNextArrow.visible = false;
  			return;
  		}
  		let roleDataNext = db.get_amaze_cloth_crossing_property_to_logic_role(roleIdNext);
  		if (!roleDataNext) {
  			comAdvancePosition.visible = false;
  			return;
  		}
  		let advanceSpriteSel = comAdvancePosition.getChild("spriteSelected");
  		advanceSpriteSel.visible = false;
  		let advanceLoaderPositionIcon = comAdvancePosition.getChild("loaderPositionIcon");
  		advanceLoaderPositionIcon.url = roleDataNext.headIcon;
  		advanceLoaderPositionIcon.color = mgrRole.isArrivedRoleId(roleDataNext.id) ? "#FFFFFF" : "#000000";
  		advanceLoaderPositionIcon.alpha = mgrRole.isArrivedRoleId(roleDataNext.id) ? 1 : 0.3;
  		let advanceTextName = comAdvancePosition.getChild("textName");
  		let loaderPositionBg = comAdvancePosition.getChild("loaderPositionBg");
  		if (mgrRole.isArrivedRoleId(roleDataNext.id)) {
  			advanceTextName.text = roleDataNext.name;
  			comAdvancePosition.getChild("tip").visible = false;
  		}
  		else {
  			advanceTextName.text = "";
  			comAdvancePosition.getChild("tip").visible = true;
  		}
  		loaderPositionBg.url = mgrRole.isArrivedRoleId(roleDataNext.id) ? "res/ui/common/sprite_dik1.png" : "res/ui/common/sprite_dik1unlock.png";
  		advanceTextName.strokeColor = mgrRole.isArrivedRoleId(roleDataNext.id) ? "#DC6237" : "#7AA190";
  		comAdvancePosition.getChild("imageEndFlagNormal").visible = (roleDataNext.maxLevelResultTimeline && roleDataNext.maxLevelResultTimeline != "") ? true : false;
  		let loaderLineIconAdvance = comAdvancePosition.getChild("loaderLineIcon");
  		loaderLineIconAdvance.visible = true;
  		loaderLineIconAdvance.url = propertyData.grownupLineIcon;
  		let loaderPositionGradeAdvance = comAdvancePosition.getChild("loaderPositionGrade");
  		loaderPositionGradeAdvance.url = roleDataNext.positionGradeIcon;
  		let rolePropertyIdNext = mgrRole.getUsingGrownupLine();
  		let propertyGroupNext = comAdvancePosition.getChild("groupProperty1");
  		propertyGroupNext.visible = !!rolePropertyIdNext;
  		if (propertyGroupNext.visible) {
  			let propertyIcon = comAdvancePosition.getChild("loaderIcon1");
  			let propertyText = comAdvancePosition.getChild("textAmount1");
  			propertyText.strokeColor = mgrRole.isArrivedRoleId(roleDataNext.id) ? "#DC6237" : "#7AA190";
  			let propertyData = db.get_amaze_cloth_crossing_role_property(rolePropertyIdNext);
  			propertyIcon.url = propertyData.smallIcon;
  			propertyText.text = `${Math.max(1, roleDataNext["property_" + rolePropertyIdNext] || 0)}`;
  		}
  	}
  	closeDialogAnimation() {
  		if (!this.context || !this.context.endPos) {
  			this.context.endPos = mgrCrossStage.endPositionWordPos;
  		}
  		if (!this.context.endPos) {
  			this.close();
  			return;
  		}
  		let selfWord = UITools.getSelfGlobalPos(this.resNode);
  		let endWord = this.context.endPos;
  		let offx = selfWord.x - endWord.x;
  		let offy = selfWord.y - endWord.y;
  		let endPosX = this.resNode.x - offx;
  		let endPosY = this.resNode.y - offy;
  		cc$1.tween(this.resNode).to(0.3, { scaleX: 0.05, scaleY: 0.05, x: endPosX, y: endPosY })
  			.call(() => {
  				this.close();
  			}).start();
  	}
  	on_click_buttonRestart() {
  		Director.openPanel("PanelRestartDialog", {
  			fOnSure: () => {
  				GameStatistics.statisCommonEvent(70001, `${mgrRole.bornCount}_${mgrCrossStage.getCurrStageId() || 0}_${mgrRole.getUsingPlayerRoleId()}`);
  				Director.openPanel(`PanelCrossLine`, { fOnChoosed: this.context.fOnChoosed });
  				this.closeDialogAnimation();
  			}
  		});
  	}
  	on_click_buttonStart() {
  		if (!mgrRole.isArrivedRoleId(this.showingRoleId)) {
  			let template = db.get_amaze_cloth_crossing_property_to_logic_role(this.showingRoleId);
  			if (template) {
  				GameStatistics.statisCommonEvent(template.statisPointId);
  			}
  		}
  		mgrRole.tryAddArrivedRoleId(this.showingRoleId);
  		this.context.fOnChoosed && this.context.fOnChoosed(this.context.bResetStage);
  		this.closeDialogAnimation();
  	}
  	on_click_textYears() {
  	}
  	on_click_buttonSure() {
  		this.closeDialogAnimation();
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  }
  PanelPositionUpPreview.sourceName = "ui://gogogo/PanelPositionUpPreview";

  class PanelQuestionEvent extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "特殊事件问题界面";
  		this.panelMaskAlpha = 0.3;
  	}
  	onLoaded() {
  		let deltaY = (Global.canvasHeight - 1024) / 2;
  		if (db.cop_db.ui_bottom_mode_switch[5]) {
  			mgrUiBottom.curInBottomViewName = "PanelQuestionEvent";
  			this.adaptBannerAdv();
  			let originY = this.resNode.y;
  			this.resNode.y = originY + 220 + deltaY;
  			if (mgrUiBottom.checkIfUiBottomRecovery(5)) {
  				let delayTime = db.cop_db.ui_bottom_delay_time[5];
  				Timer.callLater(delayTime, () => {
  					mgrUiBottom.recordUiRecoveryTime();
  					mgrUiBottom.curInBottomViewName = "";
  					this.resNode.y = originY;
  					this.adaptBannerAdv();
  				}, this);
  			}
  		}
  		this.ctrlState = this.resNode.getController("c1");
  		if (this.context.bHighBgMode) {
  			this.ctrlState.setSelectedIndex(1);
  		}
  		let context = this.context;
  		let desc = context.desc || "None";
  		this.labelDesc.text = desc;
  		this.labelDescHigh.text = this.labelDesc.text;
  		if (!this.context.bTrialQuestion && !this.context.adEventId && Tools.random(100) > 50) {
  			let tmpConfirmText = context.confirmText;
  			let tmpConfirmFunc = this.context["confirm"];
  			context.confirmText = context.cancelText;
  			this.context["confirm"] = this.context["cancel"];
  			context.cancelText = tmpConfirmText;
  			this.context["cancel"] = tmpConfirmFunc;
  		}
  		if (context.confirmText) {
  			this.buttonSure.title = context.confirmText;
  		}
  		if (context.cancelText) {
  			this.buttonCancle.title = context.cancelText;
  		}
  		if (!context.cancelText) {
  			this.buttonCancle.visible = false;
  		}
  		if (!context.bShowClose) {
  			this.buttonClose.visible = false;
  		}
  		if (!this.context.adEventId) {
  			this.buttonSure.getChild("loaderAdTag").visible = false;
  		}
  		if (this.context.bTrialQuestion) {
  			let template = db.get_item_db(2);
  			this.buttonCancle.getChild("icon").url = template.icon;
  			this.buttonSure.getChild("groupCoin").visible = false;
  			this.buttonSure.visible = !!this.context.adEventId;
  			this.buttonCancle.getChild("amount").text = `${this.context.cancelAmount || 0}`;
  		}
  		else {
  			this.buttonSure.getChild("icon").url = PROPERTY_2_TARGET_ICON_DICT[this.context.surePropertyIndex];
  			this.buttonCancle.getChild("icon").url = PROPERTY_2_TARGET_ICON_DICT[this.context.cancelPropertyIndex];
  			this.buttonSure.getChild("amount").text = `+${this.context.sureAmount}`;
  			this.buttonCancle.getChild("amount").text = `+${this.context.cancelAmount || 0}`;
  			if (!this.context.adEventId) {
  				this.buttonCancle.getChild("groupCoin").visible = false;
  				this.buttonSure.getChild("groupCoin").visible = false;
  			}
  		}
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  	}
  	dispose() {
  		mgrUiBottom.curInBottomViewName = "";
  		super.dispose();
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName != this.context.adEventId)
  			return;
  		this.close();
  		if (this.context["confirm"]) {
  			this.context["confirm"]();
  		}
  	}
  	on_click_buttonClose() {
  		this.close();
  		if (this.context["refuse"]) {
  			this.context["refuse"]();
  		}
  	}
  	on_click_buttonCancle() {
  		this.close();
  		if (this.context["cancel"]) {
  			this.context["cancel"]();
  		}
  	}
  	on_click_buttonSure() {
  		if (!this.context.adEventId) {
  			this.close();
  			if (this.context["confirm"]) {
  				this.context["confirm"]();
  			}
  			return;
  		}
  		console.info("5555555555555555555555555555555555555");
  		mgrAdv.dispatchAdv(this.context.adEventId, undefined, true);
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  	on_click_labelDesc() {
  	}
  }
  PanelQuestionEvent.sourceName = "ui://gogogo/PanelQuestionEvent";

  class PanelResultQuestionEvent extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "结算成功事件问题界面";
  		this.panelMaskAlpha = 0.0;
  	}
  	onLoaded() {
  		console.info("7777777777777777777777777777777777777777777777777777777777777777777");
  		this.ctrlState = this.resNode.getController("c1");
  		if (this.context.bHighBgMode) {
  			this.ctrlState.setSelectedIndex(1);
  		}
  		let context = this.context;
  		let desc = context.desc || "None";
  		this.labelDesc.text = desc;
  		this.labelDescHigh.text = this.labelDesc.text;
  		if (Tools.random(100) > 50) {
  			let tmpConfirmText = context.confirmText;
  			let tmpConfirmFunc = this.context["confirm"];
  			context.confirmText = context.cancelText;
  			this.context["confirm"] = this.context["cancel"];
  			context.cancelText = tmpConfirmText;
  			this.context["cancel"] = tmpConfirmFunc;
  		}
  		if (context.confirmText) {
  			this.buttonSure.title = context.confirmText;
  		}
  		if (context.cancelText) {
  			this.buttonCancle.title = context.cancelText;
  		}
  		if (!context.cancelText) {
  			this.buttonCancle.visible = false;
  		}
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_buttonClose() {
  	}
  	on_click_buttonCancle() {
  		this.close();
  		if (this.context["cancel"]) {
  			this.context["cancel"]();
  		}
  	}
  	on_click_buttonSure() {
  		this.close();
  		if (this.context["confirm"]) {
  			this.context["confirm"]();
  		}
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  	on_click_labelDesc() {
  	}
  }
  PanelResultQuestionEvent.sourceName = "ui://gogogo/PanelResultQuestionEvent";

  class PanelStageStartTip extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "关卡开始提示介绍";
  	}
  	onLoaded() {
  		this.labelDesc.text = this.context.desc;
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  	on_click_buttonConfirm() {
  		this.close();
  	}
  }
  PanelStageStartTip.sourceName = "ui://gogogo/PanelStageStartTip";

  class PanelStartBorn extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "出生选择界面";
  	}
  	onLoaded() {
  		mgrSound.play(111);
  		this.playTranslation(this.resNode, "in");
  		let bTriggerAd = mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelStartBorn_born);
  		this.bTriggerAd = bTriggerAd;
  		if (mgrRole.isMaxGotPropertyExtrnalLevel()) {
  		}
  		if (bTriggerAd && this.buttonBornType03.visible) {
  			mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelStartBorn_born);
  		}
  		let nodes = Tools.findAllNodeReg("loaderAdTag", this.resNode);
  		for (let i = 0; i < nodes.length; i++) {
  			const node = nodes[i];
  			node.visible = (!!node.visible && !!bTriggerAd) ? true : false;
  		}
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  		this.buttonBornRandom.visible = false;
  		this.labelExternalProperty1.text = `获得属性+${mgrRole.getCurrLevelGotPropertyExtrnalValue()}`;
  		this.labelExternalPropertyLevel1.text = `${mgrRole.getGotPropertyExtrnalLevel()}`;
  		let videoPropertyInfo = this.getVideoPropertyExtrnalLevel();
  		if (!!videoPropertyInfo) {
  			this.labelExternalProperty3.text = `获得属性+${videoPropertyInfo.count}`;
  			this.labelExternalPropertyLevel3.text = `${videoPropertyInfo.level}`;
  		}
  	}
  	dispose() {
  		super.dispose();
  	}
  	getVideoPropertyExtrnalLevel() {
  		let appendLv = 1;
  		if (mgrRole.getGotPropertyExtrnalLevel() <= 2) {
  			appendLv = 3;
  		}
  		else if (mgrRole.getGotPropertyExtrnalLevel() <= 5) {
  			appendLv = 2;
  		}
  		let videoLevel = mgrRole.getGotPropertyExtrnalLevel() + appendLv;
  		let maxLevel = 0;
  		let dbMap = db.get_ggg_extra_item_property_template_db_map();
  		for (let k in dbMap) {
  			if (dbMap[k].level > maxLevel) {
  				maxLevel = dbMap[k].level;
  			}
  		}
  		videoLevel = Math.min(maxLevel, videoLevel);
  		return db.get_ggg_extra_item_property_template_db(videoLevel);
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName != db.ADV_DB_ADVNAME.video_PanelStartBorn_born)
  			return;
  		if (!e.params.bBorn) {
  			return;
  		}
  		let videoPropertyInfo = this.getVideoPropertyExtrnalLevel();
  		mgrRole.setGotPropertyExtrnalLevel(videoPropertyInfo.level);
  		this.doChoose(e.params.type);
  	}
  	doChoose(type) {
  		mgrRole.markBornOnce();
  		let usingRoleId = null;
  		if (type == 1) {
  			usingRoleId = 201;
  		}
  		else {
  			usingRoleId = 401;
  		}
  		mgrRole.setUsingPlayerRoleId(usingRoleId);
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(usingRoleId);
  		mgrRole.setPropertyValue(!!roleData.property_1 ? Math.max(1, roleData.property_1) : 0, !!roleData.property_2 ? Math.max(1, roleData.property_2) : 0, !!roleData.property_3 ? Math.max(1, roleData.property_3) : 0, !!roleData.property_4 ? Math.max(1, roleData.property_4) : 0);
  		mgrCrossStage.setCurrStage(1);
  		Director.openPanel("PanelPositionUpFirstYearPreview", { fOnChoosed: this.context.fOnChoosed, bResetStage: true });
  		this.close();
  	}
  	on_click_buttonBornType01() {
  		this.doChoose(1);
  	}
  	on_click_buttonBornType02() {
  		this.doChoose(2);
  	}
  	on_click_buttonBornType03() {
  		if (this.bTriggerAd) {
  			// console.info("5555555555555555555555555555555555555");
  			mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelStartBorn_born, { bBorn: true, type: 3 }, true);
  			return;
  		}
  		this.doChoose(3);
  	}
  	on_click_buttonBornType04() {
  		if (this.bTriggerAd) {
  			// console.info("5555555555555555555555555555555555555");
  			mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelStartBorn_born, { bBorn: true, type: 4 }, true);
  			return;
  		}
  		this.doChoose(4);
  	}
  	on_click_buttonBornRandom() {
  		Director.openPanel(`PanelChoosePosition`, { fOnChoosed: this.context.fOnChoosed, bResetStage: true });
  		this.close();
  	}
  	on_click_labelExternalProperty1() {
  	}
  	on_click_labelExternalPropertyLevel1() {
  	}
  	on_click_labelExternalProperty3() {
  	}
  	on_click_labelExternalPropertyLevel3() {
  	}
  }
  PanelStartBorn.sourceName = "ui://gogogo/PanelStartBorn";

  class PanelTrail extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "开始待机从试用界面";
  	}
  	onLoaded() {
  		let deltaY = (Global.canvasHeight - 1024) / 2;
  		if (db.cop_db.ui_bottom_mode_switch[0]) {
  			mgrUiBottom.curInBottomViewName = "PanelTrail";
  			this.adaptBannerAdv();
  			this.comPa.y = 790 + deltaY;
  			if (mgrUiBottom.checkIfUiBottomRecovery(0)) {
  				let delayTime = db.cop_db.ui_bottom_delay_time[0];
  				Timer.callLater(delayTime, () => {
  					mgrUiBottom.recordUiRecoveryTime();
  					mgrUiBottom.curInBottomViewName = "";
  					this.comPa.y = 572;
  					this.adaptBannerAdv();
  				}, this);
  			}
  		}
  		let retinueLevel = this.context.level || 10;
  		let retinueData = db.get_ggg_retinue_template_db(this.context.retinueId, retinueLevel);
  		let retinueDataZero = db.get_ggg_retinue_template_db(this.context.retinueId, 0);
  		this.labelRetinueName.text = retinueData.name;
  		this.labelUnlockTip.text = `第${retinueDataZero.unlcokYears}年遇到${retinueData.name}正常应对开启`;
  		this.loaderRetinue.url = retinueData.trailBodyImg;
  		mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelTrail_trial);
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  	}
  	dispose() {
  		mgrUiBottom.curInBottomViewName = "";
  		super.dispose();
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName == db.ADV_DB_ADVNAME.video_PanelTrail_trial) {
  			if (this.context.confirm) {
  				this.context.confirm();
  			}
  			this.close();
  		}
  	}
  	on_click_buttonClose() {
  		if (this.context.cancel) {
  			this.context.cancel();
  		}
  		this.close();
  	}
  	on_click_buttonCancle() {
  		if (this.context.cancel) {
  			this.context.cancel();
  		}
  		this.close();
  	}
  	on_click_buttonSure() {
  		// console.info("5555555555555555555555555555555555555");
  		mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelTrail_trial);
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  }
  PanelTrail.sourceName = "ui://gogogo/PanelTrail";

  class ViewAddCoinNumber extends ViewBase {
  	onCreate() {
  		this.pivotX = 0.5;
  		this.pivotY = 0.5;
  		this.setAmount(this.amount);
  		this.playEff();
  	}
  	dispose() {
  		super.dispose();
  	}
  	setAmount(value) {
  		this.amount = Math.abs(value);
  		if (!!this.labelCount) {
  			this.labelCount.text = this.amount > 0 ? `+${this.amount}` : `-${this.amount}`;
  		}
  	}
  	setStartPos(pos) {
  		this.startPos = pos;
  	}
  	playEff() {
  		let layer = Director.getLayerUI();
  		layer.addChild(this);
  		this.startPos = this.startPos || new Laya.Vector2(Global.canvasWidth / 2 + 30, Global.canvasHeight / 2 - 30);
  		this.setXY(this.startPos.x, this.startPos.y - Tools.random(10));
  		this.scaleX = 0;
  		this.scaleY = 0;
  		cc$1.tween(this)
  			.toScale(0.2, 1, cc$1.Ease.backOut)
  			.delay(0.2)
  			.call(() => {
  				this.dispose();
  			})
  			.start();
  	}
  	on_click_labelCount() {
  	}
  }
  ViewAddCoinNumber.sourceName = "ui://gogogo/ViewAddCoinNumber";

  class ViewSubCoinNumber extends ViewBase {
  	onCreate() {
  		this.pivotX = 0.5;
  		this.pivotY = 0.5;
  		this.setAmount(this.amount);
  		this.playEff();
  	}
  	dispose() {
  		super.dispose();
  	}
  	setAmount(value) {
  		this.amount = Math.abs(value);
  		if (!!this.labelCount) {
  			this.labelCount.text = this.amount > 0 ? `+${this.amount}` : `-${this.amount}`;
  		}
  	}
  	setStartPos(pos) {
  		this.startPos = pos;
  	}
  	playEff() {
  		let layer = Director.getLayerUI();
  		layer.addChild(this);
  		this.startPos = this.startPos || new Laya.Vector2(Global.canvasWidth / 2 + 30, Global.canvasHeight / 2 - 30);
  		this.setXY(this.startPos.x, this.startPos.y - Tools.random(10));
  		this.scaleX = 0;
  		this.scaleY = 0;
  		cc$1.tween(this)
  			.toScale(0.2, 1, cc$1.Ease.backOut)
  			.delay(0.2)
  			.call(() => {
  				this.dispose();
  			})
  			.start();
  	}
  	on_click_labelCount() {
  	}
  }
  ViewSubCoinNumber.sourceName = "ui://gogogo/ViewSubCoinNumber";

  class PanelIllu extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "图鉴界面";
  		this.grownupLine2RoleDataDict = {};
  		this.bShowUiAni = false;
  		this.bDisableUiAni = false;
  		this.currGrownupLineToFillDataFlagDict = {};
  	}
  	onLoaded() {
  		this.playTranslation(this.resNode, "in");
  		let dbMap = db.get_amaze_cloth_crossing_property_to_logic_role_map();
  		for (let k in dbMap) {
  			let roleData = dbMap[k];
  			this.grownupLine2RoleDataDict[roleData.grownupLine] = this.grownupLine2RoleDataDict[roleData.grownupLine] || [];
  			this.grownupLine2RoleDataDict[roleData.grownupLine].push(roleData);
  		}
  		for (let k in this.grownupLine2RoleDataDict) {
  			let datas = this.grownupLine2RoleDataDict[k];
  			datas = Tools.sortArrayByField(datas, "level");
  			this.grownupLine2RoleDataDict[k] = datas;
  		}
  		this.ctrlTabState = this.comTab.getController("tabState");
  		this.ctrlListState = this.resNode.getController("listState");
  		let defaultTab = this.context.tabIndex || 0;
  		this.ctrlTabState.setSelectedIndex(defaultTab);
  		this.ctrlListState.setSelectedIndex(defaultTab);
  		for (let k in this.grownupLine2RoleDataDict) {
  			this.tryFillDataByGrownupLine(parseInt(k));
  		}
  		this.refreshTabRedPoint();
  	}
  	dispose() {
  		super.dispose();
  	}
  	update() {
  		this.textPositionAmount.text = `${mgrRole.getAllActivedRoleIdArr().length}`;
  	}
  	getRoleByGrownupLine(grownupLine) {
  		return this.grownupLine2RoleDataDict[grownupLine];
  	}
  	tryFillDataByGrownupLine(grownupLine) {
  		let bFilled = this.currGrownupLineToFillDataFlagDict[grownupLine];
  		if (!!bFilled) {
  			return;
  		}
  		this.currGrownupLineToFillDataFlagDict[grownupLine] = true;
  		let list = this["listItemsLine" + grownupLine];
  		if (!list) {
  			return;
  		}
  		let datas = this.getRoleByGrownupLine(grownupLine);
  		if (!datas) {
  			return;
  		}
  		list.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj.visible = false;
  			obj.setPivot(0.5, 0.5);
  			obj[`idx`] = idx;
  			let roleData = datas[idx];
  			obj[`roleId`] = roleData.id;
  			let bArrived = mgrRole.isArrivedRoleId(roleData.id);
  			let bActived = mgrRole.isActivedRoleId(roleData.id);
  			let unActiveChildNameArr = [
  				"textNameUnActive",
  				"spriteMask",
  			];
  			let activeChildNameArr = [
  				"textName",
  			];
  			for (let k in unActiveChildNameArr) {
  				let child = obj.getChild(unActiveChildNameArr[k]);
  				child.visible = !bActived;
  			}
  			for (let k in activeChildNameArr) {
  				let child = obj.getChild(activeChildNameArr[k]);
  				child.visible = !!bActived;
  			}
  			let validPropertyIdArr = [];
  			!!roleData.property_1 && validPropertyIdArr.push(1);
  			!!roleData.property_2 && validPropertyIdArr.push(2);
  			!!roleData.property_3 && validPropertyIdArr.push(3);
  			!!roleData.property_4 && validPropertyIdArr.push(4);
  			obj.getChild("imageEndFlagNormal").visible = (roleData.maxLevelResultTimeline && roleData.maxLevelResultTimeline != "") ? true : false;
  			obj.getChild("textName").text = roleData.name;
  			obj.getChild("loaderPositionIcon").url = roleData.headIcon;
  			obj.getChild("loaderPositionIcon").color = bActived ? "#FFFFFF" : "#000000";
  			obj.getChild("loaderPositionIcon").alpha = bActived ? 1 : 0.3;
  			obj.getChild("imgHeadUnActive").visible = false;
  			let propertyInfoArr = mgrRole.getSortedPropertyIndexArr(roleData.property_1, roleData.property_2, roleData.property_3, roleData.property_4);
  			let rolePropertyId = propertyInfoArr[0].propertyIndex;
  			let propertyGroup = obj.getChild("groupProperty1");
  			propertyGroup.visible = propertyGroup.visible && !!rolePropertyId;
  			if (propertyGroup.visible) {
  				let propertyIcon = obj.getChild("loaderIcon1");
  				let propertyText = obj.getChild("textAmount1");
  				let propertyData = db.get_amaze_cloth_crossing_role_property(rolePropertyId);
  				propertyIcon.url = propertyData.smallIcon;
  				propertyText.text = `${Math.max(1, roleData["property_" + rolePropertyId] || 0)}`;
  			}
  			if (!this.bDisableUiAni) {
  				let time = 0.15 * Math.ceil((idx + 1) / 3);
  				Timer.callLater(time, (timer) => {
  					obj.visible = true;
  					this.playTranslation(obj, "in", new Laya.Handler(this, () => {
  						timer.stop();
  						timer = null;
  					}));
  				}, obj);
  			}
  			else {
  				obj.visible = true;
  			}
  			let buttonActive = obj.getChild("buttonActive");
  			buttonActive.visible = (bArrived && !bActived) ? true : false;
  			let count = buttonActive.visible ? 1 : 0;
  			mgrTip.showBadgeWithNumber(obj.displayObject, count, new Laya.Point(4, 4));
  			if (idx == datas.length - 1) {
  				this.bDisableUiAni = false;
  			}
  		});
  		list.off(fgui.Events.CLICK_ITEM, this, this.onClickNormalButtonActive.bind(this));
  		list.on(fgui.Events.CLICK_ITEM, this, this.onClickNormalButtonActive.bind(this));
  		list.numItems = datas.length;
  	}
  	changeTab(tab) {
  		this.ctrlTabState.setSelectedIndex(tab);
  		this.ctrlListState.setSelectedIndex(tab);
  		for (let k in this.grownupLine2RoleDataDict) {
  			let grownupLine = parseInt(k);
  			let list = this["listItemsLine" + grownupLine];
  			if (!list) {
  				continue;
  			}
  			let datas = this.getRoleByGrownupLine(grownupLine);
  			if (!datas) {
  				return;
  			}
  			if (grownupLine - 1 == tab && datas.length > 0) {
  				list.numItems = datas.length;
  				list.scrollToView(0);
  			}
  		}
  		this.refreshTabRedPoint();
  	}
  	onClickNormalButtonActive(obj) {
  		UiHelper.playBigSmallOnce(obj, 1, 1.1);
  		let roleId = obj[`roleId`];
  		if (mgrRole.isActivedRoleId(roleId)) {
  			Director.openPanel(`PanelIlluDetails`, { roleId: roleId });
  			return;
  		}
  		if (!mgrRole.isArrivedRoleId(roleId)) {
  			mgrTip.showMsgTip("还未达成过");
  			return;
  		}
  		mgrRole.addActivedRoleId(roleId);
  		let template = db.get_amaze_cloth_crossing_property_to_logic_role(roleId);
  		GameStatistics.statisCommonEvent(template.statisPointIdActived);
  		this.bDisableUiAni = true;
  		let datas = this.getRoleByGrownupLine(template.grownupLine);
  		let list = this["listItemsLine" + template.grownupLine];
  		if (!!datas && !!list) {
  			list.numItems = datas.length;
  		}
  		this.showGotPanel(roleId);
  		this.refreshTabRedPoint();
  	}
  	showGotPanel(roleId) {
  		Director.openPanel("PanelUnlock", {
  			roleId: roleId,
  			fOnClose: () => {
  			}
  		});
  	}
  	isCanShowNormalRedPoint(grownupLine) {
  		let datas = this.getRoleByGrownupLine(grownupLine);
  		if (!datas) {
  			return false;
  		}
  		for (let i = 0; i < datas.length; i++) {
  			let roleData = datas[i];
  			let bArrived = mgrRole.isArrivedRoleId(roleData.id);
  			let bActived = mgrRole.isActivedRoleId(roleData.id);
  			if (bArrived && !bActived) {
  				return true;
  			}
  		}
  		return false;
  	}
  	refreshTabRedPoint() {
  		for (let k in this.grownupLine2RoleDataDict) {
  			let grownupLine = parseInt(k);
  			let count = this.isCanShowNormalRedPoint(grownupLine) ? 1 : 0;
  			let btn1 = this[`buttonTabLine${grownupLine}1`];
  			let btn2 = this[`buttonTabLine${grownupLine}2`];
  			if (!btn1 || !btn2) {
  				continue;
  			}
  			mgrTip.showBadgeWithNumber(btn1.displayObject, count, new Laya.Point(4, 4));
  			mgrTip.showBadgeWithNumber(btn2.displayObject, count, new Laya.Point(4, 4));
  		}
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  	on_click_buttonTabLine11() {
  		this.changeTab(0);
  	}
  	on_click_buttonTabLine21() {
  		this.changeTab(1);
  	}
  	on_click_buttonTabLine31() {
  		this.changeTab(2);
  	}
  	on_click_buttonTabLine41() {
  		this.changeTab(3);
  	}
  	on_click_buttonTabLine12() {
  	}
  	on_click_buttonTabLine22() {
  	}
  	on_click_buttonTabLine32() {
  	}
  	on_click_buttonTabLine42() {
  	}
  }
  PanelIllu.sourceName = "ui://illu/PanelIllu";

  class PanelUnlock extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "恭喜解锁界面";
  	}
  	onLoaded() {
  		let deltaY = (Global.canvasHeight - 1024) / 2;
  		if (db.cop_db.ui_bottom_mode_switch[3]) {
  			mgrUiBottom.curInBottomViewName = "PanelUnlock";
  			this.adaptBannerAdv();
  			let originY = this.resNode.y;
  			this.resNode.y = originY + 170 + deltaY;
  			if (mgrUiBottom.checkIfUiBottomRecovery(3)) {
  				let delayTime = db.cop_db.ui_bottom_delay_time[3];
  				Timer.callLater(delayTime, () => {
  					mgrUiBottom.recordUiRecoveryTime();
  					mgrUiBottom.curInBottomViewName = "";
  					this.resNode.y = originY;
  					this.adaptBannerAdv();
  				}, this);
  			}
  		}
  		mgrSound.play(124);
  		this.playTranslation(this.resNode, "in");
  		this.fillData();
  	}
  	dispose() {
  		mgrUiBottom.curInBottomViewName = "";
  		super.dispose();
  	}
  	fillData() {
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.context.roleId);
  		let validPropertyIdArr = [];
  		!!roleData.property_1 && validPropertyIdArr.push(1);
  		!!roleData.property_2 && validPropertyIdArr.push(2);
  		!!roleData.property_3 && validPropertyIdArr.push(3);
  		!!roleData.property_4 && validPropertyIdArr.push(4);
  		this.comPosition.getChild("textName").text = roleData.name;
  		this.comPosition.getChild("loaderPositionIcon").url = roleData.headIcon;
  		this.comPosition.getChild("loaderPositionBg").url = roleData.positionBg;
  		this.comPosition.getChild("loaderPositionIconBg").visible = false;
  		this.comPosition.getChild("textName").strokeColor = "#" + roleData.strokeColor;
  		let loaderPositionGrade = this.comPosition.getChild("loaderPositionGrade");
  		loaderPositionGrade.url = roleData.positionGradeIcon;
  		let rolePropertyId = roleData.grownupLine;
  		let propertyGroup = this.comPosition.getChild("groupProperty1");
  		propertyGroup.visible = !!rolePropertyId;
  		if (propertyGroup.visible) {
  			let propertyIcon = this.comPosition.getChild("loaderIcon1");
  			let propertyText = this.comPosition.getChild("textAmount1");
  			propertyText.strokeColor = "#" + roleData.strokeColor;
  			let propertyData = db.get_amaze_cloth_crossing_role_property(rolePropertyId);
  			propertyIcon.url = propertyData.smallIcon;
  			propertyText.text = `${Math.max(1, roleData["property_" + rolePropertyId] || 0)}`;
  		}
  		this.textRewardAmount.text = `${roleData.positionCollectRewardAmount}`;
  	}
  	getReward() {
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.context.roleId);
  		BaseFacade.mItem.addItem(2, roleData.positionCollectRewardAmount, "解锁官职");
  		mgrTip.addGotItemTip(2, roleData.positionCollectRewardAmount);
  	}
  	on_click_buttonClose() {
  		this.getReward();
  		this.close();
  	}
  	on_click_buttonOk() {
  		this.getReward();
  		this.close();
  	}
  	on_click_textRewardAmount() {
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  }
  PanelUnlock.sourceName = "ui://illu/PanelUnlock";

  class PanelIlluDetails extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "图鉴详情界面";
  		this.avatarPosCameraDict = {
  			[0]: {
  				avatarData: {
  					pos: new Laya.Vector3(0, 0, 0),
  					rot: new Laya.Vector3(0, 0, 0)
  				},
  				cameraData: {
  					fov: 35,
  					pos: new Laya.Vector3(0, 1.5, 4),
  					rot: new Laya.Vector3(-7, 0, 0),
  				}
  			}
  		};
  		this.roleData = null;
  		this.logicRoleData = null;
  		this.aniArr = [ROLE_QUOTE_MOV.movWalk, ROLE_QUOTE_MOV.movLoseShow01, ROLE_QUOTE_MOV.movResultEvent1Fault, ROLE_QUOTE_MOV.movResultEvent2RightUpper, ROLE_QUOTE_MOV.movResultEvent2RightLower, ROLE_QUOTE_MOV.movResultEvent5Right, ROLE_QUOTE_MOV.movResultEvent5Fault];
  	}
  	onLoaded() {
  		this.createScene3DBack(1);
  		this.cameraFollow = this.camera.getComponent(CameraFollow);
  		this.cameraFollow.lookMode = E_CAMERA_MODE.fixMode;
  		let param = this.avatarPosCameraDict[0].cameraData;
  		this.cameraFollow.position = param.pos.clone();
  		this.cameraFollow.endRotation = param.rot.clone();
  		this.cameraFollow.fov = param.fov;
  		this.cameraFollow.lerpValue = 1;
  		this.cameraFollow.onLateUpdate();
  		let logicRoleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.context.roleId);
  		this.logicRoleData = logicRoleData;
  		let roleData = db.get_amaze_cloth_crossing_role_db(logicRoleData.roleId);
  		this.roleData = roleData;
  		console.warn("---this.logicRoleData.maxLevelResultTimeline=", this.logicRoleData.maxLevelResultTimeline);
  		this.comChat.setScale(0, 0);
  		this.buildUi();
  		this.fillData();
  	}
  	dispose() {
  		super.dispose();
  	}
  	buildUi() {
  		if (!!this.npcAvatar) {
  			this.npcAvatar.destroy();
  			this.npcAvatar = null;
  		}
  		this.npcAvatar = new NpcAvatar(this.logicRoleData.roleId);
  		this.linkModelAtBack(this.npcAvatar);
  		this.npcAvatar.registerAllLoadEndCallback(() => {
  			this.npcAvatar.playIdle();
  		});
  		UiHelper.registerTouchEvent(this.graphEvent, this.onTouchRole.bind(this));
  		if (this.logicRoleData.maxLevelResultTimeline) {
  			this.buttonCheckEnding.visible = true;
  		}
  		else {
  			this.buttonCheckEnding.visible = false;
  		}
  	}
  	fillData() {
  		this.textName.text = this.logicRoleData.name;
  		this.textPosition.text = `官品:${this.logicRoleData.positionGrade}`;
  		this.textDesc.text = this.logicRoleData.introduction;
  	}
  	playAni() {
  		let aniName = this.aniArr[Mathf.random(0, this.aniArr.length - 1)];
  		if (aniName) {
  			this.npcAvatar.playAnimation(this.roleData[aniName], 0.1, null, () => { }, false);
  		}
  	}
  	playCheckEnding() {
  		this.comContent.visible = false;
  		if (!!this.npcAvatar) {
  			this.npcAvatar.active = false;
  		}
  		this.playTimeline(this.logicRoleData.maxLevelResultTimeline, (clearBefore) => {
  			clearBefore();
  			this.comContent.visible = true;
  			if (!!this.npcAvatar) {
  				this.npcAvatar.active = true;
  			}
  		});
  	}
  	showMovieWordPanelVisible() {
  		if (!this.comChat.visible) {
  			this.comChat.visible = true;
  		}
  		cc$1.tween(this.comChat, true)
  			.toScale(0.1, 1)
  			.delay(3)
  			.toScale(0.1, 0)
  			.start();
  	}
  	playTimeline(tilelineName, callback) {
  		Director.showWait("load_timeline");
  		let director = new PlayableDirector();
  		director.stopUpdateOnlyWhenFinish = true;
  		let template = db.get_timeline_db(tilelineName);
  		director.load(template.resPath, () => {
  			Director.hideWait("load_timeline");
  			this.linkModelAtBack(director);
  			this.camera.active = false;
  			director.play();
  			let timeSoundDbMap = db.get_ggg_timeline_movie_word_db_map();
  			let soundArr = [];
  			for (let k in timeSoundDbMap) {
  				let tmp = timeSoundDbMap[k];
  				if (tmp.timelineName == tilelineName) {
  					soundArr.push(tmp);
  				}
  			}
  			if (soundArr.length > 0) {
  				soundArr = Tools.sortArrayByField(soundArr, "frameNum");
  				for (let i = 0; i < soundArr.length; i++) {
  					const element = soundArr[i];
  					let frameNum = element.frameNum;
  					Timer.callLater(frameNum / 30, () => {
  						mgrSound.playSound(element.soundId);
  						if (!!element.word) {
  							let labelName = this.comChat.getChild("chatName");
  							let labelContent = this.comChat.getChild("chatContent");
  							labelContent.text = element.word;
  							labelName.text = element.playerName;
  							this.showMovieWordPanelVisible();
  						}
  					}, this);
  				}
  			}
  			let oldBgSoundId = mgrSound.playingMusicSoundId;
  			let config = db.get_ggg_timeline_config_db(tilelineName);
  			if (!!config && config.bgSoundId) {
  				mgrSound.play(config.bgSoundId);
  			}
  			director.on("STOPPED", this, () => {
  				let clearBefore = () => {
  					if (this.isDisposed || this.resNode.isDisposed) {
  						return;
  					}
  				};
  				mgrSound.playSound(oldBgSoundId);
  				this.camera.active = true;
  				director.removeSelf();
  				director.destroy();
  				callback && callback(clearBefore);
  			});
  		});
  	}
  	onTouchRole(e) {
  		if (e.bEnd) {
  			this.playAni();
  		}
  	}
  	on_click_buttonBack() {
  		this.close();
  	}
  	on_click_buttonCheckEnding() {
  		this.playCheckEnding();
  	}
  	on_click_buttonInteraction() {
  		this.playAni();
  	}
  }
  PanelIlluDetails.sourceName = "ui://illu/PanelIlluDetails";

  class PanelAgeTipDialog extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "适龄提示界面";
  		this.panelLayer = 2;
  	}
  	onLoaded() {
  		let baseChannelInfo = mgrSdk.getBaseChannelInfo();
  		this.labelDesc.text = baseChannelInfo.ageLevelInfo;
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  	on_click_buttonCancle() {
  		this.close();
  	}
  }
  PanelAgeTipDialog.sourceName = "ui://loading/PanelAgeTipDialog";

  class PanelLoadingBase extends PanelBase3D {
  	constructor(context) {
  		super(context);
  		this.panelLayer = 3;
  		this.panelStyle = 0;
  		this.barSytle = 0;
  		this.curProgress = 0;
  		this.maxProgress = 0;
  		this.progressDelta = 0.02;
  		this.startLoadingTime = 0;
  		this.updateCount = 0;
  		this.state = 0;
  		Global.registerListeners(this, {
  			[BASE_MSG.RES_LOAD_START]: this.onMsgLoadStart.bind(this),
  			[BASE_MSG.RES_LOAD_PROGRESS]: this.onMsgLoadProgress.bind(this),
  			[BASE_MSG.RES_LOAD_END]: this.onMsgLoadEnd.bind(this),
  		});
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgLoadStart(tip) {
  		this.startLoadingTime = Timer.time;
  		this.onLoadStart(tip);
  	}
  	onMsgLoadProgress(progress) {
  		progress = Mathf.clamp01(progress);
  		if (progress > this.maxProgress)
  			this.maxProgress = progress;
  	}
  	onMsgLoadEnd(donotJump) {
  		this.maxProgress = 1;
  		if (!donotJump) {
  			if (this.curProgress < 0.95) {
  				this.curProgress = 0.95;
  			}
  		}
  	}
  	update() {
  		switch (this.state) {
  			case 0:
  				switch (this.barSytle) {
  					case 0:
  						this.curProgress = Mathf.clamp(this.curProgress + this.progressDelta, 0, this.maxProgress);
  						break;
  					case 1:
  						this.updateCount = (this.updateCount + 1) % 5;
  						if (this.updateCount > 0)
  							return;
  						this.curProgress = this.maxProgress;
  						break;
  				}
  				if (this.curProgress >= 1) {
  					this.state = 1;
  					this.onLoadProgress(1);
  				}
  				else {
  					this.onLoadProgress(this.curProgress);
  				}
  				break;
  			case 1:
  				this.state = 2;
  				console.log("loading time:", Mathf.round(Timer.time - this.startLoadingTime, 2));
  				if (this.onLoadComplete()) {
  					this.close();
  				}
  				break;
  			case 2:
  				break;
  		}
  	}
  }

  class PanelLoading extends PanelLoadingBase {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "loading";
  		this.bShowMask = false;
  		this.index = 0;
  		this.time = 0;
  		this.bTouched = false;
  	}
  	onLoaded() {
  		Global.registerListeners(this, {
  			MSG_SDK_BASE_CHANNEL_INFO_CHANGED: this.onMsgSdkBaseChannelInfoChanged.bind(this),
  		});
  		this.fillGameInfo();
  		this.progressBar.value = 0;
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgSdkBaseChannelInfoChanged() {
  		this.fillGameInfo();
  	}
  	fillGameInfo() {
  		let baseChannelInfo = mgrSdk.getBaseChannelInfo();
  		if (baseChannelInfo) {
  			if (mgrSdk.gameName == "本宫太难了") {
  				this.imageLogoNormal.visible = false;
  				this.imageLogoWeixin.visible = true;
  			}
  			else {
  				this.imageLogoNormal.visible = true;
  				this.imageLogoWeixin.visible = false;
  			}
  			this.textLineInfo.text = baseChannelInfo.licenceInfo;
  			this.textLineInfo.visible = baseChannelInfo.isShowLicenceInfo;
  			this.buttonAgeTip.visible = baseChannelInfo.isShowAgeLevelInfo;
  		}
  		else {
  			this.imageLogoNormal.visible = true;
  			this.imageLogoWeixin.visible = false;
  			this.textLineInfo.visible = false;
  			this.buttonAgeTip.visible = false;
  		}
  	}
  	onLoadStart(str) {
  	}
  	onLoadProgress(progress) {
  		if (this.isLoaded) {
  			this.progressBar.value = progress * 100;
  			this.labelProgressTip.text = `${Math.ceil(progress * 100)}%`;
  		}
  	}
  	onLoadComplete() {
  		this.finish();
  		return false;
  	}
  	finish() {
  		this.close();
  		Global.sendMsg("MSG_LOADING_PANEL_FINISHED");
  	}
  	on_click_labelWordTip() {
  	}
  	on_click_labelProgressTip() {
  	}
  	on_click_buttonAgeTip() {
  		Director.openPanel("PanelAgeTipDialog");
  	}
  }
  PanelLoading.sourceName = "ui://loading/PanelLoading";

  class PanelWait extends PanelBase {
  	constructor() {
  		super();
  		this.PANEL_NAME = "等待";
  		this.bOpenAndCloseAnim = true;
  		Global.registerListeners(this, {
  			[BASE_MSG.PANEL_OPEN_COMPLETE]: this.onMsgPanelOpenComplete.bind(this),
  		});
  	}
  	onLoaded() {
  		let delta = 360 / 8;
  		cc$1.tween(this.loadSprite).repeatForever(cc$1.tween().delay(0.15).by(0, { rotation: delta })).start();
  	}
  	dispose() {
  		super.dispose();
  	}
  	onPanelOpenAnim() {
  		this.alpha = 0;
  		cc$1.tween(this).delay(1).to(0.4, cc$1.PROP.ALPHA1).start();
  	}
  	onPanelCloseAnim(onComplete) {
  		cc$1.tween(this, true).to(0.2, cc$1.PROP.ALPHA0).call(onComplete).start();
  	}
  	onMsgPanelOpenComplete() {
  		this.close();
  	}
  }
  PanelWait.sourceName = "ui://loading/PanelWait";

  class PanelPet extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "我的宠物界面";
  		this.petIdArr = [];
  		this.bShowUiAni = false;
  		Advertisement.insertAdverV2();
  	}
  	onLoaded() {
  		this.playTranslation(this.resNode, "in");
  		let arr = [];
  		let dbMap = db.get_ggg_pet_template_db_map();
  		for (let k in dbMap) {
  			arr.push(parseInt(k));
  		}
  		this.petIdArr = arr;
  		this.buildUi();
  		this.fillData();
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  		Advertisement.insertAdverV2();
  	}
  	dispose() {
  		super.dispose();
  	}
  	getPreLoadModels() {
  		let modelIds = [
  			db.MODEL_DB_ID._130_ui_once_levp_cw
  		];
  		return modelIds;
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName == db.ADV_DB_ADVNAME.video_PanelPet_ad_upgrade) {
  			if (e.params && e.params.type == 1) {
  				mgrCrossStage.addFreeLevelUpDialogCount(1);
  			}
  			let petId = this.curPetId;
  			let nodePos = this.curNodePos;
  			let result = mgrPet.upgradeLevel(petId, true);
  			mgrTip.showMsgTip(result.tipStr);
  			this.listPet.numItems = this.petIdArr.length;
  			if (result.bSuccess) {
  				this.curPetId = petId;
  				this.curNodePos = nodePos;
  				this.addEffect(db.MODEL_DB_ID._130_ui_once_levp_cw, { x: nodePos.x + 24, y: nodePos.y - 268 });
  			}
  		}
  	}
  	buildUi() {
  	}
  	fillData() {
  		this.listPet.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj.visible = false;
  			obj[`idx`] = idx;
  			let petId = this.petIdArr[idx];
  			obj[`petId`] = petId;
  			let currLevel = mgrPet.getGotPetIdLevel(petId);
  			let template = db.get_ggg_pet_template_db(petId, currLevel);
  			let templateNext = db.get_ggg_pet_template_db(petId, currLevel + 1);
  			let bFollowed = (mgrPet.followingPetId == petId);
  			let bGot = mgrPet.isGotPetId(petId);
  			let bCanBuyToGet = (mgrCrossStage.isPlayedStage(template.unlockYears)) ? true : false;
  			let buttonFollow = obj.getChild("buttonFollow");
  			let spriteFollowed = obj.getChild("spriteFollowed");
  			let groupUnlocked = obj.getChild("groupUnlocked");
  			let buyTip = obj.getChild("buyTip");
  			let buttonAdUpgrade = obj.getChild("buttonAdUpgrade");
  			let buttonUpgrade = obj.getChild("buttonUpgrade");
  			let loaderCoinIcon = obj.getChild("loaderCoinIcon");
  			let spritePetMax = obj.getChild("spritePetMax");
  			let groupCoinLvup = obj.getChild("groupCoinLvup");
  			buyTip.text = "需要在【第" + template.unlockYears + "年】购买";
  			obj.getChild("name").text = template.name;
  			obj.getChild("textCoinAmount").text = template.upgradeCostAmount ? template.upgradeCostAmount.toString() : "";
  			obj.getChild("loaderPetIcon").url = template.icon;
  			obj.getChild("level").text = "等级：" + template.level;
  			obj.getChild("income").text = "每秒收益：" + template.outputCount;
  			buttonFollow.visible = false;
  			spriteFollowed.visible = false;
  			groupUnlocked.visible = !!bGot;
  			buyTip.visible = false;
  			buttonAdUpgrade.visible = false;
  			groupCoinLvup.visible = false;
  			spritePetMax.visible = false;
  			if (!bGot) {
  				buyTip.visible = !bCanBuyToGet;
  				buttonAdUpgrade.visible = !!bCanBuyToGet && mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelPet_ad_upgrade);
  				groupCoinLvup.visible = !!bCanBuyToGet;
  				if (!!bCanBuyToGet) {
  					buttonUpgrade.title = "购买";
  				}
  			}
  			else {
  				buttonUpgrade.title = "升级";
  				buttonAdUpgrade.visible = false;
  				spriteFollowed.visible = bFollowed;
  				buttonFollow.visible = !spriteFollowed.visible;
  				if (!!templateNext) {
  					spritePetMax.visible = false;
  					groupCoinLvup.visible = true;
  					let count = mgrPet.isHaveCanUpgradeByPetId(templateNext.id) ? 1 : 0;
  					mgrTip.showBadgeWithNumber(buttonUpgrade.displayObject, count, new Laya.Point(5, 5));
  				}
  				else {
  					groupCoinLvup.visible = false;
  					spritePetMax.visible = true;
  				}
  			}
  			if (!this.bShowUiAni) {
  				let time = 0.1 * idx;
  				Timer.callLater(time, (timer) => {
  					obj.visible = true;
  					this.playTranslation(obj, "in", new Laya.Handler(this, () => {
  						timer.stop();
  						timer = null;
  					}));
  				}, obj);
  				if (idx == this.listPet.numItems - 1) {
  					this.bShowUiAni = true;
  				}
  			}
  			else {
  				obj.visible = true;
  			}
  			UiHelper.unregisterTouchEvent(buttonAdUpgrade);
  			UiHelper.unregisterTouchEvent(buttonUpgrade);
  			UiHelper.unregisterTouchEvent(buttonFollow);
  			UiHelper.registerTouchEvent(buttonAdUpgrade, this.onClickButtonAdUpgrade.bind(this, obj, petId));
  			UiHelper.registerTouchEvent(buttonUpgrade, this.onClickButtonUpgrade.bind(this, obj, petId));
  			UiHelper.registerTouchEvent(buttonFollow, this.onClickButtonFollow.bind(this, obj, petId));
  		});
  		this.listPet.numItems = this.petIdArr.length;
  	}
  	onClickButtonAdUpgrade(obj, petId, e) {
  		if (!e.bClick) {
  			return;
  		}
  		if (obj.petId == petId) {
  			let nodePos = obj.parent.localToGlobal(obj.x, obj.y);
  			this.curNodePos = nodePos;
  			this.curPetId = petId;
  			// console.info("5555555555555555555555555555555555555");
  			mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelPet_ad_upgrade, null, true);
  		}
  	}
  	onClickButtonUpgrade(obj, petId, e) {
  		if (!e.bClick) {
  			return;
  		}
  		if (obj.petId == petId) {
  			let nodePos = obj.parent.localToGlobal(obj.x, obj.y);
  			this.curNodePos = nodePos;
  			this.curPetId = petId;
  			if (mgrPet.getGotPetIdLevel(petId) == 0 || !mgrCrossStage.tryShowFreeLevelUpDialog(db.ADV_DB_ADVNAME.video_PanelPet_ad_upgrade, 1)) {
  				let result = mgrPet.upgradeLevel(petId);
  				mgrTip.showMsgTip(result.tipStr);
  				if (result.bSuccess) {
  					this.listPet.numItems = this.petIdArr.length;
  					this.addEffect(db.MODEL_DB_ID._130_ui_once_levp_cw, { x: nodePos.x + 24, y: nodePos.y - 268 });
  				}
  			}
  		}
  	}
  	onClickButtonFollow(obj, petId, e) {
  		if (!e.bClick) {
  			return;
  		}
  		if (obj.petId == petId) {
  			mgrPet.followingPetId = obj.petId;
  			Global.sendMsg("MSG_PET_FOLLOWING_CHANGED");
  			mgrTip.showMsgTip("成功设置跟随~");
  			this.listPet.numItems = this.petIdArr.length;
  		}
  	}
  	getCurrShowPetId(index) {
  		return this.petIdArr[index || 0];
  	}
  	getCurrShowPetItemId(index) {
  		let template = db.get_ggg_pet_template_db(this.getCurrShowPetId(index), 1);
  		return template.countDownItemId || 907;
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  }
  PanelPet.sourceName = "ui://pet/PanelPet";

  class PanelResultField extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "跑酷结算失败";
  	}
  	onLoaded() {
  	
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgAdvShowSuc(e) {
  	}
  	on_click_buttonClose() {
  		this.context.fOnConfirm();
  		this.close();
  	}
  	on_click_buttonRevival() {
  		this.on_click_buttonRestartCoin();
  	}
  	on_click_buttonRestartAd() {
  	}
  	on_click_buttonRestartCoin() {
  		let config = db.get_amaze_cloth_crossing_config(1);
  		let amount = BaseFacade.mItem.getItemAmount(1);
  		if (amount > config.revivalCostAmount) {
  			BaseFacade.mItem.subItem(1, config.revivalCostAmount, "跑酷结算失败无损重生");
  			this.context.fOnConfirm(true);
  			this.close();
  		}
  		else {
  			let templateCost = db.get_item_db(1);
  			mgrTip.showMsgTip(`${templateCost.name}不足`);
  		}
  	}
  	on_click_labelRestartCoinCost() {
  	}
  	on_click_labelRestartCoinCost2() {
  	}
  }
  PanelResultField.sourceName = "ui://result/PanelResultField";

  class PanelResultSuccess extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "跑酷结算胜利";
  	}
  	onLoaded() {
  	}
  	dispose() {
  		super.dispose();
  	}
  	doReward(bAded) {
  		let ratio = !!bAded ? this.context.adRewardAmountRatio : 1;
  		let itemId = this.context.rewardItemId;
  		let amount = this.context.rewardAmount * ratio;
  		BaseFacade.mItem.addItem(itemId, amount, "跑酷结算胜利奖励");
  		Advertisement.insertAdverV2();
  	}
  	onMsgAdvShowSuc(e) {
  	}
  	on_click_buttonReceive() {
  		this.doReward(false);
  		this.context.fOnConfirm();
  		this.close();
  	}
  	on_click_buttonClose() {
  		this.on_click_buttonReceive();
  	}
  	on_click_buttonReceiveAd() {
  	}
  	on_click_buttonReceiveNormal() {
  		this.on_click_buttonReceive();
  	}
  	on_click_labelAmount() {
  	}
  	on_click_labelReceiveAdAmount() {
  	}
  	on_click_labelReceiveNormalRatio() {
  	}
  	on_click_labelReceiveNormalAmount() {
  	}
  }
  PanelResultSuccess.sourceName = "ui://result/PanelResultSuccess";

  class PanelEnding extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "恭喜完成界面";
  	}
  	onLoaded() {
  		mgrSound.play(124);
  		this.ctrlState = this.comContent.getController("c1");
  		this.playTranslation(this.resNode, "in", new Laya.Handler(this, () => {
  			this.playTranslation(this.resNode, "idle2");
  		}));
  		this.fillData();
  	}
  	dispose() {
  		super.dispose();
  	}
  	fillData() {
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.context.newRoleId);
  		this.loaderHead.url = roleData.headIcon;
  		this.textPosition.text = roleData.name;
  		this.textPositionTip.text = "结局达成：";
  		this.ctrlState.setSelectedIndex(1);
  		this.textDesc.text = "经过" + (mgrCrossStage.getCurrStageId() - 1) + "年的努力，由于出色的表现，很快获得了皇上的赏识。";
  	}
  	on_click_buttonOk() {
  		this.close();
  	}
  }
  PanelEnding.sourceName = "ui://result/PanelEnding";

  class PanelScroll extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "圣旨卷轴界面";
  	}
  	onLoaded() {
  		let deltaY = (Global.canvasHeight - 1024) / 2;
  		if (db.cop_db.ui_bottom_mode_switch[6]) {
  			mgrUiBottom.curInBottomViewName = "PanelScroll";
  			this.adaptBannerAdv();
  			let originY = this.resNode.y;
  			this.resNode.y = originY + 220 + deltaY;
  			if (mgrUiBottom.checkIfUiBottomRecovery(6)) {
  				let delayTime = db.cop_db.ui_bottom_delay_time[6];
  				Timer.callLater(delayTime, () => {
  					mgrUiBottom.recordUiRecoveryTime();
  					mgrUiBottom.curInBottomViewName = "";
  					this.resNode.y = originY;
  					this.adaptBannerAdv();
  				}, this);
  			}
  		}
  		mgrSound.play(108);
  		this.playTranslation(this.resNode, "in");
  		this.fillData();
  		Advertisement.insertAdverV2();
  	}
  	dispose() {
  		mgrUiBottom.curInBottomViewName = "";
  		super.dispose();
  	}
  	fillData() {
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.context.newRoleId);
  		this.textPosition.text = roleData.name;
  	}
  	on_click_buttonThanks() {
  		this.close();
  	}
  	on_click_textPosition() {
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  }
  PanelScroll.sourceName = "ui://result/PanelScroll";

  class PanelSettlement extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "恭喜获得结算界面";
  		this.bOpenAndCloseAnim = true;
  	}
  	onLoaded() {
  		Advertisement.insertAdverV2();
  		// console.info(4444444444444444444444444444444444444444444444444444444444444);
  		mgrSound.play(110);
  		this.levelUp = this.comPa.getController("levelUp");
  		let deltaY = (Global.canvasHeight - 1024) / 2;
  		if (db.cop_db.ui_bottom_mode_switch[2]) {
  			mgrUiBottom.curInBottomViewName = "PanelSettlement";
  			this.adaptBannerAdv();
  			this.comPa.y = 778 + deltaY;
  			if (mgrUiBottom.checkIfUiBottomRecovery(2)) {
  				let delayTime = db.cop_db.ui_bottom_delay_time[2];
  				Timer.callLater(delayTime, () => {
  					mgrUiBottom.recordUiRecoveryTime();
  					mgrUiBottom.curInBottomViewName = "";
  					this.comPa.y = 603;
  					this.adaptBannerAdv();
  				}, this);
  			}
  		}
  		this.buildUi();
  		this.fillData();
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  		this.adaptComboGuide(this.buttonAd.visible);
  	}
  	dispose() {
  		mgrUiBottom.curInBottomViewName = "";
  		super.dispose();
  	}
  	adaptComboGuide(bValidAd) {
  		let bComboGuide = (!!bValidAd && db.cop_db.b_grey_mode && db.cop_db.b_grey_mode == 1) ? true : false;
  		this.groupAdComboGuide.visible = bComboGuide;
  		if (!bComboGuide) {
  			return;
  		}
  		let config = mgrAdv.getGreyModelVideoComboGuideInfo("视频奖励");
  		this.labelAdComboGuideDesc.text = config.desc;
  		this.imageAdComboChecked.visible = !!config.bDefaultChecked;
  		this.comboGuideInfo = config;
  		this.buttonOk.title = config.giveupBtnText || this.buttonOk.title;
  	}
  	doReward(bAded) {
  		let amountCoin = !!bAded ? this.baseRewardCoinAmount * 2 : this.baseRewardCoinAmount;
  		BaseFacade.mItem.addItem(2, amountCoin, "结算铜钱");
  		if (!!bAded) {
  			let grownupLine = mgrRole.getUsingGrownupLine();
  			let offsetPropertyAmount = Math.max(0, this.context[`propertyChangedAmount${grownupLine}`] || 0);
  			let currentProperty = mgrRole.getPropertyValueByGrownunLine(grownupLine);
  			currentProperty += offsetPropertyAmount;
  			mgrRole.setPropertyValueByGrownunLine(grownupLine, currentProperty);
  			let propertyRoleId = mgrRole.getCurrentPropertyRoleId();
  			mgrRole.setUsingPlayerRoleId(propertyRoleId);
  			if (offsetPropertyAmount) {
  				let g2IdDict = {
  					[1]: 101,
  					[2]: 102,
  					[3]: 103,
  					[4]: 104,
  				};
  				mgrTip.addGotItemTip(g2IdDict[grownupLine], offsetPropertyAmount * 2);
  			}
  			mgrTip.addGotItemTip(2, amountCoin, null, {
  				fOnClose: () => {
  					this.close();
  				}
  			});
  		}
  		else {
  			mgrTip.addGotItemTip(2, this.baseRewardCoinAmount, null, {
  				fOnClose: () => {
  					this.close();
  				}
  			});
  		}
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName != db.ADV_DB_ADVNAME.video_PanelSettlement_double)
  			return;
  		this.doReward(true);
  	}
  	buildUi() {
  	}
  	fillData() {
  		this.textYears.text = "第" + (mgrCrossStage.getCurrStageId() - 1) + "年";
  		if (this.context.oldRoleId == this.context.newRoleId) {
  			this.levelUp.setSelectedIndex(0);
  		}
  		else {
  			this.levelUp.setSelectedIndex(1);
  		}
  		let roleId = this.context.oldRoleId;
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(roleId);
  		this.comLowPosition.getChild("imageEndFlagNormal").visible = (roleData.maxLevelResultTimeline && roleData.maxLevelResultTimeline != "") ? true : false;
  		this.comLowPosition.getChild("textName").text = roleData.name;
  		this.comLowPosition.getChild("loaderPositionIcon").url = roleData.headIcon;
  		let propertyInfoArr = mgrRole.getSortedPropertyIndexArr(roleData.property_1, roleData.property_2, roleData.property_3, roleData.property_4);
  		let rolePropertyId = propertyInfoArr[0].propertyIndex;
  		let propertyGroup = this.comLowPosition.getChild("groupProperty1");
  		propertyGroup.visible = !!rolePropertyId;
  		if (propertyGroup.visible) {
  			let propertyIcon = this.comLowPosition.getChild("loaderIcon1");
  			let propertyText = this.comLowPosition.getChild("textAmount1");
  			let propertyData = db.get_amaze_cloth_crossing_role_property(rolePropertyId);
  			propertyIcon.url = propertyData.smallIcon;
  			propertyText.text = `${Math.max(1, roleData["property_" + rolePropertyId] || 0)}`;
  		}
  		this.comLowPosition.getChild("spriteSelected").visible = false;
  		this.comLowPosition.getChild("loaderPositionIconBg").visible = false;
  		roleId = this.context.newRoleId;
  		roleData = db.get_amaze_cloth_crossing_property_to_logic_role(roleId);
  		this.comHighPosition.getChild("imageEndFlagNormal").visible = (roleData.maxLevelResultTimeline && roleData.maxLevelResultTimeline != "") ? true : false;
  		this.comHighPosition.getChild("textName").text = roleData.name;
  		this.comHighPosition.getChild("loaderPositionIcon").url = roleData.headIcon;
  		this.comHighPosition.getChild("loaderPositionIconBg").visible = false;
  		propertyInfoArr = mgrRole.getSortedPropertyIndexArr(roleData.property_1, roleData.property_2, roleData.property_3, roleData.property_4);
  		rolePropertyId = propertyInfoArr[0].propertyIndex;
  		propertyGroup = this.comHighPosition.getChild("groupProperty1");
  		propertyGroup.visible = !!rolePropertyId;
  		if (propertyGroup.visible) {
  			let propertyIcon = this.comHighPosition.getChild("loaderIcon1");
  			let propertyText = this.comHighPosition.getChild("textAmount1");
  			let propertyData = db.get_amaze_cloth_crossing_role_property(rolePropertyId);
  			propertyIcon.url = propertyData.smallIcon;
  			propertyText.text = `${Math.max(1, roleData["property_" + rolePropertyId] || 0)}`;
  		}
  		this.comHighPosition.getChild("spriteSelected").visible = false;
  		this.textPosition.text = roleData.name;
  		for (let i = 1; i <= 4; i++) {
  			let propertyData = db.get_amaze_cloth_crossing_role_property(i);
  			let loaderIcon = this["comProp" + i].getChild("loaderIcon");
  			let textAmount = this["comProp" + i].getChild("textAmount");
  			let value = this.context["propertyChangedAmount" + i] || 0;
  			loaderIcon.url = propertyData.smallIcon;
  			textAmount.text = `${value}`;
  		}
  		let retinueAddRatio = 0;
  		let allGotPropertyValue = this.context.propertyChangedAmount1 + this.context.propertyChangedAmount2 + this.context.propertyChangedAmount3 + this.context.propertyChangedAmount4;
  		let property2CoinAmount = Math.floor(allGotPropertyValue * (1 + retinueAddRatio));
  		this.textGoodsAmount.text = property2CoinAmount + "";
  		this.textPositionAmount.text = roleData.positionResultRewardAmount + "";
  		this.baseRewardCoinAmount = Math.max(100, property2CoinAmount + roleData.positionResultRewardAmount);
  		let bTriggerAd = mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelSettlement_double);
  		if (bTriggerAd) {
  			this.buttonAd.visible = true;
  			mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelSettlement_double);
  		}
  		else {
  			this.buttonAd.visible = false;
  		}
  	}
  	on_click_buttonAd() {
  		// console.info("5555555555555555555555555555555555555");
  		mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelSettlement_double, {}, true);
  	}
  	on_click_buttonOk() {
  		if (!this.comboGuideInfo) {
  			this.doReward(false);
  			return;
  		}
  		if ((this.comboGuideInfo.bCheckedTriggerAd && this.imageAdComboChecked.visible) || (!this.imageAdComboChecked.visible && !this.comboGuideInfo.bCheckedTriggerAd)) {
  			this.on_click_buttonAd();
  		}
  		else {
  			this.doReward(false);
  		}
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  	on_click_buttonAdComboGuide() {
  		this.imageAdComboChecked.visible = !this.imageAdComboChecked.visible;
  	}
  }
  PanelSettlement.sourceName = "ui://result/PanelSettlement";

  class PanelAttendant extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "侍从界面";
  		this.adTrainCountDownTime = 10;
  		this.currRetinueIdIndex = 0;
  		this.avatarPosCameraDict = {
  			[0]: {
  				avatarData: {
  					pos: new Laya.Vector3(0, 0, 0),
  					rot: new Laya.Vector3(0, 0, 0)
  				},
  				cameraData: {
  					fov: 60,
  					pos: new Laya.Vector3(0, 1.6, 2.7),
  					rot: new Laya.Vector3(-13, 0, 0),
  				}
  			}
  		};
  	}
  	onLoaded() {
  		this.createScene3DBack(1);
  		this.cameraFollow = this.camera.getComponent(CameraFollow);
  		this.cameraFollow.lookMode = E_CAMERA_MODE.fixMode;
  		let param = this.avatarPosCameraDict[0].cameraData;
  		this.cameraFollow.position = param.pos.clone();
  		this.cameraFollow.endRotation = param.rot.clone();
  		this.cameraFollow.fov = param.fov;
  		this.cameraFollow.lerpValue = 1;
  		this.cameraFollow.onLateUpdate();
  		this.ctrlState = this.resNode.getController("c1");
  		let arr = [];
  		let dbMap = db.get_ggg_retinue_template_db_map();
  		for (let k in dbMap) {
  			arr.push(parseInt(k));
  		}
  		let templateArr = [];
  		for (let i = 0; i < arr.length; i++) {
  			const id = arr[i];
  			let template = db.get_ggg_retinue_template_db(id, 0);
  			templateArr.push(template);
  		}
  		templateArr = Tools.sortArrayByField(templateArr, "upgradeCostAmount");
  		let idArr = [];
  		for (let j = 0; j < templateArr.length; j++) {
  			const template = templateArr[j];
  			idArr.push(template.id);
  		}
  		this.retinueIdArr = idArr;
  		this.buttonPageLeft.visible = !!this.currRetinueIdIndex;
  		this.buildUi();
  		this.fillInfo();
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  		Advertisement.insertAdverV2();
  	}
  	dispose() {
  		super.dispose();
  	}
  	update() {
  		let level = mgrRetinue.getRetinueLevelById(this.getCurrShowRetinueId());
  		if (!level) {
  			return;
  		}
  		let retinueTemplate = db.get_ggg_retinue_template_db(this.getCurrShowRetinueId(), level);
  		let templateNext = db.get_ggg_retinue_template_db(this.getCurrShowRetinueId(), level + 1);
  		let count = (!!templateNext && BaseFacade.mItem.isEnoughItem(retinueTemplate.upgradeCostItemId, retinueTemplate.upgradeCostAmount)) ? 1 : 0;
  		mgrTip.showBadgeWithNumber(this.buttonTrain.displayObject, count, new Laya.Point(5, 5));
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName == db.ADV_DB_ADVNAME.video_PanelAttendant_train) {
  			let retinueId = this.getCurrShowRetinueId();
  			if (e.params && e.params.type == 2) {
  				mgrCrossStage.addFreeLevelUpDialogCount(0);
  			}
  			let result = mgrRetinue.upgradeLevel(retinueId, true);
  			mgrTip.showMsgTip(result.tipStr);
  			if (result.bSuccess && !!this.npcAvatar) {
  				let outResult = Tools.tranlateWorld3D2Screen(this.camera, new Laya.Vector3(this.npcAvatar.transform.position.x, this.npcAvatar.transform.position.y + 2, this.npcAvatar.transform.position.z));
  				this.addEffect(db.MODEL_DB_ID._130_ui_sc_shengji_01, { x: outResult.outPos.x, y: outResult.outPos.y });
  			}
  			this.adaptCurrRetinueUi();
  			this.fillInfo();
  		}
  	}
  	getCurrShowRetinueId() {
  		return this.retinueIdArr[this.currRetinueIdIndex || 0];
  	}
  	getCurrShowRetinueItemId() {
  		let template = db.get_ggg_retinue_template_db(this.getCurrShowRetinueId(), 1);
  		return template.countDownItemId || 901;
  	}
  	buildUi() {
  		this.adaptCurrRetinueUi();
  	}
  	adaptCurrRetinueUi() {
  		let level = mgrRetinue.getRetinueLevelById(this.getCurrShowRetinueId());
  		if (level > 0) {
  			this.ctrlState.setSelectedIndex(1);
  		}
  		else {
  			this.ctrlState.setSelectedIndex(0);
  			let retinueTemplate = db.get_ggg_retinue_template_db(this.getCurrShowRetinueId(), mgrRetinue.getRetinueLevelById(this.getCurrShowRetinueId()));
  			let bCanBuyToGet = (mgrCrossStage.isPlayedStage(retinueTemplate.unlcokYears)) ? true : false;
  			this.groupUnlockTip.visible = !bCanBuyToGet;
  			this.comBtns.visible = !!bCanBuyToGet;
  		}
  		if (mgrRetinue.isMaxLevel(this.getCurrShowRetinueId())) {
  			this.comTrain.visible = false;
  		}
  		else {
  			this.comTrain.visible = true;
  		}
  	}
  	doChangeRetinue(bRight) {
  		if (bRight) {
  			this.currRetinueIdIndex++;
  		}
  		else {
  			this.currRetinueIdIndex--;
  		}
  		this.currRetinueIdIndex = Tools.clamp(this.currRetinueIdIndex, 0, this.retinueIdArr.length - 1);
  		this.buttonPageLeft.visible = !!this.currRetinueIdIndex;
  		this.buttonPageRight.visible = this.currRetinueIdIndex != (this.retinueIdArr.length - 1) ? true : false;
  		this.adaptCurrRetinueUi();
  		this.fillInfo();
  	}
  	fillInfo() {
  		let retinueTemplateOneLevel = db.get_ggg_retinue_template_db(this.getCurrShowRetinueId(), 1);
  		let retinueTemplate = db.get_ggg_retinue_template_db(this.getCurrShowRetinueId(), mgrRetinue.getRetinueLevelById(this.getCurrShowRetinueId()));
  		let skillTemplate = db.get_ggg_skill_template_db(retinueTemplate.skillId);
  		let templateNext = db.get_ggg_retinue_template_db(this.getCurrShowRetinueId(), mgrRetinue.getRetinueLevelById(this.getCurrShowRetinueId()) + 1);
  		this.textName.text = retinueTemplate.name;
  		this.textCharacter.text = retinueTemplate.desc;
  		this.groupUpgradeCost.visible = false;
  		this.groupUpgradeAd.visible = false;
  		this.spritePeopleMax.visible = false;
  		if (!!templateNext) {
  			let differenceCount = templateNext.mustTriggerSkillCount - retinueTemplate.mustTriggerSkillCount;
  			let differenceCountText = differenceCount == 0 ? "" : "(+" + differenceCount + ")";
  			let differenceRatio = templateNext.triggerRatio - retinueTemplate.triggerRatio;
  			let differenceRatioText = differenceRatio == 0 ? "" : "(+" + differenceRatio + "%)";
  			let ratio = retinueTemplate.triggerRatio == 0 ? retinueTemplateOneLevel.triggerRatio : retinueTemplate.triggerRatio;
  			if (retinueTemplate.skillId != 3) {
  				this.richTextSkill2.visible = true;
  				this.richTextSkill1.text = `前${retinueTemplate.mustTriggerSkillCount}<font color="#31AE21">${differenceCountText}</font>次${skillTemplate.desc1}，`;
  				this.richTextSkill2.text = `${skillTemplate.desc2 + ratio + "%"}` + `<font color="#31AE21">${differenceRatioText}</font>免疫。`;
  			}
  			else {
  				this.richTextSkill1.text = `${ratio + "%"}<font color="#31AE21">${differenceRatioText}</font>${skillTemplate.desc1}。`;
  				this.richTextSkill2.visible = false;
  			}
  			this.groupUpgradeCost.visible = true;
  		}
  		else {
  			let ratio = retinueTemplate.triggerRatio == 0 ? retinueTemplateOneLevel.triggerRatio : retinueTemplate.triggerRatio;
  			if (retinueTemplate.skillId != 3) {
  				this.richTextSkill2.visible = true;
  				this.richTextSkill1.text = `前${retinueTemplate.mustTriggerSkillCount}${skillTemplate.desc1}，`;
  				this.richTextSkill2.text = `${skillTemplate.desc2 + ratio + "%"}免疫。`;
  			}
  			else {
  				this.richTextSkill1.text = `${ratio + "%"}${skillTemplate.desc1}。`;
  				this.richTextSkill2.visible = false;
  			}
  			this.spritePeopleMax.visible = true;
  		}
  		let currLevel = mgrRetinue.getRetinueLevelById(this.getCurrShowRetinueId());
  		this.textLevel.text = currLevel + "";
  		this.textUnlockYear.text = "【第" + retinueTemplate.unlcokYears + "年】";
  		if (mgrRetinue.followingRetinueId) {
  			if (this.getCurrShowRetinueId() == mgrRetinue.followingRetinueId) {
  				this.buttonFollow.visible = false;
  				this.spriteFollowing.visible = true;
  				this.buttonCancelFollow.visible = true;
  			}
  			else {
  				this.spriteFollowing.visible = false;
  				this.buttonCancelFollow.visible = false;
  				this.buttonFollow.visible = true;
  			}
  		}
  		else {
  			this.buttonFollow.visible = true;
  			this.spriteFollowing.visible = false;
  			this.buttonCancelFollow.visible = false;
  		}
  		this.textUpgradeCost.text = Math.floor(retinueTemplate.upgradeCostAmount).toString();
  		this.buttonCoinBuy.title = `${this.textUpgradeCost.text}雇佣`;
  		if (!!this.npcAvatar) {
  			this.npcAvatar.destroy();
  			this.npcAvatar = null;
  		}
  		this.npcAvatar = new NpcAvatar(retinueTemplate.baseRoleId);
  		this.linkModelAtBack(this.npcAvatar);
  		this.npcAvatar.registerAllLoadEndCallback(() => {
  			this.npcAvatar.playAnimationQuote(ROLE_QUOTE_MOV.movIdle4, 0, null, null, true, false);
  			if (retinueTemplate.showAniSoundIdArr && retinueTemplate.showAniSoundIdArr.length > 0) {
  				mgrSound.play(Tools.randomGotOneArrayData(retinueTemplate.showAniSoundIdArr));
  			}
  		});
  	}
  	on_click_buttonPageLeft() {
  		this.doChangeRetinue(false);
  	}
  	on_click_buttonPageRight() {
  		this.doChangeRetinue(true);
  	}
  	on_click_buttonBack() {
  		this.close();
  	}
  	on_click_buttonFollow() {
  		if (mgrRetinue.followingRetinueId) {
  			if (mgrRetinue.followingRetinueId == this.getCurrShowRetinueId()) {
  				mgrTip.showMsgTip("当前侍从已经跟随了");
  				return;
  			}
  		}
  		mgrRetinue.followingRetinueId = this.getCurrShowRetinueId();
  		this.buttonFollow.visible = false;
  		this.spriteFollowing.visible = true;
  		this.buttonCancelFollow.visible = true;
  	}
  	on_click_buttonTrain() {
  		if (!mgrCrossStage.tryShowFreeLevelUpDialog(db.ADV_DB_ADVNAME.video_PanelAttendant_train, 2)) {
  			let result = mgrRetinue.upgradeLevel(this.getCurrShowRetinueId());
  			mgrTip.showMsgTip(result.tipStr);
  			if (result.bSuccess) {
  				let outResult = Tools.tranlateWorld3D2Screen(this.camera, new Laya.Vector3(this.npcAvatar.transform.position.x, this.npcAvatar.transform.position.y + 2, this.npcAvatar.transform.position.z));
  				this.addEffect(db.MODEL_DB_ID._130_ui_sc_shengji_01, { x: outResult.outPos.x, y: outResult.outPos.y });
  			}
  		}
  		this.adaptCurrRetinueUi();
  		this.fillInfo();
  	}
  	on_click_buttonAdTrain() {
  		console.info("88888888888888888888888888888888888888888888888888888");
  		let retinueId = this.getCurrShowRetinueId();
  		// if (e.params && e.params.type == 2) {
  		// 	mgrCrossStage.addFreeLevelUpDialogCount(0);
  		// }
  		Advertisement.videop=this,
  		Advertisement.videoAdverV(()=>{
  			let result = mgrRetinue.upgradeLevel(retinueId, true);
  			mgrTip.showMsgTip(result.tipStr);
  			if (result.bSuccess && !!this.npcAvatar) {
  				let outResult = Tools.tranlateWorld3D2Screen(this.camera, new Laya.Vector3(this.npcAvatar.transform.position.x, this.npcAvatar.transform.position.y + 2, this.npcAvatar.transform.position.z));
  				this.addEffect(db.MODEL_DB_ID._130_ui_sc_shengji_01, { x: outResult.outPos.x, y: outResult.outPos.y });
  			}
  			this.adaptCurrRetinueUi();
  			this.fillInfo();
  		});
  		

  		// let result = mgrRetinue.upgradeLevel(this.getCurrShowRetinueId());
  		// let outResult = Tools.tranlateWorld3D2Screen(this.camera, new Laya.Vector3(this.npcAvatar.transform.position.x, this.npcAvatar.transform.position.y + 2, this.npcAvatar.transform.position.z));
  		// this.addEffect(db.MODEL_DB_ID._130_ui_sc_shengji_01, { x: outResult.outPos.x, y: outResult.outPos.y });
  		// this.adaptCurrRetinueUi();
  		// this.fillInfo();
  		//mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelAttendant_train, { retinueId: this.getCurrShowRetinueId() }, true);
  	}
  	on_click_buttonCancelFollow() {
  		mgrRetinue.cancelFollowingRetinue();
  		this.fillInfo();
  	}
  	on_click_buttonAdBuy() {
  		this.on_click_buttonAdTrain();
  	}
  	on_click_buttonCoinBuy() {
  		let result = mgrRetinue.upgradeLevel(this.getCurrShowRetinueId());
  		mgrTip.showMsgTip(result.tipStr);
  		if (result.bSuccess) {
  			let outResult = Tools.tranlateWorld3D2Screen(this.camera, new Laya.Vector3(this.npcAvatar.transform.position.x, this.npcAvatar.transform.position.y + 2, this.npcAvatar.transform.position.z));
  			this.addEffect(db.MODEL_DB_ID._130_ui_sc_shengji_01, { x: outResult.outPos.x, y: outResult.outPos.y });
  		}
  		this.adaptCurrRetinueUi();
  		this.fillInfo();
  	}
  }
  PanelAttendant.sourceName = "ui://retinue/PanelAttendant";

  class PanelRoleLevelDown extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "晋级失败";
  		this.PER_TIME = 1;
  	}
  	onLoaded() {
  		mgrSound.play(202);
  		this.buttonBack.title = "返回";
  		let bTriggerAd = mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelRoleLevelDown_revival);
  		this.buttonReliveAd.visible = !!bTriggerAd;
  		mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelRoleLevelDown_revival);
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  		this.comPlayerTitleContainer.visible = false;
  		this.labelDesc.y += 30;
  		this.labelPropertyStart1.text = `${this.context.startProperty1}`;
  		this.labelPropertyEnd1.text = `${this.context.currentProperty1}`;
  		this.labelPropertyStart2.text = `${this.context.startProperty2}`;
  		this.labelPropertyEnd2.text = `${this.context.currentProperty2}`;
  		this.labelPropertyStart3.text = `${this.context.startProperty3}`;
  		this.labelPropertyEnd3.text = `${this.context.currentProperty3}`;
  		this.labelPropertyStart4.text = `${this.context.startProperty4}`;
  		this.labelPropertyEnd4.text = `${this.context.currentProperty4}`;
  		let startRoleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.context.startRoleId);
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.context.roleId);
  		this.loaderPlayerTitleName1.url = roleData.nameIcon;
  		let baseRoleData = db.get_amaze_cloth_crossing_role_db(roleData.roleId);
  		GameStatistics.statisCommonEvent(baseRoleData.statisId);
  		if (!roleData.nameIcon2 || roleData.nameIcon2 == "") {
  			this.comName2.visible = false;
  		}
  		else {
  			this.loaderPlayerTitleName2.url = roleData.nameIcon2;
  		}
  		let desc = this.context.desc || "";
  		desc = desc.replace("@@", `<font color="#FF0000">${this.context.roleName || ""}</font>`);
  		this.labelDesc.text = desc;
  		let topComLinePoint1 = this.progressBarCrossTop.getChild("comLinePoint1");
  		topComLinePoint1.scaleY = -1;
  		this.loaderHeadFlag.setXY(this.comLinePoint1.x, this.comLinePoint1.y);
  		let comPlayerLvProgressFillFunc = (callback) => {
  			let progressPointDict = {
  				[1]: 24,
  				[2]: 50,
  				[3]: 76,
  			};
  			let rolePathPointArr = [
  				{ comLinePoint: this.comLinePoint1, progress: this.progressBarLevel, progressValue: progressPointDict[1] }
  			];
  			let tweenHead = cc$1.tween(this.loaderHeadFlag).toPos(0, this.comLinePoint1.x, this.comLinePoint1.y);
  			let realCrossBranchProgressDict = {
  				[0]: { progress: this.progressBarCrossDown, progressIndex2ValueArr: [36, 69] },
  				[1]: { progress: this.progressBarCrossTop, progressIndex2ValueArr: [25] }
  			};
  			let realCrossMainStartIndex = 10;
  			let realCrossMainEndIndex = 0;
  			let mainCrossArr = [];
  			mainCrossArr.push({ line: startRoleData.grownupLine, level: startRoleData.level });
  			if (roleData.grownupLine == startRoleData.grownupLine) {
  				if (roleData.level != startRoleData.level) {
  					mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level });
  					mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level + 1 });
  					realCrossMainEndIndex = 1;
  				}
  				else {
  					mainCrossArr.push({ line: startRoleData.grownupLine, level: startRoleData.level + 1 });
  					mainCrossArr.push({ line: startRoleData.grownupLine, level: startRoleData.level + 2 });
  				}
  				mainCrossArr[0].targetLine = startRoleData.grownupLine + 1;
  				mainCrossArr[1].targetLine = startRoleData.grownupLine + 2;
  			}
  			else {
  				realCrossMainStartIndex = 0;
  				if (Math.abs(roleData.level - startRoleData.level) >= 2) {
  					if (Tools.random(100) > 50) {
  						mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level - 1 });
  						mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level });
  						if (Tools.random(100) > 50) {
  							mainCrossArr[0].targetLine = roleData.grownupLine;
  						}
  						else {
  							mainCrossArr[1].targetLine = roleData.grownupLine;
  							realCrossMainStartIndex = 1;
  						}
  						realCrossMainEndIndex = 2;
  					}
  					else {
  						mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level });
  						mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level + 1 });
  						mainCrossArr[0].targetLine = roleData.grownupLine;
  						realCrossMainEndIndex = 1;
  					}
  				}
  				else {
  					mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level });
  					mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level + 1 });
  					mainCrossArr[0].targetLine = roleData.grownupLine;
  					realCrossMainEndIndex = 1;
  				}
  			}
  			for (let i = 0; i < mainCrossArr.length; i++) {
  				let corssInfo = mainCrossArr[i];
  				let comLinePoint = this["comLinePoint" + (i + 1)];
  				if (!comLinePoint) {
  					continue;
  				}
  				let loaderNameIcon1 = comLinePoint.getChild("loaderNameIcon1");
  				let loaderNameIcon2 = comLinePoint.getChild("loaderNameIcon2");
  				if (i == 0) {
  					comLinePoint.getChild("imgUnknownPoint").alpha = 0;
  					comLinePoint.getChild("imgLightPoint").alpha = 1;
  					loaderNameIcon1.alpha = 1;
  					loaderNameIcon2.alpha = 1;
  				}
  				else if (i != 0 && i <= realCrossMainEndIndex && i <= realCrossMainStartIndex) {
  					tweenHead = tweenHead
  						.call(() => {
  							this.progressBarLevel.tweenValue(progressPointDict[i + 1], this.PER_TIME);
  						})
  						.toPos(this.PER_TIME, comLinePoint.x, comLinePoint.y)
  						.call(() => {
  							loaderNameIcon1.alpha = 1;
  							loaderNameIcon2.alpha = 1;
  							comLinePoint.getChild("imgUnknownPoint").alpha = 0;
  							comLinePoint.getChild("imgLightPoint").alpha = 1;
  						});
  					console.log("-------------------------直线");
  				}
  				if (roleData.grownupLine == corssInfo.targetLine) {
  					comLinePoint.getChild("imgLightPoint").alpha = roleData.level >= corssInfo.level ? 1 : 0;
  					comLinePoint.getChild("imgUnknownPoint").alpha = 1 - comLinePoint.getChild("imgLightPoint").alpha;
  				}
  				else {
  					comLinePoint.getChild("imgUnknownPoint").alpha = 1;
  					comLinePoint.getChild("imgLightPoint").alpha = 1 - comLinePoint.getChild("imgUnknownPoint").alpha;
  				}
  				let tmpRoleData = null;
  				if (i == 0) {
  					tmpRoleData = startRoleData;
  				}
  				else {
  					tmpRoleData = mgrRole.getRoleDataByGrownlineAndLevel(corssInfo.line, corssInfo.level);
  				}
  				if (!!tmpRoleData) {
  					loaderNameIcon1.url = tmpRoleData.nameIcon;
  				}
  				if (!tmpRoleData || !tmpRoleData.nameIcon2 || tmpRoleData.nameIcon2 == "") {
  					loaderNameIcon2.visible = false;
  				}
  				else {
  					loaderNameIcon2.url = tmpRoleData.nameIcon2;
  				}
  				if (realCrossMainStartIndex == i && tmpRoleData) {
  					let progressInfo = realCrossBranchProgressDict[i];
  					let progressContainer = progressInfo.progress;
  					let progressIndex2ValueArr = progressInfo.progressIndex2ValueArr;
  					if (!!progressContainer) {
  						for (let tmp = 1; tmp < 3; tmp++) {
  							let comLinePoint = progressContainer.getChild("comLinePoint" + tmp);
  							if (!comLinePoint) {
  								break;
  							}
  							let tmpData = mainCrossArr[realCrossMainStartIndex + tmp];
  							if (!tmpData) {
  								break;
  							}
  							let level = tmpData.level;
  							let loaderNameIcon1 = comLinePoint.getChild("loaderNameIcon1");
  							let loaderNameIcon2 = comLinePoint.getChild("loaderNameIcon2");
  							if (tmp <= realCrossMainEndIndex) {
  								let tmpRoleData = mgrRole.getRoleDataByGrownlineAndLevel(roleData.grownupLine, level);
  								let imgUnknownPoint = comLinePoint.getChild("imgUnknownPoint");
  								let imgLightPoint = comLinePoint.getChild("imgLightPoint");
  								loaderNameIcon1.url = tmpRoleData.nameIcon;
  								loaderNameIcon2.url = tmpRoleData.nameIcon2;
  								imgUnknownPoint.alpha = 1;
  								imgLightPoint.alpha = 0;
  								tweenHead = tweenHead
  									.call(() => {
  										progressContainer.tweenValue(progressIndex2ValueArr[tmp - 1], this.PER_TIME);
  									});
  								let headFlagParnetNode = this.loaderHeadFlag.parent;
  								if (tmp == 1) {
  									let pathCorner = progressContainer.getChild("pathCorner");
  									let worldPos = pathCorner.localToGlobal(0, 0);
  									let localPos = headFlagParnetNode.globalToLocal(worldPos.x, worldPos.y);
  									localPos = new Laya.Point(localPos.x + headFlagParnetNode.width * headFlagParnetNode.pivotX, localPos.y + headFlagParnetNode.height * headFlagParnetNode.pivotY);
  									let worldPos2 = comLinePoint.localToGlobal(0, 0);
  									let localPos2 = headFlagParnetNode.globalToLocal(worldPos2.x, worldPos2.y);
  									localPos2 = new Laya.Point(localPos2.x + headFlagParnetNode.width * headFlagParnetNode.pivotX, localPos2.y + headFlagParnetNode.height * headFlagParnetNode.pivotY);
  									tweenHead = tweenHead
  										.toPos(this.PER_TIME * 0.4, localPos.x, localPos.y)
  										.toPos(this.PER_TIME * 0.6, localPos2.x, localPos2.y);
  									console.log("-------------------------有转角");
  								}
  								else {
  									let worldPos2 = comLinePoint.localToGlobal(0, 0);
  									let localPos2 = headFlagParnetNode.globalToLocal(worldPos2.x, worldPos2.y);
  									localPos2 = new Laya.Point(localPos2.x + headFlagParnetNode.width * headFlagParnetNode.pivotX, localPos2.y + headFlagParnetNode.height * headFlagParnetNode.pivotY);
  									tweenHead = tweenHead
  										.toPos(this.PER_TIME, localPos2.x, localPos2.y);
  									console.log("-------------------------转角后");
  								}
  								tweenHead = tweenHead
  									.call(() => {
  										loaderNameIcon1.alpha = 1;
  										loaderNameIcon2.alpha = 1;
  										imgUnknownPoint.alpha = 0;
  										imgLightPoint.alpha = 1;
  									});
  							}
  							else {
  								loaderNameIcon1.visible = false;
  								loaderNameIcon2.visible = false;
  							}
  						}
  					}
  				}
  			}
  			tweenHead
  				.call(() => {
  					callback && callback();
  				})
  				.start();
  		};
  		this.comPlayerLvProgress.alpha = 0;
  		this.resNode.getTransition("in").play();
  		Timer.callLater(0.3, () => {
  			cc$1.tween(this.comPlayerLvProgress)
  				.toAlpha(0.1, 1)
  				.call(() => {
  					comPlayerLvProgressFillFunc(() => {
  					});
  				})
  				.start();
  		}, this);
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName != db.ADV_DB_ADVNAME.video_PanelRoleLevelDown_revival)
  			return;
  		this.context.fOnConfirm(true);
  		this.close();
  	}
  	on_click_buttonReliveAd() {
  		this.context.fOnConfirm(true);
  		this.close();
  		// console.info("5555555555555555555555555555555555555");
  		mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelRoleLevelDown_revival, null, true, true);
  	}
  	on_click_buttonRestart() {
  		this.on_click_buttonBack();
  	}
  	on_click_buttonBack() {
  		this.context.fOnConfirm();
  		this.close();
  	}
  	on_click_buttonBackContent() {
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  	on_click_labelPropertyStart1() {
  	}
  	on_click_labelPropertyEnd1() {
  	}
  	on_click_labelPropertyStart2() {
  	}
  	on_click_labelPropertyEnd2() {
  	}
  	on_click_labelPropertyStart3() {
  	}
  	on_click_labelPropertyEnd3() {
  	}
  	on_click_labelPropertyStart4() {
  	}
  	on_click_labelPropertyEnd4() {
  	}
  }
  PanelRoleLevelDown.sourceName = "ui://gogogo/PanelRoleLevelDown";

  class PanelRoleLevelUp extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "晋级成功";
  		this.PER_TIME = 1;
  	}
  	onLoaded() {
  		mgrReview.tryShowReviewDialog();
  		this.buttonOk.title = "好的";
  		mgrSound.play(201);
  		this.labelPropertyStart1.text = `${this.context.startProperty1}`;
  		this.labelPropertyEnd1.text = `${this.context.currentProperty1}`;
  		this.labelPropertyStart2.text = `${this.context.startProperty2}`;
  		this.labelPropertyEnd2.text = `${this.context.currentProperty2}`;
  		this.labelPropertyStart3.text = `${this.context.startProperty3}`;
  		this.labelPropertyEnd3.text = `${this.context.currentProperty3}`;
  		this.labelPropertyStart4.text = `${this.context.startProperty4}`;
  		this.labelPropertyEnd4.text = `${this.context.currentProperty4}`;
  		let startRoleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.context.startRoleId);
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.context.roleId);
  		this.loaderPlayerTitleName1.url = roleData.nameIcon;
  		let baseRoleData = db.get_amaze_cloth_crossing_role_db(roleData.roleId);
  		GameStatistics.statisCommonEvent(baseRoleData.statisId);
  		if (!roleData.nameIcon2 || roleData.nameIcon2 == "") {
  			this.comName2.visible = false;
  		}
  		else {
  			this.loaderPlayerTitleName2.url = roleData.nameIcon2;
  		}
  		let desc = this.context.desc || "";
  		desc = desc.replace("@@", `<font color="#FF0000">${this.context.roleName || ""}</font>`);
  		this.labelDesc.text = desc;
  		let topComLinePoint1 = this.progressBarCrossTop.getChild("comLinePoint1");
  		topComLinePoint1.scaleY = -1;
  		this.loaderHeadFlag.setXY(this.comLinePoint1.x, this.comLinePoint1.y);
  		let comPlayerLvProgressFillFunc = (callback) => {
  			let progressPointDict = {
  				[1]: 24,
  				[2]: 50,
  				[3]: 76,
  			};
  			let rolePathPointArr = [
  				{ comLinePoint: this.comLinePoint1, progress: this.progressBarLevel, progressValue: progressPointDict[1] }
  			];
  			let tweenHead = cc$1.tween(this.loaderHeadFlag).toPos(0, this.comLinePoint1.x, this.comLinePoint1.y);
  			let realCrossBranchProgressDict = {
  				[0]: { progress: this.progressBarCrossDown, progressIndex2ValueArr: [36, 69] },
  				[1]: { progress: this.progressBarCrossTop, progressIndex2ValueArr: [25] }
  			};
  			let realCrossMainStartIndex = 10;
  			let realCrossMainEndIndex = 0;
  			let mainCrossArr = [];
  			mainCrossArr.push({ line: startRoleData.grownupLine, level: startRoleData.level });
  			if (roleData.grownupLine == startRoleData.grownupLine) {
  				if (roleData.level != startRoleData.level) {
  					mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level });
  					mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level + 1 });
  					realCrossMainEndIndex = 1;
  				}
  				else {
  					mainCrossArr.push({ line: startRoleData.grownupLine, level: startRoleData.level + 1 });
  					mainCrossArr.push({ line: startRoleData.grownupLine, level: startRoleData.level + 2 });
  				}
  				mainCrossArr[0].targetLine = startRoleData.grownupLine + 1;
  				mainCrossArr[1].targetLine = startRoleData.grownupLine + 2;
  			}
  			else {
  				realCrossMainStartIndex = 0;
  				if (Math.abs(roleData.level - startRoleData.level) >= 2) {
  					if (Tools.random(100) > 50) {
  						mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level - 1 });
  						mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level });
  						if (Tools.random(100) > 50) {
  							mainCrossArr[0].targetLine = roleData.grownupLine;
  						}
  						else {
  							mainCrossArr[1].targetLine = roleData.grownupLine;
  							realCrossMainStartIndex = 1;
  						}
  						realCrossMainEndIndex = 2;
  					}
  					else {
  						mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level });
  						mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level + 1 });
  						mainCrossArr[0].targetLine = roleData.grownupLine;
  						realCrossMainEndIndex = 1;
  					}
  				}
  				else {
  					mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level });
  					mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level + 1 });
  					mainCrossArr[0].targetLine = roleData.grownupLine;
  					realCrossMainEndIndex = 1;
  				}
  			}
  			for (let i = 0; i < mainCrossArr.length; i++) {
  				let corssInfo = mainCrossArr[i];
  				let comLinePoint = this["comLinePoint" + (i + 1)];
  				if (!comLinePoint) {
  					continue;
  				}
  				let loaderNameIcon1 = comLinePoint.getChild("loaderNameIcon1");
  				let loaderNameIcon2 = comLinePoint.getChild("loaderNameIcon2");
  				if (i == 0) {
  					comLinePoint.getChild("imgUnknownPoint").alpha = 0;
  					comLinePoint.getChild("imgLightPoint").alpha = 1;
  					loaderNameIcon1.alpha = 1;
  					loaderNameIcon2.alpha = 1;
  				}
  				else if (i != 0 && i <= realCrossMainEndIndex && i <= realCrossMainStartIndex) {
  					tweenHead = tweenHead
  						.call(() => {
  							this.progressBarLevel.tweenValue(progressPointDict[i + 1], this.PER_TIME);
  						})
  						.toPos(this.PER_TIME, comLinePoint.x, comLinePoint.y)
  						.call(() => {
  							loaderNameIcon1.alpha = 1;
  							loaderNameIcon2.alpha = 1;
  							comLinePoint.getChild("imgUnknownPoint").alpha = 0;
  							comLinePoint.getChild("imgLightPoint").alpha = 1;
  						});
  					console.log("-------------------------直线");
  				}
  				if (roleData.grownupLine == corssInfo.targetLine) {
  					comLinePoint.getChild("imgLightPoint").alpha = roleData.level >= corssInfo.level ? 1 : 0;
  					comLinePoint.getChild("imgUnknownPoint").alpha = 1 - comLinePoint.getChild("imgLightPoint").alpha;
  				}
  				else {
  					comLinePoint.getChild("imgUnknownPoint").alpha = 1;
  					comLinePoint.getChild("imgLightPoint").alpha = 1 - comLinePoint.getChild("imgUnknownPoint").alpha;
  				}
  				let tmpRoleData = null;
  				if (i == 0) {
  					tmpRoleData = startRoleData;
  				}
  				else {
  					tmpRoleData = mgrRole.getRoleDataByGrownlineAndLevel(corssInfo.line, corssInfo.level);
  				}
  				if (!!tmpRoleData) {
  					loaderNameIcon1.url = tmpRoleData.nameIcon;
  				}
  				if (!tmpRoleData || !tmpRoleData.nameIcon2 || tmpRoleData.nameIcon2 == "") {
  					loaderNameIcon2.visible = false;
  				}
  				else {
  					loaderNameIcon2.url = tmpRoleData.nameIcon2;
  				}
  				if (realCrossMainStartIndex == i && tmpRoleData) {
  					let progressInfo = realCrossBranchProgressDict[i];
  					let progressContainer = progressInfo.progress;
  					let progressIndex2ValueArr = progressInfo.progressIndex2ValueArr;
  					if (!!progressContainer) {
  						for (let tmp = 1; tmp < 3; tmp++) {
  							let comLinePoint = progressContainer.getChild("comLinePoint" + tmp);
  							if (!comLinePoint) {
  								break;
  							}
  							let tmpData = mainCrossArr[realCrossMainStartIndex + tmp];
  							if (!tmpData) {
  								break;
  							}
  							let level = tmpData.level;
  							let loaderNameIcon1 = comLinePoint.getChild("loaderNameIcon1");
  							let loaderNameIcon2 = comLinePoint.getChild("loaderNameIcon2");
  							if (tmp <= realCrossMainEndIndex) {
  								let tmpRoleData = mgrRole.getRoleDataByGrownlineAndLevel(roleData.grownupLine, level);
  								let imgUnknownPoint = comLinePoint.getChild("imgUnknownPoint");
  								let imgLightPoint = comLinePoint.getChild("imgLightPoint");
  								loaderNameIcon1.url = tmpRoleData.nameIcon;
  								loaderNameIcon2.url = tmpRoleData.nameIcon2;
  								imgUnknownPoint.alpha = 1;
  								imgLightPoint.alpha = 0;
  								tweenHead = tweenHead
  									.call(() => {
  										progressContainer.tweenValue(progressIndex2ValueArr[tmp - 1], this.PER_TIME);
  									});
  								let headFlagParnetNode = this.loaderHeadFlag.parent;
  								if (tmp == 1) {
  									let pathCorner = progressContainer.getChild("pathCorner");
  									let worldPos = pathCorner.localToGlobal(0, 0);
  									let localPos = headFlagParnetNode.globalToLocal(worldPos.x, worldPos.y);
  									localPos = new Laya.Point(localPos.x + headFlagParnetNode.width * headFlagParnetNode.pivotX, localPos.y + headFlagParnetNode.height * headFlagParnetNode.pivotY);
  									let worldPos2 = comLinePoint.localToGlobal(0, 0);
  									let localPos2 = headFlagParnetNode.globalToLocal(worldPos2.x, worldPos2.y);
  									localPos2 = new Laya.Point(localPos2.x + headFlagParnetNode.width * headFlagParnetNode.pivotX, localPos2.y + headFlagParnetNode.height * headFlagParnetNode.pivotY);
  									tweenHead = tweenHead
  										.toPos(this.PER_TIME * 0.4, localPos.x, localPos.y)
  										.toPos(this.PER_TIME * 0.6, localPos2.x, localPos2.y);
  									console.log("-------------------------有转角");
  								}
  								else {
  									let worldPos2 = comLinePoint.localToGlobal(0, 0);
  									let localPos2 = headFlagParnetNode.globalToLocal(worldPos2.x, worldPos2.y);
  									localPos2 = new Laya.Point(localPos2.x + headFlagParnetNode.width * headFlagParnetNode.pivotX, localPos2.y + headFlagParnetNode.height * headFlagParnetNode.pivotY);
  									tweenHead = tweenHead
  										.toPos(this.PER_TIME, localPos2.x, localPos2.y);
  									console.log("-------------------------转角后");
  								}
  								tweenHead = tweenHead
  									.call(() => {
  										loaderNameIcon1.alpha = 1;
  										loaderNameIcon2.alpha = 1;
  										imgUnknownPoint.alpha = 0;
  										imgLightPoint.alpha = 1;
  									});
  							}
  							else {
  								loaderNameIcon1.visible = false;
  								loaderNameIcon2.visible = false;
  							}
  						}
  					}
  				}
  			}
  			tweenHead
  				.call(() => {
  					callback && callback();
  				})
  				.start();
  		};
  		this.comPlayerTitleContainer.alpha = 0;
  		this.comLevelupFlag.alpha = 0;
  		this.comPlayerLvProgress.alpha = 0;
  		this.resNode.getTransition("in").play();
  		Timer.callLater(0.3, () => {
  			cc$1.tween(this.comPlayerLvProgress)
  				.toAlpha(0.1, 1)
  				.call(() => {
  					comPlayerLvProgressFillFunc(() => {
  						this.comLevelupFlag.setScale(3, 3);
  						cc$1.tween(this.comLevelupFlag).delay(0.3).toAlpha(0, 1).toScale(0.2, 1).start();
  						this.comPlayerTitleContainer.alpha = 1;
  						this.comPlayerTitleContainer.getTransition("in").play();
  					});
  				})
  				.start();
  		}, this);
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_buttonOk() {
  		this.context.fOnConfirm();
  		this.close();
  	}
  	on_click_buttonOk2() {
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  	on_click_labelPropertyStart1() {
  	}
  	on_click_labelPropertyEnd1() {
  	}
  	on_click_labelPropertyStart2() {
  	}
  	on_click_labelPropertyEnd2() {
  	}
  	on_click_labelPropertyStart3() {
  	}
  	on_click_labelPropertyEnd3() {
  	}
  	on_click_labelPropertyStart4() {
  	}
  	on_click_labelPropertyEnd4() {
  	}
  }
  PanelRoleLevelUp.sourceName = "ui://gogogo/PanelRoleLevelUp";

  class PanelStageSuccess extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "关卡成功结算";
  		this.PER_TIME = 1;
  	}
  	onLoaded() {
  		this.buttonConfirm.title = "确定";
  		this.labelPropertyStart1.text = `${this.context.startProperty1}`;
  		this.labelPropertyEnd1.text = `${this.context.currentProperty1}`;
  		this.labelPropertyStart2.text = `${this.context.startProperty2}`;
  		this.labelPropertyEnd2.text = `${this.context.currentProperty2}`;
  		this.labelPropertyStart3.text = `${this.context.startProperty3}`;
  		this.labelPropertyEnd3.text = `${this.context.currentProperty3}`;
  		this.labelPropertyStart4.text = `${this.context.startProperty4}`;
  		this.labelPropertyEnd4.text = `${this.context.currentProperty4}`;
  		let startRoleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.context.startRoleId);
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(this.context.roleId);
  		this.loaderPlayerTitleName1.url = roleData.nameIcon;
  		let baseRoleData = db.get_amaze_cloth_crossing_role_db(roleData.roleId);
  		GameStatistics.statisCommonEvent(baseRoleData.statisId);
  		if (!roleData.nameIcon2 || roleData.nameIcon2 == "") {
  			this.comName2.visible = false;
  		}
  		else {
  			this.loaderPlayerTitleName2.url = roleData.nameIcon2;
  		}
  		let desc = this.context.desc || "";
  		desc = desc.replace("@@", `<font color="#FF0000">${this.context.roleName || ""}</font>`);
  		this.labelDesc.text = desc;
  		let topComLinePoint1 = this.progressBarCrossTop.getChild("comLinePoint1");
  		topComLinePoint1.scaleY = -1;
  		this.loaderHeadFlag.setXY(this.comLinePoint1.x, this.comLinePoint1.y);
  		let comPlayerLvProgressFillFunc = (callback) => {
  			let progressPointDict = {
  				[1]: 24,
  				[2]: 50,
  				[3]: 76,
  			};
  			let rolePathPointArr = [
  				{ comLinePoint: this.comLinePoint1, progress: this.progressBarLevel, progressValue: progressPointDict[1] }
  			];
  			let tweenHead = cc$1.tween(this.loaderHeadFlag).toPos(0, this.comLinePoint1.x, this.comLinePoint1.y);
  			let realCrossBranchProgressDict = {
  				[0]: { progress: this.progressBarCrossDown, progressIndex2ValueArr: [36, 69] },
  				[1]: { progress: this.progressBarCrossTop, progressIndex2ValueArr: [25] }
  			};
  			let realCrossMainStartIndex = 10;
  			let realCrossMainEndIndex = 0;
  			let mainCrossArr = [];
  			mainCrossArr.push({ line: startRoleData.grownupLine, level: startRoleData.level });
  			if (roleData.grownupLine == startRoleData.grownupLine) {
  				if (roleData.level != startRoleData.level) {
  					mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level });
  					mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level + 1 });
  					realCrossMainEndIndex = 1;
  				}
  				else {
  					mainCrossArr.push({ line: startRoleData.grownupLine, level: startRoleData.level + 1 });
  					mainCrossArr.push({ line: startRoleData.grownupLine, level: startRoleData.level + 2 });
  				}
  				mainCrossArr[0].targetLine = startRoleData.grownupLine + 1;
  				mainCrossArr[1].targetLine = startRoleData.grownupLine + 2;
  			}
  			else {
  				realCrossMainStartIndex = 0;
  				if (Math.abs(roleData.level - startRoleData.level) >= 2) {
  					if (Tools.random(100) > 50) {
  						mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level - 1 });
  						mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level });
  						if (Tools.random(100) > 50) {
  							mainCrossArr[0].targetLine = roleData.grownupLine;
  						}
  						else {
  							mainCrossArr[1].targetLine = roleData.grownupLine;
  							realCrossMainStartIndex = 1;
  						}
  						realCrossMainEndIndex = 2;
  					}
  					else {
  						mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level });
  						mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level + 1 });
  						mainCrossArr[0].targetLine = roleData.grownupLine;
  						realCrossMainEndIndex = 1;
  					}
  				}
  				else {
  					mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level });
  					mainCrossArr.push({ line: startRoleData.grownupLine, level: roleData.level + 1 });
  					mainCrossArr[0].targetLine = roleData.grownupLine;
  					realCrossMainEndIndex = 1;
  				}
  			}
  			for (let i = 0; i < mainCrossArr.length; i++) {
  				let corssInfo = mainCrossArr[i];
  				let comLinePoint = this["comLinePoint" + (i + 1)];
  				if (!comLinePoint) {
  					continue;
  				}
  				let loaderNameIcon1 = comLinePoint.getChild("loaderNameIcon1");
  				let loaderNameIcon2 = comLinePoint.getChild("loaderNameIcon2");
  				if (i == 0) {
  					comLinePoint.getChild("imgUnknownPoint").alpha = 0;
  					comLinePoint.getChild("imgLightPoint").alpha = 1;
  					loaderNameIcon1.alpha = 1;
  					loaderNameIcon2.alpha = 1;
  				}
  				else if (i != 0 && i <= realCrossMainEndIndex && i <= realCrossMainStartIndex) {
  					tweenHead = tweenHead
  						.call(() => {
  							this.progressBarLevel.tweenValue(progressPointDict[i + 1], this.PER_TIME);
  						})
  						.toPos(this.PER_TIME, comLinePoint.x, comLinePoint.y)
  						.call(() => {
  							loaderNameIcon1.alpha = 1;
  							loaderNameIcon2.alpha = 1;
  							comLinePoint.getChild("imgUnknownPoint").alpha = 0;
  							comLinePoint.getChild("imgLightPoint").alpha = 1;
  						});
  					console.log("-------------------------直线");
  				}
  				if (roleData.grownupLine == corssInfo.targetLine) {
  					comLinePoint.getChild("imgLightPoint").alpha = roleData.level >= corssInfo.level ? 1 : 0;
  					comLinePoint.getChild("imgUnknownPoint").alpha = 1 - comLinePoint.getChild("imgLightPoint").alpha;
  				}
  				else {
  					comLinePoint.getChild("imgUnknownPoint").alpha = 1;
  					comLinePoint.getChild("imgLightPoint").alpha = 1 - comLinePoint.getChild("imgUnknownPoint").alpha;
  				}
  				let tmpRoleData = null;
  				if (i == 0) {
  					tmpRoleData = startRoleData;
  				}
  				else {
  					tmpRoleData = mgrRole.getRoleDataByGrownlineAndLevel(corssInfo.line, corssInfo.level);
  				}
  				if (!!tmpRoleData) {
  					loaderNameIcon1.url = tmpRoleData.nameIcon;
  				}
  				if (!tmpRoleData || !tmpRoleData.nameIcon2 || tmpRoleData.nameIcon2 == "") {
  					loaderNameIcon2.visible = false;
  				}
  				else {
  					loaderNameIcon2.url = tmpRoleData.nameIcon2;
  				}
  				if (realCrossMainStartIndex == i && tmpRoleData) {
  					let progressInfo = realCrossBranchProgressDict[i];
  					let progressContainer = progressInfo.progress;
  					let progressIndex2ValueArr = progressInfo.progressIndex2ValueArr;
  					if (!!progressContainer) {
  						for (let tmp = 1; tmp < 3; tmp++) {
  							let comLinePoint = progressContainer.getChild("comLinePoint" + tmp);
  							if (!comLinePoint) {
  								break;
  							}
  							let tmpData = mainCrossArr[realCrossMainStartIndex + tmp];
  							if (!tmpData) {
  								break;
  							}
  							let level = tmpData.level;
  							let loaderNameIcon1 = comLinePoint.getChild("loaderNameIcon1");
  							let loaderNameIcon2 = comLinePoint.getChild("loaderNameIcon2");
  							if (tmp <= realCrossMainEndIndex) {
  								let tmpRoleData = mgrRole.getRoleDataByGrownlineAndLevel(roleData.grownupLine, level);
  								let imgUnknownPoint = comLinePoint.getChild("imgUnknownPoint");
  								let imgLightPoint = comLinePoint.getChild("imgLightPoint");
  								loaderNameIcon1.url = tmpRoleData.nameIcon;
  								loaderNameIcon2.url = tmpRoleData.nameIcon2;
  								imgUnknownPoint.alpha = 1;
  								imgLightPoint.alpha = 0;
  								tweenHead = tweenHead
  									.call(() => {
  										progressContainer.tweenValue(progressIndex2ValueArr[tmp - 1], this.PER_TIME);
  									});
  								let headFlagParnetNode = this.loaderHeadFlag.parent;
  								if (tmp == 1) {
  									let pathCorner = progressContainer.getChild("pathCorner");
  									let worldPos = pathCorner.localToGlobal(0, 0);
  									let localPos = headFlagParnetNode.globalToLocal(worldPos.x, worldPos.y);
  									localPos = new Laya.Point(localPos.x + headFlagParnetNode.width * headFlagParnetNode.pivotX, localPos.y + headFlagParnetNode.height * headFlagParnetNode.pivotY);
  									let worldPos2 = comLinePoint.localToGlobal(0, 0);
  									let localPos2 = headFlagParnetNode.globalToLocal(worldPos2.x, worldPos2.y);
  									localPos2 = new Laya.Point(localPos2.x + headFlagParnetNode.width * headFlagParnetNode.pivotX, localPos2.y + headFlagParnetNode.height * headFlagParnetNode.pivotY);
  									tweenHead = tweenHead
  										.toPos(this.PER_TIME * 0.4, localPos.x, localPos.y)
  										.toPos(this.PER_TIME * 0.6, localPos2.x, localPos2.y);
  									console.log("-------------------------有转角");
  								}
  								else {
  									let worldPos2 = comLinePoint.localToGlobal(0, 0);
  									let localPos2 = headFlagParnetNode.globalToLocal(worldPos2.x, worldPos2.y);
  									localPos2 = new Laya.Point(localPos2.x + headFlagParnetNode.width * headFlagParnetNode.pivotX, localPos2.y + headFlagParnetNode.height * headFlagParnetNode.pivotY);
  									tweenHead = tweenHead
  										.toPos(this.PER_TIME, localPos2.x, localPos2.y);
  									console.log("-------------------------转角后");
  								}
  								tweenHead = tweenHead
  									.call(() => {
  										loaderNameIcon1.alpha = 1;
  										loaderNameIcon2.alpha = 1;
  										imgUnknownPoint.alpha = 0;
  										imgLightPoint.alpha = 1;
  									});
  							}
  							else {
  								loaderNameIcon1.visible = false;
  								loaderNameIcon2.visible = false;
  							}
  						}
  					}
  				}
  			}
  			tweenHead
  				.call(() => {
  					callback && callback();
  				})
  				.start();
  		};
  		this.comPlayerTitleContainer.alpha = 0;
  		this.comPlayerLvProgress.alpha = 0;
  		this.resNode.getTransition("in").play();
  		Timer.callLater(0.3, () => {
  			cc$1.tween(this.comPlayerLvProgress)
  				.toAlpha(0.1, 1)
  				.call(() => {
  					comPlayerLvProgressFillFunc(() => {
  						this.comPlayerTitleContainer.alpha = 1;
  						this.comPlayerTitleContainer.getTransition("in").play();
  					});
  				})
  				.start();
  		}, this);
  	}
  	dispose() {
  		super.dispose();
  	}
  	on_click_buttonConfirm() {
  		this.context.fOnConfirm && this.context.fOnConfirm();
  		this.close();
  	}
  	on_click_buttonConfirm2() {
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  	on_click_labelPropertyStart1() {
  	}
  	on_click_labelPropertyEnd1() {
  	}
  	on_click_labelPropertyStart2() {
  	}
  	on_click_labelPropertyEnd2() {
  	}
  	on_click_labelPropertyStart3() {
  	}
  	on_click_labelPropertyEnd3() {
  	}
  	on_click_labelPropertyStart4() {
  	}
  	on_click_labelPropertyEnd4() {
  	}
  }
  PanelStageSuccess.sourceName = "ui://gogogo/PanelStageSuccess";

  class CustomSettingSwitch extends CustomButton {
  	onCreate() {
  	}
  	dispose() {
  		super.dispose();
  	}
  	set state(value) {
  		this.spriteSwitchClose.visible = !value;
  		this.textClose.visible = !value;
  		this.spriteSwitchOpen.visible = value;
  		this.textOpen.visible = value;
  	}
  	get state() {
  		return this.spriteSwitchOpen.visible;
  	}
  }
  CustomSettingSwitch.sourceName = "ui://setting/CustomSettingSwitch";

  class PanelSetting extends PanelBase {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "设置界面";
  		this.bOpenAndCloseAnim = true;
  	}
  	onLoaded() {
  		this.comVideoRecord.visible = mgrChannel.haveVideoRecord();
  		this.buttonZQ.visible = db.cop_db.b_advanced_setting == 1;
  		this.buttonSwitchMusic.state = mgrSound.musicEnabled;
  		this.buttonSwitchVideo.state = mgrChannel.getUserOpenVideoRecord();
  		this.comShake.visible = mgrChannel.isSupportVibrate();
  		this.buttonSwitchShake.state = mgrChannel.vibrateEnable;
  		this.initDebug();
  		Global.registerListeners(this, {
  			[BASE_MSG.SDK_COP_CHANGED]: this.onMsgCopChange.bind(this),
  		});
  		this.kefuText.text = db.cop_db.s_kefu_text;
  	}
  	dispose() {
  		super.dispose();
  	}
  	onFocus(focus) {
  		super.onFocus(focus);
  	}
  	onInputCdkFocus() {
  	}
  	onInputCdkFocusOut() {
  	}
  	onMsgCopChange() {
  	}
  	initDebug() {
  		this.groupDebugInfo.visible = false;
  		let count = 0;
  		this.debugNode.onClick(this, () => {
  			count++;
  			if (count == 20) {
  				this.groupDebugInfo.visible = true;
  				this.debugOk.onClick(this, () => {
  					let inputStr = this.debugInput.text;
  					if (~inputStr.indexOf("ul_" + new Date().getHours())) {
  						Director.openPanel("DebugMain");
  						this.close();
  					}
  				});
  			}
  		});
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  	on_click_buttonSwitchMusic() {
  		mgrSound.musicEnabled = !this.buttonSwitchMusic.state;
  		mgrSound.soundEnabled = !this.buttonSwitchMusic.state;
  		this.buttonSwitchMusic.state = mgrSound.musicEnabled;
  	}
  	on_click_buttonSwitchVideo() {
  		mgrChannel.setUserOpenVideoRecord(!mgrChannel.getUserOpenVideoRecord());
  		this.buttonSwitchVideo.state = mgrChannel.getUserOpenVideoRecord();
  	}
  	on_click_buttonCdk() {
  	}
  	on_click_kefuText() {
  	}
  	on_click_buttonZQ() {
  		mgrSdk.openAdvancedSetting();
  	}
  	on_click_buttonSwitchShake() {
  		mgrChannel.vibrateEnable = !mgrChannel.vibrateEnable;
  		this.buttonSwitchShake.state = mgrChannel.vibrateEnable;
  	}
  	on_click_debugOk() {
  	}
  }
  PanelSetting.sourceName = "ui://setting/PanelSetting";

  class PanelSpecialStageFail2 extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "皇上留步结算失败界面";
  		this.bOpenAndCloseAnim = true;
  	}
  	onLoaded() {
  		mgrSound.play(202);
  		this.playTranslation(this.resNode, "in");
  		this.bAdv = this.resNode.getController("bAdv");
  		this.buildUi();
  		this.fillData();
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  		Advertisement.insertAdverV2();
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName == db.ADV_DB_ADVNAME.video_PanelSpecialStageFail2_ad_time) {
  			this.context.fOnConfirm && this.context.fOnConfirm();
  			this.close();
  		}
  	}
  	buildUi() {
  		let bTriggerAd = mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelSpecialStageFail2_ad_time);
  		this.buttonAdTime.visible = bTriggerAd;
  		if (bTriggerAd) {
  			mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelSpecialStageFail2_ad_time);
  		}
  		if (this.buttonAdTime.visible) {
  			this.bAdv.setSelectedIndex(1);
  		}
  		else {
  			this.bAdv.setSelectedIndex(0);
  		}
  	}
  	fillData() {
  	}
  	on_click_buttonClose() {
  		this.context.fOnCancel && this.context.fOnCancel();
  		this.close();
  	}
  	on_click_buttonGiveUp() {
  		this.on_click_buttonClose();
  	}
  	on_click_buttonAdTime() {
  		// console.info("5555555555555555555555555555555555555");
  		mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelSpecialStageFail2_ad_time);
  	}
  }
  PanelSpecialStageFail2.sourceName = "ui://special_stage/PanelSpecialStageFail2";

  class PanelSpecialStagePreview1 extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "太后的赏赐界面";
  		this.bUnlockedTipShow = false;
  	}
  	onLoaded() {
  		this.ctrlState = this.resNode.getController("c1");
  		this.bUnlockedTipShow = this.context.bUnlockedTipShow;
  		this.buildUi();
  		this.fillData();
  		mgrTip.showBadgeWithNumber(this.buttonFreeStart.displayObject, 1, new Laya.Point(5, 5));
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName == db.ADV_DB_ADVNAME.video_PanelGoGoGo_gold_challenge) {
  			this.on_click_buttonFreeStart();
  			this.adaptUnlockedUi();
  		}
  		else if (e.advName == db.ADV_DB_ADVNAME.video_PanelSpecialStagePreview1_ad_unlock) {
  			mgrChallenge.markChallengeTypeUnlocked(StageType.goldStage);
  			this.adaptUnlockedUi();
  		}
  	}
  	buildUi() {
  		if (this.bUnlockedTipShow) {
  			this.ctrlState.setSelectedIndex(0);
  			this.playTranslation(this.resNode, "in0");
  		}
  		else {
  			if (mgrChallenge.isUnlockedType(StageType.goldStage)) {
  				this.adaptUnlockedUi();
  			}
  			else {
  				let configStage = db.get_ggg_challenge_stage_config(StageType.goldStage);
  				if (mgrCrossStage.isPlayedStage(configStage.unlockYear)) {
  					this.ctrlState.setSelectedIndex(5);
  					let config = db.get_ggg_challenge_stage_config(StageType.goldStage);
  					this.buttonCoinBuyStagePassed.title = `${config.unlockCostGoldAmount}解锁`;
  				}
  				else {
  					this.ctrlState.setSelectedIndex(1);
  					this.playTranslation(this.resNode, "in1");
  					let bTriggerAd = mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelSpecialStagePreview1_ad_unlock);
  					this.buttonAdOpen.visible = bTriggerAd;
  					if (bTriggerAd) {
  						mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelSpecialStagePreview1_ad_unlock);
  					}
  					else {
  						this.buttonOk.text = "确定";
  					}
  				}
  			}
  		}
  	}
  	adaptUnlockedUi() {
  		// openPanel
  		if (mgrChallenge.getChallengeRemainCount(StageType.goldStage) > 0) {
  			this.ctrlState.setSelectedIndex(2);
  			this.playTranslation(this.resNode, "in2");
  		}
  		else {
  			if (mgrChallenge.getChallengeAdRemainCount(StageType.goldStage) > 0 && mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelGoGoGo_gold_challenge)) {
  				this.ctrlState.setSelectedIndex(3);
  				this.playTranslation(this.resNode, "in3");
  				this.buttonAdFreeStart.visible = true;
  				mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelGoGoGo_gold_challenge);
  			}
  			else {
  				this.ctrlState.setSelectedIndex(4);
  				this.playTranslation(this.resNode, "in4");
  			}
  		}
  		
  	}
  	static adaptUnlockedUi() {
  		// openPanel
  		if (mgrChallenge.getChallengeRemainCount(StageType.goldStage) > 0) {
  			this.ctrlState.setSelectedIndex(2);
  			this.playTranslation(this.resNode, "in2");
  		}
  		else {
  			if (mgrChallenge.getChallengeAdRemainCount(StageType.goldStage) > 0 && mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelGoGoGo_gold_challenge)) {
  				this.ctrlState.setSelectedIndex(3);
  				this.playTranslation(this.resNode, "in3");
  				this.buttonAdFreeStart.visible = true;
  				mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelGoGoGo_gold_challenge);
  			}
  			else {
  				this.ctrlState.setSelectedIndex(4);
  				this.playTranslation(this.resNode, "in4");
  			}
  		}
  		
  	}
  	fillData() {
  	}
  	on_click_buttonOk() {
  		this.close();
  	}
  	on_click_buttonAdOpen() {
  		console.info("88888888888888888888888888888888888888888888888888888");
  		// BaseFacade.mItem.subItem(2, config.unlockCostGoldAmount, "预览解锁特殊关卡");太后赏赐
  		// mgrChallenge.markChallengeTypeUnlocked(StageType.goldStage);
  		// this.adaptUnlockedUi();
  		Advertisement.videop=this,
  		Advertisement.videoAdverV(()=>{
  			mgrChallenge.markChallengeTypeUnlocked(StageType.goldStage);
  			this.adaptUnlockedUi();
  		});
  		// mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelSpecialStagePreview1_ad_unlock);
  	}
  	on_click_buttonConfirm() {
  		this.close();
  	}
  	on_click_buttonFreeStart() {
  		console.info("33333333333333333333333333333333333333333333333");
  		Global.sendMsg("MSG_GEN_AND_START_STAGE_NOW", { stageId: mgrChallenge.getChallengeStageId(StageType.goldStage) });
  		this.close();
  	}
  	on_click_buttonAdFreeStart() {
  		console.info("22222222222222222222222222222222222222");
  		mgrChallenge.markChallengeTypeUnlocked(StageType.goldStage);
  		this.adaptUnlockedUi();
  		mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelGoGoGo_gold_challenge);
  	}
  	on_click_buttonGrayOk() {
  		mgrTip.showMsgTip("今日次数已用尽~");
  		this.close();
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  	on_click_buttonClose2() {
  		this.close();
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  	on_click_buttonCoinBuyStagePassed() {
  		let config = db.get_ggg_challenge_stage_config(StageType.goldStage);
  		if (!!BaseFacade.mItem.isEnoughItem(2, config.unlockCostGoldAmount)) {
  			BaseFacade.mItem.subItem(2, config.unlockCostGoldAmount, "预览解锁特殊关卡");
  			mgrChallenge.markChallengeTypeUnlocked(StageType.goldStage);
  			this.adaptUnlockedUi();
  		}
  		else {
  			mgrTip.alertNotEnough(2, true);
  		}
  	}
  	on_click_buttonAdOpenStagePassed() {
  		console.info("1111111111111111111111111111111111111111");
  		this.on_click_buttonAdOpen();
  	}
  }
  PanelSpecialStagePreview1.sourceName = "ui://special_stage/PanelSpecialStagePreview1";

  class PanelSpecialStagePreview2 extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "皇上留步界面";
  		this.bUnlockedTipShow = false;
  	}
  	onLoaded() {
  		this.ctrlState = this.resNode.getController("c1");
  		this.bUnlockedTipShow = this.context.bUnlockedTipShow;
  		this.buildUi();
  		this.fillData();
  		mgrTip.showBadgeWithNumber(this.buttonFreeStart.displayObject, 1, new Laya.Point(5, 5));
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName == db.ADV_DB_ADVNAME.video_PanelGoGoGo_speed_challenge) {
  			this.on_click_buttonFreeStart();
  		}
  		else if (e.advName == db.ADV_DB_ADVNAME.video_PanelSpecialStagePreview2_ad_unlock) {
  			mgrChallenge.markChallengeTypeUnlocked(StageType.speedStage);
  			this.adaptUnlockedUi();
  		}
  	}
  	buildUi() {
  		if (this.bUnlockedTipShow) {
  			this.ctrlState.setSelectedIndex(0);
  			this.playTranslation(this.resNode, "in0");
  		}
  		else {
  			if (mgrChallenge.isUnlockedType(StageType.speedStage)) {
  				this.adaptUnlockedUi();
  			}
  			else {
  				let configStage = db.get_ggg_challenge_stage_config(StageType.speedStage);
  				if (mgrCrossStage.isPlayedStage(configStage.unlockYear)) {
  					this.ctrlState.setSelectedIndex(5);
  					let config = db.get_ggg_challenge_stage_config(StageType.speedStage);
  					this.buttonCoinBuyStagePassed.title = `${config.unlockCostGoldAmount}解锁`;
  				}
  				else {
  					this.ctrlState.setSelectedIndex(1);
  					this.playTranslation(this.resNode, "in1");
  					let bTriggerAd = mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelSpecialStagePreview2_ad_unlock);
  					this.buttonAdOpen.visible = bTriggerAd;
  					if (bTriggerAd) {
  						mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelSpecialStagePreview2_ad_unlock);
  					}
  					else {
  						this.buttonOk.text = "确定";
  					}
  				}
  			}
  		}
  	}
  	adaptUnlockedUi() {
  		if (mgrChallenge.getChallengeRemainCount(StageType.speedStage) > 0) {
  			this.ctrlState.setSelectedIndex(2);
  			this.playTranslation(this.resNode, "in2");
  		}
  		else {
  			if (mgrChallenge.getChallengeAdRemainCount(StageType.speedStage) > 0 && mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelGoGoGo_speed_challenge)) {
  				this.ctrlState.setSelectedIndex(3);
  				this.playTranslation(this.resNode, "in3");
  				this.buttonAdFreeStart.visible = true;
  				mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelGoGoGo_speed_challenge);
  			}
  			else {
  				this.ctrlState.setSelectedIndex(4);
  				this.playTranslation(this.resNode, "in4");
  			}
  		}
  	}
  	static adaptUnlockedUi() {
  		if (mgrChallenge.getChallengeRemainCount(StageType.speedStage) > 0) {
  			this.ctrlState.setSelectedIndex(2);
  			this.playTranslation(this.resNode, "in2");
  		}
  		else {
  			if (mgrChallenge.getChallengeAdRemainCount(StageType.speedStage) > 0 && mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelGoGoGo_speed_challenge)) {
  				this.ctrlState.setSelectedIndex(3);
  				this.playTranslation(this.resNode, "in3");
  				this.buttonAdFreeStart.visible = true;
  				mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelGoGoGo_speed_challenge);
  			}
  			else {
  				this.ctrlState.setSelectedIndex(4);
  				this.playTranslation(this.resNode, "in4");
  			}
  		}
  	}
  	fillData() {
  	}
  	on_click_buttonOk() {
  		this.close();
  	}
  	on_click_buttonAdOpen() {
  		console.info("8888888888888888888888888888888888888888888888888");
  		//皇上
  		Advertisement.videop=this,
  		Advertisement.videoAdverV(()=>{
  			mgrChallenge.markChallengeTypeUnlocked(StageType.speedStage);
  			this.adaptUnlockedUi();
  			mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelSpecialStagePreview2_ad_unlock);
  		});
  	}
  	on_click_buttonConfirm() {
  		this.close();
  	}
  	on_click_buttonFreeStart() {
  		Global.sendMsg("MSG_GEN_AND_START_STAGE_NOW", { stageId: mgrChallenge.getChallengeStageId(StageType.speedStage) });
  		this.close();
  	}
  	on_click_buttonAdFreeStart() {
  		mgrChallenge.markChallengeTypeUnlocked(StageType.speedStage);
  		this.adaptUnlockedUi();
  		mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelGoGoGo_speed_challenge);
  	}
  	on_click_buttonGrayOk() {
  		mgrTip.showMsgTip("今日次数已用尽~");
  		this.close();
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  	on_click_buttonClose2() {
  		this.close();
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  	on_click_buttonCoinBuyStagePassed() {
  		let config = db.get_ggg_challenge_stage_config(StageType.speedStage);
  		if (!!BaseFacade.mItem.isEnoughItem(2, config.unlockCostGoldAmount)) {
  			BaseFacade.mItem.subItem(2, config.unlockCostGoldAmount, "预览解锁特殊关卡");
  			mgrChallenge.markChallengeTypeUnlocked(StageType.speedStage);
  			this.adaptUnlockedUi();
  		}
  		else {
  			mgrTip.alertNotEnough(2, true);
  		}
  	}
  	on_click_buttonAdOpenStagePassed() {
  		this.on_click_buttonAdOpen();
  	}
  }
  PanelSpecialStagePreview2.sourceName = "ui://special_stage/PanelSpecialStagePreview2";

  class PanelSpecialStageSuccess1 extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "太后的赏赐结算成功界面";
  	}
  	onLoaded() {
  		mgrSound.play(201);
  		this.playTranslation(this.resNode, "in");
  		this.buildUi();
  		this.fillData();
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  		// Advertisement.insertAdverV2();
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName == db.ADV_DB_ADVNAME.video_PanelSpecialStageSuccess1_ad_double) {
  			this.getReward(true);
  			this.close();
  		}
  	}
  	buildUi() {
  		let bTriggerAd = mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelSpecialStageSuccess1_ad_double);
  		this.buttonAdDouble.visible = bTriggerAd;
  		if (bTriggerAd) {
  			mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelSpecialStageSuccess1_ad_double);
  		}
  	}
  	fillData() {
  		this.labelAmount.text = this.context.itemAmount.toString();
  		let itemData = db.get_item_db(this.context.itemId || 2);
  		this.loaderIcon.url = itemData.icon;
  	}
  	getReward(bDouble) {
  		let itemId = this.context.itemId || 2;
  		let amount = this.context.itemAmount;
  		amount = bDouble ? amount * 2 : amount;
  		BaseFacade.mItem.addItem(itemId, amount, "太后赏赐成功领奖");
  		Advertisement.insertAdverV2();
  	}
  	on_click_buttonClose() {
  		this.getReward();
  		this.close();
  	}
  	on_click_buttonReceived() {
  		this.getReward();
  		this.close();
  	}
  	on_click_buttonAdDouble() {
  		mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelSpecialStageSuccess1_ad_double);
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  }
  PanelSpecialStageSuccess1.sourceName = "ui://special_stage/PanelSpecialStageSuccess1";

  class PanelSpecialStageSuccess2 extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "皇上留步结算成功界面";
  	}
  	onLoaded() {
  		this.ctrlState = this.comContent.getController("c1");
  		mgrSound.play(201);
  		this.buildUi();
  		this.fillData();
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  		Advertisement.insertAdverV2();
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName == db.ADV_DB_ADVNAME.video_PanelSpecialStageSuccess2_ad_double) {
  			this.getReward(true);
  			this.close();
  		}
  	}
  	buildUi() {
  		switch (this.context.rewardSpecialType) {
  			case QuestionRewardSpecialType.GoldReward:
  				this.ctrlState.setSelectedIndex(0);
  				this.playTranslation(this.comContent, "in0");
  				this.playTranslation(this.comCoin, "in");
  				break;
  			case QuestionRewardSpecialType.ExtrnalLevelUp:
  				this.ctrlState.setSelectedIndex(2);
  				this.playTranslation(this.comContent, "in2");
  				if (mgrRole.isMaxGotPropertyExtrnalLevel()) {
  					this.resetToCoin();
  				}
  				break;
  			case QuestionRewardSpecialType.MaxPropertyReward:
  				this.ctrlState.setSelectedIndex(1);
  				this.playTranslation(this.comContent, "in1");
  				this.playTranslation(this.comValue, "in");
  				break;
  			case QuestionRewardSpecialType.RetinueLevelUp:
  				this.ctrlState.setSelectedIndex(2);
  				this.playTranslation(this.comContent, "in2");
  				this.playTranslation(this.comRetinue, "in");
  				if (mgrRetinue.isMaxLevel(mgrRetinue.followingRetinueId)) {
  					this.resetToCoin();
  				}
  				break;
  			case QuestionRewardSpecialType.PetLevelUp:
  				this.ctrlState.setSelectedIndex(3);
  				this.playTranslation(this.comContent, "in3");
  				this.playTranslation(this.comPet, "in");
  				if (mgrPet.isMaxLevel(mgrPet.followingPetId)) {
  					this.resetToCoin();
  				}
  				break;
  			default:
  				this.ctrlState.setSelectedIndex(0);
  				this.playTranslation(this.comContent, "in0");
  				break;
  		}
  		let bTriggerAd = mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelSpecialStageSuccess2_ad_double);
  		this.buttonAdDouble.visible = bTriggerAd;
  		if (bTriggerAd) {
  			mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelSpecialStageSuccess2_ad_double);
  		}
  		else {
  			this.buttonOk.title = "收下";
  		}
  		this.playBtnsAni();
  	}
  	resetToCoin() {
  		this.context.rewardSpecialType = QuestionRewardSpecialType.GoldReward;
  		this.context.rewardSpecialTypeParam = 100 + mgrRole.getCurrLevelGotPropertyExtrnalValue() + this.context.stageGotGoldAmount;
  		this.ctrlState.setSelectedIndex(0);
  		this.playTranslation(this.comContent, "in0");
  		this.playTranslation(this.comCoin, "in");
  		this.fillData();
  	}
  	playBtnsAni() {
  		this.playTranslation(this.resNode, "idle");
  		Timer.callLater(0.2, () => {
  			this.playTranslation(this.resNode, "in");
  		}, this);
  	}
  	fillData() {
  		this.textPassTime.text = Math.floor(this.context.passedTime).toString();
  		switch (this.context.rewardSpecialType) {
  			case QuestionRewardSpecialType.GoldReward:
  				this.fillCoin();
  				break;
  			case QuestionRewardSpecialType.ExtrnalLevelUp:
  				this.fillExtrnalLevel();
  				break;
  			case QuestionRewardSpecialType.MaxPropertyReward:
  				this.fillPropertyValue();
  				break;
  			case QuestionRewardSpecialType.RetinueLevelUp:
  				this.fillRetinue();
  				break;
  			case QuestionRewardSpecialType.PetLevelUp:
  				this.fillPet();
  				break;
  			default:
  				this.fillCoin();
  				break;
  		}
  	}
  	fillCoin() {
  		let comReward = this.comCoin.getChild("comReward");
  		comReward.getChild("labelAmount").text = this.context.rewardSpecialTypeParam + this.context.stageGotGoldAmount;
  		let loaderIcon = comReward.getChild("loaderIcon");
  		loaderIcon.url = db.get_item_db(2).icon;
  	}
  	fillExtrnalLevel() {
  		let currLevel = mgrRole.getCurrLevelGotPropertyExtrnalValue();
  		let nextLevel = mgrRole.getNextLevelGotPropertyExtrnalValue();
  		let roleId = mgrRole.getUsingPlayerRoleId();
  		let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(roleId);
  		let comReward = this.comRetinue.getChild("comReward");
  		comReward.getChild("title").text = " 属性等级：";
  		comReward.getChild("currLevel").text = currLevel.toString();
  		comReward.getChild("nextLevel").text = (currLevel + 1).toString();
  		let comRewardPosition = this.comRetinue.getChild("comRewardPosition");
  		comRewardPosition.getChild("positionName").text = roleData.name;
  		let loaderPosition = comRewardPosition.getChild("loaderPosition");
  		loaderPosition.url = roleData.headIcon;
  	}
  	fillPropertyValue() {
  		let [maxPropertyType, maxPropertyValue] = mgrRole.getMaxProperty();
  		let propertyData = db.get_amaze_cloth_crossing_role_property(maxPropertyType);
  		let comReward = this.comValue.getChild("comReward");
  		comReward.getChild("labelAmount").text = this.context.rewardSpecialTypeParam;
  		let loaderIcon = comReward.getChild("loaderIcon");
  		loaderIcon.url = propertyData.smallIcon;
  	}
  	fillRetinue() {
  		let currLevel = mgrRetinue.getRetinueLevelById(mgrRetinue.followingRetinueId);
  		let template = db.get_ggg_retinue_template_db(mgrRetinue.followingRetinueId, currLevel);
  		let comReward = this.comRetinue.getChild("comReward");
  		comReward.getChild("currLevel").text = currLevel.toString();
  		comReward.getChild("nextLevel").text = (currLevel + 1).toString();
  		let comRewardPosition = this.comRetinue.getChild("comRewardPosition");
  		comRewardPosition.getChild("positionName").text = template.positionName || template.name;
  		let loaderPosition = comRewardPosition.getChild("loaderPosition");
  		loaderPosition.url = template.icon;
  	}
  	fillPet() {
  		let currLevel = mgrPet.getGotPetIdLevel(mgrPet.followingPetId);
  		let template = db.get_ggg_pet_template_db(mgrPet.followingPetId, currLevel);
  		let comReward = this.comPet.getChild("comReward");
  		let comRewardPet = this.comPet.getChild("comRewardPet");
  		comRewardPet.getChild("name").text = template.name;
  		comReward.getChild("currLevel").text = currLevel.toString();
  		comReward.getChild("nextLevel").text = (currLevel + 1).toString();
  		let loaderPet = comRewardPet.getChild("loaderPet");
  		loaderPet.url = template.iconGot;
  	}
  	getReward(bDouble) {
  		if (this.context.stageGotGoldAmount && this.context.rewardSpecialType != QuestionRewardSpecialType.GoldReward) {
  			BaseFacade.mItem.addItem(2, this.context.stageGotGoldAmount, "皇帝留步关卡中捡的铜钱");
  		}
  		switch (this.context.rewardSpecialType) {
  			case QuestionRewardSpecialType.GoldReward:
  				let amountStageGot = bDouble ? this.context.stageGotGoldAmount * 2 : this.context.stageGotGoldAmount;
  				BaseFacade.mItem.addItem(2, amountStageGot, "皇帝留步关卡中捡的铜钱");
  				let amount = bDouble ? this.context.rewardSpecialTypeParam * 2 : this.context.rewardSpecialTypeParam;
  				BaseFacade.mItem.addItem(2, amount, "皇帝留步得铜钱");
  				let tipAmount = amount + amountStageGot;
  				mgrTip.addGotItemTip(2, tipAmount);
  				break;
  			case QuestionRewardSpecialType.ExtrnalLevelUp:
  				if (bDouble) {
  					mgrRole.upgradeGotPropertyExtrnalLevel();
  					mgrRole.upgradeGotPropertyExtrnalLevel();
  				}
  				else {
  					mgrRole.upgradeGotPropertyExtrnalLevel();
  				}
  				break;
  			case QuestionRewardSpecialType.MaxPropertyReward:
  				let [maxPropertyType, maxPropertyValue] = mgrRole.getMaxProperty();
  				let propertyAmount = bDouble ? this.context.rewardSpecialTypeParam * 2 : this.context.rewardSpecialTypeParam;
  				let propValueArr = [0, 0, 0, 0];
  				propValueArr[maxPropertyType - 1] = propertyAmount;
  				mgrRole.addPropertyValue(propValueArr[0], propValueArr[1], propValueArr[2], propValueArr[3]);
  				break;
  			case QuestionRewardSpecialType.RetinueLevelUp:
  				if (bDouble) {
  					mgrRetinue.upgradeLevel(mgrRetinue.followingRetinueId, true);
  					mgrRetinue.upgradeLevel(mgrRetinue.followingRetinueId, true);
  				}
  				else {
  					mgrRetinue.upgradeLevel(mgrRetinue.followingRetinueId, true);
  				}
  				break;
  			case QuestionRewardSpecialType.PetLevelUp:
  				if (bDouble) {
  					mgrPet.upgradeLevel(mgrPet.followingPetId, true);
  					mgrPet.upgradeLevel(mgrPet.followingPetId, true);
  				}
  				else {
  					mgrPet.upgradeLevel(mgrPet.followingPetId, true);
  				}
  				break;
  			default:
  				let defaultAmount = bDouble ? this.context.rewardSpecialTypeParam * 2 : this.context.rewardSpecialTypeParam;
  				BaseFacade.mItem.addItem(2, defaultAmount, "皇帝留步得铜钱");
  				mgrTip.addGotItemTip(2, defaultAmount);
  				break;
  		}
  	}
  	on_click_buttonClose() {
  		this.getReward();
  		this.close();
  	}
  	on_click_buttonOk() {
  		this.getReward();
  		this.close();
  	}
  	on_click_buttonAdDouble() {
  		// console.info("5555555555555555555555555555555555555");
  		mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelSpecialStageSuccess2_ad_double);
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  }
  PanelSpecialStageSuccess2.sourceName = "ui://special_stage/PanelSpecialStageSuccess2";

  class CustomYardBuildingListItem extends CustomComponent {
  	onCreate() {
  	}
  	dispose() {
  		super.dispose();
  	}
  }
  CustomYardBuildingListItem.sourceName = "ui://yard/CustomYardBuildingListItem";

  var Vector3$1 = Laya.Vector3;
  class Curve {
  	constructor(points) {
  		this.points = points;
  		this.points.unshift(points[0]);
  		this.points.push(points[points.length - 1]);
  	}
  	getPosition(t, out, bWorldSpace) {
  		t = Mathf.clamp01(t);
  		let numSections = this.points.length - 3;
  		if (numSections <= 0) {
  			let p = this.getPointPosition(0, bWorldSpace);
  			out.setValue(p.x, p.y, p.z);
  			return;
  		}
  		let currPt = Math.min(Math.floor(t * numSections), numSections - 1);
  		let u = t * numSections - currPt;
  		let a = this.getPointPosition(currPt, bWorldSpace);
  		let b = this.getPointPosition(currPt + 1, bWorldSpace);
  		let c = this.getPointPosition(currPt + 2, bWorldSpace);
  		let d = this.getPointPosition(currPt + 3, bWorldSpace);
  		out.x = Curve.interpolate(u, a.x, b.x, c.x, d.x);
  		out.y = Curve.interpolate(u, a.y, b.y, c.y, d.y);
  		out.z = Curve.interpolate(u, a.z, b.z, c.z, d.z);
  	}
  	static interpolate(u, a, b, c, d) {
  		return 0.5 * ((-a + 3 * b - 3 * c + d) * (u * u * u) + (2 * a - 5 * b + 4 * c - d) * (u * u) + (-a + c) * u + 2 * b);
  	}
  	getPointPosition(index, bWorldSpace) {
  		if (bWorldSpace) {
  			return this.points[index].position;
  		}
  		else {
  			return this.points[index].localPosition;
  		}
  	}
  	getLength(bWorldSpace) {
  		let points = this.points;
  		if (points.length < 3)
  			return 0;
  		let l = 0;
  		for (var i = 1; i < points.length - 2; i++) {
  			if (!points[1] || !points[i + 1]) {
  				return 0;
  			}
  			if (bWorldSpace) {
  				l += Vector3$1.distance(points[i].position, points[i + 1].position);
  			}
  			else {
  				l += Vector3$1.distance(points[i].localPosition, points[i + 1].localPosition);
  			}
  		}
  		return l;
  	}
  }

  class PanelYard extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "庭院主界面";
  		this.avatarPosCameraDict = {
  			[0]: {
  				avatarData: {
  					pos: new Laya.Vector3(0, 0, 0),
  					rot: new Laya.Vector3(0, 0, 0)
  				},
  				cameraData: {
  					fov: 85,
  					pos: new Laya.Vector3(0.38, 1.95, 3.7),
  					rot: new Laya.Vector3(-10, 2.9, 0),
  				}
  			},
  			[11]: {
  				avatarData: {
  					pos: new Laya.Vector3(0, 0, 0),
  					rot: new Laya.Vector3(0, 0, 0)
  				},
  				cameraData: {
  					fov: 85,
  					pos: new Laya.Vector3(0, 1.0, 2.7),
  					rot: new Laya.Vector3(90, 0, 0),
  				}
  			}
  		};
  		this.retinueCurveRoadDistance = 0;
  		this.retinueMovedRoadDistance = 0;
  		this.retinueMoveType = 0;
  		this.retinueLastMoveType = 0;
  		this.RETINUE_MOVE_TO_BEHIND = 1;
  		this.RETINUE_MOVE_TO_FRONT = 2;
  		this.MOVE_FPS_RETINUE = 2;
  		this.petCurveRoadDistance = 0;
  		this.petMovedRoadDistance = 0;
  		this.petMoveType = 0;
  		this.petLastMoveType = 0;
  		this.PET_MOVE_TO_BEHIND = 1;
  		this.PET_MOVE_TO_FRONT = 2;
  		this.MOVE_FPS_PET = 1;
  		this.aniArr = [ROLE_QUOTE_MOV.movResultEvent2RightUpper, ROLE_QUOTE_MOV.movResultEvent2RightLower, ROLE_QUOTE_MOV.movResultEvent5Right];
  		this.NativeVwAdv = null;
  	}
  	onLoaded() {
  		mgrYard.tryGenYardBuildingData();
  		this.buildScene(() => {
  			this.initPathPoints();
  			this.refreshBuilding();
  			this.refreshButtons();
  			this.tryComeInPet();
  			this.tryComeInRetinue();
  			let roleData = db.get_amaze_cloth_crossing_property_to_logic_role(mgrRole.getUsingPlayerRoleId());
  			let avatarPlayer = new NpcAvatar(roleData.roleId);
  			this.avatarPlayer = avatarPlayer;
  			this.avatarPlayerNode.addChild(avatarPlayer);
  			avatarPlayer.transform.localRotationEulerY = 0;
  			avatarPlayer.registerLoadEndCallback(() => {
  				this.playPlayerAni();
  			});
  			Timer.callLoop(0.016, this.onTimerLoopHandler.bind(this), this);
  			Global.registerListeners(this, {
  				[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  				["MSG_BUILDING_LEVEL_CHANGED"]: this.onMsgBuildingLevelChanged.bind(this),
  			});
  		});
  		Advertisement.insertAdverV2();
  	}
  	dispose() {
  		if (!!this.tingyuanModel && !this.tingyuanModel.destroyed) {
  			let buildingTypeArr = [YardBuildType.Event, YardBuildType.Business, YardBuildType.Gold, YardBuildType.Lottery];
  			for (let k in buildingTypeArr) {
  				let tmpType = buildingTypeArr[k];
  				let lv = mgrYard.getBuildingLvByType(tmpType);
  				let template = db.get_ggg_yard_build_template_db(tmpType, lv);
  				let buildRootNode = this.tingyuanModel.resNode.getChildByName(template.linkPoint);
  				let numChildren = buildRootNode.numChildren;
  				for (let i = 0; i < numChildren; i++) {
  					let node = buildRootNode.getChildAt(i);
  					if (Global.poolManager.isFromPool(node)) {
  						Global.poolManager.put(node);
  					}
  				}
  			}
  		}
  		if (this.tingyuanModel && !this.tingyuanModel.destroyed && this.tingyuanModel.resNode) {
  			let mapYun = this.tingyuanModel.resNode.getChildByName("yun01");
  			if (!!mapYun) {
  				cc$1.tween(mapYun.transform).stop();
  			}
  		}
  		if (!!this.avatarFollower) {
  			this.avatarFollower.destroy();
  			this.avatarFollower = null;
  		}
  		if (!!this.petFollower) {
  			this.petFollower.destroy();
  			this.petFollower = null;
  		}
  		if (!!this.tingyuanModel) {
  			Global.poolManager.put(this.tingyuanModel);
  			this.tingyuanModel = null;
  		}
  		if (!!this.avatarPlayer) {
  			this.avatarPlayer.destroy();
  			this.avatarPlayer = null;
  		}
  		super.dispose();
  	}
  	getPreLoadModels() {
  		return ["tingyuan"];
  	}
  	onFocus(bFocus) {
  		super.onFocus(bFocus);
  		if (!this.cameraFollow) {
  			return;
  		}
  	}
  	onTimerLoopHandler(timer) {
  		let dt = !!this.lastTimerTime ? Timer.time - this.lastTimerTime : 0;
  		this.lastTimerTime = Timer.time;
  		if (!!this.retinueMoveType) {
  			if (this.retinueMoveType == this.RETINUE_MOVE_TO_BEHIND) {
  				this._retinueMvoeToBehind(dt);
  			}
  			else {
  				this._retinueMvoeToFront(dt);
  			}
  		}
  		if (!!this.petMoveType) {
  			if (this.petMoveType == this.PET_MOVE_TO_BEHIND) {
  				this._petMvoeToBehind(dt);
  			}
  			else {
  				this._petMvoeToFront(dt);
  			}
  		}
  	}
  	onMsgAdvShowSuc(e) {
  	}
  	onMsgBuildingLevelChanged(e) {
  		let buildingType = e.buildingType;
  		if (!buildingType) {
  			return;
  		}
  	}
  	playPlayerAni() {
  		Timer.callLater(Tools.random(3, 15), () => {
  			if (!this.resNode || this.resNode.isDisposed) {
  				return;
  			}
  			let aniName = this.aniArr[Tools.random(0, this.aniArr.length - 1)];
  			if (aniName) {
  				this.avatarPlayer.playAnimationQuote(aniName, 0.1, null, () => {
  					this.playPlayerAni();
  				}, false);
  			}
  		}, this);
  	}
  	playEnvSound() {
  		Timer.callLater(Tools.random(5, 12), () => {
  			if (!this.resNode || this.resNode.isDisposed) {
  				return;
  			}
  			let buildingTypeArr = [YardBuildType.Event, YardBuildType.Business, YardBuildType.Gold, YardBuildType.Lottery];
  			let buildingType = Tools.randomGotOneArrayData(buildingTypeArr);
  			let lv = mgrYard.getBuildingLvByType(buildingType);
  			let template = db.get_ggg_yard_build_template_db(buildingType, lv);
  			if (template.evnSoundIdArr && template.evnSoundIdArr.length > 0) {
  				mgrSound.play(Tools.randomGotOneArrayData(template.evnSoundIdArr));
  				this.playEnvSound();
  			}
  		}, this);
  	}
  	refreshButtons() {
  		let count = (mgrYard.getUnhandledEventIdCount() > 0) ? 1 : 0;
  		mgrTip.showBadgeWithNumber(this.buttonEvent.guiNode.displayObject, count, new Laya.Point(20, 20));
  		count = (mgrYard.getUnhandledBusinessCount() > 0) ? 1 : 0;
  		mgrTip.showBadgeWithNumber(this.buttonBusiness.guiNode.displayObject, count, new Laya.Point(20, 20));
  		count = (mgrYard.getGoldOutputCount() > 10) ? 1 : 0;
  		mgrTip.showBadgeWithNumber(this.buttonGold.guiNode.displayObject, count, new Laya.Point(20, 20));
  		count = (mgrYard.getLotteryRemainCount() + mgrYard.getAdLotteryRemainCount()) ? 1 : 0;
  		mgrTip.showBadgeWithNumber(this.buttonLottery.guiNode.displayObject, count, new Laya.Point(20, 20));
  		count = mgrYard.hasCanUpgradeBuilding() ? 1 : 0;
  		mgrTip.showBadgeWithNumber(this.buttonBuildingLvup.guiNode.displayObject, count, new Laya.Point(5, 20));
  	}
  	buildScene(callback) {
  		let tingyuanModel = Global.poolManager.get(Model, "tingyuan");
  		this.tingyuanModel = tingyuanModel;
  		this.linkModelAtBack(this.tingyuanModel);
  		this.avatarPlayerNode = new Laya.Sprite3D;
  		this.linkModelAtBack(this.avatarPlayerNode);
  		let playerHolder = tingyuanModel.resNode.getChildByName("Guandian_player");
  		this.avatarPlayerNode.transform.localRotationEuler = playerHolder.transform.localRotationEuler.clone();
  		this.avatarPlayerNode.transform.position = playerHolder.transform.position.clone();
  		this.avatarFollowerNode = new Laya.Sprite3D;
  		this.linkModelAtBack(this.avatarFollowerNode);
  		let retinueHolder = tingyuanModel.resNode.getChildByName("retinue_path").getChildAt(0);
  		this.avatarFollowerNode.transform.position = retinueHolder.transform.position.clone();
  		this.petFollowerNode = new Laya.Sprite3D;
  		this.linkModelAtBack(this.petFollowerNode);
  		let mapYun = this.tingyuanModel.resNode.getChildByName("yun01");
  		if (!!mapYun) {
  			cc$1.tween(mapYun.transform, true)
  				.repeatForever(cc$1.tween().byLocalRotationEuler3D(30, 0, 10, 0))
  				.start();
  		}
  		this.camera.farPlane = 500;
  		this.cameraFollow = this.camera.getComponent(CameraFollow);
  		this.cameraFollow.lookMode = E_CAMERA_MODE.fixMode;
  		let param = this.avatarPosCameraDict[0].cameraData;
  		this.cameraFollow.position = param.pos.clone();
  		this.cameraFollow.endRotation = param.rot.clone();
  		this.cameraFollow.fov = param.fov;
  		this.cameraFollow.lerpValue = 1;
  		this.cameraFollow.onLateUpdate();
  		callback && callback();
  	}
  	initPathPoints() {
  		this.initRetinuePathPoints();
  		this.initPetPathPoints();
  	}
  	initRetinuePathPoints() {
  		let resNode = this.tingyuanModel.resNode;
  		let retinue_path = resNode.getChildByName("retinue_path");
  		let roadCurveTransformArr = [];
  		let curveChildrenNum = retinue_path.numChildren;
  		for (let tmpIndex = 0; tmpIndex < curveChildrenNum; tmpIndex++) {
  			let transform = retinue_path.getChildAt(tmpIndex).transform;
  			roadCurveTransformArr.push(transform);
  		}
  		this.retinueCurve = new Curve(roadCurveTransformArr);
  		let tmpCurvePosArr = [];
  		let count = roadCurveTransformArr.length * 10;
  		for (let i = 0; i < count; i++) {
  			let tmpPos = new Laya.Vector3;
  			this.retinueCurve.getPosition(i / count, tmpPos, true);
  			tmpCurvePosArr.push(tmpPos);
  		}
  		let roadCurvePosArr = [];
  		let l = 0;
  		let preposition = null;
  		for (let tmpIndex = 0; tmpIndex < tmpCurvePosArr.length; tmpIndex++) {
  			let position = tmpCurvePosArr[tmpIndex].clone();
  			let len = 0;
  			if (preposition) {
  				len = Laya.Vector3.distance(preposition, position);
  			}
  			roadCurvePosArr.push({ position: position, len: len });
  			l += len;
  			preposition = position;
  		}
  		this.retinueRoadCurvePosArr = roadCurvePosArr;
  		this.retinueCurveRoadDistance = l;
  	}
  	initPetPathPoints() {
  		let resNode = this.tingyuanModel.resNode;
  		let retinue_path = resNode.getChildByName("pet_path");
  		let roadCurveTransformArr = [];
  		let curveChildrenNum = retinue_path.numChildren;
  		for (let tmpIndex = 0; tmpIndex < curveChildrenNum; tmpIndex++) {
  			let transform = retinue_path.getChildAt(tmpIndex).transform;
  			roadCurveTransformArr.push(transform);
  		}
  		this.petCurve = new Curve(roadCurveTransformArr);
  		let tmpCurvePosArr = [];
  		let count = roadCurveTransformArr.length * 10;
  		for (let i = 0; i < count; i++) {
  			let tmpPos = new Laya.Vector3;
  			this.petCurve.getPosition(i / count, tmpPos, true);
  			tmpCurvePosArr.push(tmpPos);
  		}
  		let roadCurvePosArr = [];
  		let l = 0;
  		let preposition = null;
  		for (let tmpIndex = 0; tmpIndex < tmpCurvePosArr.length; tmpIndex++) {
  			let position = tmpCurvePosArr[tmpIndex].clone();
  			let len = 0;
  			if (preposition) {
  				len = Laya.Vector3.distance(preposition, position);
  			}
  			roadCurvePosArr.push({ position: position, len: len });
  			l += len;
  			preposition = position;
  		}
  		this.petRoadCurvePosArr = roadCurvePosArr;
  		this.petCurveRoadDistance = l;
  	}
  	resetRetinueMoveStatus() {
  		if (!mgrRetinue.followingRetinueId) {
  			return;
  		}
  		let bFirst = false;
  		if (!this.retinueLastMoveType && !this.retinueMoveType) {
  			bFirst = true;
  			this.retinueLastMoveType = Tools.randomGotOneArrayData([this.RETINUE_MOVE_TO_BEHIND, this.RETINUE_MOVE_TO_FRONT]);
  			if (this.retinueLastMoveType == this.RETINUE_MOVE_TO_BEHIND) {
  				this.avatarFollowerNode.transform.position = this.retinueRoadCurvePosArr[this.retinueRoadCurvePosArr.length - 1].position.clone();
  			}
  			else {
  				this.avatarFollowerNode.transform.position = this.retinueRoadCurvePosArr[0].position.clone();
  			}
  		}
  		else {
  			this.retinueLastMoveType = this.retinueMoveType;
  		}
  		this.retinueMoveType = 0;
  		this.retinueMovedRoadDistance = 0;
  		this.avatarFollower.transform.localRotationEulerY = 0;
  		this.avatarFollowerNode.transform.localRotationEuler = new Laya.Vector3(0, -18, 0);
  		this.avatarFollower.playAnimationQuote(ROLE_QUOTE_MOV.movIdle, 0, null, null, true, false);
  		let delay = !bFirst ? Tools.random(8, 15) : 1;
  		Timer.callLater(delay, () => {
  			if (!this.retinueLastMoveType) {
  				this.retinueMoveType = Tools.randomGotOneArrayData([this.RETINUE_MOVE_TO_BEHIND, this.RETINUE_MOVE_TO_FRONT]);
  			}
  			else {
  				this.retinueMoveType = this.retinueLastMoveType == this.RETINUE_MOVE_TO_BEHIND ? this.RETINUE_MOVE_TO_FRONT : this.RETINUE_MOVE_TO_BEHIND;
  			}
  			if (this.retinueMoveType == this.RETINUE_MOVE_TO_FRONT) {
  				this.retinueMovedRoadDistance = this.retinueCurveRoadDistance;
  			}
  			else {
  				this.avatarFollower.transform.localRotationEulerY = 180;
  			}
  			this.avatarFollower.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  		}, this);
  	}
  	_retinueMvoeToBehind(deltaTime) {
  		let useFps = this.MOVE_FPS_RETINUE;
  		let dis = Math.min(deltaTime * useFps, 0.01 * useFps);
  		this.retinueMovedRoadDistance += dis;
  		let currRotY = this.avatarFollowerNode.transform.localRotationEulerY;
  		let tmpPos = this.avatarFollowerNode.transform.position.clone();
  		if (this.retinueMovedRoadDistance >= this.retinueCurveRoadDistance) {
  			tmpPos = this.retinueRoadCurvePosArr[this.retinueRoadCurvePosArr.length - 1].position.clone();
  			this.resetRetinueMoveStatus();
  			return;
  		}
  		else {
  			let tmpMoveLen = 0;
  			for (let i = 1; i < this.retinueRoadCurvePosArr.length; i++) {
  				let dataPre = this.retinueRoadCurvePosArr[i - 1];
  				let dataNext = this.retinueRoadCurvePosArr[i];
  				let nextLen = tmpMoveLen + dataNext.len;
  				if (nextLen > this.retinueMovedRoadDistance) {
  					let tmpT = (this.retinueMovedRoadDistance - tmpMoveLen) / dataNext.len;
  					Laya.Vector3.lerp(dataPre.position.clone(), dataNext.position.clone(), tmpT, tmpPos);
  					let rotY = Tools.getAngle(dataPre.position.x, dataPre.position.z, dataNext.position.x, dataNext.position.z);
  					let diffRotY = Math.abs(rotY - currRotY);
  					if (diffRotY <= 0.01) {
  						currRotY = rotY;
  					}
  					else if (rotY > currRotY) {
  						currRotY += diffRotY * 0.1;
  					}
  					else {
  						currRotY -= diffRotY * 0.1;
  					}
  					break;
  				}
  				else {
  					tmpMoveLen += dataNext.len;
  				}
  			}
  		}
  		this.avatarFollowerNode.transform.position = tmpPos;
  		this.avatarFollowerNode.transform.localRotationEulerY = currRotY;
  	}
  	_retinueMvoeToFront(deltaTime) {
  		let useFps = this.MOVE_FPS_RETINUE;
  		let dis = Math.min(deltaTime * useFps, 0.01 * useFps);
  		this.retinueMovedRoadDistance -= dis;
  		let currRotY = this.avatarFollowerNode.transform.localRotationEulerY;
  		let tmpPos = this.avatarFollowerNode.transform.position.clone();
  		if (this.retinueMovedRoadDistance <= 0) {
  			tmpPos = this.retinueRoadCurvePosArr[0].position.clone();
  			this.resetRetinueMoveStatus();
  			return;
  		}
  		else {
  			let tmpMoveLen = 0;
  			for (let i = (this.retinueRoadCurvePosArr.length - 2); i >= 0; i--) {
  				let dataPre = this.retinueRoadCurvePosArr[i + 1];
  				let dataNext = this.retinueRoadCurvePosArr[i];
  				let nextLen = tmpMoveLen + dataNext.len;
  				let realMoved = this.retinueCurveRoadDistance - this.retinueMovedRoadDistance;
  				if (nextLen > realMoved) {
  					let tmpT = (realMoved - tmpMoveLen) / dataNext.len;
  					Laya.Vector3.lerp(dataPre.position.clone(), dataNext.position.clone(), tmpT, tmpPos);
  					let rotY = Tools.getAngle(dataNext.position.x, dataNext.position.z, dataPre.position.x, dataPre.position.z);
  					let diffRotY = Math.abs(rotY - currRotY);
  					if (diffRotY <= 0.01) {
  						currRotY = rotY;
  					}
  					else if (rotY > currRotY) {
  						currRotY += diffRotY * 0.1;
  					}
  					else {
  						currRotY -= diffRotY * 0.1;
  					}
  					break;
  				}
  				else {
  					tmpMoveLen += dataNext.len;
  				}
  			}
  		}
  		this.avatarFollowerNode.transform.position = tmpPos;
  		this.avatarFollowerNode.transform.localRotationEulerY = currRotY;
  	}
  	resetPetMoveStatus() {
  		if (!mgrPet.followingPetId) {
  			return;
  		}
  		let bFirst = false;
  		if (!this.petLastMoveType && !this.petMoveType) {
  			bFirst = true;
  			this.petLastMoveType = Tools.randomGotOneArrayData([this.PET_MOVE_TO_BEHIND, this.PET_MOVE_TO_FRONT]);
  			if (this.petLastMoveType == this.PET_MOVE_TO_BEHIND) {
  				this.petFollowerNode.transform.position = this.petRoadCurvePosArr[this.petRoadCurvePosArr.length - 1].position.clone();
  			}
  			else {
  				this.petFollowerNode.transform.position = this.petRoadCurvePosArr[0].position.clone();
  			}
  		}
  		else {
  			this.petLastMoveType = this.petMoveType;
  		}
  		this.petMoveType = 0;
  		this.petMovedRoadDistance = 0;
  		this.petFollower.transform.localRotationEulerY = 0;
  		this.petFollowerNode.transform.localRotationEuler = new Laya.Vector3;
  		this.petFollower.playAnimationQuote(ROLE_QUOTE_MOV.movIdle, 0, null, null, true, false);
  		let delay = !bFirst ? Tools.random(8, 15) : 2;
  		Timer.callLater(delay, () => {
  			if (!this.petLastMoveType) {
  				this.petMoveType = Tools.randomGotOneArrayData([this.PET_MOVE_TO_BEHIND, this.PET_MOVE_TO_FRONT]);
  			}
  			else {
  				this.petMoveType = this.petLastMoveType == this.PET_MOVE_TO_BEHIND ? this.PET_MOVE_TO_FRONT : this.PET_MOVE_TO_BEHIND;
  			}
  			if (this.petMoveType == this.PET_MOVE_TO_FRONT) {
  				this.petMovedRoadDistance = this.petCurveRoadDistance;
  			}
  			else {
  				this.petFollower.transform.localRotationEulerY = 180;
  			}
  			this.petFollower.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  		}, this);
  	}
  	_petMvoeToBehind(deltaTime) {
  		let useFps = this.MOVE_FPS_PET;
  		let dis = Math.min(deltaTime * useFps, 0.01 * useFps);
  		this.petMovedRoadDistance += dis;
  		let currRotY = this.petFollowerNode.transform.localRotationEulerY;
  		let tmpPos = this.petFollowerNode.transform.position.clone();
  		if (this.petMovedRoadDistance >= this.petCurveRoadDistance) {
  			tmpPos = this.petRoadCurvePosArr[this.petRoadCurvePosArr.length - 1].position.clone();
  			this.resetPetMoveStatus();
  			return;
  		}
  		else {
  			let tmpMoveLen = 0;
  			for (let i = 1; i < this.petRoadCurvePosArr.length; i++) {
  				let dataPre = this.petRoadCurvePosArr[i - 1];
  				let dataNext = this.petRoadCurvePosArr[i];
  				let nextLen = tmpMoveLen + dataNext.len;
  				if (nextLen > this.petMovedRoadDistance) {
  					let tmpT = (this.petMovedRoadDistance - tmpMoveLen) / dataNext.len;
  					Laya.Vector3.lerp(dataPre.position.clone(), dataNext.position.clone(), tmpT, tmpPos);
  					let rotY = Tools.getAngle(dataPre.position.x, dataPre.position.z, dataNext.position.x, dataNext.position.z);
  					let diffRotY = Math.abs(rotY - currRotY);
  					if (diffRotY <= 0.01) {
  						currRotY = rotY;
  					}
  					else if (rotY > currRotY) {
  						currRotY += diffRotY * 0.1;
  					}
  					else {
  						currRotY -= diffRotY * 0.1;
  					}
  					break;
  				}
  				else {
  					tmpMoveLen += dataNext.len;
  				}
  			}
  		}
  		this.petFollowerNode.transform.position = tmpPos;
  		this.petFollowerNode.transform.localRotationEulerY = currRotY;
  	}
  	_petMvoeToFront(deltaTime) {
  		let useFps = this.MOVE_FPS_PET;
  		let dis = Math.min(deltaTime * useFps, 0.01 * useFps);
  		this.petMovedRoadDistance -= dis;
  		let currRotY = this.petFollowerNode.transform.localRotationEulerY;
  		let tmpPos = this.petFollowerNode.transform.position.clone();
  		if (this.petMovedRoadDistance <= 0) {
  			tmpPos = this.petRoadCurvePosArr[0].position.clone();
  			this.resetPetMoveStatus();
  			return;
  		}
  		else {
  			let tmpMoveLen = 0;
  			for (let i = (this.petRoadCurvePosArr.length - 2); i >= 0; i--) {
  				let dataPre = this.petRoadCurvePosArr[i + 1];
  				let dataNext = this.petRoadCurvePosArr[i];
  				let nextLen = tmpMoveLen + dataNext.len;
  				let realMoved = this.petCurveRoadDistance - this.petMovedRoadDistance;
  				if (nextLen > realMoved) {
  					let tmpT = (realMoved - tmpMoveLen) / dataNext.len;
  					Laya.Vector3.lerp(dataPre.position.clone(), dataNext.position.clone(), tmpT, tmpPos);
  					let rotY = Tools.getAngle(dataNext.position.x, dataNext.position.z, dataPre.position.x, dataPre.position.z);
  					let diffRotY = Math.abs(rotY - currRotY);
  					if (diffRotY <= 0.01) {
  						currRotY = rotY;
  					}
  					else if (rotY > currRotY) {
  						currRotY += diffRotY * 0.1;
  					}
  					else {
  						currRotY -= diffRotY * 0.1;
  					}
  					break;
  				}
  				else {
  					tmpMoveLen += dataNext.len;
  				}
  			}
  		}
  		this.petFollowerNode.transform.position = tmpPos;
  		this.petFollowerNode.transform.localRotationEulerY = currRotY;
  	}
  	tryComeInRetinue() {
  		if (!!mgrRetinue.followingRetinueId) {
  			let retinueLevel = mgrRetinue.getRetinueLevelById(mgrRetinue.followingRetinueId);
  			let retinueData = db.get_ggg_retinue_template_db(mgrRetinue.followingRetinueId, retinueLevel);
  			let avatarFollower = new NpcAvatar(retinueData.baseRoleId);
  			this.avatarFollower = avatarFollower;
  			this.avatarFollowerNode.addChild(avatarFollower);
  			avatarFollower.transform.localPosition = new Laya.Vector3;
  			avatarFollower.registerLoadEndCallback(() => {
  				avatarFollower.playAnimationQuote(ROLE_QUOTE_MOV.movIdle, 0, null, null, true, false);
  				this.resetRetinueMoveStatus();
  			});
  		}
  	}
  	tryComeInPet() {
  		if (!!mgrPet.followingPetId && mgrPet.followingPetId != 10104) {
  			let petLevel = mgrPet.getGotPetIdLevel(mgrPet.followingPetId);
  			let petData = db.get_ggg_pet_template_db(mgrPet.followingPetId, petLevel);
  			if (petData.yardLinkPoint && petData.yardLinkPoint != "") {
  				let petHolder = this.tingyuanModel.resNode.getChildByName(petData.yardLinkPoint);
  				this.petFollowerNode.transform.position = petHolder.transform.position.clone();
  			}
  			else {
  				let petHolder = this.tingyuanModel.resNode.getChildByName("pet_path").getChildAt(0);
  				this.petFollowerNode.transform.position = petHolder.transform.position.clone();
  			}
  			let petFollower = new NpcAvatar(petData.baseRoleId);
  			this.petFollower = petFollower;
  			this.petFollowerNode.addChild(petFollower);
  			petFollower.transform.localPosition = new Laya.Vector3;
  			petFollower.registerLoadEndCallback(() => {
  				petFollower.playAnimationQuote(ROLE_QUOTE_MOV.movIdle, 0, null, null, true, false);
  				if (mgrPet.followingPetId == 10101 || mgrPet.followingPetId == 10102) {
  					this.resetPetMoveStatus();
  				}
  			});
  		}
  	}
  	refreshBuilding(buildingType, buildingTypeLv) {
  		let buildingTypeArr = [YardBuildType.Event, YardBuildType.Business, YardBuildType.Gold, YardBuildType.Lottery];
  		for (let k in buildingTypeArr) {
  			let tmpType = buildingTypeArr[k];
  			if (!!buildingType && tmpType != buildingType) {
  				continue;
  			}
  			let lv = !!buildingType ? buildingTypeLv : mgrYard.getBuildingLvByType(tmpType);
  			lv = lv || mgrYard.getBuildingLvByType(tmpType);
  			let template = db.get_ggg_yard_build_template_db(tmpType, lv);
  			let buildRootNode = this.tingyuanModel.resNode.getChildByName(template.linkPoint);
  			let numChildren = buildRootNode.numChildren;
  			for (let i = 0; i < numChildren; i++) {
  				let node = buildRootNode.getChildAt(i);
  				if (Global.poolManager.isFromPool(node)) {
  					Global.poolManager.put(node);
  				}
  				else {
  					node.active = false;
  				}
  			}
  			for (let kkk in template.childNameArr) {
  				let node = buildRootNode.getChildByName(template.childNameArr[kkk]);
  				if (!node) {
  					continue;
  				}
  				node.active = true;
  			}
  			for (let k in template.effectLoopArr) {
  				let name = template.effectLoopArr[k];
  				this.linkModelAtBack(name, buildRootNode);
  			}
  		}
  	}
  	on_click_buttonEvent() {
  		let count = mgrYard.getUnhandledEventIdCount();
  		if (count <= 0) {
  			mgrTip.showMsgTip("暂时没有需要处理的事件");
  			return;
  		}
  		let _changeCameraFunc = (bShowStage) => {
  			let param = null;
  			if (bShowStage) {
  				param = this.avatarPosCameraDict[0].cameraData;
  			}
  			else {
  				param = this.avatarPosCameraDict[11].cameraData;
  			}
  			this.cameraFollow.endRotation = param.rot.clone();
  			this.cameraFollow.onLateUpdate();
  		};
  		_changeCameraFunc(false);
  		Director.openPanel("PanelYardEvent", {
  			fOnClose: () => {
  				this.refreshButtons();
  				_changeCameraFunc(true);
  			}
  		});
  	}
  	on_click_buttonBusiness() {
  		let count = mgrYard.getUnhandledBusinessCount();
  		if (count <= 0) {
  			mgrTip.showMsgTip("暂时没有需要处理的公务");
  			return;
  		}
  		Director.openPanel("PanelYardBusiness", {
  			fOnClose: () => {
  				this.refreshButtons();
  			}
  		});
  	}
  	on_click_buttonGold() {
  		Director.openPanel("PanelYardGold", {
  			fOnClose: () => {
  				this.refreshButtons();
  			}
  		});
  	}
  	on_click_buttonLottery() {
  		Director.openPanel("PanelYardLottery", {
  			fOnClose: () => {
  				this.refreshButtons();
  			}
  		});
  	}
  	on_click_buttonBuildingLvup() {
  		Director.openPanel("PanelYardBuildingLvup", {
  			fOnClose: () => {
  				this.refreshButtons();
  			},
  			fOnUpgradeBuild: (successUpgradeBuildingIdDict) => {
  				if (!successUpgradeBuildingIdDict || Tools.getObjSize(successUpgradeBuildingIdDict) <= 0) {
  					return;
  				}
  				Timer.callLater(1, () => {
  					if (!this.resNode || this.resNode.isDisposed) {
  						return;
  					}
  					let gap = 0.5;
  					let delay = 0;
  					for (let k in successUpgradeBuildingIdDict) {
  						let buildingId = parseInt(k);
  						let lvArr = successUpgradeBuildingIdDict[k];
  						for (let i = 0; i < lvArr.length; i++) {
  							Timer.callLater(delay, () => {
  								if (!this.resNode || this.resNode.isDisposed) {
  									return;
  								}
  								let lv = lvArr[i];
  								let template = db.get_ggg_yard_build_template_db(buildingId, lv);
  								if (template.effectLvupOnce && template.effectLvupOnce != "") {
  									let buildRootNode = this.tingyuanModel.resNode.getChildByName(template.linkPoint);
  									this.linkModelAtBack(template.effectLvupOnce, null, null, 3, buildRootNode.transform.position.clone());
  								}
  								this.refreshBuilding(buildingId, lv);
  							}, this);
  							delay += gap;
  						}
  					}
  				}, this);
  			}
  		});
  	}
  	on_click_buttonBack() {
  		PanelWarpWithAnim.warp("PanelGoGoGo");
  	}
  }
  PanelYard.sourceName = "ui://yard/PanelYard";

  class PanelYardBuildingLvup extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "庭院建筑升级界面";
  		this.buildingIdArr = [];
  		this.bShowUiAni = false;
  		this.successUpgradeBuildingIdDict = {};
  	}
  	onLoaded() {
  		let arr = [];
  		let dbMap = db.get_ggg_yard_build_template_db_map();
  		for (let k in dbMap) {
  			arr.push(parseInt(k));
  		}
  		this.buildingIdArr = arr;
  		this.buildUi();
  		this.fillData();
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  		Advertisement.insertAdverV2();
  	}
  	dispose() {
  		super.dispose();
  	}
  	getPreLoadModels() {
  		let modelIds = [];
  		return modelIds;
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName == db.ADV_DB_ADVNAME.video_PanelYardBuildingLvup_lvup) {
  			mgrCrossStage.addFreeLevelUpDialogCount(3);
  			this.doUpgrade(true);
  		}
  	}
  	doUpgrade(bAd) {
  		let buildingId = this.curBuildingId;
  		let result = mgrYard.upgradeLevel(buildingId, bAd);
  		mgrTip.showMsgTip(result.tipStr);
  		this.listYardBuilding.numItems = this.buildingIdArr.length;
  		if (result.bSuccess) {
  			let lv = mgrYard.getBuildingLvByType(buildingId);
  			this.successUpgradeBuildingIdDict[buildingId] = this.successUpgradeBuildingIdDict[buildingId] || [];
  			this.successUpgradeBuildingIdDict[buildingId].push(lv);
  			Director.openPanel("PanelYardSurprise", { buildingId: buildingId });
  		}
  	}
  	buildUi() {
  	}
  	fillData() {
  		this.listYardBuilding.itemRenderer = new Laya.Handler(this, (idx, obj) => {
  			obj.visible = false;
  			obj[`idx`] = idx;
  			let buildingId = this.buildingIdArr[idx];
  			obj[`buildingId`] = buildingId;
  			let currLevel = mgrYard.getBuildingLvByType(buildingId);
  			let template = db.get_ggg_yard_build_template_db(buildingId, currLevel);
  			let templateNext = db.get_ggg_yard_build_template_db(buildingId, currLevel + 1);
  			let bMax = mgrYard.isMaxLevel(buildingId);
  			let buildingLevelTemplateArr = [];
  			let dbMap = db.get_ggg_yard_build_template_db_map();
  			let tmpDataLevels = dbMap[buildingId];
  			for (let kkk in tmpDataLevels) {
  				buildingLevelTemplateArr.push(tmpDataLevels[kkk]);
  			}
  			buildingLevelTemplateArr = Tools.sortArrayByField(buildingLevelTemplateArr, ["level"]);
  			for (let i = 0; i < buildingLevelTemplateArr.length; i++) {
  				let tmpData = buildingLevelTemplateArr[i];
  				let loader = obj.getChild("loaderBuildingLv" + tmpData.level);
  				if (!!loader) {
  					loader.url = currLevel >= tmpData.level ? tmpData.icon : tmpData.iconLocked;
  					loader.alpha = currLevel >= tmpData.level ? 1 : 0.6;
  				}
  			}
  			obj.getChild("textCoinAmount").text = template.upgradeCostAmount ? template.upgradeCostAmount.toString() : "";
  			obj.getChild("comCostDecree").getChild("labelCostDecree").text = template.upgradeCostAmount2 ? template.upgradeCostAmount2.toString() : "";
  			obj.getChild("spriteMax").visible = !!bMax;
  			let buttonAdUpgrade = obj.getChild("buttonAdUpgrade");
  			let groupCoinUpgrade = obj.getChild("groupCoinUpgrade");
  			let buttonUpgrade = obj.getChild("buttonUpgrade");
  			let comCostDecree = obj.getChild("comCostDecree");
  			let imageCurrLv = obj.getChild("imageCurrLv");
  			let loaderBuildingLv = obj.getChild("loaderBuildingLv" + currLevel) || obj.getChild("loaderBuildingLv" + 1);
  			let loaderBuildingLvNext = obj.getChild("loaderBuildingLv" + (currLevel + 1)) || obj.getChild("loaderBuildingLv" + 5);
  			imageCurrLv.x = loaderBuildingLv.x;
  			comCostDecree.x = loaderBuildingLvNext.x;
  			imageCurrLv.visible = currLevel > 0 ? true : false;
  			if (!!templateNext) {
  				if (this.adLvupBuildingInfo && this.adLvupBuildingInfo.buildingId == buildingId && this.adLvupBuildingInfo.lv == currLevel) {
  					buttonAdUpgrade.visible = true;
  					groupCoinUpgrade.visible = false;
  					comCostDecree.visible = false;
  				}
  				else {
  					buttonAdUpgrade.visible = false;
  					groupCoinUpgrade.visible = true;
  					comCostDecree.visible = true;
  					let count = 0;
  					let res = mgrYard.testCanUpgradeLevel(buildingId, false);
  					if (res && res.bSuccess) {
  						count = 1;
  					}
  					mgrTip.showBadgeWithNumber(buttonUpgrade.displayObject, count, new Laya.Point(5, 5));
  				}
  			}
  			else {
  				comCostDecree.visible = false;
  				buttonAdUpgrade.visible = false;
  				groupCoinUpgrade.visible = false;
  			}
  			if (!this.bShowUiAni) {
  				let time = 0.1 * idx;
  				Timer.callLater(time, (timer) => {
  					obj.visible = true;
  					this.playTranslation(obj, "in", new Laya.Handler(this, () => {
  						timer.stop();
  						timer = null;
  					}));
  				}, obj);
  				if (idx == this.listYardBuilding.numItems - 1) {
  					this.bShowUiAni = true;
  				}
  			}
  			else {
  				obj.visible = true;
  			}
  			UiHelper.unregisterTouchEvent(buttonUpgrade);
  			UiHelper.registerTouchEvent(buttonUpgrade, this.onClickButtonUpgrade.bind(this, obj, buildingId));
  		});
  		this.listYardBuilding.numItems = this.buildingIdArr.length;
  	}
  	onClickButtonUpgrade(obj, buildingId, e) {
  		if (!e.bClick) {
  			return;
  		}
  		if (obj.buildingId == buildingId) {
  			let nodePos = obj.parent.localToGlobal(obj.x, obj.y);
  			this.curNodePos = nodePos;
  			this.curBuildingId = buildingId;
  			if (mgrCrossStage.tryShowFreeLevelUpDialog(db.ADV_DB_ADVNAME.video_PanelYardBuildingLvup_lvup, 3)) {
  			}
  			else {
  				this.doUpgrade();
  			}
  		}
  	}
  	on_click_buttonClose() {
  		this.context.fOnUpgradeBuild && this.context.fOnUpgradeBuild(this.successUpgradeBuildingIdDict);
  		this.close();
  	}
  }
  PanelYardBuildingLvup.sourceName = "ui://yard/PanelYardBuildingLvup";

  class PanelYardBusiness extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "庭院公务界面";
  	}
  	onLoaded() {
  		this.imageAnswerResult1.alpha = 0;
  		this.imageAnswerResult2.alpha = 0;
  		this.refreshEvent();
  		this.playTranslation(this.resNode, "in");
  		Advertisement.insertAdverV2();
  	}
  	dispose() {
  		super.dispose();
  	}
  	refreshEvent() {
  		this.imageAnswerResult1.alpha = 0;
  		this.imageAnswerResult2.alpha = 0;
  		let buildLv = mgrYard.getBuildingLvByType(YardBuildType.Business);
  		let templateBusinessBuilding = db.get_ggg_yard_build_template_db(YardBuildType.Business, buildLv);
  		let count = mgrYard.getUnhandledBusinessCount();
  		this.labelRemainDesc.text = `待批阅公务：${count}/${templateBusinessBuilding.businessMaxCount}`;
  		if (count <= 0) {
  			return;
  		}
  		this.currentYardEventQuestionId = mgrYard.getCurrUnhandledBusinessQuestiond();
  		let questionData = db.get_amaze_cloth_crossing_question_db(this.currentYardEventQuestionId);
  		this.labelDesc.text = `${questionData.wordQuestion}`;
  		this.bCurrQuestionSwapAnswer = Tools.random(100) > 50 ? true : false;
  		let word1 = !this.bCurrQuestionSwapAnswer ? questionData.wordAnswer1 : questionData.wordAnswer2;
  		let word2 = !this.bCurrQuestionSwapAnswer ? questionData.wordAnswer2 : questionData.wordAnswer1;
  		this.buttonAnswer1.text = `${word1}`;
  		this.buttonAnswer2.text = `${word2}`;
  		this.groupBtns.visible = true;
  		let rightCount2ProgressDict = {
  			[0]: 0,
  			[1]: 33,
  			[2]: 65,
  			[3]: 100,
  		};
  		let progress = rightCount2ProgressDict[mgrYard.getOwnedPrestige() || 0];
  		this.progressBarGotPrestige.value = progress || 0;
  	}
  	onClickButtonAnswer(index) {
  		this.currentYardEventQuestionId = mgrYard.getCurrUnhandledBusinessQuestiond();
  		let questionData = db.get_amaze_cloth_crossing_question_db(this.currentYardEventQuestionId);
  		GameStatistics.statisCommonEvent(questionData.statisPointId, index == 1 ? 1 : 0);
  		mgrYard.markUnhandledBusinessHandledOnce();
  		let bRight = index == 1 ? true : false;
  		let tryShowNextFunc = () => {
  			let count = mgrYard.getUnhandledBusinessCount();
  			if (count <= 0) {
  				mgrTip.alertPrompt("公务处理完毕", "提示", () => {
  					this.close();
  				});
  				return;
  			}
  			this.refreshEvent();
  		};
  		let callback = () => {
  			if (bRight) {
  				mgrYard.addOwnedPrestige(1);
  				mgrTip.showMsgTip("威望+1");
  				let count = mgrYard.exchangeDecreeCount();
  				if (count > 0) {
  					mgrTip.addGotItemTip(4, count, null, {
  						fOnClose: () => {
  							tryShowNextFunc();
  						}
  					});
  					return;
  				}
  				else if (BaseFacade.mItem.getItemAmount(4) >= 10) {
  					mgrTip.showMsgTip("政令已达最大数量");
  				}
  			}
  			Timer.callLater(0.5, () => {
  				tryShowNextFunc();
  			}, this);
  		};
  		this.groupBtns.visible = false;
  		this.imageAnswerResult1.alpha = !!bRight ? 1 : 0;
  		this.imageAnswerResult2.alpha = 1 - this.imageAnswerResult1.alpha;
  		if (bRight) {
  			this.imageAnswerResult1.setScale(3, 3);
  			cc$1.tween(this.imageAnswerResult1, true).toScale(0.3, 1)
  				.call(() => {
  					callback();
  				})
  				.start();
  		}
  		else {
  			this.imageAnswerResult2.setScale(3, 3);
  			cc$1.tween(this.imageAnswerResult2, true).toScale(0.3, 1)
  				.call(() => {
  					callback();
  				})
  				.start();
  		}
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  	on_click_buttonAnswer1() {
  		this.onClickButtonAnswer(!this.bCurrQuestionSwapAnswer ? 1 : 2);
  	}
  	on_click_buttonAnswer2() {
  		this.onClickButtonAnswer(!this.bCurrQuestionSwapAnswer ? 2 : 1);
  	}
  }
  PanelYardBusiness.sourceName = "ui://yard/PanelYardBusiness";

  class PanelYardEvent extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "庭院事件界面";
  		this.EVENT_LEVEL_2_IMG_DICT = {
  			[0]: "res/yard_event_level/1event.png",
  			[1]: "res/yard_event_level/1event.png",
  			[2]: "res/yard_event_level/2event.png",
  			[3]: "res/yard_event_level/3event.png",
  			[4]: "res/yard_event_level/4event.png",
  			[5]: "res/yard_event_level/5event.png",
  		};
  		this.avatarPosCameraDict = {
  			[0]: {
  				avatarData: {
  					pos: new Laya.Vector3(0, 0, 0),
  					rot: new Laya.Vector3(0, 0, 0)
  				},
  				cameraData: {
  					fov: 60,
  					pos: new Laya.Vector3(0, 1.86, 11.06),
  					rot: new Laya.Vector3(-16, 0, 0),
  				}
  			},
  			[11]: {
  				avatarData: {
  					pos: new Laya.Vector3(0, 0, 0),
  					rot: new Laya.Vector3(0, 0, 0)
  				},
  				cameraData: {
  					fov: 60,
  					pos: new Laya.Vector3(0, 1.0, 2.7),
  					rot: new Laya.Vector3(90, 0, 0),
  				}
  			}
  		};
  	}
  	onLoaded() {
  		this.comEventerAnswer.setScale(0, 0);
  		this.comEventQuestion.setScale(0, 0);
  		this.buildScene(() => {
  			this.refreshPlayerProperty();
  			this.refreshEvent();
  		});
  		Advertisement.insertAdverV2();
  	}
  	dispose() {
  		if (!!this.avatarPlayer) {
  			this.avatarPlayer.destroy();
  			this.avatarPlayer = null;
  		}
  		if (!!this.shufangModel) {
  			Global.poolManager.put(this.shufangModel);
  			this.shufangModel = null;
  		}
  		super.dispose();
  	}
  	buildScene(callback) {
  		this.mapStage = new Laya.Sprite3D;
  		this.linkModelAtBack(this.mapStage);
  		let model = Global.poolManager.get(Model, "shufang");
  		this.linkModelAtBack(model);
  		this.shufangModel = model;
  		this.avatarPlayerNode = new Laya.Sprite3D;
  		this.linkModelAtBack(this.avatarPlayerNode);
  		this.avatarPlayerNode.transform.localPosition = new Laya.Vector3(0, 0, 7.23);
  		this.avatarPlayerNode["_originPos"] = this.avatarPlayerNode.transform.localPosition.clone();
  		this.cameraFollow = this.camera.getComponent(CameraFollow);
  		this.cameraFollow.lookMode = E_CAMERA_MODE.fixMode;
  		let param = this.avatarPosCameraDict[0].cameraData;
  		this.cameraFollow.position = param.pos.clone();
  		this.cameraFollow.endRotation = param.rot.clone();
  		this.cameraFollow.fov = param.fov;
  		this.cameraFollow.lerpValue = 1;
  		this.cameraFollow.onLateUpdate();
  		callback && callback();
  	}
  	refreshPlayerProperty(forcePropertyIndex, count) {
  		this.currentProperty1 = mgrRole.getProperty1();
  		this.currentProperty2 = mgrRole.getProperty2();
  		this.currentProperty3 = mgrRole.getProperty3();
  		this.currentProperty4 = mgrRole.getProperty4();
  		let maxPropertyIndex = mgrRole.getUsingGrownupLine();
  		let refreshOnePorperty = (pIndex, value) => {
  			let com = this["comProperty" + pIndex];
  			let point = com.getChild("point");
  			point.text = `${value}`;
  		};
  		let refreshMaxStatus = () => {
  			for (let i = 1; i <= 4; i++) {
  				let pIndex = i;
  				let com = this["comProperty" + pIndex];
  				let point = com.getChild("point");
  				if (pIndex == maxPropertyIndex) {
  					com.getChild("maxBg").visible = true;
  					com.getChild("maxCountBg").visible = true;
  					point.color = "#FFF17E";
  				}
  				else {
  					com.getChild("maxBg").visible = false;
  					com.getChild("maxCountBg").visible = false;
  					point.color = "#FFFFFF";
  				}
  			}
  		};
  		if (!!forcePropertyIndex) {
  			refreshOnePorperty(forcePropertyIndex, count);
  			refreshMaxStatus();
  			return;
  		}
  		for (let i = 1; i <= 4; i++) {
  			let value = this["currentProperty" + i];
  			refreshOnePorperty(i, value);
  		}
  		refreshMaxStatus();
  	}
  	refreshEvent() {
  		let count = mgrYard.getUnhandledEventIdCount();
  		this.labelRemainDesc.text = `待处理事件：${count}`;
  		this.comEventerAnswer.setScale(0, 0);
  		if (count <= 0) {
  			return;
  		}
  		this.currentYardEventQuestionId = mgrYard.getCurrUnhandledEventQuestiond();
  		let buildLv = mgrYard.getBuildingLvByType(YardBuildType.Event);
  		this.loaderLevel.url = this.EVENT_LEVEL_2_IMG_DICT[buildLv];
  		let questionData = db.get_amaze_cloth_crossing_question_db(this.currentYardEventQuestionId);
  		this.labelEventerQuestionDesc.text = `${questionData.wordQuestion}`;
  		let roleData = db.get_amaze_cloth_crossing_role_db(questionData.relationRoleId);
  		this.labelEventerName.text = `${roleData.name}`;
  		this.bCurrQuestionSwapAnswer = Tools.random(100) > 50 ? true : false;
  		let word1 = !this.bCurrQuestionSwapAnswer ? questionData.wordAnswer1 : questionData.wordAnswer2;
  		let word2 = !this.bCurrQuestionSwapAnswer ? questionData.wordAnswer2 : questionData.wordAnswer1;
  		this.buttonAnswer1.text = `${word1}`;
  		this.buttonAnswer2.text = `${word2}`;
  		let originPos = this.avatarPlayerNode["_originPos"];
  		cc$1.tween(this.avatarPlayerNode.transform).stop();
  		this.avatarPlayerNode.transform.localPosition = new Laya.Vector3(originPos.x, originPos.y, 3);
  		if (!!this.avatarPlayer) {
  			this.avatarPlayer.destroy();
  			this.avatarPlayer = null;
  		}
  		let avatarPlayer = new NpcAvatar(questionData.relationRoleId);
  		this.avatarPlayer = avatarPlayer;
  		this.avatarPlayerNode.addChild(avatarPlayer);
  		avatarPlayer.registerLoadEndCallback(() => {
  			avatarPlayer.playAnimationQuote(ROLE_QUOTE_MOV.movWalk, 0, null, null, true, false);
  			cc$1.tween(this.avatarPlayerNode.transform)
  				.toLocalPos3D(2, originPos.x, originPos.y, originPos.z)
  				.call(() => {
  					avatarPlayer.playAnimationQuote(ROLE_QUOTE_MOV.movYardEvent1, 0, null, () => {
  						avatarPlayer.playAnimationQuote(ROLE_QUOTE_MOV.movYardEvent2, 0, null, null, true, false);
  						this.comEventQuestion.setScale(1, 1);
  						this.buttonAnswer1.setScale(0, 0);
  						this.buttonAnswer2.setScale(0, 0);
  						cc$1.tween(this.buttonAnswer1).toScale(0.1, 1).start();
  						cc$1.tween(this.buttonAnswer2).toScale(0.1, 1).start();
  					}, false, false);
  				})
  				.start();
  		});
  	}
  	onClickButtonAnswer(index) {
  		let lv = mgrYard.getBuildingLvByType(YardBuildType.Event);
  		let template = db.get_ggg_yard_build_template_db(YardBuildType.Event, lv);
  		let questionData = db.get_amaze_cloth_crossing_question_db(this.currentYardEventQuestionId);
  		let sureScoreIndex = index;
  		let surePropertyIndex = mgrRole.getUsingGrownupLine();
  		let surePropertyAmount = !questionData["answerScore" + sureScoreIndex] ? 0 : Math.ceil(((questionData["answerScore" + sureScoreIndex] || 0) + mgrRole.getCurrLevelGotPropertyExtrnalValue()) * (questionData.answerScoreRatio || 1) * (mgrYard.getEventRewardPropertyRatioPerHandle()));
  		this.labelEventerAnswer.text = `${questionData["wordAnsweredTip" + index]}`;
  		GameStatistics.statisCommonEvent(questionData.statisPointId, index == 1 ? 1 : 0);
  		mgrYard.markUnhandledEventHandledOnce();
  		cc$1.tween(this.comEventQuestion, true).toScale(0.1, 0)
  			.call(() => {
  				this.avatarPlayer.playAnimationQuote(ROLE_QUOTE_MOV.movYardEvent3, 0, null, () => {
  					this.avatarPlayer.playIdle();
  				}, false, false);
  			})
  			.delay(0.5)
  			.call(() => {
  				cc$1.tween(this.comEventerAnswer, true).toScale(0.15, 1)
  					.delay(0.8)
  					.call(() => {
  						Director.openPanel("PanelYardEventReward", {
  							propertyIndex: surePropertyIndex,
  							propertyAmount: surePropertyAmount,
  							fOnClose: () => {
  								let count = mgrYard.getUnhandledEventIdCount();
  								if (count <= 0) {
  									mgrTip.alertPrompt("事件处理完毕", "提示", () => {
  										this.close();
  									});
  									return;
  								}
  								this.refreshPlayerProperty();
  								this.refreshEvent();
  							}
  						});
  					})
  					.start();
  			})
  			.start();
  	}
  	on_click_buttonAnswer1() {
  		this.onClickButtonAnswer(!this.bCurrQuestionSwapAnswer ? 1 : 2);
  	}
  	on_click_buttonAnswer2() {
  		this.onClickButtonAnswer(!this.bCurrQuestionSwapAnswer ? 2 : 1);
  	}
  	on_click_buttonBack() {
  		this.close();
  	}
  }
  PanelYardEvent.sourceName = "ui://yard/PanelYardEvent";

  class PanelYardEventReward extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "庭院事件奖励界面";
  	}
  	onLoaded() {
  		this.buttonAdDouble.visible = mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelYardEventReward_double);
  		if (this.buttonAdDouble.visible) {
  			mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelYardEventReward_double);
  		}
  		this.loaderPropertyIcon.url = PROPERTY_2_TARGET_ICON_DICT[this.context.propertyIndex];
  		this.labelPropertyAmount.text = `+${this.context.propertyAmount}`;
  		this.labelGoldAmount.text = `+${mgrYard.getEventRewardGoldPerHandle()}`;
  		this.playTranslation(this.resNode, "in");
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  		Advertisement.insertAdverV2();
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName == db.ADV_DB_ADVNAME.video_PanelYardEventReward_double) {
  			this.doReward(true);
  		}
  	}
  	doReward(bAd) {
  		let grownupLine = mgrRole.getUsingGrownupLine();
  		let offsetPropertyAmount = Math.max(0, this.context.propertyAmount || 0);
  		let currentProperty = mgrRole.getPropertyValueByGrownunLine(grownupLine);
  		currentProperty += offsetPropertyAmount;
  		mgrRole.setPropertyValueByGrownunLine(grownupLine, currentProperty);
  		let propertyRoleId = mgrRole.getCurrentPropertyRoleId();
  		mgrRole.setUsingPlayerRoleId(propertyRoleId);
  		if (offsetPropertyAmount) {
  			let g2IdDict = {
  				[1]: 101,
  				[2]: 102,
  				[3]: 103,
  				[4]: 104,
  			};
  			mgrTip.addGotItemTip(g2IdDict[grownupLine], offsetPropertyAmount * 2);
  		}
  		let rewardGold = mgrYard.getEventRewardGoldPerHandle();
  		if (rewardGold > 0) {
  			BaseFacade.mItem.addItem(2, !!bAd ? 2 * rewardGold : rewardGold, "庭院事件奖励");
  			mgrTip.addGotItemTip(2, !!bAd ? 2 * rewardGold : rewardGold, null, {
  				fOnClose: () => {
  					this.close();
  				}
  			});
  		}
  		else {
  			this.close();
  		}
  	}
  	on_click_buttonClose() {
  		this.on_click_buttonReceived();
  	}
  	on_click_buttonReceived() {
  		this.doReward();
  	}
  	on_click_buttonAdDouble() {
  		// console.info("5555555555555555555555555555555555555");
  		mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelYardEventReward_double);
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  }
  PanelYardEventReward.sourceName = "ui://yard/PanelYardEventReward";

  class PanelYardGold extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "庭院聚宝盆界面";
  	}
  	onLoaded() {
  		this.refreshGold();
  		Timer.callLoop(1, () => {
  			this.refreshGold();
  		}, this);
  		this.buttonAdDouble.visible = mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelYardGold_double);
  		if (this.buttonAdDouble.visible) {
  			mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelYardGold_double);
  		}
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  		let count = mgrYard.getGoldOutputCount();
  		this.groupBtns.visible = count > 0 ? true : false;
  		this.playTranslation(this.resNode, "in");
  		Advertisement.insertAdverV2();
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName == db.ADV_DB_ADVNAME.video_PanelYardGold_double) {
  			this.doReward(true);
  		}
  	}
  	doReward(bAd) {
  		let count = mgrYard.receiveGoldOutput();
  		mgrTip.addGotItemTip(2, !!bAd ? 2 * count : count);
  		this.close();
  	}
  	refreshGold() {
  		let amount = mgrYard.getGoldOutputCount();
  		let time = Timer.time - mgrYard.getLastGoldOutputTime();
  		let timeStr = Tools.formatTime(time);
  		this.labelGoldAmount.text = `+${amount}`;
  		this.labelTotalTime.text = `${timeStr}`;
  	}
  	on_click_buttonClose() {
  		this.close();
  	}
  	on_click_buttonReceived() {
  		this.doReward();
  	}
  	on_click_buttonAdDouble() {
  		// console.info("5555555555555555555555555555555555555");
  		mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelYardGold_double);
  	}
  	on_click_buttonNativeBannerGo() {
  	}
  }
  PanelYardGold.sourceName = "ui://yard/PanelYardGold";

  class PanelYardLevelUp extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "升级成功提示";
  	}
  	onLoaded() {
  		this.addEffect(db.MODEL_DB_ID._130_ui_once_levp_cw, { x: Global.canvasWidth / 2, y: Global.canvasHeight / 2 });
  		Timer.callLater(1.5, () => {
  			this.close();
  		}, this);
  		this.playTranslation(this.resNode, "in");
  	}
  	dispose() {
  		super.dispose();
  	}
  }
  PanelYardLevelUp.sourceName = "ui://yard/PanelYardLevelUp";

  class PanelYardLottery extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "庭院转盘界面";
  		this.LOTTERY_NUM = 10;
  	}
  	onLoaded() {
  		this.comPlate.touchable = false;
  		this.labelLevel.text = `${mgrYard.getBuildingLvByType(YardBuildType.Lottery)}`;
  		this.refreshLotteryUi();
  		this.comProperty1.visible = false;
  		this.comProperty2.visible = false;
  		this.comProperty3.visible = false;
  		this.comProperty4.visible = false;
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  		this.playTranslation(this.resNode, "in");
  		Advertisement.insertAdverV2();
  	}
  	dispose() {
  		super.dispose();
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName == db.ADV_DB_ADVNAME.video_PanelYardLottery_lottery) {
  			if (this.bLotterying) {
  				return;
  			}
  			this.doLottery();
  		}
  	}
  	genLotteryItems() {
  		let maxPropertyData = mgrRole.getMaxProperty();
  		let index2ItemIdDict = {
  			[1]: 101,
  			[2]: 102,
  			[3]: 103,
  			[4]: 104
  		};
  		let propertyItemId = index2ItemIdDict[maxPropertyData[0]];
  		let lotteryItemTemplate = mgrYard.getLotteryItemInfo();
  		let arr = [];
  		for (let i = 0; i < this.LOTTERY_NUM; i++) {
  			let item = lotteryItemTemplate["item" + (i + 1)];
  			let itemId = item[0];
  			let configAmount = Tools.random(item[1], item[2]);
  			let amount = 0;
  			if (itemId == 4) {
  				amount = Math.max(0, configAmount);
  			}
  			else {
  				if (itemId < 0) {
  					itemId = propertyItemId;
  				}
  				amount = Math.ceil((configAmount + mgrRole.getCurrLevelGotPropertyExtrnalValue()) * (mgrYard.getLotteryItemRatio() || 1));
  			}
  			arr.push({ itemId: itemId, amount: amount });
  		}
  		this.currTurnLotteryItemArr = arr;
  	}
  	refreshLotteryUi() {
  		this.genLotteryItems();
  		let adCount = mgrYard.getAdLotteryRemainCount();
  		let normalCount = mgrYard.getLotteryRemainCount();
  		let totalCount = adCount + normalCount;
  		if (normalCount > 0) {
  			this.labelRemainCount.text = `剩余次数：${normalCount}`;
  		}
  		else if (adCount > 0) {
  			this.labelRemainCount.text = `免费转动`;
  		}
  		else {
  			this.labelRemainCount.text = `明日再来`;
  		}
  		mgrTip.showBadgeWithNumber(this.buttonLottery.displayObject, totalCount, new Laya.Point(5, 5));
  		this.buttonLottery.visible = normalCount > 0 ? true : false;
  		this.buttonNoCount.visible = totalCount <= 0 ? true : false;
  		this.buttonLotteryAd.visible = (normalCount <= 0 && adCount > 0 && mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelYardLottery_lottery)) ? true : false;
  		if (this.buttonLotteryAd.visible) {
  			mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelYardLottery_lottery);
  		}
  		for (let i = 0; i < this.LOTTERY_NUM; i++) {
  			let item = this.currTurnLotteryItemArr[i];
  			let itemTemplate = db.get_item_db(item.itemId);
  			this["loaderItem" + (i + 1)].url = itemTemplate.icon;
  			this["labelAmount" + (i + 1)].text = `+${item.amount}`;
  		}
  		cc$1.tween(this.imageRotBorder).stop();
  		this.imageRotBorder.alpha = 0;
  	}
  	doLottery() {
  		let byRot = 360 * 6 + Tools.random(this.LOTTERY_NUM) * (360 / this.LOTTERY_NUM) + (!this.bLotteryOnce ? (360 / this.LOTTERY_NUM) / 2 : 0);
  		let dur = 3;
  		this.bLotteryOnce = true;
  		this.bLotterying = true;
  		let rotNode = this.comPlate;
  		cc$1.tween(rotNode)
  			.byRotation(dur, byRot, cc$1.Ease.cubicInOut)
  			.call(() => {
  				let usrRot = (360 - (rotNode.rotation + (360 / this.LOTTERY_NUM) / 2) % 360) % 360;
  				let itemIndex = usrRot / (360 / this.LOTTERY_NUM);
  				console.warn("-----itemIndex=", itemIndex, rotNode.rotation);
  				let item = this.currTurnLotteryItemArr[itemIndex];
  				let doReward = () => {
  					this.bLotterying = false;
  					mgrYard.markLotteryPlayOnce();
  					let oldPropertyCount = 0;
  					let propertyIndex = 0;
  					let realGotItemAmount = item.amount;
  					if (item.itemId == 101 || item.itemId == 102 || item.itemId == 103 || item.itemId == 104) {
  						let currentProperty1 = mgrRole.getProperty1();
  						let currentProperty2 = mgrRole.getProperty2();
  						let currentProperty3 = mgrRole.getProperty3();
  						let currentProperty4 = mgrRole.getProperty4();
  						if (item.itemId == 101) {
  							oldPropertyCount = currentProperty1;
  							currentProperty1 += item.amount;
  							propertyIndex = 1;
  						}
  						else if (item.itemId == 102) {
  							oldPropertyCount = currentProperty2;
  							currentProperty2 += item.amount;
  							propertyIndex = 2;
  						}
  						else if (item.itemId == 103) {
  							oldPropertyCount = currentProperty3;
  							currentProperty3 += item.amount;
  							propertyIndex = 3;
  						}
  						else {
  							oldPropertyCount = currentProperty4;
  							currentProperty4 += item.amount;
  							propertyIndex = 4;
  						}
  						let propertyRoleId = mgrRole.getPlayerRoleIdByProperty(currentProperty1, currentProperty2, currentProperty3, currentProperty4);
  						mgrRole.setUsingPlayerRoleId(propertyRoleId);
  						mgrRole.setPropertyValue(currentProperty1, currentProperty2, currentProperty3, currentProperty4);
  					}
  					else if (item.itemId == 4) {
  						let decreeAmountOld = Math.min(10, BaseFacade.mItem.getItemAmount(4));
  						let canAddDecreeAmount = Math.min(10 - decreeAmountOld, item.amount);
  						BaseFacade.mItem.addItem(4, canAddDecreeAmount, "庭院转盘");
  						realGotItemAmount = canAddDecreeAmount;
  					}
  					else {
  						BaseFacade.mItem.addItem(item.itemId, item.amount, "庭院转盘");
  					}
  					if (realGotItemAmount <= 0) {
  						if (item.itemId == 4) {
  							mgrTip.showMsgTip("政令已达最大数量");
  						}
  					}
  					else {
  						mgrTip.addGotItemTip(item.itemId, realGotItemAmount, null, {
  							fOnClose: () => {
  								this.refreshLotteryUi();
  								if (propertyIndex) {
  									this.comProperty1.visible = false;
  									this.comProperty2.visible = false;
  									this.comProperty3.visible = false;
  									this.comProperty4.visible = false;
  									let targetNode = this["comProperty" + propertyIndex];
  									targetNode.visible = true;
  									let propertyData = db.get_amaze_cloth_crossing_role_property(propertyIndex);
  									let icon = propertyData.smallIcon;
  									let com = targetNode;
  									com.getChild("point").text = `${oldPropertyCount || 0}`;
  									let worldPosEnd = targetNode.localToGlobal(0, 0);
  									let classView = null;
  									if (item.amount > 0) {
  										classView = ViewAddExpNumber;
  									}
  									else {
  										classView = ViewSubExpNumber;
  									}
  									let showCount = oldPropertyCount + item.amount;
  									let expComponent = new classView({
  										icon: icon, flyTargetPos: worldPosEnd, fOnCompleted: () => {
  											if (!this.resNode || this.resNode.isDisposed) {
  												return;
  											}
  											cc$1.tween(targetNode).toScale(0.1, 1.3).toScale(0.1, 1)
  												.start();
  											com.getChild("point").text = `${showCount || 0}`;
  										}
  									});
  									expComponent.create();
  									if (item.amount > 0) {
  										mgrSound.play(121);
  									}
  									else {
  										mgrSound.play(123);
  									}
  									expComponent.setAmount(item.amount);
  								}
  							}
  						});
  					}
  				};
  				cc$1.tween(this.imageRotBorder)
  					.toAlpha(0.1, 1).toAlpha(0.1, 0)
  					.toAlpha(0.1, 1).toAlpha(0.1, 0)
  					.toAlpha(0.1, 1).toAlpha(0.1, 0)
  					.call(() => {
  						doReward();
  					})
  					.start();
  			})
  			.start();
  	}
  	on_click_buttonClose() {
  		if (this.bLotterying) {
  			mgrTip.showMsgTip("正在转动");
  			return;
  		}
  		this.close();
  	}
  	on_click_buttonLottery() {
  		let count = mgrYard.getLotteryRemainCount() + mgrYard.getAdLotteryRemainCount();
  		if (count <= 0) {
  			mgrTip.showMsgTip("明日再来");
  			return;
  		}
  		if (this.bLotterying) {
  			mgrTip.showMsgTip("正在转动");
  			return;
  		}
  		this.doLottery();
  	}
  	on_click_buttonNoCount() {
  	}
  	on_click_buttonLotteryAd() {
  		let count = mgrYard.getAdLotteryRemainCount();
  		if (count <= 0) {
  			mgrTip.showMsgTip("明日再来");
  			return;
  		}
  		if (this.bLotterying) {
  			mgrTip.showMsgTip("正在转动");
  			return;
  		}
  		// console.info("5555555555555555555555555555555555555");
  		mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelYardLottery_lottery);
  	}
  	on_click_buttonLotteryTip() {
  		mgrTip.alertPrompt("转盘中10个物品的获得概率均为10%", "概率公示", undefined);
  	}
  	on_click_buttonCancel() {
  		if (this.bLotterying) {
  			mgrTip.showMsgTip("正在转动");
  			return;
  		}
  		this.close();
  	}
  }
  PanelYardLottery.sourceName = "ui://yard/PanelYardLottery";

  class PanelYardPreview extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "庭院预览界面";
  	}
  	onLoaded() {
  		this.adaptUi();
  		Global.registerListeners(this, {
  			[BASE_MSG.ADV_SHOW_SUC]: this.onMsgAdvShowSuc.bind(this),
  		});
  	}
  	dispose() {
  		super.dispose();
  	}
  	adaptUi() {
  		if (this.context.bUnlockedTipShow) {
  			this.resNode.getController("c1").setSelectedIndex(2);
  			this.playTranslation(this.resNode, "in2");
  		}
  		else if (mgrYard.isYardUnlocked()) {
  			this.resNode.getController("c1").setSelectedIndex(1);
  			this.playTranslation(this.resNode, "in1");
  			let count = (mgrYard.isYardUnlocked() && mgrYard.getBadgeCount() > 0) ? 1 : 0;
  			mgrTip.showBadgeWithNumber(this.buttonConfirm.displayObject, count, new Laya.Point(5, 5));
  		}
  		else {
  			this.resNode.getController("c1").setSelectedIndex(0);
  			this.playTranslation(this.resNode, "in0");
  			this.buttonAdOpen.visible = mgrAdv.checkActive(db.ADV_DB_ADVNAME.video_PanelYardPreview_ad_unlock);
  			mgrAdv.statisVideoShow(db.ADV_DB_ADVNAME.video_PanelYardPreview_ad_unlock);
  		}
  	}
  	onMsgAdvShowSuc(e) {
  		if (e.advName == db.ADV_DB_ADVNAME.video_PanelYardPreview_ad_unlock) {
  			mgrYard.unlockYard();
  			this.on_click_buttonConfirm();
  		}
  	}
  	on_click_buttonAdOpen() {
  		//庭院
  		console.info("88888888888888888888888888888888888888888");
  		Advertisement.videop=this,
  		Advertisement.videoAdverV(()=>{
  			mgrYard.unlockYard();
  			this.on_click_buttonConfirm();
  			mgrAdv.dispatchAdv(db.ADV_DB_ADVNAME.video_PanelYardPreview_ad_unlock);
  		});
  	}
  	on_click_buttonConfirm() {
  		this.close();
  	}
  	on_click_buttonCancel() {
  		this.close();
  	}
  	on_click_buttonGo() {
  		PanelWarpWithAnim.warp("PanelYard");
  		this.close();
  	}
  }
  PanelYardPreview.sourceName = "ui://yard/PanelYardPreview";

  class PanelYardSurprise extends PanelBase3D {
  	constructor() {
  		super(...arguments);
  		this.PANEL_NAME = "庭院意外之喜";
  	}
  	onLoaded() {
  		this.fillData();
  	}
  	dispose() {
  		super.dispose();
  	}
  	fillData() {
  		let buildingId = this.context.buildingId;
  		let level = mgrYard.getBuildingLvByType(buildingId);
  		let template = db.get_ggg_yard_build_template_db(buildingId, level);
  		switch (buildingId) {
  			case YardBuildType.Event:
  				this.resNode.getController("c1").setSelectedIndex(0);
  				this.playTranslation(this.resNode, "in0");
  				this.labelTitileEvent.text = `${level}级${template.name}`;
  				this.labelOutputEvent.text = `+${mgrYard.getEventRewardGoldPerHandle()}`;
  				break;
  			case YardBuildType.Business:
  				this.resNode.getController("c1").setSelectedIndex(1);
  				this.playTranslation(this.resNode, "in1");
  				this.labelTitileBusiness.text = `${level}级${template.name}`;
  				this.labelOutputBusiness.text = `+${template.businessMaxCount}`;
  				break;
  			case YardBuildType.Gold:
  				this.resNode.getController("c1").setSelectedIndex(2);
  				this.playTranslation(this.resNode, "in2");
  				this.labelTitileGold.text = `${level}级${template.name}`;
  				this.labelOutputGold.text = `+${template.goldOutputPerHour}`;
  				break;
  			case YardBuildType.Lottery:
  				this.resNode.getController("c1").setSelectedIndex(3);
  				this.playTranslation(this.resNode, "in3");
  				this.labelTitileLottery.text = `${level}级${template.name}`;
  				this.labelOutputLottery.text = `+${template.lotteryOutPutRatio * 100}%`;
  				break;
  			default:
  				break;
  		}
  	}
  	on_click_buttonConfirm() {
  		this.close();
  	}
  }
  PanelYardSurprise.sourceName = "ui://yard/PanelYardSurprise";

  function requireModule(name) {
  	switch (name) {
  		case "PanelGreyVideoFreeEnergy":
  			return PanelGreyVideoFreeEnergy;
  		case "PanelNativeAdv":
  			return PanelNativeAdv;
  		case "PanelNativeBanner":
  			return PanelNativeBanner;
  		case "PanelVideoFreeCopperCoin":
  			return PanelVideoFreeCopperCoin;
  		case "PanelVideoFreeEnergy":
  			return PanelVideoFreeEnergy;
  		case "CustomCheck1":
  			return CustomCheck1;
  		case "CustomCoinTopBar":
  			return CustomCoinTopBar;
  		case "CustomCoinTopBar2":
  			return CustomCoinTopBar2;
  		case "CustomCoinTopBar3":
  			return CustomCoinTopBar3;
  		case "PanelAdRetryDialog":
  			return PanelAdRetryDialog;
  		case "PanelGuide":
  			return PanelGuide;
  		case "PanelItemAmountTip":
  			return PanelItemAmountTip;
  		case "PanelNetworkConnectTip":
  			return PanelNetworkConnectTip;
  		case "PanelWarpWithAnim":
  			return PanelWarpWithAnim;
  		case "PanelWarpWithoutAnim":
  			return PanelWarpWithoutAnim;
  		case "PanelWarpWithWhite":
  			return PanelWarpWithWhite;
  		case "ViewGuideTip":
  			return ViewGuideTip;
  		case "ViewRedPoint":
  			return ViewRedPoint;
  		case "ViewTipItem":
  			return ViewTipItem;
  		case "CustomGameIconItem":
  			return CustomGameIconItem;
  		case "CustomGameIconItem2":
  			return CustomGameIconItem2;
  		case "CustomMoreGameIcon":
  			return CustomMoreGameIcon;
  		case "PanelAddToDesktopDouyin":
  			return PanelAddToDesktopDouyin;
  		case "PanelFindMeBaidu":
  			return PanelFindMeBaidu;
  		case "PanelFindMeDouyin":
  			return PanelFindMeDouyin;
  		case "PanelFindMeToutiao":
  			return PanelFindMeToutiao;
  		case "PanelFindMeWeixin":
  			return PanelFindMeWeixin;
  		case "PanelFollowDouyin":
  			return PanelFollowDouyin;
  		case "PanelJumpOtherGameDialog":
  			return PanelJumpOtherGameDialog;
  		case "PanelMoreGameDialog":
  			return PanelMoreGameDialog;
  		case "PanelMoreGameLeft":
  			return PanelMoreGameLeft;
  		case "PanelShareDialog":
  			return PanelShareDialog;
  		case "PanelSmallProgramDouyin":
  			return PanelSmallProgramDouyin;
  		case "PanelTryGame":
  			return PanelTryGame;
  		case "PanelVideoRecordDialog":
  			return PanelVideoRecordDialog;
  		case "ViewJumpGameSingle":
  			return ViewJumpGameSingle;
  		case "ViewMoreGameBanner":
  			return ViewMoreGameBanner;
  		case "ViewMoreGameLeft":
  			return ViewMoreGameLeft;
  		case "PanelChestDialog":
  			return PanelChestDialog;
  		case "PanelFreeLevelUpDialog":
  			return PanelFreeLevelUpDialog;
  		case "PanelPartGotDialog":
  			return PanelPartGotDialog;
  		case "PanelPromptDialog":
  			return PanelPromptDialog;
  		case "PanelRandomName":
  			return PanelRandomName;
  		case "PanelRestartDialog":
  			return PanelRestartDialog;
  		case "PanelUiTipInfoDialog":
  			return PanelUiTipInfoDialog;
  		case "CustomEditorCheckBox":
  			return CustomEditorCheckBox;
  		case "CustomEditorColor":
  			return CustomEditorColor;
  		case "CustomEditorInput":
  			return CustomEditorInput;
  		case "CustomEditorOption":
  			return CustomEditorOption;
  		case "CustomEditorSlider":
  			return CustomEditorSlider;
  		case "CustomEditorTextrue":
  			return CustomEditorTextrue;
  		case "DebugCrossStagePreview":
  			return DebugCrossStagePreview;
  		case "DebugItem":
  			return DebugItem;
  		case "DebugMain":
  			return DebugMain;
  		case "DebugMeshUvPicker":
  			return DebugMeshUvPicker;
  		case "DebugModelAnim":
  			return DebugModelAnim;
  		case "DebugOffScreenRender":
  			return DebugOffScreenRender;
  		case "DebugSoundIdPreview":
  			return DebugSoundIdPreview;
  		case "DebugSpinePreview":
  			return DebugSpinePreview;
  		case "DebugTest":
  			return DebugTest;
  		case "DebugTimelinePreview":
  			return DebugTimelinePreview;
  		case "EditorBoneSearch":
  			return EditorBoneSearch;
  		case "EditorDiy":
  			return EditorDiy;
  		case "EditorDynamicBone":
  			return EditorDynamicBone;
  		case "EditorDynamicBoneElse":
  			return EditorDynamicBoneElse;
  		case "EditorHierarchyMenu":
  			return EditorHierarchyMenu;
  		case "EditorHumanBone":
  			return EditorHumanBone;
  		case "EditorList":
  			return EditorList;
  		case "EditorModelMaterial":
  			return EditorModelMaterial;
  		case "EditorNumberInput":
  			return EditorNumberInput;
  		case "EditorSelectorColor":
  			return EditorSelectorColor;
  		case "EditorSelectorTexture":
  			return EditorSelectorTexture;
  		case "EditorTextInput":
  			return EditorTextInput;
  		case "ViewRelationBaseNode":
  			return ViewRelationBaseNode;
  		case "PanelExperience":
  			return PanelExperience;
  		case "PanelChoosePosition":
  			return PanelChoosePosition;
  		case "PanelCrossLine":
  			return PanelCrossLine;
  		case "PanelGoGoGo":
  			return PanelGoGoGo;
  		case "PanelPositionUpFirstYearPreview":
  			return PanelPositionUpFirstYearPreview;
  		case "PanelPositionUpPreview":
  			return PanelPositionUpPreview;
  		case "PanelQuestionEvent":
  			return PanelQuestionEvent;
  		case "PanelResultQuestionEvent":
  			return PanelResultQuestionEvent;
  		case "PanelStageStartTip":
  			return PanelStageStartTip;
  		case "PanelStartBorn":
  			return PanelStartBorn;
  		case "PanelTrail":
  			return PanelTrail;
  		case "ViewAddCoinNumber":
  			return ViewAddCoinNumber;
  		case "ViewAddExpNumber":
  			return ViewAddExpNumber;
  		case "ViewSubCoinNumber":
  			return ViewSubCoinNumber;
  		case "ViewSubEnergyNumber":
  			return ViewSubEnergyNumber;
  		case "ViewSubExpNumber":
  			return ViewSubExpNumber;
  		case "PanelIllu":
  			return PanelIllu;
  		case "PanelUnlock":
  			return PanelUnlock;
  		case "PanelIlluDetails":
  			return PanelIlluDetails;
  		case "PanelAgeTipDialog":
  			return PanelAgeTipDialog;
  		case "PanelLoading":
  			return PanelLoading;
  		case "PanelWait":
  			return PanelWait;
  		case "PanelPet":
  			return PanelPet;
  		case "PanelResultField":
  			return PanelResultField;
  		case "PanelResultSuccess":
  			return PanelResultSuccess;
  		case "PanelEnding":
  			return PanelEnding;
  		case "PanelScroll":
  			return PanelScroll;
  		case "PanelSettlement":
  			return PanelSettlement;
  		case "PanelAttendant":
  			return PanelAttendant;
  		case "PanelRoleLevelDown":
  			return PanelRoleLevelDown;
  		case "PanelRoleLevelUp":
  			return PanelRoleLevelUp;
  		case "PanelStageSuccess":
  			return PanelStageSuccess;
  		case "CustomSettingSwitch":
  			return CustomSettingSwitch;
  		case "PanelSetting":
  			return PanelSetting;
  		case "PanelSpecialStageFail2":
  			return PanelSpecialStageFail2;
  		case "PanelSpecialStagePreview1":
  			return PanelSpecialStagePreview1;
  		case "PanelSpecialStagePreview2":
  			return PanelSpecialStagePreview2;
  		case "PanelSpecialStageSuccess1":
  			return PanelSpecialStageSuccess1;
  		case "PanelSpecialStageSuccess2":
  			return PanelSpecialStageSuccess2;
  		case "CustomYardBuildingListItem":
  			return CustomYardBuildingListItem;
  		case "PanelYard":
  			return PanelYard;
  		case "PanelYardBuildingLvup":
  			return PanelYardBuildingLvup;
  		case "PanelYardBusiness":
  			return PanelYardBusiness;
  		case "PanelYardEvent":
  			return PanelYardEvent;
  		case "PanelYardEventReward":
  			return PanelYardEventReward;
  		case "PanelYardGold":
  			return PanelYardGold;
  		case "PanelYardLevelUp":
  			return PanelYardLevelUp;
  		case "PanelYardLottery":
  			return PanelYardLottery;
  		case "PanelYardPreview":
  			return PanelYardPreview;
  		case "PanelYardSurprise":
  			return PanelYardSurprise;
  		default:
  			return null;
  	}
  }
  function registerClass() {
  	fgui.UIObjectFactory.extensions["ui://base/CustomCheck1"] = CustomCheck1;
  	fgui.UIObjectFactory.extensions["ui://base/CustomCoinTopBar"] = CustomCoinTopBar;
  	fgui.UIObjectFactory.extensions["ui://base/CustomCoinTopBar2"] = CustomCoinTopBar2;
  	fgui.UIObjectFactory.extensions["ui://base/CustomCoinTopBar3"] = CustomCoinTopBar3;
  	fgui.UIObjectFactory.extensions["ui://channel/CustomGameIconItem"] = CustomGameIconItem;
  	fgui.UIObjectFactory.extensions["ui://channel/CustomGameIconItem2"] = CustomGameIconItem2;
  	fgui.UIObjectFactory.extensions["ui://channel/CustomMoreGameIcon"] = CustomMoreGameIcon;
  	fgui.UIObjectFactory.extensions["ui://debug/CustomEditorCheckBox"] = CustomEditorCheckBox;
  	fgui.UIObjectFactory.extensions["ui://debug/CustomEditorColor"] = CustomEditorColor;
  	fgui.UIObjectFactory.extensions["ui://debug/CustomEditorInput"] = CustomEditorInput;
  	fgui.UIObjectFactory.extensions["ui://debug/CustomEditorOption"] = CustomEditorOption;
  	fgui.UIObjectFactory.extensions["ui://debug/CustomEditorSlider"] = CustomEditorSlider;
  	fgui.UIObjectFactory.extensions["ui://debug/CustomEditorTextrue"] = CustomEditorTextrue;
  	fgui.UIObjectFactory.extensions["ui://setting/CustomSettingSwitch"] = CustomSettingSwitch;
  	fgui.UIObjectFactory.extensions["ui://yard/CustomYardBuildingListItem"] = CustomYardBuildingListItem;
  }

  class NetworkChecker {
  	static update() {
  		if (Laya.loader.retryDelay != this.retryDelay)
  			Laya.loader.retryDelay = this.retryDelay;
  		if (Laya.loader.retryNum != this.retryNum)
  			Laya.loader.retryNum = this.retryNum;
  		let failedRess = Laya.loader["_failRes"] || {};
  		let totalCount = 0;
  		Tools.forEachMap(failedRess, (url, count) => {
  			totalCount += count;
  			if (totalCount >= 15)
  				return true;
  		});
  		if (totalCount >= 15 && (Timer.time - this.lastTipTime) > this.tipInterval) {
  		}
  		if (totalCount == 0 && this.networkTip && !this.networkTip.destroyed) {
  			this.networkTip.close();
  		}
  	}
  }
  NetworkChecker.lastTipTime = 0;
  NetworkChecker.tipInterval = 999999;
  NetworkChecker.retryNum = 1000000;
  NetworkChecker.retryDelay = 100;

  class Start extends Laya.Script {
  	constructor() {
  		super();
  		this._loop = 0;
  		this._time = 0;
  	}
  	onAwake() {
  		console.log("--->>:onAwake");
  		Global.require = requireModule;
  		registerClass();
  		fgui.UIConfig.packageFileExtension = "xml";
  		Timer.initTime();
  		TweenSystem.create();
  	}
  	onEnable() {
  		console.log("--->>:onEnable");
  	}
  	onStart() {
  		
  		console.log("--->>:onStart");
  		let sprite = this.owner.getChildAt(0);
  		Laya.loader.load("url_path.json", new Laya.Handler(this, (urlConfig) => {
  			// if (urlConfig.path && !Laya.Browser.onPC) {
  				// Laya.URL.basePath = urlConfig.path;
  			// }
  			new UpdaterScript(this.owner, (msg) => {
  				if (msg == UPDATER_UI_MSG.ENTER_NEXT_SCENE) {
  					Director.init();
  					Director.runScene(SceneMain, "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;
  		NetworkChecker.update();
  	}
  	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 = "MainScene.scene";
  GameConfig.sceneRoot = "";
  GameConfig.debug = false;
  GameConfig.stat = false;
  GameConfig.physicsDebug = true;
  GameConfig.exportSceneToJson = true;
  GameConfig.init();

  /**
   * - 时间: 2020年3月11日15:27:29
   * - by: Liuwei
   * - cause: 在魅族上有文字错乱的bug.
   * - 修改方式:  在文本构造函数中 修改 cacheAs = "bitmap";
   * 
   * - 本适配文件需要放在Laya.ResourceVersion.enable调用之前创建
   */
  class ULAdapter {
  	constructor() {
  		Laya = window.Laya;
  		window.Stage = window.Laya.Stage;

  		this.adaptChannel();
  		this.adaptVersinCompress();
  		this.adaptLaya();
  		// this.adaptFrameRate();
  		this.adaptFgui();
  		this.adaptLoader();
  	}



  	/**
  	 * - 适配渠道bug
  	 * - 在发布中, 一部分渠道会有一些bug
  	 * - 适配渠道, 文件缓存
  	 */
  	adaptChannel() {
  		//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;
  			};
  		};

  		//适配启用(头条 微信 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);
  	}

  	/**
  	 * - 适配version 文件压缩
  	 */
  	adaptVersinCompress() {
  		//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'];
  			//先压缩, 再用文本的方式解压
  			data = pako.gzip(data);
  			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错误。");
  			}
  		};
  	}


  	// 适配Laya
  	adaptLaya() {
  		var Config3D = Laya.Config3D;
  		var Scene3D = Laya.Scene3D;
  		var Scene3DShaderDeclaration = Laya.Scene3DShaderDeclaration;
  		var Vector3 = Laya.Vector3;
  		var Cluster = Laya.Cluster;
  		Laya.DirectionLight.prototype[`_create`] = () => { return new Laya.DirectionLight() };

  		//解决多光源下, spotLight没有参数的问题
  		class ULScene3D extends 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);
  					}
  				}
  			}
  		}

  		Laya.Scene3D = ULScene3D;

  		Laya.Sprite.prototype[`setXY`] = function (x, y) {
  			this.pos(x, y);
  		};

  		Object.defineProperty(Laya.Sprite.prototype, "colorFliter", {
  			set(color) {
  				if (!this.filters || this.filters.length == 0) {
  					let colorMat = [
  						1, 0, 0, 0, 0, //R
  						0, 1, 0, 0, 0, //G
  						0, 0, 1, 0, 0, //B
  						0, 0, 0, 1, 0, //A
  					];
  					let filter = new Laya.ColorFilter(colorMat);
  					this.filters = [filter];
  				}
  				let filter = this.filters[0];
  				filter._mat[0] = color.x;
  				filter._mat[5] = color.y;
  				filter._mat[10] = color.z;
  				filter._mat[15] = color.w;
  			},
  			get() {
  				if (!this.filters || this.filters.length == 0) {
  					let colorMat = [
  						1, 0, 0, 0, 0, //R
  						0, 1, 0, 0, 0, //G
  						0, 0, 1, 0, 0, //B
  						0, 0, 0, 1, 0, //A
  					];
  					let filter = new Laya.ColorFilter(colorMat);
  					this.filters = [filter];
  				}
  				let filter = this.filters[0];
  				let color = new Laya.Vector4;
  				color.x = filter._mat[0];
  				color.y = filter._mat[5];
  				color.z = filter._mat[10];
  				color.w = filter._mat[15];
  				return color;
  			}
  		});

  		Object.defineProperty(Laya.Sprite.prototype, "anchorX", {
  			set(anchorX) {
  				this.pivotX = anchorX * this.width;
  			},
  			get() {
  				if (this.width == 0) return 0;
  				return this.pivotX / this.width;
  			}
  		});

  		Object.defineProperty(Laya.Sprite.prototype, "anchorY", {
  			set(anchorY) {
  				this.pivotY = anchorY * this.width;
  			},
  			get() {
  				if (this.width == 0) return 0;
  				return this.pivotY / this.width;
  			}
  		});

  		Laya.Skeleton.prototype[`_update`] = function (autoKey = true) {
  			if (this._pause)
  				return;
  			if (autoKey && this._indexControl) {
  				return;
  			}
  			var tCurrTime = this.timer.currTimer;
  			var preIndex = this._player.currentKeyframeIndex;
  			var dTime = tCurrTime - this._lastTime;
  			if (autoKey) {
  				this._player._update(dTime);
  			}
  			else {
  				preIndex = -1;
  			}
  			this._lastTime = tCurrTime;
  			if (!this._player)
  				return;
  			this._index = this._clipIndex = this._player.currentKeyframeIndex;
  			if (this._index < 0)
  				return;
  			// if (dTime > 0 && this._clipIndex == preIndex && this._lastUpdateAniClipIndex == this._aniClipIndex) {
  			//     return;
  			// }
  			this._lastUpdateAniClipIndex = this._aniClipIndex;
  			if (preIndex > this._clipIndex && this._eventIndex != 0) {
  				this._emitMissedEvents(this._player.playStart, this._player.playEnd, this._eventIndex);
  				this._eventIndex = 0;
  			}
  			var tEventArr = this._templet.eventAniArr[this._aniClipIndex];
  			var _soundChannel;
  			if (tEventArr && this._eventIndex < tEventArr.length) {
  				var tEventData = tEventArr[this._eventIndex];
  				if (tEventData.time >= this._player.playStart && tEventData.time <= this._player.playEnd) {
  					if (this._player.currentPlayTime >= tEventData.time) {
  						this.event(Laya.Event.LABEL, tEventData);
  						this._eventIndex++;
  						if (this._playAudio && tEventData.audioValue && tEventData.audioValue !== "null" && tEventData.audioValue !== "undefined") {
  							_soundChannel = Laya.SoundManager.playSound(this._player.templet._path + tEventData.audioValue, 1, Laya.Handler.create(this, this._onAniSoundStoped));
  							Laya.SoundManager.playbackRate = this._player.playbackRate;
  							_soundChannel && this._soundChannelArr.push(_soundChannel);
  						}
  					}
  				}
  				else if (tEventData.time < this._player.playStart && this._playAudio && tEventData.audioValue && tEventData.audioValue !== "null" && tEventData.audioValue !== "undefined") {
  					this._eventIndex++;
  					_soundChannel = Laya.SoundManager.playSound(this._player.templet._path + tEventData.audioValue, 1, Laya.Handler.create(this, this._onAniSoundStoped), null, (this._player.currentPlayTime - tEventData.time) / 1000);
  					Laya.SoundManager.playbackRate = this._player.playbackRate;
  					_soundChannel && this._soundChannelArr.push(_soundChannel);
  				}
  				else {
  					this._eventIndex++;
  				}
  			}
  			var tGraphics;
  			if (this._aniMode == 0) {
  				tGraphics = this._templet.getGrahicsDataWithCache(this._aniClipIndex, this._clipIndex) || this._createGraphics();
  				if (tGraphics && this.graphics != tGraphics) {
  					this.graphics = tGraphics;
  				}
  			}
  			else if (this._aniMode == 1) {
  				tGraphics = this._getGrahicsDataWithCache(this._aniClipIndex, this._clipIndex) || this._createGraphics();
  				if (tGraphics && this.graphics != tGraphics) {
  					this.graphics = tGraphics;
  				}
  			}
  			else {
  				this._createGraphics();
  			}
  		};

  		/******** 因为这部分代码, 不会生效,  因为所有的初始化和引用都在laya内部, 这里做备份 */
  		class ULInput3D extends Laya.Input3D {
  			constructor() {
  				super();
  				this._pushEventList = ((e) => {
  					(e.cancelable) && (e.preventDefault());
  					(e.cancelable) && this._eventList.push(e);
  				}).bind(this);
  			}
  		}
  		Laya.Input3D = ULInput3D;

  		class ULAnimatorControllerLayer extends Laya.AnimatorControllerLayer {
  			addState(state) {
  				var stateName = state.name;
  				if (this._statesMap[stateName]) {
  					console.warn("AnimatorControllerLayer:this stat's name has exist.");
  				}
  				else {
  					this._statesMap[stateName] = state;
  					this._states.push(state);
  					if (this._animator) {
  						state._clip._addReference();
  						this._animator._getOwnersByClip(state);
  					}
  				}
  			}
  		}
  		Laya.AnimatorControllerLayer = ULAnimatorControllerLayer;

  		class ULSimpleSingletonList extends Laya.SimpleSingletonList {
  			add(element) {
  				var index = element._getIndexInList();
  				if (index !== -1) return;
  				// throw "SimpleSingletonList:" + element + " has  in  SingletonList.";
  				this._add(element);
  				element._setIndexInList(this.length++);
  			}
  			remove(element) {
  				var index = element._getIndexInList();
  				/**
  				 * - 2020年1月8日14:50:51
  				 * - by 刘伟
  				 * - cause: 在疯狂点击, 可能会造成lenght < 0的情况 导致crash
  				 */
  				if (this.length <= 0) return;
  				this.length--;
  				if (index !== this.length) {
  					var end = this.elements[this.length];
  					this.elements[index] = end;
  					end._setIndexInList(index);
  				}
  				element._setIndexInList(-1);
  			}
  		}
  		Laya.SimpleSingletonList = ULSimpleSingletonList;
  	}

  	//适配帧率
  	adaptFrameRate() {
  		let oldrender = Laya.Stage.prototype.render;
  		this._frameStartTime = 0;
  		let frameDuration = 20;
  		let totalTime = 0;
  		let startTime = 0;
  		let frameCount = 0;

  		Laya.Stage.prototype.render = (context, x, y) => {
  			if (Laya.Browser.now() - this._frameStartTime <= frameDuration) {
  				return;
  			}
  			this._frameStartTime = Laya.Browser.now();

  			startTime = Laya.Browser.now();
  			oldrender.apply(Laya.stage, [context, x, y]);
  			totalTime += Laya.Browser.now() - startTime;
  			frameCount++;

  			frameDuration = Math.min(totalTime / frameCount + 1, 20);
  		};
  	}


  	// 适配fgui
  	adaptFgui() {
  		// 阻止fgui列表的touch down事件继续冒泡
  		// by LDW 2020-11-20
  		var scroll_panel_mouseDown = fgui.ScrollPane.prototype["__mouseDown"];
  		fgui.ScrollPane.prototype["__mouseDown"] = function (e) {
  			if (!this.bStopPropagation)
  				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() {
  		class ULLoader extends Laya.Loader {
  			onLoaded(data = null) {
  				var type = this._type;
  				var url = this._url;
  				//需要对二进制文件进行解压操作
  				if (type == Laya.Loader.BUFFER) {
  					let 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;
  					};

  					//压缩头判定版本
  					if (isMatch(data)) {
  						//匹配到了压缩头
  						data = pako.ungzip(data);
  						// console.error(`${url}: 已压缩`);
  					}

  					// // try 版本  效率低
  					// let pako = window['pako'];
  					// try {
  					//     let newData = pako.ungzip(data);
  					//     data = newData;
  					//     console.error(`${url}: 已压缩`);
  					// } catch (error) {
  					//     console.error(`${url}: 未压缩`);
  					// }
  				}
  				super.onLoaded(data);
  			}
  		}
  		Laya.ILaya.Loader = Laya.Loader = ULLoader;

  		let oldLoad = ULLoader.prototype[`load`];
  		ULLoader.prototype[`load`] = function (...args) {
  			let url = args[0];
  			if (!!url) {
  				let idx = url.indexOf(".jpg");
  				let idx1 = url.indexOf(".png");
  				if (idx >= 0) {
  					url = url.substring(0, idx + 4);
  				}
  				else if (idx1 >= 0) {
  					url = url.substring(0, idx1 + 4);
  				}
  			}
  			args[0] = url;
  			oldLoad.call(this, ...args);
  		};
  		/**
  		 * - 自定义加载管理器
  		 */
  		class ULLoaderManager extends Laya.LoaderManager {
  			_doLoad(resInfo) {
  				this._loaderCount++;
  				var loader = this._loaders.length ? this._loaders.pop() : new Laya.Loader();
  				loader.on(Laya.Event.COMPLETE, null, onLoaded);
  				loader.on(Laya.Event.PROGRESS, null, function (num) {
  					resInfo.event(Laya.Event.PROGRESS, num);
  				});
  				loader.on(Laya.Event.ERROR, null, function (msg) {
  					onLoaded(null);
  				});
  				var _me = this;
  				function onLoaded(data = null) {
  					loader.offAll();
  					loader._data = null;
  					loader._customParse = false;
  					_me._loaders.push(loader);
  					_me._endLoad(resInfo, data instanceof Array ? [data] : data);
  					_me._loaderCount--;
  					_me._next();
  				}
  				loader._constructParams = resInfo.createConstructParams;
  				loader._propertyParams = resInfo.createPropertyParams;
  				loader._createCache = resInfo.createCache;
  				loader.load(resInfo.url, resInfo.type, resInfo.cache, resInfo.group, resInfo.ignoreCache, resInfo.useWorkerLoader);
  			}
  		}
  		Laya.ILaya.loader = Laya.loader = new ULLoaderManager();
  		Laya3D._innerFirstLevelLoaderManager = new ULLoaderManager();
  		Laya3D._innerSecondLevelLoaderManager = new ULLoaderManager();
  		Laya3D._innerThirdLevelLoaderManager = new ULLoaderManager();
  		Laya3D._innerFourthLevelLoaderManager = new ULLoaderManager();
  	}
  }

  const B_ALL_TEXT_RENDER_CACHE_AS_BITMAP = false;
  class Main {
  	constructor() {
  		window[`notCacheList`] = [];
  		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;
  		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);
  		Laya.MouseManager.multiTouchEnabled = false;
  		if (!B_ALL_TEXT_RENDER_CACHE_AS_BITMAP) {
  			Laya.TextRender.forceSplitRender = true;
  		}
  		new ULAdapter();
  		Laya.ResourceVersion.enable("version.json", Laya.Handler.create(this, this.onVersionLoaded), Laya.ResourceVersion.FILENAME_VERSION);
  	}
  	onVersionLoaded() {
  	  	Laya.AtlasInfoManager.enable("fileconfig.json", Laya.Handler.create(this, this.onConfigLoaded));
  	}
  	onConfigLoaded() {
  		
  		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$1.downloadFile({
  				// var downloadTask = qg.download({
  					//资源下载==============================================
  					url: "https://duoduoyou.com.cn/CDN/Zytt/xiaozhugonglue/tiaozhandanggongnv/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) {
  								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);
  							},
  							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);
  		}
  		// GameConfig.startScene && Laya.Scene.open(GameConfig.startScene);
  	}
  }
  new Main();

}());
