app php01 5 сар өмнө
commit
2ed823359c
100 өөрчлөгдсөн 27325 нэмэгдсэн , 0 устгасан
  1. 38 0
      AndroidManifest.xml
  2. 1028 0
      App.vue
  3. 21 0
      Info.plist
  4. 21 0
      LICENSE
  5. 15 0
      README.md
  6. 736 0
      TrtcCloud/lib/TrtcCloudImpl.js
  7. 612 0
      TrtcCloud/lib/TrtcCode.js
  8. 484 0
      TrtcCloud/lib/TrtcDefines.js
  9. 10 0
      TrtcCloud/lib/constants.js
  10. 989 0
      TrtcCloud/lib/index.js
  11. 279 0
      TrtcCloud/permission.js
  12. 19 0
      TrtcCloud/view/TrtcLocalView.nvue
  13. 23 0
      TrtcCloud/view/TrtcRemoteView.nvue
  14. 8 0
      changelog.md
  15. 63 0
      common/common.scss
  16. 30 0
      common/jsencrypt.js
  17. 119 0
      common/zhifuye.html
  18. 177 0
      components/customNav/customNav.vue
  19. 78 0
      components/mapView/mapView.vue
  20. 59 0
      components/myImage/myImage.vue
  21. 81 0
      components/myorderItem/myorderItem.vue
  22. 77 0
      components/netImage/netImage.vue
  23. 617 0
      components/orderItem/orderItem.vue
  24. 555 0
      components/orderItemA/orderItemA.vue
  25. 735 0
      components/orderItemB/orderItemB.vue
  26. 534 0
      components/orderItemC/orderItemC.vue
  27. 173 0
      components/popViewA/popViewA.vue
  28. 235 0
      components/popViewGG/popViewGG.vue
  29. 78 0
      components/scrollViewR/scrollViewR.vue
  30. 974 0
      components/yhdsl-cropper/yhdsl-cropper.vue
  31. 110 0
      components/ysxyView/ysxyView.vue
  32. 32 0
      config/index.config.js
  33. BIN
      cteDev.p12
  34. BIN
      cteDis.p12
  35. BIN
      cteqishou.keystore
  36. 5 0
      cteqishou.txt
  37. BIN
      cteqsdev-3.mobileprovision
  38. BIN
      cteqsdis-2.mobileprovision
  39. 59 0
      debug/GenerateTestUserSig.js
  40. 1217 0
      debug/lib-generate-test-usersig-es.min.js
  41. 432 0
      hybrid/html/voices/audio.html
  42. 207 0
      hybrid/html/voices/audioserver.html
  43. 74 0
      hybrid/html/voices/css/index.css
  44. 1 0
      hybrid/html/voices/css/modules/code.css
  45. 0 0
      hybrid/html/voices/css/modules/laydate/default/laydate.css
  46. BIN
      hybrid/html/voices/css/modules/layer/default/icon-ext.png
  47. BIN
      hybrid/html/voices/css/modules/layer/default/icon.png
  48. 0 0
      hybrid/html/voices/css/modules/layer/default/layer.css
  49. BIN
      hybrid/html/voices/css/modules/layer/default/loading-0.gif
  50. BIN
      hybrid/html/voices/css/modules/layer/default/loading-1.gif
  51. BIN
      hybrid/html/voices/css/modules/layer/default/loading-2.gif
  52. 0 0
      hybrid/html/voices/css/slider.css
  53. 0 0
      hybrid/html/voices/css/vant.css
  54. BIN
      hybrid/html/voices/img/guaduandd.png
  55. BIN
      hybrid/html/voices/img/loading2.gif
  56. BIN
      hybrid/html/voices/img/logo.png
  57. 267 0
      hybrid/html/voices/index.html
  58. 0 0
      hybrid/html/voices/js/lib/uniwebviewsdk.js
  59. 71 0
      hybrid/html/voices/xuanfc.html
  60. 5649 0
      hybrid/html/xuanfu/css/mui.css
  61. 4 0
      hybrid/html/xuanfu/css/mui.min.css
  62. BIN
      hybrid/html/xuanfu/fonts/mui.ttf
  63. BIN
      hybrid/html/xuanfu/img/guaduandd.png
  64. BIN
      hybrid/html/xuanfu/img/jietong.png
  65. BIN
      hybrid/html/xuanfu/img/logo.png
  66. BIN
      hybrid/html/xuanfu/img/xinxi.png
  67. BIN
      hybrid/html/xuanfu/img/y800.mp3
  68. 117 0
      hybrid/html/xuanfu/index.html
  69. 8390 0
      hybrid/html/xuanfu/js/mui.js
  70. 5 0
      hybrid/html/xuanfu/js/mui.min.js
  71. 20 0
      index.html
  72. 24 0
      locale/en.json
  73. 14 0
      locale/index.js
  74. 23 0
      locale/ja.json
  75. 36 0
      locale/uni-app.ja.json
  76. 352 0
      locale/yuenan.json
  77. 352 0
      locale/zh-Hans.json
  78. 352 0
      locale/zh-Hant.json
  79. 133 0
      main.js
  80. 224 0
      manifest.json
  81. BIN
      nativeResources/android/res/drawable/not.png
  82. 11 0
      nativeResources/android/res/values/themes.xml
  83. BIN
      nativeplugins/MapBox-Plugin/.DS_Store
  84. 1 0
      nativeplugins/MapBox-Plugin/android-exclude.txt
  85. BIN
      nativeplugins/MapBox-Plugin/android/.DS_Store
  86. BIN
      nativeplugins/MapBox-Plugin/android/libbd.aar
  87. BIN
      nativeplugins/MapBox-Plugin/android/res/.DS_Store
  88. 3 0
      nativeplugins/MapBox-Plugin/android/res/values/strings.xml
  89. BIN
      nativeplugins/MapBox-Plugin/ios/.DS_Store
  90. BIN
      nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/.DS_Store
  91. 21 0
      nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXAccuracyAuthorization.h
  92. 28 0
      nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXCancelable.h
  93. 27 0
      nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXDownloadError.h
  94. 15 0
      nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXDownloadErrorCode.h
  95. 41 0
      nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXDownloadOptions.h
  96. 17 0
      nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXDownloadState.h
  97. 52 0
      nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXDownloadStatus.h
  98. 12 0
      nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXDownloadStatusCallback.h
  99. 23 0
      nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXFeature.h
  100. 36 0
      nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXGeometry.h

+ 38 - 0
AndroidManifest.xml

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>  
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"   
+  package="vn.com.cityexpress168.ptqs">  
+    <!--按下面方式配置需要移除的permissions-->  
+	<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" tools:node="remove"/>
+    <!-- Normal Permissions 不需要运行时注册 -->
+    <!-- 获取运营商信息,用于支持提供运营商信息相关的接口 -->
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
+    <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 -->
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
+    <!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位 -->
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
+    <uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/>
+    
+    <!-- 请求网络 -->
+    <uses-permission android:name="android.permission.INTERNET"/>
+        
+        
+    <uses-permission android:name="android.permission.WAKE_LOCK"/>
+	<!-- 需要运行时注册的权限 -->
+    <!-- 用于进行网络定位 -->
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
+    <!-- 用于访问GPS定位 -->
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
+    <!-- 用于提高GPS定位速度 -->
+    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
+    <!-- 更改设置 -->
+    <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
+        
+    <!--如果设置了target >= 28 如果需要启动后台定位则必须声明这个权限-->
+    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
+    <!--如果您的应用需要后台定位权限,且有可能运行在Android Q设备上,并且设置了target>28,必须增加这个权限声明-->
+    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+	<application>  
+        <!--meta-data-->  
+    </application>  
+</manifest>

+ 1028 - 0
App.vue

@@ -0,0 +1,1028 @@
+<script>//com.cityexpress1688.ptqs
+const toast = uni.requireNativePlugin('Ba-Toast');//android
+const callerID = uni.requireNativePlugin('Ba-CallerID');//android
+const KJPip = uni.requireNativePlugin('KJ-Pip');//ios
+
+
+
+//const bugly = uni.requireNativePlugin("LX-Bugly");
+import {
+	UTSKeepalive
+} from "@/uni_modules/wrs-uts-keepalive"
+
+let keepalive = new UTSKeepalive()
+
+import {
+	Mycallback
+} from "@/uni_modules/gzf-appdelegate"
+let notecallback = new Mycallback();
+
+import {
+	setRiderposition,
+	changeLanguages,
+	gcj02towgs
+} from '@/pages/api/basic';
+import api from "@/pages/api/api.js"
+
+  export default {
+	data() {
+	  	return {
+			startFl:0,
+			timer:'',
+			cid:'',
+			isAndroid:false,
+			androidflType:0,
+			isInback:false,
+			iosInit:false,
+			audioObj:null,
+			isfirst:true,
+			xdaudioObj:null,
+		}
+	},
+	globalData:{
+		_i18n:{},
+		$t:{},
+		imViewOpen:false,
+		sj:{},
+		iosfl:{},
+		EXViewOpen:false,
+		auditStatus:0,
+		isOnline:true,
+		token:'',
+		initgoEasy:{},
+		goEasycnt:false,
+		goEasy:null,
+	},
+    onLaunch: function() {
+		console.log('App Launch')
+		//bugly.init("23bea5717e","true")
+		this.globalData.$t=str=>this.$t(str);
+		this.globalData.sj=str=>this.getTimestr();
+		this.globalData.iosfl=index=>this.showpiaof(index);
+		this.globalData.token = uni.getStorageSync("token");
+		this.globalData.imViewOpen = false;
+		this.globalData.EXViewOpen = false;
+		this.globalData.goEasy = this.goEasy;
+		this.globalData.initgoEasy=str=>this.connectGoEasy();
+	    let systemInfo = uni.getSystemInfoSync();
+	    this.isAndroid = systemInfo.platform.toLowerCase() === 'android';
+		var language = uni.getStorageSync('language');
+		if(''==language||null==language||undefined==language){
+			uni.setStorageSync('language',"yuenan");
+			uni.setLocale('yuenan');
+			if(!this.isAndroid){
+				this.$i18n.locale = 'yuenan';
+			}
+			this.uploadLanguagesSet('yuenan');
+		}
+		else{
+			uni.setLocale(language);
+			if(!this.isAndroid){
+				this.$i18n.locale = language;
+			}
+			this.uploadLanguagesSet(language);
+		}
+		
+		this.connectGoEasy();
+		if(!this.isAndroid){
+			console.log('11111-----')
+			this.startLocation();
+		}
+		if(this.isAndroid){
+			console.log('11111-----2')
+			// 设置回调
+			UTSKeepalive.setCallback((resp)=>{
+			    console.log('--------',resp)
+			    let opt  = resp.opt 
+			    switch (opt){
+			        // 定位改变
+			        case "onLocationChanged":
+			        if(this.isAndroid) {
+			            let location = resp.location
+						this.androidRecvitude(location.longitude,location.latitude);
+						//this.androidRecvitude(11.1111111,22.2222222);
+			        } else {
+			            let locations = resp.locations
+			        }
+			            break;
+			        default:
+			            break;
+			    }
+			})
+			this.kaiqibaohuo();
+		}
+		
+		
+		uni.onPushMessage((res) => {
+			console.log("收到推送消息:",res) //监听推送消息
+			
+			var payload=res.data.payload;
+			this.xindingdantx(payload);
+			if(payload.indexOf("rcuser")!=-1){
+				this.updataxiaoxi(payload);
+			}
+	  		if(res.type=='click'){
+	  			var content=res.data.title;
+	  			plus.runtime.setBadgeNumber(0);
+	  	
+	  		}
+	  		if(res.type=='receive'){
+				plus.runtime.setBadgeNumber(0);
+	  			
+				var content=res.data.content;
+				if(content.indexOf("location")!=-1){
+					var objpl=JSON.parse(payload);
+					this.cid=objpl.cid;
+					this.getLocationL();
+					return
+				}
+	  			uni.createPushMessage({
+	  				content:res.data.content,
+	  				success: (res) => {
+	  					console.log(res);
+	  				},
+	  				fail(er) {
+	  				}
+	  			});
+	  		}
+	  })
+	  var that = this;
+	  that.xdaudioObj=uni.createInnerAudioContext();
+	  that.xdaudioObj.src='static/CTENEW.mp3';
+	  //android---------------------------------------------
+	  if(that.isAndroid){
+		  that.audioObj=uni.createInnerAudioContext();
+		  that.audioObj.src='hybrid/html/xuanfu/img/y800.mp3';
+	  }
+	  var globalEvent = uni.requireNativePlugin('globalEvent');
+	  globalEvent.addEventListener('baCallerIdEvent', function(e) {
+	  	console.log('baCallerIdEvent:' + JSON.stringify(e));
+		console.log(e);
+		if(e.tag=='call'&&e.action=='onClick'){
+			if(that.isInback){
+				plus.runtime.launchApplication({pname:'com.cityexpress1688.ptqs'});
+			}
+			
+			if(that.androidflType==1){
+				uni.navigateTo({
+					url:'/pages/imcall/audioCall?iscaller=0'
+				})
+			}
+			else if(that.androidflType==2){
+				uni.navigateTo({
+					url:'/pages/imcall/GoeasyExchange?iscaller=0'
+				})
+			}
+			that.audioObj.pause();
+			that.hideFW();
+		}
+		if(e.tag=='uncall'&&e.action=='onClick'){
+			that.audioObj.pause();
+			that.hideFW();
+		}
+	  });
+	  //ios-------------------------------------------------------------
+	  globalEvent.addEventListener('onPip', function(res) {
+	      console.log("onPip:" + JSON.stringify(res));
+	      if (res.method == "willStartPip") {
+	          console.log("即将开启画中画");
+	      } else if (res.method == "didStartPip") {
+	          console.log("已经开启画中画");
+			  
+	      } else if (res.method == "failedStartPip") {
+	          console.log("开启画中画失败");
+	      } else if (res.method == "willStopPip") {
+	          console.log("即将关闭画中画");
+			  //that.imdef();
+	      } else if (res.method == "didStopPip") {
+	          console.log("已经关闭画中画");
+			 
+	      } else if (res.method == "restorePip") {
+	          console.log("恢复");
+	      }
+	  });
+	  globalEvent.addEventListener('onWebview', function(res) {
+	      console.log("onWebview:" + JSON.stringify(res));
+	      if (res.method == "finish") {
+	          console.log("页面加载完成");
+	      } else if (res.method == "fail") {
+	          console.log("加载失败");
+	      }
+	  });
+	  if(!this.isAndroid){
+		  this.onH5SendDataCallBack();
+	  }
+	  
+    },
+    onShow: function() {
+      console.log('App Show')
+	  plus.runtime.setBadgeNumber(0);
+	  this.isInback=false;
+	  this.initflaotView();
+	  
+	  //bugly.report("上报内容1111")
+	  if(!this.isAndroid){
+	  	 this.startLocation()
+		 notecallback.onCallback((resp)=>{
+		 		  console.log("onCallback 收到推送消息:",resp) //监听推送消息
+		 		  //var payload=resp.data.payload;
+		 		  this.xindingdantx("payload");
+		 })
+	  }
+	  
+	  
+	  
+    },
+    onHide: function() {
+      console.log('App Hide')
+	  this.isInback=true;
+	  // if(!this.isAndroid){
+	  // 	this.openPip1();
+	  // }
+	
+	  // setInterval(() => {
+	  // 	console.log("定时任务 count: " + this.count)
+	  
+	  // }, 10000);
+	  
+	  if(!this.isAndroid){
+	  	 this.startLocation()
+	  }
+	  else{
+		  console.log('this.isAndroid');
+		  //this.startLocation()
+	  }
+    },
+	
+	methods: {
+		xindingdantx(obj){
+			//判断是否收到新订单
+			console.log(obj);
+			this.xdaudioObj.play();
+			
+			var dj = JSON.parse(obj);
+			console.log(dj);
+			if(dj.type==0){
+				if(this.globalData.isOnline){
+					this.xdaudioObj.play();
+				}
+			}
+			
+		},
+		setScreenOrientation() {
+		  uni.setScreenOrientation({
+			orientation: 'portrait-primary'
+		  });
+		},
+		getTimestr(){
+			var time=new Date();
+			var n,y,r,h,m,s;
+			n=time.getFullYear();
+			y=time.getMonth()+1;
+			r=time.getDate();
+			h=time.getHours();
+			m=time.getMinutes();
+			s=time.getSeconds();
+			var timsStr = n+'-'+y+'-'+r+' '+h+':'+m+':'+s;
+			return timsStr;
+		},
+		startLocation(){
+			console.log('1startLocation------')
+			var token = uni.getStorageSync("token");
+			//console.log('2222',that.token)
+			if(token == '' || token == undefined || token == null){
+				return;
+			}
+			else{
+				if(this.startFl==0){
+					//console.log(that.startFl);
+					this.startFl=1;
+					this.timer = setInterval(() => {
+						this.getLocationL();
+					}, 10000);
+				}
+			}
+		},
+		getLocationL(){
+			 var yszche=uni.getStorageSync('yszche');
+			 // console.log(this.startFl,yszche);
+			 if(1!=yszche){
+				 return;
+			 }
+			var that = this;
+			console.log('uni.getLocation')
+			
+			uni.getLocation({
+				type:  "wgs84", //默认为 wgs84 返回 gps 坐标//谷歌地图使用 wgs84 坐标,其他地图使用 gcj02 坐标
+				geocode: "true",
+				isHighAccuracy: "true",
+				accuracy: "best", // 精度值为20m
+				success: function (res) {
+				  // console.log("app定位获取:", res);
+				  if(res.longitude>-180&&res.longitude<180){
+					  if(res.latitude>-90&&res.latitude<90){
+							if(that.cid!=''){
+								that.pushMsg(that.cid,res.longitude,res.latitude)
+							}
+							that.setRiderposition(res.longitude,res.latitude);
+					  }
+				  }
+				},
+				fail(err) {
+					console.log('getLocation err')
+				}
+			});
+		},
+		androidRecvitude(longitude,latitude){
+			var yszche=uni.getStorageSync('yszche');
+			console.log(this.startFl,yszche);
+			if(1!=yszche){
+				return;
+			}
+			var token = uni.getStorageSync("token");
+			//console.log('2222',that.token)
+			if(token == '' || token == undefined || token == null){
+				return;
+			}
+			this.setRiderposition(longitude,latitude);
+		},
+		setRiderposition(longitude,latitude){
+			this.$http.post(`${setRiderposition}`, {
+				"longitude":longitude, 
+				"latitude":latitude 
+			},true)
+			.then(r => {
+				console.log('setRiderposition',r)
+			})
+			.catch(err => {
+				console.log(err)
+			})
+		},
+		async uploadLanguagesSet(lang){
+			var userId = uni.getStorageSync('userId');
+			if(lang=='yuenan'){
+				lang='vi';
+			}
+			if(lang=='zh-Hans'){
+				lang='zh-CN';
+			}
+			if(lang=='zh-Hant'){
+				lang='zh-TW';
+			}
+			//console.log("changeLanguages");
+			await this.$http.get(`${changeLanguages}`, {
+				id:userId,
+				lang:lang
+			},false)
+			.then(async r => {
+				//console.log(r)
+			})
+			.catch(err => {
+				console.log(err)
+			})
+		},
+		updataxiaoxi(str){
+			var xiaoxiList = uni.getStorageSync('dachexiaoxi');
+			if(''==xiaoxiList||null==xiaoxiList||undefined==xiaoxiList){
+				xiaoxiList=[];
+			}
+			xiaoxiList.push(str);
+			uni.setStorageSync('dachexiaoxi',xiaoxiList);
+		},
+		pushMsg(cid,longitude,latitude){//消息推送
+			var payloadData={
+				longitude:longitude,
+				latitude:latitude
+			}
+			api('pushMsgYH',{
+				cid:cid,
+				title:'骑手定位',
+				content:'骑手定位',
+				payload:payloadData
+			},res=>{
+				this.cid='';
+				console.log(res)
+			},failc=>{
+				//console.log('getadvertis----',failc)
+			})
+		},
+		
+		//imcall&&immessage------------------------------------------------
+		initflaotView(){
+			if(this.isAndroid){
+				if(this.isfirst){
+					this.isPermissionFW();
+					this.isfirst=false
+				}
+			}
+			else{//ios
+				// var that = this;
+				// setTimeout(function() {
+				//   // 这里写要延时执行的代码
+				//   that.initPip("landscape");
+				// }, 2000);
+			}
+		},
+		imcallrecive(str){
+			
+			if(str.indexOf("\\\"")!=-1){
+				str=str.replace(/\\\"/g, '\"');
+				str = str.replace(/\"{/g, '{');
+				str = str.replace(/}\"/g, '}');
+			}
+			var obj = JSON.parse(str)
+			console.log('imcallrecive',obj)
+			if(this.isAndroid){
+				if(this.androidflType!=0){
+					return;
+				}
+				var uobj={
+					name:obj.nickName,
+					content:this.$t('audioCall.cteyhcall'),
+					call:this.$t('audioCall.jietingyy'),
+					uncall:this.$t('audioCall.jujuejieting')
+				}
+				this.androidflType=1;
+				this.showFW(uobj,false);
+				this.audioObj.play();
+			}
+			else{//ios
+				this.imCall();
+			}
+		},
+		immessagerecive(str){
+			if(str.indexOf("\\\"")!=-1){
+				str=str.replace(/\\\"/g, '\"');
+				str = str.replace(/\"{/g, '{');
+				str = str.replace(/}\"/g, '}');
+			}
+			var obj = JSON.parse(str);
+			if(this.isAndroid){
+				if(this.androidflType!=0){
+					return;
+				}
+				var uobj={
+					name:obj.nickName,
+					content:this.$t('exchange.cteyhmsg'),
+					call:this.$t('exchange.chakanxinxi'),
+					uncall:this.$t('exchange.quxiao')
+				}
+				this.androidflType=2;
+				this.showFW(uobj,false);
+				this.audioObj.play();
+			}
+			else{//ios
+				this.imMessage();
+			}
+		},
+		//android-------------------------------------------------
+		showFW(obj,isInit) { //显示
+			var that = this;
+			callerID.show({
+					gravity: 1, //显示位置:0中间 1上 2下
+					name:obj.name,//用户昵称 ,
+					content:obj.content,//说明是骑手来电、来信息
+					call: obj.call,//接听IM,查看IM信息
+					uncall: obj.uncall,//拒绝接听IM,拒绝查看IM信息
+					empty: "",
+					avatar: "/static/logo.png",
+					totalHint: "",
+					tel: "",
+					list:[]
+				},
+				(res) => {
+					console.log(res);
+					if(isInit){
+						that.hideFW()
+					}
+					// uni.showToast({
+					// 	title: res.msg,
+					// 	icon: "none",
+					// 	duration: 3000
+					// })
+				});
+		},
+		hideFW() { //隐藏
+			this.androidflType=0;
+			callerID.hide(
+				(res) => {
+					console.log(res);
+					// uni.showToast({
+					// 	title: res.msg,
+					// 	icon: "none",
+					// 	duration: 3000
+					// })
+				});
+		},
+		permissionFW() { //申请悬浮窗权限
+			callerID.permission(
+				(res) => {
+					console.log(res);
+				});
+		},
+		goPermissionFW() { //跳转到悬浮窗权限页面
+			callerID.goPermission(
+				(res) => {
+					console.log(res);
+				});
+		},
+		isPermissionFW() { //是否申请悬浮窗权限
+			var that = this;
+			callerID.isPermission(
+				(res) => {
+					console.log(res);
+					if (res.data) {
+						if(res.data.isPermission){
+							var uobj={
+								name:'CTE',
+								content:'',
+								call:'',
+								uncall:''
+							}
+							that.showFW(uobj,true);
+						}
+						else{
+							that.goPermissionFW();
+						}
+					}
+				});
+		},
+		//ios--------------------------------------
+		showpiaof(index){
+			
+			var that = this;
+			if(index==1){
+				setTimeout(function() {
+				  // 这里写要延时执行的代码
+				  that.initPip("landscape");
+				}, 800);
+			}
+			if(index==2){
+				that.closePip();
+			}
+			if(index==3){
+				var language = uni.getStorageSync('language');
+				if(language=='yuenan'){
+					var dic = {
+					    "js": "changeImgvi()"
+					}
+					KJPip.webView_evaluateJavaScript(dic, (res) => {
+					    console.log("webView_evaluateJavaScript:" + JSON.stringify(res));
+					})
+				}
+				else{
+					var dic = {
+					    "js": "changeImg()"
+					}
+					KJPip.webView_evaluateJavaScript(dic, (res) => {
+					    console.log("webView_evaluateJavaScript:" + JSON.stringify(res));
+					})
+				}
+			}
+			if(index==4){
+				var language = uni.getStorageSync('language');
+				if(language=='yuenan'){
+					var dic = {
+					    "js": "changeImgMSvi()"
+					}
+					KJPip.webView_evaluateJavaScript(dic, (res) => {
+					    console.log("webView_evaluateJavaScript:" + JSON.stringify(res));
+					})
+				}
+				else{
+					var dic = {
+					    "js": "changeImgMS()"
+					}
+					KJPip.webView_evaluateJavaScript(dic, (res) => {
+					    console.log("webView_evaluateJavaScript:" + JSON.stringify(res));
+					})
+				}
+			}
+			return '';
+		},
+		initPip(shape) {
+		    var dic = {
+		        "shape": shape, //弹窗形状 square(正方形) landscape(横向) portrait(竖向)
+		    }
+		    KJPip.initPip(dic)
+			
+			console.log('initPip')
+			var that = this;
+			that.iosInit=true;
+			setTimeout(function() {
+			  // 这里写要延时执行的代码
+			  that.openPip1();
+			}, 2000);
+		},
+		openPip1() {//打开,加载本地页面?language='+language
+			var language = uni.getStorageSync('language');
+		    this.openPip(plus.io.convertLocalFileSystemURL("hybrid/html/xuanfu/index.html"));
+		},
+		openPip(url) {
+			var that = this;
+		    KJPip.isPictureInPictureActive((res) => {
+		        console.log("isPictureInPictureActive:" + JSON.stringify(res));
+		    })
+		    KJPip.isPictureInPictureSuspended((res) => {
+		        console.log("isPictureInPictureSuspended:" + JSON.stringify(res));
+		    })
+		    KJPip.isPictureInPicturePossible((res) => {
+		        console.log("isPictureInPicturePossible:" + JSON.stringify(res));
+				// if(!res.result){
+				// 	setTimeout(function() {
+				// 	  // 这里写要延时执行的代码
+				// 	  //that.initPip("landscape");
+				// 	}, 800);
+				// }
+		    })
+		    KJPip.isPictureInPictureSupported((res) => {
+		        console.log("isPictureInPictureSupported:" + JSON.stringify(res));
+		    })
+		    var dic = {
+		        "url": url
+		    }
+		    KJPip.openPip(dic, (res) => {
+		        console.log("openPip:" + JSON.stringify(res));
+		    })
+		},
+		closePip() {//关闭弹窗
+		    KJPip.closePip()
+		},
+		
+		imCall(){//收到IM语音通话请求
+			
+			uni.navigateTo({
+				url:'/pages/imcall/audioCall?iscaller=0'
+			})
+			
+		},
+		
+		imMessage(){//收到im文字聊天请求
+			// plus.runtime.launchApplication({action:'cityexpress1688ptqs://'},
+			// function(e){
+			// 	console.log('launchApplication',e);
+			// });
+			// plus.runtime.openURL('cityexpress1688ptqs://', function(res) {
+			// console.log('123123',res);
+			// });
+			uni.navigateTo({
+				url:'/pages/imcall/GoeasyExchange?iscaller=0'
+			})
+			
+		},
+		
+		imdef(){//收到im文字聊天请求
+			var dic = {
+			    "js": "changeImgdef()"
+			}
+			KJPip.webView_evaluateJavaScript(dic, (res) => {
+			    console.log("webView_evaluateJavaScript:" + JSON.stringify(res));
+			})
+		},
+		
+		onH5SendDataCallBack() { //注意ios16之后,弹出里的内容不能点击
+			var that = this;
+		    KJPip.onH5SendDataCallBack((res) => {
+				console.log("onH5SendDataCallBack:",res);
+				// if(res.result){
+				// 	var obj = JSON.parse(res.result);
+				// 	if(obj.key==1){
+				// 		uni.navigateTo({
+				// 			url:'/pages/imcall/audioCall?iscaller=0'
+				// 		})
+				// 		that.imdef();
+				// 	}
+				// 	else if(obj.key==2){
+				// 		uni.navigateTo({
+				// 			url:'/pages/imcall/ExchangeView?iscaller=0'
+				// 		})
+				// 		that.imdef();
+				// 	}
+				// }
+		    })
+		},
+		//GoEasy--------------------------------------------
+		connectGoEasy() {
+			var that = this;
+			if(that.globalData.goEasycnt==true){
+				that.goeasydisconnect();
+				return;
+			}
+			var userInfo=uni.getStorageSync('userInfo');
+			if(''==userInfo||null==userInfo||undefined==userInfo){
+				return;
+			}
+		    this.goEasy.connect({
+				id:'userid_'+userInfo.userId,
+				data: {
+				  name:userInfo.nickName,
+				  avatar:userInfo.avatar
+				},
+				onSuccess: () => {
+				  console.log('GoEasy connect successfully.')
+				  that.goEasyPush();
+				  that.globalData.goEasycnt=true;
+				},
+				onFailed: (error) => {
+				  console.log('Failed to connect GoEasy, code:' + error.code + ',error:' + error.content);
+				},
+				onProgress: (attempts) => {
+				  console.log('GoEasy is connecting', attempts);
+				}
+		  });
+		},
+		goEasyPush(){
+			var userInfo=uni.getStorageSync('userInfo');
+			if(''==userInfo||null==userInfo||undefined==userInfo){
+				return;
+			}
+			//console.log(userInfo);
+			var that = this;
+			var pubsub = this.goEasy.pubsub;
+			pubsub.subscribe({
+				channel:'userid_'+userInfo.userId,
+				onMessage: function (message) {
+					if(message.content){
+						var obj = JSON.parse(message.content);
+						if(obj.ptype==1){
+							if(that.globalData.imViewOpen){
+								return;
+							}
+							uni.setStorageSync('impayload',message.content);
+							that.imcallrecive(message.content);
+						}
+						if(obj.ptype==2){
+							if(that.globalData.EXViewOpen){
+								return;
+							}
+							uni.setStorageSync('impayload',message.content);
+							that.immessagerecive(message.content);
+						}
+					}
+					console.log("Channel:" + message.channel + " content:" + message.content)
+				},
+				onSuccess: function () {
+					console.log("Subscribe successfully.")
+				},
+				onFailed: function () {
+					console.log("Subscribe successfully.")
+				}
+			});
+		},
+		//断开连接
+		goeasydisconnect(){
+			var that = this;
+			this.goEasy.disconnect({
+			    onSuccess: function(){
+			        console.log("GoEasy disconnect successfully.")
+					that.globalData.goEasycnt=false;
+					that.connectGoEasy();
+			    },
+			    onFailed: function(error){
+			        console.log("Failed to disconnect GoEasy, code:"+error.code+ ",error:"+error.content);
+			    }
+			});
+		},
+//开启保活---------------------------------------------------------------------------------
+	kaiqibaohuo(){
+		if (this.isAndroid) {
+			this.requestPermission([
+				"android.permission.FOREGROUND_SERVICE",
+				"android.permission.POST_NOTIFICATIONS",
+				"android.permission.ACCESS_COARSE_LOCATION",
+				"android.permission.ACCESS_FINE_LOCATION",
+				"android.permission.WRITE_EXTERNAL_STORAGE",
+				"android.permission.ACCESS_BACKGROUND_LOCATION"
+			]);
+			
+		} else {
+			var authorizationStatus = UTSKeepalive.getAuthorizationStatus();
+			if (authorizationStatus == 0) {// 没有授权过定位时,请求定位权限
+				keepalive.requestLocationAuthorization()
+			}
+			console.log('kaiqibaohuokaiqibaohuokaiqibaohuo-----')
+		
+			// 监听app前后台状态
+			UTSKeepalive.listenerApp((resp) => {
+				let opt = resp.opt
+				switch (opt) {
+					// app进入后台
+					case "enterBackground": {
+						var authorizationStatus = UTSKeepalive.getAuthorizationStatus();
+		
+						console.log("authorizationStatus:" + authorizationStatus)
+		
+						// app进入后台,此时采用定位保活还是采用播放音乐保活可以根据自己业务决定
+						if (authorizationStatus == 3) { // 当定位权限是总是一直定位时采用定位来保活
+							console.log("定位保活")
+							keepalive.startLocation({
+								desiredAccuracy: "NearestTenMeters",
+								allowsBackgroundLocationUpdates: true, // 允许后台更新位置
+								pausesLocationUpdatesAutomatically: false // 不允许自动暂停更新位置
+							})
+						} else { // 采用播放音乐保活
+							console.log("播放音乐保活")
+							UTSKeepalive.setCategory("playback")
+							var url = plus.io.convertLocalFileSystemURL('_www/static/bgmusic.mp3');
+				
+							keepalive.playMusic({
+								url: url,
+								numberOfLoops: -1, // 循环此时,-1表示无限循环
+								volume: 0 // 音量,0
+							});
+						}
+						// 通知系统开始后台任务
+						UTSKeepalive.beginBackgroundTask()
+					}
+					break;
+					// app回到前台
+					case "enterForeground": {
+						// 停止播放音乐
+						keepalive.stopMusic()
+						// 停止定位
+						keepalive.stopLocation()
+						// 通知系统结束后台任务
+						UTSKeepalive.endBackgroundTask()
+					}
+		
+					break;
+					default:
+						break;
+				}
+			})
+		}
+	},
+	requestPermission: function(permissions) {
+		var that = this;
+		plus.android.requestPermissions(
+			permissions,
+			function(resultObj) {
+				for (var i = 0; i < resultObj.granted.length; i++) {
+					var grantedPermission = resultObj.granted[i];
+					//console.log('已获取的权限:' + grantedPermission);
+				}
+				if(resultObj.granted.length>=5){
+					that.keepAlive();
+					return;
+				}
+				for (var i = 0; i < resultObj.deniedPresent.length; i++) {
+					var deniedPresentPermission = resultObj.deniedPresent[i];
+					console.log('拒绝本次申请的权限:' + deniedPresentPermission);
+				}
+				for (var i = 0; i < resultObj.deniedAlways.length; i++) {
+					var deniedAlwaysPermission = resultObj.deniedAlways[i];
+					console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
+				}
+				// 若所需权限被永久拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限  
+				if (resultObj.deniedAlways.length > 0) {
+					uni.showModal({
+						cancelText: that.$t('index.quxiao'), // 取消按钮的文字
+						confirmText: that.$t('index.queren'), // 确认按钮的文字 
+					    title: that.$t('api.message'),
+					    content: that.$t('user.dingweiquanxian'),
+					    success: function (res) {
+							if (res.confirm) { //这里是点击了确定以后
+								that.kaiqidingwei();
+							} else { //这里是点击了取消以后
+							  console.log('用户点击取消')
+							}
+							
+					    }
+					})
+				}
+			},
+			function(error) {
+				console.log('申请权限错误:' + error.code + " = " + error.message);
+			});
+	},
+	keepAlive() {
+		console.log('keepAlive')
+		let params = this.getAndroidNotification();
+		console.log(params)
+		UTSKeepalive.startForegroundService(params)
+	
+		UTSKeepalive.startJobService(params)
+		UTSKeepalive.startLocalService(params)
+		UTSKeepalive.startRemoteService(params)
+	
+		UTSKeepalive.startScreenLockReceiver();
+		// 后台定位功能,用不到后台定位可以不需要调用
+		let locationParams = {}
+		locationParams.notification = params
+		locationParams.location = {
+		    provider: "gps", // 支持gps、fused
+		    minTimeMs:3000, // 间隔时间,这里为了测试效果,设置为500毫秒,实际情况根据自己业务设置
+		    minDistanceM: 15 // 间隔距离,这里为了测试效果,设置为0.5米,实际情况根据自己业务设置
+		}
+		UTSKeepalive.startLocstionService(locationParams)
+	},
+	//开启定位权限------------------------------
+	kaiqidingwei(){
+		var Intent = plus.android.importClass("android.content.Intent");
+		var Settings = plus.android.importClass("android.provider.Settings");
+		var Uri = plus.android.importClass("android.net.Uri");
+		var mainActivity = plus.android.runtimeMainActivity();
+		var intent = new Intent();
+		intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+		var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
+		intent.setData(uri);
+		mainActivity.startActivity(intent);
+		console.log("kaiqidingwei------")
+	},
+	getAndroidNotification() {
+		let channelId = 10
+		let params = {}
+		params.identifier = "123" // 通知ID,主要用于修改、删除通知,android里的identifier必须是数字,iOS的identifier可以是任意字符串
+		params.channel = { // 如果已经channelId的channel则不创建,如果没有则会自动创建
+			channelId: channelId,
+			channelName: "Bảo hành",
+			importance: 5, // 3: default 4: high 2: low 5: max 1: min 0: none
+			lockscreenVisibility: 1, //1: public 0: private -1: secret
+			description: "Bảo hành"
+		}
+		params.notification = {
+			channelId: channelId, // 此消息通知是属于哪个channel的
+			contentTitle: "Bảo hành",
+			contentText: "Bảo hành",
+			visibility: 1, // 1: public 0: private -1: secret
+			smallIcon: { // 小图标,必传
+				type: "resource", // 固定
+				defType: "drawable", // 固定
+				name: "not" // 文件名,不要带文件后缀,对应nativeResources/android/res/drawable文件夹下的图片
+			},
+			autoCancel: false
+		}
+		return params
+	},
+	},
+  }
+</script>
+
+<style lang="scss">
+
+.content{
+	display: flex;
+	flex-direction: column;
+	width: 94%;
+	margin-left: 3%;
+	background-color: white;
+	border-radius: 16rpx;
+	box-shadow: 0rpx 0rpx 10rpx 0rpx lightgray;
+}
+.contentInRowL{
+	display: flex;
+	flex-direction: row;
+	justify-content: flex-start;
+}
+
+.contentInRowR{
+	display: flex;
+	flex-direction: row;
+	justify-content:flex-end;
+}
+
+.contentInRowC{
+	display: flex;
+	flex-direction: row;
+	justify-content: center;
+	align-items: center;
+}
+
+.contentInRowS{
+	display: flex;
+	flex-direction: row;
+	align-items: center;
+	justify-content: space-between;
+}
+
+.contentColumn{
+	display: flex;
+	flex-direction: column;
+}
+
+.contentColumnC{
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+}
+
+.text1row{
+	overflow: hidden;
+	text-overflow: ellipsis;
+	/* #ifndef APP-PLUS-NVUE */
+	display: -webkit-box;
+	-webkit-line-clamp: 1;
+	-webkit-box-orient: vertical;
+	/* #endif */
+}
+.text2row{
+	overflow: hidden;
+	text-overflow: ellipsis;
+	/* #ifndef APP-PLUS-NVUE */
+	display: -webkit-box;
+	-webkit-line-clamp: 2;
+	-webkit-box-orient: vertical;
+	/* #endif */
+}
+</style>

+ 21 - 0
Info.plist

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+	<dict>
+		<key>UIBackgroundModes</key>
+		<array>
+			<string>location</string>
+			<string>audio</string>
+		</array>
+		<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
+		<string>Thông tin định vị được sử dụng cho các dịch vụ giao hàng và giao hàng chuyển phát nhanh đơn đặt hàng.</string>
+		<key>NSLocationAlwaysUsageDescription</key>
+		<string>Thông tin định vị được sử dụng cho các dịch vụ giao hàng và giao hàng chuyển phát nhanh đơn đặt hàng.</string>
+		<key>NSLocationTemporaryUsageDescriptionDictionary</key>
+		<string>Thông tin định vị được sử dụng cho các dịch vụ giao hàng và giao hàng chuyển phát nhanh đơn đặt hàng.</string>
+		<key>NSLocationUsageDescription</key>
+		<string>Thông tin định vị được sử dụng cho các dịch vụ giao hàng và giao hàng chuyển phát nhanh đơn đặt hàng.</string>
+		<key>NSLocationWhenInUseUsageDescription</key>
+		<string>Thông tin định vị được sử dụng cho các dịch vụ giao hàng và giao hàng chuyển phát nhanh đơn đặt hàng.</string>
+	</dict>
+</plist>

+ 21 - 0
LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 DCloud
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 15 - 0
README.md

@@ -0,0 +1,15 @@
+# hello-i18n
+
+# en
+
+A demo project for uni-app globalization
+
+This template include uni-framework, manifest.json, pages.json, tabbar, Page, Component, API
+
+
+# zh-hans
+
+uni-app 国际化演示
+
+包含 uni-framework、manifest.json、pages.json、tabbar、页面、组件、API
+

+ 736 - 0
TrtcCloud/lib/TrtcCloudImpl.js

@@ -0,0 +1,736 @@
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+    return new (P || (P = Promise))(function (resolve, reject) {
+        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+        step((generator = generator.apply(thisArg, _arguments || [])).next());
+    });
+};
+import { NAME } from './constants';
+import { TRTCRoleType, TRTCAudioQuality, TRTCVideoRotation, TRTCVideoFillMode, TRTCVideoMirrorType, TRTCVideoStreamType, TRTCVideoEncParam, TRTCAppScene, TRTCAudioRoute, TRTCBeautyStyle, } from './TrtcDefines';
+import TrtcError, { TXLiteJSError, generateError_ } from './TrtcCode';
+const TrtcNativeTrtcCloudModule = uni.requireNativePlugin('TRTCCloudUniPlugin-TRTCCloudImpl');
+const TXAudioEffectManagerModule = uni.requireNativePlugin('TRTCCloudUniPlugin-TRTCCloudImpl-TXAudioEffectManagerModule');
+const TrtcEvent = uni.requireNativePlugin('globalEvent');
+let trtcCloud = null; // trtcCloud 单例
+export default class TrtcCloudImpl {
+    constructor() {
+        this.listenersMap_ = new Map();
+    }
+    static _createInstance() {
+        try {
+            if (trtcCloud) {
+                return trtcCloud;
+            }
+            TrtcNativeTrtcCloudModule.sharedInstance();
+            trtcCloud = new TrtcCloudImpl();
+            return trtcCloud;
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    static _getInstance() {
+        if (trtcCloud) {
+            return trtcCloud;
+        }
+        throw new TrtcError({
+            code: TXLiteJSError.INVALID_OPERATION,
+            message: 'get trtcCloud failed, please create trtcCloud first',
+        });
+    }
+    static _destroyInstance() {
+        try {
+            trtcCloud = null;
+            TrtcNativeTrtcCloudModule.destroySharedInstance();
+        }
+        catch (error) {
+            throw new TrtcError({
+                code: error.code || TXLiteJSError.UNKNOWN,
+                message: error.message,
+                name: error.name,
+            });
+        }
+    }
+    // 截图保存
+    // async saveImage_(base64Data) {
+    //   return new Promise((resolve, reject) => {
+    //     let bitmap = new plus.nativeObj.Bitmap();
+    //     bitmap.loadBase64Data(base64Data, () => {
+    //       const url = "_doc/" + new Date().getTime() + ".png";  // url为时间戳命名方式
+    //       console.log('saveHeadImgFile', url);
+    //       bitmap.save(url, { overwrite: true }, (i) => {
+    //         uni.saveImageToPhotosAlbum({
+    //           filePath: url,
+    //           success: function() {
+    //             uni.showToast({
+    //               title: '图片保存成功',
+    //               icon: 'none'
+    //             })
+    //             bitmap.clear();
+    //             resolve({ code: 0, message: '图片保存成功' });
+    //           }
+    //         });
+    //       }, (e) => {
+    //         uni.showToast({
+    //           title: '图片保存失败, 请重新截图',
+    //           icon: 'none'
+    //         })
+    //         bitmap.clear();
+    //         resolve({ code: -1, message: '图片保存失败, 请重新截图' });
+    //       });
+    //     });
+    //   });
+    // }
+    on(event, callback) {
+        if (typeof event !== NAME.STRING || typeof callback !== NAME.FUNCTION) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the on method parameter types. event type is a ${typeof event}; callback type is a ${typeof callback}`,
+            });
+        }
+        const nativeListener = (res) => __awaiter(this, void 0, void 0, function* () {
+            const { data = [] } = res;
+            const code = data[0];
+            const message = data[1];
+            const extraInfo = data[2];
+            switch (event) {
+                case 'onEnterRoom': {
+                    const result = code;
+                    callback(result);
+                    break;
+                }
+                case 'onExitRoom': {
+                    const reason = code;
+                    callback(reason);
+                    break;
+                }
+                case 'onFirstVideoFrame': {
+                    const userId = code;
+                    const streamType = data[1];
+                    const width = data[2];
+                    const height = data[3];
+                    callback({ userId, streamType, width, height });
+                    break;
+                }
+                case 'onFirstAudioFrame': {
+                    const userId = code;
+                    callback(userId);
+                    break;
+                }
+                case 'onMicDidReady': {
+                    callback();
+                    break;
+                }
+                case 'onCameraDidReady': {
+                    callback();
+                    break;
+                }
+                case 'onNetworkQuality': {
+                    const localQuality = data[0];
+                    const remoteQuality = data[1];
+                    callback({ localQuality, remoteQuality });
+                    break;
+                }
+                case 'onRemoteUserEnterRoom': {
+                    const userId = code;
+                    callback(userId);
+                    break;
+                }
+                case 'onRemoteUserLeaveRoom': {
+                    const userId = code;
+                    const reason = message;
+                    callback({ userId, reason });
+                    break;
+                }
+                case 'onSendFirstLocalAudioFrame': {
+                    callback();
+                    break;
+                }
+                case 'onSendFirstLocalVideoFrame': {
+                    const streamType = code;
+                    callback(streamType);
+                    break;
+                }
+                case 'onStatistics': {
+                    const statics = data[0];
+                    callback(statics);
+                    break;
+                }
+                case 'onUserAudioAvailable': {
+                    const userId = code;
+                    const available = message;
+                    callback({ userId, available });
+                    break;
+                }
+                case 'onUserVideoAvailable': {
+                    const userId = code;
+                    const available = message;
+                    callback({ userId, available });
+                    break;
+                }
+                case 'onUserVoiceVolume': {
+                    const userVolumes = data[0];
+                    const totalVolume = data[1];
+                    callback({ userVolumes, totalVolume });
+                    break;
+                }
+                case 'onSwitchRole': {
+                    callback({ code, message });
+                    break;
+                }
+                case 'onScreenCaptureStarted': {
+                    callback({ code, message });
+                    break;
+                }
+                case 'onScreenCapturePaused': {
+                    callback({ code, message });
+                    break;
+                }
+                case 'onScreenCaptureResumed': {
+                    callback({ code, message });
+                    break;
+                }
+                case 'onScreenCaptureStopped': {
+                    callback({ code, message });
+                    break;
+                }
+                case 'onUserSubStreamAvailable': {
+                    const userId = code;
+                    const available = message;
+                    callback({ userId, available });
+                    break;
+                }
+                case 'onSnapshotComplete': {
+                    // base64 直接保存到本地图库
+                    // const { code: snapShotCode, message: msg } = await this.saveImage_(code);
+                    // callback({ snapShotCode, message: msg });
+                    callback({ base64Data: code, message });
+                    break;
+                }
+                case 'onUserVideoSizeChanged': {
+                    callback(data);
+                    break;
+                }
+                case 'onStart': {
+                    callback({ id: code, errCode: message });
+                    break;
+                }
+                case 'onPlayProgress': {
+                    callback({ id: code, curPtsMS: message, durationMS: extraInfo });
+                    break;
+                }
+                case 'onComplete': {
+                    callback({ id: code, errCode: message });
+                    break;
+                }
+                case 'onConnectOtherRoom': {
+                    // 拿不到 userid, 为了和 native 参数保持一致,所以空字符串代替
+                    callback({ userId: '', errCode: code, errMsg: message });
+                    break;
+                }
+                case 'onDisconnectOtherRoom': {
+                    callback({ errCode: code, errMsg: message });
+                    break;
+                }
+                case 'onError': {
+                    console.error(`onError: ${code}, ${message}, ${extraInfo}`);
+                    callback(generateError_({ message }, code, extraInfo));
+                    break;
+                }
+                default: {
+                    callback({ code, message, extraInfo });
+                }
+            }
+        });
+        this.listenersMap_.set(event, nativeListener); // 多次设置同一个事件时,后面的 callback 覆盖前面
+        TrtcEvent.addEventListener(event, nativeListener);
+    }
+    off(event) {
+        if (typeof event !== NAME.STRING) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the off method parameter types. event type is a ${typeof event} not a ${NAME.STRING}`,
+            });
+        }
+        try {
+            if (event === '*') {
+                this.listenersMap_.forEach((value, key) => {
+                    TrtcEvent.removeEventListener(key, value);
+                });
+                this.listenersMap_.clear();
+            }
+            else {
+                TrtcEvent.removeEventListener(event, this.listenersMap_.get(event));
+                this.listenersMap_.delete(event);
+            }
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    enterRoom(params, scene) {
+        if (scene !== TRTCAppScene.TRTCAppSceneVideoCall && scene !== TRTCAppScene.TRTCAppSceneLIVE && scene !== TRTCAppScene.TRTCAppSceneAudioCall && scene !== TRTCAppScene.TRTCAppSceneVoiceChatRoom) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the enterRoom method parameters. scene is not of TRTCAppScene`,
+            });
+        }
+        try {
+            const enterRoomParams = Object.assign(Object.assign({}, params), { role: params.role || TRTCRoleType.TRTCRoleAnchor, appScene: scene });
+            TrtcNativeTrtcCloudModule.enterRoom(enterRoomParams);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    exitRoom() {
+        try {
+            TrtcNativeTrtcCloudModule.exitRoom();
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    connectOtherRoom(params) {
+        try {
+            TrtcNativeTrtcCloudModule.connectOtherRoom(params);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    disconnectOtherRoom() {
+        try {
+            TrtcNativeTrtcCloudModule.disconnectOtherRoom();
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    switchRole(role) {
+        if (role !== TRTCRoleType.TRTCRoleAnchor && role !== TRTCRoleType.TRTCRoleAudience) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the switchRole method parameter. role is not of TRTCRoleType`,
+            });
+        }
+        try {
+            role && TrtcNativeTrtcCloudModule.switchRole(role);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    startLocalPreview(isFrontCamera = true, viewId) {
+        if (typeof isFrontCamera !== NAME.BOOLEAN || !viewId || typeof viewId !== NAME.STRING) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the startLocalPreview method parameters`,
+            });
+        }
+        try {
+            let param = { isFrontCamera: !!isFrontCamera };
+            param = viewId ? Object.assign(Object.assign({}, param), { userId: viewId }) : param;
+            TrtcNativeTrtcCloudModule.startLocalPreview(param);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    setVideoEncoderParam(param) {
+        try {
+            TrtcNativeTrtcCloudModule.setVideoEncoderParam(param);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    stopLocalPreview() {
+        try {
+            TrtcNativeTrtcCloudModule.stopLocalPreview();
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    switchCamera(isFrontCamera) {
+        if (typeof isFrontCamera !== NAME.BOOLEAN) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the switchCamera method parameter`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.switchCamera(isFrontCamera);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    setLocalRenderParams(params) {
+        try {
+            const { rotation = TRTCVideoRotation.TRTCVideoRotation_0, fillMode = TRTCVideoFillMode.TRTCVideoFillMode_Fill, mirrorType = TRTCVideoMirrorType.TRTCVideoMirrorType_Auto } = params;
+            TrtcNativeTrtcCloudModule.setLocalRenderParams({
+                rotation,
+                fillMode,
+                mirrorType,
+            });
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    muteLocalVideo(streamType, mute) {
+        if (streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSub || typeof mute !== NAME.BOOLEAN) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the muteLocalVideo method parameters`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.muteLocalVideo({ streamType, mute: !!mute });
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    startRemoteView(userId, streamType, viewId) {
+        if (!userId || streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSmall && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSub || !viewId) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the startRemoteView method parameters`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.startRemoteView({ userId, streamType, viewId });
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    stopRemoteView(userId, streamType) {
+        if (!userId || streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSmall && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSub) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the stopRemoteView method parameters`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.stopRemoteView({ userId, streamType });
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    // 远端渲染设置
+    setRemoteRenderParams(userId, streamType, params) {
+        try {
+            if (!userId || (streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSub)) {
+                throw new TrtcError({
+                    code: TXLiteJSError.INVALID_PARAMETER,
+                    message: `${NAME.LOG_PREFIX} please check the snapshotVideo method parameters`,
+                });
+            }
+            const { rotation = TRTCVideoRotation.TRTCVideoRotation_0, fillMode = TRTCVideoFillMode.TRTCVideoFillMode_Fill, mirrorType = TRTCVideoMirrorType.TRTCVideoMirrorType_Auto } = params;
+            TrtcNativeTrtcCloudModule.setRemoteRenderParams({
+                userId,
+                streamType,
+                rotation,
+                fillMode,
+                mirrorType
+            });
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    // 设置视频编码器输出的画面方向
+    setVideoEncoderRotation(rotation) {
+        if (typeof rotation !== NAME.NUMBER) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the setVideoEncoderRotation method parameter`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.setVideoEncoderRotation(rotation);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    // 设置编码器输出的画面镜像模式
+    setVideoEncoderMirror(mirror) {
+        if (typeof mirror !== NAME.BOOLEAN) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the setVideoEncoderMirror method parameter`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.setVideoEncoderMirror(mirror);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    // 设置重力感应的适配模式
+    setGSensorMode(mode) {
+        if (typeof mode !== NAME.NUMBER) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the setGSensorMode method parameter`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.setGSensorMode(mode);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    // 截图
+    snapshotVideo(userId, streamType, sourceType) {
+        if (streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSub) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the snapshotVideo method parameters`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.snapshotVideo({ userId: userId || null, streamType, sourceType });
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    startLocalAudio(quality = TRTCAudioQuality.TRTCAudioQualityDefault) {
+        if (quality !== TRTCAudioQuality.TRTCAudioQualitySpeech && quality !== TRTCAudioQuality.TRTCAudioQualityDefault && quality !== TRTCAudioQuality.TRTCAudioQualityMusic) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the startLocalAudio method parameters`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.startLocalAudio(quality);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    stopLocalAudio() {
+        try {
+            TrtcNativeTrtcCloudModule.stopLocalAudio();
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    muteLocalAudio(mute) {
+        if (typeof mute !== NAME.BOOLEAN) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the muteLocalAudio method parameters, mute type is a ${typeof mute} not a ${NAME.BOOLEAN}`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.muteLocalAudio(!!mute);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    muteRemoteAudio(userId, mute) {
+        if (typeof mute !== NAME.BOOLEAN || !userId) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the muteRemoteAudio method parameters`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.muteRemoteAudio({ userId, mute: !!mute });
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    muteAllRemoteAudio(mute) {
+        if (typeof mute !== NAME.BOOLEAN) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the muteAllRemoteAudio method parameters, mute type is a ${typeof mute} not a ${NAME.BOOLEAN}`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.muteAllRemoteAudio(!!mute);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    setAudioRoute(route) {
+        if (route !== TRTCAudioRoute.TRTCAudioRouteSpeaker && route !== TRTCAudioRoute.TRTCAudioRouteEarpiece) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the setAudioRoute method parameter, route is not of TRTCAudioRoute`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.setAudioRoute(route);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    enableAudioVolumeEvaluation(interval) {
+        if (typeof interval !== NAME.NUMBER) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the enableAudioVolumeEvaluation method parameter, interval type is a ${typeof interval} not a ${NAME.NUMBER}`,
+            });
+        }
+        try {
+            interval > 0 && TrtcNativeTrtcCloudModule.enableAudioVolumeEvaluation(interval);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    // ///////////////////////////////////////////////////////////////////////////////
+    //
+    //                      美颜 + 水印
+    //
+    // ///////////////////////////////////////////////////////////////////////////////
+    setBeautyStyle(beautyStyle) {
+        if (beautyStyle !== TRTCBeautyStyle.TRTCBeautyStyleSmooth && beautyStyle !== TRTCBeautyStyle.TRTCBeautyStyleNature && beautyStyle !== TRTCBeautyStyle.TRTCBeautyStylePitu) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the setBeautyStyle method parameter, beautyStyle is not of TRTCBeautyStyle`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.setBeautyStyle(beautyStyle);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    setBeautyLevel(beautyLevel) {
+        if (typeof beautyLevel !== NAME.NUMBER || (beautyLevel < 0 || beautyLevel > 9)) {
+            throw new TrtcError({
+                code: TXLiteJSError.INVALID_PARAMETER,
+                message: `${NAME.LOG_PREFIX} please check the setBeautyLevel method parameter, beautyLevel should in the range 0-9`,
+            });
+        }
+        try {
+            TrtcNativeTrtcCloudModule.setBeautyLevel(beautyLevel);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    // ///////////////////////////////////////////////////////////////////////////////
+    //
+    //                      背景音效
+    //
+    // ///////////////////////////////////////////////////////////////////////////////
+    startPlayMusic(musicParam) {
+        try {
+            const { id = 0 } = musicParam || {};
+            TXAudioEffectManagerModule.startPlayMusic(Object.assign(Object.assign({}, musicParam), { ID: id })); // v1.2.0 的 iOS 解析的是 ID, v1.2.1 插件进行了修复
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    stopPlayMusic(id) {
+        try {
+            TXAudioEffectManagerModule.stopPlayMusic(id);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    pausePlayMusic(id) {
+        try {
+            TXAudioEffectManagerModule.pausePlayMusic(id);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    resumePlayMusic(id) {
+        try {
+            TXAudioEffectManagerModule.resumePlayMusic(id);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    // ///////////////////////////////////////////////////////////////////////////////
+    //
+    //                      屏幕分享
+    //
+    // ///////////////////////////////////////////////////////////////////////////////
+    setSubStreamEncoderParam(param) {
+        try {
+            TrtcNativeTrtcCloudModule.setSubStreamEncoderParam(param);
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    startScreenCapture(streamType = TRTCVideoStreamType.TRTCVideoStreamTypeSub, encParams = {}, shareParams = {}) {
+        try {
+            let platform = uni.getSystemInfoSync().platform;
+            if ((streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSub && streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig)) {
+                streamType = TRTCVideoStreamType.TRTCVideoStreamTypeSub;
+            }
+            const { enableForegroundService = true } = shareParams; // 默认开启前台服务, 避免退后台后进程被杀
+            const screenCaptureParams = Object.assign({ streamType }, encParams);
+            if (platform === NAME.ANDROID) {
+                TrtcNativeTrtcCloudModule.startScreenCapture(Object.assign(Object.assign({}, screenCaptureParams), { enableForegroundService }));
+            }
+            if (platform === NAME.IOS) {
+                // 开始应用内的屏幕分享(仅支持 iOS 13.0 及以上系统)
+                TrtcNativeTrtcCloudModule.startScreenCaptureInApp(screenCaptureParams);
+                // if (shareSource === TRTCShareSource.InApp) {
+                //   TrtcNativeTrtcCloudModule.startScreenCaptureInApp(screenCaptureParams);
+                // }
+                // // 开始全系统的屏幕分享(仅支持 iOS 11.0 及以上系统)
+                // if (shareSource === TRTCShareSource.ByReplaykit) {
+                //   TrtcNativeTrtcCloudModule.startScreenCaptureByReplaykit({ ...screenCaptureParams, appGroup: null });
+                // }
+            }
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    stopScreenCapture() {
+        try {
+            TrtcNativeTrtcCloudModule.stopScreenCapture();
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    pauseScreenCapture() {
+        try {
+            TrtcNativeTrtcCloudModule.pauseScreenCapture();
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+    resumeScreenCapture() {
+        try {
+            TrtcNativeTrtcCloudModule.resumeScreenCapture();
+        }
+        catch (error) {
+            throw generateError_(error);
+        }
+    }
+}

+ 612 - 0
TrtcCloud/lib/TrtcCode.js

@@ -0,0 +1,612 @@
+import { NAME, errorCodeUrl } from './constants';
+/**
+ * @namespace ErrorCode
+ *
+ * @description 错误码、警告码和事件列表
+ */
+/////////////////////////////////////////////////////////////////////////////////
+//
+//                     (一)错误码(严重)
+//
+/////////////////////////////////////////////////////////////////////////////////
+/**
+ * @memberof ErrorCode
+ * @typedef 错误码(严重)
+ * @description SDK 错误码(严重)对照表
+ * | 符号 | 值 | 含义 |
+ * |---|---|---|
+ * |ERR_NULL|0|无错误|
+ * |ERR_ROOM_ENTER_FAIL|-3301|进入房间失败|
+ * |ERR_ENTER_ROOM_PARAM_NULL|-3316|进房参数为空,请检查 enterRoom:appScene: 接口调用是否传入有效的 param|
+ * |ERR_SDK_APPID_INVALID|-3317|进房参数 sdkAppId 错误|
+ * |ERR_ROOM_ID_INVALID|-3318|进房参数 roomId 错误|
+ * |ERR_USER_ID_INVALID|-3319|进房参数 userID 不正确|
+ * |ERR_USER_SIG_INVALID|-3320|进房参数 userSig 不正确|
+ * |ERR_ROOM_REQUEST_ENTER_ROOM_TIMEOUT|-3308|请求进房超时,请检查网络|
+ * |ERR_SERVER_INFO_SERVICE_SUSPENDED|-100013|服务不可用。请检查:套餐包剩余分钟数是否大于0,腾讯云账号是否欠费|
+ * |ERR_ROOM_REQUEST_QUIT_ROOM_TIMEOUT|-3325|请求退房超时|
+ * |ERR_CAMERA_START_FAIL|-1301|打开摄像头失败,例如在 Windows 或 Mac 设备,摄像头的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序|
+ * |ERR_CAMERA_NOT_AUTHORIZED|-1314|摄像头设备未授权,通常在移动设备出现,可能是权限被用户拒绝了|
+ * |ERR_CAMERA_SET_PARAM_FAIL|-1315|摄像头参数设置出错(参数不支持或其它)|
+ * |ERR_CAMERA_OCCUPY|-1316|摄像头正在被占用中,可尝试打开其他摄像头|
+ * |ERR_MIC_START_FAIL|-1302|打开麦克风失败,例如在 Windows 或 Mac 设备,麦克风的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序|
+ * |ERR_MIC_NOT_AUTHORIZED|-1317|麦克风设备未授权,通常在移动设备出现,可能是权限被用户拒绝了|
+ * |ERR_MIC_SET_PARAM_FAIL|-1318|麦克风设置参数失败|
+ * |ERR_MIC_OCCUPY|-1319|麦克风正在被占用中,例如移动设备正在通话时,打开麦克风会失败|
+ * |ERR_MIC_STOP_FAIL|-1320|停止麦克风失败|
+ * |ERR_SPEAKER_START_FAIL|-1321|打开扬声器失败,例如在 Windows 或 Mac 设备,扬声器的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序|
+ * |ERR_SPEAKER_SET_PARAM_FAIL|-1322|扬声器设置参数失败|
+ * |ERR_SPEAKER_STOP_FAIL|-1323|停止扬声器失败|
+ * |ERR_SCREEN_CAPTURE_START_FAIL|-1308|开始录屏失败,如果在移动设备出现,可能是权限被用户拒绝了,如果在 Windows 或 Mac 系统的设备出现,请检查录屏接口的参数是否符合要求|
+ * |ERR_SCREEN_CAPTURE_UNSURPORT|-1309|录屏失败,在 Android 平台,需要5.0以上的系统|
+ * |ERR_SERVER_CENTER_NO_PRIVILEDGE_PUSH_SUB_VIDEO|-102015|没有权限上行辅路|
+ * |ERR_SERVER_CENTER_ANOTHER_USER_PUSH_SUB_VIDEO|-102016|其他用户正在上行辅路|
+ * |ERR_VIDEO_ENCODE_FAIL|-1303|视频帧编码失败,例如 iOS 设备切换到其他应用时,硬编码器可能被系统释放,再切换回来时,硬编码器重启前,可能会抛出|
+ * |ERR_UNSUPPORTED_RESOLUTION|-1305|不支持的视频分辨率|
+ * |ERR_AUDIO_ENCODE_FAIL|-1304|音频帧编码失败,例如传入自定义音频数据,SDK 无法处理|
+ * |ERR_UNSUPPORTED_SAMPLERATE|-1306|不支持的音频采样率|
+ * |ERR_PIXEL_FORMAT_UNSUPPORTED|-1327|设置的 pixel format 不支持|
+ * |ERR_BUFFER_TYPE_UNSUPPORTED|-1328|设置的 buffer type 不支持|
+ * |ERR_PUBLISH_CDN_STREAM_REQUEST_TIME_OUT|-3321|旁路转推请求超时|
+ * |ERR_CLOUD_MIX_TRANSCODING_REQUEST_TIME_OUT|-3322|云端混流请求超时|
+ * |ERR_PUBLISH_CDN_STREAM_SERVER_FAILED|-3323|旁路转推回包异常|
+ * |ERR_CLOUD_MIX_TRANSCODING_SERVER_FAILED|-3324|云端混流回包异常|
+ * |ERR_ROOM_REQUEST_START_PUBLISHING_TIMEOUT|-3333|开始向腾讯云的直播 CDN 推流信令超时|
+ * |ERR_ROOM_REQUEST_START_PUBLISHING_ERROR|-3334|开始向腾讯云的直播 CDN 推流信令异常|
+ * |ERR_ROOM_REQUEST_STOP_PUBLISHING_TIMEOUT|-3335|停止向腾讯云的直播 CDN 推流信令超时|
+ * |ERR_ROOM_REQUEST_STOP_PUBLISHING_ERROR|-3336|停止向腾讯云的直播 CDN 推流信令异常|
+ * |ERR_ROOM_REQUEST_CONN_ROOM_TIMEOUT|-3326|请求连麦超时|
+ * |ERR_ROOM_REQUEST_DISCONN_ROOM_TIMEOUT|-3327|请求退出连麦超时|
+ * |ERR_ROOM_REQUEST_CONN_ROOM_INVALID_PARAM|-3328|无效参数|
+ * |ERR_CONNECT_OTHER_ROOM_AS_AUDIENCE|-3330|当前是观众角色,不能请求或断开跨房连麦,需要先 switchRole() 到主播|
+ * |ERR_SERVER_CENTER_CONN_ROOM_NOT_SUPPORT|-102031|不支持跨房间连麦|
+ * |ERR_SERVER_CENTER_CONN_ROOM_REACH_MAX_NUM|-102032|达到跨房间连麦上限|
+ * |ERR_SERVER_CENTER_CONN_ROOM_REACH_MAX_RETRY_TIMES|-102033|跨房间连麦重试次数耗尽|
+ * |ERR_SERVER_CENTER_CONN_ROOM_REQ_TIMEOUT|-102034|跨房间连麦请求超时|
+ * |ERR_SERVER_CENTER_CONN_ROOM_REQ|-102035|跨房间连麦请求格式错误|
+ * |ERR_SERVER_CENTER_CONN_ROOM_NO_SIG|-102036|跨房间连麦无签名|
+ * |ERR_SERVER_CENTER_CONN_ROOM_DECRYPT_SIG|-102037|跨房间连麦签名解密失败|
+ * |ERR_SERVER_CENTER_CONN_ROOM_NO_KEY|-102038|未找到跨房间连麦签名解密密钥|
+ * |ERR_SERVER_CENTER_CONN_ROOM_PARSE_SIG|-102039|跨房间连麦签名解析错误|
+ * |ERR_SERVER_CENTER_CONN_ROOM_INVALID_SIG_TIME|-102040|跨房间连麦签名时间戳错误|
+ * |ERR_SERVER_CENTER_CONN_ROOM_SIG_GROUPID|-102041|跨房间连麦签名不匹配|
+ * |ERR_SERVER_CENTER_CONN_ROOM_NOT_CONNED|-102042|本房间无连麦|
+ * |ERR_SERVER_CENTER_CONN_ROOM_USER_NOT_CONNED|-102043|本用户未发起连麦|
+ * |ERR_SERVER_CENTER_CONN_ROOM_FAILED|-102044|跨房间连麦失败|
+ * |ERR_SERVER_CENTER_CONN_ROOM_CANCEL_FAILED|-102045|取消跨房间连麦失败|
+ * |ERR_SERVER_CENTER_CONN_ROOM_CONNED_ROOM_NOT_EXIST|-102046|被连麦房间不存在|
+ * |ERR_SERVER_CENTER_CONN_ROOM_CONNED_REACH_MAX_ROOM|-102047|被连麦房间达到连麦上限|
+ * |ERR_SERVER_CENTER_CONN_ROOM_CONNED_USER_NOT_EXIST|-102048|被连麦用户不存在|
+ * |ERR_SERVER_CENTER_CONN_ROOM_CONNED_USER_DELETED|-102049|被连麦用户已被删除|
+ * |ERR_SERVER_CENTER_CONN_ROOM_CONNED_USER_FULL|-102050|被连麦用户达到资源上限|
+ * |ERR_SERVER_CENTER_CONN_ROOM_INVALID_SEQ|-102051|连麦请求序号错乱|
+ */
+export const TXLiteAVError = {
+    /** 无错误 */
+    ERR_NULL: 0,
+    /** 进入房间失败 */
+    ERR_ROOM_ENTER_FAIL: -3301,
+    /** 进房参数为空,请检查 enterRoom:appScene: 接口调用是否传入有效的 param */
+    ERR_ENTER_ROOM_PARAM_NULL: -3316,
+    /** 进房参数 sdkAppId 错误 */
+    ERR_SDK_APPID_INVALID: -3317,
+    /** 进房参数 roomId 错误 */
+    ERR_ROOM_ID_INVALID: -3318,
+    /** 进房参数 userID 不正确 */
+    ERR_USER_ID_INVALID: -3319,
+    /** 进房参数 userSig 不正确 */
+    ERR_USER_SIG_INVALID: -3320,
+    /** 请求进房超时,请检查网络 */
+    ERR_ROOM_REQUEST_ENTER_ROOM_TIMEOUT: -3308,
+    /** 服务不可用。请检查:套餐包剩余分钟数是否大于0,腾讯云账号是否欠费 */
+    ERR_SERVER_INFO_SERVICE_SUSPENDED: -100013,
+    /** 请求退房超时 */
+    ERR_ROOM_REQUEST_QUIT_ROOM_TIMEOUT: -3325,
+    /** 打开摄像头失败,例如在 Windows 或 Mac 设备,摄像头的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序 */
+    ERR_CAMERA_START_FAIL: -1301,
+    /** 摄像头设备未授权,通常在移动设备出现,可能是权限被用户拒绝了 */
+    ERR_CAMERA_NOT_AUTHORIZED: -1314,
+    /** 摄像头参数设置出错(参数不支持或其它) */
+    ERR_CAMERA_SET_PARAM_FAIL: -1315,
+    /** 摄像头正在被占用中,可尝试打开其他摄像头 */
+    ERR_CAMERA_OCCUPY: -1316,
+    /** 打开麦克风失败,例如在 Windows 或 Mac 设备,麦克风的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序 */
+    ERR_MIC_START_FAIL: -1302,
+    /** 麦克风设备未授权,通常在移动设备出现,可能是权限被用户拒绝了 */
+    ERR_MIC_NOT_AUTHORIZED: -1317,
+    /** 麦克风设置参数失败 */
+    ERR_MIC_SET_PARAM_FAIL: -1318,
+    /** 麦克风正在被占用中,例如移动设备正在通话时,打开麦克风会失败 */
+    ERR_MIC_OCCUPY: -1319,
+    /** 停止麦克风失败 */
+    ERR_MIC_STOP_FAIL: -1320,
+    /** 打开扬声器失败,例如在 Windows 或 Mac 设备,扬声器的配置程序(驱动程序)异常,禁用后重新启用设备,或者重启机器,或者更新配置程序 */
+    ERR_SPEAKER_START_FAIL: -1321,
+    /** 扬声器设置参数失败 */
+    ERR_SPEAKER_SET_PARAM_FAIL: -1322,
+    /** 停止扬声器失败 */
+    ERR_SPEAKER_STOP_FAIL: -1323,
+    /** 开始录屏失败,如果在移动设备出现,可能是权限被用户拒绝了,如果在 Windows 或 Mac 系统的设备出现,请检查录屏接口的参数是否符合要求 */
+    ERR_SCREEN_CAPTURE_START_FAIL: -1308,
+    /** 录屏失败,在 Android 平台,需要5.0以上的系统 */
+    ERR_SCREEN_CAPTURE_UNSURPORT: -1309,
+    /** 没有权限上行辅路 */
+    ERR_SERVER_CENTER_NO_PRIVILEDGE_PUSH_SUB_VIDEO: -102015,
+    /** 其他用户正在上行辅路 */
+    ERR_SERVER_CENTER_ANOTHER_USER_PUSH_SUB_VIDEO: -102016,
+    /** 视频帧编码失败,例如 iOS 设备切换到其他应用时,硬编码器可能被系统释放,再切换回来时,硬编码器重启前,可能会抛出 */
+    ERR_VIDEO_ENCODE_FAIL: -1303,
+    /** 音频帧编码失败,例如传入自定义音频数据,SDK 无法处理 */
+    ERR_AUDIO_ENCODE_FAIL: -1304,
+    /** 不支持的视频分辨率 */
+    ERR_UNSUPPORTED_RESOLUTION: -1305,
+    /** 不支持的音频采样率 */
+    ERR_UNSUPPORTED_SAMPLERATE: -1306,
+    /** 设置的 pixel format 不支持 */
+    ERR_PIXEL_FORMAT_UNSUPPORTED: -1327,
+    /** 设置的 buffer type 不支持 */
+    ERR_BUFFER_TYPE_UNSUPPORTED: -1328,
+    /** 旁路转推请求超时 */
+    ERR_PUBLISH_CDN_STREAM_REQUEST_TIME_OUT: -3321,
+    /** 云端混流请求超时 */
+    ERR_CLOUD_MIX_TRANSCODING_REQUEST_TIME_OUT: -3322,
+    /** 旁路转推回包异常 */
+    ERR_PUBLISH_CDN_STREAM_SERVER_FAILED: -3323,
+    /** 云端混流回包异常 */
+    ERR_CLOUD_MIX_TRANSCODING_SERVER_FAILED: -3324,
+    /** 开始向腾讯云的直播 CDN 推流信令超时 */
+    ERR_ROOM_REQUEST_START_PUBLISHING_TIMEOUT: -3333,
+    /** 开始向腾讯云的直播 CDN 推流信令异常 */
+    ERR_ROOM_REQUEST_START_PUBLISHING_ERROR: -3334,
+    /** 停止向腾讯云的直播 CDN 推流信令超时 */
+    ERR_ROOM_REQUEST_STOP_PUBLISHING_TIMEOUT: -3335,
+    /** 停止向腾讯云的直播 CDN 推流信令异常 */
+    ERR_ROOM_REQUEST_STOP_PUBLISHING_ERROR: -3336,
+    /** 请求连麦超时 */
+    ERR_ROOM_REQUEST_CONN_ROOM_TIMEOUT: -3326,
+    /** 请求退出连麦超时 */
+    ERR_ROOM_REQUEST_DISCONN_ROOM_TIMEOUT: -3327,
+    /** 无效参数 */
+    ERR_ROOM_REQUEST_CONN_ROOM_INVALID_PARAM: -3328,
+    /** 当前是观众角色,不能请求或断开跨房连麦,需要先 switchRole() 到主播 */
+    ERR_CONNECT_OTHER_ROOM_AS_AUDIENCE: -3330,
+    /** 不支持跨房间连麦 */
+    ERR_SERVER_CENTER_CONN_ROOM_NOT_SUPPORT: -102031,
+    /** 达到跨房间连麦上限 */
+    ERR_SERVER_CENTER_CONN_ROOM_REACH_MAX_NUM: -102032,
+    /** 跨房间连麦重试次数耗尽 */
+    ERR_SERVER_CENTER_CONN_ROOM_REACH_MAX_RETRY_TIMES: -102033,
+    /** 跨房间连麦请求超时 */
+    ERR_SERVER_CENTER_CONN_ROOM_REQ_TIMEOUT: -102034,
+    /** 跨房间连麦请求格式错误 */
+    ERR_SERVER_CENTER_CONN_ROOM_REQ: -102035,
+    /** 跨房间连麦无签名 */
+    ERR_SERVER_CENTER_CONN_ROOM_NO_SIG: -102036,
+    /** 跨房间连麦签名解密失败 */
+    ERR_SERVER_CENTER_CONN_ROOM_DECRYPT_SIG: -102037,
+    /** 未找到跨房间连麦签名解密密钥 */
+    ERR_SERVER_CENTER_CONN_ROOM_NO_KEY: -102038,
+    /** 跨房间连麦签名解析错误 */
+    ERR_SERVER_CENTER_CONN_ROOM_PARSE_SIG: -102039,
+    /** 跨房间连麦签名时间戳错误 */
+    ERR_SERVER_CENTER_CONN_ROOM_INVALID_SIG_TIME: -102040,
+    /** 跨房间连麦签名不匹配 */
+    ERR_SERVER_CENTER_CONN_ROOM_SIG_GROUPID: -102041,
+    /** 本房间无连麦 */
+    ERR_SERVER_CENTER_CONN_ROOM_NOT_CONNED: -102042,
+    /** 本用户未发起连麦 */
+    ERR_SERVER_CENTER_CONN_ROOM_USER_NOT_CONNED: -102043,
+    /** 跨房间连麦失败 */
+    ERR_SERVER_CENTER_CONN_ROOM_FAILED: -102044,
+    /** 取消跨房间连麦失败 */
+    ERR_SERVER_CENTER_CONN_ROOM_CANCEL_FAILED: -102045,
+    /** 被连麦房间不存在 */
+    ERR_SERVER_CENTER_CONN_ROOM_CONNED_ROOM_NOT_EXIST: -102046,
+    /** 被连麦房间达到连麦上限 */
+    ERR_SERVER_CENTER_CONN_ROOM_CONNED_REACH_MAX_ROOM: -102047,
+    /** 被连麦用户不存在 */
+    ERR_SERVER_CENTER_CONN_ROOM_CONNED_USER_NOT_EXIST: -102048,
+    /** 被连麦用户已被删除 */
+    ERR_SERVER_CENTER_CONN_ROOM_CONNED_USER_DELETED: -102049,
+    /** 被连麦用户达到资源上限 */
+    ERR_SERVER_CENTER_CONN_ROOM_CONNED_USER_FULL: -102050,
+    /** 连麦请求序号错乱 */
+    ERR_SERVER_CENTER_CONN_ROOM_INVALID_SEQ: -102051,
+    /** 直播,推流出现网络断开,且经过多次重试无法恢复 */
+    ERR_RTMP_PUSH_NET_DISCONNECT: -1307,
+    /** 直播,推流地址非法,例如不是 RTMP 协议的地址 */
+    ERR_RTMP_PUSH_INVALID_ADDRESS: -1313,
+    /** 直播,连接推流服务器失败(若支持智能选路,IP 全部失败) */
+    ERR_RTMP_PUSH_NET_ALLADDRESS_FAIL: -1324,
+    /** 直播,网络不可用,请确认 WiFi、移动数据或者有线网络是否正常 */
+    ERR_RTMP_PUSH_NO_NETWORK: -1325,
+    /** 直播,服务器拒绝连接请求,可能是该推流地址已经被占用,或者 TXSecret 校验失败,或者是过期了,或者是欠费了 */
+    ERR_RTMP_PUSH_SERVER_REFUSE: -1326,
+    /** 直播,网络断连,且经多次重连抢救无效,可以放弃治疗,更多重试请自行重启播放 */
+    ERR_PLAY_LIVE_STREAM_NET_DISCONNECT: -2301,
+    /** 直播,获取加速拉流的地址失败 */
+    ERR_GET_RTMP_ACC_URL_FAIL: -2302,
+    /** 播放的文件不存在 */
+    ERR_FILE_NOT_FOUND: -2303,
+    /** H265 解码失败 */
+    ERR_HEVC_DECODE_FAIL: -2304,
+    /** 点播,音视频流解密失败 */
+    ERR_VOD_DECRYPT_FAIL: -2305,
+    /** 点播,获取点播文件信息失败 */
+    ERR_GET_VODFILE_MEDIAINFO_FAIL: -2306,
+    /** 直播,切流失败(切流可以播放不同画面大小的视频) */
+    ERR_PLAY_LIVE_STREAM_SWITCH_FAIL: -2307,
+    /** 直播,服务器拒绝连接请求 */
+    ERR_PLAY_LIVE_STREAM_SERVER_REFUSE: -2308,
+    /** 直播,RTMPACC 低延时拉流失败,且经过多次重试无法恢复 */
+    ERR_RTMP_ACC_FETCH_STREAM_FAIL: -2309,
+    /** 心跳失败,客户端定时向服务器发送数据包,告诉服务器自己活着,这个错误通常是发包超时 */
+    ERR_ROOM_HEARTBEAT_FAIL: -3302,
+    /** 拉取接口机服务器地址失败 */
+    ERR_ROOM_REQUEST_IP_FAIL: -3303,
+    /** 连接接口机服务器失败 */
+    ERR_ROOM_CONNECT_FAIL: -3304,
+    /** 请求视频位失败 */
+    ERR_ROOM_REQUEST_AVSEAT_FAIL: -3305,
+    /** 请求 token https 超时,请检查网络是否正常,或网络防火墙是否放行 https 访问 official.opensso.tencent-cloud.com:443 */
+    ERR_ROOM_REQUEST_TOKEN_HTTPS_TIMEOUT: -3306,
+    /** 请求 IP 和 sig 超时,请检查网络是否正常,或网络防火墙是否放行 UDP 访问下列 IP 和域名 query.tencent-cloud.com:8000 162.14.23.140:8000 162.14.7.49:8000 */
+    ERR_ROOM_REQUEST_IP_TIMEOUT: -3307,
+    /** 请求视频位超时 */
+    ERR_ROOM_REQUEST_VIDEO_FLAG_TIMEOUT: -3309,
+    /** 请求视频数据超时 */
+    ERR_ROOM_REQUEST_VIDEO_DATA_ROOM_TIMEOUT: -3310,
+    /** 请求修改视频能力项超时 */
+    ERR_ROOM_REQUEST_CHANGE_ABILITY_TIMEOUT: -3311,
+    /** 请求状态上报超时 */
+    ERR_ROOM_REQUEST_STATUS_REPORT_TIMEOUT: -3312,
+    /** 请求关闭视频超时 */
+    ERR_ROOM_REQUEST_CLOSE_VIDEO_TIMEOUT: -3313,
+    /** 请求接收视频项超时 */
+    ERR_ROOM_REQUEST_SET_RECEIVE_TIMEOUT: -3314,
+    /** 请求 token 无效参数,请检查 TRTCParams.userSig 是否填写正确 */
+    ERR_ROOM_REQUEST_TOKEN_INVALID_PARAMETER: -3315,
+    /** 请求 AES TOKEN 时,server 返回的内容是空的 */
+    ERR_ROOM_REQUEST_AES_TOKEN_RETURN_ERROR: -3329,
+    /** 请求接口机 IP 返回的列表为空的 */
+    ERR_ACCIP_LIST_EMPTY: -3331,
+    /** 请求发送 Json 信令超时 */
+    ERR_ROOM_REQUEST_SEND_JSON_CMD_TIMEOUT: -3332,
+    // Info 服务器(查询接口机 IP), 服务器错误码,数值范围[-100000, -110000]
+    /** server 解包错误,可能请求数据被篡改 */
+    ERR_SERVER_INFO_UNPACKING_ERROR: -100000,
+    /** TOKEN 错误 */
+    ERR_SERVER_INFO_TOKEN_ERROR: -100001,
+    /** 分配接口机错误 */
+    ERR_SERVER_INFO_ALLOCATE_ACCESS_FAILED: -100002,
+    /** 生成签名错误 */
+    ERR_SERVER_INFO_GENERATE_SIGN_FAILED: -100003,
+    /** https token 超时 */
+    ERR_SERVER_INFO_TOKEN_TIMEOUT: -100004,
+    /** 无效的命令字 */
+    ERR_SERVER_INFO_INVALID_COMMAND: -100005,
+    /** 权限位校验失败 */
+    ERR_SERVER_INFO_PRIVILEGE_FLAG_ERROR: -100006,
+    /** https 请求时,生成加密 key 错误 */
+    ERR_SERVER_INFO_GENERATE_KEN_ERROR: -100007,
+    /** https 请求时,生成 token 错误 */
+    ERR_SERVER_INFO_GENERATE_TOKEN_ERROR: -100008,
+    /** 数据库查询失败(房间相关存储信息) */
+    ERR_SERVER_INFO_DATABASE: -100009,
+    /** 房间号错误 */
+    ERR_SERVER_INFO_BAD_ROOMID: -100010,
+    /** 场景或角色错误 */
+    ERR_SERVER_INFO_BAD_SCENE_OR_ROLE: -100011,
+    /** 房间号转换出错 */
+    ERR_SERVER_INFO_ROOMID_EXCHANGE_FAILED: -100012,
+    /** 房间号非法 */
+    ERR_SERVER_INFO_STRGROUP_HAS_INVALID_CHARS: -100014,
+    /** 非法SDKAppid */
+    ERR_SERVER_INFO_LACK_SDKAPPID: -100015,
+    /** 无效请求, 旧版 0x1 要求带 Token; ECDH 要求带 ECDH Publich Key; 两个都没有就按报错 */
+    ERR_SERVER_INFO_INVALID: -100016,
+    /** 生成公钥失败 */
+    ERR_SERVER_INFO_ECDH_GET_KEY: -100017,
+    /** 获取tinyid失败 */
+    ERR_SERVER_INFO_ECDH_GET_TINYID: -100018,
+    // Access 接口机
+    /** token 过期 */
+    ERR_SERVER_ACC_TOKEN_TIMEOUT: -101000,
+    /** 签名错误 */
+    ERR_SERVER_ACC_SIGN_ERROR: -101001,
+    /** 签名超时 */
+    ERR_SERVER_ACC_SIGN_TIMEOUT: -101002,
+    /** 房间不存在 */
+    ERR_SERVER_ACC_ROOM_NOT_EXIST: -101003,
+    /** 后台房间标识 roomId 错误 */
+    ERR_SERVER_ACC_ROOMID: -101004,
+    /** 后台用户位置标识 locationId 错误 */
+    ERR_SERVER_ACC_LOCATIONID: -101005,
+    // center 服务器(信令和流控处理等任务)
+    /** 后台错误 */
+    ERR_SERVER_CENTER_SYSTEM_ERROR: -102000,
+    /** 无效的房间 Id */
+    ERR_SERVER_CENTER_INVALID_ROOMID: -102001,
+    /** 创建房间失败 */
+    ERR_SERVER_CENTER_CREATE_ROOM_FAILED: -102002,
+    /** 签名错误 */
+    ERR_SERVER_CENTER_SIGN_ERROR: -102003,
+    /** 签名过期 */
+    ERR_SERVER_CENTER_SIGN_TIMEOUT: -102004,
+    /** 房间不存在 */
+    ERR_SERVER_CENTER_ROOM_NOT_EXIST: -102005,
+    /** 房间添加用户失败 */
+    ERR_SERVER_CENTER_ADD_USER_FAILED: -102006,
+    /** 查找用户失败 */
+    ERR_SERVER_CENTER_FIND_USER_FAILED: -102007,
+    /** 频繁切换终端 */
+    ERR_SERVER_CENTER_SWITCH_TERMINATION_FREQUENTLY: -102008,
+    /** locationid 错误 */
+    ERR_SERVER_CENTER_LOCATION_NOT_EXIST: -102009,
+    /** 没有权限创建房间 */
+    ERR_SERVER_CENTER_NO_PRIVILEDGE_CREATE_ROOM: -102010,
+    /** 没有权限进入房间 */
+    ERR_SERVER_CENTER_NO_PRIVILEDGE_ENTER_ROOM: -102011,
+    /** 辅路抢视频位、申请辅路请求类型参数错误 */
+    ERR_SERVER_CENTER_INVALID_PARAMETER_SUB_VIDEO: -102012,
+    /** 没有权限上视频 */
+    ERR_SERVER_CENTER_NO_PRIVILEDGE_PUSH_VIDEO: -102013,
+    /** 没有空闲路由表 */
+    ERR_SERVER_CENTER_ROUTE_TABLE_ERROR: -102014,
+    /** 当前用户没有上行辅路 */
+    ERR_SERVER_CENTER_NOT_PUSH_SUB_VIDEO: -102017,
+    /** 用户被删除状态 */
+    ERR_SERVER_CENTER_USER_WAS_DELETED: -102018,
+    /** 没有权限请求视频 */
+    ERR_SERVER_CENTER_NO_PRIVILEDGE_REQUEST_VIDEO: -102019,
+    /** 进房参数 bussInfo 错误 */
+    ERR_SERVER_CENTER_INVALID_PARAMETER: -102023,
+    /** 请求 I 帧未知 opType */
+    ERR_SERVER_CENTER_I_FRAME_UNKNOW_TYPE: -102024,
+    /** 请求 I 帧包格式错误 */
+    ERR_SERVER_CENTER_I_FRAME_INVALID_PACKET: -102025,
+    /** 请求 I 帧目标用户不存在 */
+    ERR_SERVER_CENTER_I_FRAME_DEST_USER_NOT_EXIST: -102026,
+    /** 请求 I 帧房间用户太多 */
+    ERR_SERVER_CENTER_I_FRAME_ROOM_TOO_BIG: -102027,
+    /** 请求 I 帧参数错误 */
+    ERR_SERVER_CENTER_I_FRAME_RPS_INVALID_PARAMETER: -102028,
+    /** 房间号非法 */
+    ERR_SERVER_CENTER_INVALID_ROOM_ID: -102029,
+    /** 房间号超过限制 */
+    ERR_SERVER_CENTER_ROOM_ID_TOO_LONG: -102030,
+    /** 房间满员 */
+    ERR_SERVER_CENTER_ROOM_FULL: -102052,
+    /** json串解析失败 */
+    ERR_SERVER_CENTER_DECODE_JSON_FAIL: -102053,
+    /** 未定义命令字 */
+    ERR_SERVER_CENTER_UNKNOWN_SUB_CMD: -102054,
+    /** 未定义角色 */
+    ERR_SERVER_CENTER_INVALID_ROLE: -102055,
+    /** 代理机超出限制 */
+    ERR_SERVER_CENTER_REACH_PROXY_MAX: -102056,
+    //add by sunlitwang begin
+    /** 无法保存用户自定义recordId */
+    ERR_SERVER_CENTER_RECORDID_STORE: -102057,
+    /** Protobuf序列化错误 */
+    ERR_SERVER_CENTER_PB_SERIALIZE: -102058,
+    // https://cloud.tencent.com/document/product/269/1671#.E5.B8.90.E5.8F.B7.E7.B3.BB.E7.BB.9F , 帐号系统, 主要是70000 - 79999之间.
+    // 在请求 token 过程中,出现账号错误,SSO 返回的错误码,原为正数,现将其转换为负数。
+    /** sig 过期,请尝试重新生成。如果是刚生成,就过期,请检查有效期填写的是否过小,或者填的 0 */
+    ERR_SERVER_SSO_SIG_EXPIRED: -70001,
+    /** sig 校验失败,请确认下 sig 内容是否被截断,如缓冲区长度不够导致的内容截断 */
+    ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_1: -70003,
+    /** sig 校验失败,请确认下 sig 内容是否被截断,如缓冲区长度不够导致的内容截断 */
+    ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_2: -70004,
+    /** sig 校验失败,可用工具自行验证生成的 sig 是否正确 */
+    ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_3: -70005,
+    /** sig 校验失败,可用工具自行验证生成的 sig 是否正确 */
+    ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_4: -70006,
+    /** sig 校验失败,可用工具自行验证生成的 sig 是否正确 */
+    ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_5: -70007,
+    /** sig 校验失败,可用工具自行验证生成的 sig 是否正确 */
+    ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_6: -70008,
+    /** 用业务公钥验证 sig 失败,请确认生成的 usersig 使用的私钥和 sdkAppId 是否对应 */
+    ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_7: -70009,
+    /** sig 校验失败,可用工具自行验证生成的 sig 是否正确 */
+    ERR_SERVER_SSO_SIG_VERIFICATION_FAILED_8: -70010,
+    /** sig 中 identifier 与请求时的 identifier 不匹配,请检查登录时填写的 identifier 与 sig 中的是否一致 */
+    ERR_SERVER_SSO_SIG_VERIFICATION_ID_NOT_MATCH: -70013,
+    /** sig 中 sdkAppId 与请求时的 sdkAppId 不匹配,请检查登录时填写的 sdkAppId 与 sig 中的是否一致 */
+    ERR_SERVER_SSO_APPID_NOT_MATCH: -70014,
+    /** 内部第三方票据验证超时,请重试,如多次重试不成功,请@TLS 帐号支持,QQ 3268519604 */
+    ERR_SERVER_SSO_VERIFICATION_EXPIRED: -70017,
+    /** 内部第三方票据验证超时,请重试,如多次重试不成功,请@TLS 帐号支持,QQ 3268519604 */
+    ERR_SERVER_SSO_VERIFICATION_FAILED: -70018,
+    /** sdkAppId 未找到,请确认是否已经在腾讯云上配置 */
+    ERR_SERVER_SSO_APPID_NOT_FOUND: -70020,
+    /** 帐号已被拉入黑名单,请联系 TLS 帐号支持 QQ 3268519604 */
+    ERR_SERVER_SSO_ACCOUNT_IN_BLACKLIST: -70051,
+    /** usersig 已经失效,请重新生成,再次尝试 */
+    ERR_SERVER_SSO_SIG_INVALID: -70052,
+    /** 安全原因被限制 */
+    ERR_SERVER_SSO_LIMITED_BY_SECURITY: -70114,
+    /** 登录状态无效,请使用 usersig 重新鉴权 */
+    ERR_SERVER_SSO_INVALID_LOGIN_STATUS: -70221,
+    /** sdkAppId 填写错误 */
+    ERR_SERVER_SSO_APPID_ERROR: -70252,
+    /** 票据校验失败,请检查各项参数是否正确 */
+    ERR_SERVER_SSO_TICKET_VERIFICATION_FAILED: -70346,
+    /** 票据因过期原因校验失败 */
+    ERR_SERVER_SSO_TICKET_EXPIRED: -70347,
+    /** 创建账号数量超过已购买预付费数量限制 */
+    ERR_SERVER_SSO_ACCOUNT_EXCEED_PURCHASES: -70398,
+    /** 服务器内部错误,请重试 */
+    ERR_SERVER_SSO_INTERNAL_ERROR: -70500,
+};
+/////////////////////////////////////////////////////////////////////////////////
+//
+//                     (二)错误码(警告)
+//
+/////////////////////////////////////////////////////////////////////////////////
+/**
+ * @memberof ErrorCode
+ * @typedef 错误码(警告)
+ * @description SDK 错误码(警告)对照表
+ * | 符号 | 值 | 含义 |
+ * |---|---|---|
+ * |WARNING_HW_ENCODER_START_FAIL|1103|硬编码启动出现问题,自动切换到软编码|
+ * |WARNING_VIDEO_ENCODER_SW_TO_HW|1107|当前 CPU 使用率太高,无法满足软件编码需求,自动切换到硬件编码|
+ * |WARNING_INSUFFICIENT_CAPTURE_FPS|1108|摄像头采集帧率不足,部分自带美颜算法的 Android 手机上会出现|
+ * |WARNING_SW_ENCODER_START_FAIL|1109|软编码启动失败|
+ * |WARNING_REDUCE_CAPTURE_RESOLUTION|1110|摄像头采集分辨率被降低,以满足当前帧率和性能最优解。|
+ * |WARNING_VIDEO_FRAME_DECODE_FAIL|2101|当前视频帧解码失败|
+ * |WARNING_AUDIO_FRAME_DECODE_FAIL|2102|当前音频帧解码失败|
+ * |WARNING_VIDEO_PLAY_LAG|2105|当前视频播放出现卡顿|
+ * |WARNING_HW_DECODER_START_FAIL|2106|硬解启动失败,采用软解码|
+ * |WARNING_VIDEO_DECODER_HW_TO_SW|2108|当前流硬解第一个 I 帧失败,SDK 自动切软解|
+ * |WARNING_SW_DECODER_START_FAIL|2109|软解码器启动失败|
+ * |WARNING_VIDEO_RENDER_FAIL|2110|视频渲染失败|
+ * |WARNING_AUDIO_RECORDING_WRITE_FAIL|7001|音频录制写入文件失败|
+ * |WARNING_ROOM_DISCONNECT|5101|网络断开连接|
+ * |WARNING_IGNORE_UPSTREAM_FOR_AUDIENCE|6001|当前是观众角色,忽略上行音视频数据|
+ */
+export const TXLiteAVWarning = {
+    /** 硬编码启动出现问题,自动切换到软编码 */
+    WARNING_HW_ENCODER_START_FAIL: 1103,
+    /** 当前 CPU 使用率太高,无法满足软件编码需求,自动切换到硬件编码 */
+    WARNING_VIDEO_ENCODER_SW_TO_HW: 1107,
+    /** 摄像头采集帧率不足,部分自带美颜算法的 Android 手机上会出现 */
+    WARNING_INSUFFICIENT_CAPTURE_FPS: 1108,
+    /** 软编码启动失败 */
+    WARNING_SW_ENCODER_START_FAIL: 1109,
+    /** 摄像头采集分辨率被降低,以满足当前帧率和性能最优解。 */
+    WARNING_REDUCE_CAPTURE_RESOLUTION: 1110,
+    /** 当前视频帧解码失败 */
+    WARNING_VIDEO_FRAME_DECODE_FAIL: 2101,
+    /** 当前音频帧解码失败 */
+    WARNING_AUDIO_FRAME_DECODE_FAIL: 2102,
+    /** 当前视频播放出现卡顿 */
+    WARNING_VIDEO_PLAY_LAG: 2105,
+    /** 硬解启动失败,采用软解码 */
+    WARNING_HW_DECODER_START_FAIL: 2106,
+    /** 当前流硬解第一个 I 帧失败,SDK 自动切软解 */
+    WARNING_VIDEO_DECODER_HW_TO_SW: 2108,
+    /** 软解码器启动失败 */
+    WARNING_SW_DECODER_START_FAIL: 2109,
+    /** 视频渲染失败 */
+    WARNING_VIDEO_RENDER_FAIL: 2110,
+    /** 音频录制写入文件失败 */
+    WARNING_AUDIO_RECORDING_WRITE_FAIL: 7001,
+    /** 网络断开连接 */
+    WARNING_ROOM_DISCONNECT: 5101,
+    /** 当前是观众角色,忽略上行音视频数据 */
+    WARNING_IGNORE_UPSTREAM_FOR_AUDIENCE: 6001,
+    /** 网络状况不佳:上行带宽太小,上传数据受阻 */
+    WARNING_NET_BUSY: 1101,
+    /** 直播,网络断连, 已启动自动重连(自动重连连续失败超过三次会放弃) */
+    WARNING_RTMP_SERVER_RECONNECT: 1102,
+    /** 直播,网络断连, 已启动自动重连(自动重连连续失败超过三次会放弃) */
+    WARNING_LIVE_STREAM_SERVER_RECONNECT: 2103,
+    /** 网络来包不稳:可能是下行带宽不足,或由于主播端出流不均匀 */
+    WARNING_RECV_DATA_LAG: 2104,
+    /** 直播,DNS 解析失败 */
+    WARNING_RTMP_DNS_FAIL: 3001,
+    /** 直播,服务器连接失败 */
+    WARNING_RTMP_SEVER_CONN_FAIL: 3002,
+    /** 直播,与 RTMP 服务器握手失败 */
+    WARNING_RTMP_SHAKE_FAIL: 3003,
+    /** 直播,服务器主动断开 */
+    WARNING_RTMP_SERVER_BREAK_CONNECT: 3004,
+    /** 直播,RTMP 读/写失败,将会断开连接 */
+    WARNING_RTMP_READ_WRITE_FAIL: 3005,
+    /** 直播,RTMP 写失败(SDK 内部错误码,不会对外抛出) */
+    WARNING_RTMP_WRITE_FAIL: 3006,
+    /** 直播,RTMP 读失败(SDK 内部错误码,不会对外抛出) */
+    WARNING_RTMP_READ_FAIL: 3007,
+    /** 直播,超过30s 没有数据发送,主动断开连接 */
+    WARNING_RTMP_NO_DATA: 3008,
+    /** 直播,connect 服务器调用失败(SDK 内部错误码,不会对外抛出) */
+    WARNING_PLAY_LIVE_STREAM_INFO_CONNECT_FAIL: 3009,
+    /** 直播,连接失败,该流地址无视频(SDK 内部错误码,不会对外抛出) */
+    WARNING_NO_STEAM_SOURCE_FAIL: 3010,
+    /** 网络断连,已启动自动重连 */
+    WARNING_ROOM_RECONNECT: 5102,
+    /** 网络状况不佳:上行带宽太小,上传数据受阻 */
+    WARNING_ROOM_NET_BUSY: 5103,
+};
+/////////////////////////////////////////////////////////////////////////////////
+//
+//                     (三)JS 封装层抛出的异常(严重)
+//
+/////////////////////////////////////////////////////////////////////////////////
+/**
+ * @namespace ErrorCode
+ * @description 错误码
+ */
+export const TXLiteJSError = {
+    /**
+     * 未知错误
+     * @default 0xFFFF
+     * @memberof module:ErrorCode
+     */
+    UNKNOWN: 0xffff,
+    /**
+     * 无效参数
+     *
+     * @default 0x1000
+     * @memberof module:ErrorCode
+     */
+    INVALID_PARAMETER: 0x1000,
+    /**
+     * 非法操作
+     *
+     * @default 0x1001
+     * @memberof module:ErrorCode
+     */
+    INVALID_OPERATION: 0x1001,
+};
+const getErrorName = function (code) {
+    for (let key in TXLiteJSError) {
+        if (TXLiteJSError[key] === code) {
+            return key;
+        }
+    }
+    return 'UNKNOWN';
+};
+/**
+ * TrtcError 错误对象<br>
+ * @extends Error
+ * @namespace ErrorCode
+ */
+class TrtcError extends Error {
+    constructor({ code = TXLiteJSError.UNKNOWN, message, extraInfo }) {
+        if (extraInfo) {
+            const tempError = {
+                errCode: code,
+                errMsg: message,
+                extraInfo: Object.assign(Object.assign({}, extraInfo), { errCodeUrl: errorCodeUrl }),
+            };
+            super(JSON.stringify(tempError));
+        }
+        else {
+            super(message +
+                ` <${getErrorName(code)} 0x${code.toString(16)}>. Refer to: ${errorCodeUrl}`);
+        }
+        this.errCode = code;
+        this.errMsg = message;
+        this.extraInfo = Object.assign(Object.assign({}, extraInfo), { errCodeUrl: errorCodeUrl });
+    }
+    /**
+     * 获取错误码<br>
+     * 详细错误码列表参见 {@link module:ErrorCode ErrorCode}
+     * @memberof TrtcError
+     */
+    getCode() {
+        return this.errCode;
+    }
+}
+export default TrtcError;
+export function generateError_(error, code = TXLiteJSError.UNKNOWN, extraInfo) {
+    return new TrtcError({
+        code: error.code || code,
+        message: `${NAME.LOG_PREFIX}${error.message}`,
+        extraInfo,
+    });
+}
+;

+ 484 - 0
TrtcCloud/lib/TrtcDefines.js

@@ -0,0 +1,484 @@
+/**
+ * TRTC 关键类型定义<br>
+ * @description 分辨率、质量等级等枚举和常量值的定义
+ */
+/////////////////////////////////////////////////////////////////////////////////
+//
+//                    【(一)视频相关枚举值定义】
+//
+/////////////////////////////////////////////////////////////////////////////////
+/**
+ * 视频分辨率<br>
+ * 此处仅定义横屏分辨率(如 640 × 360),如需使用竖屏分辨率(如 360 × 640),需要同时指定 VideoResolutionMode 为 Portrait
+ * @enum {Number}
+ */
+const TRTCVideoResolution_HACK_JSDOC = {
+    /** 宽高比 1:1;分辨率 120x120;建议码率(VideoCall)80kbps; 建议码率(LIVE)120kbps */
+    TRTCVideoResolution_120_120: 1,
+    /** 宽高比 1:1 分辨率 160x160;建议码率(VideoCall)100kbps; 建议码率(LIVE)150kbps */
+    TRTCVideoResolution_160_160: 3,
+    /** 宽高比 1:1;分辨率 270x270;建议码率(VideoCall)200kbps; 建议码率(LIVE)300kbps */
+    TRTCVideoResolution_270_270: 5,
+    /** 宽高比 1:1;分辨率 480x480;建议码率(VideoCall)350kbps; 建议码率(LIVE)500kbps */
+    TRTCVideoResolution_480_480: 7,
+    /** 宽高比4:3;分辨率 160x120;建议码率(VideoCall)100kbps; 建议码率(LIVE)150kbps */
+    TRTCVideoResolution_160_120: 50,
+    /** 宽高比 4:3;分辨率 240x180;建议码率(VideoCall)150kbps; 建议码率(LIVE)250kbps */
+    TRTCVideoResolution_240_180: 52,
+    /** 宽高比 4:3;分辨率 280x210;建议码率(VideoCall)200kbps; 建议码率(LIVE)300kbps */
+    TRTCVideoResolution_280_210: 54,
+    /** 宽高比 4:3;分辨率 320x240;建议码率(VideoCall)250kbps; 建议码率(LIVE)375kbps */
+    TRTCVideoResolution_320_240: 56,
+    /** 宽高比 4:3;分辨率 400x300;建议码率(VideoCall)300kbps; 建议码率(LIVE)450kbps */
+    TRTCVideoResolution_400_300: 58,
+    /** 宽高比 4:3;分辨率 480x360;建议码率(VideoCall)400kbps; 建议码率(LIVE)600kbps */
+    TRTCVideoResolution_480_360: 60,
+    /** 宽高比 4:3;分辨率 640x480;建议码率(VideoCall)600kbps; 建议码率(LIVE)900kbps */
+    TRTCVideoResolution_640_480: 62,
+    /** 宽高比 4:3;分辨率 960x720;建议码率(VideoCall)1000kbps; 建议码率(LIVE)1500kbps */
+    TRTCVideoResolution_960_720: 64,
+    /** 宽高比 16:9;分辨率 160x90;建议码率(VideoCall)150kbps; 建议码率(LIVE)250kbps */
+    TRTCVideoResolution_160_90: 100,
+    /** 宽高比 16:9;分辨率 256x144;建议码率(VideoCall)200kbps; 建议码率(LIVE)300kbps */
+    TRTCVideoResolution_256_144: 102,
+    /** 宽高比 16:9;分辨率 320x180;建议码率(VideoCall)250kbps; 建议码率(LIVE)400kbps */
+    TRTCVideoResolution_320_180: 104,
+    /** 宽高比 16:9;分辨率 480x270;建议码率(VideoCall)350kbps; 建议码率(LIVE)550kbps */
+    TRTCVideoResolution_480_270: 106,
+    /** 宽高比 16:9;分辨率 640x360;建议码率(VideoCall)500kbps; 建议码率(LIVE)900kbps */
+    TRTCVideoResolution_640_360: 108,
+    /** 宽高比 16:9;分辨率 960x540;建议码率(VideoCall)850kbps; 建议码率(LIVE)1300kbps */
+    TRTCVideoResolution_960_540: 110,
+    /** 宽高比 16:9;分辨率 1280x720;建议码率(VideoCall)1200kbps; 建议码率(LIVE)1800kbps */
+    TRTCVideoResolution_1280_720: 112,
+    /** 宽高比 16:9;分辨率 1920x1080;建议码率(VideoCall)2000kbps; 建议码率(LIVE)3000kbps */
+    TRTCVideoResolution_1920_1080: 114,
+};
+export var TRTCVideoResolution;
+(function (TRTCVideoResolution) {
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_120_120"] = 1] = "TRTCVideoResolution_120_120";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_160_160"] = 3] = "TRTCVideoResolution_160_160";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_270_270"] = 5] = "TRTCVideoResolution_270_270";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_480_480"] = 7] = "TRTCVideoResolution_480_480";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_160_120"] = 50] = "TRTCVideoResolution_160_120";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_240_180"] = 52] = "TRTCVideoResolution_240_180";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_280_210"] = 54] = "TRTCVideoResolution_280_210";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_320_240"] = 56] = "TRTCVideoResolution_320_240";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_400_300"] = 58] = "TRTCVideoResolution_400_300";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_480_360"] = 60] = "TRTCVideoResolution_480_360";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_640_480"] = 62] = "TRTCVideoResolution_640_480";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_960_720"] = 64] = "TRTCVideoResolution_960_720";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_160_90"] = 100] = "TRTCVideoResolution_160_90";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_256_144"] = 102] = "TRTCVideoResolution_256_144";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_320_180"] = 104] = "TRTCVideoResolution_320_180";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_480_270"] = 106] = "TRTCVideoResolution_480_270";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_640_360"] = 108] = "TRTCVideoResolution_640_360";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_960_540"] = 110] = "TRTCVideoResolution_960_540";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_1280_720"] = 112] = "TRTCVideoResolution_1280_720";
+    TRTCVideoResolution[TRTCVideoResolution["TRTCVideoResolution_1920_1080"] = 114] = "TRTCVideoResolution_1920_1080";
+})(TRTCVideoResolution || (TRTCVideoResolution = {}));
+/**
+ * 视频分辨率模式<br>
+ * TRTCVideoResolution 中仅定义了横屏分辨率(如 640 × 360),如需使用竖屏分辨率(如 360 × 640),需要同时指定 TRTCVideoResolutionMode 为 Portrait
+ * @enum {Number}
+ */
+const TRTCVideoResolutionMode_HACK_JSDOC = {
+    /** 横屏分辨率 */
+    TRTCVideoResolutionModeLandscape: 0,
+    /** 竖屏分辨率 */
+    TRTCVideoResolutionModePortrait: 1,
+};
+export var TRTCVideoResolutionMode;
+(function (TRTCVideoResolutionMode) {
+    TRTCVideoResolutionMode[TRTCVideoResolutionMode["TRTCVideoResolutionModeLandscape"] = 0] = "TRTCVideoResolutionModeLandscape";
+    TRTCVideoResolutionMode[TRTCVideoResolutionMode["TRTCVideoResolutionModePortrait"] = 1] = "TRTCVideoResolutionModePortrait";
+})(TRTCVideoResolutionMode || (TRTCVideoResolutionMode = {}));
+;
+/**
+ * 视频流类型<br>
+ * TRTC 内部有三种不同的音视频流,分别是:
+ * - 高清大画面:一般用来传输摄像头的视频数据
+ * - 低清小画面:小画面和大画面的内容相互,但是分辨率和码率都比大画面低,因此清晰度也更低
+ * - 辅流画面:一般用于屏幕分享,同一时间在同一个房间中只允许一个用户发布辅流视频,其他用户必须要等该用户关闭之后才能发布自己的辅流
+ *
+ * **Note:**
+ * - 不支持单独开启低清小画面,小画面必须依附于大画面而存在,SDK 会自动设定低清小画面的分辨率和码率
+ * @enum {Number}
+ */
+const TRTCVideoStreamType_HACK_JSDOC = {
+    /** 大画面视频流 */
+    TRTCVideoStreamTypeBig: 0,
+    /** 小画面视频流 */
+    TRTCVideoStreamTypeSmall: 1,
+    /** 辅流(屏幕分享) */
+    TRTCVideoStreamTypeSub: 2,
+};
+export var TRTCVideoStreamType;
+(function (TRTCVideoStreamType) {
+    TRTCVideoStreamType[TRTCVideoStreamType["TRTCVideoStreamTypeBig"] = 0] = "TRTCVideoStreamTypeBig";
+    TRTCVideoStreamType[TRTCVideoStreamType["TRTCVideoStreamTypeSmall"] = 1] = "TRTCVideoStreamTypeSmall";
+    TRTCVideoStreamType[TRTCVideoStreamType["TRTCVideoStreamTypeSub"] = 2] = "TRTCVideoStreamTypeSub";
+})(TRTCVideoStreamType || (TRTCVideoStreamType = {}));
+/**
+ * 画面来源<br>
+ * TRTC 内部有两种不同的画面来源,分别是:
+ * - TRTCSnapshotSourceTypeStream: 视频流画面
+ * - TRTCSnapshotSourceTypeView: 视频渲染画面
+ *
+ * **Note:**
+ * - 截取视频流画面(TRTCSnapshotSourceTypeStream)一般更清晰。
+ * @enum {Number}
+ */
+const TRTCSnapshotSourceType_HACK_JSDOC = {
+    /** 视频流画面 */
+    TRTCSnapshotSourceTypeStream: 0,
+    /** 视频渲染画面 */
+    TRTCSnapshotSourceTypeView: 1,
+};
+export var TRTCSnapshotSourceType;
+(function (TRTCSnapshotSourceType) {
+    TRTCSnapshotSourceType[TRTCSnapshotSourceType["TRTCSnapshotSourceTypeStream"] = 0] = "TRTCSnapshotSourceTypeStream";
+    TRTCSnapshotSourceType[TRTCSnapshotSourceType["TRTCSnapshotSourceTypeView"] = 1] = "TRTCSnapshotSourceTypeView";
+})(TRTCSnapshotSourceType || (TRTCSnapshotSourceType = {}));
+/**
+ * 视频画面填充模式<br>
+ * 如果画面的显示分辨率不等于画面的原始分辨率,就需要您设置画面的填充模式:
+ * - TRTCVideoFillMode_Fill,图像铺满屏幕,超出显示视窗的视频部分将被截掉,所以画面显示可能不完整。
+ * - TRTCVideoFillMode_Fit,图像长边填满屏幕,短边区域会被填充黑色,但画面的内容肯定是完整的。
+ * @enum {Number}
+ */
+const TRTCVideoFillMode_HACK_JSDOC = {
+    /** 图像铺满屏幕,超出显示视窗的视频部分将被截掉 */
+    TRTCVideoFillMode_Fill: 0,
+    /** 图像长边填满屏幕,短边区域会被填充黑色 */
+    TRTCVideoFillMode_Fit: 1,
+};
+export var TRTCVideoFillMode;
+(function (TRTCVideoFillMode) {
+    TRTCVideoFillMode[TRTCVideoFillMode["TRTCVideoFillMode_Fill"] = 0] = "TRTCVideoFillMode_Fill";
+    TRTCVideoFillMode[TRTCVideoFillMode["TRTCVideoFillMode_Fit"] = 1] = "TRTCVideoFillMode_Fit";
+})(TRTCVideoFillMode || (TRTCVideoFillMode = {}));
+;
+/**
+ * 视频画面旋转方向<br>
+ * TRTC SDK 提供了对本地和远程画面的旋转角度设置 API,如下的旋转角度都是指顺时针方向的。
+ * @enum {Number}
+ */
+const TRTCVideoRotation_HACK_JSDOC = {
+    /** 顺时针旋转0度 */
+    TRTCVideoRotation_0: 0,
+    /** 顺时针旋转90度 */
+    TRTCVideoRotation_90: 1,
+    /** 顺时针旋转180度 */
+    TRTCVideoRotation_180: 2,
+    /** 顺时针旋转270度 */
+    TRTCVideoRotation_270: 3,
+};
+export var TRTCVideoRotation;
+(function (TRTCVideoRotation) {
+    TRTCVideoRotation[TRTCVideoRotation["TRTCVideoRotation_0"] = 0] = "TRTCVideoRotation_0";
+    TRTCVideoRotation[TRTCVideoRotation["TRTCVideoRotation_90"] = 1] = "TRTCVideoRotation_90";
+    TRTCVideoRotation[TRTCVideoRotation["TRTCVideoRotation_180"] = 2] = "TRTCVideoRotation_180";
+    TRTCVideoRotation[TRTCVideoRotation["TRTCVideoRotation_270"] = 3] = "TRTCVideoRotation_270";
+})(TRTCVideoRotation || (TRTCVideoRotation = {}));
+/**
+ * 画面渲染镜像类型<br>
+ * TRTC 的画面镜像提供下列设置模式
+ * @enum {Number}
+ */
+const TRTCVideoMirrorType_HACK_JSDOC = {
+    /** 只适用于移动端, 本地预览时,前置摄像头镜像,后置摄像头不镜像 */
+    TRTCVideoMirrorType_Auto: 0,
+    /** 所有画面均镜像 */
+    TRTCVideoMirrorType_Enable: 1,
+    /** 所有画面均不镜像 */
+    TRTCVideoMirrorType_Disable: 2
+};
+export var TRTCVideoMirrorType;
+(function (TRTCVideoMirrorType) {
+    TRTCVideoMirrorType[TRTCVideoMirrorType["TRTCVideoMirrorType_Auto"] = 0] = "TRTCVideoMirrorType_Auto";
+    TRTCVideoMirrorType[TRTCVideoMirrorType["TRTCVideoMirrorType_Enable"] = 1] = "TRTCVideoMirrorType_Enable";
+    TRTCVideoMirrorType[TRTCVideoMirrorType["TRTCVideoMirrorType_Disable"] = 2] = "TRTCVideoMirrorType_Disable";
+})(TRTCVideoMirrorType || (TRTCVideoMirrorType = {}));
+/**
+ * 美颜(磨皮)算法<br>
+ * TRTC SDK 内置了多种不同的磨皮算法,您可以选择最适合您产品定位的方案。
+ * @enum {Number}
+ */
+const TRTCBeautyStyle_HACK_JSDOC = {
+    /** 光滑,算法比较激进,磨皮效果比较明显,适用于秀场直播 */
+    TRTCBeautyStyleSmooth: 0,
+    /** 自然,算法更多地保留了面部细节,磨皮效果更加自然,适用于绝大多数直播场景 */
+    TRTCBeautyStyleNature: 1,
+    /** 优图,由优图实验室提供,磨皮效果介于光滑和自然之间,比光滑保留更多皮肤细节,比自然磨皮程度更高 */
+    TRTCBeautyStylePitu: 2,
+};
+export var TRTCBeautyStyle;
+(function (TRTCBeautyStyle) {
+    TRTCBeautyStyle[TRTCBeautyStyle["TRTCBeautyStyleSmooth"] = 0] = "TRTCBeautyStyleSmooth";
+    TRTCBeautyStyle[TRTCBeautyStyle["TRTCBeautyStyleNature"] = 1] = "TRTCBeautyStyleNature";
+    TRTCBeautyStyle[TRTCBeautyStyle["TRTCBeautyStylePitu"] = 2] = "TRTCBeautyStylePitu";
+})(TRTCBeautyStyle || (TRTCBeautyStyle = {}));
+/**
+ * 背景音效<br>
+ * @enum {Number}
+ */
+export class AudioMusicParam {
+    constructor(id, path, loopCount, publish, isShortFile, startTimeMS, endTimeMS) {
+        this.id = id;
+        this.path = path;
+        this.loopCount = loopCount;
+        this.publish = publish;
+        this.isShortFile = isShortFile;
+        this.startTimeMS = startTimeMS;
+        this.endTimeMS = endTimeMS;
+    }
+}
+/////////////////////////////////////////////////////////////////////////////////
+//
+//                    【(二)网络相关枚举值定义】
+//
+/////////////////////////////////////////////////////////////////////////////////
+/**
+ * 应用场景<br>
+ * TRTC 可用于视频会议和在线直播等多种应用场景,针对不同的应用场景,TRTC SDK 的内部会进行不同的优化配置:
+ * - TRTCAppSceneVideoCall    :视频通话场景,适合[1对1视频通话]、[300人视频会议]、[在线问诊]、[视频聊天]、[远程面试]等。
+ * - TRTCAppSceneLIVE         :视频互动直播,适合[视频低延时直播]、[十万人互动课堂]、[视频直播 PK]、[视频相亲房]、[互动课堂]、[远程培训]、[超大型会议]等。
+ * - TRTCAppSceneAudioCall    :语音通话场景,适合[1对1语音通话]、[300人语音会议]、[语音聊天]、[语音会议]、[在线狼人杀]等。
+ * - TRTCAppSceneVoiceChatRoom:语音互动直播,适合:[语音低延时直播]、[语音直播连麦]、[语聊房]、[K 歌房]、[FM 电台]等。
+ * @enum {Number}
+ */
+const TRTCAppScene_HACK_JSDOC = {
+    /**
+     * 视频通话场景,支持720P、1080P高清画质,单个房间最多支持300人同时在线,最高支持50人同时发言。<br>
+     * 适合:[视频低延时直播]、[十万人互动课堂]、[视频直播 PK]、[视频相亲房]、[互动课堂]、[远程培训]、[超大型会议]等。<br>
+     * 注意:此场景下,您必须通过 TRTCParams 中的 role 字段指定当前用户的角色。
+     */
+    TRTCAppSceneVideoCall: 0,
+    /**
+     * 视频互动直播,支持平滑上下麦,切换过程无需等待,主播延时小于300ms;支持十万级别观众同时播放,播放延时低至1000ms。<br>
+     * 在线直播场景,内部编码器和网络协议优化侧重性能和兼容性,性能和清晰度表现更佳。
+     */
+    TRTCAppSceneLIVE: 1,
+    /**
+     * 语音通话场景,支持 48kHz,支持双声道。单个房间最多支持300人同时在线,最高支持50人同时发言。<br>
+     * 适合:[1对1语音通话]、[300人语音会议]、[语音聊天]、[语音会议]、[在线狼人杀]等。
+     */
+    TRTCAppSceneAudioCall: 2,
+    /**
+     * 语音互动直播,支持平滑上下麦,切换过程无需等待,主播延时小于300ms;支持十万级别观众同时播放,播放延时低至1000ms。<br>
+     * 适合:[语音低延时直播]、[语音直播连麦]、[语聊房]、[K 歌房]、[FM 电台]等。<br>
+     * 注意:此场景下,您必须通过 TRTCParams 中的 role 字段指定当前用户的角色。
+     */
+    TRTCAppSceneVoiceChatRoom: 3,
+};
+export var TRTCAppScene;
+(function (TRTCAppScene) {
+    TRTCAppScene[TRTCAppScene["TRTCAppSceneVideoCall"] = 0] = "TRTCAppSceneVideoCall";
+    TRTCAppScene[TRTCAppScene["TRTCAppSceneLIVE"] = 1] = "TRTCAppSceneLIVE";
+    TRTCAppScene[TRTCAppScene["TRTCAppSceneAudioCall"] = 2] = "TRTCAppSceneAudioCall";
+    TRTCAppScene[TRTCAppScene["TRTCAppSceneVoiceChatRoom"] = 3] = "TRTCAppSceneVoiceChatRoom";
+})(TRTCAppScene || (TRTCAppScene = {}));
+/**
+ * 角色,仅适用于直播场景(TRTCAppSceneLIVE 和 TRTCAppSceneVoiceChatRoom)<br>
+ * 在直播场景中,多数用户只是观众,只有个别用户是主播,这种角色区分可以有利于 TRTC 进行更好的定向优化。
+ * - Anchor:主播,可以上行视频和音频,一个房间里最多支持50个主播同时上行音视频。
+ * - Audience:观众,只能观看,不能上行视频和音频,一个房间里的观众人数没有上限。
+ *
+ * @enum {Number}
+ */
+const TRTCRoleType_HACK_JSDOC = {
+    /** 主播 */
+    TRTCRoleAnchor: 20,
+    /** 观众 */
+    TRTCRoleAudience: 21,
+};
+export var TRTCRoleType;
+(function (TRTCRoleType) {
+    TRTCRoleType[TRTCRoleType["TRTCRoleAnchor"] = 20] = "TRTCRoleAnchor";
+    TRTCRoleType[TRTCRoleType["TRTCRoleAudience"] = 21] = "TRTCRoleAudience";
+})(TRTCRoleType || (TRTCRoleType = {}));
+/////////////////////////////////////////////////////////////////////////////////
+//
+//                    【(三)音频相关枚举值定义】
+//
+/////////////////////////////////////////////////////////////////////////////////
+/**
+ * 音频质量<br>
+ * @enum {Number}
+ */
+const TRTCAudioQuality_HACK_JSDOC = {
+    /** 人声模式:适用于以人声沟通为主的应用场景,该模式下音频传输的抗性较强,TRTC 会通过各种人声处理技术保障在弱网络环境下的流畅度最佳 */
+    TRTCAudioQualitySpeech: 1,
+    /** 标准模式(或者默认模式):介于 Speech 和 Music 之间的档位,对音乐的还原度比人声模式要好,但传输数据量比音乐模式要低很多,对各种场景均有不错的适应性,如无特殊需求推荐选择之。 */
+    TRTCAudioQualityDefault: 2,
+    /** 音乐模式:适用于对声乐要求很苛刻的场景,该模式下音频传输的数据量很大,TRTC 会通过各项技术确保音乐信号在各频段均能获得高保真的细节还原度 */
+    TRTCAudioQualityMusic: 3
+};
+export var TRTCAudioQuality;
+(function (TRTCAudioQuality) {
+    TRTCAudioQuality[TRTCAudioQuality["TRTCAudioQualitySpeech"] = 1] = "TRTCAudioQualitySpeech";
+    TRTCAudioQuality[TRTCAudioQuality["TRTCAudioQualityDefault"] = 2] = "TRTCAudioQualityDefault";
+    TRTCAudioQuality[TRTCAudioQuality["TRTCAudioQualityMusic"] = 3] = "TRTCAudioQualityMusic";
+})(TRTCAudioQuality || (TRTCAudioQuality = {}));
+/////////////////////////////////////////////////////////////////////////////////
+//
+//                      【(四)TRTC 核心类型定义】
+//
+/////////////////////////////////////////////////////////////////////////////////
+/**
+ * 进房相关参数<br>
+ * 只有该参数填写正确,才能顺利调用 enterRoom 进入 roomId 所指定的音视频房间。
+ * @param {Number}       sdkAppId      - 【字段含义】应用标识(必填),腾讯视频云基于 sdkAppId 完成计费统计。<br>
+ *                                       【推荐取值】在腾讯云 [TRTC 控制台](https://console.cloud.tencent.com/rav/) 中创建应用,之后可以在账号信息页面中得到该 ID。<br>
+ * @param {String}       userId        - 【字段含义】用户标识(必填)。当前用户的 userId,相当于用户名,UTF-8编码。<br>
+ *                                       【推荐取值】如果一个用户在您的账号系统中的 ID 为“abc”,则 userId 即可设置为“abc”。<br>
+ * @param {String}       userSig       - 【字段含义】用户签名(必填),当前 userId 对应的验证签名,相当于登录密码。<br>
+ *                                       【推荐取值】请参考 [如何计算UserSig](https://cloud.tencent.com/document/product/647/17275)。<br>
+ * @param {Number}       roomId        - 【字段含义】房间号码(必填),指定房间号,在同一个房间里的用户(userId)可以彼此看到对方并进行视频通话, roomId 和 strRoomId 必须填一个, 若您选用 strRoomId,则 roomId 需要填写为0。<br>
+ *                                       【推荐取值】您可以随意指定,但请不要重复,如果您的用户账号 ID 是数字类型的,可以直接用创建者的用户 ID 作为 roomId。<br>
+ * @param {String}       strRoomId     - 【字段含义】字符串房间号码(选填),roomId 和 strRoomId 必须填一个。若两者都填,则优先选择 roomId。<br>
+ *                                       【推荐取值】您可以随意指定,但请不要重复。<br>
+ * @param {TRTCRoleType} role          - 【字段含义】直播场景下的角色,仅适用于直播场景(TRTCAppSceneLIVE 和 TRTCAppSceneVoiceChatRoom),视频通话场景下指定无效。<br>
+ *                                       【推荐取值】默认值:主播(TRTCRoleAnchor)<br>
+ * @param {String}       privateMapKey - 【字段含义】房间签名(非必填),如果您希望某个房间只能让特定的某些 userId 进入,就需要使用 privateMapKey 进行权限保护。<br>
+ *                                       【推荐取值】仅建议有高级别安全需求的客户使用,参考文档:[进房权限保护](https://cloud.tencent.com/document/product/647/32240)<br>
+ * @param {String}       businessInfo  - 【字段含义】业务数据(非必填),某些非常用的高级特性才需要用到此字段。<br>
+ *                                       【推荐取值】不建议使用<br>
+ * @param {String}       streamId      - 【字段含义】绑定腾讯云直播 CDN 流 ID[非必填],设置之后,您就可以在腾讯云直播 CDN 上通过标准直播方案(FLV或HLS)播放该用户的音视频流。<br>
+ *                                       【推荐取值】限制长度为64字节,可以不填写,一种推荐的方案是使用 “sdkappid_roomid_userid_main” 作为 streamid,这样比较好辨认且不会在您的多个应用中发生冲突。<br>
+ *                                       【特殊说明】要使用腾讯云直播 CDN,您需要先在[控制台](https://console.cloud.tencent.com/trtc/) 中的功能配置页开启“启动自动旁路直播”开关。<br>
+ *                                       【参考文档】[CDN 旁路直播](https://cloud.tencent.com/document/product/647/16826)。
+ * @param {String}       userDefineRecordId - 【字段含义】设置云端录制完成后的回调消息中的 "userdefinerecordid"  字段内容,便于您更方便的识别录制回调。<br>
+ *                                            【推荐取值】限制长度为64字节,只允许包含大小写英文字母(a-zA-Z)、数字(0-9)及下划线和连词符。<br>
+ *                                            【参考文档】[云端录制](https://cloud.tencent.com/document/product/647/16823)。
+ */
+export class TRTCParams {
+    constructor(sdkAppId, userId, roomId, userSig, strRoomId, privateMapKey, role, businessInfo, streamId, userDefineRecordId) {
+        this.sdkAppId = sdkAppId;
+        this.userId = userId;
+        this.roomId = roomId;
+        this.userSig = userSig;
+        this.strRoomId = strRoomId;
+        this.privateMapKey = privateMapKey;
+        this.role = role;
+        this.businessInfo = businessInfo;
+        this.streamId = streamId;
+        this.userDefineRecordId = userDefineRecordId;
+    }
+}
+/**
+ * 视频编码参数<br>
+ * 该设置决定了远端用户看到的画面质量(同时也是云端录制出的视频文件的画面质量)。
+ * @param {TRTCVideoResolution}     videoResolution - 【字段含义】 视频分辨率<br>
+ *                                                    【推荐取值】 <br>
+ *                                                     - 视频通话建议选择360 × 640及以下分辨率,resMode 选择 Portrait。<br>
+ *                                                     - 手机直播建议选择 540 × 960,resMode 选择 Portrait。<br>
+ *                                                     - Window 和 iMac 建议选择 640 × 360 及以上分辨率,resMode 选择 Landscape。
+ *                                                    【特别说明】 TRTCVideoResolution 默认只能横屏模式的分辨率,例如640 × 360。<br>
+ *                                                                如需使用竖屏分辨率,请指定 resMode 为 Portrait,例如640 × 360结合 Portrait 则为360 × 640。<br>
+ * @param {TRTCVideoResolutionMode} resMode         - 【字段含义】分辨率模式(横屏分辨率 - 竖屏分辨率)<br>
+ *                                                    【推荐取值】手机直播建议选择 Portrait,Window 和 Mac 建议选择 Landscape。<br>
+ *                                                    【特别说明】如果 videoResolution 指定分辨率 640 × 360,resMode 指定模式为 Portrait,则最终编码出的分辨率为360 × 640。<br>
+ * @param {Number}                  videoFps        - 【字段含义】视频采集帧率<br>
+ *                                                    【推荐取值】15fps 或 20fps,10fps 以下会有轻微卡顿感,5fps 以下卡顿感明显,20fps 以上的帧率则过于浪费(电影的帧率也只有 24fps)。<br>
+ *                                                    【特别说明】很多 Android 手机的前置摄像头并不支持15fps以上的采集帧率,部分过于突出美颜功能的 Android 手机前置摄像头的采集帧率可能低于10fps。<br>
+ * @param {Number}                  videoBitrate    - 【字段含义】视频上行码率<br>
+ *                                                    【推荐取值】推荐设置请参考本文件前半部分 TRTCVideoResolution 定义处的注释说明<br>
+ *                                                    【特别说明】码率太低会导致视频中有很多的马赛克<br>
+ * @param {Number}                  minVideoBitrate  -【字段含义】最低视频码率,SDK 会在网络不佳的情况下主动降低视频码率,最低会降至 minVideoBitrate 所设定的数值。
+ *                                                    【推荐取值】<br>
+ *                                                      - 如果您追求“允许卡顿但要保持清晰”的效果,可以设置 minVideoBitrate 为 videoBitrate 的 60%;
+ *                                                      - 如果您追求“允许模糊但要保持流畅”的效果,可以设置 minVideoBitrate 为 200kbps;
+ *                                                      - 如果您将 videoBitrate 和 minVideoBitrate 设置为同一个值,等价于关闭 SDK 的自适应调节能力;
+ *                                                      - 默认值:0,此时最低码率由 SDK 根据分辨率情况,自动设置合适的数值。<br>
+ *                                                    【特别说明】<br>
+ *                                                     - 当您把分辨率设置的比较高时,minVideoBitrate 不适合设置的太低,否则会出现画面模糊和大范围的马赛克宏块。
+ *                                                       比如把分辨率设置为 720p,把码率设置为 200kbps,那么编码出的画面将会出现大范围区域性马赛克。
+ * @param {Boolean}                 enableAdjustRes - 【字段含义】是否允许调整分辨率<br>
+ *                                                    【推荐取值】 <br>
+ *                                                     - 手机直播建议选择 NO。<br>
+ *                                                     - 视频通话模式,若更关注流畅性,建议选择 YES,此时若遇到带宽有限的弱网,SDK 会自动降低分辨率以保障更好的流畅度(仅针对 TRTCVideoStreamTypeBig 生效)。
+ *                                                     - 默认值:NO。<br>
+ *                                                    【特别说明】若有录制需求,选择 YES 时,请确保通话过程中,调整分辨率不会影响您的录制效果。<br>
+ */
+export class TRTCVideoEncParam {
+    constructor(videoResolution = TRTCVideoResolution.TRTCVideoResolution_640_360, resMode = TRTCVideoResolutionMode.TRTCVideoResolutionModePortrait, videoFps = 15, videoBitrate = 550, minVideoBitrate = 0, enableAdjustRes = false) {
+        this.videoResolution = videoResolution;
+        this.videoResolutionMode = resMode;
+        this.videoFps = videoFps;
+        this.videoBitrate = videoBitrate;
+        this.minVideoBitrate = minVideoBitrate;
+        this.enableAdjustRes = enableAdjustRes;
+    }
+}
+;
+/**
+ * 画面渲染参数<br>
+ * 您可以通过设置此参数来控制画面的旋转、填充、镜像模式
+ * @param {TRTCVideoRotation} rotation  - 【字段含义】视频画面旋转方向
+ * @param {TRTCVideoFillMode} fillMode  - 【字段含义】视频画面填充模式
+ * @param {TRTCVideoMirrorType} mirrorType  - 【字段含义】画面渲染镜像类型
+ */
+export class TRTCRenderParams {
+    constructor(rotation = TRTCVideoRotation.TRTCVideoRotation_0, fillMode = TRTCVideoFillMode.TRTCVideoFillMode_Fit, mirrorType = TRTCVideoMirrorType.TRTCVideoMirrorType_Disable) {
+        this.rotation = rotation;
+        this.fillMode = fillMode;
+        this.mirrorType = mirrorType;
+    }
+}
+/**
+ * 屏幕分享参数(仅适用于 Android 平台)<br>
+ * 该设置决定了远端用户看到的画面质量(同时也是云端录制出的视频文件的画面质量)。
+ * @param {Boolean} enableForegroundService - 是否同时启用 SDK 内置的前台服务,停止屏幕分享时会停止该服务。
+ * 从 Android 10 开始,如果 APP 的 targetSdkVersion 大于等于 29 时,
+ * 需要有 mediaProjection 类型的前台服务才能成功开始,否则会报 SecurityException。您可以自己启动一个前台服务,也可以使用 SDK 内置的前台服务。当使用内置的前台服务时 ** 您需要在 manifest.json 中添加以下内容:<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />**
+ */
+export class TRTCScreenShareParams {
+    constructor(enableForegroundService) {
+        this.enableForegroundService = enableForegroundService;
+    }
+}
+;
+/**
+ * 音频路由(即声音的播放模式)<br>
+ * @enum {Number}
+ */
+const TRTCAudioRoute_HACK_JSDOC = {
+    /** 使用扬声器播放(即“免提”),扬声器位于手机底部,声音偏大,适合外放音乐 */
+    TRTCAudioRouteSpeaker: 0,
+    /** 使用听筒播放,听筒位于手机顶部,声音偏小,适合需要保护隐私的通话场景 */
+    TRTCAudioRouteEarpiece: 1,
+};
+export var TRTCAudioRoute;
+(function (TRTCAudioRoute) {
+    TRTCAudioRoute[TRTCAudioRoute["TRTCAudioRouteSpeaker"] = 0] = "TRTCAudioRouteSpeaker";
+    TRTCAudioRoute[TRTCAudioRoute["TRTCAudioRouteEarpiece"] = 1] = "TRTCAudioRouteEarpiece";
+})(TRTCAudioRoute || (TRTCAudioRoute = {}));
+/////////////////////////////////////////////////////////////////////////////////
+//
+//                    【其它参数】
+//
+/////////////////////////////////////////////////////////////////////////////////
+export var TRTCShareSource;
+(function (TRTCShareSource) {
+    TRTCShareSource["InApp"] = "InApp";
+    TRTCShareSource["ByReplaykit"] = "ByReplaykit";
+})(TRTCShareSource || (TRTCShareSource = {}));
+/**
+ * 重力感应开关(仅适用于移动端)<br>
+ * @enum {Number}
+ */
+const TRTCGSensorMode_HACK_JSDOC = {
+    /** 不适配重力感应,该模式是桌面平台上的默认值,该模式下,当前用户发布出去的视频画面不受重力感应方向变化的影响。 */
+    TRTC_GSENSOR_MODE_DISABLE: 0,
+    /** 适配重力感应,该模式是移动平台上的默认值,该模式下,当前用户发布出去的视频画面会跟随设备的重力感应方向进行相应的调整,同时本地预览画面保持方向不变。
+      SDK 目前支持的一种适配模式是:当手机或 Pad 上下颠倒时,为了保证远端用户看到的画面方向正常,SDK 会自动将发布出去的画面上下旋转180度。如果您的 APP 的界面层开启了重力感应自适应,推荐使用 UIFixLayout 模式。
+    */
+    TRTC_GSENSOR_MODE_UIAUTOLAYOUT: 1,
+};
+export var TRTCGSensorMode;
+(function (TRTCGSensorMode) {
+    TRTCGSensorMode[TRTCGSensorMode["TRTC_GSENSOR_MODE_DISABLE"] = 0] = "TRTC_GSENSOR_MODE_DISABLE";
+    TRTCGSensorMode[TRTCGSensorMode["TRTC_GSENSOR_MODE_UIAUTOLAYOUT"] = 1] = "TRTC_GSENSOR_MODE_UIAUTOLAYOUT";
+})(TRTCGSensorMode || (TRTCGSensorMode = {}));

+ 10 - 0
TrtcCloud/lib/constants.js

@@ -0,0 +1,10 @@
+export const NAME = {
+    ANDROID: 'android',
+    IOS: 'ios',
+    STRING: 'string',
+    FUNCTION: 'function',
+    BOOLEAN: 'boolean',
+    NUMBER: 'number',
+    LOG_PREFIX: '【UniApp-JS】',
+};
+export const errorCodeUrl = 'https://web.sdk.qcloud.com/trtc/uniapp/doc/zh-cn/ErrorCode.html';

+ 989 - 0
TrtcCloud/lib/index.js

@@ -0,0 +1,989 @@
+import TrtcCloudImpl from './TrtcCloudImpl';
+import { TRTCVideoStreamType } from './TrtcDefines';
+const version = '1.3.3';
+export * from './TrtcDefines';
+/**
+ * TrtcCloud
+ *
+ * @class TrtcCloud
+ */
+export default class TrtcCloud {
+    /**
+     * 创建 TrtcCloud 单例
+     *
+     * @static
+     * @memberof TrtcCloud
+     * @example
+     * TrtcCloud.createInstance();
+     */
+    static createInstance() {
+        console.log('----------------------------------------------------------------');
+        console.log(`                        SDK ${version}                    `);
+        console.log('----------------------------------------------------------------');
+        return TrtcCloudImpl._createInstance();
+    }
+    /**
+     * 销毁 TrtcCloud 单例
+     *
+     * @static
+     * @memberof TrtcCloud
+     * @example
+     * TrtcCloud.destroyInstance();
+     */
+    static destroyInstance() {
+        return TrtcCloudImpl._destroyInstance();
+    }
+    /**
+     * 设置 TrtcCloud 事件监听
+     *
+     * @param {String} event 事件名称
+     * @param {Function} callback 事件回调
+     * @memberof TrtcCloud
+     *
+     * @example
+     * this.trtcCloud = TrtcCloud.createInstance(); // 创建 trtcCloud 实例
+     * this.trtcCloud.on('onEnterRoom', (res) => {});
+     */
+    on(event, callback) {
+        return TrtcCloudImpl._getInstance().on(event, callback);
+    }
+    /**
+     * 取消事件绑定<br>
+     *
+     * @param {String} event 事件名称,传入通配符 '*' 会解除所有事件绑定。
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.off('onEnterRoom');
+     *
+     * this.trtcCloud.off('*'); // 取消所有绑定的事件
+     */
+    off(event) {
+        return TrtcCloudImpl._getInstance().off(event);
+    }
+    /**
+     * 进房<br>
+     * 调用接口后,您会收到来自 TRTCCallback 中的 [onEnterRoom(result)]{@link TRTCCallback#onEnterRoom} 回调
+     * 如果加入成功,result 会是一个正数(result > 0),表示加入房间所消耗的时间,单位是毫秒(ms)。<br>
+     * 如果加入失败,result 会是一个负数(result < 0),表示进房失败的错误码。
+     *
+     * * 参数 scene 的枚举值如下:
+     * - {@link TRTCAppSceneVideoCall}:<br>
+     *          视频通话场景,支持720P、1080P高清画质,单个房间最多支持300人同时在线,最高支持50人同时发言。<br>
+     *          适合:[1对1视频通话]、[300人视频会议]、[在线问诊]、[视频聊天]、[远程面试]等。<br>
+     * - {@link TRTCAppSceneAudioCall}:<br>
+     *          语音通话场景,支持 48kHz,支持双声道。单个房间最多支持300人同时在线,最高支持50人同时发言。<br>
+     *          适合:[1对1语音通话]、[300人语音会议]、[语音聊天]、[语音会议]、[在线狼人杀]等。<br>
+     * - {@link TRTCAppSceneLIVE}:<br>
+     *          视频互动直播,支持平滑上下麦,切换过程无需等待,主播延时小于300ms;支持十万级别观众同时播放,播放延时低至1000ms。<br>
+     *          适合:[视频低延时直播]、[十万人互动课堂]、[视频直播 PK]、[视频相亲房]、[互动课堂]、[远程培训]、[超大型会议]等。<br>
+     * - {@link TRTCAppSceneVoiceChatRoom}:<br>
+     *          语音互动直播,支持平滑上下麦,切换过程无需等待,主播延时小于300ms;支持十万级别观众同时播放,播放延时低至1000ms。<br>
+     *          适合:[语音低延时直播]、[语音直播连麦]、[语聊房]、[K 歌房]、[FM 电台]等。<br>
+     *
+     * **Note:**
+     * 1. 当 scene 选择为 TRTCAppSceneLIVE 或 TRTCAppSceneVoiceChatRoom 时,您必须通过 TRTCParams 中的 role 字段指定当前用户的角色。
+     * 2. 不管进房是否成功,enterRoom 都必须与 exitRoom 配对使用,在调用 `exitRoom` 前再次调用 `enterRoom` 函数会导致不可预期的错误问题。
+     *
+     * @param {TRTCParams} params - 进房参数
+     * @param {Number} params.sdkAppId      - 应用标识(必填)
+     * @param {String} params.userId        - 用户标识(必填)
+     * @param {String} params.userSig       - 用户签名(必填)
+     * @param {Number} params.roomId        - 房间号码, roomId 和 strRoomId 必须填一个, 若您选用 strRoomId,则 roomId 需要填写为0。
+     * @param {String} params.strRoomId     - 字符串房间号码 [选填],在同一个房间内的用户可以看到彼此并进行视频通话, roomId 和 strRoomId 必须填一个。若两者都填,则优先选择 roomId
+     * @param {TRTCRoleType} params.role    - 直播场景下的角色,默认值:主播
+     * - TRTCRoleAnchor: 主播,可以上行视频和音频,一个房间里最多支持50个主播同时上行音视频。
+     * - TRTCRoleAudience: 观众,只能观看,不能上行视频和音频,一个房间里的观众人数没有上限。
+     * @param {String=} params.privateMapKey - 房间签名(非必填)
+     * @param {String=} params.businessInfo  - 业务数据(非必填)
+     * @param {String=} params.streamId      - 自定义 CDN 播放地址(非必填)
+     * @param {String=} params.userDefineRecordId - 设置云端录制完成后的回调消息中的 "userdefinerecordid" 字段内容,便于您更方便的识别录制回调(非必填)
+     * @param {TRTCAppScene} scene 应用场景,目前支持视频通话(TRTCAppSceneVideoCall)、语音通话(TRTCAppSceneAudioCall)、在线直播(TRTCAppSceneLIVE)、语音聊天室(VTRTCAppSceneVoiceChatRoom)四种场景,
+     * 详见 [TrtcDefines] 中 TRTCAppScene 参数定义
+     *
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCAppScene } from '@/TrtcCloud/lib/TrtcDefines';
+     * this.trtcCloud = TrtcCloud.createInstance(); // 创建实例,只需创建一次
+     * const params = {
+     *   sdkAppId: 0,
+     *   userId: 'xxx',
+     *   roomId: 12345,
+     *   userSig: 'xxx'
+     * };
+     * this.trtcCloud.enterRoom(params, TRTCAppScene.TRTCAppSceneVideoCall);
+     */
+    enterRoom(params, scene) {
+        return TrtcCloudImpl._getInstance().enterRoom(params, scene);
+    }
+    /**
+     * 退房<br>
+     * 执行退出房间的相关逻辑释放资源后,SDK 会通过 `onExitRoom()` 回调通知到您
+     *
+     * **Note:**
+     * 1. 如果您要再次调用 `enterRoom()` 或者切换到其它的音视频 SDK,请等待 `onExitRoom()` 回调到来后再执行相关操作,否则可能会遇到如摄像头、麦克风设备被强占等各种异常问题。
+     *
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.exitRoom();
+     */
+    exitRoom() {
+        return TrtcCloudImpl._getInstance().exitRoom();
+    }
+    /**
+     * 切换角色,仅适用于直播场景(TRTCAppSceneLIVE 和 TRTCAppSceneVoiceChatRoom)
+     *
+     * 在直播场景下,一个用户可能需要在“观众”和“主播”之间来回切换。
+     * 您可以在进房前通过 TRTCParams 中的 role 字段确定角色,也可以通过 switchRole 在进房后切换角色。
+     *
+     * @param {TRTCRoleType} role - 目标角色,默认为主播
+     * - TRTCRoleAnchor: 主播,可以上行视频和音频,一个房间里最多支持50个主播同时上行音视频。
+     * - TRTCRoleAudience: 观众,只能观看,不能上行视频和音频,一个房间里的观众人数没有上限。
+     *
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCRoleType } from '@/TrtcCloud/lib/TrtcDefines';
+     * this.trtcCloud.switchRole(TRTCRoleType.TRTCRoleAudience);
+     */
+    switchRole(role) {
+        return TrtcCloudImpl._getInstance().switchRole(role);
+    }
+    /**
+     * 请求跨房通话
+     *
+     * 默认情况下,只有同一个房间中的用户之间可以进行音视频通话,不同的房间之间的音视频流是相互隔离的。
+     * 使用该接口让身处两个不同房间中的主播进行跨房间的音视频流分享,从而让每个房间中的观众都能观看到这两个主播的音视频。
+     * 跨房通话的请求结果会通过监听 [onConnectOtherRoom](https://web.sdk.qcloud.com/trtc/uniapp/doc/zh-cn/TRTCCallback.html#event:onConnectOtherRoom) 事件通知给您。
+     *
+     * @param {Object} params - 跨房通话参数
+     * - 如果对端的房间号为数字,那么传入的参数为 roomId。
+     * - 如果对端的房间号为字符串,那么传入的参数为 strRoomId。
+     * - 针对对端的房间号类型传递对应参数,不需要两个同时传递。具体请看 example 的使用。
+     * @param {Number} params.roomId 跨房通话时对端的数字房间号 roomId(与 strRoomId 选填其中一个,不可同时传递)
+     * @param {String} params.strRoomId 跨房通话时对端的字符串房间号 strRoomId(与 roomId 选填其中一个,不可同时传递)
+     * @param {String} params.userId 跨房通话时对端的 userId(必填)
+     *
+     *
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.connectOtherRoom({"roomId": 1233, "userId": "user_11"});
+     * this.trtcCloud.connectOtherRoom({"strRoomId": "1233", "userId": "user_22"});
+     */
+    connectOtherRoom(params) {
+        return TrtcCloudImpl._getInstance().connectOtherRoom(params);
+    }
+    /**
+     * 退出跨房通话
+     *
+     * 退出跨房通话的请求结果会通过监听 [onDisconnectOtherRoom](https://web.sdk.qcloud.com/trtc/uniapp/doc/zh-cn/TRTCCallback.html#event:onDisconnectOtherRoom) 事件通知给您。
+     *
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.disconnectOtherRoom();
+     */
+    disconnectOtherRoom() {
+        return TrtcCloudImpl._getInstance().disconnectOtherRoom();
+    }
+    /**
+     * 开启本地视频的预览画面<br>
+     * 当开始渲染首帧摄像头画面时,您会收到 `onFirstVideoFrame(null)` 回调
+     *
+     * @param {Boolean} isFrontCamera 前置、后置摄像头,true:前置摄像头;false:后置摄像头,**默认为 true**
+     * @param {String=} viewId 用于承载视频画面的渲染控件,使用原生插件中的 TRTCCloudUniPlugin-TXLocalViewComponent component,需要提供 viewId 属性值,例如 viewId=userId
+     * @memberof TrtcCloud
+     * @example
+     * // 预览本地画面
+     * const viewId = this.userId;
+     * this.trtcCloud.startLocalPreview(true, viewId);
+     */
+    startLocalPreview(isFrontCamera = true, viewId) {
+        return TrtcCloudImpl._getInstance().startLocalPreview(isFrontCamera, viewId);
+    }
+    /**
+     * 设置视频编码器的编码参数
+     * - 该设置能够决定远端用户看到的画面质量,同时也能决定云端录制出的视频文件的画面质量。
+     * @param {TRTCVideoEncParam} param 用于设置视频编码器的相关参数
+     * @memberof TrtcCloud
+     * @example
+     *
+     * import { TRTCVideoResolution, TRTCVideoResolutionMode, TRTCVideoEncParam } from '@/TrtcCloud/lib/TrtcDefines';
+     * const videoResolution = TRTCVideoResolution.TRTCVideoResolution_480_360;
+     * const videoResolutionMode = TRTCVideoResolutionMode.TRTCVideoResolutionModeLandscape; // 横屏采集
+     * const videoFps = 15;
+     * const videoBitrate = 900;
+     * const minVideoBitrate = 200;
+     * const enableAdjustRes = false;
+     * // const param = new TRTCVideoEncParam(videoResolution, videoResolutionMode, videoFps, videoBitrate, minVideoBitrate, enableAdjustRes); // v1.1.0 方式
+     *
+     * const param = { // v1.2.0 以上版本支持的方式
+     *  videoResolution,
+     *  videoResolutionMode,
+     *  videoFps,
+     *  videoBitrate,
+     *  minVideoBitrate,
+     *  enableAdjustRes,
+     * };
+     *
+     * this.trtcCloud.setVideoEncoderParam(param);
+     */
+    setVideoEncoderParam(param) {
+        return TrtcCloudImpl._getInstance().setVideoEncoderParam(param);
+    }
+    /**
+     * 切换前置或后置摄像头
+     *
+     * @param {Boolean} isFrontCamera 前置、后置摄像头,true:前置摄像头;false:后置摄像头
+     * @memberof TrtcCloud
+     * @example
+     * // 切换前置或后置摄像头
+     * const isFrontCamera = true;
+     * this.trtcCloud.switchCamera(isFrontCamera);
+     */
+    switchCamera(isFrontCamera) {
+        return TrtcCloudImpl._getInstance().switchCamera(isFrontCamera);
+    }
+    /**
+     * 停止本地视频采集及预览
+     *
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.stopLocalPreview();
+     */
+    stopLocalPreview() {
+        return TrtcCloudImpl._getInstance().stopLocalPreview();
+    }
+    /**
+     * 设置本地画面的渲染参数,可设置的参数包括有:画面的旋转角度、填充模式以及左右镜像等。
+     * @param {TRTCRenderParams} params - 本地图像的参数
+     * @param {TRTCVideoRotation} params.rotation - 图像的顺时针旋转角度,支持90、180以及270旋转角度,默认值:TRTCVideoRotation.TRTCVideoRotation_0
+     * @param {TRTCVideoFillMode} params.fillMode - 视频画面填充模式,填充(画面可能会被拉伸裁剪)或适应(画面可能会有黑边),默认值:TRTCVideoFillMode.TRTCVideoFillMode_Fill
+     * @param {TRTCVideoMirrorType} params.mirrorType - 画面镜像模式,默认值:TRTCVideoMirrorType.TRTCVideoMirrorType_Auto
+     *
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCVideoRotation, TRTCVideoFillMode, TRTCVideoMirrorType } from '@/TrtcCloud/lib/TrtcDefines';
+     * const renderParams = {
+     *  rotation: TRTCVideoRotation.TRTCVideoRotation_0,
+     *  fillMode: TRTCVideoFillMode.TRTCVideoFillMode_Fill,
+     *  mirrorType: TRTCVideoMirrorType.TRTCVideoMirrorType_Auto
+     * };
+     * this.trtcCloud.setLocalRenderParams(renderParams);
+     */
+    setLocalRenderParams(params) {
+        return TrtcCloudImpl._getInstance().setLocalRenderParams(params);
+    }
+    /**
+     * 暂停/恢复发布本地的视频流
+     *
+     * 该接口可以暂停(或恢复)发布本地的视频画面,暂停之后,同一房间中的其他用户将无法继续看到自己画面。 该接口在指定 TRTCVideoStreamTypeBig 时等效于 start/stopLocalPreview 这两个接口,但具有更好的响应速度。 因为 start/stopLocalPreview 需要打开和关闭摄像头,而打开和关闭摄像头都是硬件设备相关的操作,非常耗时。 相比之下,muteLocalVideo 只需要在软件层面对数据流进行暂停或者放行即可,因此效率更高,也更适合需要频繁打开关闭的场景。 当暂停/恢复发布指定 TRTCVideoStreamTypeBig 后,同一房间中的其他用户将会收到 onUserVideoAvailable 回调通知。 当暂停/恢复发布指定 TRTCVideoStreamTypeSub 后,同一房间中的其他用户将会收到 onUserSubStreamAvailable 回调通知。
+     * @param {Number} streamType 要暂停/恢复的视频流类型(仅支持 TRTCVideoStreamTypeBig 和 TRTCVideoStreamTypeSub)
+     * @param {Boolean} mute - true:屏蔽;false:开启,默认值:false
+     *
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.muteLocalVideo(TRTCVideoStreamType.TRTCVideoStreamTypeBig, true);
+     */
+    muteLocalVideo(streamType, mute) {
+        return TrtcCloudImpl._getInstance().muteLocalVideo(streamType, mute);
+    }
+    /**
+     * 显示远端视频或辅流<br>
+     *
+     * @param {String} userId 指定远端用户的 userId
+     * @param {Number} streamType 指定要观看 userId 的视频流类型
+     * - 高清大画面:TRTCVideoStreamType.TRTCVideoStreamTypeBig
+     * - 低清小画面:TRTCVideoStreamType.TRTCVideoStreamTypeSmall
+     * - 辅流(屏幕分享):TRTCVideoStreamType.TRTCVideoStreamTypeSub
+     * @param {String} viewId 用于承载视频画面的渲染控件,使用原生插件中的 TRTCCloudUniPlugin-TXRemoteViewComponent component,需要提供 viewId 属性值,例如 viewId=userId
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCVideoStreamType } from '@/TrtcCloud/lib/TrtcDefines';
+     * const viewId = this.remoteUserId;
+     * this.trtcCloud.startRemoteView(userId, TRTCVideoStreamType.TRTCVideoStreamTypeBig, viewId);
+     */
+    startRemoteView(userId, streamType, viewId) {
+        return TrtcCloudImpl._getInstance().startRemoteView(userId, streamType, viewId);
+    }
+    /**
+     * 停止显示远端视频画面,同时不再拉取该远端用户的视频数据流<br>
+     * 指定要停止观看的 userId 的视频流类型
+     *
+     * @param {String} userId 指定的远端用户 ID
+     * @param {Number} streamType
+     * - 高清大画面:TRTCVideoStreamType.TRTCVideoStreamTypeBig
+     * - 低清小画面:TRTCVideoStreamType.TRTCVideoStreamTypeSmall
+     * - 辅流(屏幕分享):TRTCVideoStreamType.TRTCVideoStreamTypeSub
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCVideoStreamType } from '@/TrtcCloud/lib/TrtcDefines';
+     * this.trtcCloud.stopRemoteView(remoteUserId, TRTCVideoStreamType.TRTCVideoStreamTypeBig);
+     */
+    stopRemoteView(userId, streamType) {
+        return TrtcCloudImpl._getInstance().stopRemoteView(userId, streamType);
+    }
+    /**
+     * 设置远端画面的渲染参数,可设置的参数包括有:画面的旋转角度、填充模式以及左右镜像等。
+     * @param {String} userId 远端用户 ID
+     * @param {Number} streamType 可以设置为主路画面(TRTCVideoStreamTypeBig)或辅路画面(TRTCVideoStreamTypeSub)
+     * @param {TRTCRenderParams} params - 图像的参数
+     * @param {TRTCVideoRotation} params.rotation - 图像的顺时针旋转角度,支持90、180以及270旋转角度,默认值:TRTCVideoRotation.TRTCVideoRotation_0
+     * @param {TRTCVideoFillMode} params.fillMode - 视频画面填充模式,填充(画面可能会被拉伸裁剪)或适应(画面可能会有黑边),默认值:TRTCVideoFillMode.TRTCVideoFillMode_Fill
+     * @param {TRTCVideoMirrorType} params.mirrorType - 画面镜像模式,默认值:TRTCVideoMirrorType.TRTCVideoMirrorType_Auto
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCVideoRotation, TRTCVideoFillMode, TRTCVideoMirrorType } from '@/TrtcCloud/lib/TrtcDefines';
+     * const renderParams = {
+     *  rotation: TRTCVideoRotation.TRTCVideoRotation_0,
+     *  fillMode: TRTCVideoFillMode.TRTCVideoFillMode_Fill,
+     *  mirrorType: TRTCVideoMirrorType.TRTCVideoMirrorType_Auto
+     * };
+     * this.trtcCloud.setRemoteRenderParams(userId, TRTCVideoStreamType.TRTCVideoStreamTypeBig, renderParams);
+     */
+    setRemoteRenderParams(userId, streamType, params) { }
+    /**
+     * 设置视频编码器输出的画面方向<br>
+     * 该设置不影响本地画面的预览方向,但会影响房间中其他用户所观看到(以及云端录制文件)的画面方向。
+     * 当用户将手机或 Pad 上下颠倒时,由于摄像头的采集方向没有变,所以房间中其他用户所看到的画面会变成上下颠倒的,
+     * 在这种情况下,您可以通过调用该接口将 SDK 编码出的画面方向旋转180度,如此一来,房间中其他用户所看到的画面可保持正常的方向。
+     * 如果您希望实现上述这种友好的交互体验,我们更推荐您直接调用 setGSensorMode 实现更加智能的方向适配,无需您手动调用本接口。
+     * @param {Number} rotation 目前支持 0、90、180、270 两个旋转角度,默认值:TRTCVideoRotation_0,即不旋转。
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCVideoRotation } from '@/TrtcCloud/lib/TrtcDefines';
+     * this.trtcCloud.setVideoEncoderRotation(TRTCVideoRotation.TRTCVideoRotation_90);
+     */
+    setVideoEncoderRotation(rotation) {
+        return TrtcCloudImpl._getInstance().setVideoEncoderRotation(rotation);
+    }
+    /**
+     * 设置编码器输出的画面镜像模式
+     * @param {Boolean} mirror 是否开启远端镜像,true:开启远端画面镜像;false:关闭远端画面镜像,默认值:false。
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.setVideoEncoderMirror(true);
+     */
+    setVideoEncoderMirror(mirror) {
+        return TrtcCloudImpl._getInstance().setVideoEncoderMirror(mirror);
+    }
+    /**
+     * 设置重力感应的适配模式<br>
+     * 您可以通过本接口实现如下这种友好的交互体验:
+     * 当用户将手机或 Pad 上下颠倒时,由于摄像头的采集方向没有变,所以房间中其他用户所看到的画面会变成上下颠倒的,
+     * 在这种情况下,您可以通过调用该接口让 SDK 根据设备陀螺仪的朝向自动调整本地画面和编码器输出画面的旋转方向,以使远端观众可以看到正常朝向的画面。
+     * @param {Number} mode 重力感应模式,详情请参见 TRTCGSensorMode,默认值:TRTCGSensorMode_UIAutoLayout。。
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCGSensorMode } from '@/TrtcCloud/lib/TrtcDefines';
+     * this.trtcCloud.setGSensorMode(TRTCGSensorMode.TRTC_GSENSOR_MODE_DISABLE);
+     */
+    setGSensorMode(mode) {
+        return TrtcCloudImpl._getInstance().setGSensorMode(mode);
+    }
+    /**
+     * 视频画面截图
+     *
+     * 您可以通过本接口截取本地的视频画面,远端用户的主路画面以及远端用户的辅路(屏幕分享)画面。
+     *
+     * @param {String | null} userId 用户 ID,如指定 null 表示截取本地的视频画面
+     * @param {Number} streamType 视频流类型,可选择截取主路画面(TRTCVideoStreamTypeBig,常用于摄像头)或辅路画面(TRTCVideoStreamTypeSub,常用于屏幕分享)
+     * @param {TRTCSnapshotSourceType} sourceType 画面来源,可选择截取视频流画面(TRTCSnapshotSourceTypeStream)或视频渲染画面(TRTCSnapshotSourceTypeView),前者一般更清晰
+     *
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCVideoStreamType } from '@/TrtcCloud/lib/TrtcDefines';
+     * this.trtcCloud.snapshotVideo(null, TRTCVideoStreamType.TRTCVideoStreamTypeBig, TRTCSnapshotSourceType.TRTCSnapshotSourceTypeStream); // 截取本地视频流画面
+     * this.trtcCloud.snapshotVideo(this.remoteUserId, TRTCVideoStreamType.TRTCVideoStreamTypeBig, TRTCSnapshotSourceType.TRTCSnapshotSourceTypeView); // 截取远端指定用户视频渲染画面
+     */
+    snapshotVideo(userId, streamType, sourceType) {
+        return TrtcCloudImpl._getInstance().snapshotVideo(userId, streamType, sourceType);
+    }
+    /**
+     * 开启本地音频的采集和上行, 并设置音频质量<br>
+     * 该函数会启动麦克风采集,并将音频数据传输给房间里的其他用户。 SDK 不会默认开启本地音频采集和上行,您需要调用该函数开启,否则房间里的其他用户将无法听到您的声音<br>
+     * 主播端的音质越高,观众端的听感越好,但传输所依赖的带宽也就越高,在带宽有限的场景下也更容易出现卡顿
+     *
+     * @param {TRTCAudioQuality} quality 声音音质
+     * - TRTCAudioQualitySpeech,流畅:采样率:16k;单声道;音频裸码率:16kbps;适合语音通话为主的场景,比如在线会议,语音通话。
+     * - TRTCAudioQualityDefault,默认:采样率:48k;单声道;音频裸码率:50kbps;SDK 默认的音频质量,如无特殊需求推荐选择之。
+     * - TRTCAudioQualityMusic,高音质:采样率:48k;双声道 + 全频带;音频裸码率:128kbps;适合需要高保真传输音乐的场景,比如在线K歌、音乐直播等
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCAudioQuality } from '@/TrtcCloud/lib/TrtcDefines';
+     * this.trtcCloud.startLocalAudio(TRTCAudioQuality.TRTCAudioQualityDefault);
+     */
+    startLocalAudio(quality) {
+        return TrtcCloudImpl._getInstance().startLocalAudio(quality);
+    }
+    /**
+     * 关闭本地音频的采集和上行<br>
+     * 当关闭本地音频的采集和上行,房间里的其它成员会收到 `onUserAudioAvailable(false)` 回调通知
+     *
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.stopLocalAudio();
+     */
+    stopLocalAudio() {
+        return TrtcCloudImpl._getInstance().stopLocalAudio();
+    }
+    /**
+     * 静音本地的音频
+     *
+     * 当静音本地音频后,房间里的其它成员会收到 onUserAudioAvailable(false) 回调通知。
+     * 与 stopLocalAudio 不同之处在于,muteLocalAudio 并不会停止发送音视频数据,而是会继续发送码率极低的静音包。
+     * 在对录制质量要求很高的场景中,选择 muteLocalAudio 是更好的选择,能录制出兼容性更好的 MP4 文件。
+     * 这是由于 MP4 等视频文件格式,对于音频的连续性是要求很高的,简单粗暴地 stopLocalAudio 会导致录制出的 MP4 不易播放。
+     *
+     * @param {Boolean} mute - true:屏蔽;false:开启,默认值:false
+     *
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.muteLocalAudio(true);
+     */
+    muteLocalAudio(mute) {
+        return TrtcCloudImpl._getInstance().muteLocalAudio(mute);
+    }
+    /**
+     * 静音掉某一个用户的声音,同时不再拉取该远端用户的音频数据流
+     *
+     * @param {String}  userId - 用户 ID
+     * @param {Boolean} mute   - true:静音;false:非静音
+     *
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.muteRemoteAudio('denny', true);
+     */
+    muteRemoteAudio(userId, mute) {
+        return TrtcCloudImpl._getInstance().muteRemoteAudio(userId, mute);
+    }
+    /**
+     * 静音掉所有用户的声音,同时不再拉取该远端用户的音频数据流
+     *
+     * @param {Boolean} mute - true:静音;false:非静音
+     *
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.muteAllRemoteAudio(true);
+     */
+    muteAllRemoteAudio(mute) {
+        return TrtcCloudImpl._getInstance().muteAllRemoteAudio(mute);
+    }
+    /**
+     * 设置音频路由
+     *
+     * 设置“音频路由”,即设置声音是从手机的扬声器还是从听筒中播放出来,因此该接口仅适用于手机等移动端设备。 手机有两个扬声器:一个是位于手机顶部的听筒,一个是位于手机底部的立体声扬声器。
+     * 设置音频路由为听筒时,声音比较小,只有将耳朵凑近才能听清楚,隐私性较好,适合用于接听电话。 设置音频路由为扬声器时,声音比较大,不用将手机贴脸也能听清,因此可以实现“免提”的功能。
+     *
+     * @param {TRTCAudioRoute} route 音频路由,即声音由哪里输出(扬声器、听筒), 默认值:TRTCAudioRoute.TRTCAudioRouteSpeaker(扬声器),
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCAudioRoute } from '@/TrtcCloud/lib/TrtcDefines';
+     * this.trtcCloud.setAudioRoute(TRTCAudioRoute.TRTCAudioRouteSpeaker); // TRTCAudioRoute.TRTCAudioRouteEarpiece (听筒)
+     */
+    setAudioRoute(route) {
+        return TrtcCloudImpl._getInstance().setAudioRoute(route);
+    }
+    /**
+     * 启用或关闭音量大小提示
+     *
+     * 开启此功能后,SDK 会在 onUserVoiceVolume() 中反馈对每一路声音音量大小值的评估。
+     *
+     * **Note:**
+     * - 如需打开此功能,请在 startLocalAudio 之前调用才可以生效。
+     *
+     * @param {Number} interval - 设置 onUserVoiceVolume 回调的触发间隔,单位为ms,最小间隔为100ms,如果小于等于0则会关闭回调,建议设置为300ms
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.enableAudioVolumeEvaluation(300);
+     */
+    enableAudioVolumeEvaluation(interval) {
+        return TrtcCloudImpl._getInstance().enableAudioVolumeEvaluation(interval);
+    }
+    /////////////////////////////////////////////////////////////////////////////////
+    //
+    //                      屏幕分享
+    //
+    /////////////////////////////////////////////////////////////////////////////////
+    /**
+     * 设置屏幕分享(即辅路)的视频编码参数
+     *
+     * 该接口可以设定远端用户所看到的屏幕分享(即辅路)的画面质量,同时也能决定云端录制出的视频文件中屏幕分享的画面质量。 请注意如下两个接口的差异:
+     *  - setVideoEncoderParam 用于设置主路画面(TRTCVideoStreamTypeBig,一般用于摄像头)的视频编码参数。
+     *  - setSubStreamEncoderParam 用于设置辅路画面(TRTCVideoStreamTypeSub,一般用于屏幕分享)的视频编码参数。
+     *
+     * **Note:**
+     *  - 即使您使用主路传输屏幕分享(在调用 startScreenCapture 时设置 type=TRTCVideoStreamTypeBig),依然要使用 setSubStreamEncoderParam 设定屏幕分享的编码参数,而不要使用 setVideoEncoderParam
+     * @param {TRTCVideoEncParam} param	辅流编码参数,详情请参考 TRTCVideoEncParam。
+     * @memberof TrtcCloud
+     * @example
+     * const params = {
+     *   videoResolution: TRTCVideoResolution.TRTCVideoResolution_640_360,
+     *   videoResolutionMode: TRTCVideoResolutionMode.TRTCVideoResolutionModePortrait,
+     *   videoFps: 15,
+     *   videoBitrate: 900,
+     *   minVideoBitrate: 200,
+     *   enableAdjustRes: false,
+     * };
+     * this.trtcCloud.setSubStreamEncoderParam(params);
+     */
+    setSubStreamEncoderParam(param) {
+        return TrtcCloudImpl._getInstance().setSubStreamEncoderParam(param);
+    }
+    /**
+     * 启动屏幕分享
+     *
+     * **Note:**
+     *  - 一个用户同时最多只能上传一条主路(TRTCVideoStreamTypeBig)画面和一条辅路(TRTCVideoStreamTypeSub)画面,
+     * 默认情况下,屏幕分享使用辅路画面,如果使用主路画面,建议您提前停止摄像头采集(stopLocalPreview)避免相互冲突。
+     *  - **仅支持 iOS 13.0 及以上系统,进行应用内的屏幕分享**
+     *  - **Android: UniApp 使用 SDK 内置的前台服务时,只需要将接口参数 enableForegroundService 设置为 true。**
+     *  - **Android: UniApp 自己启动前台,需要在 mediaProject 类型的前台服务成功后再启动屏幕分享。**
+     *
+     * @param {Number} streamType 屏幕分享使用的线路,可以设置为主路(TRTCVideoStreamTypeBig)或者辅路(TRTCVideoStreamTypeSub),推荐使用
+     * @param {TRTCVideoEncParam} encParams 屏幕分享的画面编码参数,可以设置为 null,表示让 SDK 选择最佳的编码参数(分辨率、码率等)。即使在调用 startScreenCapture 时设置 type=TRTCVideoStreamTypeBig,依然可以使用此接口更新屏幕分享的编码参数。
+     * @param {TRTCScreenShareParams} shareParams 您可以通过其中的 enableForegroundService 参数启用 SDK 内置的前台服务
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCVideoResolution, TRTCVideoResolutionMode, TRTCVideoStreamType} from '@/TrtcCloud/lib/TrtcDefines';
+     * const encParams = {
+     *   videoResolution: TRTCVideoResolution.TRTCVideoResolution_640_360,
+     *   videoResolutionMode: TRTCVideoResolutionMode.TRTCVideoResolutionModePortrait,
+     *   videoFps: 15,
+     *   videoBitrate: 900,
+     *   minVideoBitrate: 200,
+     *   enableAdjustRes: false,
+     * };
+     * const shareParams = {
+     *   enableForegroundService: true,
+     * };
+     * this.trtcCloud.startScreenCapture(TRTCVideoStreamType.TRTCVideoStreamTypeSub, encParams, shareParams);
+     */
+    startScreenCapture(streamType = TRTCVideoStreamType.TRTCVideoStreamTypeSub, encParams = null, shareParams = {}) {
+        return TrtcCloudImpl._getInstance().startScreenCapture(streamType, encParams, shareParams);
+    }
+    /**
+     * 停止屏幕分享
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.stopScreenCapture();
+     */
+    stopScreenCapture() {
+        return TrtcCloudImpl._getInstance().stopScreenCapture();
+    }
+    /**
+     * 暂停屏幕分享
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.pauseScreenCapture();
+     */
+    pauseScreenCapture() {
+        return TrtcCloudImpl._getInstance().pauseScreenCapture();
+    }
+    /**
+     * 恢复屏幕分享
+     * @memberof TrtcCloud
+     * @example
+     * this.trtcCloud.resumeScreenCapture();
+     */
+    resumeScreenCapture() {
+        return TrtcCloudImpl._getInstance().resumeScreenCapture();
+    }
+    /////////////////////////////////////////////////////////////////////////////////
+    //
+    //                      美颜 + 水印
+    //
+    /////////////////////////////////////////////////////////////////////////////////
+    /**
+     * 设置美颜(磨皮)算法
+     * TRTC 内置多种不同的磨皮算法,您可以选择最适合您产品定位的方案
+     *
+     * **Note:**
+     * - 设置美颜前,先调用 `setBeautyLevel` 设置美颜级别。否则美颜级别为 0 表示关闭美颜
+     *
+     * @param {TRTCBeautyStyle} beautyStyle 美颜风格,TRTCBeautyStyleSmooth:光滑;TRTCBeautyStyleNature:自然;TRTCBeautyStylePitu:优图
+     * @memberof TrtcCloud
+     * @example
+     * import { TRTCBeautyStyle } from '@/TrtcCloud/lib/TrtcDefines';
+     * const beautyLevel = 5; // 美颜级别,取值范围0 - 9; 0表示关闭,9表示效果最明显。
+     * this.trtcCloud.setBeautyLevel(beautyLevel);
+     * this.trtcCloud.setBeautyStyle(TRTCBeautyStyle.TRTCBeautyStyleSmooth);
+     */
+    setBeautyStyle(beautyStyle) {
+        return TrtcCloudImpl._getInstance().setBeautyStyle(beautyStyle);
+    }
+    /**
+     * 设置美颜级别
+     * @param {Number} beautyLevel	美颜级别,取值范围0 - 9; 0表示关闭,9表示效果最明显。
+     *
+     * @memberof TrtcCloud
+     * @example
+     * const beautyLevel = 5; // 美颜级别,取值范围0 - 9; 0表示关闭,9表示效果最明显。
+     * this.trtcCloud.setBeautyLevel(beautyLevel);
+     */
+    setBeautyLevel(beautyLevel) {
+        return TrtcCloudImpl._getInstance().setBeautyLevel(beautyLevel);
+    }
+    /////////////////////////////////////////////////////////////////////////////////
+    //
+    //                      背景音效
+    //
+    /////////////////////////////////////////////////////////////////////////////////
+    /**
+     * 开始播放背景音乐
+     * 每个音乐都需要您指定具体的 ID,您可以通过该 ID 对音乐的开始、停止、音量等进行设置。<br>
+     * **Note:**
+     * - 如果要多次播放同一首背景音乐,请不要每次播放都分配一个新的 ID,我们推荐使用相同的 ID。
+     * - 若您希望同时播放多首不同的音乐,请为不同的音乐分配不同的 ID 进行播放。
+     * - 如果使用同一个 ID 播放不同音乐,SDK 会先停止播放旧的音乐,再播放新的音乐。
+     *
+     * **Note:**<br>
+     * 在 uni-app 中 path 如何获取。
+     * - 使用 cdn 地址,例如:`path = https://web.sdk.qcloud.com/component/TUIKit/assets/uni-app/calling-bell-1.mp3;`
+     * - 使用本地绝对路径。
+     *     1. 通过 [uni.saveFile](https://zh.uniapp.dcloud.io/api/file/file.html#savefile) 获取保存后的相对路径(建议这种路径)。
+     *     2. 将上一步的相对路径转成绝对路径,[plus.io.convertLocalFileSystemURL](https://www.html5plus.org/doc/zh_cn/io.html#plus.io.convertLocalFileSystemURL)。
+     *
+     * @param {AudioMusicParam} musicParam 音乐参数
+     * @param {Number} musicParam.id 音乐 ID
+     * @param {String} musicParam.path 音效文件的完整路径或 URL 地址。支持的音频格式包括 MP3、AAC、M4A、WAV
+     * @param {Number} musicParam.loopCount 音乐循环播放的次数。取值范围为0 - 任意正整数,默认值:0。0表示播放音乐一次;1表示播放音乐两次;以此类推
+     * @param {Boolean} musicParam.publish 是否将音乐传到远端。true:音乐在本地播放的同时,远端用户也能听到该音乐;false:主播只能在本地听到该音乐,远端观众听不到。默认值:false。
+     * @param {Boolean} musicParam.isShortFile 播放的是否为短音乐文件。true:需要重复播放的短音乐文件;false:正常的音乐文件。默认值:false
+     * @param {Number} musicParam.startTimeMS 音乐开始播放时间点,单位: 毫秒。
+     * @param {Number} musicParam.endTimeMS 音乐结束播放时间点,单位: 毫秒,0 表示播放至文件结尾。
+     * @memberof TrtcCloud
+     * @example
+     * import { AudioMusicParam } from '@/TrtcCloud/lib/TrtcDefines';
+     * const musicParam = {
+     *  id: 1,
+     *  path: '',
+     *  loopCount: 1,
+     *  publish: true,
+     *  isShortFile: false,
+     *  startTimeMS: 0,
+     *  endTimeMS: 0,
+     * };
+     * this.trtcCloud.startPlayMusic(musicParam);
+     */
+    startPlayMusic(musicParam) {
+        return TrtcCloudImpl._getInstance().startPlayMusic(musicParam);
+    }
+    /**
+     * 停止播放背景音乐
+     * @param {Number} id	音乐 ID
+     *
+     * @memberof TrtcCloud
+     * @example
+     * const musicId = 5;
+     * this.trtcCloud.stopPlayMusic(musicId);
+     */
+    stopPlayMusic(id) {
+        return TrtcCloudImpl._getInstance().stopPlayMusic(id);
+    }
+    /**
+     * 暂停播放背景音乐
+     * @param {Number} id	音乐 ID
+     * @memberof TrtcCloud
+     * @example
+     * const musicId = 5;
+     * this.trtcCloud.pausePlayMusic(musicId);
+     */
+    pausePlayMusic(id) {
+        return TrtcCloudImpl._getInstance().pausePlayMusic(id);
+    }
+    /**
+     * 恢复播放背景音乐
+     * @param {Number} id	音乐 ID
+     * @memberof TrtcCloud
+     * @example
+     * const musicId = 5;
+     * this.trtcCloud.resumePlayMusic(musicId);
+     */
+    resumePlayMusic(id) {
+        return TrtcCloudImpl._getInstance().resumePlayMusic(id);
+    }
+    /////////////////////////////////////////////////////////////////////////////////
+    //
+    //                       设置 TRTCCallback 回调
+    //
+    /////////////////////////////////////////////////////////////////////////////////
+    /**
+     * 设置 TrtcCloud 回调
+     *
+     * @example
+     * // 创建/使用/销毁 TrtcCloud 对象的示例代码:
+     * import TrtcCloud from '@/TrtcCloud/lib/index';
+     * this.trtcCloud = new TrtcCloud();
+     *
+     * // 添加事件监听的方法,事件关键字详见下方”通用事件回调“
+     * this.trtcCloud.on('onEnterRoom', (result) => {
+     *   if (result > 0) {
+     *     console.log(`enter room success, spend ${result}ms`);
+     *   } else {
+     *     console.log(`enter room failed, error code = ${result}`);
+     *   }
+     * });
+     *
+     * @namespace TRTCCallback
+     */
+    /////////////////////////////////////////////////////////////////////////////////
+    //
+    //                      (一)事件回调
+    //
+    /////////////////////////////////////////////////////////////////////////////////
+    /**
+     * 错误回调,表示 SDK 不可恢复的错误,一定要监听并分情况给用户适当的界面提示<br>
+     * @event TRTCCallback#onError
+     * @param {Number} code 错误码,[详见](https://cloud.tencent.com/document/product/647/38308#.E9.94.99.E8.AF.AF.E7.A0.81.E8.A1.A8)
+     * @param {String} message 错误信息
+     * @param {Object} extraInfo 扩展信息字段,个别错误码可能会带额外的信息帮助定位问题
+     */
+    onError(code, message, extraInfo) { }
+    /**
+     * 警告回调,用于告知您一些非严重性问题,例如出现卡顿或者可恢复的解码失败<br>
+     * @event TRTCCallback#onWarning
+     * @param {Number} code 警告码,[详见](https://cloud.tencent.com/document/product/647/38308#.E8.AD.A6.E5.91.8A.E7.A0.81.E8.A1.A8)
+     * @param {String} message 警告信息
+     * @param {Object} extraInfo 扩展信息字段,个别警告码可能会带额外的信息帮助定位问题
+     */
+    onWarning(code, message, extraInfo) { }
+    /**
+     * 进房后的回调<br>
+     * 调用 `enterRoom()` 接口执行进房操作后,会收到 `onEnterRoom(result)` 回调<br>
+     * 如果加入成功,result 会是一个正数(result > 0),代表加入房间的时间消耗,单位是毫秒(ms)。<br>
+     * 如果加入失败,result 会是一个负数(result < 0),代表进房失败的错误码。
+     *
+     * @event TRTCCallback#onEnterRoom
+     * @param {Number} result 进房耗时
+     */
+    onEnterRoom(result) { }
+    /**
+     * 离开房间的事件回调<br>
+     * 调用 `exitRoom()` 接口会执行退出房间的相关逻辑,例如释放音视频设备资源和编解码器资源等。待资源释放完毕,会通过 `onExitRoom()` 回调通知到您<br>
+     *
+     * **Note:**
+     * - 如果您要再次调用 `enterRoom()` 或者切换到其他的音视频 SDK,请等待 `onExitRoom()` 回调到来之后再执行相关操作。 否则可能会遇到音频设备被占用等各种异常问题
+     *
+     * @event TRTCCallback#onExitRoom
+     * @param {Number} reason 离开房间原因,0:主动调用 exitRoom 退房;1:被服务器踢出当前房间;2:当前房间整个被解散
+     */
+    onExitRoom(reason) { }
+    /**
+     * 跨房通话事件回调<br>
+     * 调用 TRTCCloud 中的 [connectOtherRoom()](https://web.sdk.qcloud.com/trtc/uniapp/doc/zh-cn/TrtcCloud.html#connectOtherRoom) 接口会将两个不同房间中的主播拉通视频通话,也就是所谓的“主播PK”功能。
+     * 调用者会收到 onConnectOtherRoom() 事件回调来获知跨房通话是否成功, 如果成功,两个房间中的所有用户都会收到来自另一个房间中的 PK 主播的 [onUserVideoAvailable()](http://127.0.0.1:5500/UniApp-TRTC-SDK/packages/TrtcCloud/docs/zh-cn/api/TRTCCallback.html#event:onUserVideoAvailable) 回调。
+     *
+     * @event TRTCCallback#onConnectOtherRoom
+     * @param {Object} params 调用 [connectOtherRoom()](https://web.sdk.qcloud.com/trtc/uniapp/doc/zh-cn/TrtcCloud.html#connectOtherRoom) 接口返回值数据。
+     * - userId:跨房通话时对端 userId
+     * - errCode: [错误状态码](https://cloud.tencent.com/document/product/647/38308#.E8.AD.A6.E5.91.8A.E7.A0.81.E8.A1.A8),返回0表示跨房通话成功。
+     * - errMsg: 状态信息,跨房通话成功返回 OK。
+     */
+    onConnectOtherRoom(params) { }
+    /**
+     * 结束跨房通话的结果回调<br>
+     * 调用 TRTCCloud 中的 [disconnectOtherRoom()](https://web.sdk.qcloud.com/trtc/uniapp/doc/zh-cn/TrtcCloud.html#disconnectOtherRoom) 接口会将两个不同房间中的主播拉通视频通话,也就是所谓的“主播PK”功能。
+     * 调用者会收到 onDisconnectOtherRoom() 事件回调来获知结束跨房通话是否成功。
+     *
+     * @event TRTCCallback#onDisconnectOtherRoom
+     * @param {Object} params 调用 [disconnectOtherRoom()](https://web.sdk.qcloud.com/trtc/uniapp/doc/zh-cn/TrtcCloud.html#disconnectOtherRoom) 失败时返回的错误数据。
+     * - errCode: [错误状态码](https://cloud.tencent.com/document/product/647/38308#.E8.AD.A6.E5.91.8A.E7.A0.81.E8.A1.A8)。
+     * - errMsg: 错误信息。
+     */
+    onDisconnectOtherRoom(params) { }
+    /**
+     * 切换角色的事件回调<br>
+     * 调用 TRTCCloud 中的 switchRole() 接口会切换主播和观众的角色,该操作会伴随一个线路切换的过程, 待 SDK 切换完成后,会抛出 onSwitchRole() 事件回调
+     *
+     * @event TRTCCallback#onSwitchRole
+     * @param {Number} code 错误码,[详见](https://cloud.tencent.com/document/product/647/38308#.E8.AD.A6.E5.91.8A.E7.A0.81.E8.A1.A8)
+     * @param {String} message 错误信息
+     */
+    onSwitchRole(code, message) { }
+    /**
+     * 开始渲染本地或远程用户的首帧画面<br>
+     * 如果 userId 为 null,代表开始渲染本地采集的摄像头画面,需要您先调用 `startLocalPreview` 触发。 如果 userId 不为 null,代表开始渲染远程用户的首帧画面,需要您先调用 `startRemoteView` 触发<br>
+     * 只有当您调用 `startLocalPreview()、startRemoteView() 或 startRemoteSubStreamView()` 之后,才会触发该回调
+     *
+     * @event TRTCCallback#onFirstVideoFrame
+     * @param {String} userId 本地或远程用户 ID,如果 userId === null 代表本地,userId !== null 代表远程
+     * @param {Number} streamType 视频流类型:摄像头或屏幕分享
+     * @param {Number} width 画面宽度
+     * @param {Number} height 画面高度
+     */
+    onFirstVideoFrame(userId, streamType, width, height) { }
+    /**
+     * 开始播放远程用户的首帧音频(本地声音暂不通知)<br>
+     * 如果 userId 为 null,代表开始渲染本地采集的摄像头画面,需要您先调用 `startLocalPreview` 触发。 如果 userId 不为 null,代表开始渲染远程用户的首帧画面,需要您先调用 `startRemoteView` 触发<br>
+     * 只有当您调用 `startLocalPreview()、startRemoteView() 或 startRemoteSubStreamView()` 之后,才会触发该回调
+     *
+     * @event TRTCCallback#onFirstAudioFrame
+     * @param {String} userId 远程用户 ID
+     */
+    onFirstAudioFrame(userId) { }
+    /**
+     * 截图完成时回调<br>
+     * @event TRTCCallback#onSnapshotComplete
+     * @param {String} base64Data 截图对应的 base64 数据
+     * @param {String} message 错误信息
+     */
+    onSnapshotComplete(base64Data, message) { }
+    /**
+     * 麦克风准备就绪
+     */
+    onMicDidReady() { }
+    /**
+     * 摄像头准备就绪
+     */
+    onCameraDidReady() { }
+    /**
+     * 网络质量:该回调每2秒触发一次,统计当前网络的上行和下行质量<br>
+     * userId 为本地用户 ID 代表自己当前的视频质量
+     *
+     * @param {String} localQuality 上行网络质量
+     * @param {String} remoteQuality 下行网络质量
+     */
+    onNetworkQuality(localQuality, remoteList) { }
+    /**
+     * 有用户加入当前房间<br>
+     * 出于性能方面的考虑,在两种不同的应用场景下,该通知的行为会有差别:<br>
+     * 通话场景(TRTCAppScene.TRTCAppSceneVideoCall 和 TRTCAppScene.TRTCAppSceneAudioCall):该场景下用户没有角色的区别,任何用户进入房间都会触发该通知。<br>
+     * 直播场景(TRTCAppScene.TRTCAppSceneLIVE 和 TRTCAppScene.TRTCAppSceneVoiceChatRoom ):该场景不限制观众的数量,如果任何用户进出都抛出回调会引起很大的性能损耗,所以该场景下只有主播进入房间时才会触发该通知,观众进入房间不会触发该通知
+     *
+     * @event TRTCCallback#onRemoteUserEnterRoom
+     * @param {String} userId 用户标识 ID
+     */
+    onRemoteUserEnterRoom(userId) { }
+    /**
+     * 有用户离开当前房间<br>
+     * 与 onRemoteUserEnterRoom 相对应,在两种不同的应用场景下,该通知的行为会有差别:<br>
+     * 通话场景(TRTCAppScene.TRTCAppSceneVideoCall 和 TRTCAppScene.TRTCAppSceneAudioCall):该场景下用户没有角色的区别,任何用户进入房间都会触发该通知。<br>
+     * 直播场景(TRTCAppScene.TRTCAppSceneLIVE 和 TRTCAppScene.TRTCAppSceneVoiceChatRoom ):该场景不限制观众的数量,如果任何用户进出都抛出回调会引起很大的性能损耗,所以该场景下只有主播进入房间时才会触发该通知,观众进入房间不会触发该通知
+     *
+     * @event TRTCCallback#onRemoteUserLeaveRoom
+     * @param {String} userId 用户标识 ID
+     * @param {Number} reason 离开原因,0 表示用户主动退出房间,1 表示用户超时退出,2 表示被踢出房间
+     */
+    onRemoteUserLeaveRoom(userId, reason) { }
+    /**
+     * 首帧本地音频数据已经被送出<br>
+     * 在 `enterRoom()` 并 `startLocalAudio()` 成功后开始麦克风采集,并将采集到的声音进行编码。 当 SDK 成功向云端送出第一帧音频数据后,会抛出这个回调事件
+     *
+     * @event TRTCCallback#onSendFirstLocalAudioFrame
+     */
+    onSendFirstLocalAudioFrame() { }
+    /**
+     * 首帧本地视频数据已经被送出<br>
+     * SDK 会在 `enterRoom()` 并 `startLocalPreview()` 成功后开始摄像头采集,并将采集到的画面进行编码。 当 SDK 成功向云端送出第一帧视频数据后,会抛出这个回调事件
+     *
+     * @event TRTCCallback#onSendFirstLocalVideoFrame
+     * @param {Number} streamType 视频流类型,大画面、小画面或辅流画面(屏幕分享)
+     */
+    onSendFirstLocalVideoFrame(streamType) { }
+    /**
+     * 技术指标统计回调<br>
+     * 如果您是熟悉音视频领域相关术语,可以通过这个回调获取 SDK 的所有技术指标。 如果您是首次开发音视频相关项目,可以只关注 `onNetworkQuality` 回调
+     *
+     * **Note:**
+     * - 每 2 秒回调一次
+     *
+     * @param {Object} statics 状态数据
+     */
+    onStatistics(statics) { }
+    /**
+     * 远端用户是否存在可播放的音频数据<br>
+     * @event TRTCCallback#onUserAudioAvailable
+     * @param {String} userId 用户标识 ID
+     * @param {Boolean} available 声音是否开启
+     */
+    onUserAudioAvailable(userId, available) { }
+    /**
+     * 远端用户是否存在可播放的主路画面(一般用于摄像头)<br>
+     * 当您收到 `onUserVideoAvailable(userId, true)` 通知时,表示该路画面已经有可用的视频数据帧到达。 此时,您需要调用 `startRemoteView(userId)` 接口加载该用户的远程画面。 然后,您会收到名为 onFirstVideoFrame(userid) 的首帧画面渲染回调。<br>
+     * 当您收到 `onUserVideoAvailable(userId, false)` 通知时,表示该路远程画面已经被关闭,可能由于该用户调用了 `muteLocalVideo()` 或 `stopLocalPreview()`。
+     *
+     * @event TRTCCallback#onUserVideoAvailable
+     * @param {String} userId 用户标识 ID
+     * @param {Boolean} available 画面是否开启
+     */
+    onUserVideoAvailable(userId, available) { }
+    /**
+     * 用于提示音量大小的回调,包括每个 userId 的音量和远端总音量<br>
+     * SDK 可以评估每一路音频的音量大小,并每隔一段时间抛出该事件回调,您可以根据音量大小在 UI 上做出相应的提示,比如“波形图”或“音量槽”。 要完成这个功能, 您需要先调用 enableAudioVolumeEvaluation 开启这个能力并设定事件抛出的时间间隔。 需要补充说明的是,无论当前房间中是否有人说话,SDK 都会按照您设定的时间间隔定时抛出此事件回调,只不过当没有人说话时,userVolumes 为空,totalVolume 为 0。
+     *
+     * **Note:**
+     * - userVolumes 为一个数组,对于数组中的每一个元素,当 userId 为空时表示本地麦克风采集的音量大小,当 userId 不为空时代表远端用户的音量大小
+     *
+     * @event TRTCCallback#onUserVoiceVolume
+     * @param {Array} userVolumes 是一个数组,用于承载所有正在说话的用户的音量大小,取值范围 0 - 100
+     * @param {Number} totalVolume 所有远端用户的总音量大小, 取值范围 0 - 100
+     */
+    onUserVoiceVolume(userVolumes, totalVolume) { }
+    /**
+     * 屏幕分享开启的事件回调<br>
+     * 当您通过 startScreenCapture 等相关接口启动屏幕分享时,SDK 便会抛出此事件回调
+     * @event TRTCCallback#onScreenCaptureStarted
+     */
+    onScreenCaptureStarted() { }
+    /**
+     * 屏幕分享停止的事件回调<br>
+     * 当您通过 stopScreenCapture 停止屏幕分享时,SDK 便会抛出此事件回调
+     * @event TRTCCallback#onScreenCaptureStopped
+     * @param {Number} reason 停止原因,0:用户主动停止;1:屏幕窗口关闭导致停止;2:表示屏幕分享的显示屏状态变更(如接口被拔出、投影模式变更等)
+     */
+    onScreenCaptureStopped(reason) { }
+    /**
+     * 屏幕分享停止的事件回调<br>
+     * 当您通过 pauseScreenCapture 停止屏幕分享时,SDK 便会抛出此事件回调
+     * @event TRTCCallback#onScreenCapturePaused
+     * @param {Number} reason 停止原因,0:用户主动停止;1:屏幕窗口关闭导致停止;2:表示屏幕分享的显示屏状态变更(如接口被拔出、投影模式变更等)
+     */
+    onScreenCapturePaused(reason) { }
+    /**
+     * 屏幕分享恢复的事件回调<br>
+     * 当您通过 resumeScreenCapture 恢复屏幕分享时,SDK 便会抛出此事件回调
+     * @event TRTCCallback#onScreenCaptureResumed
+     */
+    onScreenCaptureResumed() { }
+    /**
+     * 某远端用户发布/取消了辅路视频画面<br>
+     * “辅路画面”一般被用于承载屏幕分享的画面。当您收到 onUserSubStreamAvailable(userId, true) 通知时,表示该路画面已经有可播放的视频帧到达。 此时,您需要调用 startRemoteView 接口订阅该用户的远程画面,订阅成功后,您会继续收到该用户的首帧画面渲染回调 onFirstVideoFrame(userId)
+     *
+     * **Note:**
+     * - 拉取 Web 端(用 [WebRTC](https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/index.html) 实现屏幕分享)的屏幕分享,收不到 onUserSubStreamAvailable 事件。因为 [WebRTC](https://web.sdk.qcloud.com/trtc/webrtc/doc/zh-cn/index.html) 推的屏幕分享也是主流
+     * @param {String} userId 用户 ID
+     * @param {Boolean} available 是否可用,true 表示辅流可用
+     * @event TRTCCallback#onUserSubStreamAvailable
+     */
+    onUserSubStreamAvailable(userId, available) { }
+    /**
+     * 用户视频大小发生改变回调。<br>
+     * 当您收到 onUserVideoSizeChanged(userId, streamtype, newWidth, newHeight) 通知时,表示该路画面大小发生了调整,调整的原因可能是该用户调用了 setVideoEncoderParam 或者 setSubStreamEncoderParam 重新设置了画面尺寸。
+     * @param {String} userId 用户 ID
+     * @param {Number} streamType 视频流类型,仅支持 TRTCVideoStreamTypeBig 和 TRTCVideoStreamTypeSub
+     * @param {Number} newWidth 视频流的宽度(像素)
+     * @param {Number} newHeight 视频流的高度(像素)
+     * @event TRTCCallback#onUserVideoSizeChanged
+     */
+    onUserVideoSizeChanged(userId, streamType, newWidth, newHeight) { }
+    /**
+     * 背景音乐开始播放
+     * @param {Number} id 播放的 id
+     * @param {Number} errCode 播放的状态码
+     * @event TRTCCallback#onStart
+     */
+    onStart(id, errCode) { }
+    /**
+     * 背景音乐的播放进度
+     * @param {Number} id 播放的 id
+     * @param {Number} curPtsMS 当前播放的位置
+     * @param {Number} durationMS 当前音频总时长
+     * @event TRTCCallback#onPlayProgress
+     */
+    onPlayProgress(id, curPtsMS, durationMS) { }
+    /**
+     * 背景音乐已经播放完毕
+     * @param {Number} id 播放的 id
+     * @param {Number} errCode 播放结束的状态码
+     * @event TRTCCallback#onComplete
+     */
+    onComplete(id, errCode) { }
+}

+ 279 - 0
TrtcCloud/permission.js

@@ -0,0 +1,279 @@
+/**
+ * 本模块封装了Android、iOS的应用权限判断、打开应用权限设置界面、以及位置系统服务是否开启
+ */
+ var isIos
+ // #ifdef APP-PLUS
+ isIos = (plus.os.name == "iOS");
+ // #endif
+ 
+ // 判断推送权限是否开启
+ function judgeIosPermissionPush() {
+   var result = false;
+   var UIApplication = plus.ios.import("UIApplication");
+   var app = UIApplication.sharedApplication();
+   var enabledTypes = 0;
+   if (app.currentUserNotificationSettings) {
+     var settings = app.currentUserNotificationSettings();
+     enabledTypes = settings.plusGetAttribute("types");
+     console.log("enabledTypes1:" + enabledTypes);
+     if (enabledTypes == 0) {
+       console.log("推送权限没有开启");
+     } else {
+       result = true;
+       console.log("已经开启推送功能!")
+     }
+     plus.ios.deleteObject(settings);
+   } else {
+     enabledTypes = app.enabledRemoteNotificationTypes();
+     if (enabledTypes == 0) {
+       console.log("推送权限没有开启!");
+     } else {
+       result = true;
+       console.log("已经开启推送功能!")
+     }
+     console.log("enabledTypes2:" + enabledTypes);
+   }
+   plus.ios.deleteObject(app);
+   plus.ios.deleteObject(UIApplication);
+   return result;
+ }
+ 
+ // 判断定位权限是否开启
+ function judgeIosPermissionLocation() {
+   var result = false;
+   var cllocationManger = plus.ios.import("CLLocationManager");
+   var status = cllocationManger.authorizationStatus();
+   result = (status != 2)
+   console.log("定位权限开启:" + result);
+   // 以下代码判断了手机设备的定位是否关闭,推荐另行使用方法 checkSystemEnableLocation
+   /* var enable = cllocationManger.locationServicesEnabled();
+   var status = cllocationManger.authorizationStatus();
+   console.log("enable:" + enable);
+   console.log("status:" + status);
+   if (enable && status != 2) {
+     result = true;
+     console.log("手机定位服务已开启且已授予定位权限");
+   } else {
+     console.log("手机系统的定位没有打开或未给予定位权限");
+   } */
+   plus.ios.deleteObject(cllocationManger);
+   return result;
+ }
+ // 判断麦克风权限是否开启
+ function judgeIosPermissionRecord() {
+   var result = false;
+   var avaudiosession = plus.ios.import("AVAudioSession");
+   var avaudio = avaudiosession.sharedInstance();
+   var permissionStatus = avaudio.recordPermission();
+   console.log("permissionStatus:" + permissionStatus);
+   if (permissionStatus == 1684369017 || permissionStatus == 1970168948) {
+     console.log("麦克风权限没有开启");
+   } else {
+     result = true;
+     console.log("麦克风权限已经开启");
+   }
+   plus.ios.deleteObject(avaudiosession);
+   return result;
+ }
+ 
+ // 判断相机权限是否开启
+ function judgeIosPermissionCamera() {
+   var result = false;
+   var AVCaptureDevice = plus.ios.import("AVCaptureDevice");
+   var authStatus = AVCaptureDevice.authorizationStatusForMediaType('vide');
+   console.log("authStatus:" + authStatus);
+   if (authStatus == 3) {
+     result = true;
+     console.log("相机权限已经开启");
+   } else {
+     console.log("相机权限没有开启");
+   }
+   plus.ios.deleteObject(AVCaptureDevice);
+   return result;
+ }
+ 
+ // 判断相册权限是否开启
+ function judgeIosPermissionPhotoLibrary() {
+   var result = false;
+   var PHPhotoLibrary = plus.ios.import("PHPhotoLibrary");
+   var authStatus = PHPhotoLibrary.authorizationStatus();
+   console.log("authStatus:" + authStatus);
+   if (authStatus == 3) {
+     result = true;
+     console.log("相册权限已经开启");
+   } else {
+     console.log("相册权限没有开启");
+   }
+   plus.ios.deleteObject(PHPhotoLibrary);
+   return result;
+ }
+ 
+ // 判断通讯录权限是否开启
+ function judgeIosPermissionContact() {
+   var result = false;
+   var CNContactStore = plus.ios.import("CNContactStore");
+   var cnAuthStatus = CNContactStore.authorizationStatusForEntityType(0);
+   if (cnAuthStatus == 3) {
+     result = true;
+     console.log("通讯录权限已经开启");
+   } else {
+     console.log("通讯录权限没有开启");
+   }
+   plus.ios.deleteObject(CNContactStore);
+   return result;
+ }
+ 
+ // 判断日历权限是否开启
+ function judgeIosPermissionCalendar() {
+   var result = false;
+   var EKEventStore = plus.ios.import("EKEventStore");
+   var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(0);
+   if (ekAuthStatus == 3) {
+     result = true;
+     console.log("日历权限已经开启");
+   } else {
+     console.log("日历权限没有开启");
+   }
+   plus.ios.deleteObject(EKEventStore);
+   return result;
+ }
+ 
+ // 判断备忘录权限是否开启
+ function judgeIosPermissionMemo() {
+   var result = false;
+   var EKEventStore = plus.ios.import("EKEventStore");
+   var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(1);
+   if (ekAuthStatus == 3) {
+     result = true;
+     console.log("备忘录权限已经开启");
+   } else {
+     console.log("备忘录权限没有开启");
+   }
+   plus.ios.deleteObject(EKEventStore);
+   return result;
+ }
+ 
+ // Android权限查询
+ function requestAndroidPermission(permissionID) {
+   return new Promise((resolve, reject) => {
+     plus.android.requestPermissions(
+       [permissionID], // 理论上支持多个权限同时查询,但实际上本函数封装只处理了一个权限的情况。有需要的可自行扩展封装
+       function(resultObj) {
+         var result = 0;
+         for (var i = 0; i < resultObj.granted.length; i++) {
+           var grantedPermission = resultObj.granted[i];
+           console.log('已获取的权限:' + grantedPermission);
+           result = 1
+         }
+         for (var i = 0; i < resultObj.deniedPresent.length; i++) {
+           var deniedPresentPermission = resultObj.deniedPresent[i];
+           console.log('拒绝本次申请的权限:' + deniedPresentPermission);
+           result = 0
+         }
+         for (var i = 0; i < resultObj.deniedAlways.length; i++) {
+           var deniedAlwaysPermission = resultObj.deniedAlways[i];
+           console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
+           result = -1
+         }
+         resolve(result);
+         // 若所需权限被拒绝,则打开APP设置界面,可以在APP设置界面打开相应权限
+         // if (result != 1) {
+         // gotoAppPermissionSetting()
+         // }
+       },
+       function(error) {
+         console.log('申请权限错误:' + error.code + " = " + error.message);
+         resolve({
+           code: error.code,
+           message: error.message
+         });
+       }
+     );
+   });
+ }
+ 
+ // 使用一个方法,根据参数判断权限
+ function judgeIosPermission(permissionID) {
+   if (permissionID == "location") {
+     return judgeIosPermissionLocation()
+   } else if (permissionID == "camera") {
+     return judgeIosPermissionCamera()
+   } else if (permissionID == "photoLibrary") {
+     return judgeIosPermissionPhotoLibrary()
+   } else if (permissionID == "record") {
+     return judgeIosPermissionRecord()
+   } else if (permissionID == "push") {
+     return judgeIosPermissionPush()
+   } else if (permissionID == "contact") {
+     return judgeIosPermissionContact()
+   } else if (permissionID == "calendar") {
+     return judgeIosPermissionCalendar()
+   } else if (permissionID == "memo") {
+     return judgeIosPermissionMemo()
+   }
+   return false;
+ }
+ 
+ // 跳转到**应用**的权限页面
+ function gotoAppPermissionSetting() {
+   if (isIos) {
+     var UIApplication = plus.ios.import("UIApplication");
+     var application2 = UIApplication.sharedApplication();
+     var NSURL2 = plus.ios.import("NSURL");
+     // var setting2 = NSURL2.URLWithString("prefs:root=LOCATION_SERVICES");		
+     var setting2 = NSURL2.URLWithString("app-settings:");
+     application2.openURL(setting2);
+ 
+     plus.ios.deleteObject(setting2);
+     plus.ios.deleteObject(NSURL2);
+     plus.ios.deleteObject(application2);
+   } else {
+     // console.log(plus.device.vendor);
+     var Intent = plus.android.importClass("android.content.Intent");
+     var Settings = plus.android.importClass("android.provider.Settings");
+     var Uri = plus.android.importClass("android.net.Uri");
+     var mainActivity = plus.android.runtimeMainActivity();
+     var intent = new Intent();
+     intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+     var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
+     intent.setData(uri);
+     mainActivity.startActivity(intent);
+   }
+ }
+ 
+ // 检查系统的设备服务是否开启
+ // var checkSystemEnableLocation = async function () {
+ function checkSystemEnableLocation() {
+   if (isIos) {
+     var result = false;
+     var cllocationManger = plus.ios.import("CLLocationManager");
+     var result = cllocationManger.locationServicesEnabled();
+     console.log("系统定位开启:" + result);
+     plus.ios.deleteObject(cllocationManger);
+     return result;
+   } else {
+     var context = plus.android.importClass("android.content.Context");
+     var locationManager = plus.android.importClass("android.location.LocationManager");
+     var main = plus.android.runtimeMainActivity();
+     var mainSvr = main.getSystemService(context.LOCATION_SERVICE);
+     var result = mainSvr.isProviderEnabled(locationManager.GPS_PROVIDER);
+     console.log("系统定位开启:" + result);
+     return result
+   }
+ }
+ 
+//  module.exports = {
+//    judgeIosPermission: judgeIosPermission,
+//    requestAndroidPermission: requestAndroidPermission,
+//    checkSystemEnableLocation: checkSystemEnableLocation,
+//    gotoAppPermissionSetting: gotoAppPermissionSetting
+//  }
+
+// HBuilder 选择 vue3 时, 上面的打包无法通过 import 进行引入
+export default {
+  judgeIosPermission: judgeIosPermission,
+  requestAndroidPermission: requestAndroidPermission,
+  checkSystemEnableLocation: checkSystemEnableLocation,
+  gotoAppPermissionSetting: gotoAppPermissionSetting
+};
+ 

+ 19 - 0
TrtcCloud/view/TrtcLocalView.nvue

@@ -0,0 +1,19 @@
+<template>
+	<TRTCCloudUniPlugin-TXLocalViewComponent :viewId="viewId"></TRTCCloudUniPlugin-TXLocalViewComponent>
+</template>
+
+<script>
+	export default {
+		name: 'TrtcLocalView',
+		props: {
+			viewId: {
+				type: String,
+				default: ''
+			}
+		},
+	}
+</script>
+
+<style>
+
+</style>

+ 23 - 0
TrtcCloud/view/TrtcRemoteView.nvue

@@ -0,0 +1,23 @@
+<template>
+	<TRTCCloudUniPlugin-TXRemoteViewComponent :userId="userId" :viewId="viewId"></TRTCCloudUniPlugin-TXRemoteViewComponent>
+</template>
+
+<script>
+	export default {
+		name: 'TrtcRemoteView',
+		props: {
+			userId: {
+				type: String,
+				default: ''
+			},
+			viewId: {
+				type: String,
+				default: ''
+			}
+		},
+	}
+</script>
+
+<style>
+
+</style>

+ 8 - 0
changelog.md

@@ -0,0 +1,8 @@
+## 1.0.2(2022-06-30)
+- 新增 支持 ios 安全区
+## 1.0.1(2021-11-26)
+- 新增 schema 国际化 (HBuilderX 3.3+)
+- 修复 非 Android 平台切换语音无法实时变化的问题
+- 修复 设置某些语言下无法生效的问题 (HBuilderX 3.3+)
+## 1.0.0(2021-10-20)
+- 初始化

+ 63 - 0
common/common.scss

@@ -0,0 +1,63 @@
+.content{
+	display: flex;
+	flex-direction: column;
+	width: 94%;
+	margin-left: 3%;
+	background-color: white;
+	border-radius: 16rpx;
+	box-shadow: 0rpx 0rpx 10rpx 0rpx lightgray;
+}
+.contentInRowL{
+	display: flex;
+	flex-direction: row;
+	justify-content: flex-start;
+}
+
+.contentInRowR{
+	display: flex;
+	flex-direction: row;
+	justify-content:flex-end;
+}
+
+.contentInRowC{
+	display: flex;
+	flex-direction: row;
+	justify-content: center;
+	align-items: center;
+}
+
+.contentInRowS{
+	display: flex;
+	flex-direction: row;
+	align-items: center;
+	justify-content: space-between;
+}
+
+.contentColumn{
+	display: flex;
+	flex-direction: column;
+}
+
+.contentColumnC{
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+}
+
+.text1row{
+	overflow: hidden;
+	text-overflow: ellipsis;
+	display: -webkit-box;
+	-webkit-line-clamp: 1;
+	-webkit-box-orient: vertical;
+}
+.text2row{
+	overflow: hidden;
+	text-overflow: ellipsis;
+	display: -webkit-box;
+	-webkit-line-clamp: 2;
+	-webkit-box-orient: vertical;
+}
+
+

+ 30 - 0
common/jsencrypt.js

@@ -0,0 +1,30 @@
+import JSEncrypt from 'jsencrypt/bin/jsencrypt.min'
+
+// 密钥对生成 http://web.chacuo.net/netrsakeypair
+
+const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' +
+  'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='
+
+const privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' +
+  '7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' +
+  'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' +
+  'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' +
+  'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' +
+  'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' +
+  'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' +
+  'UP8iWi1Qw0Y='
+
+// 加密
+export function encrypt(txt) {
+  const encryptor = new JSEncrypt()
+  encryptor.setPublicKey(publicKey) // 设置公钥
+  return encryptor.encrypt(txt) // 对数据进行加密
+}
+
+// 解密
+export function decrypt(txt) {
+  const encryptor = new JSEncrypt()
+  encryptor.setPrivateKey(privateKey) // 设置私钥
+  return encryptor.decrypt(txt) // 对数据进行解密
+}
+

+ 119 - 0
common/zhifuye.html

@@ -0,0 +1,119 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="utf-8" />
+		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
+		<title>网络网页</title>
+		<style type="text/css">
+			.btn {
+				display: block;
+				margin: 20px auto;
+				padding: 5px;
+				background-color: #007aff;
+				border: 0;
+				color: #ffffff;
+				height: 40px;
+				width: 200px;
+			}
+
+			.btn-red {
+				background-color: #dd524d;
+			}
+
+			.btn-yellow {
+				background-color: #f0ad4e;
+			}
+
+			.desc {
+				padding: 10px;
+				color: #999999;
+			}
+
+			.post-message-section {
+				visibility: hidden;
+			}
+		</style>
+	</head>
+	<body>
+		<p class="desc">web-view 组件加载网络 html 示例。点击下列按钮,跳转至其它页面。</p>
+		<div class="btn-list">
+			<button class="btn" type="button" data-action="navigateTo">navigateTo</button>
+			<button class="btn" type="button" data-action="redirectTo">redirectTo</button>
+			<button class="btn" type="button" data-action="navigateBack">navigateBack</button>
+			<button class="btn" type="button" data-action="reLaunch">reLaunch</button>
+			<button class="btn" type="button" data-action="switchTab">switchTab</button>
+		</div>
+		<div class="post-message-section">
+			<p class="desc">网页向应用发送消息,注意:小程序端应用会在此页面后退时接收到消息。</p>
+			<div class="btn-list">
+				<button class="btn btn-red" type="button" id="postMessage">postMessage</button>
+			</div>
+		</div>
+		<script type="text/javascript">
+			var userAgent = navigator.userAgent;
+			if (userAgent.indexOf('AlipayClient') > -1) {
+				// 支付宝小程序的 JS-SDK 防止 404 需要动态加载,如果不需要兼容支付宝小程序,则无需引用此 JS 文件。
+				document.writeln('<script src="https://appx/web-view.min.js"' + '>' + '<' + '/' + 'script>');
+			} else if (/QQ/i.test(userAgent) && /miniProgram/i.test(userAgent)) {
+				// QQ 小程序
+				document.write('<script type="text/javascript" src="https://qqq.gtimg.cn/miniprogram/webview_jssdk/qqjssdk-1.0.0.js"><\/script>');
+			} else if (/miniProgram/i.test(userAgent) && /micromessenger/i.test(userAgent)) {
+				// 微信小程序 JS-SDK 如果不需要兼容微信小程序,则无需引用此 JS 文件。
+				document.write('<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"><\/script>');
+			} else if (/toutiaomicroapp/i.test(userAgent)) {
+				// 头条小程序 JS-SDK 如果不需要兼容头条小程序,则无需引用此 JS 文件。
+				document.write('<script type="text/javascript" src="https://s3.pstatp.com/toutiao/tmajssdk/jssdk-1.0.1.js"><\/script>');
+			} else if (/swan/i.test(userAgent)) {
+				// 百度小程序 JS-SDK 如果不需要兼容百度小程序,则无需引用此 JS 文件。
+				document.write('<script type="text/javascript" src="https://b.bdstatic.com/searchbox/icms/searchbox/js/swan-2.0.18.js"><\/script>');
+			} else if (/quickapp/i.test(userAgent)) {
+				// quickapp
+				document.write('<script type="text/javascript" src="https://quickapp/jssdk.webview.min.js"><\/script>');
+			}
+			if (!/toutiaomicroapp/i.test(userAgent)) {
+				document.querySelector('.post-message-section').style.visibility = 'visible';
+			}
+		</script>
+		<!-- uni 的 SDK -->
+		<script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.1/index.js"></script>
+		<script type="text/javascript">
+			document.addEventListener('UniAppJSBridgeReady', function() {
+				document.querySelector('.btn-list').addEventListener('click', function(evt) {
+					var target = evt.target;
+					if (target.tagName === 'BUTTON') {
+						var action = target.getAttribute('data-action');
+						switch (action) {
+							case 'switchTab':
+								uni.switchTab({
+									url: '/pages/tabBar/API/API'
+								});
+								break;
+							case 'reLaunch':
+								uni.reLaunch({
+									url: '/pages/tabBar/component/component'
+								});
+								break;
+							case 'navigateBack':
+								uni.navigateBack({
+									delta: 1
+								});
+								break;
+							default:
+								uni[action]({
+									url: '/pages/component/button/button'
+								});
+								break;
+						}
+					}
+				});
+				document.getElementById('postMessage').addEventListener('click', function() {
+					uni.postMessage({
+						data: {
+							action: 'message'
+						}
+					});
+				});
+			});
+		</script>
+	</body>
+</html>

+ 177 - 0
components/customNav/customNav.vue

@@ -0,0 +1,177 @@
+<template>
+	<view class="">
+		<!-- 自定义导航栏 -->
+			<view class="contentView" :style="{'backgroundColor':tinColor}">
+			<!-- 状态栏占位 -->
+			<view class="navBarBox" :style="{'marginTop':+statusBarHeight+'rpx','backgroundColor':tinColor}">
+				<!-- 直正的导航栏内容 -->
+				<view v-if="shownav" class="navBar" >
+					<view v-if="jiantou==0" class="leftconten">
+						<image class="logo" :src="fanhuisrc" mode="aspectFit" @click="leftbuttonsel(1)"></image>
+						<view v-if="titledetl==''" class="textlableR">
+							<view class="lableTR">{{title}}</view>
+						</view>
+						<view v-if="titledetl!=''" class="textlable">
+							<text class="lableT">{{title}}</text>
+							<text  class="lableB">{{titledetl}}</text>
+						</view>
+					</view>
+					<view v-if="jiantou==1" class="leftconten">
+						<image class="logo" :src="fanhuisrcb" mode="aspectFit" @click="leftbuttonsel(1)"></image>
+						<view v-if="titledetl==''" class="textlableR">
+							<view class="lableTRb">{{title}}</view>
+						</view>
+						<view v-if="titledetl!=''" class="textlable">
+							<view class="lableTb">{{title}}</view>
+							<view  class="lableB">{{titledetl}}</view>
+						</view>
+					</view>
+					<view class="rightconten">
+						<image  v-if="rightBT1==1" class="mycart" :src="rightBTimg1" mode="scaleToFill" @click="leftbuttonsel(2)"></image>
+						<image  v-if="rightBT2==1" class="mycart" :src="rightBTimg2" mode="scaleToFill" @click="leftbuttonsel(3)"></image>
+						<!-- <image  v-if="addBT==1" class="mycart" src="/static/images/plus-circle-fill@3x.png" mode="aspectFit" @click="leftbuttonsel(4)"></image> -->
+						<text v-if="xinzeng==1" class="xinzengTxt" @click="leftbuttonsel(5)">{{$t('schema.add')}}</text>
+						<uni-icons v-if="addBT==1"  custom-prefix="custom-icon" color="white" type="plus" size="26"  @click="leftbuttonsel(4)"></uni-icons>
+					</view>
+				</view>
+			</view>
+		</view>
+		<view v-if="shownav" :style="{height:navBarHeight+'rpx'}">
+		</view>
+		<view v-if="!shownav" :style="{height:statusBarHeight+'rpx'}">
+		</view>
+	</view>
+		
+</template>
+
+<script>
+
+export default
+{
+	props:{
+		shownav:true,
+		tinColor:'',
+		title:'',
+		titledetl:'',
+		rightBT1:'',
+		rightBTimg1:'',
+		rightBT2:0,
+		rightBTimg2:'',
+		isfaver:0,
+		addBT:0,
+		jiantou:0,
+		xinzeng:0
+	},
+	data() {
+		return{ 
+			// 状态栏高度
+			statusBarHeight:0,
+			// 导航栏高度
+			navBarHeight: 50,
+			fanhuisrc:'/static/imags/fanhuiz@3x.png',
+			fanhuisrcb:'/static/imags/fanhuiB@3x.png',
+			
+			}
+	},
+		//第一次加载时调用
+	created() {
+			//获取手机状态栏高度
+			var systemInfo = uni.getSystemInfoSync();
+			this.statusBarHeight=systemInfo.statusBarHeight*2+30;
+			this.navBarHeight = 50+this.statusBarHeight;
+	},
+	methods:{
+		leftbuttonsel(item){
+			//触发一个更新事件
+			if(item==1){
+				uni.navigateBack();
+			}
+			this.$emit('Enavbarsel',item);
+		}
+		
+	},
+}
+
+</script>
+
+<style>
+	.contentView{
+		position: fixed;
+		left: 0;
+		right: 0;
+		top: 0;
+		z-index: 999;
+		background-color: #006AFF;
+	}
+	.navBarBox{
+		display: flex;
+		width: 700rpx;
+		background-color: #006AFF;
+	}
+	
+	.navBar {
+		display: flex;
+		width: 700rpx;
+		margin-left: 5%;
+		padding-bottom: 10rpx;
+		display: flex;
+		flex-direction: row;
+		justify-content: space-between;
+		align-items: center;
+	}
+	.logo {
+		width: 50rpx;
+		height: 50rpx;
+		margin-left: 6rpx;
+	}
+	.textlable{
+		flex-direction:column;
+		margin-left: 20rpx;
+	}
+	.textlableR{
+		flex-direction:column;
+		margin-left: 20rpx;
+	}
+	.lableTR{
+		font-size: 32rpx;
+		color: white;
+	}
+	.lableTRb{
+		font-size: 30rpx;
+		color: #1A1A1A;
+	}
+	.lableT{
+		font-size: 30rpx;
+		color: white;
+	}
+	.lableTb{
+		font-size: 30rpx;
+		color: #1A1A1A;
+		text-align: left;
+	}
+	.lableB{
+		font-size: 22rpx;
+		color: white;
+	}
+	.leftconten{
+		display: flex;
+		flex-direction: row;
+		justify-content:flex-start;
+	}
+	.rightconten{
+		display: flex;
+		flex-direction: row;
+		justify-content:flex-end;
+	}
+
+	.mycart {
+		margin-right: 10rpx;
+		width: 50rpx;
+		height: 46rpx;
+	}
+	.xinzengTxt{
+		margin-right: 10rpx;
+		color: white;
+		font-size: 28rpx;
+	}
+</style>

+ 78 - 0
components/mapView/mapView.vue

@@ -0,0 +1,78 @@
+<template>
+	<view>
+		<view class="">
+			<view class="">
+				 <map id="map" class="mapbody" :style="'height:'+mapHeight+'rpx;'" :latitude="latitude" :longitude="longitude" :covers="covers" @regionchange="regionChange">
+				</map>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name:"mapView",
+		data() {
+			return {
+				covers: [{
+					latitude: 39.909,
+					longitude: 116.39742,
+					iconPath: '/static/images/dizhil@3x.png'
+				}],
+				controls:[],
+				latitude: 39.909,
+				longitude: 116.39742,
+				mapHeight:0,
+				mapready:false
+			};
+		},
+		created() {
+			var info = uni.getSystemInfoSync();
+			console.log(info);
+			this.mapHeight=info.windowHeight;
+			this.listHight=info.windowHeight;
+			this.left = 750/4;
+			this.top = this.mapHeight/6;
+			this.mapContext = uni.createMapContext("map",this); 
+		},
+		onReady() {
+		},
+		methods: {
+			regionChange(){
+				var that = this;
+				if(!this.mapready){
+					return;
+				}
+				this.controls=[{//在地图上显示控件,控件不随着地图移动
+					id:1,//控件id
+					iconPath:'/static/imags/datouzhenl.png',//显示的图标    
+					position:{//控件在地图的位置
+					    left:this.left-6,
+					    top:this.top-10,
+					    width:28,
+					    height:35
+					},    
+				}];
+				this.mapContext.getCenterLocation({
+					success: res => {
+						console.log('getCenterLocation');
+					},
+					fail: res => {
+						uni.showModal({
+							content: that.$t('api.dingweishibai'),
+							showCancel: false
+						})
+					}
+				})
+			},
+		},
+	}
+</script>
+
+<style>
+	
+	.mapbody{
+		width: 100%;
+	}
+
+</style>

+ 59 - 0
components/myImage/myImage.vue

@@ -0,0 +1,59 @@
+<template>
+	<view>
+		<image v-if="isIcon" style="border-radius: 55rpx;" :class="[mymode=='widthFix'?'imageW':'imagev']"  :src="showdefault==1?dfImage:baseUrl+comUrl" mode="scaleToFill" @error="imageError" @click="myimageclick"></image>
+		<image v-if="!isIcon" :class="[mymode=='widthFix'?'imageW':'imagev']"  :src="showdefault==1?dfImage:baseUrl+comUrl" :mode="mymode" @error="imageError" @click="myimageclick"></image>
+	</view>
+</template>
+
+<script>
+	export default {
+		name:"myImage",
+		props:{
+			mysrc: '',
+			mymode:'',
+			isIcon:false,
+			defaultImage:''
+		},
+		data() {
+			return {
+				baseUrl:'https://backend.cityexpress168.com.vn/prod-api',
+				showdefault:0,
+				comUrl:this.mysrc,
+				dfImage:this.defaultImage
+			};
+		},
+		watch: {
+			mysrc(val){
+				this.showdefault=0;
+				this.comUrl = this.mysrc
+				// console.log(this.baseUrl+this.comUrl);
+			}
+		},
+		methods:{
+			imageError(){
+				if(this.dfImage==''||undefined==this.dfImage){
+					this.dfImage='/static/logo.png';
+				}
+				this.showdefault=1;
+			},
+			myimageclick(comUrl){
+				this.$emit('Emyimageclick',comUrl);
+			},
+		},
+	}
+</script>
+
+<style>
+	.imageW{
+		margin: 0rpx;
+		width:100%;
+	}
+	.imageH{
+		margin: 0rpx;
+		height:100%;
+	}
+	.imagev{
+		width:100%;
+		height:100%;
+	}
+</style>

+ 81 - 0
components/myorderItem/myorderItem.vue

@@ -0,0 +1,81 @@
+<template>
+	<view >
+		<view class="itemContent" v-for="(item,index) in orderObj">
+			<view style="width: 100%;height: 4rpx;background-color:lightgray;"></view>
+			<view class="contentInRowL" style="padding-top: 30rpx;align-items: center;">
+				<text class="dateText">{{item.date}}</text>
+				<text class="datedsText">{{item.dateds}}</text>
+			</view>
+			<view class="contentInRowS">
+				<view class="contentColumn" style="justify-content: center;padding-top: 10rpx;align-items: center;">
+					<text class="stateText">{{$t('order.wanchengdingd')}}</text>
+					<view class="contentInRowL" style="align-items: baseline;">
+						<text class="shuliangText">25</text>
+						<text class="danweiText">{{$t('order.danweidan')}}</text>
+					</view>
+				</view>
+				<view class="contentColumn" style="justify-content: center;padding-top: 10rpx;align-items: center;">
+					<text class="stateText">{{$t('order.quxiaodingdan')}}</text>
+					<view class="contentInRowL" style="align-items: baseline;">
+						<text class="shuliangText">1</text>
+						<text class="danweiText">{{$t('order.danweidan')}}</text>
+					</view>
+				</view>
+				<view class="contentColumn" style="justify-content: center;padding-top: 10rpx;align-items: center;">
+					<text class="stateText">{{$t('order.peisonglc')}}</text>
+					<view class="contentInRowL" style="align-items: baseline;">
+						<text class="shuliangText">304.5</text>
+						<text class="danweiText">Km</text>
+					</view>
+				</view>
+			</view>
+		</view>
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		name:"myorderItem",
+		props:{
+			orderObj:''
+		},
+		data() {
+			return {
+				
+			};
+		}
+	}
+</script>
+
+<style lang="scss">
+	@import '@/common/common.scss';
+	
+	.itemContent{
+		width: 94%;
+		margin-left: 3%;
+		padding-bottom: 30rpx;
+	}
+	
+	.dateText{
+		font-size: 28rpx;
+		font-weight: bold;
+	}
+	.datedsText{
+		font-size: 24rpx;
+		color: darkgray;
+		padding-left: 30rpx;
+	}
+	.stateText{
+		font-size: 26rpx;
+		color: darkgray;
+	}
+	.shuliangText{
+		font-size: 40rpx;
+		font-weight: bold;
+	}
+	.danweiText{
+		font-size: 24rpx;
+	}
+
+</style>

+ 77 - 0
components/netImage/netImage.vue

@@ -0,0 +1,77 @@
+<template>
+	<view :class="backgrS==1?'':'imageBGV'" :style="{width:width+'rpx',height:height+'rpx',borderRadius:bradius+'rpx'}">
+		<image :style="{width:width+'rpx',height:height+'rpx',borderRadius:bradius+'rpx'}"  :src="compleurl(comUrl)" :mode="mymode" @error="imageError" @click="myimageclick"></image>
+	</view>
+</template>
+
+<script>
+	export default {
+		name:"netImage",
+		props:{
+			mysrc: '',
+			mymode:'',
+			width:0,
+			height:0,
+			bradius:0,
+			backgrS:0,
+		},
+		data() {
+			return {
+				defaultImage:'/static/logo.png',
+				baseUrl:'https://backend.cityexpress168.com.vn/prod-api',
+				showdefault:0,
+				comUrl:this.mysrc
+			};
+		},
+		watch: {
+			mysrc(val){
+				this.showdefault=0;
+				this.comUrl = this.mysrc
+				//console.log('watch-------------')
+				//console.log(this.comUrl);
+			}
+		},
+		methods:{
+			imageError(){
+				this.comUrl ='';// this.defaultImage;//morentup
+				//console.log('imageError---------------')
+				//console.log(this.baseUrl+this.comUrl)
+				this.showdefault=1;
+			},
+			myimageclick(){
+				this.$emit('Emyimageclick',this.comUrl);
+			},
+			compleurl(url){
+				//console.log('------compleurl',url)
+				if(!url){
+					return '';
+				}
+				if(url.length<8){
+					return '';
+				}
+				var https= url.substring(0,8);
+				if(https==='https://'){
+					return url;
+				}
+				var http= url.substring(0,7);
+				if(http==='http://'){
+					return url;
+				}
+				else if(http==='/static/'){
+					return url;
+				}
+				else{
+					//console.log(this.baseUrl+url);
+					return (this.baseUrl+url);
+				}
+			}
+		},
+	}
+</script>
+
+<style>
+	.imageBGV{
+		background-color:floralwhite;
+		border: 1rpx solid lightgray;
+	}
+</style>

+ 617 - 0
components/orderItem/orderItem.vue

@@ -0,0 +1,617 @@
+<template>
+	<view style="background-color: whitesmoke;">
+		<view class="itemV content" v-for="(item,index) in orderList">
+			<view class="contentInRowS">
+				<text class="timeText">{{item.ddId}}</text>
+				<text v-if="item.collectPayment==1" class="jiedanBtdf" style="font-size: 24rpx;">{{$t('index.huodaofukan')}}</text>
+			</view>
+			<view class="contentColumn">
+				<view class="contentInRowL">
+					<text class="titleText pnametext" style="margin-left:20rpx;">{{$t('order.peisongfei')}}: {{$formPr(item.freight)}}{{$t('api.huobidanwei')}}</text>
+				</view>
+				<view class="contentInRowR">
+					<text class="priceText">{{$t('order.dingdanjin')}}: {{$formPr(item.amount)}}{{$t('api.huobidanwei')}}</text>
+				</view>
+			</view>
+			<view v-if="youyouhui(item)" class="contentInRowL" style="margin-left:20rpx;">
+				<text class="titleText pnametext">{{$t('order.youhuijine')}}:</text>
+				<text class="titleText" style="padding-left: 20rpx;">{{getyhjr(item)}}</text>
+			</view>
+			<view v-if="item.pointsReduction>0" class="contentInRowL" style="margin-left:20rpx;">
+				<text class="titleText">{{$t('jifen.jifendikou')}}:</text>
+				<text class="titleText" style="padding-left: 20rpx;"> -{{$formPr(item.pointsReduction)}}{{$t('api.huobidanwei')}}</text>
+			</view>
+			
+			
+			<view style="width: 100%;margin-top: 20rpx;margin-left: 20rpx;" class="contentInRowL">
+				<view style="width: 100rpx" class="contentColumn">
+					<text class="quhuodian">{{$t('order.quhuodian')}}</text>
+					<view class="lineimag">
+					</view>
+				</view>
+				<view style="margin-left: 20rpx;width: 80%;" class="contentColumn">
+					<view class="contentColumn">
+						<text class="titleText pnametext">{{item.store.posName}}</text>
+						<text class="distenText">({{$t('order.juli')}}{{item.qsjvli}}Km)</text>
+					</view>
+					<view>
+						<text class="addrText">{{item.store.address}}</text>
+					</view>
+					<view >
+						<text v-if="item.diningStatus==1" class="stateText">{{$t('order.shangjiayqrcc')}}</text>
+					</view>
+				</view>
+			</view>
+			
+			<view v-if="item.shaddress!=null" style="margin-left: 20rpx;margin-top: 20rpx;" class="contentInRowL">
+				<view style="width: 100rpx" class="contentColumn">
+					<text class="shouhuodian">{{$t('order.shouhuodian')}}</text>
+				</view>
+				<view style="margin-left: 20rpx;width: 80%;" class="contentColumn" @click="openBimg(item.shaddress.annexes)">
+					<view class="contentInRowL">
+						<text class="titleText">{{item.shaddress.name}}</text>
+						<text class="distenText">({{$t('order.juli')}}{{item.jvli}}Km)</text>
+					</view>
+					<text class="addrText">{{item.shaddress.address}}</text>
+					<text class="addrText">{{item.shaddress.area}}</text>
+					<text v-if="item.remarks!=''" class="noteText">{{item.remarks}}</text>
+				</view>
+			</view>
+			<view v-if="youyouhui(item)" class="contentColumnC psfnote">
+				<text  class="addrText" style="color:white;padding: 6rpx;">{{$t('order.qishouyhts')}}</text>
+			</view>
+			<view class="contentInRowC" style="width: 100%;margin-top: 10rpx;">
+				<view class="contentInRowC wanchengV"  @click="jiedan(item)">
+					<view class="wanchengT">{{$t('shouye.jieshoudd')}}</view>
+				</view>
+			</view>
+			<view v-if="item.state==2||1" style="margin-bottom: 20rpx;margin-top: 20rpx;" class="contentInRowS">
+				<view class="contentColumnC" style="margin:20rpx;padding-left: 10rpx;" @click="callPhone(item.shaddress.phone,item.user)">
+					<uni-icons custom-prefix="custom-icon" color="#006AFF" type="phone-filled" size="28"></uni-icons>
+					<text class="jiedanText">{{$t('order.lianxi')}}</text>
+				</view>
+				<view class="contentColumnC" style="margin:20rpx;padding-right: 10rpx;" @click="gotoNav(item.shaddress)">
+					<uni-icons custom-prefix="custom-icon" color="#006AFF" type="navigate-filled" size="28"></uni-icons>
+					<text class="jiedanText">Navigation</text>
+				</view>
+				<view class="contentColumnC" style="margin:20rpx;" @click="Exchange(item.ddId,item.user)">
+					<uni-icons custom-prefix="custom-icon" color="#006AFF" type="chatboxes" size="28"></uni-icons>
+					<text class="jiedanText">{{$t('exchange.xinxi')}}</text>
+				</view>
+				<view class="contentColumnC" style="margin:20rpx;padding-left: 10rpx;" @click="imCall(item.ddId,item.user)">
+					<uni-icons custom-prefix="custom-icon" color="#006AFF" type="phone" size="28"></uni-icons>
+					<text class="jiedanText">IM Call</text>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	 import api from "@/pages/api/api.js"
+	import {
+		setorderuzt
+	} from '@/pages/api/basic';
+	export default {
+		name:"orderItem",
+		props:{
+			orderList:'',
+			qsId:''
+		},
+		data() {
+			return {
+				isAndroid:true
+			};
+		},
+		mounted() {
+			let systemInfo = uni.getSystemInfoSync();
+			this.isAndroid = systemInfo.platform.toLowerCase() === 'android';
+		},
+		methods:{
+			
+			youyouhui(obj){
+				if(obj.mdSalesReduction){
+					return true;
+				}
+				if(obj.mdDiscountAmount){
+					return true;
+				}
+				if(obj.discountAmount){
+					return true;
+				}
+				if(obj.salesReduction){
+					return true;
+				}
+				
+				return false;
+			},
+			
+			getyhjr(obj){
+				var jinr=0;
+				if(obj.mdSalesReduction){
+					jinr=obj.mdSalesReduction;
+				}
+				if(obj.mdDiscountAmount){
+					jinr=jinr+obj.mdDiscountAmount;
+				}
+				if(obj.discountAmount){
+					jinr=jinr+obj.discountAmount;
+				}
+				if(obj.salesReduction){
+					jinr=jinr+obj.salesReduction;
+				}
+				jinr=parseInt(jinr);
+				return '-'+this.$formPr(jinr)+this.$t('api.huobidanwei');
+			},
+			
+			openBimg(mysrc){
+				
+				if(!mysrc){
+					return;
+				}
+				if(mysrc.length<8){
+					return;
+				}
+				console.log(mysrc);
+				uni.navigateTo({
+					url:'/pages/index/BigimageView?mysrc='+mysrc
+				})
+			},
+			jiedan(obj){
+				var online = getApp().globalData.isOnline;
+				if(!online){
+					uni.showToast({
+					    title: this.$t('user.xiaxianzh'),
+					    icon: 'none',
+					    duration: 2500
+					})
+					return;
+				}
+				
+				if(this.qsId<=0 ||''==this.qsId){
+					uni.showToast({
+					    title: this.$t('user.denglushixiao'),
+					    icon: 'none',
+					    duration: 2500
+					})
+					return;
+				}
+				var austate = getApp().globalData.auditStatus;
+				if(austate!=1){
+					uni.showToast({
+					    title: this.$t('user.zhanghaowsh'),
+					    icon: 'none',
+					    duration: 2500
+					})
+					return;
+				}
+				if(obj.collectPayment==1){
+					var that = this;
+					uni.showModal({
+					    title:that.$t('shouye.jieshoudd'),
+					    content:that.$t('index.jiedanfengx'),
+						confirmText:that.$t('index.queren'),
+						cancelText:that.$t('index.quxiao'),
+					    success: function (res) {
+					        if (res.confirm) { //这里是点击了确定以后
+								that.setorderuzt(obj,3)
+								//向商家推送通知
+								that.pushMsg(obj);
+					        } else { //这里是点击了取消以后
+					          console.log('点击取消')
+					        }
+					    }
+					})
+				}
+				else{
+					this.setorderuzt(obj,3)
+				}
+				
+			},
+			pushMsg(obj){//消息推送
+				if(obj.shanghu.cid==''||obj.shanghu.cid==null||obj.shanghu.cid==undefined){
+					return;
+				}
+				api('pushMsgSJ',{
+					cid:obj.shanghu.cid,
+					title:'新订单|Lệnh mới',
+					content:'你有新订单了|Anh có lệnh mới.',
+					payload:''
+				},res=>{
+					console.log(res)
+				},failc=>{
+					//console.log('getadvertis----',failc)
+				})
+			},
+			callPhone(telphone,user){
+				var that = this;
+				uni.showModal({
+				    title: that.$t('api.message'),
+				    content:that.$t('api.nqdbddh'),
+					confirmText:that.$t('index.queren'),
+					cancelText:that.$t('index.quxiao'),
+				    success: function (res) {
+				        if (res.confirm) { //这里是点击了确定以后
+							console.log('打电话')
+							plus.device.dial(telphone, false );
+				        } else { //这里是点击了取消以后
+				          console.log('点击取消')
+				        }
+				    }
+				})
+			},
+			imCall(ddid,user){
+				var data = {
+					ddId:ddid,
+					userId:user.userId,
+					nickName:user.nickName,
+					avatar:user.avatar,
+					cid:user.cid
+				}
+				uni.setStorageSync('imUser',data);
+				uni.navigateTo({
+					url:'/pages/imcall/audioCall?caller=1'
+				})
+			},
+			Exchange(ddid,user){
+				var data = {
+					ddId:ddid,
+					userId:user.userId,
+					nickName:user.nickName,
+					avatar:user.avatar,
+					cid:user.cid
+				}
+				uni.setStorageSync('imUser',data);
+				uni.navigateTo({
+					url:'/pages/imcall/GoeasyExchange?caller=1'
+				})
+			},
+			setorderuzt(obj,state,){
+				var that = this;
+				var data;
+				if(obj.collectPayment==1){
+					data={
+						id:obj.id,
+						state:state,
+						qsId:this.qsId,
+						collectPayment:obj.collectPayment
+					}
+				}
+				else{
+					data={
+						id:obj.id,
+						state:state,
+						qsId:this.qsId
+					}
+				}
+				uni.showLoading({
+					title:'Loading...',
+					mask:true
+				})
+				this.$http.post(`${setorderuzt}`,data,true)
+				.then(r => {
+					uni.hideLoading();
+					console.log(r);
+					if(r.data.code==500){
+						uni.showToast({
+						    title: r.data.msg,
+						    icon: 'none',
+						    duration: 2500
+						})
+						return;
+					}
+					this.$emit('ErefleshList');
+				})
+				.catch(err => {
+					uni.hideLoading();
+					console.log(err)
+				})
+			},
+			gotoNav(store){
+				var navData={
+					latitude:parseFloat(store.latitude),
+					longitude:parseFloat(store.longitude),
+					address:store.address
+				}
+				var temp = JSON.stringify(navData);
+				uni.navigateTo({
+					url:'/pages/map/mapboxView?navdata='+temp
+				})
+				
+			},
+			
+			handlePosition(lat,lon,cityName) {
+				//如果是Andrios的设备
+				if (plus.os.name == 'Android') {
+					console.log('Android')
+					const hasBaiduMap = plus.runtime.isApplicationExist({
+						pname: 'com.baidu.BaiduMap',
+						action: 'baidumap://'
+					});
+					const hasAmap = plus.runtime.isApplicationExist({
+						pname: 'com.autonavi.minimap',
+						action: 'androidamap://'
+					});
+					const hasgoogle = plus.runtime.isApplicationExist({
+						pname: 'com.google.android.apps.maps',
+						action: 'comgooglemaps://'
+					});
+					
+					//重点是下面的url要根据官方给出的api进行对应,不同的需求对应不同的api
+					let urlBaiduMap =
+					'baidumap://map/direction?region=起点&destination='+lat+','+lon+'&coord_type=wgs84&mode=riding&src=andr.paotuiwang.qishou';
+					urlBaiduMap = encodeURI(urlBaiduMap)
+					let urlAmap =
+						'androidamap://viewMap?sourceApplication=appname&poiname='+cityName+'&lat='+lat+'&lon='+lon+'&dev=1';
+					urlAmap = encodeURI(urlAmap)
+					
+					
+					var buttons=[];
+					if(hasBaiduMap){
+						buttons.push({
+							title: this.$t('user.baiduNav'),
+							value:urlBaiduMap
+						})
+					}
+					if(hasAmap){
+						buttons.push({
+							title: this.$t('user.gaodeNav'),
+							value:urlAmap
+						})
+					}
+					// if(hasgoogle){
+					// 	buttons.push({title: this.$t('user.googleNav')})
+					// }
+					if(buttons.length==0){
+						if(hasgoogle){
+							var url = 'google.navigation:q=' + lat + ',' + lon;  //如果是国外应用,应该优先使用这个,会启动google地图。这个接口不能统一坐标系,进入百度地图时会有偏差
+							plus.runtime.openURL(url);
+							return;
+						}
+					}
+					
+					plus.nativeUI.actionSheet({
+						title: this.$t('user.xuanzedaoh'),
+						cancel: this.$t('index.quxiao'),
+						buttons: buttons
+					}, function(e) {
+						plus.runtime.openURL(buttons[e.index-1].value);
+					});
+				} else {
+					// iOS上获取本机是否安装了百度高德地图,需要在manifest里配置,在manifest.json文件app-plus->distribute->apple->urlschemewhitelist节点下添加(如urlschemewhitelist:["iosamap","baidumap"])
+					var url='';
+					var that = this;
+					plus.nativeUI.actionSheet({
+						title: this.$t('user.xuanzedaoh'),
+						cancel: this.$t('index.quxiao'),
+						buttons: [{
+							title: this.$t('user.baiduNav')
+						},{
+							title: this.$t('user.gaodeNav')
+						},{
+							title: this.$t('user.googleNav')
+						},{
+							title: this.$t('user.appleNav')
+						}]
+					}, function(e) {
+						switch (e.index) {
+							case 1:
+								url ='baidumap://map/marker?location='+lat+','+lon+'&title='+cityName+'&content='+cityName+'&coord_type=wgs84&src=ios.baidu.openAPIdemo';
+								break;
+							case 2:
+								url ='iosamap://path?sourceApplication=fuxishan_uni_client&dlat='+lat+'&dlon='+lon+'&dname='+cityName+'&dev=1&t=0';
+								break;
+							case 3:
+								url='comgooglemapsurl://?daddr='+ lat + ',' + lon;
+								break;
+							case 4:
+								url = 'http://maps.apple.com/?q=' +cityName + '&ll=' + lat + ',' + lon + '&spn=0.008766,0.019441';
+								break;
+							default:
+								break;
+						}
+						if (url!='') {
+							url = encodeURI(url)
+							plus.runtime.openURL(url, function(e) {
+							    plus.nativeUI.alert(that.$t('user.weianzhuangapp'));
+							});
+						}
+					})
+				}
+			},
+		},
+	}
+</script>
+
+<style>
+	@import '@/common/common.scss';
+	@font-face {
+		font-family: zrht;
+		src: url('/uni_modules/font/zrht.otf');
+	}
+
+.itemV{
+	margin-top: 16rpx;
+	background-color: white;
+}
+
+.psfnote{
+	width: 92%;
+	margin-left: 4%;
+	margin-top: 5rpx;
+	border-radius: 10rpx;
+	background-color: crimson;
+}
+.qiangdImg{
+	width: 120rpx;
+	height: 120rpx;
+}
+
+.quhuodian{
+	font-size: 26rpx;
+	padding: 8rpx;
+	color: royalblue;
+	border-radius: 16rpx;
+	border: solid royalblue;
+}
+
+.shouhuodian{
+	font-size: 26rpx;
+	padding: 8rpx;
+	color: crimson;
+	border-radius: 16rpx;
+	border: solid crimson;
+}
+.lineimag{
+	display: flex;
+	flex-direction: column;
+	justify-content: space-between;
+	margin-left: 45rpx;
+	width: 4rpx;
+	background-color: lightgray;
+	height: 100rpx;
+	margin-top: 4rpx;
+	margin-bottom: 4rpx;
+}
+.yuandian{
+	width: 16rpx;
+	height: 16rpx;
+	background-color: lightgray;
+	border-radius: 8rpx;
+	margin-left: -8rpx;
+}
+
+.timeText{
+	font-size: 32rpx;
+	color: #006AFF;
+	padding-left: 20rpx;
+	font-weight: bold;
+}
+
+.priceText{
+	font-size: 30rpx;
+	color: crimson;
+	padding-right: 20rpx;
+}
+
+.titleText{
+	font-size: 28rpx;
+	/* font-family: zrht; */
+}
+
+.pnametext{
+	overflow: hidden;
+	text-overflow: ellipsis;
+	display: -webkit-box;
+	-webkit-line-clamp: 1;
+	-webkit-box-orient: vertical;
+}
+
+.distenText{
+	font-size: 30rpx;
+	color: darkgray;
+}
+
+.addrText{
+	font-size: 28rpx;
+	color: dimgray;
+}
+
+.stateText{
+	font-size: 28rpx;
+	color: darkgray;
+	margin-top: 6rpx;
+	padding-left: 8rpx;
+	padding-right: 8rpx;
+	padding-top: 2rpx;
+	padding-bottom: 2rpx;
+	border: 2rpx solid darkgray;
+	border-radius: 8rpx;
+	
+}
+
+.noteText{
+	margin-top: 16rpx;
+	font-size: 28rpx;
+	color: dimgray;
+	padding: 8rpx;
+	background-color: whitesmoke;
+	border-radius: 8rpx;
+}
+
+.connectText{
+	font-size: 28rpx;
+	color: black;
+	margin-top: 6rpx;
+	padding-left: 8rpx;
+	padding-right: 8rpx;
+	padding-top: 2rpx;
+	padding-bottom: 2rpx;
+	border: 2rpx solid darkgray;
+	border-radius: 8rpx;
+	
+}
+
+.setImg{
+	width: 30rpx;
+	height: 30rpx;
+}
+
+.setImgB{
+	width: 40rpx;
+	height: 40rpx;
+}
+
+
+.jiedanText{
+	font-size: 24rpx;
+	color: black;
+}
+
+.jiedanTextS{
+	font-size: 20rpx;
+	color: black;
+}
+
+.wanchengV{
+	width: 80%;
+	height: 68rpx;
+	border-radius: 10rpx;
+	margin-top: 40rpx;
+	margin-bottom: 20rpx;
+	background-color: #006AFF;
+}
+
+.shuaxinBT{
+	font-weight: bold;
+	font-size: 30rpx;
+	color: black;
+	border-radius: 8rpx;
+	padding: 6rpx;
+	margin-right: 30rpx;	
+}
+.wanchengT{
+	width: 100%;
+	font-weight: bold;
+	font-size: 26rpx;
+	color: white;
+	border-radius: 8rpx;
+	text-align: center;
+}
+.jiedanBt{
+	padding: 10rpx;
+	color:white;
+	background-color: #00A6FF;
+	border-radius: 8rpx;
+	box-shadow: 0rpx 0rpx 10rpx 0rpx #00A6FF;
+}
+
+.jiedanBtdf{
+	padding: 10rpx;
+	color:white;
+	background-color: #1A1A1A;
+	border-radius: 8rpx;
+	box-shadow: 0rpx 0rpx 2rpx 0rpx #1A1A1A;
+}
+	
+</style>

+ 555 - 0
components/orderItemA/orderItemA.vue

@@ -0,0 +1,555 @@
+<template>
+	<view style="background-color: whitesmoke;">
+		<view v-if="orderList!=''">
+			<view class="itemV content" v-for="(item,index) in orderList">
+				<view class="contentInRowS">
+					<text class="timeText">{{item.ddId}}</text>
+					<text v-if="item.collectPayment==1" class="jiedanBtdf" style="font-size: 24rpx;">{{$t('index.huodaofukan')}}</text>
+				</view>
+				<view class="contentColumn">
+					<view class="contentInRowL">
+						<text class="titleText pnametext" style="margin-left:20rpx;">{{$t('order.peisongfei')}}: {{$formPr(item.freight)}}{{$t('api.huobidanwei')}}</text>
+					</view>
+					<view class="contentInRowR">
+						<text class="priceText">{{$t('order.shangpinxj')}}: {{shphj(item)}}</text>
+					</view>
+				</view>
+				<view v-if="youyouhui(item)" class="contentInRowL" style="margin-left:20rpx;">
+					<text class="titleText">{{$t('order.youhuijine')}}:</text>
+					<text class="titleText" style="padding-left: 20rpx;">{{getyhjr(item)}}</text>
+				</view>
+				<view style="width: 100%;margin-top: 20rpx;margin-left: 20rpx;" class="contentInRowL">
+					<view style="width: 100rpx" class="contentColumn">
+						<text class="quhuodian">{{$t('order.quhuodian')}}</text>
+					</view>
+					<view style="margin-left: 20rpx;width: 100%;" class="contentColumn">
+						<view v-if="item.store" class="" @click="gotoNav(item.store)">
+							<view class="contentColumn">
+								<text class="titleText">{{item.store.posName}}</text>
+								<!-- <text class="distenText">({{$t('order.juli')}}{{item.qsjvli}})</text> -->
+							</view>
+							<view style="width: 94%;">
+								<text class="addrText">{{item.store.address}}</text>
+							</view>
+							<view>
+								<text v-if="item.diningStatus==1" class="stateText">{{$t('order.shangjiayqrcc')}}</text>
+							</view>
+						</view>
+						<view v-for="(itemf,index) in item.food"  style="width: 100%;">
+							<view class="contentInRowL" style="margin-top: 12rpx;width: 90%;">
+								<myImage class="spIcon" :mysrc="itemf.image" mymode="scaleToFill" ></myImage>
+								<view class="contentColumn" style="margin-left: 10rpx;width: 78%;">
+									<text class="addrText">{{itemf.name}}</text>
+									<view class="contentInRowS">
+										<view class="contentInRowL ">
+											<text class="kouweisku" v-for="sku in itemf.ask">{{sku}}</text>
+										</view>
+										<text class="addrText">{{itemf.number}}</text>
+									</view>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+				<view v-if="youyouhui(item)" class="contentColumnC psfnote">
+					<text class="addrText" style="color:white;padding: 6rpx;">{{$t('order.qishouyhts')}}</text>
+				</view>
+				<view v-if="item.collectPayment==1" class="contentColumnC psfnote" style="background-color: darkgreen;">
+					<text class="addrText" style="color:white;padding: 6rpx;">{{$t('order.qiszhifts')}}</text>
+				</view>
+				<view class="contentInRowS" style="margin-top: 10rpx;">
+					<view class="contentColumnC" style="margin:20rpx;padding-left: 10rpx;" @click="callPhone(item.store.telephone,item.store)">
+						<uni-icons custom-prefix="custom-icon" color="#006AFF" type="phone-filled" size="28"></uni-icons>
+						<label class="jiedanText">{{$t('order.lianxi')}}</label>
+					</view>
+					<view class="contentColumnC" style="margin:20rpx;padding-right: 10rpx;" @click="gotoNav(item.store)">
+						<uni-icons custom-prefix="custom-icon" color="#006AFF" type="navigate-filled" size="28"></uni-icons>
+						<label class="jiedanText">Navigation</label>
+					</view>
+					<view class="contentColumnC" style="margin:20rpx;padding-left: 10rpx;" @click="qucanshibai(item)">
+						<uni-icons custom-prefix="custom-icon" color="crimson" type="closeempty" size="28"></uni-icons>
+						<label class="jiedanText">{{$t('order.qucanshib')}}</label>
+					</view>
+					<view class="contentColumnC" style="margin:20rpx;padding-left: 10rpx;" @click="quchan(item)">
+						<uni-icons custom-prefix="custom-icon" color="#006AFF" type="checkmarkempty" size="28"></uni-icons>
+						<label class="jiedanText">{{$t('order.wanchengquhuo')}}</label>
+					</view>
+				</view>
+			</view>
+		</view>
+		<uni-popup style="z-index: 9999;" ref="popqc" type="center" :isMaskClick="true" :safeArea="true">
+			<view class="contentColumn" style="width:600rpx;background-color: whitesmoke;border-radius: 10rpx;">
+				<view class="item_list">
+					<view class="item_content" v-for="(itemi,indexi) in annexList" @click="imagesel(indexi)">
+						<netImage v-if="itemi!=''" width="180" height="180" bradius="4" :mysrc="itemi" mymode="scaleToFill" ></netImage>
+					</view>
+					<view class="item_content" @click="updataImage">
+						<image class="upimagV" src="/static/imags/shangctp.png" mode="scaleToFill"></image>
+					</view>
+				</view>
+				<view class="contentInRowC">
+					<text class="actbttext" style="background-color:rosybrown;" @click="quxiaoqc">{{$t('index.quxiao')}}</text>
+					<text class="actbttext" style="background-color:#006Aff;" @click="querenqucan">{{$t('order.wanchengquhuo')}}</text>
+				</view>
+			</view>
+		</uni-popup>
+	</view>
+</template>
+
+<script>
+	import {
+		UploadImage,
+		setorderuzt
+	} from '@/pages/api/basic';
+	export default {
+		name:"orderItem",
+		props:{
+			orderList:'',
+			qsId:''
+		},
+		data() {
+			return {
+				isAndroid:true,
+				annexList:[],
+				actId:''
+			};
+		},
+		mounted() {
+			let systemInfo = uni.getSystemInfoSync();
+			this.isAndroid = systemInfo.platform.toLowerCase() === 'android';
+		},
+		methods:{
+			shphj(obj){
+				var yhjinr=0;
+				if(obj.mdSalesReduction){
+					yhjinr=obj.mdSalesReduction;
+				}
+				if(obj.mdDiscountAmount){
+					yhjinr=yhjinr+obj.mdDiscountAmount;
+				}
+				yhjinr=parseInt(yhjinr);
+				
+				var spxj=0;
+				for(var i=0;i<obj.food.length;i++){
+					spxj=spxj+(obj.food[i].price+obj.food[i].otherPrice)*obj.food[i].number;
+				}
+				var jinr=spxj-yhjinr;
+				if(jinr>0){
+					jinr=parseInt(jinr);
+				}
+				else{
+					jinr=0;
+				}
+				jinr=parseInt(jinr);
+				return this.$formPr(jinr)+this.$t('api.huobidanwei');
+			},
+			
+			youyouhui(obj){
+				if(obj.mdSalesReduction){
+					return true;
+				}
+				if(obj.mdDiscountAmount){
+					return true;
+				}
+				if(obj.discountAmount){
+					return true;
+				}
+				if(obj.salesReduction){
+					return true;
+				}
+				
+				return false;
+			},
+			
+			getyhjr(obj){
+				var jinr=0;
+				if(obj.mdSalesReduction){
+					jinr=obj.mdSalesReduction;
+				}
+				if(obj.mdDiscountAmount){
+					jinr=jinr+obj.mdDiscountAmount;
+				}
+				if(obj.discountAmount){
+					jinr=jinr+obj.discountAmount;
+				}
+				if(obj.salesReduction){
+					jinr=jinr+obj.salesReduction;
+				}
+				jinr=parseInt(jinr);
+				return '-'+this.$formPr(jinr)+this.$t('api.huobidanwei');
+			},
+			
+			qucanshibai(obj){
+				var that = this;
+				uni.showModal({
+				    title: that.$t('api.message'),
+				    content:that.$t('order.qrqucanshib'),
+					confirmText:that.$t('index.queren'),
+					cancelText:that.$t('index.quxiao'),
+				    success: function (res) {
+				        if (res.confirm) { //这里是点击了确定以后
+							that.setorderuzt(obj.id,9)
+				        } else { //这里是点击了取消以后
+				          console.log('点击取消')
+				        }
+				    }
+				})
+			},
+			
+			quchan(obj){
+				console.log('quchan');
+				this.actId=obj.id;
+				if(obj.sqImg){
+					this.annexList=JSON.parse(obj.sqImg);
+				}
+				else{
+					this.annexList=[];
+				}
+				this.$refs.popqc.open('center');
+			},
+			querenqucan(){
+				
+				//还要同步上传图片
+				if(this.annexList.length==0){
+					uni.showToast({
+						title:this.$t('order.qingxiansctp'),
+						icon: 'none',
+						duration: 2500
+					})
+					return;
+				}
+				this.$refs.popqc.close();
+				var data={
+					id:this.actId,
+					state:4,
+					//qsId:this.qsId,
+					diningStatus:1,
+					qsImg:JSON.stringify(this.annexList)
+				}
+				console.log(data)
+				this.$http.post(`${setorderuzt}`,data,true)
+				.then(r => {
+					console.log(r);
+					this.$emit('ErefleshList');
+				})
+				.catch(err => {
+					console.log(err)
+				})
+			},
+			quxiaoqc(){
+				this.$refs.popqc.close();
+			},
+			imagesel(index){
+				
+			},
+			updataImage(){
+				var that = this;
+				uni.showModal({
+				    title: that.$t('api.message'),
+				    content:that.$t('order.qingxuanz'),
+					confirmText:that.$t('order.qupaishe'),
+					cancelText:that.$t('order.qushangc'),
+				    success: function (res) {
+				        if (res.confirm) { //这里是点击了确定以后
+							that.getimage(2);
+				        } else { //这里是点击了取消以后
+				          console.log('点击取消')
+						  that.getimage(1)
+				        }
+				    }
+				})
+			},
+			getimage(state){
+				var sourceType=[];
+				if(state==1){
+					sourceType=['album']
+				}
+				else{
+					sourceType=['camera']
+				}
+				var that = this;
+				uni.chooseImage({
+					count: 1,  // 图片数量
+					sizeType: ['compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType:sourceType, //从相册选择或者拍照
+					success: (res) => {
+						const tempFilePaths = res.tempFilePaths;
+						uni.uploadFile({
+							url: that.$baseurl+UploadImage, //上传图片api
+							filePath: tempFilePaths[0],
+							name: 'file',
+							header:{
+								//"Authorization": userinfo.token
+							},
+							success: (res) => {
+								// console.log(res)
+								let group =  JSON.parse(res.data);
+								var l = that.annexList.length;
+								var temp = that.annexList;
+								temp.push(group.data);
+								that.annexList=temp;
+							}
+						});
+					}
+				});
+			},
+			callPhone(telphone,user){
+				var that = this;
+				uni.showModal({
+				    title: that.$t('api.message'),
+				    content:that.$t('api.nqdbddh'),
+					confirmText:that.$t('index.queren'),
+					cancelText:that.$t('index.quxiao'),
+				    success: function (res) {
+				        if (res.confirm) { //这里是点击了确定以后
+							console.log('打电话')
+							plus.device.dial(telphone, false );
+				        } else { //这里是点击了取消以后
+				          console.log('点击取消')
+				        }
+				    }
+				})
+			},
+			async setorderuzt(rId,state){
+				var that = this;
+				var data;
+				if(state==3){
+					data={
+						id:rId,
+						state:state,
+						qsId:this.qsId
+					}
+				}
+				else{
+					data={
+						id:rId,
+						state:state,
+						qsId:this.qsId,
+						diningStatus:1
+					}
+				}
+				await this.$http.post(`${setorderuzt}`,data,true)
+				.then(async r => {
+					console.log(r);
+					this.$emit('ErefleshList');
+				})
+				.catch(err => {
+					console.log(err)
+				})
+			},
+			
+			gotoNav(store){
+				var navData={
+					latitude:store.latitude,
+					longitude:store.longitude,
+					address:store.posName
+				}
+				var temp = JSON.stringify(navData);
+				uni.navigateTo({
+					url:'/pages/map/mapboxView?navdata='+temp
+				})
+				
+			},
+		},
+	}
+</script>
+
+<style lang="scss">
+	@import '@/common/common.scss';
+	@font-face {
+		font-family: zrht;
+		src: url('/uni_modules/font/zrht.otf');
+	}
+
+.itemV{
+	margin-top: 16rpx;
+	background-color: white;
+}
+.psfnote{
+	width: 92%;
+	margin-left: 4%;
+	margin-top: 5rpx;
+	border-radius: 10rpx;
+	background-color: crimson;
+}
+.spIcon{
+	width: 90rpx;
+	height: 90rpx;
+}
+
+.kouweisku{
+	color:chocolate;
+	padding-right: 12rpx;
+	font-size: 28rpx;
+}
+
+.qiangdImg{
+	width: 120rpx;
+	height: 120rpx;
+}
+
+.quhuodian{
+	font-size: 26rpx;
+	padding: 8rpx;
+	color: royalblue;
+	border-radius: 16rpx;
+	border: solid royalblue;
+}
+
+.shouhuodian{
+	font-size: 26rpx;
+	padding: 8rpx;
+	color: crimson;
+	border-radius: 16rpx;
+	border: solid crimson;
+}
+.lineimag{
+	display: flex;
+	flex-direction: column;
+	justify-content: space-between;
+	margin-left: 45rpx;
+	width: 4rpx;
+	background-color: lightgray;
+	height: 100rpx;
+	margin-top: 4rpx;
+	margin-bottom: 4rpx;
+}
+.yuandian{
+	width: 16rpx;
+	height: 16rpx;
+	background-color: lightgray;
+	border-radius: 8rpx;
+	margin-left: -8rpx;
+}
+
+.timeText{
+	font-size: 32rpx;
+	color: #006AFF;
+	padding-left: 20rpx;
+	font-weight: bold;
+}
+
+.priceText{
+	font-size: 30rpx;
+	color: crimson;
+	padding-right: 20rpx;
+	text-align: right;
+}
+
+.titleText{
+	font-size: 28rpx;
+	/* font-family: zrht; */
+}
+
+.distenText{
+	font-size: 26rpx;
+	color: darkgray;
+}
+
+.addrText{
+	font-size: 28rpx;
+	color: dimgray;
+}
+
+.stateText{
+	font-size: 28rpx;
+	color: darkgray;
+	margin-top: 6rpx;
+	padding-left: 8rpx;
+	padding-right: 8rpx;
+	padding-top: 2rpx;
+	padding-bottom: 2rpx;
+	border: 2rpx solid darkgray;
+	border-radius: 8rpx;
+	
+}
+
+.noteText{
+	margin-top: 16rpx;
+	font-size: 28rpx;
+	color: dimgray;
+	padding: 8rpx;
+	background-color: whitesmoke;
+	border-radius: 8rpx;
+}
+
+.connectText{
+	font-size: 28rpx;
+	color: black;
+	padding: 8rpx;
+	border: solid darkgray;
+	border-radius: 8rpx;
+	
+}
+
+.setImg{
+	width: 30rpx;
+	height: 30rpx;
+}
+
+.setImgB{
+	width: 40rpx;
+	height: 40rpx;
+}
+
+
+.jiedanText{
+	font-size: 24rpx;
+	color: black;
+}
+
+.jiedanTextS{
+	font-size: 20rpx;
+	color: black;
+}
+
+.wanchengV{
+	width: 80%;
+	height: 68rpx;
+	border-radius: 10rpx;
+	margin-left: 10%;
+	margin-top: 40rpx;
+	margin-bottom: 20rpx;
+	background-color: #006AFF;
+}
+
+.wanchengT{
+	font-weight: bold;
+	font-size: 30rpx;
+	color: black;
+	border-radius: 8rpx;
+	padding: 6rpx;
+	margin-right: 30rpx;	
+}
+.jiedanBtdf{
+	padding: 10rpx;
+	color:white;
+	background-color: #1A1A1A;
+	border-radius: 8rpx;
+	box-shadow: 0rpx 0rpx 2rpx 0rpx #1A1A1A;
+}
+
+.item_list{
+	display: flex;
+	flex-wrap: wrap;
+	justify-content: flex-start;
+	.item_content{
+		width:180rpx;
+		height:180rpx;
+		margin: 10rpx;
+		box-sizing: border-box;
+	}
+}
+.upimagV{
+	width: 180rpx;
+	height:180rpx;
+}
+.actbttext{
+	width: 50%;
+	line-height: 66rpx;
+	font-size: 28rpx;
+	color: white;
+	text-align: center;
+}
+	
+</style>

+ 735 - 0
components/orderItemB/orderItemB.vue

@@ -0,0 +1,735 @@
+<template>
+	<view style="background-color: whitesmoke;">
+		<view class="itemV content" v-for="(item,indexo) in orderList">
+			<view class="contentInRowS">
+				<text class="timeText">{{item.ddId}}</text>
+				<text v-if="item.collectPayment==1" class="jiedanBtdf" style="font-size: 24rpx;">{{$t('index.huodaofukan')}}</text>
+			</view>
+			<view class="contentColumn">
+				<view class="contentInRowL">
+					<text class="titleText" style="margin-left:20rpx;">{{$t('order.peisongfei')}}: {{$formPr(item.freight)}}{{$t('api.huobidanwei')}}</text>
+				</view>
+				<view class="contentInRowR">
+					<text class="priceText" >{{$t('order.dingdanjin')}}: {{$formPr(item.amount)}}{{$t('api.huobidanwei')}}</text>
+				</view>
+			</view>
+			<view v-if="youyouhui(item)" class="contentInRowL" style="margin-left:20rpx;">
+				<text class="titleText">{{$t('order.youhuijine')}}:</text>
+				<text class="titleText" style="padding-left: 20rpx;">{{getyhjr(item)}}</text>
+			</view>
+			<view v-if="item.pointsReduction>0" class="contentInRowL" style="margin-left:20rpx;">
+				<text class="titleText">{{$t('jifen.jifendikou')}}:</text>
+				<text class="titleText" style="padding-left: 20rpx;"> -{{$formPr(item.pointsReduction)}}{{$t('api.huobidanwei')}}</text>
+			</view>
+			<view style="width: 100%;margin-top: 20rpx;margin-left: 20rpx;" class="contentInRowL">
+				<view v-if="item.store" class="contentColumn">
+					<view>
+						<text class="quhuodian">{{$t('order.quhuodian')}}</text>
+					</view>
+					<view style="margin-top: 20rpx;margin-left: 10rpx;width: 94%;">
+						<text class="titleText">{{item.store.posName}}</text>
+					</view>
+				</view>
+			</view>
+			
+			<view style="margin-left: 20rpx;margin-top: 20rpx;" class="contentInRowL">
+				<view style="width: 100rpx" class="contentColumn">
+					<text class="shouhuodian">{{$t('order.shouhuodian')}}</text>
+				</view>
+				<view style="margin-left: 20rpx;width: 80%;" class="contentColumn">
+					<view v-if="item.shaddress!=null" @click="openBimg(item.shaddress.annexes)">
+						<view class="contentInRowL">
+							<text class="titleText">{{item.shaddress.name}}</text>
+							<text class="distenText">({{$t('order.juli')}}{{item.jvli}}Km)</text>
+						</view>
+						<text class="addrText">{{item.shaddress.address}}</text>
+						<text class="addrText">{{item.shaddress.area}}</text>
+						<text v-if="item.remarks!=''" class="noteText">{{item.remarks}}</text>
+					</view>
+					
+					<view v-for="(itemf,index) in item.food">
+						<view class="contentInRowL" style="margin-top: 12rpx;">
+							<myImage class="spIcon" :mysrc="itemf.image" mymode="scaleToFill" ></myImage>
+							<view class="contentColumn" style="margin-left: 10rpx;width: 78%;">
+								<text class="addrText">{{itemf.name}}</text>
+								<view class="contentInRowS">
+									<view class="contentInRowL ">
+										<text class="kouweisku" v-for="sku in itemf.ask">{{sku}}</text>
+									</view>
+									<text class="addrText">{{itemf.number}}(份)</text>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view v-if="youyouhui(item)" class="contentColumnC psfnote">
+				<text class="addrText" style="color:white;padding: 6rpx;">{{$t('order.qishouyhts')}}</text>
+			</view>
+			<view class="contentInRowS" style="width: 90%;margin-top: 20rpx;margin-left: 5%;">
+				<view class="wanchengT" style="background-color: crimson;" @click="chakantp(item)">{{$t('order.chakantp')}}</view>
+				<view class="wanchengT" style="background-color: #006AFF;"  @click="wancheng(item)">{{$t('order.songda')}}</view>
+			</view>
+			<view v-if="item.shaddress!=null" class="contentInRowS" style="align-items: flex-start;">
+				<view class="contentColumnC" style="margin:20rpx;padding-left: 10rpx;" @click="callPhone(item.shaddress.phone,item.user)">
+					<uni-icons custom-prefix="custom-icon" color="#006AFF" type="phone-filled" size="28"></uni-icons>
+					<label class="jiedanText">{{$t('order.lianxi')}}</label>
+				</view>
+				<view class="contentColumnC" style="margin:20rpx;padding-right: 10rpx;" @click="gotoNav(item.shaddress)">
+					<uni-icons custom-prefix="custom-icon" color="#006AFF" type="navigate-filled" size="28"></uni-icons>
+					<label class="jiedanText">Navigation</label>
+				</view>
+				<view v-if="canopenBimg(item.shaddress.annexes)" class="contentColumnC" style="margin:20rpx;padding-left: 10rpx;" @click="openBimg(item.shaddress.annexes)">
+					<uni-icons custom-prefix="custom-icon" color="#006AFF" type="home" size="28"></uni-icons>
+					<label class="jiedanText">{{$t('order.menpaizp')}}</label>
+				</view>
+				<view class="contentColumnC" style="margin:20rpx;padding-left: 10rpx;" @click="Exchange(item.ddId,item.user)">
+					<uni-icons custom-prefix="custom-icon" color="#006AFF" type="chatboxes" size="28"></uni-icons>
+					<label class="jiedanText">{{$t('exchange.xinxi')}}</label>
+				</view>
+				<view class="contentColumnC" style="margin:20rpx;padding-left: 10rpx;" @click="imCall(item.ddId,item.user)">
+					<uni-icons custom-prefix="custom-icon" color="#006AFF" type="phone" size="28"></uni-icons>
+					<label class="jiedanText">IM Call</label>
+				</view>
+			</view>
+		</view>
+		<uni-popup style="z-index: 9999;" ref="popqc" type="center" :isMaskClick="true" :safeArea="true">
+			<view class="contentColumn" style="width:600rpx;background-color: whitesmoke;border-radius: 10rpx;">
+				<view class="item_list">
+					<view class="item_content" v-for="(itemi,indexi) in annexList" @click="imagesel(indexi)">
+						<netImage v-if="itemi!=''" width="180" height="180" bradius="4" :mysrc="itemi" mymode="scaleToFill" ></netImage>
+					</view>
+					<view class="item_content" @click="updataImage">
+						<image class="upimagV" src="/static/imags/shangctp.png" mode="scaleToFill"></image>
+					</view>
+				</view>
+				<view class="contentInRowC">
+					<text class="actbttext" style="background-color:rosybrown;" @click="quxiaoqc">{{$t('index.quxiao')}}</text>
+					<text class="actbttext" style="background-color:#006Aff;" @click="querensongda">{{$t('order.songda')}}</text>
+				</view>
+			</view>
+		</uni-popup>
+	</view>
+</template>
+
+<script>
+	import {
+		UploadImage,
+		setorderuzt,
+		setLocat
+	} from '@/pages/api/basic';
+	export default {
+		name:"orderItem",
+		props:{
+			orderList:'',
+			qsId:'',
+			
+		},
+		data() {
+			return {
+				isAndroid:true,
+				annexList:[],
+				actobj:''
+			};
+		},
+		mounted() {
+			let systemInfo = uni.getSystemInfoSync();
+			this.isAndroid = systemInfo.platform.toLowerCase() === 'android';
+			console.log('mounted------------------')
+		},
+		methods:{
+			canopenBimg(mysrc){
+				if(!mysrc){
+					return false;
+				}
+				if(mysrc.length<8){
+					return false;
+				}
+				return true;
+			},
+			openBimg(mysrc){
+				
+				if(!mysrc){
+					return;
+				}
+				if(mysrc.length<8){
+					return;
+				}
+				console.log(mysrc);
+				uni.navigateTo({
+					url:'/pages/index/BigimageView?mysrc='+mysrc
+				})
+			},
+			youyouhui(obj){
+				if(obj.mdSalesReduction){
+					return true;
+				}
+				if(obj.mdDiscountAmount){
+					return true;
+				}
+				if(obj.discountAmount){
+					return true;
+				}
+				if(obj.salesReduction){
+					return true;
+				}
+				
+				return false;
+			},
+			
+			getyhjr(obj){
+				var jinr=0;
+				if(obj.mdSalesReduction){
+					jinr=obj.mdSalesReduction;
+				}
+				if(obj.mdDiscountAmount){
+					jinr=jinr+obj.mdDiscountAmount;
+				}
+				if(obj.discountAmount){
+					jinr=jinr+obj.discountAmount;
+				}
+				if(obj.salesReduction){
+					jinr=jinr+obj.salesReduction;
+				}
+				jinr=parseInt(jinr);
+				return '-'+this.$formPr(jinr)+this.$t('api.huobidanwei');
+			},
+			// candianyw(obj){
+			// 	var that = this;
+			// 	uni.showModal({
+			// 		title: that.$t('api.message'),
+			// 		content:that.$t('order.qrcandianyw'),
+			// 		confirmText:that.$t('index.queren'),
+			// 		cancelText:that.$t('index.quxiao'),
+			// 	    success: function (res) {
+			// 			if (res.confirm) { //这里是点击了确定以后
+			// 				that.setorderuzt(obj.id,6);
+			// 			} else { //这里是点击了取消以后
+			// 			  console.log('用户点击取消')
+			// 			}
+			// 	    }
+			// 	})
+			// },
+			chakantp(obj){
+				// this.setorderuzt(obj.id,0)
+				// return;
+				var data={
+					id:'',
+					img:'[]'
+				}
+				if(obj.sqImg){
+					data.img=obj.sqImg;
+				}
+				uni.navigateTo({
+					url:'/pages/index/GoodsImages?obj='+JSON.stringify(data)
+				})
+			},
+			wancheng(obj){
+				this.actobj=obj;
+				if(obj.sqImg){
+					this.annexList=JSON.parse(obj.sqImg);
+				}
+				else{
+					this.annexList=[];
+				}
+				if(this.actobj.collectPayment==0){
+					this.$refs.popqc.open('center');
+				}
+				else{
+					var that = this;
+					uni.showModal({
+					    title: that.$t('api.message'),
+					    content:that.$t('index.shoukuanwc'),
+						confirmText:that.$t('index.queren'),
+						cancelText:that.$t('index.quxiao'),
+					    success: function (res) {
+					        if (res.confirm) { //这里是点击了确定以后
+								that.$refs.popqc.open('center');
+					        } else { //这里是点击了取消以后
+					          console.log('点击取消')
+					        }
+					    }
+					})
+				}
+			},
+			
+			querensongda(){
+				
+				//还要同步上传图片
+				if(this.annexList.length==0){
+					uni.showToast({
+						title:this.$t('order.qingxiansctp'),
+						icon: 'none',
+						duration: 2500
+					})
+					return;
+				}
+				this.$refs.popqc.close();
+				var data={
+					id:this.actobj.id,
+					state:12,
+					qsImg:JSON.stringify(this.annexList)
+				}
+				this.$http.post(`${setorderuzt}`,data,true)
+				.then(r => {
+					console.log(r);
+					this.$emit('ErefleshList');
+				})
+				.catch(err => {
+					console.log(err)
+				})
+			},
+			quxiaoqc(){
+				this.$refs.popqc.close();
+			},
+			imagesel(index){
+				
+			},
+			updataImage(){
+				var that = this;
+				uni.showModal({
+				    title: that.$t('api.message'),
+				    content:that.$t('order.qingxuanz'),
+					confirmText:that.$t('order.qupaishe'),
+					cancelText:that.$t('order.qushangc'),
+				    success: function (res) {
+				        if (res.confirm) { //这里是点击了确定以后
+							that.getimage(2);
+				        } else { //这里是点击了取消以后
+				          console.log('点击取消')
+						  that.getimage(1)
+				        }
+				    }
+				})
+			},
+			getimage(state){
+				var sourceType=[];
+				if(state==1){
+					sourceType=['album']
+				}
+				else{
+					sourceType=['camera']
+				}
+				var that = this;
+				uni.chooseImage({
+					count: 1,  // 图片数量
+					sizeType: ['compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType:sourceType, //从相册选择或者拍照
+					success: (res) => {
+						const tempFilePaths = res.tempFilePaths;
+						uni.uploadFile({
+							url: that.$baseurl+UploadImage, //上传图片api
+							filePath: tempFilePaths[0],
+							name: 'file',
+							header:{
+								//"Authorization": userinfo.token
+							},
+							success: (res) => {
+								let group =  JSON.parse(res.data);
+								var l = that.annexList.length;
+								var temp = that.annexList;
+								temp.push(group.data);
+								that.annexList=temp;
+							}
+						});
+					}
+				});
+			},
+			callPhone(telphone,user){
+				var that = this;
+				uni.showModal({
+				    title: that.$t('api.message'),
+				    content:that.$t('api.nqdbddh'),
+					confirmText:that.$t('index.queren'),
+					cancelText:that.$t('index.quxiao'),
+				    success: function (res) {
+				        if (res.confirm) { //这里是点击了确定以后
+							console.log('打电话')
+							plus.device.dial(telphone, false );
+				        } else { //这里是点击了取消以后
+				          console.log('点击取消')
+				        }
+				    }
+				})
+			},
+			imCall(ddid,user){
+				var data = {
+					ddId:ddid,
+					userId:user.userId,
+					nickName:user.nickName,
+					avatar:user.avatar,
+					cid:user.cid
+				}
+				uni.setStorageSync('imUser',user);
+				uni.navigateTo({
+					url:'/pages/imcall/audioCall?caller=1'
+				})
+			},
+			Exchange(ddid,user){
+				console.log(ddid,user);
+				var data = {
+					ddId:ddid,
+					userId:user.userId,
+					nickName:user.nickName,
+					avatar:user.avatar,
+					cid:user.cid
+				}
+				uni.setStorageSync('imUser',data);
+				// uni.navigateTo({
+				// 	url:'/pages/imcall/ExchangeView?caller=1'
+				// })
+				uni.navigateTo({
+					url:'/pages/imcall/GoeasyExchange?caller=1'
+				})
+			},
+			setorderuzt(rId,state,){
+				var that = this;
+				var data;
+				if(state==3){
+					data={
+						id:rId,
+						state:state,
+						qsId:this.qsId
+					}
+				}
+				else{
+					data={
+						id:rId,
+						state:state,
+						// qsId:'',
+						// diningStatus:0
+						qsId:this.qsId,
+						diningStatus:1
+					}
+				}
+				this.$http.post(`${setorderuzt}`,data,true)
+				.then(r => {
+					console.log('setorderuzt',r);
+					this.$emit('ErefleshList');
+				})
+				.catch(err => {
+					console.log(err)
+				})
+			},
+			gotoNav(store){
+				console.log(store)
+				var navData={
+					latitude:parseFloat(store.latitude),
+					longitude:parseFloat(store.longitude),
+					address:store.address
+				}
+				console.log(navData)
+				var temp = JSON.stringify(navData);
+				uni.navigateTo({
+					url:'/pages/map/mapboxView?navdata='+temp
+				})
+				//this.handlePosition(store.latitude,store.longitude,store.address);
+			},
+			
+			
+			handlePosition(lat,lon,cityName) {
+				//如果是Andrios的设备
+				if (plus.os.name == 'Android') {
+					console.log('Android')
+					const hasBaiduMap = plus.runtime.isApplicationExist({
+						pname: 'com.baidu.BaiduMap',
+						action: 'baidumap://'
+					});
+					const hasAmap = plus.runtime.isApplicationExist({
+						pname: 'com.autonavi.minimap',
+						action: 'androidamap://'
+					});
+					const hasgoogle = plus.runtime.isApplicationExist({
+						pname: 'com.google.android.apps.maps',
+						action: 'comgooglemaps://'
+					});
+					
+					//重点是下面的url要根据官方给出的api进行对应,不同的需求对应不同的api
+					let urlBaiduMap =
+					'baidumap://map/direction?region=起点&destination='+lat+','+lon+'&coord_type=wgs84&mode=riding&src=andr.paotuiwang.qishou';
+					urlBaiduMap = encodeURI(urlBaiduMap)
+					let urlAmap =
+						'androidamap://viewMap?sourceApplication=appname&poiname='+cityName+'&lat='+lat+'&lon='+lon+'&dev=1';
+					urlAmap = encodeURI(urlAmap)
+					
+					
+					var buttons=[];
+					if(hasBaiduMap){
+						buttons.push({
+							title: this.$t('user.baiduNav'),
+							value:urlBaiduMap
+						})
+					}
+					if(hasAmap){
+						buttons.push({
+							title: this.$t('user.gaodeNav'),
+							value:urlAmap
+						})
+					}
+					// if(hasgoogle){
+					// 	buttons.push({title: this.$t('user.googleNav')})
+					// }
+					if(buttons.length==0){
+						if(hasgoogle){
+							var url = 'google.navigation:q=' + lat + ',' + lon;  //如果是国外应用,应该优先使用这个,会启动google地图。这个接口不能统一坐标系,进入百度地图时会有偏差
+							plus.runtime.openURL(url);
+							return;
+						}
+					}
+					
+					plus.nativeUI.actionSheet({
+						title: this.$t('user.xuanzedaoh'),
+						cancel: this.$t('index.quxiao'),
+						buttons: buttons
+					}, function(e) {
+						plus.runtime.openURL(buttons[e.index-1].value);
+					});
+				} else {
+					// iOS上获取本机是否安装了百度高德地图,需要在manifest里配置,在manifest.json文件app-plus->distribute->apple->urlschemewhitelist节点下添加(如urlschemewhitelist:["iosamap","baidumap"])
+					var url='';
+					var that = this;
+					plus.nativeUI.actionSheet({
+						title: this.$t('user.xuanzedaoh'),
+						cancel: this.$t('index.quxiao'),
+						buttons: [{
+							title: this.$t('user.baiduNav')
+						},{
+							title: this.$t('user.gaodeNav')
+						},{
+							title: this.$t('user.googleNav')
+						},{
+							title: this.$t('user.appleNav')
+						}]
+					}, function(e) {
+						switch (e.index) {
+							case 1:
+								url ='baidumap://map/marker?location='+lat+','+lon+'&title='+cityName+'&content='+cityName+'&coord_type=wgs84&src=ios.baidu.openAPIdemo';
+								break;
+							case 2:
+								url ='iosamap://path?sourceApplication=fuxishan_uni_client&dlat='+lat+'&dlon='+lon+'&dname='+cityName+'&dev=1&t=0';
+								break;
+							case 3:
+								url='comgooglemapsurl://?daddr='+ lat + ',' + lon;
+								break;
+							case 4:
+								url = 'http://maps.apple.com/?q=' +cityName + '&ll=' + lat + ',' + lon + '&spn=0.008766,0.019441';
+								break;
+							default:
+								break;
+						}
+						if (url!='') {
+							url = encodeURI(url)
+							plus.runtime.openURL(url, function(e) {
+							    plus.nativeUI.alert(that.$t('user.weianzhuangapp'));
+							});
+						}
+					})
+				}
+			},
+		},
+	}
+</script>
+
+<style lang="scss">
+	@import '@/common/common.scss';
+	@font-face {
+		font-family: zrht;
+		src: url('/uni_modules/font/zrht.otf');
+	}
+
+.itemV{
+	margin-top: 16rpx;
+	background-color: white;
+}
+.psfnote{
+	width: 92%;
+	margin-left: 4%;
+	margin-top: 5rpx;
+	border-radius: 10rpx;
+	background-color: crimson;
+}
+.spIcon{
+	width: 90rpx;
+	height: 90rpx;
+}
+
+.kouweisku{
+	color:chocolate;
+	padding-right: 12rpx;
+	font-size: 28rpx;
+}
+.qiangdImg{
+	width: 120rpx;
+	height: 120rpx;
+}
+
+.quhuodian{
+	font-size: 26rpx;
+	padding: 8rpx;
+	color: royalblue;
+	border-radius: 16rpx;
+	border: solid royalblue;
+}
+
+.shouhuodian{
+	font-size: 26rpx;
+	padding: 8rpx;
+	color: crimson;
+	border-radius: 16rpx;
+	border: solid crimson;
+}
+.lineimag{
+	display: flex;
+	flex-direction: column;
+	justify-content: space-between;
+	margin-left: 45rpx;
+	width: 4rpx;
+	background-color: lightgray;
+	height: 100rpx;
+	margin-top: 4rpx;
+	margin-bottom: 4rpx;
+}
+.yuandian{
+	width: 16rpx;
+	height: 16rpx;
+	background-color: lightgray;
+	border-radius: 8rpx;
+	margin-left: -8rpx;
+}
+
+.timeText{
+	font-size: 32rpx;
+	color: #006AFF;
+	padding-left: 20rpx;
+	font-weight: bold;
+}
+
+.priceText{
+	font-size: 30rpx;
+	color: crimson;
+	padding-right: 20rpx;
+}
+
+.titleText{
+	font-size: 28rpx;
+	/* font-family: zrht; */
+}
+
+.pnametext{
+	overflow: hidden;
+	text-overflow: ellipsis;
+	display: -webkit-box;
+	-webkit-line-clamp: 1;
+	-webkit-box-orient: vertical;
+}
+
+.distenText{
+	font-size: 26rpx;
+	color: darkgray;
+	padding-left: 20rpx;
+}
+
+.addrText{
+	font-size: 28rpx;
+	color: dimgray;
+}
+
+.stateText{
+	font-size: 28rpx;
+	color: darkgray;
+	padding: 8rpx;
+	border: solid darkgray;
+	border-radius: 8rpx;
+	
+}
+
+.noteText{
+	margin-top: 16rpx;
+	font-size: 28rpx;
+	color: dimgray;
+	padding: 8rpx;
+	background-color: whitesmoke;
+	border-radius: 8rpx;
+}
+
+.connectText{
+	font-size: 28rpx;
+	color: black;
+	padding-left: 8rpx;
+	padding-right: 8rpx;
+	padding-top: 2rpx;
+	padding-bottom: 2rpx;
+	border: 2rpx solid darkgray;
+	border-radius: 8rpx;
+	
+}
+
+.setImg{
+	width: 30rpx;
+	height: 30rpx;
+}
+
+.setImgB{
+	width: 40rpx;
+	height: 40rpx;
+}
+
+
+.jiedanText{
+	font-size: 24rpx;
+	color: black;
+}
+
+.jiedanTextS{
+	font-size: 20rpx;
+	color: black;
+}
+
+.wanchengV{
+	width: 480rpx;
+	height: 68rpx;
+	border-radius: 10rpx;
+	background-color: crimson;
+}
+
+.wanchengT{
+	padding-left: 20rpx;
+	padding-right: 20rpx;
+	line-height: 68rpx;
+	font-weight: bold;
+	font-size: 26rpx;
+	color: white;
+	border-radius: 10rpx;
+	text-align: center;
+}
+
+.jiedanBtdf{
+	padding: 10rpx;
+	color:white;
+	background-color: #1A1A1A;
+	border-radius: 8rpx;
+	box-shadow: 0rpx 0rpx 2rpx 0rpx #1A1A1A;
+}
+.item_list{
+	display: flex;
+	flex-wrap: wrap;
+	justify-content: flex-start;
+	.item_content{
+		width:180rpx;
+		height:180rpx;
+		margin: 10rpx;
+		box-sizing: border-box;
+	}
+}
+.upimagV{
+	width: 180rpx;
+	height:180rpx;
+}
+.actbttext{
+	width: 50%;
+	line-height: 66rpx;
+	font-size: 28rpx;
+	color: white;
+	text-align: center;
+}
+</style>

+ 534 - 0
components/orderItemC/orderItemC.vue

@@ -0,0 +1,534 @@
+<template>
+	<view style="background-color: whitesmoke;">
+		<view class="itemV content" v-for="(item,indexo) in orderList">
+			<view class="contentInRowS">
+				<text class="timeText">{{item.ddId}}</text>
+				<text v-if="item.collectPayment==1" class="jiedanBtdf" style="font-size: 24rpx;">{{$t('index.huodaofukan')}}</text>
+			</view>
+			<view class="contentColumn">
+				<view class="contentInRowL">
+					<text class="titleText" style="margin-left:20rpx;">{{$t('order.peisongfei')}}: {{$formPr(item.freight)}}{{$t('api.huobidanwei')}}</text>
+				</view>
+				<view class="contentInRowR">
+					<text class="priceText" >{{$t('order.dingdanjin')}}: {{$formPr(item.amount)}}{{$t('api.huobidanwei')}}</text>
+				</view>
+			</view>
+			<view v-if="youyouhui(item)" class="contentInRowL" style="margin-left:20rpx;">
+				<text class="titleText">{{$t('order.youhuijine')}}:</text>
+				<text class="titleText" style="padding-left: 20rpx;">{{getyhjr(item)}}</text>
+			</view>
+			<view style="width: 100%;margin-top: 20rpx;margin-left: 20rpx;" class="contentInRowL">
+				<view v-if="item.store" class="contentColumn">
+					<view>
+						<text class="quhuodian">{{$t('order.quhuodian')}}</text>
+					</view>
+					<view style="margin-top: 20rpx;margin-left: 10rpx;width: 94%;">
+						<text class="titleText">{{item.store.posName}}</text>
+					</view>
+				</view>
+			</view>
+			
+			<view style="margin-left: 20rpx;margin-top: 20rpx;" class="contentInRowL">
+				<view style="width: 100rpx" class="contentColumn">
+					<text class="shouhuodian">{{$t('order.shouhuodian')}}</text>
+				</view>
+				<view style="margin-left: 20rpx;width: 80%;" class="contentColumn">
+					<view v-if="item.shaddress!=null" @click="openBimg(item.shaddress.annexes)">
+						<view class="contentInRowL">
+							<text class="titleText">{{item.shaddress.name}}</text>
+							<text class="distenText">({{$t('order.juli')}}{{item.jvli}}Km)</text>
+						</view>
+						<text class="addrText">{{item.shaddress.address}}</text>
+						<text v-if="item.remarks!=''" class="noteText">{{item.remarks}}</text>
+					</view>
+					
+					<view v-for="(itemf,index) in item.food">
+						<view class="contentInRowL" style="margin-top: 12rpx;">
+							<myImage class="spIcon" :mysrc="itemf.image" mymode="scaleToFill" ></myImage>
+							<view class="contentColumn" style="margin-left: 10rpx;width: 78%;">
+								<text class="addrText">{{itemf.name}}</text>
+								<view class="contentInRowS">
+									<view class="contentInRowL ">
+										<text class="kouweisku" v-for="sku in itemf.ask">{{sku}}</text>
+									</view>
+									<text class="addrText">{{itemf.number}}(份)</text>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view v-if="youyouhui(item)" class="contentColumnC psfnote">
+				<text class="addrText" style="color:white;padding: 6rpx;">{{$t('order.qishouyhts')}}</text>
+			</view>
+			<view class="contentInRowS" style="width: 90%;margin-top: 20rpx;margin-left: 5%;">
+				<text class="addrText">{{$t('zhanghu.zhuangtai')}}:{{getStateStr(item)}}</text>
+			</view>
+			<view class="contentInRowS" style="width: 90%;margin-top: 20rpx;margin-left: 5%;">
+				<view class="wanchengT" style="background-color: crimson;" @click="chakantp(item)">{{$t('order.chakantp')}}</view>
+				<view class="wanchengT" style="background-color:#006AFF;" @click="gotoMsgList(item)">{{$t('order.lianxikef')}}</view>
+			</view>
+			<view v-if="item.shaddress!=null" class="contentInRowS" style="align-items: flex-start;">
+				<view class="contentColumnC" style="margin:20rpx;padding-left: 10rpx;" @click="callPhone(item.shaddress.phone,item.user)">
+					<uni-icons custom-prefix="custom-icon" color="#006AFF" type="phone-filled" size="28"></uni-icons>
+					<label class="jiedanText">{{$t('order.lianxi')}}</label>
+				</view>
+				<view class="contentColumnC" style="margin:20rpx;padding-right: 10rpx;" @click="gotoNav(item.shaddress)">
+					<uni-icons custom-prefix="custom-icon" color="#006AFF" type="navigate-filled" size="28"></uni-icons>
+					<label class="jiedanText">Navigation</label>
+				</view>
+				<view v-if="canopenBimg(item.shaddress.annexes)" class="contentColumnC" style="margin:20rpx;padding-left: 10rpx;" @click="openBimg(item.shaddress.annexes)">
+					<uni-icons custom-prefix="custom-icon" color="#006AFF" type="home" size="28"></uni-icons>
+					<label class="jiedanText">{{$t('order.menpaizp')}}</label>
+				</view>
+				<view class="contentColumnC" style="margin:20rpx;padding-left: 10rpx;" @click="Exchange(item.ddId,item.user)">
+					<uni-icons custom-prefix="custom-icon" color="#006AFF" type="chatboxes" size="28"></uni-icons>
+					<label class="jiedanText">{{$t('exchange.xinxi')}}</label>
+				</view>
+				<view class="contentColumnC" style="margin:20rpx;padding-left: 10rpx;" @click="imCall(item.ddId,item.user)">
+					<uni-icons custom-prefix="custom-icon" color="#006AFF" type="phone" size="28"></uni-icons>
+					<label class="jiedanText">IM Call</label>
+				</view>
+			</view>
+		</view>
+		
+	</view>
+</template>
+
+<script>
+	import {
+		setorderuzt,
+		setLocat
+	} from '@/pages/api/basic';
+	export default {
+		name:"orderItem",
+		props:{
+			orderList:'',
+			qsId:''
+		},
+		data() {
+			return {
+				isAndroid:true
+			};
+		},
+		mounted() {
+			let systemInfo = uni.getSystemInfoSync();
+			this.isAndroid = systemInfo.platform.toLowerCase() === 'android';
+			console.log('mounted------------------')
+		},
+		methods:{
+			youyouhui(obj){
+				if(obj.mdSalesReduction){
+					return true;
+				}
+				if(obj.mdDiscountAmount){
+					return true;
+				}
+				if(obj.discountAmount){
+					return true;
+				}
+				if(obj.salesReduction){
+					return true;
+				}
+				
+				return false;
+			},
+			
+			getyhjr(obj){
+				var jinr=0;
+				if(obj.mdSalesReduction){
+					jinr=obj.mdSalesReduction;
+				}
+				if(obj.mdDiscountAmount){
+					jinr=jinr+obj.mdDiscountAmount;
+				}
+				if(obj.discountAmount){
+					jinr=jinr+obj.discountAmount;
+				}
+				if(obj.salesReduction){
+					jinr=jinr+obj.salesReduction;
+				}
+				jinr=parseInt(jinr);
+				return '-'+this.$formPr(jinr)+this.$t('api.huobidanwei');
+			},
+			getStateStr(obj){
+				if(obj.kefuState==0){
+					 return this.$t('order.kefujs');
+				}
+				else{
+					if(obj.kefuRepeat==0){
+						if(obj.kefuState==1){
+							return this.$t('order.yishouli');
+						}
+						if(obj.kefuState==2){
+							return this.$t('order.shouhwc');
+						}
+					}
+					else{
+						if(obj.repeatDdId){
+							return this.$t('order.chongpaidd')+':'+obj.repeatDdId;
+						}
+						else{
+							return this.$t('order.chongpaidd');
+						}
+					}
+				}
+			},
+			gotoMsgList(obj){
+				uni.navigateTo({
+					url:'/pages/kehufuwu/kefuMsgList?ddId='+obj.ddId
+				})
+			},
+			chakantp(obj){
+				var data={
+					id:'',
+					img:'[]'
+				}
+				if(obj.sqImg){
+					data.img=obj.sqImg;
+				}
+				uni.navigateTo({
+					url:'/pages/index/GoodsImages?obj='+JSON.stringify(data)
+				})
+			},
+			canopenBimg(mysrc){
+				if(!mysrc){
+					return false;
+				}
+				if(mysrc.length<8){
+					return false;
+				}
+				return true;
+			},
+			openBimg(mysrc){
+				
+				if(!mysrc){
+					return;
+				}
+				if(mysrc.length<8){
+					return;
+				}
+				console.log(mysrc);
+				uni.navigateTo({
+					url:'/pages/index/BigimageView?mysrc='+mysrc
+				})
+			},
+			jiedan(id){
+				var online = getApp().globalData.isOnline;
+				if(!online){
+					uni.showToast({
+					    title: this.$t('user.xiaxianzh'),
+					    icon: 'none',
+					    duration: 2500
+					})
+					return;
+				}
+				
+				if(this.qsId<=0 ||''==this.qsId){
+					uni.showToast({
+					    title: this.$t('user.denglushixiao'),
+					    icon: 'none',
+					    duration: 2500
+					})
+					return;
+				}
+				this.setorderuzt(id,3)
+			},
+			quchan(id){
+				this.setorderuzt(id,4)
+			},
+			wancheng(obj){
+				if(obj.collectPayment==0){
+					this.setorderuzt(obj.id,5);
+				}
+				else{
+					var that = this;
+					uni.showModal({
+					    title: that.$t('api.message'),
+					    content:that.$t('index.shoukuanwc'),
+						confirmText:that.$t('index.queren'),
+						cancelText:that.$t('index.quxiao'),
+					    success: function (res) {
+					        if (res.confirm) { //这里是点击了确定以后
+								console.log('打电话')
+								that.setorderuzt(obj.id,5)
+					        } else { //这里是点击了取消以后
+					          console.log('点击取消')
+					        }
+					    }
+					})
+				}
+			},
+			callPhone(telphone,user){
+				var that = this;
+				uni.showModal({
+				    title: that.$t('api.message'),
+				    content:that.$t('api.nqdbddh'),
+					confirmText:that.$t('index.queren'),
+					cancelText:that.$t('index.quxiao'),
+				    success: function (res) {
+				        if (res.confirm) { //这里是点击了确定以后
+							console.log('打电话')
+							plus.device.dial(telphone, false );
+				        } else { //这里是点击了取消以后
+				          console.log('点击取消')
+				        }
+				    }
+				})
+			},
+			imCall(ddid,user){
+				var data = {
+					ddId:ddid,
+					userId:user.userId,
+					nickName:user.nickName,
+					avatar:user.avatar,
+					cid:user.cid
+				}
+				uni.setStorageSync('imUser',user);
+				uni.navigateTo({
+					url:'/pages/imcall/audioCall?caller=1'
+				})
+			},
+			Exchange(ddid,user){
+				console.log(ddid,user);
+				var data = {
+					ddId:ddid,
+					userId:user.userId,
+					nickName:user.nickName,
+					avatar:user.avatar,
+					cid:user.cid
+				}
+				uni.setStorageSync('imUser',data);
+				// uni.navigateTo({
+				// 	url:'/pages/imcall/ExchangeView?caller=1'
+				// })
+				uni.navigateTo({
+					url:'/pages/imcall/GoeasyExchange?caller=1'
+				})
+			},
+			async setorderuzt(rId,state,){
+				var that = this;
+				var data;
+				if(state==3){
+					data={
+						id:rId,
+						state:state,
+						qsId:this.qsId
+					}
+				}
+				else{
+					data={
+						id:rId,
+						state:state,
+						qsId:this.qsId,
+						diningStatus:1
+					}
+				}
+				await this.$http.post(`${setorderuzt}`,data,true)
+				.then(async r => {
+					console.log(r);
+					this.$emit('ErefleshList');
+				})
+				.catch(err => {
+					console.log(err)
+				})
+			},
+			gotoNav(store){
+				var navData={
+					latitude:parseFloat(store.latitude),
+					longitude:parseFloat(store.longitude),
+					address:store.address
+				}
+				var temp = JSON.stringify(navData);
+				
+				uni.navigateTo({
+					url:'/pages/map/mapboxView?navdata='+temp
+				})
+				//this.handlePosition(store.latitude,store.longitude,store.address);
+			},
+		},
+	}
+</script>
+
+<style>
+	@import '@/common/common.scss';
+	@font-face {
+		font-family: zrht;
+		src: url('/uni_modules/font/zrht.otf');
+	}
+
+.itemV{
+	margin-top: 16rpx;
+	background-color: white;
+}
+.psfnote{
+	width: 92%;
+	margin-left: 4%;
+	margin-top: 5rpx;
+	border-radius: 10rpx;
+	background-color: crimson;
+}
+.spIcon{
+	width: 90rpx;
+	height: 90rpx;
+}
+
+.kouweisku{
+	color:chocolate;
+	padding-right: 12rpx;
+	font-size: 28rpx;
+}
+.qiangdImg{
+	width: 120rpx;
+	height: 120rpx;
+}
+
+.quhuodian{
+	font-size: 26rpx;
+	padding: 8rpx;
+	color: royalblue;
+	border-radius: 16rpx;
+	border: solid royalblue;
+}
+
+.shouhuodian{
+	font-size: 26rpx;
+	padding: 8rpx;
+	color: crimson;
+	border-radius: 16rpx;
+	border: solid crimson;
+}
+.lineimag{
+	display: flex;
+	flex-direction: column;
+	justify-content: space-between;
+	margin-left: 45rpx;
+	width: 4rpx;
+	background-color: lightgray;
+	height: 100rpx;
+	margin-top: 4rpx;
+	margin-bottom: 4rpx;
+}
+.yuandian{
+	width: 16rpx;
+	height: 16rpx;
+	background-color: lightgray;
+	border-radius: 8rpx;
+	margin-left: -8rpx;
+}
+
+.timeText{
+	font-size: 32rpx;
+	color: #006AFF;
+	padding-left: 20rpx;
+	font-weight: bold;
+}
+
+.priceText{
+	font-size: 30rpx;
+	color: crimson;
+	padding-right: 20rpx;
+}
+
+.titleText{
+	font-size: 28rpx;
+	/* font-family: zrht; */
+}
+
+.pnametext{
+	overflow: hidden;
+	text-overflow: ellipsis;
+	display: -webkit-box;
+	-webkit-line-clamp: 1;
+	-webkit-box-orient: vertical;
+}
+
+.distenText{
+	font-size: 26rpx;
+	color: darkgray;
+	padding-left: 20rpx;
+}
+
+.addrText{
+	font-size: 28rpx;
+	color: dimgray;
+}
+
+.stateText{
+	font-size: 28rpx;
+	color: darkgray;
+	padding: 8rpx;
+	border: solid darkgray;
+	border-radius: 8rpx;
+	
+}
+
+.noteText{
+	margin-top: 16rpx;
+	font-size: 28rpx;
+	color: dimgray;
+	padding: 8rpx;
+	background-color: whitesmoke;
+	border-radius: 8rpx;
+}
+
+.connectText{
+	font-size: 28rpx;
+	color: black;
+	padding-left: 8rpx;
+	padding-right: 8rpx;
+	padding-top: 2rpx;
+	padding-bottom: 2rpx;
+	border: 2rpx solid darkgray;
+	border-radius: 8rpx;
+	
+}
+
+.setImg{
+	width: 30rpx;
+	height: 30rpx;
+}
+
+.setImgB{
+	width: 40rpx;
+	height: 40rpx;
+}
+
+
+.jiedanText{
+	font-size: 24rpx;
+	color: black;
+}
+
+.jiedanTextS{
+	font-size: 20rpx;
+	color: black;
+}
+
+.wanchengV{
+	width: 480rpx;
+	height: 68rpx;
+	border-radius: 10rpx;
+	background-color: crimson;
+}
+
+.wanchengT{
+	padding-left: 20rpx;
+	padding-right: 20rpx;
+	line-height: 68rpx;
+	font-weight: bold;
+	font-size: 26rpx;
+	color: white;
+	border-radius: 10rpx;
+	text-align: center;
+}
+
+.jiedanBtdf{
+	padding: 10rpx;
+	color:white;
+	background-color: #1A1A1A;
+	border-radius: 8rpx;
+	box-shadow: 0rpx 0rpx 2rpx 0rpx #1A1A1A;
+}
+	
+</style>

+ 173 - 0
components/popViewA/popViewA.vue

@@ -0,0 +1,173 @@
+<template>
+	<view>
+		<view class="tui-actionsheet-mask" :class="[show?'tui-mask-show':'']" @tap="handleClickMask"></view>
+		<view class="tui-actionsheet-class tui-actionsheet" :class="[show?'tui-actionsheet-show':'']">
+			<view class="tui-tips" :style="{fontSize:size+'rpx',color:color}" v-if="tips">
+				{{tips}}
+			</view>
+			<view :class="[isCancel?'tui-operate-box':'']">
+				<block v-for="(item,index) in itemList" :key="index">
+					<view class="tui-actionsheet-btn tui-actionsheet-divider"
+						:class="[(!isCancel && index==itemList.length-1)?'tui-btn-last':'']"
+						hover-class="tui-actionsheet-hover" :hover-stay-time="150" :data-index="index"
+						:style="{color:item.color || '#1a1a1a'}" @tap="handleClickItem">{{item.text}}</view>
+				</block>
+			</view>
+			<view class="tui-actionsheet-btn tui-actionsheet-cancel" hover-class="tui-actionsheet-hover"
+				:hover-stay-time="150" v-if="isCancel" @tap="handleClickCancel">{{$t('index.quxiao')}}</view>
+		</view>
+	</view>
+</template>
+ 
+<script>
+	export default {
+		name: "tuiActionsheet",
+		props: {
+			//点击遮罩 是否可关闭
+			maskClosable: {
+				type: Boolean,
+				default: true
+			},
+			//显示操作菜单
+			show: {
+				type: Boolean,
+				default: false
+			},
+			//菜单按钮数组,自定义文本颜色,红色参考色:#e53a37
+			itemList: {
+				type: Array,
+				default: function() {
+					return [{
+						text:this.$t('order.queding'),
+						color: "#1a1a1a"
+					}]
+				}
+			},
+			//提示文字
+			tips: {
+				type: String,
+				default: ""
+			},
+			//提示文字颜色
+			color: {
+				type: String,
+				default: "#9a9a9a"
+			},
+			//提示文字大小 rpx
+			size: {
+				type: Number,
+				default: 26
+			},
+			//是否需要取消按钮
+			isCancel: {
+				type: Boolean,
+				default: true
+			}
+		},
+		methods: {
+			handleClickMask() {
+				if (!this.maskClosable) return;
+				this.handleClickCancel();
+			},
+			handleClickItem(e) {
+				if (!this.show) return;
+				const dataset = e.currentTarget.dataset;
+				this.$emit('Itemclick', dataset.index);
+			},
+			handleClickCancel() {
+				this.$emit('chooseCancel');
+			}
+		}
+	}
+</script>
+ 
+<style>
+	.tui-actionsheet {
+		width:750upx;
+		position: fixed;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		z-index: 9999;
+		visibility: hidden;
+		transform: translate3d(0, 100%, 0);
+		transform-origin: center;
+		transition: all 0.3s ease-in-out;
+		background: #eaeaec;
+		min-height: 100rpx;
+	}
+ 
+	.tui-actionsheet-show {
+		transform: translate3d(0, 0, 0);
+		visibility: visible;
+	}
+ 
+	.tui-tips {
+		width:750upx;
+		padding: 30rpx 60rpx;
+		box-sizing: border-box;
+		text-align: center;
+		background: #fff;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+	}
+ 
+	.tui-operate-box {
+		padding-bottom: 12rpx;
+	}
+ 
+	.tui-actionsheet-btn {
+		width:750upx;
+		height: 100rpx;
+		background: #fff;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		text-align: center;
+		font-size: 36rpx;
+		position: relative;
+	}
+ 
+	.tui-btn-last {
+		padding-bottom: env(safe-area-inset-bottom);
+	}
+ 
+	.tui-actionsheet-divider::before {
+		content: '';
+		width:750upx;
+		border-top: 1rpx solid #d9d9d9;
+		position: absolute;
+		top: 0;
+		left: 0;
+		-webkit-transform: scaleY(0.5);
+		transform: scaleY(0.5);
+	}
+ 
+	.tui-actionsheet-cancel {
+		color: #1a1a1a;
+		padding-bottom: env(safe-area-inset-bottom);
+	}
+ 
+	.tui-actionsheet-hover {
+		background: #f7f7f9;
+	}
+ 
+	.tui-actionsheet-mask {
+		position: fixed;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		background: rgba(0, 0, 0, 0.6);
+		z-index: 9996;
+		transition: all 0.3s ease-in-out;
+		opacity: 0;
+		visibility: hidden;
+	}
+ 
+	.tui-mask-show {
+		opacity: 1;
+		visibility: visible;
+	}
+</style>

+ 235 - 0
components/popViewGG/popViewGG.vue

@@ -0,0 +1,235 @@
+<template>
+	<view>
+		<view class="tui-actionsheet-mask" :class="[show?'tui-mask-show':'']" @tap="handleClickMask"></view>
+		<view class="tui-actionsheet-class tui-actionsheet" :class="[show?'tui-actionsheet-show':'']">
+			<view class="tui-tips" :style="{fontSize:size+'rpx',color:color}" v-if="tips">
+				{{tips}}
+			</view>
+			<view :class="[isCancel?'tui-operate-box':'tui-operate-boxN']">
+				<slot></slot>
+			</view>
+			<view v-if="showbotom">
+				<view class="tui-actionsheet-btn tui-actionsheet-cancel" hover-class="tui-actionsheet-hover"
+					:hover-stay-time="150" v-if="isCancel" @tap="handleClickCancel(1)">{{acttips}}</view>
+			</view>
+			
+		</view>
+	</view>
+</template>
+ 
+<script>
+	export default {
+		name: "tuiActionsheet",
+		props: {
+			//点击遮罩 是否可关闭
+			maskClosable: {
+				type: Boolean,
+				default: true
+			},
+			//显示操作菜单
+			show: {
+				type: Boolean,
+				default: false
+			},
+			//菜单按钮数组,自定义文本颜色,红色参考色:#e53a37
+			itemList:{},
+			//提示文字
+			tips: {
+				type: String,
+				default: ""
+			},
+			//提示文字
+			acttips: {
+				type: String,
+				default: "Hoàn thành"
+			},
+			//提示文字颜色
+			color: {
+				type: String,
+				default: "#9a9a9a"
+			},
+			//提示文字大小 rpx
+			size: {
+				type: Number,
+				default: 26
+			},
+			//是否需要取消按钮
+			isCancel: {
+				type: Boolean,
+				default: true
+			},
+			//是否需要底部按钮
+			showbotom: {
+				type: Boolean,
+				default: true
+			},
+			
+		},
+		watch: {
+			show(val){
+				if(val){
+					// 背景不可滚动
+					//document.body.style.overflow='hidden';
+				}
+				else{
+					// 背景可滚动
+					//document.body.style.overflow='';
+				}
+			}
+		},
+		methods: {
+			handleClickMask() {
+				if (!this.maskClosable) return;
+				this.handleClickCancel(0);
+			},
+			handleClickItem(e) {
+				if (!this.show) return;
+				const dataset = e.currentTarget.dataset;
+				this.$emit('click', {
+					index: dataset.index
+				});
+			},
+			
+			selectGuige(index,name){
+				this.$emit('EselectGuige',index,name);
+			},
+			
+			handleClickCancel(index) {
+				this.$emit('chooseCancel',index);
+			}
+		}
+	}
+</script>
+ 
+<style>
+	.tui-actionsheet {
+		width:750upx;
+		position: fixed;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		z-index: 9999;
+		visibility: hidden;
+		transform: translate3d(0, 100%, 0);
+		transform-origin: center;
+		transition: all 0.3s ease-in-out;
+		background: #eaeaec;
+		min-height: 100rpx;
+	}
+ 
+	.tui-actionsheet-show {
+		transform: translate3d(0, 0, 0);
+		visibility: visible;
+	}
+ 
+	.tui-tips {
+		width:750upx;
+		padding: 30rpx 60rpx;
+		box-sizing: border-box;
+		text-align: center;
+		background: #fff;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+	}
+ 
+	.tui-operate-box {
+		padding-bottom: 12rpx;
+		max-height: 70vh;
+		overflow: scroll;
+	}
+	.tui-operate-boxN {
+		max-height: 70vh;
+		overflow: scroll;
+	}
+ 
+	.tui-actionsheet-btn {
+		width:750upx;
+		height: 100rpx;
+		background: #fff;
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		text-align: center;
+		font-size: 36rpx;
+		position: relative;
+	}
+ 
+	.tui-btn-last {
+		padding-bottom: env(safe-area-inset-bottom);
+	}
+ 
+	.tui-actionsheet-divider::before {
+		content: '';
+		width:750upx;
+		border-top: 1rpx solid #d9d9d9;
+		position: absolute;
+		top: 0;
+		left: 0;
+		-webkit-transform: scaleY(0.5);
+		transform: scaleY(0.5);
+	}
+ 
+	.tui-actionsheet-cancel {
+		color: #1a1a1a;
+		padding-bottom: env(safe-area-inset-bottom);
+	}
+ 
+	.tui-actionsheet-hover {
+		background: #f7f7f9;
+	}
+ 
+	.tui-actionsheet-mask {
+		position: fixed;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		background: rgba(0, 0, 0, 0.6);
+		z-index: 9996;
+		transition: all 0.3s ease-in-out;
+		opacity: 0;
+		visibility: hidden;
+	}
+ 
+	.tui-mask-show {
+		opacity: 1;
+		visibility: visible;
+	}
+	
+	.skuViewCt{
+		display: flex;
+		flex-direction: column;
+		justify-content:center;
+		width: 100%;
+		margin-top: 10rpx;
+	}
+	
+	.contensbgg{
+		display: flex;
+		flex-wrap: wrap;
+		justify-content:flex-start;
+		align-items:center;
+	}
+	
+	.guigeleixing{
+		font-size: 26rpx;
+		line-height: 40rpx;
+		height: 40rpx;
+		color: black;
+		font-weight: bold;
+	}
+	.youhuixinxi{
+		margin: 8rpx;
+		padding: 4rpx;
+		font-size: 26rpx;
+		line-height: 54rpx;
+		height: 54rpx;
+		border: 2rpx solid lightgray;
+		border-radius: 8rpx;
+	}
+	.xz{
+		background-color: #ff0000;
+	}
+	
+</style>

+ 78 - 0
components/scrollViewR/scrollViewR.vue

@@ -0,0 +1,78 @@
+<template>
+	<view>
+		<view style="width: 90%;margin-left: 5%;margin-top: 20rpx;margin-bottom: 20rpx;">
+			<view v-if="showTitle" class="titleText">
+				<text>{{title}}</text>
+			</view>
+			<scroll-view scroll-x="true" class="ScontenView">
+				<view class="contentInRowL">
+					<view  v-for="(item,index) in itemList">
+						<view class="contentColumnC" style="width: 200rpx;padding-right: 12rpx" @click="itemSelect(index)">
+							<image class="itemImage" :src="item.imagStr" mode="widthFix"></image>
+							<text class="itemTitle">{{item.title}}</text>
+						</view>
+					</view>
+				</view>
+			</scroll-view>
+		</view>
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		name:"scrollViewR",
+		props:{
+			title:'',
+			itemList:'',
+			showTitle:false
+		},
+		data() {
+			return {
+				
+			};
+		},
+		methods: {
+			itemSelect(index){
+				this.$emit('EitemSelect',index);
+			},
+		},
+	}
+</script>
+
+<style lang="scss">
+@font-face {
+	font-family: zrht;
+	src: url('/uni_modules/font/zrht.otf');
+}
+.titleText{
+	// font-family: zrht;
+	font-size: 28rpx;
+	color: #1A1A1A;
+	margin-top: 20rpx;
+	margin-bottom: 20rpx;
+}
+
+.ScontenView{
+	display: flex;
+	flex-direction: row;
+	justify-content: space-between;
+	align-items: center;
+}
+
+.contentColumn{
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+}
+.itemImage{
+	width: 50rpx;
+}
+.itemTitle{
+	font-size: 26rpx;
+	color: #1A1A1A;
+	text-align: center;
+}
+
+</style>

+ 974 - 0
components/yhdsl-cropper/yhdsl-cropper.vue

@@ -0,0 +1,974 @@
+<template>
+	<view class="yhdsl" v-show="isShow">
+		<view>
+			<view class="cropper-content">
+				<view v-if="isShowImg" class="uni-corpper"
+					:style="'width:' + cropperInitW + 'px;height:' + cropperInitH + 'px;background:#000'">
+					<view class="uni-corpper-content" :style="
+							'width:' +
+								cropperW +
+								'px;height:' +
+								cropperH +
+								'px;left:' +
+								cropperL +
+								'px;top:' +
+								cropperT +
+								'px'
+						">
+						<image :src="imageSrc" :style="'width:' + cropperW + 'px;height:' + cropperH + 'px'"></image>
+						<view class="uni-corpper-crop-box" @touchstart.stop="contentStartMove"
+							@touchmove.stop="contentMoveing" @touchend.stop="contentTouchEnd" :style="
+								'left:' + cutL + 'px;top:' + cutT + 'px;right:' + cutR + 'px;bottom:' + cutB + 'px'
+							">
+							<view class="uni-cropper-view-box">
+								<view class="uni-cropper-dashed-h"></view>
+								<view class="uni-cropper-dashed-v"></view>
+ 
+								<!-- 截图区域顶部 -->
+								<view class="uni-cropper-line-t" data-drag="top" @touchstart.stop="dragStart"
+									@touchmove.stop="dragMove"></view>
+ 
+								<!-- 截图区域右侧 -->
+								<view class="uni-cropper-line-r" data-drag="right" @touchstart.stop="dragStart"
+									@touchmove.stop="dragMove"></view>
+ 
+								<!-- 截图区域底部 -->
+								<view class="uni-cropper-line-b" data-drag="bottom" @touchstart.stop="dragStart"
+									@touchmove.stop="dragMove"></view>
+ 
+								<!-- 截图区域左侧 -->
+								<view class="uni-cropper-line-l" data-drag="left" @touchstart.stop="dragStart"
+									@touchmove.stop="dragMove"></view>
+ 
+								<!-- 右下角截图滑块 -->
+								<view class="uni-cropper-point point-t" data-drag="top" @touchstart.stop="dragStart"
+									@touchmove.stop="dragMove"></view>
+								<view class="uni-cropper-point point-tr" data-drag="topTight"></view>
+								<view class="uni-cropper-point point-r" data-drag="right" @touchstart.stop="dragStart"
+									@touchmove.stop="dragMove"></view>
+								<view class="uni-cropper-point point-rb" data-drag="rightBottom"
+									@touchstart.stop="dragStart" @touchmove.stop="dragMove"></view>
+								<view class="uni-cropper-point point-b" data-drag="bottom" @touchstart.stop="dragStart"
+									@touchmove.stop="dragMove" @touchend.stop="dragEnd"></view>
+								<view class="uni-cropper-point point-bl" data-drag="bottomLeft"></view>
+								<view class="uni-cropper-point point-l" data-drag="left" @touchstart.stop="dragStart"
+									@touchmove.stop="dragMove"></view>
+								<view class="uni-cropper-point point-lt" data-drag="leftTop"></view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="cropper-config">
+				<view class="button-box">
+					<button type="warn" @click="chooseImage">{{$t('order.chongxuan')}}</button>
+					<!-- <button type="warn" @click="previewImg">预览</button> -->
+					<button type="warn" @click="finish">{{$t('order.wancheng')}}</button>
+				</view>
+			</view>
+			<canvas canvas-id="myCanvas" :style="
+					'position:absolute;border: 2px solid red; width:' +
+						imageW +
+						'px;height:' +
+						imageH +
+						'px;top:-9999px;left:-9999px;'
+				"></canvas>
+		</view>
+	</view>
+</template>
+ 
+<script>
+	let sysInfo = uni.getSystemInfoSync();
+	let SCREEN_WIDTH = sysInfo.screenWidth;
+	let SCREEN_HEIGHT = sysInfo.windowHeight + 40;
+	let PAGE_X, // 手按下的x位置
+		PAGE_Y, // 手按下y的位置
+		PR = sysInfo.pixelRatio, // dpi
+		T_PAGE_X, // 手移动的时候x的位置
+		T_PAGE_Y, // 手移动的时候Y的位置
+		CUT_L, // 初始化拖拽元素的left值
+		CUT_T, // 初始化拖拽元素的top值
+		CUT_R, // 初始化拖拽元素的
+		CUT_B, // 初始化拖拽元素的
+		CUT_W, // 初始化拖拽元素的宽度
+		CUT_H, //  初始化拖拽元素的高度
+		IMG_RATIO, // 图片比例
+		IMG_REAL_W, // 图片实际的宽度
+		IMG_REAL_H, // 图片实际的高度
+		DRAFG_MOVE_RATIO = 1, //移动时候的比例,
+		INIT_DRAG_POSITION = 100, // 初始化屏幕宽度和裁剪区域的宽度之差,用于设置初始化裁剪的宽度
+		DRAW_IMAGE_W = sysInfo.screenWidth; // 设置生成的图片宽度
+	export default {
+		/**
+		 * 页面的初始数据
+		 */
+		data() {
+			return {
+				imageSrc: "",
+				isShow: false,
+				isShowImg: false,
+				// 初始化的宽高
+				cropperInitW: SCREEN_WIDTH,
+				cropperInitH: SCREEN_HEIGHT,
+				// 动态的宽高
+				cropperW: SCREEN_WIDTH,
+				cropperH: SCREEN_HEIGHT - 100,
+				// 动态的left top值
+				cropperL: 0,
+				cropperT: 0,
+				transL: 0,
+				transT: 0,
+				// 图片缩放值
+				scaleP: 0,
+				imageW: 0,
+				imageH: 0,
+				// 裁剪框 宽高
+				cutL: 0,
+				cutT: 0,
+				cutB: SCREEN_WIDTH,
+				cutR: "100%",
+				qualityWidth: DRAW_IMAGE_W,
+				innerAspectRadio: DRAFG_MOVE_RATIO,
+			};
+		},
+		props: {
+			/* 截图质量,压缩比  */
+			quality: {
+				type: Number | String,
+				default: 1,
+			},
+ 
+
+			src: String,
+ 
+			fileType: {
+				type: String,
+				default: "png",
+				validator: function(t) {
+					// 这个值必须匹配下列字符串中的一个
+					return t === "png" || t === "jpg";
+				},
+			},
+ 
+			/* 截取类型,自由截取free;固定比例截取(正方形)fixed  */
+			mode: {
+				type: String,
+				default: "free",
+				validator: function(t) {
+					// 这个值必须匹配下列字符串中的一个
+					return t === "free" || t === "fixed" || t === "scale";
+				},
+			},
+			scale: {
+				type: Number,
+				default: 1,
+			},
+		},
+		created() {
+			if (this.src) {
+				this.imageSrc = this.src;
+				this.loadImage();
+				this.isShow = true;
+				this.isShowImg = true;
+			}
+		},
+		methods: {
+			setData: function(obj) {
+				let that = this;
+				Object.keys(obj).forEach(function(key) {
+					that.$set(that.$data, key, obj[key]);
+				});
+			},
+ 
+			/* 选择图片  */
+			chooseImage: function() {
+				var _this = this;
+				uni.chooseImage({
+					count: 1,
+					sizeType: ['compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['album'], //从相册选择或者拍照
+					success: function(res) {
+						if(res.tempFiles[0].size / 1024 < 1024) {
+							_this.setData({
+								imageSrc: res.tempFilePaths[0],
+							});
+							_this.loadImage();
+							_this.isShow = true;
+						} else {
+							uni.showToast({
+								title: '图片大小不能超过1024KB,当前大小' + (res.tempFiles[0].size / 1024).toFixed(2) + 'KB',
+								icon: 'none'
+							})
+						}
+					},
+				});
+			},
+			/* 将图片加载到画布  */
+			loadImage: function() {
+				var _this = this;
+				uni.showLoading({
+					title: "图片加载中...",
+				});
+ 
+				/* 获取图片信息  */
+				uni.getImageInfo({
+					src: _this.imageSrc,
+					success: function success(res) {
+						let imgH = res.height;
+						let imgW = res.width;
+ 
+						// let IMG_SCR_H_R = SCREEN_HEIGHT / imgH;
+						// let IMG_SCR_W_R = SCREEN_WIDTH / imgW;
+ 
+						/* 图片的宽高比  */
+						IMG_RATIO = imgW / imgH;
+ 
+						/**
+						 * 如果图片更高一些,为确保图片能够完整在视窗内显示需如下处理
+						 * 1. 缩放图片的高为 视窗高度减去底部菜单按钮高度(120)
+						 * 2. 根据图片缩放后的高度,根据图片宽高比计算图片的宽度
+						 * 3. 如果步骤2计算的图片宽度大于屏幕宽度,则需要再次调整图片宽度为视窗宽度-margin(10)
+						 * 4. 根据步骤3的宽度,结合图片宽高比重新计算图片的高度
+						 */
+						if (IMG_RATIO < 1 && (SCREEN_HEIGHT - 120) * IMG_RATIO < SCREEN_WIDTH - 10) {
+							IMG_REAL_W = (SCREEN_HEIGHT - 120) * IMG_RATIO;
+							IMG_REAL_H = SCREEN_HEIGHT - 120;
+						} else {
+							IMG_REAL_W = SCREEN_WIDTH - 10;
+							IMG_REAL_H = IMG_REAL_W / IMG_RATIO;
+						}
+ 
+						/* 初始化裁剪区域的位置和形状  */
+						let [cutT, cutB, cutL, cutR] = _this.initCutArea(IMG_RATIO, IMG_REAL_H,
+						IMG_REAL_W);
+ 
+						_this.setData({
+							/* 裁剪区域的宽高同图片尺寸  */
+							cropperW: IMG_REAL_W,
+							cropperH: IMG_REAL_H,
+ 
+							/* 上下左右各留一定的margin已便更好的拖动裁剪区域  */
+							cropperL: Math.ceil((SCREEN_WIDTH - IMG_REAL_W) / 2),
+ 
+							/* 留出底部操作按钮位置 70  */
+							cropperT: Math.ceil((SCREEN_HEIGHT - IMG_REAL_H - 90) / 2),
+							cutL: cutL,
+							cutT: cutT,
+							cutR: cutR,
+							cutB: cutB,
+							// 图片缩放值
+							imageW: IMG_REAL_W,
+							imageH: IMG_REAL_H,
+							scaleP: IMG_REAL_W / SCREEN_WIDTH,
+							qualityWidth: DRAW_IMAGE_W,
+							innerAspectRadio: IMG_RATIO,
+						});
+						_this.setData({
+							isShowImg: true,
+						});
+						uni.hideLoading();
+					},
+				});
+			},
+ 
+			initCutArea(IMG_RATIO, IMG_REAL_H, IMG_REAL_W) {
+				let _this = this;
+				/* 自由裁剪裁剪区域默认覆盖整个图片  */
+				let cutT = 0;
+				let cutB = 0;
+				let cutL = 0;
+				let cutR = 0;
+ 
+				/* 正方形裁剪,初始化裁剪区域为正方形并居中  */
+				if (_this.mode == "fixed") {
+					if (IMG_RATIO < 1) {
+						/* 图片比较高  */
+						cutT = (IMG_REAL_H - IMG_REAL_W) / 2;
+						cutB = (IMG_REAL_H - IMG_REAL_W) / 2;
+					} else {
+						/* 图片比较宽  */
+						cutL = (IMG_REAL_W - IMG_REAL_H) / 2;
+						cutR = (IMG_REAL_W - IMG_REAL_H) / 2;
+					}
+				}
+ 
+				/* 固定比例裁剪,初始化裁剪区域比例和设定值相同  */
+				if (_this.mode == "scale") {
+					let scale = +_this.scale;
+					if (IMG_RATIO < 1) {
+						/* 图片比较高  */
+						if (IMG_REAL_W / scale > IMG_REAL_H) {
+							cutT = cutB = 0;
+							cutL = cutR = (IMG_REAL_W - IMG_REAL_H * scale) / 2;
+						} else {
+							cutR = cutL = 0;
+							cutT = cutB = (IMG_REAL_H - IMG_REAL_W / scale) / 2;
+						}
+					} else {
+						/* 图片比较宽  */
+						if (IMG_REAL_H * scale > IMG_REAL_W) {
+							cutL = cutR = 0;
+							cutB = cutT = (IMG_REAL_H - IMG_REAL_W / scale) / 2;
+						} else {
+							cutT = cutB = 0;
+							cutL = cutR = (IMG_REAL_W - IMG_REAL_H * scale) / 2;
+						}
+					}
+				}
+ 
+				return [cutT, cutB, cutL, cutR];
+			},
+			// 拖动时候触发的touchStart事件
+			contentStartMove(e) {
+				PAGE_X = e.touches[0].pageX;
+				PAGE_Y = e.touches[0].pageY;
+			},
+			// 拖动时候触发的touchMove事件
+			contentMoveing(e) {
+				var _this = this;
+				var dragLengthX = (PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO;
+				var dragLengthY = (PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO;
+				// 左移
+				if (dragLengthX > 0) {
+					if (this.cutL - dragLengthX < 0) dragLengthX = this.cutL;
+				} else {
+					if (this.cutR + dragLengthX < 0) dragLengthX = -this.cutR;
+				}
+				if (dragLengthY > 0) {
+					if (this.cutT - dragLengthY < 0) dragLengthY = this.cutT;
+				} else {
+					if (this.cutB + dragLengthY < 0) dragLengthY = -this.cutB;
+				}
+				this.setData({
+					cutL: this.cutL - dragLengthX,
+					cutT: this.cutT - dragLengthY,
+					cutR: this.cutR + dragLengthX,
+					cutB: this.cutB + dragLengthY,
+				});
+				PAGE_X = e.touches[0].pageX;
+				PAGE_Y = e.touches[0].pageY;
+			},
+			contentTouchEnd() {},
+ 
+			// 获取图片尺寸信息
+			previewImg() {
+				try {
+					var _this = this;
+					uni.showLoading({
+						title: "图片生成中...",
+					});
+					// 将图片写入画布
+					const ctx = uni.createCanvasContext("myCanvas", _this);
+					ctx.drawImage(_this.imageSrc, 0, 0, IMG_REAL_W, IMG_REAL_H);
+					ctx.draw(true, () => {
+						// 获取画布要裁剪的位置和宽度   均为百分比 * 画布中图片的宽度    保证了在微信小程序中裁剪的图片模糊  位置不对的问题 canvasT = (_this.cutT / _this.cropperH) * (_this.imageH / pixelRatio)
+						var canvasW = ((_this.cropperW - _this.cutL - _this.cutR) / _this.cropperW) * IMG_REAL_W;
+						var canvasH = ((_this.cropperH - _this.cutT - _this.cutB) / _this.cropperH) * IMG_REAL_H;
+						var canvasL = (_this.cutL / _this.cropperW) * IMG_REAL_W;
+						var canvasT = (_this.cutT / _this.cropperH) * IMG_REAL_H;
+						uni.canvasToTempFilePath({
+								x: canvasL,
+								y: canvasT,
+								width: canvasW,
+								height: canvasH,
+								// destWidth: canvasW,
+								// destHeight: canvasH,
+								quality: +this.quality,
+								fileType: this.fileType,
+								canvasId: "myCanvas",
+								success: function(res) {
+									uni.hideLoading();
+									// 成功获得地址的地方
+									uni.previewImage({
+										current: "", // 当前显示图片的http链接
+										urls: [res.tempFilePath], // 需要预览的图片http链接列表
+									});
+								},
+								fail: function(err) {
+									uni.hideLoading();
+									uni.showToast({
+										title: "图片截取失败!",
+										icon: "none",
+									});
+								},
+							},
+							_this
+						);
+					});
+				} catch (e) {}
+			},
+ 
+			/* 完成裁剪,输出裁剪后的图片路径  */
+			finish: function() {
+				var _this = this;
+				uni.showLoading({
+					title: "图片生成中...",
+				});
+				// 将图片写入画布
+				const ctx = uni.createCanvasContext("myCanvas", _this);
+				ctx.drawImage(_this.imageSrc, 0, 0, IMG_REAL_W, IMG_REAL_H);
+				ctx.draw(true, () => {
+					// 获取画布要裁剪的位置和宽度   均为百分比 * 画布中图片的宽度    保证了在微信小程序中裁剪的图片模糊  位置不对的问题 canvasT = (_this.cutT / _this.cropperH) * (_this.imageH / pixelRatio)
+					var canvasW = ((_this.cropperW - _this.cutL - _this.cutR) / _this.cropperW) * IMG_REAL_W;
+					var canvasH = ((_this.cropperH - _this.cutT - _this.cutB) / _this.cropperH) * IMG_REAL_H;
+					var canvasL = (_this.cutL / _this.cropperW) * IMG_REAL_W;
+					var canvasT = (_this.cutT / _this.cropperH) * IMG_REAL_H;
+					uni.canvasToTempFilePath({
+							x: canvasL,
+							y: canvasT,
+							width: canvasW,
+							height: canvasH,
+							// destWidth: canvasW,
+							// destHeight: canvasH,
+							quality: +this.quality,
+							fileType: this.fileType,
+							canvasId: "myCanvas",
+							success: function(res) {
+								uni.hideLoading();
+								// 成功获得地址的地方
+								_this.$emit("uploadImg", res.tempFilePath);
+								_this.isShow = false;
+							},
+							fail: function(err) {
+								uni.hideLoading();
+								uni.showToast({
+									title: "图片截取失败!",
+									icon: "none",
+								});
+							},
+						},
+						_this
+					);
+				});
+			},
+ 
+			// 设置大小的时候触发的touchStart事件
+			dragStart(e) {
+				T_PAGE_X = e.touches[0].pageX;
+				T_PAGE_Y = e.touches[0].pageY;
+				CUT_L = this.cutL;
+				CUT_R = this.cutR;
+				CUT_B = this.cutB;
+				CUT_T = this.cutT;
+			},
+ 
+			// 设置大小的时候触发的touchMove事件
+			dragMove(e) {
+				// this.mode == "fixed" ? this.fixedScaleDrag(e) : this.freeDrag(e);
+				this[this.mode + "Drag"](e);
+			},
+ 
+			/* 固定比例(正方形)截取 ,只有右下角裁剪滑动拖动有效*/
+			fixedDrag(e) {
+				var _this = this;
+				var dragType = e.target.dataset.drag;
+				switch (dragType) {
+					case "rightBottom":
+						var dragLengthX = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO;
+						// var dragLengthY = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO;
+						// if (CUT_B + dragLengthY < 0) dragLengthY = -CUT_B;
+ 
+						if (CUT_R + dragLengthX < 0) dragLengthX = -CUT_R;
+ 
+						/* 右侧和底部同比变化 */
+						let cutB = CUT_B + dragLengthX;
+						let cutR = CUT_R + dragLengthX;
+ 
+						/* 越界判断  */
+						if (_this.cutB == 0 && cutB < 0) return;
+						if (_this.cutR == 0 && cutR < 0) return;
+ 
+						(_this.cutB > 0 || CUT_B == 0) &&
+						this.setData({
+							cutB: cutB < 0 ? 0 : cutB,
+							cutR: cutR,
+						});
+						break;
+					default:
+						break;
+				}
+			},
+ 
+			/* 等比例截图,只能通过右下角的滑块改变截图区域  */
+			scaleDrag(e) {
+				var _this = this;
+				var dragType = e.target.dataset.drag;
+				switch (dragType) {
+					case "rightBottom":
+						var dragLengthX = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO;
+						// var dragLengthY = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO;
+						// if (CUT_B + dragLengthY < 0) dragLengthY = -CUT_B;
+ 
+						if (CUT_R + dragLengthX < 0) dragLengthX = -CUT_R;
+ 
+						/* 右侧和底部同比变化 */
+						let cutB = CUT_B + dragLengthX / _this.scale;
+						let cutR = CUT_R + dragLengthX;
+ 
+						/* 越界判断  */
+						if (_this.cutB == 0 && cutB < 0) return;
+						if (_this.cutR == 0 && cutR < 0) return;
+ 
+						(_this.cutB > 0 || CUT_B == 0) &&
+						this.setData({
+							cutB: cutB < 0 ? 0 : cutB,
+							cutR: cutR,
+						});
+						break;
+					default:
+						break;
+				}
+			},
+ 
+			/* 自由截取,整个裁剪边框均能拖动  */
+			freeDrag(e) {
+				var _this = this;
+				var dragType = e.target.dataset.drag;
+				switch (dragType) {
+					case "right":
+						var dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO;
+						if (CUT_R + dragLength < 0) dragLength = -CUT_R;
+						this.setData({
+							cutR: CUT_R + dragLength,
+						});
+						break;
+					case "left":
+						var dragLength = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO;
+						if (CUT_L - dragLength < 0) dragLength = CUT_L;
+						if (CUT_L - dragLength > this.cropperW - this.cutR)
+							dragLength = CUT_L - (this.cropperW - this.cutR);
+						this.setData({
+							cutL: CUT_L - dragLength,
+						});
+						break;
+					case "top":
+						var dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO;
+						if (CUT_T - dragLength < 0) dragLength = CUT_T;
+						if (CUT_T - dragLength > this.cropperH - this.cutB)
+							dragLength = CUT_T - (this.cropperH - this.cutB);
+						this.setData({
+							cutT: CUT_T - dragLength,
+						});
+						break;
+					case "bottom":
+						var dragLength = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO;
+						if (CUT_B + dragLength < 0) dragLength = -CUT_B;
+						this.setData({
+							cutB: CUT_B + dragLength,
+						});
+						break;
+					case "rightBottom":
+						var dragLengthX = (T_PAGE_X - e.touches[0].pageX) * DRAFG_MOVE_RATIO;
+						var dragLengthY = (T_PAGE_Y - e.touches[0].pageY) * DRAFG_MOVE_RATIO;
+						if (CUT_B + dragLengthY < 0) dragLengthY = -CUT_B;
+						if (CUT_R + dragLengthX < 0) dragLengthX = -CUT_R;
+						let cutB = CUT_B + dragLengthY;
+						let cutR = CUT_R + dragLengthX;
+						this.setData({
+							cutB: cutB,
+							cutR: cutR,
+						});
+						break;
+					default:
+						break;
+				}
+			},
+		},
+	};
+</script>
+ 
+<style>
+	/* pages/uni-cropper/index.wxss */
+	.yhdsl {
+		background-color: #fff;
+		position: fixed;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 50px;
+		display: block;
+		align-items: center;
+		flex-direction: column;
+		z-index: 998;
+		height: 100vh;
+	}
+ 
+	.cropper-config {
+		position: fixed;
+		z-index: 999;
+		bottom: 10px;
+		left: 0;
+		right: 0;
+ 
+		width: 90%;
+		margin: 0 auto;
+		/* padding: 20upx 40upx; */
+	}
+ 
+	.button-box {
+		position: absolute;
+		bottom: 0;
+		display: flex;
+		flex-direction: row;
+		justify-content: space-between;
+ 
+		width: 100%;
+	}
+ 
+	.button-box button {
+		width: 25%;
+		line-height: 35px;
+		height: 35px;
+		background-color: #509cff;
+	}
+ 
+	.cropper-content {
+		width: 100%;
+		min-height: 750upx;
+	}
+ 
+	.uni-corpper {
+		position: relative;
+ 
+		overflow: hidden;
+ 
+		box-sizing: border-box;
+		margin: 0 auto;
+ 
+		-webkit-user-select: none;
+		-moz-user-select: none;
+		-ms-user-select: none;
+		user-select: none;
+ 
+		-webkit-tap-highlight-color: transparent;
+		-webkit-touch-callout: none;
+	}
+ 
+	.uni-corpper-content {
+		position: relative;
+	}
+ 
+	.uni-corpper-content image {
+		display: block;
+ 
+		width: 100%;
+		min-width: 0 !important;
+		max-width: none !important;
+		/* height: 100%; */
+		min-height: 0 !important;
+		/* max-height: none !important; */
+ 
+		max-height: calc(100vh - 100upx);
+		margin: 0 auto;
+ 
+		image-orientation: 0deg !important;
+	}
+ 
+	/* 移动图片效果 */
+	.uni-cropper-drag-box {
+		position: absolute;
+		z-index: 1;
+		top: 0;
+		right: 0;
+		bottom: 0;
+		left: 0;
+ 
+		cursor: move;
+ 
+		background: rgba(0, 0, 0, 0.479);
+	}
+ 
+	/* 内部的信息 */
+	.uni-corpper-crop-box {
+		position: absolute;
+		z-index: 2;
+		max-height: calc(100vh - 100upx);
+		background: rgba(56, 50, 50, 0.479);
+	}
+ 
+	.uni-corpper-crop-box .uni-cropper-view-box {
+		position: relative;
+ 
+		display: block;
+		overflow: visible;
+ 
+		width: 100%;
+		height: 100%;
+ 
+		max-height: calc(100vh - 100upx);
+		outline: 5upx solid rgb(43, 89, 255);
+		outline-color: rgba(255, 255 255, 1);
+	}
+ 
+	/* 横向虚线 */
+	.uni-cropper-dashed-h {
+		position: absolute;
+		top: 33.33333333%;
+		left: 0;
+ 
+		width: 100%;
+		height: 33.33333333%;
+ 
+		border-top: 1upx dashed rgba(255, 255, 255, 0.5);
+		border-bottom: 1upx dashed rgba(255, 255, 255, 0.5);
+	}
+ 
+	/* 纵向虚线 */
+	.uni-cropper-dashed-v {
+		position: absolute;
+		top: 0;
+		left: 33.33333333%;
+ 
+		width: 33.33333333%;
+		height: 100%;
+ 
+		border-right: 1upx dashed rgba(255, 255, 255, 0.5);
+		border-left: 1upx dashed rgba(255, 255, 255, 0.5);
+	}
+ 
+	/* 四个方向的线  为了之后的拖动事件*/
+	.uni-cropper-line-t {
+		position: absolute;
+		top: 0;
+		left: 0;
+ 
+		display: block;
+ 
+		width: 100%;
+		height: 3upx;
+ 
+		cursor: n-resize;
+ 
+		opacity: 0.1;
+		background-color: white;
+	}
+ 
+	.uni-cropper-line-t::before {
+		position: absolute;
+		z-index: 11;
+		top: 50%;
+		right: 0upx;
+		bottom: 0;
+ 
+		width: 100%;
+		height: 41upx;
+ 
+		content: "";
+		-webkit-transform: translate3d(0, -50%, 0);
+		transform: translate3d(0, -50%, 0);
+ 
+		background: transparent;
+	}
+ 
+	.uni-cropper-line-r {
+		position: absolute;
+		top: 0;
+		right: 0upx;
+ 
+		display: block;
+ 
+		width: 3upx;
+		height: 100%;
+ 
+		cursor: e-resize;
+ 
+		opacity: 0.1;
+		background-color: white;
+	}
+ 
+	.uni-cropper-line-r::before {
+		position: absolute;
+		z-index: 11;
+		top: 0;
+		bottom: 0;
+		left: 50%;
+ 
+		width: 41upx;
+		height: 100%;
+ 
+		content: "";
+		-webkit-transform: translate3d(-50%, 0, 0);
+		transform: translate3d(-50%, 0, 0);
+ 
+		background: transparent;
+	}
+ 
+	.uni-cropper-line-b {
+		position: absolute;
+		bottom: 0;
+		left: 0;
+ 
+		display: block;
+ 
+		width: 100%;
+		height: 3upx;
+ 
+		cursor: s-resize;
+ 
+		opacity: 0.1;
+		background-color: white;
+	}
+ 
+	.uni-cropper-line-b::before {
+		position: absolute;
+		z-index: 11;
+		top: 50%;
+		right: 0upx;
+		bottom: 0;
+ 
+		width: 100%;
+		height: 41upx;
+ 
+		content: "";
+		-webkit-transform: translate3d(0, -50%, 0);
+		transform: translate3d(0, -50%, 0);
+ 
+		background: transparent;
+	}
+ 
+	.uni-cropper-line-l {
+		position: absolute;
+		top: 0;
+		left: 0;
+ 
+		display: block;
+ 
+		width: 3upx;
+		height: 100%;
+ 
+		cursor: w-resize;
+ 
+		opacity: 0.1;
+		background-color: white;
+	}
+ 
+	.uni-cropper-line-l::before {
+		position: absolute;
+		z-index: 11;
+		top: 0;
+		bottom: 0;
+		left: 50%;
+ 
+		width: 41upx;
+		height: 100%;
+ 
+		content: "";
+		-webkit-transform: translate3d(-50%, 0, 0);
+		transform: translate3d(-50%, 0, 0);
+ 
+		background: transparent;
+	}
+ 
+	.uni-cropper-point {
+		position: absolute;
+		z-index: 3;
+ 
+		width: 5upx;
+		height: 5upx;
+ 
+		opacity: 0.75;
+		background-color: rgb(145, 132, 132);
+	}
+ 
+	.point-t {
+		top: -3upx;
+		left: 50%;
+ 
+		margin-left: -3upx;
+ 
+		cursor: n-resize;
+	}
+ 
+	.point-tr {
+		top: -3upx;
+		left: 100%;
+ 
+		margin-left: -3upx;
+ 
+		cursor: n-resize;
+	}
+ 
+	.point-r {
+		top: 50%;
+		left: 100%;
+ 
+		margin-top: -3upx;
+		margin-left: -3upx;
+ 
+		cursor: n-resize;
+	}
+ 
+	.point-rb {
+		position: absolute;
+		z-index: 1112;
+		top: 100%;
+		left: 100%;
+ 
+		width: 30upx;
+		height: 30upx;
+		border-radius: 50%;
+ 
+		cursor: n-resize;
+		-webkit-transform: translate3d(-50%, -50%, 0);
+		transform: translate3d(-50%, -50%, 0);
+ 
+		opacity: 1;
+		background-color: rgb(231, 222, 222);
+		background-color: #509cff;
+	}
+ 
+	.point-b {
+		top: 100%;
+		left: 50%;
+ 
+		margin-top: -3upx;
+		margin-left: -3upx;
+ 
+		cursor: n-resize;
+	}
+ 
+	.point-bl {
+		top: 100%;
+		left: 0;
+ 
+		margin-top: -3upx;
+		margin-left: -3upx;
+ 
+		cursor: n-resize;
+	}
+ 
+	.point-l {
+		top: 50%;
+		left: 0;
+ 
+		margin-top: -3upx;
+		margin-left: -3upx;
+ 
+		cursor: n-resize;
+	}
+ 
+	.point-lt {
+		top: 0;
+		left: 0;
+ 
+		margin-top: -3upx;
+		margin-left: -3upx;
+ 
+		cursor: n-resize;
+	}
+ 
+	/* 裁剪框预览内容 */
+	.uni-cropper-viewer {
+		position: relative;
+ 
+		overflow: hidden;
+ 
+		width: 100%;
+		height: 100%;
+	}
+ 
+	.uni-cropper-viewer image {
+		position: absolute;
+		z-index: 2;
+	}
+</style>

+ 110 - 0
components/ysxyView/ysxyView.vue

@@ -0,0 +1,110 @@
+<template>
+	<view class="ysviewContent">
+		<view v-if="yuyan==0">
+			<view class="contentColumnC" style="padding-top: 20rpx;">
+				<text class="textfontB2" style="text-align: center;">用户协议及隐私政策</text>
+			</view>
+			<view style="margin-top: 20rpx;padding: 16rpx;">
+				<text>您在使用我们的服务时,我们可能会收集和使用您的相关信息。我们希望通过本</text>
+				<text class="ynszcdi" @click="btSelect(2)">《隐私政策》</text>
+				<text>向您说明,在使用我们的服务时,我们如何收集、使用、储存和分享这些信息,以及我们为您提供的访问、更新、控制和保护这些信息的方式。本</text>
+				<text class="ynszcdi" @click="btSelect(2)">《隐私政策》</text>
+				<text>,希望您仔细阅读,充分理解协议中的内容后再点击同意。</text>
+			</view>
+			<view class="contentInRowS" style="width: 90%;margin-left: 5%;margin-top: 20rpx;padding-bottom:20rpx;">
+				<text class="disagrBt" style="font-size: 24rpx;" @click="qiehuanyuy(1)">Ngôn ngữ/语言</text>
+				<text class="disagrBt" @click="btSelect(0)">不同意</text>
+				<text class="agrBt" @click="btSelect(1)">同意</text>
+			</view>
+		</view>
+		<view v-if="yuyan==1">
+			<view class="contentColumnC" style="padding-top: 20rpx;">
+				<text class="textfontB2" style="text-align: center;">Thỏa thuận người dùng và Chính sách bảo mật</text>
+			</view>
+			<view style="margin-top: 20rpx;padding: 16rpx;">
+				<text>Chúng tôi có thể thu thập và sử dụng thông tin về bạn khi bạn sử dụng Dịch vụ của chúng tôi. Chúng tôi hy vọng thông qua Ben</text>
+				<text class="ynszcdi" @click="btSelect(2)">《Chính sách bảo mật》</text>
+				<text>Giải thích cho bạn cách chúng tôi thu thập, sử dụng, lưu trữ và chia sẻ thông tin này khi sử dụng Dịch vụ của chúng tôi và cách chúng tôi cung cấp cho bạn quyền truy cập, cập nhật, kiểm soát và bảo vệ thông tin này. Ben</text>
+				<text class="ynszcdi" @click="btSelect(2)">《Chính sách bảo mật》</text>
+				<text>,Hy vọng bạn đọc kỹ, hiểu đầy đủ nội dung trong thỏa thuận trước khi nhấp vào đồng ý.</text>
+			</view>
+			<view class="contentInRowS" style="width: 90%;margin-left: 5%;margin-top: 20rpx;padding-bottom:20rpx;">
+				<text class="disagrBt" style="font-size: 24rpx;" @click="qiehuanyuy(0)">Ngôn ngữ/语言</text>
+				<text class="disagrBt" @click="btSelect(0)">Không đồng ý</text>
+				<text class="agrBt" @click="btSelect(1)">Đồng ý</text>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		name:"ysxyView",
+		data() {
+			return {
+				yuyan:1
+			};
+		},
+		methods:{
+			btSelect(state){
+				this.$emit('EagrResult',state);
+			},
+			qiehuanyuy(s){
+				this.yuyan=s;
+				var code='';
+				if(this.yuyan==1){
+					code='yuenan';
+				}
+				else{
+					code='zh-Hans';
+				}
+				if (plus.os.name.toLowerCase() === 'android') {
+					uni.setStorageSync('language',code);
+					uni.setLocale(code);
+				}
+				else{
+					uni.setStorageSync('language',code);
+					uni.setLocale(code);
+					this.$i18n.locale = code;
+				}
+				
+			}
+			
+		},
+	}
+</script>
+
+<style>
+	.ysviewContent{
+		width: 80%;
+		margin-left: 10%;
+		background-color: white;
+		border-radius: 10rpx;
+	}
+	
+	.ynszcdi{
+		color: blue;
+		text-decoration:underline;
+	}
+	
+	.disagrBt{
+		background-color: white;
+		border: 2rpx solid lightgray;
+		padding-left: 12rpx;
+		padding-right: 12rpx;
+		line-height: 60rpx;
+		font-size: 26rpx;
+		border-radius: 8rpx;
+	}
+	.agrBt{
+		background-color: #00A6FF;
+		border: 2rpx solid #00A6FF;
+		padding-left: 12rpx;
+		padding-right: 12rpx;
+		line-height: 60rpx;
+		font-size: 26rpx;
+		border-radius: 8rpx;
+		color: white;
+	}
+
+</style>

+ 32 - 0
config/index.config.js

@@ -0,0 +1,32 @@
+const CONFIG = {
+	// 开发环境配置
+	development: {
+		assetsPath: '/static', // 静态资源路径
+		qqMapKey:'',
+		// baseUrl: 'http://192.168.1.13:8080',//测试
+		// hostUrl: 'http://192.168.1.13:8080', // H5地址(前端运行地址)
+		baseUrl: 'https://api.amazeway.com.cn',//预发布
+		hostUrl: 'https://api.amazeway.com.cn', // H5地址(前端运行地址)
+		// baseUrl: 'https://api.cityexpress168.com.vn', // 后台接口请求地址 http://203.175.169.46:8080
+		// hostUrl: 'https://api.cityexpress168.com.vn', // H5地址(前端运行地址) http://203.175.169.46:8080
+		websocketUrl: '', // websocket服务端地址
+		weixinAppId: '', // 微信公众号appid
+		storeId: 0 //
+	},
+	// 生产环境配置
+	production: {
+		qqMapKey:'',
+		assetsPath: '/static', // 静态资源路径
+		// baseUrl: ' http://192.168.1.7:8080',
+		// hostUrl: ' http://192.168.1.7:8080', // H5地址(前端运行地址)
+		// baseUrl: 'https://api.cityexpress168.com.vn', // 后台接口请求地址
+		// hostUrl: 'https://api.cityexpress168.com.vn', // H5地址(前端运行地址)
+		baseUrl: 'https://api.amazeway.com.cn',//预发布
+		hostUrl: 'https://api.amazeway.com.cn',//预发布
+		websocketUrl: '', // websocket服务端地址
+		weixinAppId: '', // 微信公众号appid
+		storeId: 0 //
+	}
+
+};
+export default CONFIG[process.env.NODE_ENV];

BIN
cteDev.p12


BIN
cteDis.p12


BIN
cteqishou.keystore


+ 5 - 0
cteqishou.txt

@@ -0,0 +1,5 @@
+证书指纹:
+         MD5:  E1:05:A9:23:1A:79:5A:61:4C:63:39:20:07:E1:6C:49
+         SHA1: B8:00:D8:4F:AC:72:1A:4F:69:8C:5E:6F:E3:90:C0:67:39:97:F5:18
+         SHA256: 10:C1:D8:F3:29:D8:F3:9F:3D:F0:24:09:B2:45:4A:A5:AD:34:F1:89:E4:29:D3:C2:02:71:1B:4C:93:CA:7B:D5
+签名算法名称: SHA256withRSA

BIN
cteqsdev-3.mobileprovision


BIN
cteqsdis-2.mobileprovision


+ 59 - 0
debug/GenerateTestUserSig.js

@@ -0,0 +1,59 @@
+import LibGenerateTestUserSig from './lib-generate-test-usersig-es.min.js';
+/**
+ * 腾讯云 SDKAppId,需要替换为您自己账号下的 SDKAppId。
+ *
+ * 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ) 创建应用,即可看到 SDKAppId,
+ * 它是腾讯云用于区分客户的唯一标识。
+ */
+
+const SDKAPPID = 1600036174;
+/**
+ * 签名过期时间,建议不要设置的过短
+ * <p>
+ * 时间单位:秒
+ * 默认时间:7 x 24 x 60 x 60 = 604800 = 7 天
+ */
+
+const EXPIRETIME = 604800;
+/**
+ * 计算签名用的加密密钥,获取步骤如下:
+ *
+ * step1. 进入腾讯云实时音视频[控制台](https://console.cloud.tencent.com/rav ),如果还没有应用就创建一个,
+ * step2. 单击“应用配置”进入基础配置页面,并进一步找到“帐号体系集成”部分。
+ * step3. 点击“查看密钥”按钮,就可以看到计算 UserSig 使用的加密的密钥了,请将其拷贝并复制到如下的变量中
+ *
+ * 注意:该方案仅适用于调试Demo,正式上线前请将 UserSig 计算代码和密钥迁移到您的后台服务器上,以避免加密密钥泄露导致的流量盗用。
+ * 文档:https://cloud.tencent.com/document/product/647/17275#Server
+ */
+
+const SECRETKEY = 'e3b6abb54f40fc92d207ab95616887b1f06ffaf97e60fcb1f780e7002a3c114e';
+/*
+ * Module:   GenerateTestUserSig
+ *
+ * Function: 用于生成测试用的 UserSig,UserSig 是腾讯云为其云服务设计的一种安全保护签名。
+ *           其计算方法是对 SDKAppID、UserID 和 EXPIRETIME 进行加密,加密算法为 HMAC-SHA256。
+ *
+ * Attention: 请不要将如下代码发布到您的线上正式版本的 App 中,原因如下:
+ *
+ *            本文件中的代码虽然能够正确计算出 UserSig,但仅适合快速调通 SDK 的基本功能,不适合线上产品,
+ *            这是因为客户端代码中的 SECRETKEY 很容易被反编译逆向破解,尤其是 Web 端的代码被破解的难度几乎为零。
+ *            一旦您的密钥泄露,攻击者就可以计算出正确的 UserSig 来盗用您的腾讯云流量。
+ *
+ *            正确的做法是将 UserSig 的计算代码和加密密钥放在您的业务服务器上,然后由 App 按需向您的服务器获取实时算出的 UserSig。
+ *            由于破解服务器的成本要高于破解客户端 App,所以服务器计算的方案能够更好地保护您的加密密钥。
+ *
+ * Reference:https://cloud.tencent.com/document/product/647/17275#Server
+ */
+
+function genTestUserSig(userID) {
+  const generator = new LibGenerateTestUserSig(SDKAPPID, SECRETKEY, EXPIRETIME);
+  const userSig = generator.genTestUserSig(userID);
+  return {
+    sdkAppId: SDKAPPID,
+    userSig,
+  };
+}
+
+module.exports = {
+  genTestUserSig,
+};

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 1217 - 0
debug/lib-generate-test-usersig-es.min.js


+ 432 - 0
hybrid/html/voices/audio.html

@@ -0,0 +1,432 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="UTF-8">
+		<meta http-equiv="X-UA-Compatible" content="IE=edge">
+		<meta name="viewport" content="width=device-width, initial-scale=1.0">
+		<link rel="stylesheet" type="text/css" href="./css/index.css" />
+		<title id="title"></title>
+		<style>
+		html, body {
+		    height: 100%;
+		}
+		body {
+		    margin: 0;
+		}
+		video {
+		    width: 100%;
+		    height: 100%;
+		    position: absolute;
+		    left: 0;
+		    top: 0;
+		    z-index: -1;
+		}
+		
+		</style>
+	</head>
+	<body>
+		<!-- <video class="Bvideo" id="Big_video"  preload autoplay onclick="Bvideoselc()"></video> -->
+		<!-- <video class="Svideo" id="sm_video"  preload muted autoplay onclick="Svideoselc()"></video> -->
+		<audio id="my_audio" autoplay></audio>
+		<div class="contentColumnC" style="width: 100%;margin-top: 60px;"">
+			<div id="userName"></div>
+			<img id='icon_Img' class="iconImg" style="margin-top: 5px;" src="./img/logo.png" alt="" onclick="guaduan()"/>
+			<div class="contentInRowC" style="width: 100%;margin-top: 10px;">
+				<div id="markNote"></div>
+				<img class="calling" src="./img/loading2.gif" alt="" />
+			</div>
+		</div>
+		 <div style="width: 100%;margin-top: 100px;">
+			 <div class="contentColumnC">
+				 <img class="guadanImg" style="margin-top: 5px;" src="./img/guaduandd.png" alt="" onclick="guaduan()"/>
+			 </div>
+		 </div>
+	</body>
+	<script type="text/javascript" src="./js/lib/uniwebviewsdk.js"></script>
+	<script>
+	let language =getQueryVariable('language');
+	let title,state1,state2,state3,state4,state5;
+	let localStream = null;
+	let localCall = 0;
+	let localCandidata=null;
+	let peer = null;
+	let video=null;
+	// const Big_video = document.getElementById('Big_video');
+	// const sm_video = document.getElementById('sm_video');
+	// const my_audio = document.getElementById('my_audio');
+	const userName = document.getElementById('userName');
+	const markNote = document.getElementById('markNote');
+	const icon_Img = document.getElementById('icon_Img');
+	const title_div = document.getElementById('title');
+	//====================================================
+	
+	function getQueryVariable(variable) {
+		var query = decodeURI(window.location.search.substring(1));
+		var vars = query.split("&");
+		for (var i = 0; i < vars.length; i++) {
+			var pair = vars[i].split("=");
+			if (pair[0] == variable) {
+				return pair[1];
+			}
+		}
+		return (false);
+	}
+	function Bvideoselc(){
+		if(localStream!=null){
+			//Big_video.srcObject =localStream;
+			Big_video.setAttribute('autoplay', true); /* THIS */
+		}
+	}
+	function Svideoselc(){
+		if(localStream!=null){
+			//sm_video.srcObject =localStream;
+			sm_video.setAttribute('autoplay', true); /* THIS */
+		}
+	}
+	function guaduan(){
+		if(peer){
+			peer.close();
+		}
+		uni.postMessage({
+		    data: {
+		        data:'', // 回传
+				type:88
+		    },
+		});
+	}
+	
+	function duifangguaduan(){
+		if(peer){
+			peer.close();
+		}
+		markNote.innerHTML=state4;
+	}
+	//====================================================
+	function appAct (obj) {
+		if(obj.type==1){//主动发起im通话
+			localCall=1;
+			startWebRct(obj.type);
+			markNote.innerHTML=state1;
+			userName.innerHTML=obj.payload.userName;
+			icon_Img.src=obj.payload.avatar;
+		}
+		else if(obj.type==2){//收到推送消息
+			if(localCall==1){
+				//markNote.innerHTML=state2;
+				RCremoteData(obj.payload);
+			}
+			else{
+				RCstartWebRct(obj.payload);
+			}
+		}
+		else if(obj.type==3){//收到candidate
+			//markNote.innerHTML=state2;
+			for(var i=0;i<obj.payload.length;i++){
+				peer.addIceCandidate(obj.payload[i]);
+			}
+			if(localCall!=1){
+				uni.postMessage({
+				    data: {
+				        data:localCandidata, //应答方回应candidate
+						type:3
+				    },
+				});
+			}
+			else{
+				// uni.postMessage({
+				//     data: {
+				//         data:'kaishi 通话', //应答方回应candidate
+				// 		type:12343
+				//     },
+				// });
+			}
+		}
+	}
+	
+	async function startCapture(displayMediaOptions) {
+	    try {
+	        localStream = await navigator.mediaDevices.getUserMedia(displayMediaOptions);
+			// Big_video.srcObject =localStream;
+			// Big_video.setAttribute('autoplay', true); /* THIS */
+			// var otherVideos = document.querySelector('#my_audio');
+			// otherVideos.srcObject = localStream;
+			
+			uni.postMessage({
+			    data: {
+			        data:'', // 回传
+					type:99
+			    },
+			});
+	    } catch(err) {
+	        console.error(err);
+	    }
+	}
+	async function startWebRct(type){
+		peer = new RTCPeerConnection(
+			{
+				iceServers:[
+					{
+						urls:'stun:stun.l.google.com:19302',
+					}
+				],
+				offerExtmapAllowMixed:false
+			}
+		);
+		//添加本地音视频
+		localStream.getTracks().forEach((track) => {
+		  peer.addTrack(track, localStream)
+		});
+		//创建本地offer
+		const offer = peer.createOffer({
+			offerToReceiveAudio:1,
+			offerToReceiveVideo:1
+		});
+		//记录本地offer
+		offer.then(value => {
+			peer.setLocalDescription(value);
+			uni.postMessage({
+			    data: {
+			        data:value, // 回传并推送offer
+					type:2
+			    },
+			});
+		}).catch(error => {
+		});
+		
+		localCandidata=[]
+		peer.onicecandidate = function (event) {
+		  if (event.candidate){
+			localCandidata.push(event.candidate);
+		  }
+		}
+		peer.onconnectionstatechange = function (ev) {
+			uni.postMessage({
+			    data: {
+			        data:peer.connectionState, // 发起方先发candidate
+					type:34567
+			    },
+			});
+			if(peer.connectionState=="closed"){
+				markNote.innerHTML=state5;
+			}
+			if(peer.connectionState=="connected"){
+				markNote.innerHTML=state3;
+			}
+			if(peer.connectionState=="connecting"){
+				markNote.innerHTML=state2;
+			}
+			if(peer.connectionState=="disconnected"){
+				markNote.innerHTML=state4;
+			}
+		};
+		startCommunicate();
+	}
+	
+	async function RCremoteData(rcData){//收到remoteAnswer
+		//记录远端offer
+		
+		await peer.setRemoteDescription(rcData)
+		
+		uni.postMessage({
+		    data: {
+		        data:localCandidata, // 发起方先发candidate
+				type:3
+		    },
+		});
+	}
+	function startCommunicate(){
+		peer.ontrack = (e) => {
+			if(e.streams[0]){
+				var otherVideos = document.querySelector('#my_audio');
+				otherVideos.srcObject = e.streams[0];
+				//otherVideos.srcObject = localStream;
+			}
+			// sm_video.srcObject =localStream;
+			// sm_video.setAttribute('autoplay', true); /* THIS */
+		}
+	}
+	async function RCstartWebRct(payload){
+		peer = new RTCPeerConnection(
+			{
+				iceServers:[
+					{
+						urls:'stun:stun.l.google.com:19302',
+					}
+				]
+			}
+		);
+		//添加本地音视频
+		localStream.getTracks().forEach((track) => {
+		  peer.addTrack(track, localStream)
+		})
+		localCandidata=[];
+		peer.onicecandidate = function (event) {
+		  if (event.candidate){
+			//let strcandidate=JSON.stringify(event.candidate);
+			localCandidata.push(event.candidate);
+		  }
+		}
+		startCommunicate();
+		peer.onconnectionstatechange = function (ev) {
+			if(peer.connectionState=="closed"){
+				markNote.innerHTML=state5;
+			}
+			if(peer.connectionState=="connected"){
+				markNote.innerHTML=state3;
+			}
+			if(peer.connectionState=="connecting"){
+				markNote.innerHTML=state2;
+			}
+			if(peer.connectionState=="disconnected"){
+				markNote.innerHTML=state4;
+			}
+		};
+		//记录远端offer
+		const offer = new RTCSessionDescription(payload);
+		await peer.setRemoteDescription(offer);
+		
+		const remoteAnswer = await peer.createAnswer();
+		//记录本地offer
+		await peer.setLocalDescription(remoteAnswer);
+		//推送remoteAnswer
+		uni.postMessage({
+		    data: {
+		        data:remoteAnswer, // 回传并推送offer
+				type:2
+		    },
+		});
+		
+	}
+	function initRtc() {
+		markNote.innerHTML=language;
+		if(language=='yuenan'){//越南语
+			title='IM Cuộc gọi thoại';
+			state1='Đang gọi';
+			state2='Đang kết nối';
+			state3='Đã kết nối';
+			state4='Bị treo';
+			state5='Kết thúc cuộc gọi';
+		}
+		if(language=='zh-Hans'){//简体中文
+			title='IM 语音通话';
+			state1='正在呼叫';
+			state2='正在接通';
+			state3='已接通';
+			state4='已挂断';
+			state5='结束通话';
+		}
+		if(language=='zh-Hant'){//繁体中文
+			title='IM 語音通話';
+			state1='正在呼叫';
+			state2='正在接通';
+			state3='已接通';
+			state4='已掛斷';
+			state5='結束通話';
+		}
+		markNote.innerHTML=title;
+		title_div.innerHTML=title;
+		// uni.postMessage({
+		//     data: {
+		//         data:'', // 回传
+		// 		type:9999
+		//     },
+		// });
+		setTimeout(() => {
+			startCapture({ video: true, audio: true});
+			//startCapture({audio: true});
+		}, 1000)
+		return;
+	}
+	function releaseTack(){
+		if(peer){
+			peer.close();
+		}
+	}
+	//window.onload=initRtc;
+	
+	// 正确的做法,使用匿名函数的方式来扩展现有的行为
+	window.onload = function() {
+	    markNote.innerHTML=language;
+	    if(language=='yuenan'){//越南语
+	    	title='IM Cuộc gọi thoại';
+	    	state1='Đang gọi';
+	    	state2='Đang kết nối';
+	    	state3='Đã kết nối';
+	    	state4='Bị treo';
+	    	state5='Kết thúc cuộc gọi';
+	    }
+	    if(language=='zh-Hans'){//简体中文
+	    	title='IM 语音通话';
+	    	state1='正在呼叫';
+	    	state2='正在接通';
+	    	state3='已接通';
+	    	state4='已挂断';
+	    	state5='结束通话';
+	    }
+	    if(language=='zh-Hant'){//繁体中文
+	    	title='IM 語音通話';
+	    	state1='正在呼叫';
+	    	state2='正在接通';
+	    	state3='已接通';
+	    	state4='已掛斷';
+	    	state5='結束通話';
+	    }
+	    markNote.innerHTML=title;
+	    title_div.innerHTML=title;
+	    // uni.postMessage({
+	    //     data: {
+	    //         data:'', // 回传
+	    // 		type:9999
+	    //     },
+	    // });
+	    setTimeout(() => {
+	    	startCapture({ video: true, audio: true});
+	    	//startCapture({audio: true});
+	    }, 1000)
+	    return;
+	};
+	window.onload = window.onload || function() {
+	    markNote.innerHTML=language;
+	    if(language=='yuenan'){//越南语
+	    	title='IM Cuộc gọi thoại';
+	    	state1='Đang gọi';
+	    	state2='Đang kết nối';
+	    	state3='Đã kết nối';
+	    	state4='Bị treo';
+	    	state5='Kết thúc cuộc gọi';
+	    }
+	    if(language=='zh-Hans'){//简体中文
+	    	title='IM 语音通话';
+	    	state1='正在呼叫';
+	    	state2='正在接通';
+	    	state3='已接通';
+	    	state4='已挂断';
+	    	state5='结束通话';
+	    }
+	    if(language=='zh-Hant'){//繁体中文
+	    	title='IM 語音通話';
+	    	state1='正在呼叫';
+	    	state2='正在接通';
+	    	state3='已接通';
+	    	state4='已掛斷';
+	    	state5='結束通話';
+	    }
+	    markNote.innerHTML=title;
+	    title_div.innerHTML=title;
+	    // uni.postMessage({
+	    //     data: {
+	    //         data:'', // 回传
+	    // 		type:9999
+	    //     },
+	    // });
+	    setTimeout(() => {
+	    	startCapture({ video: true, audio: true});
+	    	//startCapture({audio: true});
+	    }, 1000)
+	    return;
+	};
+	
+	window.onunload=releaseTack;
+	</script>
+	
+</html>

+ 207 - 0
hybrid/html/voices/audioserver.html

@@ -0,0 +1,207 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="UTF-8">
+		<meta http-equiv="X-UA-Compatible" content="IE=edge">
+		<meta name="viewport" content="width=device-width, initial-scale=1.0">
+		<link rel="stylesheet" type="text/css" href="./css/index.css" />
+		<title id="title"></title>
+		<style>
+		html, body {
+		    height: 100%;
+		}
+		body {
+		    margin: 0;
+		}
+		video {
+		    width: 100%;
+		    height: 100%;
+		    position: absolute;
+		    left: 0;
+		    top: 0;
+		    z-index: -1;
+		}
+		
+		</style>
+	</head>
+	<body>
+		<video id="localVideo" playsinline autoplay muted></video>
+		
+		    <div class="box">
+		        <button id="startButton">Start</button>
+		        <button id="callButton">Call</button>
+		        <button id="hangupButton">Hang Up</button>
+		    </div>
+	</body>
+	<script type="text/javascript" src="./js/lib/uniwebviewsdk.js"></script>
+	<script>
+	const startButton = document.getElementById('startButton');
+	const callButton = document.getElementById('callButton');
+	const hangupButton = document.getElementById('hangupButton');
+	callButton.disabled = true;
+	hangupButton.disabled = true;
+	let localCandidata=null;
+	startButton.addEventListener('click', start);
+	callButton.addEventListener('click', call);
+	hangupButton.addEventListener('click', hangup);
+	
+	
+	const localVideo = document.getElementById('localVideo');
+	
+	
+	localVideo.addEventListener('loadedmetadata', function () {
+	    console.log(`Local video videoWidth: ${this.videoWidth}px,  videoHeight: ${this.videoHeight}px`);
+	});
+	
+	
+	
+	let localStream;
+	let pc1;
+	let whipLocation;
+	const offerOptions = {
+	    offerToReceiveAudio: 1,
+	    offerToReceiveVideo: 1
+	};
+	const configuration = {
+	    iceServers: [
+	        {
+	            urls: "stun:stun.l.google.com:19302"
+	        }
+	    ]
+	};
+	
+	
+	async function start() {
+	    console.log('Requesting local stream');
+	    startButton.disabled = true;
+	    try {
+	        const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: { width: 1280, height: 720, frameRate: 30 } });
+	        console.log('Received local stream');
+	        localVideo.srcObject = stream;
+	        localStream = stream;
+	        callButton.disabled = false;
+	    } catch (e) {
+	        alert(`getUserMedia() error: ${e.name}`);
+	    }
+	}
+	async function call() {
+	    callButton.disabled = true;
+	    hangupButton.disabled = false;
+	    console.log('Starting call');
+	    const videoTracks = localStream.getVideoTracks();
+	    const audioTracks = localStream.getAudioTracks();
+	    if (videoTracks.length > 0) {
+	        console.log(`Using video device: ${videoTracks[0].label}`);
+	    }
+	    if (audioTracks.length > 0) {
+	        console.log(`Using audio device: ${audioTracks[0].label}`);
+	    }
+	
+	
+	    console.log('RTCPeerConnection configuration:', configuration);
+	    pc1 = new RTCPeerConnection(configuration);
+	    console.log('Created local peer connection object pc1');
+	    // pc1.addEventListener('icecandidate', e => onIceCandidate(pc1, e));
+	    //pc1.onicegatheringstatechange = gatheringStateChange;
+	    //pc1.addEventListener('iceconnectionstatechange', e => onIceStateChange(pc1, e));
+	    localCandidata=[];
+		pc1.onicecandidate = function (event) {
+		  if (event.candidate){
+			localCandidata.push(event.candidate);
+			uni.postMessage({
+				data: {
+					data:localCandidata, // 发起方先发candidate
+					type:34567111
+				},
+			});
+		  }
+		}
+		pc1.onconnectionstatechange = function (ev) {
+			uni.postMessage({
+				data: {
+					data:pc1.connectionState, // 发起方先发candidate
+					type:34567
+				},
+			});
+		}
+		localStream.getTracks().forEach(track => pc1.addTrack(track, localStream));
+	    console.log('Added local stream to pc1');
+	
+	
+	    try {
+	        console.log('pc1 createOffer start');
+	        const offer = await pc1.createOffer(offerOptions);
+			uni.postMessage({
+			    data: {
+			        data:offer, // 发起方先发candidate
+					type:345671
+			    },
+			});
+	        await pc1.setLocalDescription(offer);
+	        const answer = await postSDPOffer("https://203.175.169.44:8443/live/user111.whip", pc1.localDescription.sdp);
+	        uni.postMessage({
+	            data: {
+	                data:answer, // 发起方先发candidate
+	        		type:345672
+	            },
+	        });
+			await pc1.setRemoteDescription(answer);
+			console.log('setRemoteDescription');
+	        whipLocation = answer.location;
+	        // await onCreateOfferSuccess(offer);
+	    } catch (e) {
+	        onCreateSessionDescriptionError(e);
+	    }
+	}
+	
+	async function postSDPOffer(url, sdp) {
+	    let result = {
+	        status: 0,
+	        type: 'answer',
+	    };
+	    try {
+	        const response = await fetch(url, {
+	            method: 'POST',
+	            headers: {
+	                'Content-Type': 'application/sdp',
+	                "video-bitrate": 2_000_000,
+	                "video-keyint": 3,
+	                "audio-bitrate": 64_000
+	            },
+	            body: sdp
+	        });
+	        result.status = response.status;
+	        result.sdp = await response.text();
+	        result.location = response.headers.get("Location");
+			uni.postMessage({
+			    data: {
+			        data:JSON.stringify(result), // 发起方先发candidate
+					type:345673
+			    },
+			});
+	    } catch (error) {
+	        result.error = error;
+			uni.postMessage({
+			    data: {
+			        data:JSON.stringify(error), // 发起方先发candidate
+					type:345674
+			    },
+			});
+	    }
+	
+	
+	    return result;
+	}
+	function hangup() {
+	    console.log('Ending call');
+	    pc1.close();
+	    pc1 = null;
+	    hangupButton.disabled = true;
+	    callButton.disabled = false;
+	    fetch(whipLocation, { method: "DELETE" });
+	}
+	
+	window.onunload=releaseTack;
+	</script>
+	
+</html>

+ 74 - 0
hybrid/html/voices/css/index.css

@@ -0,0 +1,74 @@
+* {
+	padding: 0;
+	margin: 0;
+}
+
+.loadinggif {
+	width: 50px;
+	height: 50px;
+	position: fixed;
+	left: 50%;
+	bottom: 50%;
+	margin-left: -25px;
+	margin-top: -25px;
+	z-index: 99;
+}
+
+.Bvideo {
+	display: flex;
+	width: 100%;
+	height: auto;
+	left: 0;
+	top: 0;
+	z-index: 1;
+}
+.Svideo {
+	position: fixed;
+	flex-direction: row;
+	width: 30%;
+	height: auto;
+	left: auto;
+	right: 0;
+	bottom: 0;
+	z-index: 99;
+}
+
+.bottomView{
+	position: fixed;
+	flex-direction: column;
+	justify-content: center;
+	align-items: center;
+	width: 100%;
+	height: 100px;
+	top: auto;
+	bottom: 0;
+	z-index: 999;
+	background-color: rgba(100, 100, 100, 0.5); /* 黑色,50% 透明度 */
+}
+
+.contentInRowC{
+	display: flex;
+	flex-direction: row;
+	justify-content: center;
+	align-items: center;
+}
+.contentColumnC{
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+}
+.iconImg{
+	width: 120px;
+	height: 120px;
+	border-radius: 6px;
+}
+.guadanImg{
+	width: 60px;
+	height: 60px;
+}
+.calling{
+	width: 26px;
+	height: 26px;
+}
+

+ 1 - 0
hybrid/html/voices/css/modules/code.css

@@ -0,0 +1 @@
+html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-view{display:block;position:relative;margin:10px 0;padding:0;border:1px solid #eee;border-left-width:6px;background-color:#fafafa;color:#333;font-family:Courier New;font-size:13px}.layui-code-title{position:relative;padding:0 10px;height:40px;line-height:40px;border-bottom:1px solid #eee;font-size:12px}.layui-code-title>.layui-code-about{position:absolute;right:10px;top:0;color:#b7b7b7}.layui-code-about>a{padding-left:10px}.layui-code-view>.layui-code-ol,.layui-code-view>.layui-code-ul{position:relative;overflow:auto}.layui-code-view>.layui-code-ol>li{position:relative;margin-left:45px;line-height:20px;padding:0 10px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view>.layui-code-ol>li:first-child,.layui-code-view>.layui-code-ul>li:first-child{padding-top:10px}.layui-code-view>.layui-code-ol>li:last-child,.layui-code-view>.layui-code-ul>li:last-child{padding-bottom:10px}.layui-code-view>.layui-code-ul>li{position:relative;line-height:20px;padding:0 10px;list-style-type:none;*list-style-type:none;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-dark{border:1px solid #0c0c0c;border-left-color:#3f3f3f;background-color:#0c0c0c;color:#c2be9e}.layui-code-dark>.layui-code-title{border-bottom:none}.layui-code-dark>.layui-code-ol>li,.layui-code-dark>.layui-code-ul>li{background-color:#3f3f3f;border-left:none}.layui-code-dark>.layui-code-ul>li{margin-left:6px}.layui-code-demo .layui-code{visibility:visible!important;margin:-15px;border-top:none;border-right:none;border-bottom:none}.layui-code-demo .layui-tab-content{padding:15px;border-top:none}

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
hybrid/html/voices/css/modules/laydate/default/laydate.css


BIN
hybrid/html/voices/css/modules/layer/default/icon-ext.png


BIN
hybrid/html/voices/css/modules/layer/default/icon.png


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
hybrid/html/voices/css/modules/layer/default/layer.css


BIN
hybrid/html/voices/css/modules/layer/default/loading-0.gif


BIN
hybrid/html/voices/css/modules/layer/default/loading-1.gif


BIN
hybrid/html/voices/css/modules/layer/default/loading-2.gif


+ 0 - 0
hybrid/html/voices/css/slider.css


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
hybrid/html/voices/css/vant.css


BIN
hybrid/html/voices/img/guaduandd.png


BIN
hybrid/html/voices/img/loading2.gif


BIN
hybrid/html/voices/img/logo.png


+ 267 - 0
hybrid/html/voices/index.html

@@ -0,0 +1,267 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="UTF-8">
+		<meta http-equiv="X-UA-Compatible" content="IE=edge">
+		<meta name="viewport" content="width=device-width, initial-scale=1.0">
+		<link rel="stylesheet" type="text/css" href="./css/index.css" />
+		<title>IM通话</title>
+		<style>
+		html, body {
+		    height: 100%;
+		}
+		body {
+		    margin: 0;
+		}
+		video {
+		    width: 100%;
+		    height: 100%;
+		    position: absolute;
+		    left: 0;
+		    top: 0;
+		    z-index: -1;
+		}
+		
+		</style>
+	</head>
+	<body>
+		<video class="Bvideo" id="Big_video" autoplay></video>
+		<!-- <video class="Svideo" id="sm_video"  preload muted autoplay onclick="Svideoselc()"></video> -->
+		<!-- <audio id="my_audio" autoplay></audio> -->
+		 <div class="bottomView" style="width: 100%;">
+			 <div class="contentColumnC">
+				 <img class="guadanImg" style="margin-top: 5px;" src="./img/guaduandd.png" alt="" onclick="guaduan()"/>
+				 <div class="contentInRowC" style="width: 100%;margin-top: 10px;">
+					 <div id="markNote"></div>
+					 <img class="calling" src="./img/loading2.gif" alt="" />
+				 </div>
+			 </div>
+		 </div>
+	</body>
+	<script type="text/javascript" src="./js/lib/uniwebviewsdk.js"></script>
+	<script>
+	let localStream = null;
+	let localCall = 0;
+	let localCandidata=null;
+	let peer = null;
+	let video=null;
+	//const Big_video = document.getElementById('Big_video');
+	// const sm_video = document.getElementById('sm_video');
+	// const my_audio = document.getElementById('my_audio');
+	const markNote = document.getElementById('markNote');
+	//====================================================
+	// function Bvideoselc(){
+	// 	if(localStream!=null){
+	// 		//Big_video.srcObject =localStream;
+	// 		Big_video.setAttribute('autoplay', true); /* THIS */
+	// 	}
+	// }
+	function Svideoselc(){
+		if(localStream!=null){
+			//sm_video.srcObject =localStream;
+			sm_video.setAttribute('autoplay', true); /* THIS */
+		}
+		
+	}
+	function guaduan(){
+		uni.postMessage({
+		    data: {
+		        data:'', // 回传
+				type:88
+		    },
+		});
+	}
+	//====================================================
+	function appAct (obj) {
+		if(obj.type==1){//主动发起im通话
+			localCall=1;
+			startWebRct(obj.type);
+			markNote.innerHTML='拨打中'
+		}
+		else if(obj.type==2){//收到推送消息
+			if(localCall==1){
+				markNote.innerHTML='接通中'
+				RCremoteData(obj.payload);
+			}
+			else{
+				RCstartWebRct(obj.payload);
+			}
+		}
+		else if(obj.type==3){//收到candidate
+			markNote.innerHTML='接通中'
+			for(var i=0;i<obj.payload.length;i++){
+				peer.addIceCandidate(obj.payload[i]);
+			}
+			if(localCall!=1){
+				uni.postMessage({
+				    data: {
+				        data:localCandidata, //应答方回应candidate
+						type:3
+				    },
+				});
+			}
+			
+		}
+	}
+	
+	async function startCapture(displayMediaOptions) {
+	    try {
+	        localStream = await navigator.mediaDevices.getUserMedia(displayMediaOptions);
+			// var otherVideos = document.querySelector('#Big_video');
+			// otherVideos.srcObject = localStream;
+			uni.postMessage({
+			    data: {
+			        data:'', // 回传
+					type:99
+			    },
+			});
+	    } catch(err) {
+	        console.error(err);
+	    }
+	}
+	async function startWebRct(type){
+		peer = new RTCPeerConnection(
+			{
+				iceServers:[
+					{
+						urls:'stun:stun.l.google.com:19302',
+					}
+				]
+			}
+		);
+		//添加本地音视频
+		localStream.getTracks().forEach((track) => {
+		  peer.addTrack(track, localStream)
+		});
+		//创建本地offer
+		const offer = peer.createOffer({
+			offerToReceiveAudio:1,
+			offerToReceiveVideo:1
+		});
+		//记录本地offer
+		offer.then(value => {
+			peer.setLocalDescription(value);
+			uni.postMessage({
+			    data: {
+			        data:value, // 回传并推送offer
+					type:2
+			    },
+			});
+		}).catch(error => {
+		});
+		peer.oniceconnectionstatechange = function (ev) {
+			if(peer.connectionState=="closed"){
+				markNote.innerHTML='结束通话'
+			}
+			if(peer.connectionState=="connected"){
+				markNote.innerHTML='已接通'
+			}
+			if(peer.connectionState=="connecting"){
+				markNote.innerHTML='连接中'
+			}
+			if(peer.connectionState=="disconnected"){
+				markNote.innerHTML='对方挂断'
+			}
+		};
+		localCandidata=[]
+		peer.onicecandidate = function (event) {
+		  if (event.candidate){
+			localCandidata.push(event.candidate);
+		  }
+		}
+		startCommunicate();
+	}
+	
+	async function RCremoteData(rcData){//收到remoteAnswer
+		//记录远端offer
+		await peer.setRemoteDescription(rcData)
+		
+		uni.postMessage({
+		    data: {
+		        data:localCandidata, // 发起方先发candidate
+				type:3
+		    },
+		});
+	}
+	function startCommunicate(){
+		peer.ontrack = (e) => {
+			if(e.streams[0]){
+				//var otherVideos = document.querySelector('#my_audio');
+				var otherVideos = document.querySelector('#Big_video');
+				otherVideos.srcObject = e.streams[0];
+				//markNote.innerHTML=e.streams[0];
+				//Big_video.srcObject=e.streams[0];
+				//Big_video.setAttribute('autoplay', true); /* THIS */
+			}
+			
+			// sm_video.srcObject =localStream;
+			// sm_video.setAttribute('autoplay', true); /* THIS */
+			
+			
+			// if(video!=null){
+			// 	video.srcObject = e.streams[0];
+			// 	video.setAttribute('autoplay', true); /* THIS */
+			// }
+			// else{
+			// 	video = document.createElement("video");
+			// 	video.srcObject = e.streams[0];
+			// 	video.setAttribute('autoplay', true); /* THIS */
+			// 	document.body.appendChild(video);
+			// }
+		}
+	}
+	async function RCstartWebRct(payload){
+		peer = new RTCPeerConnection(
+			{
+				iceServers:[
+					{
+						urls:'stun:stun.l.google.com:19302',
+					}
+				]
+			}
+		);
+		//添加本地音视频
+		localStream.getTracks().forEach((track) => {
+		  peer.addTrack(track, localStream)
+		})
+		localCandidata=[];
+		peer.onicecandidate = function (event) {
+		  if (event.candidate){
+			//let strcandidate=JSON.stringify(event.candidate);
+			localCandidata.push(event.candidate);
+		  }
+		}
+		startCommunicate();
+		//记录远端offer
+		await peer.setRemoteDescription(payload)
+		
+		const remoteAnswer = await peer.createAnswer();
+		//记录本地offer
+		await peer.setLocalDescription(remoteAnswer);
+		//推送remoteAnswer
+		uni.postMessage({
+		    data: {
+		        data:remoteAnswer, // 回传并推送offer
+				type:2
+		    },
+		});
+		
+	}
+	function initRtc() {
+		markNote.innerHTML='IM通话'
+		setTimeout(() => {
+			startCapture({ video: true, audio: true});
+			//startCapture({audio: true});
+		}, 1000)
+		return;
+	}
+	function releaseTack(){
+		if(peer){
+			peer.close();
+		}
+	}
+	window.onload=initRtc;
+	window.onunload=releaseTack;
+	</script>
+	
+</html>

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
hybrid/html/voices/js/lib/uniwebviewsdk.js


+ 71 - 0
hybrid/html/voices/xuanfc.html

@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="UTF-8">
+		<meta http-equiv="X-UA-Compatible" content="IE=edge">
+		<meta name="viewport" content="width=device-width, initial-scale=1.0">
+		<link rel="stylesheet" type="text/css" href="./css/index.css" />
+		<title>悬浮</title>
+		<style>
+		html, body {
+		    height: 100%;
+		}
+		body {
+		    margin: 0;
+		}
+		video {
+		    width: 100%;
+		    height: 100%;
+		    position: absolute;
+		    left: 0;
+		    top: 0;
+		    z-index: -1;
+		}
+		
+		</style>
+	</head>
+	<body>
+		<audio id="my_audio" autoplay></audio>
+		 <div class="bottomView" style="width: 100%;">
+			 <div class="contentColumnC">
+				 <img class="guadanImg" style="margin-top: 5px;" src="./img/guaduandd.png" alt="" onclick="changeImg()"/>
+				 <div class="contentInRowC" style="width: 100%;margin-top: 10px;">
+					 <div id="markNote">打电话</div>
+					 <img class="calling" src="./img/loading2.gif" alt="" />
+				 </div>
+			 </div>
+		 </div>
+	</body>
+	<script type="text/javascript" src="./js/lib/uniwebviewsdk.js"></script>
+	<script>
+	let localStream = null;
+	const markNote = document.getElementById('markNote');
+	
+	function guaduan(){
+		var dic = {
+			"key": 1
+		}
+		var jsonStr = JSON.stringify(dic)
+		try {
+			window.webkit.messageHandlers.sendData.postMessage(jsonStr); //ios
+		} catch (e) {}
+	}
+	
+	
+	//====================================================
+	function appAct (obj) {
+		
+	}
+	function initRtc(){
+		uni.postMessage({
+		    data: {
+		        data:'初始化', // 回传
+				type:88
+		    },
+		});
+	}
+	window.onload=initRtc;
+	window.onunload=releaseTack;
+	</script>
+	
+</html>

+ 5649 - 0
hybrid/html/xuanfu/css/mui.css

@@ -0,0 +1,5649 @@
+/*!
+ * =====================================================
+ * Mui v3.7.3 (http://dev.dcloud.net.cn/mui)
+ * =====================================================
+ */
+
+/*! normalize.css v3.0.1 | MIT License | git.io/normalize */
+html
+{
+    font-family: sans-serif;
+
+    -webkit-text-size-adjust: 100%;
+}
+
+body
+{
+    margin: 0;
+}
+
+body::after
+{
+    position: fixed;
+    top: -1000px;
+    left: -1000px;
+
+    content: '';
+    -webkit-animation: shadow-preload .1s;
+            animation: shadow-preload .1s;
+    -webkit-animation-delay: 3s;
+            animation-delay: 3s;
+}
+
+@-webkit-keyframes shadow-preload
+{
+    0%
+    {
+        background-image: url(https://cdn.dcloud.net.cn/img/mui-shadow-grey.png);
+    }
+
+    100%
+    {
+        background-image: url(https://cdn.dcloud.net.cn/img/mui-shadow-grey.png);
+    }
+}
+@keyframes shadow-preload
+{
+    0%
+    {
+        background-image: url(https://cdn.dcloud.net.cn/img/mui-shadow-grey.png);
+    }
+
+    100%
+    {
+        background-image: url(https://cdn.dcloud.net.cn/img/mui-shadow-grey.png);
+    }
+}
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+nav,
+section,
+summary
+{
+    display: block;
+}
+
+audio,
+canvas,
+progress,
+video
+{
+    display: inline-block;
+
+    vertical-align: baseline;
+}
+
+audio:not([controls])
+{
+    display: none;
+
+    height: 0;
+}
+
+[hidden],
+template
+{
+    display: none;
+}
+
+a
+{
+    background: transparent;
+}
+
+a:active,
+a:hover
+{
+    outline: 0;
+}
+
+abbr[title]
+{
+    border-bottom: 1px dotted;
+}
+
+b,
+strong
+{
+    font-weight: bold;
+}
+
+dfn
+{
+    font-style: italic;
+}
+
+h1
+{
+    font-size: 2em;
+
+    margin: .67em 0;
+}
+
+mark
+{
+    color: #000;
+    background: #ff0;
+}
+
+small
+{
+    font-size: 80%;
+}
+
+sub,
+sup
+{
+    font-size: 75%;
+    line-height: 0;
+
+    position: relative;
+
+    vertical-align: baseline;
+}
+
+sup
+{
+    top: -.5em;
+}
+
+sub
+{
+    bottom: -.25em;
+}
+
+img
+{
+    border: 0;
+}
+
+svg:not(:root)
+{
+    overflow: hidden;
+}
+
+figure
+{
+    margin: 1em 40px;
+}
+
+hr
+{
+    box-sizing: content-box;
+    height: 0;
+}
+
+pre
+{
+    overflow: auto;
+}
+
+code,
+kbd,
+pre,
+samp
+{
+    font-family: monospace, monospace;
+    font-size: 1em;
+}
+
+button,
+input,
+optgroup,
+select,
+textarea
+{
+    font: inherit;
+
+    margin: 0;
+
+    color: inherit;
+}
+
+button
+{
+    overflow: visible;
+}
+
+button,
+select
+{
+    text-transform: none;
+}
+
+button,
+html input[type='button'],
+input[type='reset'],
+input[type='submit']
+{
+    cursor: pointer;
+
+    -webkit-appearance: button;
+}
+
+button[disabled],
+html input[disabled]
+{
+    cursor: default;
+}
+
+input
+{
+    line-height: normal;
+}
+
+input[type='checkbox'],
+input[type='radio']
+{
+    box-sizing: border-box;
+    padding: 0;
+}
+
+input[type='number']::-webkit-inner-spin-button,
+input[type='number']::-webkit-outer-spin-button
+{
+    height: auto;
+}
+
+input[type='search']
+{
+    -webkit-box-sizing: content-box;
+            box-sizing: content-box;
+
+    -webkit-appearance: textfield;
+}
+
+input[type='search']::-webkit-search-cancel-button,
+input[type='search']::-webkit-search-decoration
+{
+    -webkit-appearance: none;
+}
+
+fieldset
+{
+    margin: 0 2px;
+    padding: .35em .625em .75em;
+
+    border: 1px solid #c0c0c0;
+}
+
+legend
+{
+    padding: 0;
+
+    border: 0;
+}
+
+textarea
+{
+    overflow: auto;
+}
+
+optgroup
+{
+    font-weight: bold;
+}
+
+table
+{
+    border-spacing: 0;
+    border-collapse: collapse;
+}
+
+td,
+th
+{
+    padding: 0;
+}
+
+*
+{
+    -webkit-box-sizing: border-box;
+            box-sizing: border-box;
+
+    -webkit-user-select: none;
+
+    outline: none;
+
+    -webkit-tap-highlight-color: transparent;
+    -webkit-tap-highlight-color: transparent;
+}
+
+body
+{
+    font-family: 'Helvetica Neue', Helvetica, sans-serif;
+    font-size: 17px;
+    line-height: 21px;
+
+    color: #000;
+    background-color: #efeff4;
+
+    -webkit-overflow-scrolling: touch;
+}
+
+a
+{
+    text-decoration: none;
+
+    color: #007aff;
+}
+a:active
+{
+    color: #0062cc;
+}
+
+.mui-content
+{
+    background-color: #efeff4;
+
+    -webkit-overflow-scrolling: touch;
+}
+
+.mui-bar-nav ~ .mui-content
+{
+    padding-top: 44px;
+}
+.mui-bar-nav ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
+{
+    top: 44px;
+}
+
+.mui-bar-header-secondary ~ .mui-content
+{
+    padding-top: 88px;
+}
+.mui-bar-header-secondary ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
+{
+    top: 88px;
+}
+
+.mui-bar-footer ~ .mui-content
+{
+    padding-bottom: 44px;
+}
+.mui-bar-footer ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
+{
+    bottom: 44px;
+}
+
+.mui-bar-footer-secondary ~ .mui-content
+{
+    padding-bottom: 88px;
+}
+.mui-bar-footer-secondary ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
+{
+    bottom: 88px;
+}
+
+.mui-bar-tab ~ .mui-content
+{
+    padding-bottom: 50px;
+}
+.mui-bar-tab ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
+{
+    bottom: 50px;
+}
+
+.mui-bar-footer-secondary-tab ~ .mui-content
+{
+    padding-bottom: 94px;
+}
+.mui-bar-footer-secondary-tab ~ .mui-content.mui-scroll-wrapper .mui-scrollbar-vertical
+{
+    bottom: 94px;
+}
+
+.mui-content-padded
+{
+    margin: 10px;
+}
+
+.mui-inline
+{
+    display: inline-block;
+
+    vertical-align: top;
+}
+
+.mui-block
+{
+    display: block !important;
+}
+
+.mui-visibility
+{
+    visibility: visible !important;
+}
+
+.mui-hidden
+{
+    display: none !important;
+}
+
+.mui-ellipsis
+{
+    overflow: hidden;
+
+    white-space: nowrap;
+    text-overflow: ellipsis;
+}
+
+.mui-ellipsis-2
+{
+    display: -webkit-box;
+    overflow: hidden;
+
+    white-space: normal !important;
+    text-overflow: ellipsis;
+    word-wrap: break-word;
+
+    -webkit-line-clamp: 2;
+    -webkit-box-orient: vertical;
+}
+
+.mui-table
+{
+    display: table;
+
+    width: 100%;
+
+    table-layout: fixed;
+}
+
+.mui-table-cell
+{
+    position: relative;
+
+    display: table-cell;
+}
+
+.mui-text-left
+{
+    text-align: left !important;
+}
+
+.mui-text-center
+{
+    text-align: center !important;
+}
+
+.mui-text-justify
+{
+    text-align: justify !important;
+}
+
+.mui-text-right
+{
+    text-align: right !important;
+}
+
+.mui-pull-left
+{
+    float: left;
+}
+
+.mui-pull-right
+{
+    float: right;
+}
+
+.mui-list-unstyled
+{
+    padding-left: 0;
+
+    list-style: none;
+}
+
+.mui-list-inline
+{
+    margin-left: -5px;
+    padding-left: 0;
+
+    list-style: none;
+}
+
+.mui-list-inline > li
+{
+    display: inline-block;
+
+    padding-right: 5px;
+    padding-left: 5px;
+}
+
+.mui-clearfix:before, .mui-clearfix:after
+{
+    display: table;
+
+    content: ' ';
+}
+.mui-clearfix:after
+{
+    clear: both;
+}
+
+.mui-bg-primary
+{
+    background-color: #007aff;
+}
+
+.mui-bg-positive
+{
+    background-color: #4cd964;
+}
+
+.mui-bg-negative
+{
+    background-color: #dd524d;
+}
+
+.mui-error
+{
+    margin: 88px 35px;
+    padding: 10px;
+
+    border-radius: 6px;
+    background-color: #bbb;
+}
+
+.mui-subtitle
+{
+    font-size: 15px;
+}
+
+h1, h2, h3, h4, h5, h6
+{
+    line-height: 1;
+
+    margin-top: 5px;
+    margin-bottom: 5px;
+}
+
+h1, .mui-h1
+{
+    font-size: 36px;
+}
+
+h2, .mui-h2
+{
+    font-size: 30px;
+}
+
+h3, .mui-h3
+{
+    font-size: 24px;
+}
+
+h4, .mui-h4
+{
+    font-size: 18px;
+}
+
+h5, .mui-h5
+{
+    font-size: 14px;
+    font-weight: normal;
+
+    color: #8f8f94;
+}
+
+h6, .mui-h6
+{
+    font-size: 12px;
+    font-weight: normal;
+
+    color: #8f8f94;
+}
+
+p
+{
+    font-size: 14px;
+
+    margin-top: 0;
+    margin-bottom: 10px;
+
+    color: #8f8f94;
+}
+
+.mui-row:before, .mui-row:after
+{
+    display: table;
+
+    content: ' ';
+}
+.mui-row:after
+{
+    clear: both;
+}
+
+.mui-col-xs-1, .mui-col-sm-1, .mui-col-xs-2, .mui-col-sm-2, .mui-col-xs-3, .mui-col-sm-3, .mui-col-xs-4, .mui-col-sm-4, .mui-col-xs-5, .mui-col-sm-5, .mui-col-xs-6, .mui-col-sm-6, .mui-col-xs-7, .mui-col-sm-7, .mui-col-xs-8, .mui-col-sm-8, .mui-col-xs-9, .mui-col-sm-9, .mui-col-xs-10, .mui-col-sm-10, .mui-col-xs-11, .mui-col-sm-11, .mui-col-xs-12, .mui-col-sm-12
+{
+    position: relative;
+
+    min-height: 1px;
+}
+
+.mui-row > [class*='mui-col-']
+{
+    float: left;
+}
+
+.mui-col-xs-12
+{
+    width: 100%;
+}
+
+.mui-col-xs-11
+{
+    width: 91.66666667%;
+}
+
+.mui-col-xs-10
+{
+    width: 83.33333333%;
+}
+
+.mui-col-xs-9
+{
+    width: 75%;
+}
+
+.mui-col-xs-8
+{
+    width: 66.66666667%;
+}
+
+.mui-col-xs-7
+{
+    width: 58.33333333%;
+}
+
+.mui-col-xs-6
+{
+    width: 50%;
+}
+
+.mui-col-xs-5
+{
+    width: 41.66666667%;
+}
+
+.mui-col-xs-4
+{
+    width: 33.33333333%;
+}
+
+.mui-col-xs-3
+{
+    width: 25%;
+}
+
+.mui-col-xs-2
+{
+    width: 16.66666667%;
+}
+
+.mui-col-xs-1
+{
+    width: 8.33333333%;
+}
+
+@media (min-width: 400px)
+{
+    .mui-col-sm-12
+    {
+        width: 100%;
+    }
+
+    .mui-col-sm-11
+    {
+        width: 91.66666667%;
+    }
+
+    .mui-col-sm-10
+    {
+        width: 83.33333333%;
+    }
+
+    .mui-col-sm-9
+    {
+        width: 75%;
+    }
+
+    .mui-col-sm-8
+    {
+        width: 66.66666667%;
+    }
+
+    .mui-col-sm-7
+    {
+        width: 58.33333333%;
+    }
+
+    .mui-col-sm-6
+    {
+        width: 50%;
+    }
+
+    .mui-col-sm-5
+    {
+        width: 41.66666667%;
+    }
+
+    .mui-col-sm-4
+    {
+        width: 33.33333333%;
+    }
+
+    .mui-col-sm-3
+    {
+        width: 25%;
+    }
+
+    .mui-col-sm-2
+    {
+        width: 16.66666667%;
+    }
+
+    .mui-col-sm-1
+    {
+        width: 8.33333333%;
+    }
+}
+.mui-scroll-wrapper
+{
+    position: absolute;
+    z-index: 2;
+    top: 0;
+    bottom: 0;
+    left: 0;
+
+    overflow: hidden;
+
+    width: 100%;
+}
+
+.mui-scroll
+{
+    position: absolute;
+    z-index: 1;
+
+    width: 100%;
+}
+
+.mui-scrollbar
+{
+    position: absolute;
+    z-index: 9998;
+
+    overflow: hidden;
+
+    -webkit-transition: 500ms;
+            transition: 500ms;
+    transform: translateZ(0px);
+    pointer-events: none;
+
+    opacity: 0;
+}
+
+.mui-scrollbar-vertical
+{
+    top: 0;
+    right: 1px;
+    bottom: 2px;
+
+    width: 4px;
+}
+.mui-scrollbar-vertical .mui-scrollbar-indicator
+{
+    width: 100%;
+}
+
+.mui-scrollbar-horizontal
+{
+    right: 2px;
+    bottom: 0;
+    left: 2px;
+
+    height: 4px;
+}
+.mui-scrollbar-horizontal .mui-scrollbar-indicator
+{
+    height: 100%;
+}
+
+.mui-scrollbar-indicator
+{
+    position: absolute;
+
+    display: block;
+
+    box-sizing: border-box;
+
+    -webkit-transition: .01s cubic-bezier(.1, .57, .1, 1);
+            transition: .01s cubic-bezier(.1, .57, .1, 1);
+    transform: translate(0px, 0px) translateZ(0px);
+
+    border: 1px solid rgba(255, 255, 255, .80196);
+    border-radius: 2px;
+    background: rgba(0, 0, 0, .39804);
+}
+
+.mui-plus-pullrefresh .mui-fullscreen .mui-scroll-wrapper .mui-scroll-wrapper, .mui-plus-pullrefresh .mui-fullscreen .mui-slider-group .mui-scroll-wrapper
+{
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 0;
+
+    overflow: hidden;
+
+    width: 100%;
+}
+.mui-plus-pullrefresh .mui-fullscreen .mui-scroll-wrapper .mui-scroll, .mui-plus-pullrefresh .mui-fullscreen .mui-slider-group .mui-scroll
+{
+    position: absolute;
+
+    width: 100%;
+}
+.mui-plus-pullrefresh .mui-scroll-wrapper, .mui-plus-pullrefresh .mui-slider-group
+{
+    position: static;
+    top: auto;
+    bottom: auto;
+    left: auto;
+
+    overflow: auto;
+
+    width: auto;
+}
+.mui-plus-pullrefresh .mui-slider-group
+{
+    overflow: visible;
+}
+.mui-plus-pullrefresh .mui-scroll
+{
+    position: static;
+
+    width: auto;
+}
+
+.mui-off-canvas-wrap .mui-bar
+{
+    position: absolute !important;
+
+    -webkit-transform: translate3d(0, 0, 0);
+            transform: translate3d(0, 0, 0);
+
+    -webkit-box-shadow: none;
+            box-shadow: none;
+}
+
+.mui-off-canvas-wrap
+{
+    position: relative;
+    z-index: 1;
+
+    overflow: hidden;
+
+    width: 100%;
+    height: 100%;
+}
+.mui-off-canvas-wrap .mui-inner-wrap
+{
+    position: relative;
+    z-index: 1;
+
+    width: 100%;
+    height: 100%;
+}
+.mui-off-canvas-wrap .mui-inner-wrap.mui-transitioning
+{
+    -webkit-transition: -webkit-transform 350ms;
+            transition:         transform 350ms cubic-bezier(.165, .84, .44, 1);
+}
+.mui-off-canvas-wrap .mui-inner-wrap .mui-off-canvas-left
+{
+    -webkit-transform: translate3d(-100%, 0, 0);
+            transform: translate3d(-100%, 0, 0);
+}
+.mui-off-canvas-wrap .mui-inner-wrap .mui-off-canvas-right
+{
+    -webkit-transform: translate3d(100%, 0, 0);
+            transform: translate3d(100%, 0, 0);
+}
+.mui-off-canvas-wrap.mui-active
+{
+    overflow: hidden;
+
+    height: 100%;
+}
+.mui-off-canvas-wrap.mui-active .mui-off-canvas-backdrop
+{
+    position: absolute;
+    z-index: 998;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    display: block;
+
+    transition: background 350ms cubic-bezier(.165, .84, .44, 1);
+
+    background: rgba(0, 0, 0, .4);
+    box-shadow: -4px 0 4px rgba(0, 0, 0, .5), 4px 0 4px rgba(0, 0, 0, .5);
+
+    -webkit-tap-highlight-color: transparent;
+}
+.mui-off-canvas-wrap.mui-slide-in .mui-off-canvas-right
+{
+    z-index: 10000 !important;
+
+    -webkit-transform: translate3d(100%, 0px, 0px);
+}
+.mui-off-canvas-wrap.mui-slide-in .mui-off-canvas-left
+{
+    z-index: 10000 !important;
+
+    -webkit-transform: translate3d(-100%, 0px, 0px);
+}
+
+.mui-off-canvas-left, .mui-off-canvas-right
+{
+    position: absolute;
+    z-index: -1;
+    top: 0;
+    bottom: 0;
+
+    visibility: hidden;
+
+    box-sizing: content-box;
+    width: 70%;
+    min-height: 100%;
+
+    background: #333;
+
+    -webkit-overflow-scrolling: touch;
+}
+.mui-off-canvas-left.mui-transitioning, .mui-off-canvas-right.mui-transitioning
+{
+    -webkit-transition: -webkit-transform 350ms cubic-bezier(.165, .84, .44, 1);
+            transition:         transform 350ms cubic-bezier(.165, .84, .44, 1);
+}
+
+.mui-off-canvas-left
+{
+    left: 0;
+}
+
+.mui-off-canvas-right
+{
+    right: 0;
+}
+
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable
+{
+    background-color: #333;
+}
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-left, .mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-right
+{
+    width: 80%;
+
+    -webkit-transform: scale(.8);
+            transform: scale(.8);
+
+    opacity: .1;
+}
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-left.mui-transitioning, .mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-right.mui-transitioning
+{
+    -webkit-transition: -webkit-transform 350ms cubic-bezier(.165, .84, .44, 1), opacity 350ms cubic-bezier(.165, .84, .44, 1);
+            transition:         transform 350ms cubic-bezier(.165, .84, .44, 1), opacity 350ms cubic-bezier(.165, .84, .44, 1);
+}
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-left
+{
+    -webkit-transform-origin: -100%;
+            transform-origin: -100%;
+}
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable > .mui-off-canvas-right
+{
+    -webkit-transform-origin: 200%;
+            transform-origin: 200%;
+}
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active > .mui-inner-wrap
+{
+    -webkit-transform: scale(.8);
+            transform: scale(.8);
+}
+.mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active > .mui-off-canvas-left, .mui-off-canvas-wrap:not(.mui-slide-in).mui-scalable.mui-active > .mui-off-canvas-right
+{
+    -webkit-transform: scale(1);
+            transform: scale(1);
+
+    opacity: 1;
+}
+
+.mui-loading .mui-spinner
+{
+    display: block;
+
+    margin: 0 auto;
+}
+
+.mui-spinner
+{
+    display: inline-block;
+
+    width: 24px;
+    height: 24px;
+
+    -webkit-transform-origin: 50%;
+            transform-origin: 50%;
+    -webkit-animation: spinner-spin 1s step-end infinite;
+            animation: spinner-spin 1s step-end infinite;
+}
+
+.mui-spinner:after
+{
+    display: block;
+
+    width: 100%;
+    height: 100%;
+
+    content: '';
+
+    background-image: url('data:image/svg+xml;charset=utf-8,<svg viewBox=\'0 0 120 120\' xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\'><defs><line id=\'l\' x1=\'60\' x2=\'60\' y1=\'7\' y2=\'27\' stroke=\'%236c6c6c\' stroke-width=\'11\' stroke-linecap=\'round\'/></defs><g><use xlink:href=\'%23l\' opacity=\'.27\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(30 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(60 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(90 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(120 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(150 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.37\' transform=\'rotate(180 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.46\' transform=\'rotate(210 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.56\' transform=\'rotate(240 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.66\' transform=\'rotate(270 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.75\' transform=\'rotate(300 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.85\' transform=\'rotate(330 60,60)\'/></g></svg>');
+    background-repeat: no-repeat;
+    background-position: 50%;
+    background-size: 100%;
+}
+
+.mui-spinner-white:after
+{
+    background-image: url('data:image/svg+xml;charset=utf-8,<svg viewBox=\'0 0 120 120\' xmlns=\'http://www.w3.org/2000/svg\' xmlns:xlink=\'http://www.w3.org/1999/xlink\'><defs><line id=\'l\' x1=\'60\' x2=\'60\' y1=\'7\' y2=\'27\' stroke=\'%23fff\' stroke-width=\'11\' stroke-linecap=\'round\'/></defs><g><use xlink:href=\'%23l\' opacity=\'.27\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(30 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(60 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(90 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(120 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.27\' transform=\'rotate(150 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.37\' transform=\'rotate(180 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.46\' transform=\'rotate(210 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.56\' transform=\'rotate(240 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.66\' transform=\'rotate(270 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.75\' transform=\'rotate(300 60,60)\'/><use xlink:href=\'%23l\' opacity=\'.85\' transform=\'rotate(330 60,60)\'/></g></svg>');
+}
+
+@-webkit-keyframes spinner-spin
+{
+    0%
+    {
+        -webkit-transform: rotate(0deg);
+    }
+
+    8.33333333%
+    {
+        -webkit-transform: rotate(30deg);
+    }
+
+    16.66666667%
+    {
+        -webkit-transform: rotate(60deg);
+    }
+
+    25%
+    {
+        -webkit-transform: rotate(90deg);
+    }
+
+    33.33333333%
+    {
+        -webkit-transform: rotate(120deg);
+    }
+
+    41.66666667%
+    {
+        -webkit-transform: rotate(150deg);
+    }
+
+    50%
+    {
+        -webkit-transform: rotate(180deg);
+    }
+
+    58.33333333%
+    {
+        -webkit-transform: rotate(210deg);
+    }
+
+    66.66666667%
+    {
+        -webkit-transform: rotate(240deg);
+    }
+
+    75%
+    {
+        -webkit-transform: rotate(270deg);
+    }
+
+    83.33333333%
+    {
+        -webkit-transform: rotate(300deg);
+    }
+
+    91.66666667%
+    {
+        -webkit-transform: rotate(330deg);
+    }
+
+    100%
+    {
+        -webkit-transform: rotate(360deg);
+    }
+}
+@keyframes spinner-spin
+{
+    0%
+    {
+        transform: rotate(0deg);
+    }
+
+    8.33333333%
+    {
+        transform: rotate(30deg);
+    }
+
+    16.66666667%
+    {
+        transform: rotate(60deg);
+    }
+
+    25%
+    {
+        transform: rotate(90deg);
+    }
+
+    33.33333333%
+    {
+        transform: rotate(120deg);
+    }
+
+    41.66666667%
+    {
+        transform: rotate(150deg);
+    }
+
+    50%
+    {
+        transform: rotate(180deg);
+    }
+
+    58.33333333%
+    {
+        transform: rotate(210deg);
+    }
+
+    66.66666667%
+    {
+        transform: rotate(240deg);
+    }
+
+    75%
+    {
+        transform: rotate(270deg);
+    }
+
+    83.33333333%
+    {
+        transform: rotate(300deg);
+    }
+
+    91.66666667%
+    {
+        transform: rotate(330deg);
+    }
+
+    100%
+    {
+        transform: rotate(360deg);
+    }
+}
+input[type='button'],
+input[type='submit'],
+input[type='reset'],
+button,
+.mui-btn
+{
+    font-size: 14px;
+    font-weight: 400;
+    line-height: 1.42;
+
+    position: relative;
+
+    display: inline-block;
+
+    margin-bottom: 0;
+    padding: 6px 12px;
+
+    cursor: pointer;
+    -webkit-transition: all;
+            transition: all;
+    -webkit-transition-timing-function: linear;
+            transition-timing-function: linear;
+    -webkit-transition-duration: .2s;
+            transition-duration: .2s;
+    text-align: center;
+    vertical-align: top;
+    white-space: nowrap;
+
+    color: #333;
+    border: 1px solid #ccc;
+    border-radius: 3px;
+    border-top-left-radius: 3px;
+    border-top-right-radius: 3px;
+    border-bottom-right-radius: 3px;
+    border-bottom-left-radius: 3px;
+    background-color: #fff;
+    background-clip: padding-box;
+}
+input[type='button']:enabled:active, input[type='button'].mui-active:enabled,
+input[type='submit']:enabled:active,
+input[type='submit'].mui-active:enabled,
+input[type='reset']:enabled:active,
+input[type='reset'].mui-active:enabled,
+button:enabled:active,
+button.mui-active:enabled,
+.mui-btn:enabled:active,
+.mui-btn.mui-active:enabled
+{
+    color: #fff;
+    background-color: #929292;
+}
+input[type='button']:disabled, input[type='button'].mui-disabled,
+input[type='submit']:disabled,
+input[type='submit'].mui-disabled,
+input[type='reset']:disabled,
+input[type='reset'].mui-disabled,
+button:disabled,
+button.mui-disabled,
+.mui-btn:disabled,
+.mui-btn.mui-disabled
+{
+    opacity: .6;
+}
+
+input[type='submit'],
+.mui-btn-primary,
+.mui-btn-blue
+{
+    color: #fff;
+    border: 1px solid #007aff;
+    background-color: #007aff;
+}
+input[type='submit']:enabled:active, input[type='submit'].mui-active:enabled,
+.mui-btn-primary:enabled:active,
+.mui-btn-primary.mui-active:enabled,
+.mui-btn-blue:enabled:active,
+.mui-btn-blue.mui-active:enabled
+{
+    color: #fff;
+    border: 1px solid #0062cc;
+    background-color: #0062cc;
+}
+
+.mui-btn-positive,
+.mui-btn-success,
+.mui-btn-green
+{
+    color: #fff;
+    border: 1px solid #4cd964;
+    background-color: #4cd964;
+}
+.mui-btn-positive:enabled:active, .mui-btn-positive.mui-active:enabled,
+.mui-btn-success:enabled:active,
+.mui-btn-success.mui-active:enabled,
+.mui-btn-green:enabled:active,
+.mui-btn-green.mui-active:enabled
+{
+    color: #fff;
+    border: 1px solid #2ac845;
+    background-color: #2ac845;
+}
+
+.mui-btn-warning,
+.mui-btn-yellow
+{
+    color: #fff;
+    border: 1px solid #f0ad4e;
+    background-color: #f0ad4e;
+}
+.mui-btn-warning:enabled:active, .mui-btn-warning.mui-active:enabled,
+.mui-btn-yellow:enabled:active,
+.mui-btn-yellow.mui-active:enabled
+{
+    color: #fff;
+    border: 1px solid #ec971f;
+    background-color: #ec971f;
+}
+
+.mui-btn-negative,
+.mui-btn-danger,
+.mui-btn-red
+{
+    color: #fff;
+    border: 1px solid #dd524d;
+    background-color: #dd524d;
+}
+.mui-btn-negative:enabled:active, .mui-btn-negative.mui-active:enabled,
+.mui-btn-danger:enabled:active,
+.mui-btn-danger.mui-active:enabled,
+.mui-btn-red:enabled:active,
+.mui-btn-red.mui-active:enabled
+{
+    color: #fff;
+    border: 1px solid #cf2d28;
+    background-color: #cf2d28;
+}
+
+.mui-btn-royal,
+.mui-btn-purple
+{
+    color: #fff;
+    border: 1px solid #8a6de9;
+    background-color: #8a6de9;
+}
+.mui-btn-royal:enabled:active, .mui-btn-royal.mui-active:enabled,
+.mui-btn-purple:enabled:active,
+.mui-btn-purple.mui-active:enabled
+{
+    color: #fff;
+    border: 1px solid #6641e2;
+    background-color: #6641e2;
+}
+
+.mui-btn-grey
+{
+    color: #fff;
+    border: 1px solid #c7c7cc;
+    background-color: #c7c7cc;
+}
+.mui-btn-grey:enabled:active, .mui-btn-grey.mui-active:enabled
+{
+    color: #fff;
+    border: 1px solid #acacb4;
+    background-color: #acacb4;
+}
+
+.mui-btn-outlined
+{
+    background-color: transparent;
+}
+.mui-btn-outlined.mui-btn-primary, .mui-btn-outlined.mui-btn-blue
+{
+    color: #007aff;
+}
+.mui-btn-outlined.mui-btn-positive, .mui-btn-outlined.mui-btn-success, .mui-btn-outlined.mui-btn-green
+{
+    color: #4cd964;
+}
+.mui-btn-outlined.mui-btn-warning, .mui-btn-outlined.mui-btn-yellow
+{
+    color: #f0ad4e;
+}
+.mui-btn-outlined.mui-btn-negative, .mui-btn-outlined.mui-btn-danger, .mui-btn-outlined.mui-btn-red
+{
+    color: #dd524d;
+}
+.mui-btn-outlined.mui-btn-royal, .mui-btn-outlined.mui-btn-purple
+{
+    color: #8a6de9;
+}
+.mui-btn-outlined.mui-btn-primary:enabled:active, .mui-btn-outlined.mui-btn-blue:enabled:active, .mui-btn-outlined.mui-btn-positive:enabled:active, .mui-btn-outlined.mui-btn-success:enabled:active, .mui-btn-outlined.mui-btn-green:enabled:active, .mui-btn-outlined.mui-btn-warning:enabled:active, .mui-btn-outlined.mui-btn-yellow:enabled:active, .mui-btn-outlined.mui-btn-negative:enabled:active, .mui-btn-outlined.mui-btn-danger:enabled:active, .mui-btn-outlined.mui-btn-red:enabled:active, .mui-btn-outlined.mui-btn-royal:enabled:active, .mui-btn-outlined.mui-btn-purple:enabled:active
+{
+    color: #fff;
+}
+
+.mui-btn-link
+{
+    padding-top: 6px;
+    padding-bottom: 6px;
+
+    color: #007aff;
+    border: 0;
+    background-color: transparent;
+}
+.mui-btn-link:enabled:active, .mui-btn-link.mui-active:enabled
+{
+    color: #0062cc;
+    background-color: transparent;
+}
+
+.mui-btn-block
+{
+    font-size: 18px;
+
+    display: block;
+
+    width: 100%;
+    margin-bottom: 10px;
+    padding: 15px 0;
+}
+
+.mui-btn .mui-badge
+{
+    font-size: 14px;
+
+    margin: -2px -4px -2px 4px;
+
+    background-color: rgba(0, 0, 0, .15);
+}
+
+.mui-btn .mui-badge-inverted,
+.mui-btn:enabled:active .mui-badge-inverted
+{
+    background-color: transparent;
+}
+
+.mui-btn-primary:enabled:active .mui-badge-inverted,
+.mui-btn-positive:enabled:active .mui-badge-inverted,
+.mui-btn-negative:enabled:active .mui-badge-inverted
+{
+    color: #fff;
+}
+
+.mui-btn-block .mui-badge
+{
+    position: absolute;
+    right: 0;
+
+    margin-right: 10px;
+}
+
+.mui-btn .mui-icon
+{
+    font-size: inherit;
+}
+
+.mui-btn.mui-icon
+{
+    font-size: 14px;
+    line-height: 1.42;
+}
+
+.mui-btn.mui-fab
+{
+    width: 56px;
+    height: 56px;
+    padding: 16px;
+
+    border-radius: 50%;
+    outline: none;
+}
+.mui-btn.mui-fab.mui-btn-mini
+{
+    width: 40px;
+    height: 40px;
+    padding: 8px;
+}
+.mui-btn.mui-fab .mui-icon
+{
+    font-size: 24px;
+    line-height: 24px;
+
+    width: 24px;
+    height: 24px;
+}
+
+.mui-btn .mui-spinner
+{
+    width: 14px;
+    height: 14px;
+
+    vertical-align: text-bottom;
+}
+
+.mui-btn-block .mui-spinner
+{
+    width: 22px;
+    height: 22px;
+}
+
+.mui-bar
+{
+    position: fixed;
+    z-index: 10;
+    right: 0;
+    left: 0;
+
+    height: 44px;
+    padding-right: 10px;
+    padding-left: 10px;
+
+    border-bottom: 0;
+    background-color: #f7f7f7;
+    -webkit-box-shadow: 0 0 1px rgba(0, 0, 0, .85);
+            box-shadow: 0 0 1px rgba(0, 0, 0, .85);
+
+    -webkit-backface-visibility: hidden;
+            backface-visibility: hidden;
+}
+
+.mui-bar .mui-title
+{
+    right: 40px;
+    left: 40px;
+
+    display: inline-block;
+    overflow: hidden;
+
+    width: auto;
+    margin: 0;
+
+    text-overflow: ellipsis;
+}
+.mui-bar .mui-backdrop
+{
+    background: none;
+}
+
+.mui-bar-header-secondary
+{
+    top: 44px;
+}
+
+.mui-bar-footer
+{
+    bottom: 0;
+}
+
+.mui-bar-footer-secondary
+{
+    bottom: 44px;
+}
+
+.mui-bar-footer-secondary-tab
+{
+    bottom: 50px;
+}
+
+.mui-bar-footer,
+.mui-bar-footer-secondary,
+.mui-bar-footer-secondary-tab
+{
+    border-top: 0;
+}
+
+.mui-bar-transparent
+{
+    top: 0;
+
+    background-color: rgba(247, 247, 247, 0);
+    -webkit-box-shadow: none;
+            box-shadow: none;
+}
+
+.mui-bar-nav
+{
+    top: 0;
+
+    -webkit-box-shadow: 0 1px 6px #ccc;
+            box-shadow: 0 1px 6px #ccc;
+}
+.mui-bar-nav ~ .mui-content .mui-anchor
+{
+    display: block;
+    visibility: hidden;
+
+    height: 45px;
+    margin-top: -45px;
+}
+.mui-bar-nav.mui-bar .mui-icon
+{
+    margin-right: -10px;
+    margin-left: -10px;
+    padding-right: 10px;
+    padding-left: 10px;
+}
+
+.mui-title
+{
+    font-size: 17px;
+    font-weight: 500;
+    line-height: 44px;
+
+    position: absolute;
+
+    display: block;
+
+    width: 100%;
+    margin: 0 -10px;
+    padding: 0;
+
+    text-align: center;
+    white-space: nowrap;
+
+    color: #000;
+}
+
+.mui-title a
+{
+    color: inherit;
+}
+
+.mui-bar-tab
+{
+    bottom: 0;
+
+    display: table;
+
+    width: 100%;
+    height: 50px;
+    padding: 0;
+
+    table-layout: fixed;
+
+    border-top: 0;
+    border-bottom: 0;
+
+    -webkit-touch-callout: none;
+}
+.mui-bar-tab .mui-tab-item
+{
+    display: table-cell;
+    overflow: hidden;
+
+    width: 1%;
+    height: 50px;
+
+    text-align: center;
+    vertical-align: middle;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+
+    color: #929292;
+}
+.mui-bar-tab .mui-tab-item.mui-active
+{
+    color: #007aff;
+}
+.mui-bar-tab .mui-tab-item .mui-icon
+{
+    top: 3px;
+
+    width: 24px;
+    height: 24px;
+    padding-top: 0;
+    padding-bottom: 0;
+}
+.mui-bar-tab .mui-tab-item .mui-icon ~ .mui-tab-label
+{
+    font-size: 11px;
+
+    display: block;
+    overflow: hidden;
+
+    text-overflow: ellipsis;
+}
+.mui-bar-tab .mui-tab-item .mui-icon:active
+{
+    background: none;
+}
+
+.mui-focusin > .mui-bar-nav,
+.mui-focusin > .mui-bar-header-secondary
+{
+    position: absolute;
+}
+
+.mui-focusin > .mui-bar ~ .mui-content
+{
+    padding-bottom: 0;
+}
+
+.mui-bar .mui-btn
+{
+    font-weight: 400;
+
+    position: relative;
+    z-index: 20;
+    top: 7px;
+
+    margin-top: 0;
+    padding: 6px 12px 7px;
+}
+.mui-bar .mui-btn.mui-pull-right
+{
+    margin-left: 10px;
+}
+.mui-bar .mui-btn.mui-pull-left
+{
+    margin-right: 10px;
+}
+
+.mui-bar .mui-btn-link
+{
+    font-size: 16px;
+    line-height: 44px;
+
+    top: 0;
+
+    padding: 0;
+
+    color: #007aff;
+    border: 0;
+}
+.mui-bar .mui-btn-link:active, .mui-bar .mui-btn-link.mui-active
+{
+    color: #0062cc;
+}
+
+.mui-bar .mui-btn-block
+{
+    font-size: 16px;
+
+    top: 6px;
+
+    margin-bottom: 0;
+    padding: 5px 0;
+}
+
+.mui-bar .mui-btn-nav.mui-pull-left
+{
+    margin-left: -5px;
+}
+.mui-bar .mui-btn-nav.mui-pull-left .mui-icon-left-nav
+{
+    margin-right: -3px;
+}
+.mui-bar .mui-btn-nav.mui-pull-right
+{
+    margin-right: -5px;
+}
+.mui-bar .mui-btn-nav.mui-pull-right .mui-icon-right-nav
+{
+    margin-left: -3px;
+}
+.mui-bar .mui-btn-nav:active
+{
+    opacity: .3;
+}
+
+.mui-bar .mui-icon
+{
+    font-size: 24px;
+
+    position: relative;
+    z-index: 20;
+
+    padding-top: 10px;
+    padding-bottom: 10px;
+}
+.mui-bar .mui-icon:active
+{
+    opacity: .3;
+}
+.mui-bar .mui-btn .mui-icon
+{
+    top: 1px;
+
+    margin: 0;
+    padding: 0;
+}
+.mui-bar .mui-title .mui-icon
+{
+    margin: 0;
+    padding: 0;
+}
+.mui-bar .mui-title .mui-icon.mui-icon-caret
+{
+    top: 4px;
+
+    margin-left: -5px;
+}
+
+.mui-bar input[type='search']
+{
+    height: 29px;
+    margin: 6px 0;
+}
+
+.mui-bar .mui-input-row .mui-btn
+{
+    padding: 12px 10px;
+}
+
+.mui-bar .mui-search:before
+{
+    margin-top: -10px;
+}
+
+.mui-bar .mui-input-row .mui-input-clear ~ .mui-icon-clear,
+.mui-bar .mui-input-row .mui-input-speech ~ .mui-icon-speech
+{
+    top: 0;
+    right: 12px;
+}
+
+.mui-bar.mui-bar-header-secondary .mui-input-row .mui-input-clear ~ .mui-icon-clear,
+.mui-bar.mui-bar-header-secondary .mui-input-row .mui-input-speech ~ .mui-icon-speech
+{
+    top: 0;
+    right: 0;
+}
+
+.mui-bar .mui-segmented-control
+{
+    top: 7px;
+
+    width: auto;
+    margin: 0 auto;
+}
+
+.mui-bar.mui-bar-header-secondary .mui-segmented-control
+{
+    top: 0;
+}
+
+.mui-badge
+{
+    font-size: 12px;
+    line-height: 1;
+
+    display: inline-block;
+
+    padding: 3px 6px;
+
+    color: #333;
+    border-radius: 100px;
+    background-color: rgba(0, 0, 0, .15);
+}
+.mui-badge.mui-badge-inverted
+{
+    padding: 0 5px 0 0;
+
+    color: #929292;
+    background-color: transparent;
+}
+
+.mui-badge-primary, .mui-badge-blue
+{
+    color: #fff;
+    background-color: #007aff;
+}
+.mui-badge-primary.mui-badge-inverted, .mui-badge-blue.mui-badge-inverted
+{
+    color: #007aff;
+    background-color: transparent;
+}
+
+.mui-badge-success, .mui-badge-green
+{
+    color: #fff;
+    background-color: #4cd964;
+}
+.mui-badge-success.mui-badge-inverted, .mui-badge-green.mui-badge-inverted
+{
+    color: #4cd964;
+    background-color: transparent;
+}
+
+.mui-badge-warning, .mui-badge-yellow
+{
+    color: #fff;
+    background-color: #f0ad4e;
+}
+.mui-badge-warning.mui-badge-inverted, .mui-badge-yellow.mui-badge-inverted
+{
+    color: #f0ad4e;
+    background-color: transparent;
+}
+
+.mui-badge-danger, .mui-badge-red
+{
+    color: #fff;
+    background-color: #dd524d;
+}
+.mui-badge-danger.mui-badge-inverted, .mui-badge-red.mui-badge-inverted
+{
+    color: #dd524d;
+    background-color: transparent;
+}
+
+.mui-badge-royal, .mui-badge-purple
+{
+    color: #fff;
+    background-color: #8a6de9;
+}
+.mui-badge-royal.mui-badge-inverted, .mui-badge-purple.mui-badge-inverted
+{
+    color: #8a6de9;
+    background-color: transparent;
+}
+
+.mui-icon .mui-badge
+{
+    font-size: 10px;
+    line-height: 1.4;
+
+    position: absolute;
+    top: -2px;
+    left: 100%;
+
+    margin-left: -10px;
+    padding: 1px 5px;
+
+    color: white;
+    background: red;
+}
+
+.mui-card
+{
+    font-size: 14px;
+
+    position: relative;
+
+    overflow: hidden;
+
+    margin: 10px;
+
+    border-radius: 2px;
+    background-color: white;
+    background-clip: padding-box;
+    box-shadow: 0 1px 2px rgba(0, 0, 0, .3);
+}
+
+.mui-content > .mui-card:first-child
+{
+    margin-top: 15px;
+}
+
+.mui-card .mui-input-group:before, .mui-card .mui-input-group:after
+{
+    height: 0;
+}
+.mui-card .mui-input-group .mui-input-row:last-child:before, .mui-card .mui-input-group .mui-input-row:last-child:after
+{
+    height: 0;
+}
+
+.mui-card .mui-table-view
+{
+    margin-bottom: 0;
+
+    border-top: 0;
+    border-bottom: 0;
+    border-radius: 6px;
+}
+.mui-card .mui-table-view .mui-table-view-divider:first-child, .mui-card .mui-table-view .mui-table-view-cell:first-child
+{
+    top: 0;
+
+    border-top-left-radius: 6px;
+    border-top-right-radius: 6px;
+}
+.mui-card .mui-table-view .mui-table-view-divider:last-child, .mui-card .mui-table-view .mui-table-view-cell:last-child
+{
+    border-bottom-right-radius: 6px;
+    border-bottom-left-radius: 6px;
+}
+.mui-card .mui-table-view:before, .mui-card .mui-table-view:after
+{
+    height: 0;
+}
+
+.mui-card > .mui-table-view > .mui-table-view-cell:last-child:before, .mui-card > .mui-table-view > .mui-table-view-cell:last-child:after
+{
+    height: 0;
+}
+
+.mui-card-header,
+.mui-card-footer
+{
+    position: relative;
+
+    display: -webkit-box;
+    display: -webkit-flex;
+    display:         flex;
+
+    min-height: 44px;
+    padding: 10px 15px;
+
+    -webkit-box-pack: justify;
+    -webkit-justify-content: space-between;
+            justify-content: space-between;
+    -webkit-box-align: center;
+    -webkit-align-items: center;
+            align-items: center;
+}
+.mui-card-header .mui-card-link,
+.mui-card-footer .mui-card-link
+{
+    line-height: 44px;
+
+    position: relative;
+
+    display: -webkit-box;
+    display: -webkit-flex;
+    display:         flex;
+
+    height: 44px;
+    margin-top: -10px;
+    margin-bottom: -10px;
+
+    -webkit-transition-duration: .3s;
+            transition-duration: .3s;
+    text-decoration: none;
+
+    -webkit-box-pack: start;
+    -webkit-justify-content: flex-start;
+            justify-content: flex-start;
+    -webkit-box-align: center;
+    -webkit-align-items: center;
+            align-items: center;
+}
+
+.mui-card-header:after,
+.mui-card-footer:before
+{
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+
+.mui-card-header
+{
+    font-size: 17px;
+
+    border-radius: 2px 2px 0 0;
+}
+.mui-card-header:after
+{
+    top: auto;
+    bottom: 0;
+}
+.mui-card-header > img:first-child
+{
+    font-size: 0;
+    line-height: 0;
+
+    float: left;
+
+    width: 34px;
+    height: 34px;
+}
+
+.mui-card-footer
+{
+    color: #6d6d72;
+    border-radius: 0 0 2px 2px;
+}
+
+.mui-card-content
+{
+    font-size: 14px;
+
+    position: relative;
+}
+
+.mui-card-content-inner
+{
+    position: relative;
+
+    padding: 15px;
+}
+
+.mui-card-media
+{
+    vertical-align: bottom;
+
+    color: #fff;
+    background-position: center;
+    background-size: cover;
+}
+
+.mui-card-header.mui-card-media
+{
+    display: block;
+
+    padding: 10px;
+}
+.mui-card-header.mui-card-media .mui-media-body
+{
+    font-size: 14px;
+    font-weight: 500;
+    line-height: 17px;
+
+    margin-bottom: 0;
+    margin-left: 44px;
+
+    color: #333;
+}
+.mui-card-header.mui-card-media .mui-media-body p
+{
+    font-size: 13px;
+
+    margin-bottom: 0;
+}
+
+.mui-table-view
+{
+    position: relative;
+
+    margin-top: 0;
+    margin-bottom: 0;
+    padding-left: 0;
+
+    list-style: none;
+
+    background-color: #fff;
+}
+.mui-table-view:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-table-view:before
+{
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-table-view:before
+{
+    top: -1px;
+}
+
+.mui-table-view-icon .mui-table-view-cell .mui-navigate-right .mui-icon
+{
+    font-size: 20px;
+
+    margin-top: -1px;
+    margin-right: 5px;
+    margin-left: -5px;
+}
+.mui-table-view-icon .mui-table-view-cell:after
+{
+    left: 40px;
+}
+
+.mui-table-view-chevron .mui-table-view-cell
+{
+    padding-right: 65px;
+}
+.mui-table-view-chevron .mui-table-view-cell > a:not(.mui-btn)
+{
+    margin-right: -65px;
+}
+
+.mui-table-view-radio .mui-table-view-cell
+{
+    padding-right: 65px;
+}
+.mui-table-view-radio .mui-table-view-cell > a:not(.mui-btn)
+{
+    margin-right: -65px;
+}
+.mui-table-view-radio .mui-table-view-cell .mui-navigate-right:after
+{
+    font-size: 30px;
+    font-weight: 600;
+
+    right: 9px;
+
+    content: '';
+
+    color: #007aff;
+}
+.mui-table-view-radio .mui-table-view-cell.mui-selected .mui-navigate-right:after
+{
+    content: '\e472';
+}
+
+.mui-table-view-inverted
+{
+    color: #fff;
+    background: #333;
+}
+.mui-table-view-inverted:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #222;
+}
+.mui-table-view-inverted:before
+{
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #222;
+}
+.mui-table-view-inverted .mui-table-view-cell:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 15px;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #222;
+}
+.mui-table-view-inverted .mui-table-view-cell.mui-active
+{
+    background-color: #242424;
+}
+.mui-table-view-inverted .mui-table-view-cell > a:not(.mui-btn).mui-active
+{
+    background-color: #242424;
+}
+
+.mui-table-view-cell
+{
+    position: relative;
+
+    overflow: hidden;
+
+    padding: 11px 15px;
+
+    -webkit-touch-callout: none;
+}
+.mui-table-view-cell:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 15px;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-table-view-cell.mui-radio input[type=radio], .mui-table-view-cell.mui-checkbox input[type=checkbox]
+{
+    top: 8px;
+}
+.mui-table-view-cell.mui-radio.mui-left, .mui-table-view-cell.mui-checkbox.mui-left
+{
+    padding-left: 58px;
+}
+.mui-table-view-cell.mui-active
+{
+    background-color: #eee;
+}
+.mui-table-view-cell:last-child:before, .mui-table-view-cell:last-child:after
+{
+    height: 0;
+}
+.mui-table-view-cell > a:not(.mui-btn)
+{
+    position: relative;
+
+    display: block;
+    overflow: hidden;
+
+    margin: -11px -15px;
+    padding: inherit;
+
+    white-space: nowrap;
+    text-overflow: ellipsis;
+
+    color: inherit;
+  /*&:active {
+      background-color: #eee;
+  }*/
+}
+.mui-table-view-cell > a:not(.mui-btn).mui-active
+{
+    background-color: #eee;
+}
+.mui-table-view-cell p
+{
+    margin-bottom: 0;
+}
+
+.mui-table-view-cell.mui-transitioning > .mui-slider-handle, .mui-table-view-cell.mui-transitioning > .mui-slider-left .mui-btn, .mui-table-view-cell.mui-transitioning > .mui-slider-right .mui-btn
+{
+    -webkit-transition: -webkit-transform 300ms ease;
+            transition:         transform 300ms ease;
+}
+.mui-table-view-cell.mui-active > .mui-slider-handle
+{
+    background-color: #eee;
+}
+.mui-table-view-cell > .mui-slider-handle
+{
+    position: relative;
+
+    background-color: #fff;
+}
+.mui-table-view-cell > .mui-slider-handle.mui-navigate-right:after, .mui-table-view-cell > .mui-slider-handle .mui-navigate-right:after
+{
+    right: 0;
+}
+.mui-table-view-cell > .mui-slider-handle, .mui-table-view-cell > .mui-slider-left .mui-btn, .mui-table-view-cell > .mui-slider-right .mui-btn
+{
+    -webkit-transition: -webkit-transform 0ms ease;
+            transition:         transform 0ms ease;
+}
+.mui-table-view-cell > .mui-slider-left, .mui-table-view-cell > .mui-slider-right
+{
+    position: absolute;
+    top: 0;
+
+    display: -webkit-box;
+    display: -webkit-flex;
+    display:         flex;
+
+    height: 100%;
+}
+.mui-table-view-cell > .mui-slider-left > .mui-btn, .mui-table-view-cell > .mui-slider-right > .mui-btn
+{
+    position: relative;
+    left: 0;
+
+    display: -webkit-box;
+    display: -webkit-flex;
+    display:         flex;
+
+    padding: 0 30px;
+
+    color: #fff;
+    border: 0;
+    border-radius: 0;
+
+    -webkit-box-align: center;
+    -webkit-align-items: center;
+            align-items: center;
+}
+.mui-table-view-cell > .mui-slider-left > .mui-btn:after, .mui-table-view-cell > .mui-slider-right > .mui-btn:after
+{
+    position: absolute;
+    z-index: -1;
+    top: 0;
+
+    width: 600%;
+    height: 100%;
+
+    content: '';
+
+    background: inherit;
+}
+.mui-table-view-cell > .mui-slider-left > .mui-btn.mui-icon, .mui-table-view-cell > .mui-slider-right > .mui-btn.mui-icon
+{
+    font-size: 30px;
+}
+.mui-table-view-cell > .mui-slider-right
+{
+    right: 0;
+
+    -webkit-transition: -webkit-transform 0ms ease;
+            transition:         transform 0ms ease;
+    -webkit-transform: translateX(100%);
+            transform: translateX(100%);
+}
+.mui-table-view-cell > .mui-slider-left
+{
+    left: 0;
+
+    -webkit-transition: -webkit-transform 0ms ease;
+            transition:         transform 0ms ease;
+    -webkit-transform: translateX(-100%);
+            transform: translateX(-100%);
+}
+.mui-table-view-cell > .mui-slider-left > .mui-btn:after
+{
+    right: 100%;
+
+    margin-right: -1px;
+}
+
+.mui-table-view-divider
+{
+    font-weight: 500;
+
+    position: relative;
+
+    margin-top: -1px;
+    margin-left: 0;
+    padding-top: 6px;
+    padding-bottom: 6px;
+    padding-left: 15px;
+
+    color: #999;
+    background-color: #fafafa;
+}
+.mui-table-view-divider:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-table-view-divider:before
+{
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+
+.mui-table-view .mui-media,
+.mui-table-view .mui-media-body
+{
+    overflow: hidden;
+}
+
+.mui-table-view .mui-media-large .mui-media-object
+{
+    line-height: 80px;
+
+    max-width: 80px;
+    height: 80px;
+}
+.mui-table-view .mui-media .mui-subtitle
+{
+    color: #000;
+}
+.mui-table-view .mui-media-object
+{
+    line-height: 42px;
+
+    max-width: 42px;
+    height: 42px;
+}
+.mui-table-view .mui-media-object.mui-pull-left
+{
+    margin-right: 10px;
+}
+.mui-table-view .mui-media-object.mui-pull-right
+{
+    margin-left: 10px;
+}
+.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object
+{
+    line-height: 29px;
+
+    max-width: 29px;
+    height: 29px;
+    margin: -4px 0;
+}
+.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object img
+{
+    line-height: 29px;
+
+    max-width: 29px;
+    height: 29px;
+}
+.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object.mui-pull-left
+{
+    margin-right: 10px;
+}
+.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-object .mui-icon
+{
+    font-size: 29px;
+}
+.mui-table-view .mui-table-view-cell.mui-media-icon .mui-media-body:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 55px;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-table-view .mui-table-view-cell.mui-media-icon:after
+{
+    height: 0 !important;
+}
+
+.mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view
+{
+    display: block;
+}
+.mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view:before, .mui-table-view.mui-unfold .mui-table-view-cell.mui-collapse .mui-table-view:after
+{
+    height: 0 !important;
+}
+.mui-table-view.mui-unfold .mui-table-view-cell.mui-media-icon.mui-collapse .mui-media-body:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 70px;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+
+.mui-table-view-cell > .mui-btn,
+.mui-table-view-cell > .mui-badge,
+.mui-table-view-cell > .mui-switch,
+.mui-table-view-cell > a > .mui-btn,
+.mui-table-view-cell > a > .mui-badge,
+.mui-table-view-cell > a > .mui-switch
+{
+    position: absolute;
+    top: 50%;
+    right: 15px;
+
+    -webkit-transform: translateY(-50%);
+            transform: translateY(-50%);
+}
+.mui-table-view-cell .mui-navigate-right > .mui-btn,
+.mui-table-view-cell .mui-navigate-right > .mui-badge,
+.mui-table-view-cell .mui-navigate-right > .mui-switch,
+.mui-table-view-cell .mui-push-left > .mui-btn,
+.mui-table-view-cell .mui-push-left > .mui-badge,
+.mui-table-view-cell .mui-push-left > .mui-switch,
+.mui-table-view-cell .mui-push-right > .mui-btn,
+.mui-table-view-cell .mui-push-right > .mui-badge,
+.mui-table-view-cell .mui-push-right > .mui-switch,
+.mui-table-view-cell > a .mui-navigate-right > .mui-btn,
+.mui-table-view-cell > a .mui-navigate-right > .mui-badge,
+.mui-table-view-cell > a .mui-navigate-right > .mui-switch,
+.mui-table-view-cell > a .mui-push-left > .mui-btn,
+.mui-table-view-cell > a .mui-push-left > .mui-badge,
+.mui-table-view-cell > a .mui-push-left > .mui-switch,
+.mui-table-view-cell > a .mui-push-right > .mui-btn,
+.mui-table-view-cell > a .mui-push-right > .mui-badge,
+.mui-table-view-cell > a .mui-push-right > .mui-switch
+{
+    right: 35px;
+}
+
+.mui-content > .mui-table-view:first-child
+{
+    margin-top: 15px;
+}
+
+.mui-table-view-cell.mui-collapse .mui-table-view:before, .mui-table-view-cell.mui-collapse .mui-table-view:after
+{
+    height: 0;
+}
+.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell:last-child:after
+{
+    height: 0;
+}
+.mui-table-view-cell.mui-collapse > .mui-navigate-right:after, .mui-table-view-cell.mui-collapse > .mui-push-right:after
+{
+    content: '\e581';
+}
+.mui-table-view-cell.mui-collapse.mui-active
+{
+    margin-top: -1px;
+}
+.mui-table-view-cell.mui-collapse.mui-active .mui-table-view, .mui-table-view-cell.mui-collapse.mui-active .mui-collapse-content
+{
+    display: block;
+}
+.mui-table-view-cell.mui-collapse.mui-active > .mui-navigate-right:after, .mui-table-view-cell.mui-collapse.mui-active > .mui-push-right:after
+{
+    content: '\e580';
+}
+.mui-table-view-cell.mui-collapse.mui-active .mui-table-view-cell > a:not(.mui-btn).mui-active
+{
+    margin-left: -31px;
+    padding-left: 47px;
+}
+.mui-table-view-cell.mui-collapse .mui-collapse-content
+{
+    position: relative;
+
+    display: none;
+    overflow: hidden;
+
+    margin: 11px -15px -11px;
+    padding: 8px 15px;
+
+    -webkit-transition: height .35s ease;
+         -o-transition: height .35s ease;
+            transition: height .35s ease;
+
+    background: white;
+}
+.mui-table-view-cell.mui-collapse .mui-collapse-content > .mui-input-group, .mui-table-view-cell.mui-collapse .mui-collapse-content > .mui-slider
+{
+    width: auto;
+    height: auto;
+    margin: -8px -15px;
+}
+.mui-table-view-cell.mui-collapse .mui-collapse-content > .mui-slider
+{
+    margin: -8px -16px;
+}
+.mui-table-view-cell.mui-collapse .mui-table-view
+{
+    display: none;
+
+    margin-top: 11px;
+    margin-right: -15px;
+    margin-bottom: -11px;
+    margin-left: -15px;
+
+    border: 0;
+}
+.mui-table-view-cell.mui-collapse .mui-table-view.mui-table-view-chevron
+{
+    margin-right: -65px;
+}
+.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell
+{
+    padding-left: 31px;
+
+    background-position: 31px 100%;
+}
+.mui-table-view-cell.mui-collapse .mui-table-view .mui-table-view-cell:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 30px;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+
+.mui-table-view.mui-grid-view
+{
+    font-size: 0;
+
+    display: block;
+
+    width: 100%;
+    padding: 0 10px 10px 0;
+
+    white-space: normal;
+}
+.mui-table-view.mui-grid-view .mui-table-view-cell
+{
+    font-size: 17px;
+
+    display: inline-block;
+
+    margin-right: -4px;
+    padding: 10px 0 0 14px;
+
+    text-align: center;
+    vertical-align: middle;
+
+    background: none;
+}
+.mui-table-view.mui-grid-view .mui-table-view-cell .mui-media-object
+{
+    width: 100%;
+    max-width: 100%;
+    height: auto;
+}
+.mui-table-view.mui-grid-view .mui-table-view-cell > a:not(.mui-btn)
+{
+    margin: -10px 0 0 -14px;
+}
+.mui-table-view.mui-grid-view .mui-table-view-cell > a:not(.mui-btn):active, .mui-table-view.mui-grid-view .mui-table-view-cell > a:not(.mui-btn).mui-active
+{
+    background: none;
+}
+.mui-table-view.mui-grid-view .mui-table-view-cell .mui-media-body
+{
+    font-size: 15px;
+    line-height: 15px;
+
+    display: block;
+
+    width: 100%;
+    height: 15px;
+    margin-top: 8px;
+
+    text-overflow: ellipsis;
+
+    color: #333;
+}
+.mui-table-view.mui-grid-view .mui-table-view-cell:before, .mui-table-view.mui-grid-view .mui-table-view-cell:after
+{
+    height: 0;
+}
+
+.mui-grid-view.mui-grid-9
+{
+    margin: 0;
+    padding: 0;
+
+    border-top: 1px solid #eee;
+    border-left: 1px solid #eee;
+    background-color: #f2f2f2;
+}
+.mui-grid-view.mui-grid-9:before, .mui-grid-view.mui-grid-9:after
+{
+    display: table;
+
+    content: ' ';
+}
+.mui-grid-view.mui-grid-9:after
+{
+    clear: both;
+}
+.mui-grid-view.mui-grid-9:after
+{
+    position: static;
+}
+.mui-grid-view.mui-grid-9 .mui-table-view-cell
+{
+    margin: 0;
+    padding: 11px 15px;
+
+    vertical-align: top;
+
+    border-right: 1px solid #eee;
+    border-bottom: 1px solid #eee;
+}
+.mui-grid-view.mui-grid-9 .mui-table-view-cell.mui-active
+{
+    background-color: #eee;
+}
+.mui-grid-view.mui-grid-9 .mui-table-view-cell > a:not(.mui-btn)
+{
+    margin: 0;
+    padding: 10px 0;
+}
+.mui-grid-view.mui-grid-9:before
+{
+    height: 0;
+}
+.mui-grid-view.mui-grid-9 .mui-media
+{
+    color: #797979;
+}
+.mui-grid-view.mui-grid-9 .mui-media .mui-icon
+{
+    font-size: 2.4em;
+
+    position: relative;
+}
+
+.mui-slider-cell
+{
+    position: relative;
+}
+.mui-slider-cell > .mui-slider-handle
+{
+    z-index: 1;
+}
+.mui-slider-cell > .mui-slider-left, .mui-slider-cell > .mui-slider-right
+{
+    position: absolute;
+    z-index: 0;
+    top: 0;
+    bottom: 0;
+}
+.mui-slider-cell > .mui-slider-left
+{
+    left: 0;
+}
+.mui-slider-cell > .mui-slider-right
+{
+    right: 0;
+}
+
+input,
+textarea,
+select
+{
+    font-family: 'Helvetica Neue', Helvetica, sans-serif;
+    font-size: 17px;
+
+    -webkit-tap-highlight-color: transparent;
+    -webkit-tap-highlight-color: transparent;
+}
+input:focus,
+textarea:focus,
+select:focus
+{
+    -webkit-tap-highlight-color: transparent;
+    -webkit-tap-highlight-color: transparent;
+    -webkit-user-modify: read-write-plaintext-only;
+}
+
+select,
+textarea,
+input[type='text'],
+input[type='search'],
+input[type='password'],
+input[type='datetime'],
+input[type='datetime-local'],
+input[type='date'],
+input[type='month'],
+input[type='time'],
+input[type='week'],
+input[type='number'],
+input[type='email'],
+input[type='url'],
+input[type='tel'],
+input[type='color']
+{
+    line-height: 21px;
+
+    width: 100%;
+    height: 40px;
+    margin-bottom: 15px;
+    padding: 10px 15px;
+
+    -webkit-user-select: text;
+
+    border: 1px solid rgba(0, 0, 0, .2);
+    border-radius: 3px;
+    outline: none;
+    background-color: #fff;
+
+    -webkit-appearance: none;
+}
+
+input[type=number]::-webkit-inner-spin-button,
+input[type=number]::-webkit-outer-spin-button
+{
+    margin: 0;
+
+    -webkit-appearance: none;
+}
+
+input[type='search']
+{
+    font-size: 16px;
+
+    -webkit-box-sizing: border-box;
+            box-sizing: border-box;
+    height: 34px;
+
+    text-align: center;
+
+    border: 0;
+    border-radius: 6px;
+    background-color: rgba(0, 0, 0, .1);
+}
+
+input[type='search']:focus
+{
+    text-align: left;
+}
+
+textarea
+{
+    height: auto;
+
+    resize: none;
+}
+
+select
+{
+    font-size: 14px;
+
+    height: auto;
+    margin-top: 1px;
+
+    border: 0 !important;
+    background-color: #fff;
+}
+select:focus
+{
+    -webkit-user-modify: read-only;
+}
+
+.mui-input-group
+{
+    position: relative;
+
+    padding: 0;
+
+    border: 0;
+    background-color: #fff;
+}
+.mui-input-group:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-input-group:before
+{
+    position: absolute;
+    top: 0;
+    right: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+
+.mui-input-group input,
+.mui-input-group textarea
+{
+    margin-bottom: 0;
+
+    border: 0;
+    border-radius: 0;
+    background-color: transparent;
+    -webkit-box-shadow: none;
+            box-shadow: none;
+}
+
+.mui-input-group input[type='search']
+{
+    background: none;
+}
+
+.mui-input-group input:last-child
+{
+    background-image: none;
+}
+
+.mui-input-row
+{
+    clear: left;
+    overflow: hidden;
+}
+.mui-input-row select
+{
+    font-size: 17px;
+
+    height: 37px;
+    padding: 0;
+}
+
+.mui-input-row:last-child,
+.mui-input-row label + input, .mui-input-row .mui-btn + input
+{
+    background: none;
+}
+
+.mui-input-group .mui-input-row
+{
+    height: 40px;
+}
+.mui-input-group .mui-input-row:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 15px;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+
+.mui-input-row label
+{
+    font-family: 'Helvetica Neue', Helvetica, sans-serif;
+    line-height: 1.1;
+
+    float: left;
+
+    width: 35%;
+    padding: 11px 15px;
+}
+
+.mui-input-row label ~ input, .mui-input-row label ~ select, .mui-input-row label ~ textarea
+{
+    float: right;
+
+    width: 65%;
+    margin-bottom: 0;
+    padding-left: 0;
+
+    border: 0;
+}
+
+.mui-input-row .mui-btn
+{
+    line-height: 1.1;
+
+    float: right;
+
+    width: 15%;
+    padding: 10px 15px;
+}
+
+.mui-input-row .mui-btn ~ input, .mui-input-row .mui-btn ~ select, .mui-input-row .mui-btn ~ textarea
+{
+    float: left;
+
+    width: 85%;
+    margin-bottom: 0;
+    padding-left: 0;
+
+    border: 0;
+}
+
+.mui-button-row
+{
+    position: relative;
+
+    padding-top: 5px;
+
+    text-align: center;
+}
+
+.mui-input-group .mui-button-row
+{
+    height: 45px;
+}
+
+.mui-input-row
+{
+    position: relative;
+}
+.mui-input-row.mui-input-range
+{
+    overflow: visible;
+
+    padding-right: 20px;
+}
+.mui-input-row .mui-inline
+{
+    padding: 8px 0;
+}
+.mui-input-row .mui-input-clear ~ .mui-icon-clear, .mui-input-row .mui-input-speech ~ .mui-icon-speech, .mui-input-row .mui-input-password ~ .mui-icon-eye
+{
+    font-size: 20px;
+
+    position: absolute;
+    z-index: 1;
+    top: 10px;
+    right: 0;
+
+    width: 38px;
+    height: 38px;
+
+    text-align: center;
+
+    color: #999;
+}
+.mui-input-row .mui-input-clear ~ .mui-icon-clear.mui-active, .mui-input-row .mui-input-speech ~ .mui-icon-speech.mui-active, .mui-input-row .mui-input-password ~ .mui-icon-eye.mui-active
+{
+    color: #007aff;
+}
+.mui-input-row .mui-input-speech ~ .mui-icon-speech
+{
+    font-size: 24px;
+
+    top: 8px;
+}
+.mui-input-row .mui-input-clear ~ .mui-icon-clear ~ .mui-icon-speech
+{
+    display: none;
+}
+.mui-input-row .mui-input-clear ~ .mui-icon-clear.mui-hidden ~ .mui-icon-speech
+{
+    display: inline-block;
+}
+.mui-input-row .mui-icon-speech ~ .mui-placeholder
+{
+    right: 38px;
+}
+.mui-input-row.mui-search .mui-icon-clear
+{
+    top: 7px;
+}
+.mui-input-row.mui-search .mui-icon-speech
+{
+    top: 5px;
+}
+
+.mui-radio, .mui-checkbox
+{
+    position: relative;
+}
+.mui-radio label, .mui-checkbox label
+{
+    display: inline-block;
+    float: none;
+
+    width: 100%;
+    padding-right: 58px;
+}
+
+.mui-radio.mui-left input[type='radio'], .mui-checkbox.mui-left input[type='checkbox']
+{
+    left: 20px;
+}
+
+.mui-radio.mui-left label, .mui-checkbox.mui-left label
+{
+    padding-right: 15px;
+    padding-left: 58px;
+}
+
+.mui-radio input[type='radio'], .mui-checkbox input[type='checkbox']
+{
+    position: absolute;
+    top: 4px;
+    right: 20px;
+
+    display: inline-block;
+
+    width: 28px;
+    height: 26px;
+
+    border: 0;
+    outline: 0 !important;
+    background-color: transparent;
+
+    -webkit-appearance: none;
+}
+.mui-radio input[type='radio'][disabled]:before, .mui-checkbox input[type='checkbox'][disabled]:before
+{
+    opacity: .3;
+}
+.mui-radio input[type='radio']:before, .mui-checkbox input[type='checkbox']:before
+{
+    font-family: Muiicons;
+    font-size: 28px;
+    font-weight: normal;
+    line-height: 1;
+
+    text-decoration: none;
+
+    color: #aaa;
+    border-radius: 0;
+    background: none;
+
+    -webkit-font-smoothing: antialiased;
+}
+.mui-radio input[type='radio']:checked:before, .mui-checkbox input[type='checkbox']:checked:before
+{
+    color: #007aff;
+}
+
+.mui-radio.mui-disabled label, .mui-radio label.mui-disabled, .mui-checkbox.mui-disabled label, .mui-checkbox label.mui-disabled
+{
+    opacity: .4;
+}
+
+.mui-radio input[type='radio']:before
+{
+    content: '\e411';
+}
+
+.mui-radio input[type='radio']:checked:before
+{
+    content: '\e441';
+}
+
+.mui-checkbox input[type='checkbox']:before
+{
+    content: '\e411';
+}
+
+.mui-checkbox input[type='checkbox']:checked:before
+{
+    content: '\e442';
+}
+
+.mui-select
+{
+    position: relative;
+}
+
+.mui-select:before
+{
+    font-family: Muiicons;
+
+    position: absolute;
+    top: 8px;
+    right: 21px;
+
+    content: '\e581';
+
+    color: rgba(170, 170, 170, .6);
+}
+
+.mui-input-row .mui-switch
+{
+    float: right;
+
+    margin-top: 5px;
+    margin-right: 20px;
+}
+
+.mui-input-range
+{
+  /*input[type="range"] {
+      -webkit-appearance: none;
+      background: #999;
+      height: 36px;
+      border-radius: 1px;
+      overflow: hidden;
+      margin-top: 2px;
+      margin-bottom: 2px;
+      outline:none;
+      position:relative;
+      width:100%;
+  }*/
+  /*input[type='range']::-webkit-slider-thumb {
+      -webkit-appearance: none!important;
+      opacity: 0.5;
+      height:28px;
+      width:28px;
+      border-radius: 50%;
+      background:#00b7fb;
+      position: relative;
+      pointer-events: none;
+      -webkit-box-sizing: border-box;
+      box-sizing: border-box;
+      &:before{
+          position: absolute;
+          top: 13px;
+          left: -2000px;
+          width: 2000px;
+          height: 2px;
+          background: #00b7fb;
+          content:' ';
+      }
+  }*/
+}
+.mui-input-range input[type='range']
+{
+    position: relative;
+
+    width: 100%;
+    height: 2px;
+    margin: 17px 0;
+    padding: 0;
+
+    cursor: pointer;
+
+    border: 0;
+    border-radius: 3px;
+    outline: none;
+    background-color: #999;
+
+    -webkit-appearance: none !important;
+}
+.mui-input-range input[type='range']::-webkit-slider-thumb
+{
+    width: 28px;
+    height: 28px;
+
+    border-color: #0062cc;
+    border-radius: 50%;
+    background-color: #007aff;
+    background-clip: padding-box;
+
+    -webkit-appearance: none !important;
+}
+.mui-input-range label ~ input[type='range']
+{
+    width: 65%;
+}
+.mui-input-range .mui-tooltip
+{
+    font-size: 36px;
+    line-height: 64px;
+
+    position: absolute;
+    z-index: 1;
+    top: -70px;
+
+    width: 64px;
+    height: 64px;
+
+    text-align: center;
+
+    opacity: .8;
+    color: #333;
+    border: 1px solid #ddd;
+    border-radius: 6px;
+    background-color: #fff;
+    text-shadow: 0 1px 0 #f3f3f3;
+}
+
+.mui-search
+{
+    position: relative;
+}
+.mui-search input[type='search']
+{
+    padding-left: 30px;
+}
+.mui-search .mui-placeholder
+{
+    font-size: 16px;
+    line-height: 34px;
+
+    position: absolute;
+    z-index: 1;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    display: inline-block;
+
+    height: 34px;
+
+    text-align: center;
+
+    color: #999;
+    border: 0;
+    border-radius: 6px;
+    background: none;
+}
+.mui-search .mui-placeholder .mui-icon
+{
+    font-size: 20px;
+
+    color: #333;
+}
+.mui-search:before
+{
+    font-family: Muiicons;
+    font-size: 20px;
+    font-weight: normal;
+
+    position: absolute;
+    top: 50%;
+    right: 50%;
+
+    display: none;
+
+    margin-top: -18px;
+    margin-right: 31px;
+
+    content: '\e466';
+}
+.mui-search.mui-active:before
+{
+    font-size: 20px;
+
+    right: auto;
+    left: 5px;
+
+    display: block;
+
+    margin-right: 0;
+}
+.mui-search.mui-active input[type='search']
+{
+    text-align: left;
+}
+.mui-search.mui-active .mui-placeholder
+{
+    display: none;
+}
+
+.mui-segmented-control
+{
+    font-size: 15px;
+    font-weight: 400;
+
+    position: relative;
+
+    display: table;
+    overflow: hidden;
+
+    width: 100%;
+
+    table-layout: fixed;
+
+    border: 1px solid #007aff;
+    border-radius: 3px;
+    background-color: transparent;
+
+    -webkit-touch-callout: none;
+}
+.mui-segmented-control.mui-segmented-control-vertical
+{
+    border-collapse: collapse;
+
+    border-width: 0;
+    border-radius: 0;
+}
+.mui-segmented-control.mui-segmented-control-vertical .mui-control-item
+{
+    display: block;
+
+    border-bottom: 1px solid #c8c7cc;
+    border-left-width: 0;
+}
+.mui-segmented-control.mui-scroll-wrapper
+{
+    height: 38px;
+}
+.mui-segmented-control.mui-scroll-wrapper .mui-scroll
+{
+    width: auto;
+    height: 40px;
+
+    white-space: nowrap;
+}
+.mui-segmented-control.mui-scroll-wrapper .mui-control-item
+{
+    display: inline-block;
+
+    width: auto;
+    padding: 0 20px;
+
+    border: 0;
+}
+.mui-segmented-control .mui-control-item
+{
+    line-height: 38px;
+
+    display: table-cell;
+    overflow: hidden;
+
+    width: 1%;
+
+    -webkit-transition: background-color .1s linear;
+            transition: background-color .1s linear;
+    text-align: center;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+
+    color: #007aff;
+    border-color: #007aff;
+    border-left: 1px solid #007aff;
+}
+.mui-segmented-control .mui-control-item:first-child
+{
+    border-left-width: 0;
+}
+.mui-segmented-control .mui-control-item.mui-active
+{
+    color: #fff;
+    background-color: #007aff;
+}
+.mui-segmented-control.mui-segmented-control-inverted
+{
+    width: 100%;
+
+    border: 0;
+    border-radius: 0;
+}
+.mui-segmented-control.mui-segmented-control-inverted.mui-segmented-control-vertical .mui-control-item
+{
+    border-bottom: 1px solid #c8c7cc;
+}
+.mui-segmented-control.mui-segmented-control-inverted.mui-segmented-control-vertical .mui-control-item.mui-active
+{
+    border-bottom: 1px solid #c8c7cc;
+}
+.mui-segmented-control.mui-segmented-control-inverted .mui-control-item
+{
+    color: inherit;
+    border: 0;
+}
+.mui-segmented-control.mui-segmented-control-inverted .mui-control-item.mui-active
+{
+    color: #007aff;
+    border-bottom: 2px solid #007aff;
+    background: none;
+}
+.mui-segmented-control.mui-segmented-control-inverted ~ .mui-slider-progress-bar
+{
+    background-color: #007aff;
+}
+
+.mui-segmented-control-positive
+{
+    border: 1px solid #4cd964;
+}
+.mui-segmented-control-positive .mui-control-item
+{
+    color: #4cd964;
+    border-color: inherit;
+}
+.mui-segmented-control-positive .mui-control-item.mui-active
+{
+    color: #fff;
+    background-color: #4cd964;
+}
+.mui-segmented-control-positive.mui-segmented-control-inverted .mui-control-item.mui-active
+{
+    color: #4cd964;
+    border-bottom: 2px solid #4cd964;
+    background: none;
+}
+.mui-segmented-control-positive.mui-segmented-control-inverted ~ .mui-slider-progress-bar
+{
+    background-color: #4cd964;
+}
+
+.mui-segmented-control-negative
+{
+    border: 1px solid #dd524d;
+}
+.mui-segmented-control-negative .mui-control-item
+{
+    color: #dd524d;
+    border-color: inherit;
+}
+.mui-segmented-control-negative .mui-control-item.mui-active
+{
+    color: #fff;
+    background-color: #dd524d;
+}
+.mui-segmented-control-negative.mui-segmented-control-inverted .mui-control-item.mui-active
+{
+    color: #dd524d;
+    border-bottom: 2px solid #dd524d;
+    background: none;
+}
+.mui-segmented-control-negative.mui-segmented-control-inverted ~ .mui-slider-progress-bar
+{
+    background-color: #dd524d;
+}
+
+.mui-control-content
+{
+    position: relative;
+
+    display: none;
+}
+.mui-control-content.mui-active
+{
+    display: block;
+}
+
+.mui-popover
+{
+    position: absolute;
+    z-index: 999;
+
+    display: none;
+
+    width: 280px;
+
+    -webkit-transition: opacity .3s;
+            transition: opacity .3s;
+    -webkit-transition-property: opacity;
+            transition-property: opacity;
+    -webkit-transform: none;
+            transform: none;
+
+    opacity: 0;
+    border-radius: 7px;
+    background-color: #f7f7f7;
+    -webkit-box-shadow: 0 0 15px rgba(0, 0, 0, .1);
+            box-shadow: 0 0 15px rgba(0, 0, 0, .1);
+}
+.mui-popover .mui-popover-arrow
+{
+    position: absolute;
+    z-index: 1000;
+    top: -25px;
+    left: 0;
+
+    overflow: hidden;
+
+    width: 26px;
+    height: 26px;
+}
+.mui-popover .mui-popover-arrow:after
+{
+    position: absolute;
+    top: 19px;
+    left: 0;
+
+    width: 26px;
+    height: 26px;
+
+    content: ' ';
+    -webkit-transform: rotate(45deg);
+            transform: rotate(45deg);
+
+    border-radius: 3px;
+    background: #f7f7f7;
+}
+.mui-popover .mui-popover-arrow.mui-bottom
+{
+    top: 100%;
+    left: -26px;
+
+    margin-top: -1px;
+}
+.mui-popover .mui-popover-arrow.mui-bottom:after
+{
+    top: -19px;
+    left: 0;
+}
+.mui-popover.mui-popover-action
+{
+    bottom: 0;
+
+    width: 100%;
+
+    -webkit-transition: -webkit-transform .3s, opacity .3s;
+            transition:         transform .3s, opacity .3s;
+    -webkit-transform: translate3d(0, 100%, 0);
+            transform: translate3d(0, 100%, 0);
+
+    border-radius: 0;
+    background: none;
+    -webkit-box-shadow: none;
+            box-shadow: none;
+}
+.mui-popover.mui-popover-action .mui-popover-arrow
+{
+    display: none;
+}
+.mui-popover.mui-popover-action.mui-popover-bottom
+{
+    position: fixed;
+}
+.mui-popover.mui-popover-action.mui-active
+{
+    -webkit-transform: translate3d(0, 0, 0);
+            transform: translate3d(0, 0, 0);
+}
+.mui-popover.mui-popover-action .mui-table-view
+{
+    margin: 8px;
+
+    text-align: center;
+
+    color: #007aff;
+    border-radius: 4px;
+}
+.mui-popover.mui-popover-action .mui-table-view .mui-table-view-cell:after
+{
+    position: absolute;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+
+    background-color: #c8c7cc;
+}
+.mui-popover.mui-popover-action .mui-table-view small
+{
+    font-weight: 400;
+    line-height: 1.3;
+
+    display: block;
+}
+.mui-popover.mui-active
+{
+    display: block;
+
+    opacity: 1;
+}
+.mui-popover .mui-bar ~ .mui-table-view
+{
+    padding-top: 44px;
+}
+
+.mui-backdrop
+{
+    position: fixed;
+    z-index: 998;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    background-color: rgba(0, 0, 0, .3);
+}
+
+.mui-bar-backdrop.mui-backdrop
+{
+    bottom: 50px;
+
+    background: none;
+}
+
+.mui-backdrop-action.mui-backdrop
+{
+    background-color: rgba(0, 0, 0, .3);
+}
+
+.mui-bar-backdrop.mui-backdrop, .mui-backdrop-action.mui-backdrop
+{
+    opacity: 0;
+}
+.mui-bar-backdrop.mui-backdrop.mui-active, .mui-backdrop-action.mui-backdrop.mui-active
+{
+    -webkit-transition: all .4s ease;
+            transition: all .4s ease;
+
+    opacity: 1;
+}
+
+.mui-popover .mui-btn-block
+{
+    margin-bottom: 5px;
+}
+.mui-popover .mui-btn-block:last-child
+{
+    margin-bottom: 0;
+}
+
+.mui-popover .mui-bar
+{
+    -webkit-box-shadow: none;
+            box-shadow: none;
+}
+
+.mui-popover .mui-bar-nav
+{
+    border-bottom: 1px solid rgba(0, 0, 0, .15);
+    border-top-left-radius: 12px;
+    border-top-right-radius: 12px;
+    -webkit-box-shadow: none;
+            box-shadow: none;
+}
+
+.mui-popover .mui-scroll-wrapper
+{
+    margin: 7px 0;
+
+    border-radius: 7px;
+    background-clip: padding-box;
+}
+
+.mui-popover .mui-scroll .mui-table-view
+{
+    max-height: none;
+}
+
+.mui-popover .mui-table-view
+{
+    overflow: auto;
+
+    max-height: 300px;
+    margin-bottom: 0;
+
+    border-radius: 7px;
+    background-color: #f7f7f7;
+    background-image: none;
+
+    -webkit-overflow-scrolling: touch;
+}
+.mui-popover .mui-table-view:before, .mui-popover .mui-table-view:after
+{
+    height: 0;
+}
+.mui-popover .mui-table-view .mui-table-view-cell:first-child,
+.mui-popover .mui-table-view .mui-table-view-cell:first-child > a:not(.mui-btn)
+{
+    border-top-left-radius: 12px;
+    border-top-right-radius: 12px;
+}
+.mui-popover .mui-table-view .mui-table-view-cell:last-child,
+.mui-popover .mui-table-view .mui-table-view-cell:last-child > a:not(.mui-btn)
+{
+    border-bottom-right-radius: 12px;
+    border-bottom-left-radius: 12px;
+}
+
+.mui-popover.mui-bar-popover .mui-table-view
+{
+    width: 106px;
+}
+.mui-popover.mui-bar-popover .mui-table-view .mui-table-view-cell
+{
+    padding: 11px 15px 11px 15px;
+
+    background-position: 0 100%;
+}
+.mui-popover.mui-bar-popover .mui-table-view .mui-table-view-cell > a:not(.mui-btn)
+{
+    margin: -11px -15px -11px -15px;
+}
+
+.mui-popup-backdrop
+{
+    position: fixed;
+    z-index: 998;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+
+    -webkit-transition-duration: 400ms;
+            transition-duration: 400ms;
+
+    opacity: 0;
+    background: rgba(0, 0, 0, .4);
+}
+.mui-popup-backdrop.mui-active
+{
+    opacity: 1;
+}
+
+.mui-popup
+{
+    position: fixed;
+    z-index: 10000;
+    top: 50%;
+    left: 50%;
+
+    display: none;
+    overflow: hidden;
+
+    width: 270px;
+
+    -webkit-transition-property: -webkit-transform,opacity;
+            transition-property:         transform,opacity;
+    -webkit-transform: translate3d(-50%, -50%, 0) scale(1.185);
+            transform: translate3d(-50%, -50%, 0) scale(1.185);
+    text-align: center;
+
+    opacity: 0;
+    color: #000;
+    border-radius: 13px;
+}
+.mui-popup.mui-popup-in
+{
+    display: block;
+
+    -webkit-transition-duration: 400ms;
+            transition-duration: 400ms;
+    -webkit-transform: translate3d(-50%, -50%, 0) scale(1);
+            transform: translate3d(-50%, -50%, 0) scale(1);
+
+    opacity: 1;
+}
+.mui-popup.mui-popup-out
+{
+    -webkit-transition-duration: 400ms;
+            transition-duration: 400ms;
+    -webkit-transform: translate3d(-50%, -50%, 0) scale(1);
+            transform: translate3d(-50%, -50%, 0) scale(1);
+
+    opacity: 0;
+}
+
+.mui-popup-inner
+{
+    position: relative;
+
+    padding: 15px;
+
+    border-radius: 13px 13px 0 0;
+    background: rgba(255, 255, 255, .95);
+}
+.mui-popup-inner:after
+{
+    position: absolute;
+    z-index: 15;
+    top: auto;
+    right: auto;
+    bottom: 0;
+    left: 0;
+
+    display: block;
+
+    width: 100%;
+    height: 1px;
+
+    content: '';
+    -webkit-transform: scaleY(.5);
+            transform: scaleY(.5);
+    -webkit-transform-origin: 50% 100%;
+            transform-origin: 50% 100%;
+
+    background-color: rgba(0, 0, 0, .2);
+}
+
+.mui-popup-title
+{
+    font-size: 18px;
+    font-weight: 500;
+
+    text-align: center;
+}
+
+.mui-popup-title + .mui-popup-text
+{
+    font-family: inherit;
+    font-size: 14px;
+
+    margin: 5px 0 0;
+}
+
+.mui-popup-buttons
+{
+    position: relative;
+
+    display: -webkit-box;
+    display: -webkit-flex;
+    display:         flex;
+
+    height: 44px;
+
+    -webkit-box-pack: center;
+    -webkit-justify-content: center;
+            justify-content: center;
+}
+
+.mui-popup-button
+{
+    font-size: 17px;
+    line-height: 44px;
+
+    position: relative;
+
+    display: block;
+    overflow: hidden;
+
+    box-sizing: border-box;
+    width: 100%;
+    height: 44px;
+    padding: 0 5px;
+
+    cursor: pointer;
+    text-align: center;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+
+    color: #007aff;
+    background: rgba(255, 255, 255, .95);
+
+    -webkit-box-flex: 1;
+}
+.mui-popup-button:after
+{
+    position: absolute;
+    z-index: 15;
+    top: 0;
+    right: 0;
+    bottom: auto;
+    left: auto;
+
+    display: block;
+
+    width: 1px;
+    height: 100%;
+
+    content: '';
+    -webkit-transform: scaleX(.5);
+            transform: scaleX(.5);
+    -webkit-transform-origin: 100% 50%;
+            transform-origin: 100% 50%;
+
+    background-color: rgba(0, 0, 0, .2);
+}
+.mui-popup-button:first-child
+{
+    border-radius: 0 0 0 13px;
+}
+.mui-popup-button:first-child:last-child
+{
+    border-radius: 0 0 13px 13px;
+}
+.mui-popup-button:last-child
+{
+    border-radius: 0 0 13px 0;
+}
+.mui-popup-button:last-child:after
+{
+    display: none;
+}
+.mui-popup-button.mui-popup-button-bold
+{
+    font-weight: 600;
+}
+
+.mui-popup-input input
+{
+    font-size: 14px;
+
+    width: 100%;
+    height: 26px;
+    margin: 15px 0 0;
+    padding: 0 5px;
+
+    border: 1px solid rgba(0, 0, 0, .3);
+    border-radius: 0;
+    background: #fff;
+}
+
+.mui-plus.mui-android .mui-popup-backdrop
+{
+    -webkit-transition-duration: 1ms;
+            transition-duration: 1ms;
+}
+
+.mui-plus.mui-android .mui-popup
+{
+    -webkit-transition-duration: 1ms;
+            transition-duration: 1ms;
+    -webkit-transform: translate3d(-50%, -50%, 0) scale(1);
+            transform: translate3d(-50%, -50%, 0) scale(1);
+}
+
+/* === Progress Bar === */
+.mui-progressbar
+{
+    position: relative;
+
+    display: block;
+    overflow: hidden;
+
+    width: 100%;
+    height: 2px;
+
+    -webkit-transform-origin: center top;
+            transform-origin: center top;
+    vertical-align: middle;
+
+    border-radius: 2px;
+    background: #b6b6b6;
+
+    -webkit-transform-style: preserve-3d;
+            transform-style: preserve-3d;
+}
+.mui-progressbar span
+{
+    position: absolute;
+    top: 0;
+    left: 0;
+
+    width: 100%;
+    height: 100%;
+
+    -webkit-transition: 150ms;
+            transition: 150ms;
+    -webkit-transform: translate3d(-100%, 0, 0);
+            transform: translate3d(-100%, 0, 0);
+
+    background: #007aff;
+}
+.mui-progressbar.mui-progressbar-infinite:before
+{
+    position: absolute;
+    top: 0;
+    left: 0;
+
+    width: 100%;
+    height: 100%;
+
+    content: '';
+    -webkit-transform: translate3d(0, 0, 0);
+            transform: translate3d(0, 0, 0);
+    -webkit-transform-origin: left center;
+            transform-origin: left center;
+    -webkit-animation: mui-progressbar-infinite 1s linear infinite;
+            animation: mui-progressbar-infinite 1s linear infinite;
+
+    background: #007aff;
+}
+
+body > .mui-progressbar
+{
+    position: absolute;
+    z-index: 10000;
+    top: 44px;
+    left: 0;
+
+    border-radius: 0;
+}
+
+.mui-progressbar-in
+{
+    -webkit-animation: mui-progressbar-in 300ms forwards;
+            animation: mui-progressbar-in 300ms forwards;
+}
+
+.mui-progressbar-out
+{
+    -webkit-animation: mui-progressbar-out 300ms forwards;
+            animation: mui-progressbar-out 300ms forwards;
+}
+
+@-webkit-keyframes mui-progressbar-in
+{
+    from
+    {
+        -webkit-transform: scaleY(0);
+
+        opacity: 0;
+    }
+
+    to
+    {
+        -webkit-transform: scaleY(1);
+
+        opacity: 1;
+    }
+}
+@keyframes mui-progressbar-in
+{
+    from
+    {
+        transform: scaleY(0);
+
+        opacity: 0;
+    }
+
+    to
+    {
+        transform: scaleY(1);
+
+        opacity: 1;
+    }
+}
+@-webkit-keyframes mui-progressbar-out
+{
+    from
+    {
+        -webkit-transform: scaleY(1);
+
+        opacity: 1;
+    }
+
+    to
+    {
+        -webkit-transform: scaleY(0);
+
+        opacity: 0;
+    }
+}
+@keyframes mui-progressbar-out
+{
+    from
+    {
+        transform: scaleY(1);
+
+        opacity: 1;
+    }
+
+    to
+    {
+        transform: scaleY(0);
+
+        opacity: 0;
+    }
+}
+@-webkit-keyframes mui-progressbar-infinite
+{
+    0%
+    {
+        -webkit-transform: translate3d(-50%, 0, 0) scaleX(.5);
+    }
+
+    100%
+    {
+        -webkit-transform: translate3d(100%, 0, 0) scaleX(.5);
+    }
+}
+@keyframes mui-progressbar-infinite
+{
+    0%
+    {
+        transform: translate3d(-50%, 0, 0) scaleX(.5);
+    }
+
+    100%
+    {
+        transform: translate3d(100%, 0, 0) scaleX(.5);
+    }
+}
+.mui-pagination
+{
+    display: inline-block;
+
+    margin: 0 auto;
+    padding-left: 0;
+
+    border-radius: 6px;
+}
+.mui-pagination > li
+{
+    display: inline;
+}
+.mui-pagination > li > a,
+.mui-pagination > li > span
+{
+    line-height: 1.428571429;
+
+    position: relative;
+
+    float: left;
+
+    margin-left: -1px;
+    padding: 6px 12px;
+
+    text-decoration: none;
+
+    color: #007aff;
+    border: 1px solid #ddd;
+    background-color: #fff;
+}
+.mui-pagination > li:first-child > a,
+.mui-pagination > li:first-child > span
+{
+    margin-left: 0;
+
+    border-top-left-radius: 6px;
+    border-bottom-left-radius: 6px;
+    background-clip: padding-box;
+}
+.mui-pagination > li:last-child > a,
+.mui-pagination > li:last-child > span
+{
+    border-top-right-radius: 6px;
+    border-bottom-right-radius: 6px;
+    background-clip: padding-box;
+}
+.mui-pagination > li:active > a, .mui-pagination > li:active > a:active,
+.mui-pagination > li:active > span,
+.mui-pagination > li:active > span:active,
+.mui-pagination > li.mui-active > a,
+.mui-pagination > li.mui-active > a:active,
+.mui-pagination > li.mui-active > span,
+.mui-pagination > li.mui-active > span:active
+{
+    z-index: 2;
+
+    cursor: default;
+
+    color: #fff;
+    border-color: #007aff;
+    background-color: #007aff;
+}
+.mui-pagination > li.mui-disabled > span,
+.mui-pagination > li.mui-disabled > span:active,
+.mui-pagination > li.mui-disabled > a,
+.mui-pagination > li.mui-disabled > a:active
+{
+    opacity: .6;
+    color: #777;
+    border: 1px solid #ddd;
+    background-color: #fff;
+}
+
+.mui-pagination-lg > li > a,
+.mui-pagination-lg > li > span
+{
+    font-size: 18px;
+
+    padding: 10px 16px;
+}
+
+.mui-pagination-sm > li > a,
+.mui-pagination-sm > li > span
+{
+    font-size: 12px;
+
+    padding: 5px 10px;
+}
+
+.mui-pager
+{
+    padding-left: 0;
+
+    list-style: none;
+
+    text-align: center;
+}
+.mui-pager:before, .mui-pager:after
+{
+    display: table;
+
+    content: ' ';
+}
+.mui-pager:after
+{
+    clear: both;
+}
+.mui-pager li
+{
+    display: inline;
+}
+.mui-pager li > a,
+.mui-pager li > span
+{
+    display: inline-block;
+
+    padding: 5px 14px;
+
+    border: 1px solid #ddd;
+    border-radius: 6px;
+    background-color: #fff;
+    background-clip: padding-box;
+}
+.mui-pager li:active > a, .mui-pager li:active > span, .mui-pager li.mui-active > a, .mui-pager li.mui-active > span
+{
+    cursor: default;
+    text-decoration: none;
+
+    color: #fff;
+    border-color: #007aff;
+    background-color: #007aff;
+}
+.mui-pager .mui-next > a,
+.mui-pager .mui-next > span
+{
+    float: right;
+}
+.mui-pager .mui-previous > a,
+.mui-pager .mui-previous > span
+{
+    float: left;
+}
+.mui-pager .mui-disabled > a,
+.mui-pager .mui-disabled > a:active,
+.mui-pager .mui-disabled > span,
+.mui-pager .mui-disabled > span:active
+{
+    opacity: .6;
+    color: #777;
+    border: 1px solid #ddd;
+    background-color: #fff;
+}
+
+.mui-modal
+{
+    position: fixed;
+    z-index: 999;
+    top: 0;
+
+    overflow: hidden;
+
+    width: 100%;
+    min-height: 100%;
+
+    -webkit-transition: -webkit-transform .25s, opacity 1ms .25s;
+            transition:         transform .25s, opacity 1ms .25s;
+    -webkit-transition-timing-function: cubic-bezier(.1, .5, .1, 1);
+            transition-timing-function: cubic-bezier(.1, .5, .1, 1);
+    -webkit-transform: translate3d(0, 100%, 0);
+            transform: translate3d(0, 100%, 0);
+
+    opacity: 0;
+    background-color: #fff;
+}
+.mui-modal.mui-active
+{
+    height: 100%;
+
+    -webkit-transition: -webkit-transform .25s;
+            transition:         transform .25s;
+    -webkit-transition-timing-function: cubic-bezier(.1, .5, .1, 1);
+            transition-timing-function: cubic-bezier(.1, .5, .1, 1);
+    -webkit-transform: translate3d(0, 0, 0);
+            transform: translate3d(0, 0, 0);
+
+    opacity: 1;
+}
+
+.mui-android .mui-modal .mui-bar
+{
+    position: static;
+}
+
+.mui-android .mui-modal .mui-bar-nav ~ .mui-content
+{
+    padding-top: 0;
+}
+
+.mui-slider
+{
+    position: relative;
+    z-index: 1;
+
+    overflow: hidden;
+
+    width: 100%;
+}
+.mui-slider .mui-segmented-control.mui-segmented-control-inverted .mui-control-item.mui-active
+{
+    border-bottom: 0;
+}
+.mui-slider .mui-segmented-control.mui-segmented-control-inverted ~ .mui-slider-group .mui-slider-item
+{
+    border-top: 1px solid #c8c7cc;
+    border-bottom: 1px solid #c8c7cc;
+}
+.mui-slider .mui-slider-group
+{
+    font-size: 0;
+
+    position: relative;
+
+    -webkit-transition: all 0s linear;
+            transition: all 0s linear;
+    white-space: nowrap;
+}
+.mui-slider .mui-slider-group .mui-slider-item
+{
+    font-size: 14px;
+
+    position: relative;
+
+    display: inline-block;
+
+    width: 100%;
+    height: 100%;
+
+    vertical-align: top;
+    white-space: normal;
+}
+.mui-slider .mui-slider-group .mui-slider-item > a:not(.mui-control-item)
+{
+    line-height: 0;
+
+    position: relative;
+
+    display: block;
+}
+.mui-slider .mui-slider-group .mui-slider-item img
+{
+    width: 100%;
+}
+.mui-slider .mui-slider-group .mui-slider-item .mui-table-view:before, .mui-slider .mui-slider-group .mui-slider-item .mui-table-view:after
+{
+    height: 0;
+}
+.mui-slider .mui-slider-group.mui-slider-loop
+{
+    -webkit-transform: translate(-100%, 0px);
+            transform: translate(-100%, 0px);
+}
+
+.mui-slider-title
+{
+    line-height: 30px;
+
+    position: absolute;
+    bottom: 0;
+    left: 0;
+
+    width: 100%;
+    height: 30px;
+    margin: 0;
+
+    text-align: left;
+    text-indent: 12px;
+
+    opacity: .8;
+    background-color: #000;
+}
+
+.mui-slider-indicator
+{
+    position: absolute;
+    bottom: 8px;
+
+    width: 100%;
+
+    text-align: center;
+
+    background: none;
+}
+.mui-slider-indicator.mui-segmented-control
+{
+    position: relative;
+    bottom: auto;
+}
+.mui-slider-indicator .mui-indicator
+{
+    display: inline-block;
+
+    width: 6px;
+    height: 6px;
+    margin: 1px 6px;
+
+    cursor: pointer;
+
+    border-radius: 50%;
+    background: #aaa;
+    -webkit-box-shadow: 0 0 1px 1px rgba(130, 130, 130, .7);
+            box-shadow: 0 0 1px 1px rgba(130, 130, 130, .7);
+}
+.mui-slider-indicator .mui-active.mui-indicator
+{
+    background: #fff;
+}
+.mui-slider-indicator .mui-icon
+{
+    font-size: 20px;
+    line-height: 30px;
+
+    width: 40px;
+    height: 30px;
+    margin: 3px;
+
+    text-align: center;
+
+    border: 1px solid #ddd;
+}
+.mui-slider-indicator .mui-number
+{
+    line-height: 32px;
+
+    display: inline-block;
+
+    width: 58px;
+}
+.mui-slider-indicator .mui-number span
+{
+    color: #ff5053;
+}
+
+.mui-slider-progress-bar
+{
+    z-index: 1;
+
+    height: 2px;
+
+    -webkit-transform: translateZ(0);
+            transform: translateZ(0);
+}
+
+.mui-switch
+{
+    position: relative;
+
+    display: block;
+
+    width: 74px;
+    height: 30px;
+
+    -webkit-transition-timing-function: ease-in-out;
+            transition-timing-function: ease-in-out;
+    -webkit-transition-duration: .2s;
+            transition-duration: .2s;
+    -webkit-transition-property: background-color, border;
+            transition-property: background-color, border;
+
+    border: 2px solid #ddd;
+    border-radius: 20px;
+    background-color: #fff;
+    background-clip: padding-box;
+}
+.mui-switch.mui-disabled
+{
+    opacity: .3;
+}
+.mui-switch .mui-switch-handle
+{
+    position: absolute;
+    z-index: 1;
+    top: -1px;
+    left: -1px;
+
+    width: 28px;
+    height: 28px;
+
+    -webkit-transition: .2s ease-in-out;
+            transition: .2s ease-in-out;
+    -webkit-transition-property: -webkit-transform, width,left;
+            transition-property:         transform, width,left;
+
+    border-radius: 16px;
+    background-color: #fff;
+    background-clip: padding-box;
+    -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, .4);
+            box-shadow: 0 2px 5px rgba(0, 0, 0, .4);
+}
+.mui-switch:before
+{
+    font-size: 13px;
+
+    position: absolute;
+    top: 3px;
+    right: 11px;
+
+    content: 'Off';
+    text-transform: uppercase;
+
+    color: #999;
+}
+.mui-switch.mui-dragging
+{
+    border-color: #f7f7f7;
+    background-color: #f7f7f7;
+}
+.mui-switch.mui-dragging .mui-switch-handle
+{
+    width: 38px;
+}
+.mui-switch.mui-dragging.mui-active .mui-switch-handle
+{
+    left: -11px;
+
+    width: 38px;
+}
+.mui-switch.mui-active
+{
+    border-color: #4cd964;
+    background-color: #4cd964;
+}
+.mui-switch.mui-active .mui-switch-handle
+{
+    -webkit-transform: translate(43px, 0);
+            transform: translate(43px, 0);
+}
+.mui-switch.mui-active:before
+{
+    right: auto;
+    left: 15px;
+
+    content: 'On';
+
+    color: #fff;
+}
+.mui-switch input[type='checkbox']
+{
+    display: none;
+}
+
+.mui-switch-mini
+{
+    width: 47px;
+}
+.mui-switch-mini:before
+{
+    display: none;
+}
+.mui-switch-mini.mui-active .mui-switch-handle
+{
+    -webkit-transform: translate(16px, 0);
+            transform: translate(16px, 0);
+}
+
+.mui-switch-blue.mui-active
+{
+    border: 2px solid #007aff;
+    background-color: #007aff;
+}
+
+.mui-content.mui-fade
+{
+    left: 0;
+
+    opacity: 0;
+}
+.mui-content.mui-fade.mui-in
+{
+    opacity: 1;
+}
+.mui-content.mui-sliding
+{
+    z-index: 2;
+
+    -webkit-transition: -webkit-transform .4s;
+            transition:         transform .4s;
+    -webkit-transform: translate3d(0, 0, 0);
+            transform: translate3d(0, 0, 0);
+}
+.mui-content.mui-sliding.mui-left
+{
+    z-index: 1;
+
+    -webkit-transform: translate3d(-100%, 0, 0);
+            transform: translate3d(-100%, 0, 0);
+}
+.mui-content.mui-sliding.mui-right
+{
+    z-index: 3;
+
+    -webkit-transform: translate3d(100%, 0, 0);
+            transform: translate3d(100%, 0, 0);
+}
+
+.mui-navigate-right:after,
+.mui-push-left:after,
+.mui-push-right:after
+{
+    font-family: Muiicons;
+    font-size: inherit;
+    line-height: 1;
+
+    position: absolute;
+    top: 50%;
+
+    display: inline-block;
+
+    -webkit-transform: translateY(-50%);
+            transform: translateY(-50%);
+    text-decoration: none;
+
+    color: #bbb;
+
+    -webkit-font-smoothing: antialiased;
+}
+
+.mui-push-left:after
+{
+    left: 15px;
+
+    content: '\e582';
+}
+
+.mui-navigate-right:after,
+.mui-push-right:after
+{
+    right: 15px;
+
+    content: '\e583';
+}
+
+.mui-pull-top-pocket, .mui-pull-bottom-pocket
+{
+    position: absolute;
+    left: 0;
+
+    display: block;
+    visibility: hidden;
+    overflow: hidden;
+
+    width: 100%;
+    height: 50px;
+}
+
+.mui-plus-pullrefresh .mui-pull-top-pocket, .mui-plus-pullrefresh .mui-pull-bottom-pocket
+{
+    display: none;
+    visibility: visible;
+}
+
+.mui-pull-top-pocket
+{
+    top: 0;
+}
+
+.mui-bar-nav ~ .mui-content .mui-pull-top-pocket
+{
+    top: 44px;
+}
+
+.mui-bar-nav ~ .mui-bar-header-secondary ~ .mui-content .mui-pull-top-pocket
+{
+    top: 88px;
+}
+
+.mui-pull-bottom-pocket
+{
+    position: relative;
+    bottom: 0;
+
+    height: 40px;
+}
+.mui-pull-bottom-pocket .mui-pull-loading
+{
+    visibility: hidden;
+}
+.mui-pull-bottom-pocket .mui-pull-loading.mui-in
+{
+    display: inline-block;
+}
+
+.mui-pull
+{
+    font-weight: bold;
+
+    position: absolute;
+    right: 0;
+    bottom: 10px;
+    left: 0;
+
+    text-align: center;
+
+    color: #777;
+}
+
+.mui-pull-loading
+{
+    margin-right: 10px;
+
+    -webkit-transition: -webkit-transform .4s;
+            transition:         transform .4s;
+    -webkit-transition-duration: 400ms;
+            transition-duration: 400ms;
+    vertical-align: middle;
+}
+
+.mui-pull-loading.mui-reverse
+{
+    -webkit-transform: rotate(180deg) translateZ(0);
+            transform: rotate(180deg) translateZ(0);
+}
+
+.mui-pull-caption
+{
+    font-size: 15px;
+    line-height: 24px;
+
+    position: relative;
+
+    display: inline-block;
+    overflow: visible;
+
+    margin-top: 0;
+
+    vertical-align: middle;
+}
+.mui-pull-caption span
+{
+    display: none;
+}
+.mui-pull-caption span.mui-in
+{
+    display: inline;
+}
+
+.mui-toast-container
+{
+    line-height: 17px;
+
+    position: fixed;
+    z-index: 9999;
+    bottom: 50px;
+    left: 50%;
+
+    -webkit-transition: opacity .3s;
+            transition: opacity .3s;
+    -webkit-transform: translate(-50%, 0);
+            transform: translate(-50%, 0);
+
+    opacity: 0;
+}
+.mui-toast-container.mui-active
+{
+    opacity: .9;
+}
+
+.mui-toast-message
+{
+    font-size: 14px;
+
+    padding: 10px 25px;
+
+    text-align: center;
+
+    color: #fff;
+    border-radius: 6px;
+    background-color: #323232;
+}
+
+.mui-numbox
+{
+    position: relative;
+
+    display: inline-block;
+    overflow: hidden;
+
+    width: 120px;
+    height: 35px;
+    padding: 0 40px 0 40px;
+
+    vertical-align: top;
+    vertical-align: middle;
+
+    border: solid 1px #bbb;
+    border-radius: 3px;
+    background-color: #efeff4;
+}
+.mui-numbox [class*=numbox-btn], .mui-numbox [class*=btn-numbox]
+{
+    font-size: 18px;
+    font-weight: normal;
+    line-height: 100%;
+
+    position: absolute;
+    top: 0;
+
+    overflow: hidden;
+
+    width: 40px;
+    height: 100%;
+    padding: 0;
+
+    color: #555;
+    border: none;
+    border-radius: 0;
+    background-color: #f9f9f9;
+}
+.mui-numbox [class*=numbox-btn]:active, .mui-numbox [class*=btn-numbox]:active
+{
+    background-color: #ccc;
+}
+.mui-numbox [class*=numbox-btn][disabled], .mui-numbox [class*=btn-numbox][disabled]
+{
+    color: #c0c0c0;
+}
+.mui-numbox .mui-numbox-btn-plus, .mui-numbox .mui-btn-numbox-plus
+{
+    right: 0;
+
+    border-top-right-radius: 3px;
+    border-bottom-right-radius: 3px;
+}
+.mui-numbox .mui-numbox-btn-minus, .mui-numbox .mui-btn-numbox-minus
+{
+    left: 0;
+
+    border-top-left-radius: 3px;
+    border-bottom-left-radius: 3px;
+}
+.mui-numbox .mui-numbox-input, .mui-numbox .mui-input-numbox
+{
+    display: inline-block;
+    overflow: hidden;
+
+    width: 100% !important;
+    height: 100%;
+    margin: 0;
+    padding: 0 3px !important;
+
+    text-align: center;
+    text-overflow: ellipsis;
+    word-break: normal;
+
+    border: none !important;
+    border-right: solid 1px #ccc !important;
+    border-left: solid 1px #ccc !important;
+    border-radius: 0 !important;
+}
+
+.mui-input-row .mui-numbox
+{
+    float: right;
+
+    margin: 2px 8px;
+}
+
+@font-face {
+    font-family: Muiicons;
+    font-weight: normal;
+    font-style: normal;
+
+    src: url('../fonts/mui.ttf') format('truetype');
+}
+.mui-icon
+{
+    font-family: Muiicons;
+    font-size: 24px;
+    font-weight: normal;
+    font-style: normal;
+    line-height: 1;
+
+    display: inline-block;
+
+    text-decoration: none;
+
+    -webkit-font-smoothing: antialiased;
+}
+.mui-icon.mui-active
+{
+    color: #007aff;
+}
+.mui-icon.mui-right:before
+{
+    float: right;
+
+    padding-left: .2em;
+}
+
+.mui-icon-contact:before
+{
+    content: '\e100';
+}
+
+.mui-icon-person:before
+{
+    content: '\e101';
+}
+
+.mui-icon-personadd:before
+{
+    content: '\e102';
+}
+
+.mui-icon-contact-filled:before
+{
+    content: '\e130';
+}
+
+.mui-icon-person-filled:before
+{
+    content: '\e131';
+}
+
+.mui-icon-personadd-filled:before
+{
+    content: '\e132';
+}
+
+.mui-icon-phone:before
+{
+    content: '\e200';
+}
+
+.mui-icon-email:before
+{
+    content: '\e201';
+}
+
+.mui-icon-chatbubble:before
+{
+    content: '\e202';
+}
+
+.mui-icon-chatboxes:before
+{
+    content: '\e203';
+}
+
+.mui-icon-phone-filled:before
+{
+    content: '\e230';
+}
+
+.mui-icon-email-filled:before
+{
+    content: '\e231';
+}
+
+.mui-icon-chatbubble-filled:before
+{
+    content: '\e232';
+}
+
+.mui-icon-chatboxes-filled:before
+{
+    content: '\e233';
+}
+
+.mui-icon-weibo:before
+{
+    content: '\e260';
+}
+
+.mui-icon-weixin:before
+{
+    content: '\e261';
+}
+
+.mui-icon-pengyouquan:before
+{
+    content: '\e262';
+}
+
+.mui-icon-chat:before
+{
+    content: '\e263';
+}
+
+.mui-icon-qq:before
+{
+    content: '\e264';
+}
+
+.mui-icon-videocam:before
+{
+    content: '\e300';
+}
+
+.mui-icon-camera:before
+{
+    content: '\e301';
+}
+
+.mui-icon-mic:before
+{
+    content: '\e302';
+}
+
+.mui-icon-location:before
+{
+    content: '\e303';
+}
+
+.mui-icon-mic-filled:before, .mui-icon-speech:before
+{
+    content: '\e332';
+}
+
+.mui-icon-location-filled:before
+{
+    content: '\e333';
+}
+
+.mui-icon-micoff:before
+{
+    content: '\e360';
+}
+
+.mui-icon-image:before
+{
+    content: '\e363';
+}
+
+.mui-icon-map:before
+{
+    content: '\e364';
+}
+
+.mui-icon-compose:before
+{
+    content: '\e400';
+}
+
+.mui-icon-trash:before
+{
+    content: '\e401';
+}
+
+.mui-icon-upload:before
+{
+    content: '\e402';
+}
+
+.mui-icon-download:before
+{
+    content: '\e403';
+}
+
+.mui-icon-close:before
+{
+    content: '\e404';
+}
+
+.mui-icon-redo:before
+{
+    content: '\e405';
+}
+
+.mui-icon-undo:before
+{
+    content: '\e406';
+}
+
+.mui-icon-refresh:before
+{
+    content: '\e407';
+}
+
+.mui-icon-star:before
+{
+    content: '\e408';
+}
+
+.mui-icon-plus:before
+{
+    content: '\e409';
+}
+
+.mui-icon-minus:before
+{
+    content: '\e410';
+}
+
+.mui-icon-circle:before, .mui-icon-checkbox:before
+{
+    content: '\e411';
+}
+
+.mui-icon-close-filled:before, .mui-icon-clear:before
+{
+    content: '\e434';
+}
+
+.mui-icon-refresh-filled:before
+{
+    content: '\e437';
+}
+
+.mui-icon-star-filled:before
+{
+    content: '\e438';
+}
+
+.mui-icon-plus-filled:before
+{
+    content: '\e439';
+}
+
+.mui-icon-minus-filled:before
+{
+    content: '\e440';
+}
+
+.mui-icon-circle-filled:before
+{
+    content: '\e441';
+}
+
+.mui-icon-checkbox-filled:before
+{
+    content: '\e442';
+}
+
+.mui-icon-closeempty:before
+{
+    content: '\e460';
+}
+
+.mui-icon-refreshempty:before
+{
+    content: '\e461';
+}
+
+.mui-icon-reload:before
+{
+    content: '\e462';
+}
+
+.mui-icon-starhalf:before
+{
+    content: '\e463';
+}
+
+.mui-icon-spinner:before
+{
+    content: '\e464';
+}
+
+.mui-icon-spinner-cycle:before
+{
+    content: '\e465';
+}
+
+.mui-icon-search:before
+{
+    content: '\e466';
+}
+
+.mui-icon-plusempty:before
+{
+    content: '\e468';
+}
+
+.mui-icon-forward:before
+{
+    content: '\e470';
+}
+
+.mui-icon-back:before, .mui-icon-left-nav:before
+{
+    content: '\e471';
+}
+
+.mui-icon-checkmarkempty:before
+{
+    content: '\e472';
+}
+
+.mui-icon-home:before
+{
+    content: '\e500';
+}
+
+.mui-icon-navigate:before
+{
+    content: '\e501';
+}
+
+.mui-icon-gear:before
+{
+    content: '\e502';
+}
+
+.mui-icon-paperplane:before
+{
+    content: '\e503';
+}
+
+.mui-icon-info:before
+{
+    content: '\e504';
+}
+
+.mui-icon-help:before
+{
+    content: '\e505';
+}
+
+.mui-icon-locked:before
+{
+    content: '\e506';
+}
+
+.mui-icon-more:before
+{
+    content: '\e507';
+}
+
+.mui-icon-flag:before
+{
+    content: '\e508';
+}
+
+.mui-icon-home-filled:before
+{
+    content: '\e530';
+}
+
+.mui-icon-gear-filled:before
+{
+    content: '\e532';
+}
+
+.mui-icon-info-filled:before
+{
+    content: '\e534';
+}
+
+.mui-icon-help-filled:before
+{
+    content: '\e535';
+}
+
+.mui-icon-more-filled:before
+{
+    content: '\e537';
+}
+
+.mui-icon-settings:before
+{
+    content: '\e560';
+}
+
+.mui-icon-list:before
+{
+    content: '\e562';
+}
+
+.mui-icon-bars:before
+{
+    content: '\e563';
+}
+
+.mui-icon-loop:before
+{
+    content: '\e565';
+}
+
+.mui-icon-paperclip:before
+{
+    content: '\e567';
+}
+
+.mui-icon-eye:before
+{
+    content: '\e568';
+}
+
+.mui-icon-arrowup:before
+{
+    content: '\e580';
+}
+
+.mui-icon-arrowdown:before
+{
+    content: '\e581';
+}
+
+.mui-icon-arrowleft:before
+{
+    content: '\e582';
+}
+
+.mui-icon-arrowright:before
+{
+    content: '\e583';
+}
+
+.mui-icon-arrowthinup:before
+{
+    content: '\e584';
+}
+
+.mui-icon-arrowthindown:before
+{
+    content: '\e585';
+}
+
+.mui-icon-arrowthinleft:before
+{
+    content: '\e586';
+}
+
+.mui-icon-arrowthinright:before
+{
+    content: '\e587';
+}
+
+.mui-icon-pulldown:before
+{
+    content: '\e588';
+}
+
+.mui-fullscreen
+{
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+}
+.mui-fullscreen.mui-slider .mui-slider-group
+{
+    height: 100%;
+}
+.mui-fullscreen .mui-segmented-control ~ .mui-slider-group
+{
+    position: absolute;
+    top: 40px;
+    bottom: 0;
+
+    width: 100%;
+    height: auto;
+}
+.mui-fullscreen.mui-slider .mui-slider-item > a
+{
+    top: 50%;
+
+    -webkit-transform: translateY(-50%);
+            transform: translateY(-50%);
+}
+.mui-fullscreen .mui-off-canvas-wrap .mui-slider-item > a
+{
+    top: auto;
+
+    -webkit-transform: none;
+            transform: none;
+}
+
+.mui-bar-nav ~ .mui-content .mui-slider.mui-fullscreen
+{
+    top: 44px;
+}
+
+.mui-bar-tab ~ .mui-content .mui-slider.mui-fullscreen .mui-segmented-control ~ .mui-slider-group
+{
+    bottom: 50px;
+}
+
+.mui-android.mui-android-4-0 input:focus,
+.mui-android.mui-android-4-0 textarea:focus
+{
+    -webkit-user-modify: inherit;
+}
+
+.mui-android.mui-android-4-2 input,
+.mui-android.mui-android-4-2 textarea, .mui-android.mui-android-4-3 input,
+.mui-android.mui-android-4-3 textarea
+{
+    -webkit-user-select: text;
+}
+
+.mui-ios .mui-table-view-cell
+{
+    -webkit-transform-style: preserve-3d;
+            transform-style: preserve-3d;
+}
+
+.mui-plus-visible, .mui-wechat-visible
+{
+    display: none !important;
+}
+
+.mui-plus-hidden, .mui-wechat-hidden
+{
+    display: block !important;
+}
+
+.mui-tab-item.mui-plus-hidden, .mui-tab-item.mui-wechat-hidden
+{
+    display: table-cell !important;
+}
+
+.mui-plus .mui-plus-visible, .mui-wechat .mui-wechat-visible
+{
+    display: block !important;
+}
+
+.mui-plus .mui-tab-item.mui-plus-visible, .mui-wechat .mui-tab-item.mui-wechat-visible
+{
+    display: table-cell !important;
+}
+
+.mui-plus .mui-plus-hidden, .mui-wechat .mui-wechat-hidden
+{
+    display: none !important;
+}
+
+.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav
+{
+    height: 64px;
+    padding-top: 20px;
+}
+.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav ~ .mui-content
+{
+    padding-top: 64px;
+}
+.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-nav ~ .mui-content .mui-pull-top-pocket
+{
+    top: 64px;
+}
+.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-header-secondary
+{
+    top: 64px;
+}
+.mui-plus.mui-statusbar.mui-statusbar-offset .mui-bar-header-secondary ~ .mui-content
+{
+    padding-top: 94px;
+}
+
+.mui-iframe-wrapper
+{
+    position: absolute;
+    right: 0;
+    left: 0;
+
+    -webkit-overflow-scrolling: touch;
+}
+.mui-iframe-wrapper iframe
+{
+    width: 100%;
+    height: 100%;
+
+    border: 0;
+}

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 4 - 0
hybrid/html/xuanfu/css/mui.min.css


BIN
hybrid/html/xuanfu/fonts/mui.ttf


BIN
hybrid/html/xuanfu/img/guaduandd.png


BIN
hybrid/html/xuanfu/img/jietong.png


BIN
hybrid/html/xuanfu/img/logo.png


BIN
hybrid/html/xuanfu/img/xinxi.png


BIN
hybrid/html/xuanfu/img/y800.mp3


+ 117 - 0
hybrid/html/xuanfu/index.html

@@ -0,0 +1,117 @@
+<!DOCTYPE html>
+<html>
+
+	<head>
+		<meta charset="utf-8">
+		<meta name="viewport"
+			content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
+		<title></title>
+		<script src="js/mui.min.js"></script>
+		<link href="css/mui.min.css" rel="stylesheet" />
+		<script>
+			mui.init();
+		</script>
+		<style type="text/css">
+			html,
+			body {
+				width: 100%;
+				height: 100%;
+				background-color:transparent;
+				display: flex;
+				flex-direction: column;
+				align-items: center;
+				justify-content: center;
+				/* opacity: 0.2; */
+			}
+			.contentColumnC{
+				display: flex;
+				flex-direction: column;
+				align-items: center;
+				justify-content: center;
+			}
+		</style>
+	</head>
+
+	<body>
+		<div id="time" class="contentColumnC">
+			<div>
+				CTE
+			</div>
+			<div id="noteT" style="font-size: 12px;">
+				鈴聲響時請退出導航查看信息
+			</div>
+			<div id="noteM" style="font-size: 12px;">
+				Thoát khỏi Navigation khi chuông reo Xem thông tin
+			</div>
+		</div>
+		<audio id="my_audio" autoplay></audio>
+		<!-- <button id="btn">发送消息给app</button> -->
+		
+		<script>
+			let state=0;
+			Date.prototype.Format = function(fmt) {
+				var o = {
+					"M+": this.getMonth() + 1, //月份 
+					"d+": this.getDate(), //日 
+					"h+": this.getHours(), //小时 
+					"m+": this.getMinutes(), //分 
+					"s+": this.getSeconds(), //秒 
+					"q+": Math.floor((this.getMonth() + 3) / 3), //季度 
+					"S": this.getMilliseconds() //毫秒 
+				};
+				if (/(y+)/.test(fmt))
+					fmt = fmt.replace(RegExp.$1, (this.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;
+			}
+			// setInterval((res) => {
+			// 	var time = new Date().Format("yyyy-MM-dd hh:mm:ss");
+			// 	document.getElementById("time").innerHTML = "当前时间:" + time
+			// }, 10)
+
+			function changeImg() {
+				
+			}
+			function changeImgvi() {
+				
+			}
+			function changeImgMS() {
+			}
+			function changeImgMSvi() {
+				// state=2;
+				// document.getElementById("img").style.display="none";
+				// document.getElementById("noteT").textContent='Có tin mới rồi';
+				// document.getElementById("noteM").textContent='Thoát Navigation Xem thông tin.';
+				// //document.getElementById("img").setAttribute("src", "img/xinxi.png");
+				// document.getElementById("my_audio").setAttribute("src", "img/y800.mp3");
+			}
+			
+			function changeImgdef(){
+				state=0;
+				// document.getElementById("img").style.display="block";
+				// //document.getElementById("img").setAttribute("src", "img/logo.png");
+				// document.getElementById("my_audio").setAttribute("src", "");
+			}
+			
+			document.getElementById("img").addEventListener("click", function(res) {
+				document.getElementById("my_audio").setAttribute("src", "");
+				var dic = {
+					"key": state
+				}
+				var jsonStr = JSON.stringify(dic)
+				try {
+					window.webkit.messageHandlers.sendData.postMessage(jsonStr); //ios
+				} catch (e) {}
+			})
+			function releaseTack(){
+				document.getElementById("my_audio").setAttribute("src", "");
+			}
+			window.onunload=releaseTack;
+		</script>
+	</body>
+</html>

+ 8390 - 0
hybrid/html/xuanfu/js/mui.js

@@ -0,0 +1,8390 @@
+/*!
+ * =====================================================
+ * Mui v3.7.3 (http://dev.dcloud.net.cn/mui)
+ * =====================================================
+ */
+/**
+ * MUI核心JS
+ * @type _L4.$|Function
+ */
+var mui = (function(document, undefined) {
+	var readyRE = /complete|loaded|interactive/;
+	var idSelectorRE = /^#([\w-]+)$/;
+	var classSelectorRE = /^\.([\w-]+)$/;
+	var tagSelectorRE = /^[\w-]+$/;
+	var translateRE = /translate(?:3d)?\((.+?)\)/;
+	var translateMatrixRE = /matrix(3d)?\((.+?)\)/;
+
+	var $ = function(selector, context) {
+		context = context || document;
+		if (!selector)
+			return wrap();
+		if (typeof selector === 'object')
+			if ($.isArrayLike(selector)) {
+				return wrap($.slice.call(selector), null);
+			} else {
+				return wrap([selector], null);
+			}
+		if (typeof selector === 'function')
+			return $.ready(selector);
+		if (typeof selector === 'string') {
+			try {
+				selector = selector.trim();
+				if (idSelectorRE.test(selector)) {
+					var found = document.getElementById(RegExp.$1);
+					return wrap(found ? [found] : []);
+				}
+				return wrap($.qsa(selector, context), selector);
+			} catch (e) {}
+		}
+		return wrap();
+	};
+
+	var wrap = function(dom, selector) {
+		dom = dom || [];
+		Object.setPrototypeOf(dom, $.fn);
+		dom.selector = selector || '';
+		return dom;
+	};
+
+	$.uuid = 0;
+
+	$.data = {};
+	/**
+	 * extend(simple)
+	 * @param {type} target
+	 * @param {type} source
+	 * @param {type} deep
+	 * @returns {unresolved}
+	 */
+	$.extend = function() { //from jquery2
+		var options, name, src, copy, copyIsArray, clone,
+			target = arguments[0] || {},
+			i = 1,
+			length = arguments.length,
+			deep = false;
+
+		if (typeof target === "boolean") {
+			deep = target;
+
+			target = arguments[i] || {};
+			i++;
+		}
+
+		if (typeof target !== "object" && !$.isFunction(target)) {
+			target = {};
+		}
+
+		if (i === length) {
+			target = this;
+			i--;
+		}
+
+		for (; i < length; i++) {
+			if ((options = arguments[i]) != null) {
+				for (name in options) {
+					src = target[name];
+					copy = options[name];
+
+					if (target === copy) {
+						continue;
+					}
+
+					if (deep && copy && ($.isPlainObject(copy) || (copyIsArray = $.isArray(copy)))) {
+						if (copyIsArray) {
+							copyIsArray = false;
+							clone = src && $.isArray(src) ? src : [];
+
+						} else {
+							clone = src && $.isPlainObject(src) ? src : {};
+						}
+
+						target[name] = $.extend(deep, clone, copy);
+
+					} else if (copy !== undefined) {
+						target[name] = copy;
+					}
+				}
+			}
+		}
+
+		return target;
+	};
+	/**
+	 * mui noop(function)
+	 */
+	$.noop = function() {};
+	/**
+	 * mui slice(array)
+	 */
+	$.slice = [].slice;
+	/**
+	 * mui filter(array)
+	 */
+	$.filter = [].filter;
+
+	$.type = function(obj) {
+		return obj == null ? String(obj) : class2type[{}.toString.call(obj)] || "object";
+	};
+	/**
+	 * mui isArray
+	 */
+	$.isArray = Array.isArray ||
+		function(object) {
+			return object instanceof Array;
+		};
+	/**
+	 * mui isArrayLike 
+	 * @param {Object} obj
+	 */
+	$.isArrayLike = function(obj) {
+		var length = !!obj && "length" in obj && obj.length;
+		var type = $.type(obj);
+		if (type === "function" || $.isWindow(obj)) {
+			return false;
+		}
+		return type === "array" || length === 0 ||
+			typeof length === "number" && length > 0 && (length - 1) in obj;
+	};
+	/**
+	 * mui isWindow(需考虑obj为undefined的情况)
+	 */
+	$.isWindow = function(obj) {
+		return obj != null && obj === obj.window;
+	};
+	/**
+	 * mui isObject
+	 */
+	$.isObject = function(obj) {
+		return $.type(obj) === "object";
+	};
+	/**
+	 * mui isPlainObject
+	 */
+	$.isPlainObject = function(obj) {
+		return $.isObject(obj) && !$.isWindow(obj) && Object.getPrototypeOf(obj) === Object.prototype;
+	};
+	/**
+	 * mui isEmptyObject
+	 * @param {Object} o
+	 */
+	$.isEmptyObject = function(o) {
+		for (var p in o) {
+			if (p !== undefined) {
+				return false;
+			}
+		}
+		return true;
+	};
+	/**
+	 * mui isFunction
+	 */
+	$.isFunction = function(value) {
+		return $.type(value) === "function";
+	};
+	/**
+	 * mui querySelectorAll
+	 * @param {type} selector
+	 * @param {type} context
+	 * @returns {Array}
+	 */
+	$.qsa = function(selector, context) {
+		context = context || document;
+		return $.slice.call(classSelectorRE.test(selector) ? context.getElementsByClassName(RegExp.$1) : tagSelectorRE.test(selector) ? context.getElementsByTagName(selector) : context.querySelectorAll(selector));
+	};
+	/**
+	 * ready(DOMContentLoaded)
+	 * @param {type} callback
+	 * @returns {_L6.$}
+	 */
+	$.ready = function(callback) {
+		if (readyRE.test(document.readyState)) {
+			callback($);
+		} else {
+			document.addEventListener('DOMContentLoaded', function() {
+				callback($);
+			}, false);
+		}
+		return this;
+	};
+	/**
+	 * 将 fn 缓存一段时间后, 再被调用执行
+	 * 此方法为了避免在 ms 段时间内, 执行 fn 多次. 常用于 resize , scroll , mousemove 等连续性事件中;
+	 * 当 ms 设置为 -1, 表示立即执行 fn, 即和直接调用 fn 一样;
+	 * 调用返回函数的 stop 停止最后一次的 buffer 效果
+	 * @param {Object} fn
+	 * @param {Object} ms
+	 * @param {Object} context
+	 */
+	$.buffer = function(fn, ms, context) {
+		var timer;
+		var lastStart = 0;
+		var lastEnd = 0;
+		var ms = ms || 150;
+
+		function run() {
+			if (timer) {
+				timer.cancel();
+				timer = 0;
+			}
+			lastStart = $.now();
+			fn.apply(context || this, arguments);
+			lastEnd = $.now();
+		}
+
+		return $.extend(function() {
+			if (
+				(!lastStart) || // 从未运行过
+				(lastEnd >= lastStart && $.now() - lastEnd > ms) || // 上次运行成功后已经超过ms毫秒
+				(lastEnd < lastStart && $.now() - lastStart > ms * 8) // 上次运行或未完成,后8*ms毫秒
+			) {
+				run.apply(this, arguments);
+			} else {
+				if (timer) {
+					timer.cancel();
+				}
+				timer = $.later(run, ms, null, $.slice.call(arguments));
+			}
+		}, {
+			stop: function() {
+				if (timer) {
+					timer.cancel();
+					timer = 0;
+				}
+			}
+		});
+	};
+	/**
+	 * each
+	 * @param {type} elements
+	 * @param {type} callback
+	 * @returns {_L8.$}
+	 */
+	$.each = function(elements, callback, hasOwnProperty) {
+		if (!elements) {
+			return this;
+		}
+		if (typeof elements.length === 'number') {
+			[].every.call(elements, function(el, idx) {
+				return callback.call(el, idx, el) !== false;
+			});
+		} else {
+			for (var key in elements) {
+				if (hasOwnProperty) {
+					if (elements.hasOwnProperty(key)) {
+						if (callback.call(elements[key], key, elements[key]) === false) return elements;
+					}
+				} else {
+					if (callback.call(elements[key], key, elements[key]) === false) return elements;
+				}
+			}
+		}
+		return this;
+	};
+	$.focus = function(element) {
+		if ($.os.ios) {
+			setTimeout(function() {
+				element.focus();
+			}, 10);
+		} else {
+			element.focus();
+		}
+	};
+	/**
+	 * trigger event
+	 * @param {type} element
+	 * @param {type} eventType
+	 * @param {type} eventData
+	 * @returns {_L8.$}
+	 */
+	$.trigger = function(element, eventType, eventData) {
+		element.dispatchEvent(new CustomEvent(eventType, {
+			detail: eventData,
+			bubbles: true,
+			cancelable: true
+		}));
+		return this;
+	};
+	/**
+	 * getStyles
+	 * @param {type} element
+	 * @param {type} property
+	 * @returns {styles}
+	 */
+	$.getStyles = function(element, property) {
+		var styles = element.ownerDocument.defaultView.getComputedStyle(element, null);
+		if (property) {
+			return styles.getPropertyValue(property) || styles[property];
+		}
+		return styles;
+	};
+	/**
+	 * parseTranslate
+	 * @param {type} translateString
+	 * @param {type} position
+	 * @returns {Object}
+	 */
+	$.parseTranslate = function(translateString, position) {
+		var result = translateString.match(translateRE || '');
+		if (!result || !result[1]) {
+			result = ['', '0,0,0'];
+		}
+		result = result[1].split(",");
+		result = {
+			x: parseFloat(result[0]),
+			y: parseFloat(result[1]),
+			z: parseFloat(result[2])
+		};
+		if (position && result.hasOwnProperty(position)) {
+			return result[position];
+		}
+		return result;
+	};
+	/**
+	 * parseTranslateMatrix
+	 * @param {type} translateString
+	 * @param {type} position
+	 * @returns {Object}
+	 */
+	$.parseTranslateMatrix = function(translateString, position) {
+		var matrix = translateString.match(translateMatrixRE);
+		var is3D = matrix && matrix[1];
+		if (matrix) {
+			matrix = matrix[2].split(",");
+			if (is3D === "3d")
+				matrix = matrix.slice(12, 15);
+			else {
+				matrix.push(0);
+				matrix = matrix.slice(4, 7);
+			}
+		} else {
+			matrix = [0, 0, 0];
+		}
+		var result = {
+			x: parseFloat(matrix[0]),
+			y: parseFloat(matrix[1]),
+			z: parseFloat(matrix[2])
+		};
+		if (position && result.hasOwnProperty(position)) {
+			return result[position];
+		}
+		return result;
+	};
+	$.hooks = {};
+	$.addAction = function(type, hook) {
+		var hooks = $.hooks[type];
+		if (!hooks) {
+			hooks = [];
+		}
+		hook.index = hook.index || 1000;
+		hooks.push(hook);
+		hooks.sort(function(a, b) {
+			return a.index - b.index;
+		});
+		$.hooks[type] = hooks;
+		return $.hooks[type];
+	};
+	$.doAction = function(type, callback) {
+		if ($.isFunction(callback)) { //指定了callback
+			$.each($.hooks[type], callback);
+		} else { //未指定callback,直接执行
+			$.each($.hooks[type], function(index, hook) {
+				return !hook.handle();
+			});
+		}
+	};
+	/**
+	 * setTimeout封装
+	 * @param {Object} fn
+	 * @param {Object} when
+	 * @param {Object} context
+	 * @param {Object} data
+	 */
+	$.later = function(fn, when, context, data) {
+		when = when || 0;
+		var m = fn;
+		var d = data;
+		var f;
+		var r;
+
+		if (typeof fn === 'string') {
+			m = context[fn];
+		}
+
+		f = function() {
+			m.apply(context, $.isArray(d) ? d : [d]);
+		};
+
+		r = setTimeout(f, when);
+
+		return {
+			id: r,
+			cancel: function() {
+				clearTimeout(r);
+			}
+		};
+	};
+	$.now = Date.now || function() {
+		return +new Date();
+	};
+	var class2type = {};
+	$.each(['Boolean', 'Number', 'String', 'Function', 'Array', 'Date', 'RegExp', 'Object', 'Error'], function(i, name) {
+		class2type["[object " + name + "]"] = name.toLowerCase();
+	});
+	if (window.JSON) {
+		$.parseJSON = JSON.parse;
+	}
+	/**
+	 * $.fn
+	 */
+	$.fn = {
+		each: function(callback) {
+			[].every.call(this, function(el, idx) {
+				return callback.call(el, idx, el) !== false;
+			});
+			return this;
+		}
+	};
+
+	/**
+	 * 兼容 AMD 模块
+	 **/
+	if (typeof define === 'function' && define.amd) {
+		define('mui', [], function() {
+			return $;
+		});
+	}
+
+	return $;
+})(document);
+//window.mui = mui;
+//'$' in window || (window.$ = mui);
+/**
+ * $.os
+ * @param {type} $
+ * @returns {undefined}
+ */
+(function($, window) {
+	function detect(ua) {
+		this.os = {};
+		var funcs = [
+
+			function() { //wechat
+				var wechat = ua.match(/(MicroMessenger)\/([\d\.]+)/i);
+				if (wechat) { //wechat
+					this.os.wechat = {
+						version: wechat[2].replace(/_/g, '.')
+					};
+				}
+				return false;
+			},
+			function() { //android
+				var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
+				if (android) {
+					this.os.android = true;
+					this.os.version = android[2];
+
+					this.os.isBadAndroid = !(/Chrome\/\d/.test(window.navigator.appVersion));
+				}
+				return this.os.android === true;
+			},
+			function() { //ios
+				var iphone = ua.match(/(iPhone\sOS)\s([\d_]+)/);
+				if (iphone) { //iphone
+					this.os.ios = this.os.iphone = true;
+					this.os.version = iphone[2].replace(/_/g, '.');
+				} else {
+					var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
+					if (ipad) { //ipad
+						this.os.ios = this.os.ipad = true;
+						this.os.version = ipad[2].replace(/_/g, '.');
+					}
+				}
+				return this.os.ios === true;
+			}
+		];
+		[].every.call(funcs, function(func) {
+			return !func.call($);
+		});
+	}
+	detect.call($, navigator.userAgent);
+})(mui, window);
+/**
+ * $.os.plus
+ * @param {type} $
+ * @returns {undefined}
+ */
+(function($, document) {
+	function detect(ua) {
+		this.os = this.os || {};
+		var plus = ua.match(/Html5Plus/i); //TODO 5\+Browser?
+		if (plus) {
+			this.os.plus = true;
+			$(function() {
+				document.body.classList.add('mui-plus');
+			});
+			if (ua.match(/StreamApp/i)) { //TODO 最好有流应用自己的标识
+				this.os.stream = true;
+				$(function() {
+					document.body.classList.add('mui-plus-stream');
+				});
+			}
+		}
+	}
+	detect.call($, navigator.userAgent);
+})(mui, document);
+/**
+ * 仅提供简单的on,off(仅支持事件委托,不支持当前元素绑定,当前元素绑定请直接使用addEventListener,removeEventListener)
+ * @param {Object} $
+ */
+(function($) {
+	if ('ontouchstart' in window) {
+		$.isTouchable = true;
+		$.EVENT_START = 'touchstart';
+		$.EVENT_MOVE = 'touchmove';
+		$.EVENT_END = 'touchend';
+	} else {
+		$.isTouchable = false;
+		$.EVENT_START = 'mousedown';
+		$.EVENT_MOVE = 'mousemove';
+		$.EVENT_END = 'mouseup';
+	}
+	$.EVENT_CANCEL = 'touchcancel';
+	$.EVENT_CLICK = 'click';
+
+	var _mid = 1;
+	var delegates = {};
+	//需要wrap的函数
+	var eventMethods = {
+		preventDefault: 'isDefaultPrevented',
+		stopImmediatePropagation: 'isImmediatePropagationStopped',
+		stopPropagation: 'isPropagationStopped'
+	};
+	//默认true返回函数
+	var returnTrue = function() {
+		return true
+	};
+	//默认false返回函数
+	var returnFalse = function() {
+		return false
+	};
+	//wrap浏览器事件
+	var compatible = function(event, target) {
+		if (!event.detail) {
+			event.detail = {
+				currentTarget: target
+			};
+		} else {
+			event.detail.currentTarget = target;
+		}
+		$.each(eventMethods, function(name, predicate) {
+			var sourceMethod = event[name];
+			event[name] = function() {
+				this[predicate] = returnTrue;
+				return sourceMethod && sourceMethod.apply(event, arguments)
+			}
+			event[predicate] = returnFalse;
+		}, true);
+		return event;
+	};
+	//简单的wrap对象_mid
+	var mid = function(obj) {
+		return obj && (obj._mid || (obj._mid = _mid++));
+	};
+	//事件委托对象绑定的事件回调列表
+	var delegateFns = {};
+	//返回事件委托的wrap事件回调
+	var delegateFn = function(element, event, selector, callback) {
+		return function(e) {
+			//same event
+			var callbackObjs = delegates[element._mid][event];
+			var handlerQueue = [];
+			var target = e.target;
+			var selectorAlls = {};
+			for (; target && target !== document; target = target.parentNode) {
+				if (target === element) {
+					break;
+				}
+				if (~['click', 'tap', 'doubletap', 'longtap', 'hold'].indexOf(event) && (target.disabled || target.classList.contains('mui-disabled'))) {
+					break;
+				}
+				var matches = {};
+				$.each(callbackObjs, function(selector, callbacks) { //same selector
+					selectorAlls[selector] || (selectorAlls[selector] = $.qsa(selector, element));
+					if (selectorAlls[selector] && ~(selectorAlls[selector]).indexOf(target)) {
+						if (!matches[selector]) {
+							matches[selector] = callbacks;
+						}
+					}
+				}, true);
+				if (!$.isEmptyObject(matches)) {
+					handlerQueue.push({
+						element: target,
+						handlers: matches
+					});
+				}
+			}
+			selectorAlls = null;
+			e = compatible(e); //compatible event
+			$.each(handlerQueue, function(index, handler) {
+				target = handler.element;
+				var tagName = target.tagName;
+				if (event === 'tap' && (tagName !== 'INPUT' && tagName !== 'TEXTAREA' && tagName !== 'SELECT')) {
+					e.preventDefault();
+					e.detail && e.detail.gesture && e.detail.gesture.preventDefault();
+				}
+				$.each(handler.handlers, function(index, handler) {
+					$.each(handler, function(index, callback) {
+						if (callback.call(target, e) === false) {
+							e.preventDefault();
+							e.stopPropagation();
+						}
+					}, true);
+				}, true)
+				if (e.isPropagationStopped()) {
+					return false;
+				}
+			}, true);
+		};
+	};
+	var findDelegateFn = function(element, event) {
+		var delegateCallbacks = delegateFns[mid(element)];
+		var result = [];
+		if (delegateCallbacks) {
+			result = [];
+			if (event) {
+				var filterFn = function(fn) {
+					return fn.type === event;
+				}
+				return delegateCallbacks.filter(filterFn);
+			} else {
+				result = delegateCallbacks;
+			}
+		}
+		return result;
+	};
+	var preventDefaultException = /^(INPUT|TEXTAREA|BUTTON|SELECT)$/;
+	/**
+	 * mui delegate events
+	 * @param {type} event
+	 * @param {type} selector
+	 * @param {type} callback
+	 * @returns {undefined}
+	 */
+	$.fn.on = function(event, selector, callback) { //仅支持简单的事件委托,主要是tap事件使用,类似mouse,focus之类暂不封装支持
+		return this.each(function() {
+			var element = this;
+			mid(element);
+			mid(callback);
+			var isAddEventListener = false;
+			var delegateEvents = delegates[element._mid] || (delegates[element._mid] = {});
+			var delegateCallbackObjs = delegateEvents[event] || ((delegateEvents[event] = {}));
+			if ($.isEmptyObject(delegateCallbackObjs)) {
+				isAddEventListener = true;
+			}
+			var delegateCallbacks = delegateCallbackObjs[selector] || (delegateCallbackObjs[selector] = []);
+			delegateCallbacks.push(callback);
+			if (isAddEventListener) {
+				var delegateFnArray = delegateFns[mid(element)];
+				if (!delegateFnArray) {
+					delegateFnArray = [];
+				}
+				var delegateCallback = delegateFn(element, event, selector, callback);
+				delegateFnArray.push(delegateCallback);
+				delegateCallback.i = delegateFnArray.length - 1;
+				delegateCallback.type = event;
+				delegateFns[mid(element)] = delegateFnArray;
+				element.addEventListener(event, delegateCallback);
+				if (event === 'tap') { //TODO 需要找个更好的解决方案
+					element.addEventListener('click', function(e) {
+						if (e.target) {
+							var tagName = e.target.tagName;
+							if (!preventDefaultException.test(tagName)) {
+								if (tagName === 'A') {
+									var href = e.target.href;
+									if (!(href && ~href.indexOf('tel:'))) {
+										e.preventDefault();
+									}
+								} else {
+									e.preventDefault();
+								}
+							}
+						}
+					});
+				}
+			}
+		});
+	};
+	$.fn.off = function(event, selector, callback) {
+		return this.each(function() {
+			var _mid = mid(this);
+			if (!event) { //mui(selector).off();
+				delegates[_mid] && delete delegates[_mid];
+			} else if (!selector) { //mui(selector).off(event);
+				delegates[_mid] && delete delegates[_mid][event];
+			} else if (!callback) { //mui(selector).off(event,selector);
+				delegates[_mid] && delegates[_mid][event] && delete delegates[_mid][event][selector];
+			} else { //mui(selector).off(event,selector,callback);
+				var delegateCallbacks = delegates[_mid] && delegates[_mid][event] && delegates[_mid][event][selector];
+				$.each(delegateCallbacks, function(index, delegateCallback) {
+					if (mid(delegateCallback) === mid(callback)) {
+						delegateCallbacks.splice(index, 1);
+						return false;
+					}
+				}, true);
+			}
+			if (delegates[_mid]) {
+				//如果off掉了所有当前element的指定的event事件,则remove掉当前element的delegate回调
+				if ((!delegates[_mid][event] || $.isEmptyObject(delegates[_mid][event]))) {
+					findDelegateFn(this, event).forEach(function(fn) {
+						this.removeEventListener(fn.type, fn);
+						delete delegateFns[_mid][fn.i];
+					}.bind(this));
+				}
+			} else {
+				//如果delegates[_mid]已不存在,删除所有
+				findDelegateFn(this).forEach(function(fn) {
+					this.removeEventListener(fn.type, fn);
+					delete delegateFns[_mid][fn.i];
+				}.bind(this));
+			}
+		});
+
+	};
+})(mui);
+/**
+ * mui target(action>popover>modal>tab>toggle)
+ */
+(function($, window, document) {
+	/**
+	 * targets
+	 */
+	$.targets = {};
+	/**
+	 * target handles
+	 */
+	$.targetHandles = [];
+	/**
+	 * register target
+	 * @param {type} target
+	 * @returns {$.targets}
+	 */
+	$.registerTarget = function(target) {
+
+		target.index = target.index || 1000;
+
+		$.targetHandles.push(target);
+
+		$.targetHandles.sort(function(a, b) {
+			return a.index - b.index;
+		});
+
+		return $.targetHandles;
+	};
+	window.addEventListener($.EVENT_START, function(event) {
+		var target = event.target;
+		var founds = {};
+		for (; target && target !== document; target = target.parentNode) {
+			var isFound = false;
+			$.each($.targetHandles, function(index, targetHandle) {
+				var name = targetHandle.name;
+				if (!isFound && !founds[name] && targetHandle.hasOwnProperty('handle')) {
+					$.targets[name] = targetHandle.handle(event, target);
+					if ($.targets[name]) {
+						founds[name] = true;
+						if (targetHandle.isContinue !== true) {
+							isFound = true;
+						}
+					}
+				} else {
+					if (!founds[name]) {
+						if (targetHandle.isReset !== false)
+							$.targets[name] = false;
+					}
+				}
+			});
+			if (isFound) {
+				break;
+			}
+		}
+	});
+	window.addEventListener('click', function(event) { //解决touch与click的target不一致的问题(比如链接边缘点击时,touch的target为html,而click的target为A)
+		var target = event.target;
+		var isFound = false;
+		for (; target && target !== document; target = target.parentNode) {
+			if (target.tagName === 'A') {
+				$.each($.targetHandles, function(index, targetHandle) {
+					var name = targetHandle.name;
+					if (targetHandle.hasOwnProperty('handle')) {
+						if (targetHandle.handle(event, target)) {
+							isFound = true;
+							event.preventDefault();
+							return false;
+						}
+					}
+				});
+				if (isFound) {
+					break;
+				}
+			}
+		}
+	});
+})(mui, window, document);
+/**
+ * fixed trim
+ * @param {type} undefined
+ * @returns {undefined}
+ */
+(function(undefined) {
+	if (String.prototype.trim === undefined) { // fix for iOS 3.2
+		String.prototype.trim = function() {
+			return this.replace(/^\s+|\s+$/g, '');
+		};
+	}
+	Object.setPrototypeOf = Object.setPrototypeOf || function(obj, proto) {
+		obj['__proto__'] = proto;
+		return obj;
+	};
+
+})();
+/**
+ * fixed CustomEvent
+ */
+(function() {
+	if (typeof window.CustomEvent === 'undefined') {
+		function CustomEvent(event, params) {
+			params = params || {
+				bubbles: false,
+				cancelable: false,
+				detail: undefined
+			};
+			var evt = document.createEvent('Events');
+			var bubbles = true;
+			for (var name in params) {
+				(name === 'bubbles') ? (bubbles = !!params[name]) : (evt[name] = params[name]);
+			}
+			evt.initEvent(event, bubbles, true);
+			return evt;
+		};
+		CustomEvent.prototype = window.Event.prototype;
+		window.CustomEvent = CustomEvent;
+	}
+})();
+/*
+	A shim for non ES5 supporting browsers.
+	Adds function bind to Function prototype, so that you can do partial application.
+	Works even with the nasty thing, where the first word is the opposite of extranet, the second one is the profession of Columbus, and the version number is 9, flipped 180 degrees.
+*/
+
+Function.prototype.bind = Function.prototype.bind || function(to) {
+	// Make an array of our arguments, starting from second argument
+	var partial = Array.prototype.splice.call(arguments, 1),
+		// We'll need the original function.
+		fn = this;
+	var bound = function() {
+			// Join the already applied arguments to the now called ones (after converting to an array again).
+			var args = partial.concat(Array.prototype.splice.call(arguments, 0));
+			// If not being called as a constructor
+			if (!(this instanceof bound)) {
+				// return the result of the function called bound to target and partially applied.
+				return fn.apply(to, args);
+			}
+			// If being called as a constructor, apply the function bound to self.
+			fn.apply(this, args);
+		}
+		// Attach the prototype of the function to our newly created function.
+	bound.prototype = fn.prototype;
+	return bound;
+};
+/**
+ * mui fixed classList
+ * @param {type} document
+ * @returns {undefined}
+ */
+(function(document) {
+    if (!("classList" in document.documentElement) && Object.defineProperty && typeof HTMLElement !== 'undefined') {
+
+        Object.defineProperty(HTMLElement.prototype, 'classList', {
+            get: function() {
+                var self = this;
+                function update(fn) {
+                    return function(value) {
+                        var classes = self.className.split(/\s+/),
+                                index = classes.indexOf(value);
+
+                        fn(classes, index, value);
+                        self.className = classes.join(" ");
+                    };
+                }
+
+                var ret = {
+                    add: update(function(classes, index, value) {
+                        ~index || classes.push(value);
+                    }),
+                    remove: update(function(classes, index) {
+                        ~index && classes.splice(index, 1);
+                    }),
+                    toggle: update(function(classes, index, value) {
+                        ~index ? classes.splice(index, 1) : classes.push(value);
+                    }),
+                    contains: function(value) {
+                        return !!~self.className.split(/\s+/).indexOf(value);
+                    },
+                    item: function(i) {
+                        return self.className.split(/\s+/)[i] || null;
+                    }
+                };
+
+                Object.defineProperty(ret, 'length', {
+                    get: function() {
+                        return self.className.split(/\s+/).length;
+                    }
+                });
+
+                return ret;
+            }
+        });
+    }
+})(document);
+
+/**
+ * mui fixed requestAnimationFrame
+ * @param {type} window
+ * @returns {undefined}
+ */
+(function(window) {
+	if (!window.requestAnimationFrame) {
+		var lastTime = 0;
+		window.requestAnimationFrame = window.webkitRequestAnimationFrame || function(callback, element) {
+			var currTime = new Date().getTime();
+			var timeToCall = Math.max(0, 16.7 - (currTime - lastTime));
+			var id = window.setTimeout(function() {
+				callback(currTime + timeToCall);
+			}, timeToCall);
+			lastTime = currTime + timeToCall;
+			return id;
+		};
+		window.cancelAnimationFrame = window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame || function(id) {
+			clearTimeout(id);
+		};
+	};
+}(window));
+/**
+ * fastclick(only for radio,checkbox)
+ */
+(function($, window, name) {
+	if (!$.os.android && !$.os.ios) { //目前仅识别android和ios
+		return;
+	}
+	if (window.FastClick) {
+		return;
+	}
+
+	var handle = function(event, target) {
+		if (target.tagName === 'LABEL') {
+			if (target.parentNode) {
+				target = target.parentNode.querySelector('input');
+			}
+		}
+		if (target && (target.type === 'radio' || target.type === 'checkbox')) {
+			if (!target.disabled) { //disabled
+				return target;
+			}
+		}
+		return false;
+	};
+
+	$.registerTarget({
+		name: name,
+		index: 40,
+		handle: handle,
+		target: false
+	});
+	var dispatchEvent = function(event) {
+		var targetElement = $.targets.click;
+		if (targetElement) {
+			var clickEvent, touch;
+			// On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect
+			if (document.activeElement && document.activeElement !== targetElement) {
+				document.activeElement.blur();
+			}
+			touch = event.detail.gesture.changedTouches[0];
+			// Synthesise a click event, with an extra attribute so it can be tracked
+			clickEvent = document.createEvent('MouseEvents');
+			clickEvent.initMouseEvent('click', true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
+			clickEvent.forwardedTouchEvent = true;
+			targetElement.dispatchEvent(clickEvent);
+			event.detail && event.detail.gesture.preventDefault();
+		}
+	};
+	window.addEventListener('tap', dispatchEvent);
+	window.addEventListener('doubletap', dispatchEvent);
+	//捕获
+	window.addEventListener('click', function(event) {
+		if ($.targets.click) {
+			if (!event.forwardedTouchEvent) { //stop click
+				if (event.stopImmediatePropagation) {
+					event.stopImmediatePropagation();
+				} else {
+					// Part of the hack for browsers that don't support Event#stopImmediatePropagation
+					event.propagationStopped = true;
+				}
+				event.stopPropagation();
+				event.preventDefault();
+				return false;
+			}
+		}
+	}, true);
+
+})(mui, window, 'click');
+(function($, document) {
+	$(function() {
+		if (!$.os.ios) {
+			return;
+		}
+		var CLASS_FOCUSIN = 'mui-focusin';
+		var CLASS_BAR_TAB = 'mui-bar-tab';
+		var CLASS_BAR_FOOTER = 'mui-bar-footer';
+		var CLASS_BAR_FOOTER_SECONDARY = 'mui-bar-footer-secondary';
+		var CLASS_BAR_FOOTER_SECONDARY_TAB = 'mui-bar-footer-secondary-tab';
+		// var content = document.querySelector('.' + CLASS_CONTENT);
+		// if (content) {
+		// 	document.body.insertBefore(content, document.body.firstElementChild);
+		// }
+		document.addEventListener('focusin', function(e) {
+			if ($.os.plus) { //在父webview里边不fix
+				if (window.plus) {
+					if (plus.webview.currentWebview().children().length > 0) {
+						return;
+					}
+				}
+			}
+			var target = e.target;
+			//TODO 需考虑所有键盘弹起的情况
+			if (target.tagName && (target.tagName === 'TEXTAREA' || (target.tagName === 'INPUT' && (target.type === 'text' || target.type === 'search' || target.type === 'number')))) {
+				if (target.disabled || target.readOnly) {
+					return;
+				}
+				document.body.classList.add(CLASS_FOCUSIN);
+				var isFooter = false;
+				for (; target && target !== document; target = target.parentNode) {
+					var classList = target.classList;
+					if (classList && classList.contains(CLASS_BAR_TAB) || classList.contains(CLASS_BAR_FOOTER) || classList.contains(CLASS_BAR_FOOTER_SECONDARY) || classList.contains(CLASS_BAR_FOOTER_SECONDARY_TAB)) {
+						isFooter = true;
+						break;
+					}
+				}
+				if (isFooter) {
+					var scrollTop = document.body.scrollHeight;
+					var scrollLeft = document.body.scrollLeft;
+					setTimeout(function() {
+						window.scrollTo(scrollLeft, scrollTop);
+					}, 20);
+				}
+			}
+		});
+		document.addEventListener('focusout', function(e) {
+			var classList = document.body.classList;
+			if (classList.contains(CLASS_FOCUSIN)) {
+				classList.remove(CLASS_FOCUSIN);
+				setTimeout(function() {
+					window.scrollTo(document.body.scrollLeft, document.body.scrollTop);
+				}, 20);
+			}
+		});
+	});
+})(mui, document);
+/**
+ * mui namespace(optimization)
+ * @param {type} $
+ * @returns {undefined}
+ */
+(function($) {
+	$.namespace = 'mui';
+	$.classNamePrefix = $.namespace + '-';
+	$.classSelectorPrefix = '.' + $.classNamePrefix;
+	/**
+	 * 返回正确的className
+	 * @param {type} className
+	 * @returns {String}
+	 */
+	$.className = function(className) {
+		return $.classNamePrefix + className;
+	};
+	/**
+	 * 返回正确的classSelector
+	 * @param {type} classSelector
+	 * @returns {String}
+	 */
+	$.classSelector = function(classSelector) {
+		return classSelector.replace(/\./g, $.classSelectorPrefix);
+	};
+	/**
+         * 返回正确的eventName
+         * @param {type} event
+         * @param {type} module
+         * @returns {String}
+         */
+	$.eventName = function(event, module) {
+		return event + ($.namespace ? ('.' + $.namespace) : '') + ( module ? ('.' + module) : '');
+	};
+})(mui);
+
+/**
+ * mui gestures
+ * @param {type} $
+ * @param {type} window
+ * @returns {undefined}
+ */
+(function($, window) {
+	$.gestures = {
+		session: {}
+	};
+	/**
+	 * Gesture preventDefault
+	 * @param {type} e
+	 * @returns {undefined}
+	 */
+	$.preventDefault = function(e) {
+		e.preventDefault();
+	};
+	/**
+	 * Gesture stopPropagation
+	 * @param {type} e
+	 * @returns {undefined}
+	 */
+	$.stopPropagation = function(e) {
+		e.stopPropagation();
+	};
+
+	/**
+	 * register gesture
+	 * @param {type} gesture
+	 * @returns {$.gestures}
+	 */
+	$.addGesture = function(gesture) {
+		return $.addAction('gestures', gesture);
+
+	};
+
+	var round = Math.round;
+	var abs = Math.abs;
+	var sqrt = Math.sqrt;
+	var atan = Math.atan;
+	var atan2 = Math.atan2;
+	/**
+	 * distance
+	 * @param {type} p1
+	 * @param {type} p2
+	 * @returns {Number}
+	 */
+	var getDistance = function(p1, p2, props) {
+		if(!props) {
+			props = ['x', 'y'];
+		}
+		var x = p2[props[0]] - p1[props[0]];
+		var y = p2[props[1]] - p1[props[1]];
+		return sqrt((x * x) + (y * y));
+	};
+	/**
+	 * scale
+	 * @param {Object} starts
+	 * @param {Object} moves
+	 */
+	var getScale = function(starts, moves) {
+		if(starts.length >= 2 && moves.length >= 2) {
+			var props = ['pageX', 'pageY'];
+			return getDistance(moves[1], moves[0], props) / getDistance(starts[1], starts[0], props);
+		}
+		return 1;
+	};
+	/**
+	 * angle
+	 * @param {type} p1
+	 * @param {type} p2
+	 * @returns {Number}
+	 */
+	var getAngle = function(p1, p2, props) {
+		if(!props) {
+			props = ['x', 'y'];
+		}
+		var x = p2[props[0]] - p1[props[0]];
+		var y = p2[props[1]] - p1[props[1]];
+		return atan2(y, x) * 180 / Math.PI;
+	};
+	/**
+	 * direction
+	 * @param {Object} x
+	 * @param {Object} y
+	 */
+	var getDirection = function(x, y) {
+		if(x === y) {
+			return '';
+		}
+		if(abs(x) >= abs(y)) {
+			return x > 0 ? 'left' : 'right';
+		}
+		return y > 0 ? 'up' : 'down';
+	};
+	/**
+	 * rotation
+	 * @param {Object} start
+	 * @param {Object} end
+	 */
+	var getRotation = function(start, end) {
+		var props = ['pageX', 'pageY'];
+		return getAngle(end[1], end[0], props) - getAngle(start[1], start[0], props);
+	};
+	/**
+	 * px per ms
+	 * @param {Object} deltaTime
+	 * @param {Object} x
+	 * @param {Object} y
+	 */
+	var getVelocity = function(deltaTime, x, y) {
+		return {
+			x: x / deltaTime || 0,
+			y: y / deltaTime || 0
+		};
+	};
+	/**
+	 * detect gestures
+	 * @param {type} event
+	 * @param {type} touch
+	 * @returns {undefined}
+	 */
+	var detect = function(event, touch) {
+		if($.gestures.stoped) {
+			return;
+		}
+		$.doAction('gestures', function(index, gesture) {
+			if(!$.gestures.stoped) {
+				if($.options.gestureConfig[gesture.name] !== false) {
+					gesture.handle(event, touch);
+				}
+			}
+		});
+	};
+	/**
+	 * 暂时无用
+	 * @param {Object} node
+	 * @param {Object} parent
+	 */
+	var hasParent = function(node, parent) {
+		while(node) {
+			if(node == parent) {
+				return true;
+			}
+			node = node.parentNode;
+		}
+		return false;
+	};
+
+	var uniqueArray = function(src, key, sort) {
+		var results = [];
+		var values = [];
+		var i = 0;
+
+		while(i < src.length) {
+			var val = key ? src[i][key] : src[i];
+			if(values.indexOf(val) < 0) {
+				results.push(src[i]);
+			}
+			values[i] = val;
+			i++;
+		}
+
+		if(sort) {
+			if(!key) {
+				results = results.sort();
+			} else {
+				results = results.sort(function sortUniqueArray(a, b) {
+					return a[key] > b[key];
+				});
+			}
+		}
+
+		return results;
+	};
+	var getMultiCenter = function(touches) {
+		var touchesLength = touches.length;
+		if(touchesLength === 1) {
+			return {
+				x: round(touches[0].pageX),
+				y: round(touches[0].pageY)
+			};
+		}
+
+		var x = 0;
+		var y = 0;
+		var i = 0;
+		while(i < touchesLength) {
+			x += touches[i].pageX;
+			y += touches[i].pageY;
+			i++;
+		}
+
+		return {
+			x: round(x / touchesLength),
+			y: round(y / touchesLength)
+		};
+	};
+	var multiTouch = function() {
+		return $.options.gestureConfig.pinch;
+	};
+	var copySimpleTouchData = function(touch) {
+		var touches = [];
+		var i = 0;
+		while(i < touch.touches.length) {
+			touches[i] = {
+				pageX: round(touch.touches[i].pageX),
+				pageY: round(touch.touches[i].pageY)
+			};
+			i++;
+		}
+		return {
+			timestamp: $.now(),
+			gesture: touch.gesture,
+			touches: touches,
+			center: getMultiCenter(touch.touches),
+			deltaX: touch.deltaX,
+			deltaY: touch.deltaY
+		};
+	};
+
+	var calDelta = function(touch) {
+		var session = $.gestures.session;
+		var center = touch.center;
+		var offset = session.offsetDelta || {};
+		var prevDelta = session.prevDelta || {};
+		var prevTouch = session.prevTouch || {};
+
+		if(touch.gesture.type === $.EVENT_START || touch.gesture.type === $.EVENT_END) {
+			prevDelta = session.prevDelta = {
+				x: prevTouch.deltaX || 0,
+				y: prevTouch.deltaY || 0
+			};
+
+			offset = session.offsetDelta = {
+				x: center.x,
+				y: center.y
+			};
+		}
+		touch.deltaX = prevDelta.x + (center.x - offset.x);
+		touch.deltaY = prevDelta.y + (center.y - offset.y);
+	};
+	var calTouchData = function(touch) {
+		var session = $.gestures.session;
+		var touches = touch.touches;
+		var touchesLength = touches.length;
+
+		if(!session.firstTouch) {
+			session.firstTouch = copySimpleTouchData(touch);
+		}
+
+		if(multiTouch() && touchesLength > 1 && !session.firstMultiTouch) {
+			session.firstMultiTouch = copySimpleTouchData(touch);
+		} else if(touchesLength === 1) {
+			session.firstMultiTouch = false;
+		}
+
+		var firstTouch = session.firstTouch;
+		var firstMultiTouch = session.firstMultiTouch;
+		var offsetCenter = firstMultiTouch ? firstMultiTouch.center : firstTouch.center;
+
+		var center = touch.center = getMultiCenter(touches);
+		touch.timestamp = $.now();
+		touch.deltaTime = touch.timestamp - firstTouch.timestamp;
+
+		touch.angle = getAngle(offsetCenter, center);
+		touch.distance = getDistance(offsetCenter, center);
+
+		calDelta(touch);
+
+		touch.offsetDirection = getDirection(touch.deltaX, touch.deltaY);
+
+		touch.scale = firstMultiTouch ? getScale(firstMultiTouch.touches, touches) : 1;
+		touch.rotation = firstMultiTouch ? getRotation(firstMultiTouch.touches, touches) : 0;
+
+		calIntervalTouchData(touch);
+
+	};
+	var CAL_INTERVAL = 25;
+	var calIntervalTouchData = function(touch) {
+		var session = $.gestures.session;
+		var last = session.lastInterval || touch;
+		var deltaTime = touch.timestamp - last.timestamp;
+		var velocity;
+		var velocityX;
+		var velocityY;
+		var direction;
+
+		if(touch.gesture.type != $.EVENT_CANCEL && (deltaTime > CAL_INTERVAL || last.velocity === undefined)) {
+			var deltaX = last.deltaX - touch.deltaX;
+			var deltaY = last.deltaY - touch.deltaY;
+
+			var v = getVelocity(deltaTime, deltaX, deltaY);
+			velocityX = v.x;
+			velocityY = v.y;
+			velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y;
+			direction = getDirection(deltaX, deltaY) || last.direction;
+
+			session.lastInterval = touch;
+		} else {
+			velocity = last.velocity;
+			velocityX = last.velocityX;
+			velocityY = last.velocityY;
+			direction = last.direction;
+		}
+
+		touch.velocity = velocity;
+		touch.velocityX = velocityX;
+		touch.velocityY = velocityY;
+		touch.direction = direction;
+	};
+	var targetIds = {};
+	var convertTouches = function(touches) {
+		for(var i = 0; i < touches.length; i++) {
+			!touches['identifier'] && (touches['identifier'] = 0);
+		}
+		return touches;
+	};
+	var getTouches = function(event, touch) {
+		var allTouches = convertTouches($.slice.call(event.touches || [event]));
+
+		var type = event.type;
+
+		var targetTouches = [];
+		var changedTargetTouches = [];
+
+		//当touchstart或touchmove且touches长度为1,直接获得all和changed
+		if((type === $.EVENT_START || type === $.EVENT_MOVE) && allTouches.length === 1) {
+			targetIds[allTouches[0].identifier] = true;
+			targetTouches = allTouches;
+			changedTargetTouches = allTouches;
+			touch.target = event.target;
+		} else {
+			var i = 0;
+			var targetTouches = [];
+			var changedTargetTouches = [];
+			var changedTouches = convertTouches($.slice.call(event.changedTouches || [event]));
+
+			touch.target = event.target;
+			var sessionTarget = $.gestures.session.target || event.target;
+			targetTouches = allTouches.filter(function(touch) {
+				return hasParent(touch.target, sessionTarget);
+			});
+
+			if(type === $.EVENT_START) {
+				i = 0;
+				while(i < targetTouches.length) {
+					targetIds[targetTouches[i].identifier] = true;
+					i++;
+				}
+			}
+
+			i = 0;
+			while(i < changedTouches.length) {
+				if(targetIds[changedTouches[i].identifier]) {
+					changedTargetTouches.push(changedTouches[i]);
+				}
+				if(type === $.EVENT_END || type === $.EVENT_CANCEL) {
+					delete targetIds[changedTouches[i].identifier];
+				}
+				i++;
+			}
+
+			if(!changedTargetTouches.length) {
+				return false;
+			}
+		}
+		targetTouches = uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true);
+		var touchesLength = targetTouches.length;
+		var changedTouchesLength = changedTargetTouches.length;
+		if(type === $.EVENT_START && touchesLength - changedTouchesLength === 0) { //first
+			touch.isFirst = true;
+			$.gestures.touch = $.gestures.session = {
+				target: event.target
+			};
+		}
+		touch.isFinal = ((type === $.EVENT_END || type === $.EVENT_CANCEL) && (touchesLength - changedTouchesLength === 0));
+
+		touch.touches = targetTouches;
+		touch.changedTouches = changedTargetTouches;
+		return true;
+
+	};
+	var handleTouchEvent = function(event) {
+		var touch = {
+			gesture: event
+		};
+		var touches = getTouches(event, touch);
+		if(!touches) {
+			return;
+		}
+		calTouchData(touch);
+		detect(event, touch);
+		$.gestures.session.prevTouch = touch;
+		if(event.type === $.EVENT_END && !$.isTouchable) {
+			$.gestures.touch = $.gestures.session = {};
+		}
+	};
+	var supportsPassive = (function checkPassiveListener() {
+		var supportsPassive = false;
+		try {
+			var opts = Object.defineProperty({}, 'passive', {
+				get: function get() {
+					supportsPassive = true;
+				},
+			});
+			window.addEventListener('testPassiveListener', null, opts);
+		} catch(e) {
+			// No support
+		}
+		return supportsPassive;
+	}())
+	window.addEventListener($.EVENT_START, handleTouchEvent);
+	window.addEventListener($.EVENT_MOVE, handleTouchEvent, supportsPassive ? {
+		passive: false,
+		capture: false
+	} : false);
+	window.addEventListener($.EVENT_END, handleTouchEvent);
+	window.addEventListener($.EVENT_CANCEL, handleTouchEvent);
+	//fixed hashchange(android)
+	window.addEventListener($.EVENT_CLICK, function(e) {
+		//TODO 应该判断当前target是不是在targets.popover内部,而不是非要相等
+		if(($.os.android || $.os.ios) && (($.targets.popover && e.target === $.targets.popover) || ($.targets.tab) || $.targets.offcanvas || $.targets.modal)) {
+			e.preventDefault();
+		}
+	}, true);
+
+	//增加原生滚动识别
+	$.isScrolling = false;
+	var scrollingTimeout = null;
+	window.addEventListener('scroll', function() {
+		$.isScrolling = true;
+		scrollingTimeout && clearTimeout(scrollingTimeout);
+		scrollingTimeout = setTimeout(function() {
+			$.isScrolling = false;
+		}, 250);
+	});
+})(mui, window);
+/**
+ * mui gesture flick[left|right|up|down]
+ * @param {type} $
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, name) {
+	var flickStartTime = 0;
+	var handle = function(event, touch) {
+		var session = $.gestures.session;
+		var options = this.options;
+		var now = $.now();
+		switch (event.type) {
+			case $.EVENT_MOVE:
+				if (now - flickStartTime > 300) {
+					flickStartTime = now;
+					session.flickStart = touch.center;
+				}
+				break;
+			case $.EVENT_END:
+			case $.EVENT_CANCEL:
+				touch.flick = false;
+				if (session.flickStart && options.flickMaxTime > (now - flickStartTime) && touch.distance > options.flickMinDistince) {
+					touch.flick = true;
+					touch.flickTime = now - flickStartTime;
+					touch.flickDistanceX = touch.center.x - session.flickStart.x;
+					touch.flickDistanceY = touch.center.y - session.flickStart.y;
+					$.trigger(session.target, name, touch);
+					$.trigger(session.target, name + touch.direction, touch);
+				}
+				break;
+		}
+
+	};
+	/**
+	 * mui gesture flick
+	 */
+	$.addGesture({
+		name: name,
+		index: 5,
+		handle: handle,
+		options: {
+			flickMaxTime: 200,
+			flickMinDistince: 10
+		}
+	});
+})(mui, 'flick');
+/**
+ * mui gesture swipe[left|right|up|down]
+ * @param {type} $
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, name) {
+	var handle = function(event, touch) {
+		var session = $.gestures.session;
+		if (event.type === $.EVENT_END || event.type === $.EVENT_CANCEL) {
+			var options = this.options;
+			touch.swipe = false;
+			//TODO 后续根据velocity计算
+			if (touch.direction && options.swipeMaxTime > touch.deltaTime && touch.distance > options.swipeMinDistince) {
+				touch.swipe = true;
+				$.trigger(session.target, name, touch);
+				$.trigger(session.target, name + touch.direction, touch);
+			}
+		}
+	};
+	/**
+	 * mui gesture swipe
+	 */
+	$.addGesture({
+		name: name,
+		index: 10,
+		handle: handle,
+		options: {
+			swipeMaxTime: 300,
+			swipeMinDistince: 18
+		}
+	});
+})(mui, 'swipe');
+/**
+ * mui gesture drag[start|left|right|up|down|end]
+ * @param {type} $
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, name) {
+	var handle = function(event, touch) {
+		var session = $.gestures.session;
+		switch (event.type) {
+			case $.EVENT_START:
+				break;
+			case $.EVENT_MOVE:
+				if (!touch.direction || !session.target) {
+					return;
+				}
+				//修正direction,可在session期间自行锁定拖拽方向,方便开发scroll类不同方向拖拽插件嵌套
+				if (session.lockDirection && session.startDirection) {
+					if (session.startDirection && session.startDirection !== touch.direction) {
+						if (session.startDirection === 'up' || session.startDirection === 'down') {
+							touch.direction = touch.deltaY < 0 ? 'up' : 'down';
+						} else {
+							touch.direction = touch.deltaX < 0 ? 'left' : 'right';
+						}
+					}
+				}
+
+				if (!session.drag) {
+					session.drag = true;
+					$.trigger(session.target, name + 'start', touch);
+				}
+				$.trigger(session.target, name, touch);
+				$.trigger(session.target, name + touch.direction, touch);
+				break;
+			case $.EVENT_END:
+			case $.EVENT_CANCEL:
+				if (session.drag && touch.isFinal) {
+					$.trigger(session.target, name + 'end', touch);
+				}
+				break;
+		}
+	};
+	/**
+	 * mui gesture drag
+	 */
+	$.addGesture({
+		name: name,
+		index: 20,
+		handle: handle,
+		options: {
+			fingers: 1
+		}
+	});
+})(mui, 'drag');
+/**
+ * mui gesture tap and doubleTap
+ * @param {type} $
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, name) {
+	var lastTarget;
+	var lastTapTime;
+	var handle = function(event, touch) {
+		var session = $.gestures.session;
+		var options = this.options;
+		switch (event.type) {
+			case $.EVENT_END:
+				if (!touch.isFinal) {
+					return;
+				}
+				var target = session.target;
+				if (!target || (target.disabled || (target.classList && target.classList.contains('mui-disabled')))) {
+					return;
+				}
+				if (touch.distance < options.tapMaxDistance && touch.deltaTime < options.tapMaxTime) {
+					if ($.options.gestureConfig.doubletap && lastTarget && (lastTarget === target)) { //same target
+						if (lastTapTime && (touch.timestamp - lastTapTime) < options.tapMaxInterval) {
+							$.trigger(target, 'doubletap', touch);
+							lastTapTime = $.now();
+							lastTarget = target;
+							return;
+						}
+					}
+					$.trigger(target, name, touch);
+					lastTapTime = $.now();
+					lastTarget = target;
+				}
+				break;
+		}
+	};
+	/**
+	 * mui gesture tap
+	 */
+	$.addGesture({
+		name: name,
+		index: 30,
+		handle: handle,
+		options: {
+			fingers: 1,
+			tapMaxInterval: 300,
+			tapMaxDistance: 5,
+			tapMaxTime: 250
+		}
+	});
+})(mui, 'tap');
+/**
+ * mui gesture longtap
+ * @param {type} $
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, name) {
+	var timer;
+	var handle = function(event, touch) {
+		var session = $.gestures.session;
+		var options = this.options;
+		switch (event.type) {
+			case $.EVENT_START:
+				clearTimeout(timer);
+				timer = setTimeout(function() {
+					$.trigger(session.target, name, touch);
+				}, options.holdTimeout);
+				break;
+			case $.EVENT_MOVE:
+				if (touch.distance > options.holdThreshold) {
+					clearTimeout(timer);
+				}
+				break;
+			case $.EVENT_END:
+			case $.EVENT_CANCEL:
+				clearTimeout(timer);
+				break;
+		}
+	};
+	/**
+	 * mui gesture longtap
+	 */
+	$.addGesture({
+		name: name,
+		index: 10,
+		handle: handle,
+		options: {
+			fingers: 1,
+			holdTimeout: 500,
+			holdThreshold: 2
+		}
+	});
+})(mui, 'longtap');
+/**
+ * mui gesture hold
+ * @param {type} $
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, name) {
+	var timer;
+	var handle = function(event, touch) {
+		var session = $.gestures.session;
+		var options = this.options;
+		switch (event.type) {
+			case $.EVENT_START:
+				if ($.options.gestureConfig.hold) {
+					timer && clearTimeout(timer);
+					timer = setTimeout(function() {
+						touch.hold = true;
+						$.trigger(session.target, name, touch);
+					}, options.holdTimeout);
+				}
+				break;
+			case $.EVENT_MOVE:
+				break;
+			case $.EVENT_END:
+			case $.EVENT_CANCEL:
+				if (timer) {
+					clearTimeout(timer) && (timer = null);
+					$.trigger(session.target, 'release', touch);
+				}
+				break;
+		}
+	};
+	/**
+	 * mui gesture hold
+	 */
+	$.addGesture({
+		name: name,
+		index: 10,
+		handle: handle,
+		options: {
+			fingers: 1,
+			holdTimeout: 0
+		}
+	});
+})(mui, 'hold');
+/**
+ * mui gesture pinch
+ * @param {type} $
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, name) {
+	var handle = function(event, touch) {
+		var options = this.options;
+		var session = $.gestures.session;
+		switch (event.type) {
+			case $.EVENT_START:
+				break;
+			case $.EVENT_MOVE:
+				if ($.options.gestureConfig.pinch) {
+					if (touch.touches.length < 2) {
+						return;
+					}
+					if (!session.pinch) { //start
+						session.pinch = true;
+						$.trigger(session.target, name + 'start', touch);
+					}
+					$.trigger(session.target, name, touch);
+					var scale = touch.scale;
+					var rotation = touch.rotation;
+					var lastScale = typeof touch.lastScale === 'undefined' ? 1 : touch.lastScale;
+					var scaleDiff = 0.000000000001; //防止scale与lastScale相等,不触发事件的情况。
+					if (scale > lastScale) { //out
+						lastScale = scale - scaleDiff;
+						$.trigger(session.target, name + 'out', touch);
+					} //in
+					else if (scale < lastScale) {
+						lastScale = scale + scaleDiff;
+						$.trigger(session.target, name + 'in', touch);
+					}
+					if (Math.abs(rotation) > options.minRotationAngle) {
+						$.trigger(session.target, 'rotate', touch);
+					}
+				}
+				break;
+			case $.EVENT_END:
+			case $.EVENT_CANCEL:
+				if ($.options.gestureConfig.pinch && session.pinch && touch.touches.length === 2) {
+					session.pinch = false;
+					$.trigger(session.target, name + 'end', touch);
+				}
+				break;
+		}
+	};
+	/**
+	 * mui gesture pinch
+	 */
+	$.addGesture({
+		name: name,
+		index: 10,
+		handle: handle,
+		options: {
+			minRotationAngle: 0
+		}
+	});
+})(mui, 'pinch');
+/**
+ * mui.init
+ * @param {type} $
+ * @returns {undefined}
+ */
+(function($) {
+	$.global = $.options = {
+		gestureConfig: {
+			tap: true,
+			doubletap: false,
+			longtap: false,
+			hold: false,
+			flick: true,
+			swipe: true,
+			drag: true,
+			pinch: false
+		}
+	};
+	/**
+	 *
+	 * @param {type} options
+	 * @returns {undefined}
+	 */
+	$.initGlobal = function(options) {
+		$.options = $.extend(true, $.global, options);
+		return this;
+	};
+	var inits = {};
+
+	/**
+	 * 单页配置 初始化
+	 * @param {object} options
+	 */
+	$.init = function(options) {
+		$.options = $.extend(true, $.global, options || {});
+		$.ready(function() {
+			$.doAction('inits', function(index, init) {
+				var isInit = !!(!inits[init.name] || init.repeat);
+				if (isInit) {
+					init.handle.call($);
+					inits[init.name] = true;
+				}
+			});
+		});
+		return this;
+	};
+
+	/**
+	 * 增加初始化执行流程
+	 * @param {function} init
+	 */
+	$.addInit = function(init) {
+		return $.addAction('inits', init);
+	};
+	/**
+	 * 处理html5版本subpages 
+	 */
+	$.addInit({
+		name: 'iframe',
+		index: 100,
+		handle: function() {
+			var options = $.options;
+			var subpages = options.subpages || [];
+			if (!$.os.plus && subpages.length) {
+				//暂时只处理单个subpage。后续可以考虑支持多个subpage
+				createIframe(subpages[0]);
+			}
+		}
+	});
+	var createIframe = function(options) {
+		var wrapper = document.createElement('div');
+		wrapper.className = 'mui-iframe-wrapper';
+		var styles = options.styles || {};
+		if (typeof styles.top !== 'string') {
+			styles.top = '0px';
+		}
+		if (typeof styles.bottom !== 'string') {
+			styles.bottom = '0px';
+		}
+		wrapper.style.top = styles.top;
+		wrapper.style.bottom = styles.bottom;
+		var iframe = document.createElement('iframe');
+		iframe.src = options.url;
+		iframe.id = options.id || options.url;
+		iframe.name = iframe.id;
+		wrapper.appendChild(iframe);
+		document.body.appendChild(wrapper);
+		//目前仅处理微信
+		$.os.wechat && handleScroll(wrapper, iframe);
+	};
+
+	function handleScroll(wrapper, iframe) {
+		var key = 'MUI_SCROLL_POSITION_' + document.location.href + '_' + iframe.src;
+		var scrollTop = (parseFloat(localStorage.getItem(key)) || 0);
+		if (scrollTop) {
+			(function(y) {
+				iframe.onload = function() {
+					window.scrollTo(0, y);
+				};
+			})(scrollTop);
+		}
+		setInterval(function() {
+			var _scrollTop = window.scrollY;
+			if (scrollTop !== _scrollTop) {
+				localStorage.setItem(key, _scrollTop + '');
+				scrollTop = _scrollTop;
+			}
+		}, 100);
+	};
+	$(function() {
+		var classList = document.body.classList;
+		var os = [];
+		if ($.os.ios) {
+			os.push({
+				os: 'ios',
+				version: $.os.version
+			});
+			classList.add('mui-ios');
+		} else if ($.os.android) {
+			os.push({
+				os: 'android',
+				version: $.os.version
+			});
+			classList.add('mui-android');
+		}
+		if ($.os.wechat) {
+			os.push({
+				os: 'wechat',
+				version: $.os.wechat.version
+			});
+			classList.add('mui-wechat');
+		}
+		if (os.length) {
+			$.each(os, function(index, osObj) {
+				var version = '';
+				var classArray = [];
+				if (osObj.version) {
+					$.each(osObj.version.split('.'), function(i, v) {
+						version = version + (version ? '-' : '') + v;
+						classList.add($.className(osObj.os + '-' + version));
+					});
+				}
+			});
+		}
+	});
+})(mui);
+/**
+ * mui.init 5+
+ * @param {type} $
+ * @returns {undefined}
+ */
+(function($) {
+	var defaultOptions = {
+		swipeBack: false,
+		preloadPages: [], //5+ lazyLoad webview
+		preloadLimit: 10, //预加载窗口的数量限制(一旦超出,先进先出)
+		keyEventBind: {
+			backbutton: true,
+			menubutton: true
+		},
+		titleConfig: {
+			height: "44px",
+			backgroundColor: "#f7f7f7", //导航栏背景色
+			bottomBorderColor: "#cccccc", //底部边线颜色
+			title: { //标题配置
+				text: "", //标题文字
+				position: {
+					top: 0,
+					left: 0,
+					width: "100%",
+					height: "100%"
+				},
+				styles: {
+					color: "#000000",
+					align: "center",
+					family: "'Helvetica Neue',Helvetica,sans-serif",
+					size: "17px",
+					style: "normal",
+					weight: "normal",
+					fontSrc: ""
+				}
+			},
+			back: {
+				image: {
+					base64Data: '',
+					imgSrc: '',
+					sprite: {
+						top: '0px',
+						left: '0px',
+						width: '100%',
+						height: '100%'
+					},
+					position: {
+						top: "10px",
+						left: "10px",
+						width: "24px",
+						height: "24px"
+					}
+				}
+			}
+		}
+	};
+
+	//默认页面动画
+	var defaultShow = {
+		event:"titleUpdate",
+		autoShow: true,
+		duration: 300,
+		aniShow: 'slide-in-right',
+		extras:{}
+	};
+	//若执行了显示动画初始化操作,则要覆盖默认配置
+	if($.options.show) {
+		defaultShow = $.extend(true, defaultShow, $.options.show);
+	}
+
+	$.currentWebview = null;
+
+	$.extend(true, $.global, defaultOptions);
+	$.extend(true, $.options, defaultOptions);
+	/**
+	 * 等待动画配置
+	 * @param {type} options
+	 * @returns {Object}
+	 */
+	$.waitingOptions = function(options) {
+		return $.extend(true, {}, {
+			autoShow: true,
+			title: '',
+			modal: false
+		}, options);
+	};
+	/**
+	 * 窗口显示配置
+	 * @param {type} options
+	 * @returns {Object}
+	 */
+	$.showOptions = function(options) {
+		return $.extend(true, {}, defaultShow, options);
+	};
+	/**
+	 * 窗口默认配置
+	 * @param {type} options
+	 * @returns {Object}
+	 */
+	$.windowOptions = function(options) {
+		return $.extend({
+			scalable: false,
+			bounce: "" //vertical
+		}, options);
+	};
+	/**
+	 * plusReady
+	 * @param {type} callback
+	 * @returns {_L6.$}
+	 */
+	$.plusReady = function(callback) {
+		if(window.plus) {
+			setTimeout(function() { //解决callback与plusready事件的执行时机问题(典型案例:showWaiting,closeWaiting)
+				callback();
+			}, 0);
+		} else {
+			document.addEventListener("plusready", function() {
+				callback();
+			}, false);
+		}
+		return this;
+	};
+	/**
+	 * 5+ event(5+没提供之前我自己实现)
+	 * @param {type} webview
+	 * @param {type} eventType
+	 * @param {type} data
+	 * @returns {undefined}
+	 */
+	$.fire = function(webview, eventType, data) {
+		if(webview) {
+			if(typeof data === 'undefined') {
+				data = '';
+			} else if(typeof data === 'boolean' || typeof data === 'number') {
+				webview.evalJS("typeof mui!=='undefined'&&mui.receive('" + eventType + "'," + data + ")");
+				return;
+			} else if($.isPlainObject(data) || $.isArray(data)) {
+				data = JSON.stringify(data || {}).replace(/\'/g, "\\u0027").replace(/\\/g, "\\u005c");
+			}
+			webview.evalJS("typeof mui!=='undefined'&&mui.receive('" + eventType + "','" + data + "')");
+		}
+	};
+	/**
+	 * 5+ event(5+没提供之前我自己实现)
+	 * @param {type} eventType
+	 * @param {type} data
+	 * @returns {undefined}
+	 */
+	$.receive = function(eventType, data) {
+		if(eventType) {
+			try {
+				if(data && typeof data === 'string') {
+					data = JSON.parse(data);
+				}
+			} catch(e) {}
+			$.trigger(document, eventType, data);
+		}
+	};
+	var triggerPreload = function(webview) {
+		if(!webview.preloaded) { //保证仅触发一次
+			$.fire(webview, 'preload');
+			var list = webview.children();
+			for(var i = 0; i < list.length; i++) {
+				$.fire(list[i], 'preload');
+			}
+			webview.preloaded = true;
+		}
+	};
+	var trigger = function(webview, eventType, timeChecked) {
+		if(timeChecked) {
+			if(!webview[eventType + 'ed']) {
+				$.fire(webview, eventType);
+				var list = webview.children();
+				for(var i = 0; i < list.length; i++) {
+					$.fire(list[i], eventType);
+				}
+				webview[eventType + 'ed'] = true;
+			}
+		} else {
+			$.fire(webview, eventType);
+			var list = webview.children();
+			for(var i = 0; i < list.length; i++) {
+				$.fire(list[i], eventType);
+			}
+		}
+
+	};
+	/**
+	 * 打开新窗口
+	 * @param {string} url 要打开的页面地址
+	 * @param {string} id 指定页面ID
+	 * @param {object} options 可选:参数,等待,窗口,显示配置{params:{},waiting:{},styles:{},show:{}}
+	 */
+	$.openWindow = function(url, id, options) {
+		if(typeof url === 'object') {
+			options = url;
+			url = options.url;
+			id = options.id || url;
+		} else {
+			if(typeof id === 'object') {
+				options = id;
+				id = options.id || url;
+			} else {
+				id = id || url;
+			}
+		}
+		if(!$.os.plus) {
+			//TODO 先临时这么处理:手机上顶层跳,PC上parent跳
+			if($.os.ios || $.os.android) {
+				window.top.location.href = url;
+			} else {
+				window.parent.location.href = url;
+			}
+			return;
+		}
+		if(!window.plus) {
+			return;
+		}
+
+		options = options || {};
+		var params = options.params || {};
+		var webview = null,
+			webviewCache = null,
+			nShow, nWaiting;
+
+		if($.webviews[id]) {
+			webviewCache = $.webviews[id];
+			//webview真实存在,才能获取
+			if(plus.webview.getWebviewById(id)) {
+				webview = webviewCache.webview;
+			}
+		} else if(options.createNew !== true) {
+			webview = plus.webview.getWebviewById(id);
+		}
+
+		if(webview) { //已缓存
+			//每次show都需要传递动画参数;
+			//预加载的动画参数优先级:openWindow配置>preloadPages配置>mui默认配置;
+			nShow = webviewCache ? webviewCache.show : defaultShow;
+			nShow = options.show ? $.extend(nShow, options.show) : nShow;
+			nShow.autoShow && webview.show(nShow.aniShow, nShow.duration, function() {
+				triggerPreload(webview);
+				trigger(webview, 'pagebeforeshow', false);
+			});
+			if(webviewCache) {
+				webviewCache.afterShowMethodName && webview.evalJS(webviewCache.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')');
+			}
+			return webview;
+		} else { //新窗口
+			if(!url) {
+				throw new Error('webview[' + id + '] does not exist');
+			}
+
+			//显示waiting
+			var waitingConfig = $.waitingOptions(options.waiting);
+			if(waitingConfig.autoShow) {
+				nWaiting = plus.nativeUI.showWaiting(waitingConfig.title, waitingConfig.options);
+			}
+
+			//创建页面
+			options = $.extend(options, {
+				id: id,
+				url: url
+			});
+
+			webview = $.createWindow(options);
+
+			//显示
+			nShow = $.showOptions(options.show);
+			if(nShow.autoShow) {
+				var showWebview = function() {
+					//关闭等待框
+					if(nWaiting) {
+						nWaiting.close();
+					}
+					//显示页面
+					webview.show(nShow.aniShow, nShow.duration, function() {},nShow.extras);
+					options.afterShowMethodName && webview.evalJS(options.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')');
+				};
+				//titleUpdate触发时机早于loaded,更换为titleUpdate后,可以更早的显示webview
+				webview.addEventListener(nShow.event, showWebview, false);
+				//loaded事件发生后,触发预加载和pagebeforeshow事件
+				webview.addEventListener("loaded", function() {
+					triggerPreload(webview);
+					trigger(webview, 'pagebeforeshow', false);
+				}, false);
+			}
+		}
+		return webview;
+	};
+
+	$.openWindowWithTitle = function(options, titleConfig) {
+		options = options || {};
+		var url = options.url;
+		var id = options.id || url;
+
+		if(!$.os.plus) {
+			//TODO 先临时这么处理:手机上顶层跳,PC上parent跳
+			if($.os.ios || $.os.android) {
+				window.top.location.href = url;
+			} else {
+				window.parent.location.href = url;
+			}
+			return;
+		}
+		if(!window.plus) {
+			return;
+		}
+
+		var params = options.params || {};
+		var webview = null,
+			webviewCache = null,
+			nShow, nWaiting;
+
+		if($.webviews[id]) {
+			webviewCache = $.webviews[id];
+			//webview真实存在,才能获取
+			if(plus.webview.getWebviewById(id)) {
+				webview = webviewCache.webview;
+			}
+		} else if(options.createNew !== true) {
+			webview = plus.webview.getWebviewById(id);
+		}
+
+		if(webview) { //已缓存
+			//每次show都需要传递动画参数;
+			//预加载的动画参数优先级:openWindow配置>preloadPages配置>mui默认配置;
+			nShow = webviewCache ? webviewCache.show : defaultShow;
+			nShow = options.show ? $.extend(nShow, options.show) : nShow;
+			nShow.autoShow && webview.show(nShow.aniShow, nShow.duration, function() {
+				triggerPreload(webview);
+				trigger(webview, 'pagebeforeshow', false);
+			});
+			if(webviewCache) {
+				webviewCache.afterShowMethodName && webview.evalJS(webviewCache.afterShowMethodName + '(\'' + JSON.stringify(params) + '\')');
+			}
+			return webview;
+		} else { //新窗口
+			if(!url) {
+				throw new Error('webview[' + id + '] does not exist');
+			}
+
+			//显示waiting
+			var waitingConfig = $.waitingOptions(options.waiting);
+			if(waitingConfig.autoShow) {
+				nWaiting = plus.nativeUI.showWaiting(waitingConfig.title, waitingConfig.options);
+			}
+
+			//创建页面
+			options = $.extend(options, {
+				id: id,
+				url: url
+			});
+
+			webview = $.createWindow(options);
+
+			if(titleConfig) { //处理原生头
+				$.extend(true, $.options.titleConfig, titleConfig);
+				var tid = $.options.titleConfig.id ? $.options.titleConfig.id : id + "_title";
+				var view = new plus.nativeObj.View(tid, {
+					top: 0,
+					height: $.options.titleConfig.height,
+					width: "100%",
+					dock: "top",
+					position: "dock"
+				});
+				view.drawRect($.options.titleConfig.backgroundColor); //绘制背景色
+				var _b = parseInt($.options.titleConfig.height) - 1;
+				view.drawRect($.options.titleConfig.bottomBorderColor, {
+					top: _b + "px",
+					left: "0px"
+				}); //绘制底部边线
+
+				//绘制文字
+				if($.options.titleConfig.title.text){
+					var _title = $.options.titleConfig.title;
+					view.drawText(_title.text,_title.position , _title.styles);
+				}
+				
+				//返回图标绘制
+				var _back = $.options.titleConfig.back;
+				var backClick = null;
+				//优先字体
+
+				//其次是图片
+				var _backImage = _back.image;
+				if(_backImage.base64Data || _backImage.imgSrc) {
+					//TODO 此处需要处理百分比的情况
+					backClick = {
+						left:parseInt(_backImage.position.left),
+						right:parseInt(_backImage.position.left) + parseInt(_backImage.position.width)
+					};
+					var bitmap = new plus.nativeObj.Bitmap(id + "_back");
+					if(_backImage.base64Data) { //优先base64编码字符串
+						bitmap.loadBase64Data(_backImage.base64Data);
+					} else { //其次加载图片文件
+						bitmap.load(_backImage.imgSrc);
+					}
+					view.drawBitmap(bitmap,_backImage.sprite , _backImage.position);
+				}
+
+				//处理点击事件
+				view.setTouchEventRect({
+					top: "0px",
+					left: "0px",
+					width: "100%",
+					height: "100%"
+				});
+				view.interceptTouchEvent(true);
+				view.addEventListener("click", function(e) {
+					var x = e.clientX;
+					
+					//返回按钮点击
+					if(backClick&& x > backClick.left && x < backClick.right){
+						if( _back.click && $.isFunction(_back.click)){
+							_back.click();
+						}else{
+							webview.evalJS("window.mui&&mui.back();");
+						}
+					}
+				}, false);
+				webview.append(view);
+
+			}
+
+			//显示
+			nShow = $.showOptions(options.show);
+			if(nShow.autoShow) {
+				//titleUpdate触发时机早于loaded,更换为titleUpdate后,可以更早的显示webview
+				webview.addEventListener(nShow.event, function () {
+					//关闭等待框
+					if(nWaiting) {
+						nWaiting.close();
+					}
+					//显示页面
+					webview.show(nShow.aniShow, nShow.duration, function() {},nShow.extras);
+				}, false);
+			}
+		}
+		return webview;
+	};
+
+	/**
+	 * 根据配置信息创建一个webview
+	 * @param {type} options
+	 * @param {type} isCreate
+	 * @returns {webview}
+	 */
+	$.createWindow = function(options, isCreate) {
+		if(!window.plus) {
+			return;
+		}
+		var id = options.id || options.url;
+		var webview;
+		if(options.preload) {
+			if($.webviews[id] && $.webviews[id].webview.getURL()) { //已经cache
+				webview = $.webviews[id].webview;
+			} else { //新增预加载窗口
+				//判断是否携带createNew参数,默认为false
+				if(options.createNew !== true) {
+					webview = plus.webview.getWebviewById(id);
+				}
+
+				//之前没有,那就新创建	
+				if(!webview) {
+					webview = plus.webview.create(options.url, id, $.windowOptions(options.styles), $.extend({
+						preload: true
+					}, options.extras));
+					if(options.subpages) {
+						$.each(options.subpages, function(index, subpage) {
+							var subpageId = subpage.id || subpage.url;
+							if(subpageId) { //过滤空对象
+								var subWebview = plus.webview.getWebviewById(subpageId);
+								if(!subWebview) { //如果该webview不存在,则创建
+									subWebview = plus.webview.create(subpage.url, subpageId, $.windowOptions(subpage.styles), $.extend({
+										preload: true
+									}, subpage.extras));
+								}
+								webview.append(subWebview);
+							}
+						});
+					}
+				}
+			}
+
+			//TODO 理论上,子webview也应该计算到预加载队列中,但这样就麻烦了,要退必须退整体,否则可能出现问题;
+			$.webviews[id] = {
+				webview: webview, //目前仅preload的缓存webview
+				preload: true,
+				show: $.showOptions(options.show),
+				afterShowMethodName: options.afterShowMethodName //就不应该用evalJS。应该是通过事件消息通讯
+			};
+			//索引该预加载窗口
+			var preloads = $.data.preloads;
+			var index = preloads.indexOf(id);
+			if(~index) { //删除已存在的(变相调整插入位置)
+				preloads.splice(index, 1);
+			}
+			preloads.push(id);
+			if(preloads.length > $.options.preloadLimit) {
+				//先进先出
+				var first = $.data.preloads.shift();
+				var webviewCache = $.webviews[first];
+				if(webviewCache && webviewCache.webview) {
+					//需要将自己打开的所有页面,全部close;
+					//关闭该预加载webview	
+					$.closeAll(webviewCache.webview);
+				}
+				//删除缓存
+				delete $.webviews[first];
+			}
+		} else {
+			if(isCreate !== false) { //直接创建非预加载窗口
+				webview = plus.webview.create(options.url, id, $.windowOptions(options.styles), options.extras);
+				if(options.subpages) {
+					$.each(options.subpages, function(index, subpage) {
+						var subpageId = subpage.id || subpage.url;
+						var subWebview = plus.webview.getWebviewById(subpageId);
+						if(!subWebview) {
+							subWebview = plus.webview.create(subpage.url, subpageId, $.windowOptions(subpage.styles), subpage.extras);
+						}
+						webview.append(subWebview);
+					});
+				}
+			}
+		}
+		return webview;
+	};
+
+	/**
+	 * 预加载
+	 */
+	$.preload = function(options) {
+		//调用预加载函数,不管是否传递preload参数,强制变为true
+		if(!options.preload) {
+			options.preload = true;
+		}
+		return $.createWindow(options);
+	};
+
+	/**
+	 *关闭当前webview打开的所有webview;
+	 */
+	$.closeOpened = function(webview) {
+		var opened = webview.opened();
+		if(opened) {
+			for(var i = 0, len = opened.length; i < len; i++) {
+				var openedWebview = opened[i];
+				var open_open = openedWebview.opened();
+				if(open_open && open_open.length > 0) {
+					//关闭打开的webview
+					$.closeOpened(openedWebview);
+					//关闭自己
+					openedWebview.close("none");
+				} else {
+					//如果直接孩子节点,就不用关闭了,因为父关闭的时候,会自动关闭子;
+					if(openedWebview.parent() !== webview) {
+						openedWebview.close('none');
+					}
+				}
+			}
+		}
+	};
+	$.closeAll = function(webview, aniShow) {
+		$.closeOpened(webview);
+		if(aniShow) {
+			webview.close(aniShow);
+		} else {
+			webview.close();
+		}
+	};
+
+	/**
+	 * 批量创建webview
+	 * @param {type} options
+	 * @returns {undefined}
+	 */
+	$.createWindows = function(options) {
+		$.each(options, function(index, option) {
+			//初始化预加载窗口(创建)和非预加载窗口(仅配置,不创建)
+			$.createWindow(option, false);
+		});
+	};
+	/**
+	 * 创建当前页面的子webview
+	 * @param {type} options
+	 * @returns {webview}
+	 */
+	$.appendWebview = function(options) {
+		if(!window.plus) {
+			return;
+		}
+		var id = options.id || options.url;
+		var webview;
+		if(!$.webviews[id]) { //保证执行一遍
+			//TODO 这里也有隐患,比如某个webview不是作为subpage创建的,而是作为target webview的话;
+			if(!plus.webview.getWebviewById(id)) {
+				webview = plus.webview.create(options.url, id, options.styles, options.extras);
+			}
+			//之前的实现方案:子窗口loaded之后再append到父窗口中;
+			//问题:部分子窗口loaded事件发生较晚,此时执行父窗口的children方法会返回空,导致父子通讯失败;
+			//     比如父页面执行完preload事件后,需触发子页面的preload事件,此时未append的话,就无法触发;
+			//修改方式:不再监控loaded事件,直接append
+			//by chb@20150521
+			// webview.addEventListener('loaded', function() {
+			plus.webview.currentWebview().append(webview);
+			// });
+			$.webviews[id] = options;
+
+		}
+		return webview;
+	};
+
+	//全局webviews
+	$.webviews = {};
+	//预加载窗口索引
+	$.data.preloads = [];
+	//$.currentWebview
+	$.plusReady(function() {
+		$.currentWebview = plus.webview.currentWebview();
+	});
+	$.addInit({
+		name: '5+',
+		index: 100,
+		handle: function() {
+			var options = $.options;
+			var subpages = options.subpages || [];
+			if($.os.plus) {
+				$.plusReady(function() {
+					//TODO  这里需要判断一下,最好等子窗口加载完毕后,再调用主窗口的show方法;
+					//或者:在openwindow方法中,监听实现;
+					$.each(subpages, function(index, subpage) {
+						$.appendWebview(subpage);
+					});
+					//判断是否首页
+					if(plus.webview.currentWebview() === plus.webview.getWebviewById(plus.runtime.appid)) {
+						//首页需要自己激活预加载;
+						//timeout因为子页面loaded之后才append的,防止子页面尚未append、从而导致其preload未触发的问题;
+						setTimeout(function() {
+							triggerPreload(plus.webview.currentWebview());
+						}, 300);
+					}
+					//设置ios顶部状态栏颜色;
+					if($.os.ios && $.options.statusBarBackground) {
+						plus.navigator.setStatusBarBackground($.options.statusBarBackground);
+					}
+					if($.os.android && parseFloat($.os.version) < 4.4) {
+						//解决Android平台4.4版本以下,resume后,父窗体标题延迟渲染的问题;
+						if(plus.webview.currentWebview().parent() == null) {
+							document.addEventListener("resume", function() {
+								var body = document.body;
+								body.style.display = 'none';
+								setTimeout(function() {
+									body.style.display = '';
+								}, 10);
+							});
+						}
+					}
+				});
+			} else {
+				//已支持iframe嵌入
+				//				if (subpages.length > 0) {
+				//					var err = document.createElement('div');
+				//					err.className = 'mui-error';
+				//					//文字描述
+				//					var span = document.createElement('span');
+				//					span.innerHTML = '在该浏览器下,不支持创建子页面,具体参考';
+				//					err.appendChild(span);
+				//					var a = document.createElement('a');
+				//					a.innerHTML = '"mui框架适用场景"';
+				//					a.href = 'http://ask.dcloud.net.cn/article/113';
+				//					err.appendChild(a);
+				//					document.body.appendChild(err);
+				//					console.log('在该浏览器下,不支持创建子页面');
+				//				}
+
+			}
+
+		}
+	});
+	window.addEventListener('preload', function() {
+		//处理预加载部分
+		var webviews = $.options.preloadPages || [];
+		$.plusReady(function() {
+			$.each(webviews, function(index, webview) {
+				$.createWindow($.extend(webview, {
+					preload: true
+				}));
+			});
+
+		});
+	});
+	$.supportStatusbarOffset = function() {
+		return $.os.plus && $.os.ios && parseFloat($.os.version) >= 7;
+	};
+	$.ready(function() {
+		//标识当前环境支持statusbar
+		if($.supportStatusbarOffset()) {
+			document.body.classList.add('mui-statusbar');
+		}
+	});
+})(mui);
+
+/**
+ * mui back
+ * @param {type} $
+ * @param {type} window
+ * @returns {undefined}
+ */
+(function($, window) {
+	/**
+	 * register back
+	 * @param {type} back
+	 * @returns {$.gestures}
+	 */
+	$.addBack = function(back) {
+		return $.addAction('backs', back);
+	};
+	/**
+	 * default
+	 */
+	$.addBack({
+		name: 'browser',
+		index: 100,
+		handle: function() {
+			if (window.history.length > 1) {
+				window.history.back();
+				return true;
+			}
+			return false;
+		}
+	});
+	/**
+	 * 后退
+	 */
+	$.back = function() {
+		if (typeof $.options.beforeback === 'function') {
+			if ($.options.beforeback() === false) {
+				return;
+			}
+		}
+		$.doAction('backs');
+	};
+	window.addEventListener('tap', function(e) {
+		var action = $.targets.action;
+		if (action && action.classList.contains('mui-action-back')) {
+			$.back();
+			$.targets.action = false;
+		}
+	});
+	window.addEventListener('swiperight', function(e) {
+		var detail = e.detail;
+		if ($.options.swipeBack === true && Math.abs(detail.angle) < 3) {
+			$.back();
+		}
+	});
+
+})(mui, window);
+/**
+ * mui back 5+
+ * @param {type} $
+ * @param {type} window
+ * @returns {undefined}
+ */
+(function($, window) {
+	if ($.os.plus && $.os.android) {
+		$.addBack({
+			name: 'mui',
+			index: 5,
+			handle: function() {
+				//后续重新设计此处,将back放到各个空间内部实现
+				//popover
+				if ($.targets._popover && $.targets._popover.classList.contains('mui-active')) {
+					$($.targets._popover).popover('hide');
+					return true;
+				}
+				//offcanvas
+				var offCanvas = document.querySelector('.mui-off-canvas-wrap.mui-active');
+				if (offCanvas) {
+					$(offCanvas).offCanvas('close');
+					return true;
+				}
+				var previewImage = $.isFunction($.getPreviewImage) && $.getPreviewImage();
+				if (previewImage && previewImage.isShown()) {
+					previewImage.close();
+					return true;
+				}
+				//popup
+				return $.closePopup();
+			}
+		});
+	}
+	//首次按下back按键的时间
+	$.__back__first = null;
+	/**
+	 * 5+ back
+	 */
+	$.addBack({
+		name: '5+',
+		index: 10,
+		handle: function() {
+			if (!window.plus) {
+				return false;
+			}
+			var wobj = plus.webview.currentWebview();
+			var parent = wobj.parent();
+			if (parent) {
+				parent.evalJS('mui&&mui.back();');
+			} else {
+				wobj.canBack(function(e) {
+					//by chb 暂时注释,在碰到类似popover之类的锚点的时候,需多次点击才能返回;
+					if (e.canBack) { //webview history back
+						window.history.back();
+					} else { //webview close or hide
+						//fixed by fxy 此处不应该用opener判断,因为用户有可能自己close掉当前窗口的opener。这样的话。opener就为空了,导致不能执行close
+						if (wobj.id === plus.runtime.appid) { //首页
+							//首页不存在opener的情况下,后退实际上应该是退出应用;
+							//首次按键,提示‘再按一次退出应用’
+							if (!$.__back__first) {
+								$.__back__first = new Date().getTime();
+								mui.toast('再按一次退出应用');
+								setTimeout(function() {
+									$.__back__first = null;
+								}, 2000);
+							} else {
+								if (new Date().getTime() - $.__back__first < 2000) {
+									plus.runtime.quit();
+								}
+							}
+						} else { //其他页面,
+							if (wobj.preload) {
+								wobj.hide("auto");
+							} else {
+								//关闭页面时,需要将其打开的所有子页面全部关闭;
+								$.closeAll(wobj);
+							}
+						}
+					}
+				});
+			}
+			return true;
+		}
+	});
+
+
+	$.menu = function() {
+		var menu = document.querySelector('.mui-action-menu');
+		if (menu) {
+			$.trigger(menu, $.EVENT_START); //临时处理menu无touchstart的话,找不到当前targets的问题
+			$.trigger(menu, 'tap');
+		} else { //执行父窗口的menu
+			if (window.plus) {
+				var wobj = $.currentWebview;
+				var parent = wobj.parent();
+				if (parent) { //又得evalJS
+					parent.evalJS('mui&&mui.menu();');
+				}
+			}
+		}
+	};
+	var __back = function() {
+		$.back();
+	};
+	var __menu = function() {
+		$.menu();
+	};
+	//默认监听
+	$.plusReady(function() {
+		if ($.options.keyEventBind.backbutton) {
+			plus.key.addEventListener('backbutton', __back, false);
+		}
+		if ($.options.keyEventBind.menubutton) {
+			plus.key.addEventListener('menubutton', __menu, false);
+		}
+	});
+	//处理按键监听事件
+	$.addInit({
+		name: 'keyEventBind',
+		index: 1000,
+		handle: function() {
+			$.plusReady(function() {
+				//如果不为true,则移除默认监听
+				if (!$.options.keyEventBind.backbutton) {
+					plus.key.removeEventListener('backbutton', __back);
+				}
+				if (!$.options.keyEventBind.menubutton) {
+					plus.key.removeEventListener('menubutton', __menu);
+				}
+			});
+		}
+	});
+})(mui, window);
+/**
+ * mui.init pulldownRefresh
+ * @param {type} $
+ * @returns {undefined}
+ */
+(function($) {
+	$.addInit({
+		name: 'pullrefresh',
+		index: 1000,
+		handle: function() {
+			var options = $.options;
+			var pullRefreshOptions = options.pullRefresh || {};
+			var hasPulldown = pullRefreshOptions.down && pullRefreshOptions.down.hasOwnProperty('callback');
+			var hasPullup = pullRefreshOptions.up && pullRefreshOptions.up.hasOwnProperty('callback');
+			if(hasPulldown || hasPullup) {
+				var container = pullRefreshOptions.container;
+				if(container) {
+					var $container = $(container);
+					if($container.length === 1) {
+						if($.os.plus) { //5+环境
+							if(hasPulldown && pullRefreshOptions.down.style == "circle") { //原生转圈
+								$.plusReady(function() {
+									//这里改写$.fn.pullRefresh
+									$.fn.pullRefresh = $.fn.pullRefresh_native;
+									$container.pullRefresh(pullRefreshOptions);
+								});
+
+							} else if($.os.android) { //非原生转圈,但是Android环境
+								$.plusReady(function() {
+									//这里改写$.fn.pullRefresh
+									$.fn.pullRefresh = $.fn.pullRefresh_native
+									var webview = plus.webview.currentWebview();
+									if(window.__NWin_Enable__ === false) { //不支持多webview
+										$container.pullRefresh(pullRefreshOptions);
+									} else {
+										if(hasPullup) {
+											//当前页面初始化pullup
+											var upOptions = {};
+											upOptions.up = pullRefreshOptions.up;
+											upOptions.webviewId = webview.id || webview.getURL();
+											$container.pullRefresh(upOptions);
+										}
+										if(hasPulldown) {
+											var parent = webview.parent();
+											var id = webview.id || webview.getURL();
+											if(parent) {
+												if(!hasPullup) { //如果没有上拉加载,需要手动初始化一个默认的pullRefresh,以便当前页面容器可以调用endPulldownToRefresh等方法
+													$container.pullRefresh({
+														webviewId: id
+													});
+												}
+												var downOptions = {
+													webviewId: id//子页面id
+												};
+												downOptions.down = $.extend({}, pullRefreshOptions.down);
+												downOptions.down.callback = '_CALLBACK';
+												//改写父页面的$.fn.pullRefresh
+												parent.evalJS("mui.fn.pullRefresh=mui.fn.pullRefresh_native");
+												//父页面初始化pulldown
+												parent.evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('" + JSON.stringify(downOptions) + "')");
+											}
+										}
+									}
+								});
+							} else { //非原生转圈,iOS环境
+								$container.pullRefresh(pullRefreshOptions);
+							}
+						} else {
+							$container.pullRefresh(pullRefreshOptions);
+						}
+					}
+				}
+			}
+		}
+	});
+})(mui);
+/**
+ * mui ajax
+ * @param {type} $
+ * @returns {undefined}
+ */
+(function($, window, undefined) {
+
+	var jsonType = 'application/json';
+	var htmlType = 'text/html';
+	var rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi;
+	var scriptTypeRE = /^(?:text|application)\/javascript/i;
+	var xmlTypeRE = /^(?:text|application)\/xml/i;
+	var blankRE = /^\s*$/;
+
+	$.ajaxSettings = {
+		type: 'GET',
+		beforeSend: $.noop,
+		success: $.noop,
+		error: $.noop,
+		complete: $.noop,
+		context: null,
+		xhr: function(protocol) {
+			return new window.XMLHttpRequest();
+		},
+		accepts: {
+			script: 'text/javascript, application/javascript, application/x-javascript',
+			json: jsonType,
+			xml: 'application/xml, text/xml',
+			html: htmlType,
+			text: 'text/plain'
+		},
+		timeout: 0,
+		processData: true,
+		cache: true
+	};
+	var ajaxBeforeSend = function(xhr, settings) {
+		var context = settings.context
+		if(settings.beforeSend.call(context, xhr, settings) === false) {
+			return false;
+		}
+	};
+	var ajaxSuccess = function(data, xhr, settings) {
+		settings.success.call(settings.context, data, 'success', xhr);
+		ajaxComplete('success', xhr, settings);
+	};
+	// type: "timeout", "error", "abort", "parsererror"
+	var ajaxError = function(error, type, xhr, settings) {
+		settings.error.call(settings.context, xhr, type, error);
+		ajaxComplete(type, xhr, settings);
+	};
+	// status: "success", "notmodified", "error", "timeout", "abort", "parsererror"
+	var ajaxComplete = function(status, xhr, settings) {
+		settings.complete.call(settings.context, xhr, status);
+	};
+
+	var serialize = function(params, obj, traditional, scope) {
+		var type, array = $.isArray(obj),
+			hash = $.isPlainObject(obj);
+		$.each(obj, function(key, value) {
+			type = $.type(value);
+			if(scope) {
+				key = traditional ? scope :
+					scope + '[' + (hash || type === 'object' || type === 'array' ? key : '') + ']';
+			}
+			// handle data in serializeArray() format
+			if(!scope && array) {
+				params.add(value.name, value.value);
+			}
+			// recurse into nested objects
+			else if(type === "array" || (!traditional && type === "object")) {
+				serialize(params, value, traditional, key);
+			} else {
+				params.add(key, value);
+			}
+		});
+	};
+	var serializeData = function(options) {
+		if(options.processData && options.data && typeof options.data !== "string") {
+			var contentType = options.contentType;
+			if(!contentType && options.headers) {
+				contentType = options.headers['Content-Type'];
+			}
+			if(contentType && ~contentType.indexOf(jsonType)) { //application/json
+				options.data = JSON.stringify(options.data);
+			} else {
+				options.data = $.param(options.data, options.traditional);
+			}
+		}
+		if(options.data && (!options.type || options.type.toUpperCase() === 'GET')) {
+			options.url = appendQuery(options.url, options.data);
+			options.data = undefined;
+		}
+	};
+	var appendQuery = function(url, query) {
+		if(query === '') {
+			return url;
+		}
+		return(url + '&' + query).replace(/[&?]{1,2}/, '?');
+	};
+	var mimeToDataType = function(mime) {
+		if(mime) {
+			mime = mime.split(';', 2)[0];
+		}
+		return mime && (mime === htmlType ? 'html' :
+			mime === jsonType ? 'json' :
+			scriptTypeRE.test(mime) ? 'script' :
+			xmlTypeRE.test(mime) && 'xml') || 'text';
+	};
+	var parseArguments = function(url, data, success, dataType) {
+		if($.isFunction(data)) {
+			dataType = success, success = data, data = undefined;
+		}
+		if(!$.isFunction(success)) {
+			dataType = success, success = undefined;
+		}
+		return {
+			url: url,
+			data: data,
+			success: success,
+			dataType: dataType
+		};
+	};
+	$.ajax = function(url, options) {
+		if(typeof url === "object") {
+			options = url;
+			url = undefined;
+		}
+		var settings = options || {};
+		settings.url = url || settings.url;
+		for(var key in $.ajaxSettings) {
+			if(settings[key] === undefined) {
+				settings[key] = $.ajaxSettings[key];
+			}
+		}
+		serializeData(settings);
+		var dataType = settings.dataType;
+
+		if(settings.cache === false || ((!options || options.cache !== true) && ('script' === dataType))) {
+			settings.url = appendQuery(settings.url, '_=' + $.now());
+		}
+		var mime = settings.accepts[dataType && dataType.toLowerCase()];
+		var headers = {};
+		var setHeader = function(name, value) {
+			headers[name.toLowerCase()] = [name, value];
+		};
+		var protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol;        
+		var xhr = settings.xhr(settings);
+        
+        if(location.protocol === 'file:' && $.os.ios && window.webkit && window.webkit.messageHandlers && !(xhr instanceof plus.net.XMLHttpRequest)){
+            console.error("当前运行环境为WKWebview,需在plusReady事件触发后再调用mui.ajax,否则可能会执行失败或报Script error的错误")
+        }
+		var nativeSetHeader = xhr.setRequestHeader;
+		var abortTimeout;
+
+		setHeader('X-Requested-With', 'XMLHttpRequest');
+		setHeader('Accept', mime || '*/*');
+		if(!!(mime = settings.mimeType || mime)) {
+			if(mime.indexOf(',') > -1) {
+				mime = mime.split(',', 2)[0];
+			}
+			xhr.overrideMimeType && xhr.overrideMimeType(mime);
+		}
+		if(settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() !== 'GET')) {
+			setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded');
+		}
+		if(settings.headers) {
+			for(var name in settings.headers)
+				setHeader(name, settings.headers[name]);
+		}
+		xhr.setRequestHeader = setHeader;
+
+		xhr.onreadystatechange = function() {
+			if(xhr.readyState === 4) {
+				xhr.onreadystatechange = $.noop;
+				clearTimeout(abortTimeout);
+				var result, error = false;
+				var isLocal = protocol === 'file:';
+				if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || (xhr.status === 0 && isLocal && xhr.responseText)) {
+					dataType = dataType || mimeToDataType(settings.mimeType || xhr.getResponseHeader('content-type'));
+					result = xhr.responseText;
+					try {
+						// http://perfectionkills.com/global-eval-what-are-the-options/
+						if(dataType === 'script') {
+							(1, eval)(result);
+						} else if(dataType === 'xml') {
+							result = xhr.responseXML;
+						} else if(dataType === 'json') {
+							result = blankRE.test(result) ? null : $.parseJSON(result);
+						}
+					} catch(e) {
+						error = e;
+					}
+
+					if(error) {
+						ajaxError(error, 'parsererror', xhr, settings);
+					} else {
+						ajaxSuccess(result, xhr, settings);
+					}
+				} else {
+					var status = xhr.status ? 'error' : 'abort';
+					var statusText = xhr.statusText || null;
+					if(isLocal) {
+						status = 'error';
+						statusText = '404';
+					}
+					ajaxError(statusText, status, xhr, settings);
+				}
+			}
+		};
+		if(ajaxBeforeSend(xhr, settings) === false) {
+			xhr.abort();
+			ajaxError(null, 'abort', xhr, settings);
+			return xhr;
+		}
+
+		if(settings.xhrFields) {
+			for(var name in settings.xhrFields) {
+				xhr[name] = settings.xhrFields[name];
+			}
+		}
+
+		var async = 'async' in settings ? settings.async : true;
+
+		xhr.open(settings.type.toUpperCase(), settings.url, async, settings.username, settings.password);
+
+		for(var name in headers) {
+			if(headers.hasOwnProperty(name)) {
+				nativeSetHeader.apply(xhr, headers[name]);
+			}
+		}
+		if(settings.timeout > 0) {
+			abortTimeout = setTimeout(function() {
+				xhr.onreadystatechange = $.noop;
+				xhr.abort();
+				ajaxError(null, 'timeout', xhr, settings);
+			}, settings.timeout);
+		}
+		xhr.send(settings.data ? settings.data : null);
+		return xhr;
+	};
+
+	$.param = function(obj, traditional) {
+		var params = [];
+		params.add = function(k, v) {
+			this.push(encodeURIComponent(k) + '=' + encodeURIComponent(v));
+		};
+		serialize(params, obj, traditional);
+		return params.join('&').replace(/%20/g, '+');
+	};
+	$.get = function( /* url, data, success, dataType */ ) {
+		return $.ajax(parseArguments.apply(null, arguments));
+	};
+
+	$.post = function( /* url, data, success, dataType */ ) {
+		var options = parseArguments.apply(null, arguments);
+		options.type = 'POST';
+		return $.ajax(options);
+	};
+
+	$.getJSON = function( /* url, data, success */ ) {
+		var options = parseArguments.apply(null, arguments);
+		options.dataType = 'json';
+		return $.ajax(options);
+	};
+
+	$.fn.load = function(url, data, success) {
+		if(!this.length)
+			return this;
+		var self = this,
+			parts = url.split(/\s/),
+			selector,
+			options = parseArguments(url, data, success),
+			callback = options.success;
+		if(parts.length > 1)
+			options.url = parts[0], selector = parts[1];
+		options.success = function(response) {
+			if(selector) {
+				var div = document.createElement('div');
+				div.innerHTML = response.replace(rscript, "");
+				var selectorDiv = document.createElement('div');
+				var childs = div.querySelectorAll(selector);
+				if(childs && childs.length > 0) {
+					for(var i = 0, len = childs.length; i < len; i++) {
+						selectorDiv.appendChild(childs[i]);
+					}
+				}
+				self[0].innerHTML = selectorDiv.innerHTML;
+			} else {
+				self[0].innerHTML = response;
+			}
+			callback && callback.apply(self, arguments);
+		};
+		$.ajax(options);
+		return this;
+	};
+
+})(mui, window);
+/**
+ * 5+ ajax
+ */
+(function($) {
+	var originAnchor = document.createElement('a');
+	originAnchor.href = window.location.href;
+	$.plusReady(function() {
+		$.ajaxSettings = $.extend($.ajaxSettings, {
+			xhr: function(settings) {
+				if (settings.crossDomain) { //强制使用plus跨域
+					return new plus.net.XMLHttpRequest();
+				}
+				//仅在webview的url为远程文件,且ajax请求的资源不同源下使用plus.net.XMLHttpRequest
+				if (originAnchor.protocol !== 'file:') {
+					var urlAnchor = document.createElement('a');
+					urlAnchor.href = settings.url;
+					urlAnchor.href = urlAnchor.href;
+					settings.crossDomain = (originAnchor.protocol + '//' + originAnchor.host) !== (urlAnchor.protocol + '//' + urlAnchor.host);
+					if (settings.crossDomain) {
+						return new plus.net.XMLHttpRequest();
+					}
+				}
+				if ($.os.ios && window.webkit && window.webkit.messageHandlers) { //wkwebview下同样使用5+ xhr
+                    return new plus.net.XMLHttpRequest();
+                }
+				return new window.XMLHttpRequest();
+			}
+		});
+	});
+})(mui);
+/**
+ * mui layout(offset[,position,width,height...])
+ * @param {type} $
+ * @param {type} window
+ * @param {type} undefined
+ * @returns {undefined}
+ */
+(function($, window, undefined) {
+	$.offset = function(element) {
+		var box = {
+			top : 0,
+			left : 0
+		};
+		if ( typeof element.getBoundingClientRect !== undefined) {
+			box = element.getBoundingClientRect();
+		}
+		return {
+			top : box.top + window.pageYOffset - element.clientTop,
+			left : box.left + window.pageXOffset - element.clientLeft
+		};
+	};
+})(mui, window); 
+/**
+ * mui animation
+ */
+(function($, window) {
+	/**
+	 * scrollTo
+	 */
+	$.scrollTo = function(scrollTop, duration, callback) {
+		duration = duration || 1000;
+		var scroll = function(duration) {
+			if (duration <= 0) {
+				window.scrollTo(0, scrollTop);
+				callback && callback();
+				return;
+			}
+			var distaince = scrollTop - window.scrollY;
+			setTimeout(function() {
+				window.scrollTo(0, window.scrollY + distaince / duration * 10);
+				scroll(duration - 10);
+			}, 16.7);
+		};
+		scroll(duration);
+	};
+	$.animationFrame = function(cb) {
+		var args, isQueued, context;
+		return function() {
+			args = arguments;
+			context = this;
+			if (!isQueued) {
+				isQueued = true;
+				requestAnimationFrame(function() {
+					cb.apply(context, args);
+					isQueued = false;
+				});
+			}
+		};
+	};
+
+})(mui, window);
+(function($) {
+	var initializing = false,
+		fnTest = /xyz/.test(function() {
+			xyz;
+		}) ? /\b_super\b/ : /.*/;
+
+	var Class = function() {};
+	Class.extend = function(prop) {
+		var _super = this.prototype;
+		initializing = true;
+		var prototype = new this();
+		initializing = false;
+		for (var name in prop) {
+			prototype[name] = typeof prop[name] == "function" &&
+				typeof _super[name] == "function" && fnTest.test(prop[name]) ?
+				(function(name, fn) {
+					return function() {
+						var tmp = this._super;
+
+						this._super = _super[name];
+
+						var ret = fn.apply(this, arguments);
+						this._super = tmp;
+
+						return ret;
+					};
+				})(name, prop[name]) :
+				prop[name];
+		}
+		function Class() {
+			if (!initializing && this.init)
+				this.init.apply(this, arguments);
+		}
+		Class.prototype = prototype;
+		Class.prototype.constructor = Class;
+		Class.extend = arguments.callee;
+		return Class;
+	};
+	$.Class = Class;
+})(mui);
+(function($, document, undefined) {
+    var CLASS_PULL_TOP_POCKET = 'mui-pull-top-pocket';
+    var CLASS_PULL_BOTTOM_POCKET = 'mui-pull-bottom-pocket';
+    var CLASS_PULL = 'mui-pull';
+    var CLASS_PULL_LOADING = 'mui-pull-loading';
+    var CLASS_PULL_CAPTION = 'mui-pull-caption';
+    var CLASS_PULL_CAPTION_DOWN = 'mui-pull-caption-down';
+    var CLASS_PULL_CAPTION_REFRESH = 'mui-pull-caption-refresh';
+    var CLASS_PULL_CAPTION_NOMORE = 'mui-pull-caption-nomore';
+
+    var CLASS_ICON = 'mui-icon';
+    var CLASS_SPINNER = 'mui-spinner';
+    var CLASS_ICON_PULLDOWN = 'mui-icon-pulldown';
+
+    var CLASS_BLOCK = 'mui-block';
+    var CLASS_HIDDEN = 'mui-hidden';
+    var CLASS_VISIBILITY = 'mui-visibility';
+
+    var CLASS_LOADING_UP = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_ICON_PULLDOWN;
+    var CLASS_LOADING_DOWN = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_ICON_PULLDOWN;
+    var CLASS_LOADING = CLASS_PULL_LOADING + ' ' + CLASS_ICON + ' ' + CLASS_SPINNER;
+
+    var pocketHtml = ['<div class="' + CLASS_PULL + '">', '<div class="{icon}"></div>', '<div class="' + CLASS_PULL_CAPTION + '">{contentrefresh}</div>', '</div>'].join('');
+
+    var PullRefresh = {
+        init: function(element, options) {
+            this._super(element, $.extend(true, {
+                scrollY: true,
+                scrollX: false,
+                indicators: true,
+                deceleration: 0.003,
+                down: {
+                    height: 50,
+                    contentinit: '下拉可以刷新',
+                    contentdown: '下拉可以刷新',
+                    contentover: '释放立即刷新',
+                    contentrefresh: '正在刷新...'
+                },
+                up: {
+                    height: 50,
+                    auto: false,
+                    contentinit: '上拉显示更多',
+                    contentdown: '上拉显示更多',
+                    contentrefresh: '正在加载...',
+                    contentnomore: '没有更多数据了',
+                    duration: 300
+                }
+            }, options));
+        },
+        _init: function() {
+            this._super();
+            this._initPocket();
+        },
+        _initPulldownRefresh: function() {
+            this.pulldown = true;
+            if (this.topPocket) {
+                this.pullPocket = this.topPocket;
+                this.pullPocket.classList.add(CLASS_BLOCK);
+                this.pullPocket.classList.add(CLASS_VISIBILITY);
+                this.pullCaption = this.topCaption;
+                this.pullLoading = this.topLoading;
+            }
+        },
+        _initPullupRefresh: function() {
+            this.pulldown = false;
+            if (this.bottomPocket) {
+                this.pullPocket = this.bottomPocket;
+                this.pullPocket.classList.add(CLASS_BLOCK);
+                this.pullPocket.classList.add(CLASS_VISIBILITY);
+                this.pullCaption = this.bottomCaption;
+                this.pullLoading = this.bottomLoading;
+            }
+        },
+        _initPocket: function() {
+            var options = this.options;
+            if (options.down && options.down.hasOwnProperty('callback')) {
+                this.topPocket = this.scroller.querySelector('.' + CLASS_PULL_TOP_POCKET);
+                if (!this.topPocket) {
+                    this.topPocket = this._createPocket(CLASS_PULL_TOP_POCKET, options.down, CLASS_LOADING_DOWN);
+                    this.wrapper.insertBefore(this.topPocket, this.wrapper.firstChild);
+                }
+                this.topLoading = this.topPocket.querySelector('.' + CLASS_PULL_LOADING);
+                this.topCaption = this.topPocket.querySelector('.' + CLASS_PULL_CAPTION);
+            }
+            if (options.up && options.up.hasOwnProperty('callback')) {
+                this.bottomPocket = this.scroller.querySelector('.' + CLASS_PULL_BOTTOM_POCKET);
+                if (!this.bottomPocket) {
+                    this.bottomPocket = this._createPocket(CLASS_PULL_BOTTOM_POCKET, options.up, CLASS_LOADING);
+                    this.scroller.appendChild(this.bottomPocket);
+                }
+                this.bottomLoading = this.bottomPocket.querySelector('.' + CLASS_PULL_LOADING);
+                this.bottomCaption = this.bottomPocket.querySelector('.' + CLASS_PULL_CAPTION);
+                //TODO only for h5
+                this.wrapper.addEventListener('scrollbottom', this);
+            }
+        },
+        _createPocket: function(clazz, options, iconClass) {
+            var pocket = document.createElement('div');
+            pocket.className = clazz;
+            pocket.innerHTML = pocketHtml.replace('{contentrefresh}', options.contentinit).replace('{icon}', iconClass);
+            return pocket;
+        },
+        _resetPullDownLoading: function() {
+            var loading = this.pullLoading;
+            if (loading) {
+                this.pullCaption.innerHTML = this.options.down.contentdown;
+                loading.style.webkitTransition = "";
+                loading.style.webkitTransform = "";
+                loading.style.webkitAnimation = "";
+                loading.className = CLASS_LOADING_DOWN;
+            }
+        },
+        _setCaptionClass: function(isPulldown, caption, title) {
+            if (!isPulldown) {
+                switch (title) {
+                    case this.options.up.contentdown:
+                        caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN;
+                        break;
+                    case this.options.up.contentrefresh:
+                        caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_REFRESH
+                        break;
+                    case this.options.up.contentnomore:
+                        caption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_NOMORE;
+                        break;
+                }
+            }
+        },
+        _setCaption: function(title, reset) {
+            if (this.loading) {
+                return;
+            }
+            var options = this.options;
+            var pocket = this.pullPocket;
+            var caption = this.pullCaption;
+            var loading = this.pullLoading;
+            var isPulldown = this.pulldown;
+            var self = this;
+            if (pocket) {
+                if (reset) {
+                    setTimeout(function() {
+                        caption.innerHTML = self.lastTitle = title;
+                        if (isPulldown) {
+                            loading.className = CLASS_LOADING_DOWN;
+                        } else {
+                            self._setCaptionClass(false, caption, title);
+                            loading.className = CLASS_LOADING;
+                        }
+                        loading.style.webkitAnimation = "";
+                        loading.style.webkitTransition = "";
+                        loading.style.webkitTransform = "";
+                    }, 100);
+                } else {
+                    if (title !== this.lastTitle) {
+                        caption.innerHTML = title;
+                        if (isPulldown) {
+                            if (title === options.down.contentrefresh) {
+                                loading.className = CLASS_LOADING;
+                                loading.style.webkitAnimation = "spinner-spin 1s step-end infinite";
+                            } else if (title === options.down.contentover) {
+                                loading.className = CLASS_LOADING_UP;
+                                loading.style.webkitTransition = "-webkit-transform 0.3s ease-in";
+                                loading.style.webkitTransform = "rotate(180deg)";
+                            } else if (title === options.down.contentdown) {
+                                loading.className = CLASS_LOADING_DOWN;
+                                loading.style.webkitTransition = "-webkit-transform 0.3s ease-in";
+                                loading.style.webkitTransform = "rotate(0deg)";
+                            }
+                        } else {
+                            if (title === options.up.contentrefresh) {
+                                loading.className = CLASS_LOADING + ' ' + CLASS_VISIBILITY;
+                            } else {
+                                loading.className = CLASS_LOADING + ' ' + CLASS_HIDDEN;
+                            }
+                            self._setCaptionClass(false, caption, title);
+                        }
+                        this.lastTitle = title;
+                    }
+                }
+
+            }
+        }
+    };
+    $.PullRefresh = PullRefresh;
+})(mui, document);
+(function($, window, document, undefined) {
+	var CLASS_SCROLL = 'mui-scroll';
+	var CLASS_SCROLLBAR = 'mui-scrollbar';
+	var CLASS_INDICATOR = 'mui-scrollbar-indicator';
+	var CLASS_SCROLLBAR_VERTICAL = CLASS_SCROLLBAR + '-vertical';
+	var CLASS_SCROLLBAR_HORIZONTAL = CLASS_SCROLLBAR + '-horizontal';
+
+	var CLASS_ACTIVE = 'mui-active';
+
+	var ease = {
+		quadratic: {
+			style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
+			fn: function(k) {
+				return k * (2 - k);
+			}
+		},
+		circular: {
+			style: 'cubic-bezier(0.1, 0.57, 0.1, 1)',
+			fn: function(k) {
+				return Math.sqrt(1 - (--k * k));
+			}
+		},
+		outCirc: {
+			style: 'cubic-bezier(0.075, 0.82, 0.165, 1)'
+		},
+		outCubic: {
+			style: 'cubic-bezier(0.165, 0.84, 0.44, 1)'
+		}
+	}
+	var Scroll = $.Class.extend({
+		init: function(element, options) {
+			this.wrapper = this.element = element;
+			this.scroller = this.wrapper.children[0];
+			this.scrollerStyle = this.scroller && this.scroller.style;
+			this.stopped = false;
+
+			this.options = $.extend(true, {
+				scrollY: true, //是否竖向滚动
+				scrollX: false, //是否横向滚动
+				startX: 0, //初始化时滚动至x
+				startY: 0, //初始化时滚动至y
+
+				indicators: true, //是否显示滚动条
+				stopPropagation: false,
+				hardwareAccelerated: true,
+				fixedBadAndorid: false,
+				preventDefaultException: {
+					tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/
+				},
+				momentum: true,
+
+				snapX: 0.5, //横向切换距离(以当前容器宽度为基准)
+				snap: false, //图片轮播,拖拽式选项卡
+
+				bounce: true, //是否启用回弹
+				bounceTime: 500, //回弹动画时间
+				bounceEasing: ease.outCirc, //回弹动画曲线
+
+				scrollTime: 500,
+				scrollEasing: ease.outCubic, //轮播动画曲线
+
+				directionLockThreshold: 5,
+
+				parallaxElement: false, //视差元素
+				parallaxRatio: 0.5
+			}, options);
+
+			this.x = 0;
+			this.y = 0;
+			this.translateZ = this.options.hardwareAccelerated ? ' translateZ(0)' : '';
+
+			this._init();
+			if (this.scroller) {
+				this.refresh();
+				//				if (this.options.startX !== 0 || this.options.startY !== 0) { //需要判断吗?后续根据实际情况再看看
+				this.scrollTo(this.options.startX, this.options.startY);
+				//				}
+			}
+		},
+		_init: function() {
+			this._initParallax();
+			this._initIndicators();
+			this._initEvent();
+		},
+		_initParallax: function() {
+			if (this.options.parallaxElement) {
+				this.parallaxElement = document.querySelector(this.options.parallaxElement);
+				this.parallaxStyle = this.parallaxElement.style;
+				this.parallaxHeight = this.parallaxElement.offsetHeight;
+				this.parallaxImgStyle = this.parallaxElement.querySelector('img').style;
+			}
+		},
+		_initIndicators: function() {
+			var self = this;
+			self.indicators = [];
+			if (!this.options.indicators) {
+				return;
+			}
+			var indicators = [],
+				indicator;
+
+			// Vertical scrollbar
+			if (self.options.scrollY) {
+				indicator = {
+					el: this._createScrollBar(CLASS_SCROLLBAR_VERTICAL),
+					listenX: false
+				};
+
+				this.wrapper.appendChild(indicator.el);
+				indicators.push(indicator);
+			}
+
+			// Horizontal scrollbar
+			if (this.options.scrollX) {
+				indicator = {
+					el: this._createScrollBar(CLASS_SCROLLBAR_HORIZONTAL),
+					listenY: false
+				};
+
+				this.wrapper.appendChild(indicator.el);
+				indicators.push(indicator);
+			}
+
+			for (var i = indicators.length; i--;) {
+				this.indicators.push(new Indicator(this, indicators[i]));
+			}
+
+		},
+		_initSnap: function() {
+			this.currentPage = {};
+			this.pages = [];
+			var snaps = this.snaps;
+			var length = snaps.length;
+			var m = 0;
+			var n = -1;
+			var x = 0;
+			var leftX = 0;
+			var rightX = 0;
+			var snapX = 0;
+			for (var i = 0; i < length; i++) {
+				var snap = snaps[i];
+				var offsetLeft = snap.offsetLeft;
+				var offsetWidth = snap.offsetWidth;
+				if (i === 0 || offsetLeft <= snaps[i - 1].offsetLeft) {
+					m = 0;
+					n++;
+				}
+				if (!this.pages[m]) {
+					this.pages[m] = [];
+				}
+				x = this._getSnapX(offsetLeft);
+				snapX = Math.round((offsetWidth) * this.options.snapX);
+				leftX = x - snapX;
+				rightX = x - offsetWidth + snapX;
+				this.pages[m][n] = {
+					x: x,
+					leftX: leftX,
+					rightX: rightX,
+					pageX: m,
+					element: snap
+				}
+				if (snap.classList.contains(CLASS_ACTIVE)) {
+					this.currentPage = this.pages[m][0];
+				}
+				if (x >= this.maxScrollX) {
+					m++;
+				}
+			}
+			this.options.startX = this.currentPage.x || 0;
+		},
+		_getSnapX: function(offsetLeft) {
+			return Math.max(Math.min(0, -offsetLeft + (this.wrapperWidth / 2)), this.maxScrollX);
+		},
+		_gotoPage: function(index) {
+			this.currentPage = this.pages[Math.min(index, this.pages.length - 1)][0];
+			for (var i = 0, len = this.snaps.length; i < len; i++) {
+				if (i === index) {
+					this.snaps[i].classList.add(CLASS_ACTIVE);
+				} else {
+					this.snaps[i].classList.remove(CLASS_ACTIVE);
+				}
+			}
+			this.scrollTo(this.currentPage.x, 0, this.options.scrollTime);
+		},
+		_nearestSnap: function(x) {
+			if (!this.pages.length) {
+				return {
+					x: 0,
+					pageX: 0
+				};
+			}
+			var i = 0;
+			var length = this.pages.length;
+			if (x > 0) {
+				x = 0;
+			} else if (x < this.maxScrollX) {
+				x = this.maxScrollX;
+			}
+			for (; i < length; i++) {
+				var nearestX = this.direction === 'left' ? this.pages[i][0].leftX : this.pages[i][0].rightX;
+				if (x >= nearestX) {
+					return this.pages[i][0];
+				}
+			}
+			return {
+				x: 0,
+				pageX: 0
+			};
+		},
+		_initEvent: function(detach) {
+			var action = detach ? 'removeEventListener' : 'addEventListener';
+			window[action]('orientationchange', this);
+			window[action]('resize', this);
+
+			this.scroller[action]('webkitTransitionEnd', this);
+
+			this.wrapper[action]($.EVENT_START, this);
+			this.wrapper[action]($.EVENT_CANCEL, this);
+			this.wrapper[action]($.EVENT_END, this);
+			this.wrapper[action]('drag', this);
+			this.wrapper[action]('dragend', this);
+			this.wrapper[action]('flick', this);
+			this.wrapper[action]('scrollend', this);
+			if (this.options.scrollX) {
+				this.wrapper[action]('swiperight', this);
+			}
+			var segmentedControl = this.wrapper.querySelector('.mui-segmented-control');
+			if (segmentedControl) { //靠,这个bug排查了一下午,阻止hash跳转,一旦hash跳转会导致可拖拽选项卡的tab不见
+				mui(segmentedControl)[detach ? 'off' : 'on']('click', 'a', $.preventDefault);
+			}
+
+			this.wrapper[action]('scrollstart', this);
+			this.wrapper[action]('refresh', this);
+		},
+		_handleIndicatorScrollend: function() {
+			this.indicators.map(function(indicator) {
+				indicator.fade();
+			});
+		},
+		_handleIndicatorScrollstart: function() {
+			this.indicators.map(function(indicator) {
+				indicator.fade(1);
+			});
+		},
+		_handleIndicatorRefresh: function() {
+			this.indicators.map(function(indicator) {
+				indicator.refresh();
+			});
+		},
+		handleEvent: function(e) {
+			if (this.stopped) {
+				this.resetPosition();
+				return;
+			}
+
+			switch (e.type) {
+				case $.EVENT_START:
+					this._start(e);
+					break;
+				case 'drag':
+					this.options.stopPropagation && e.stopPropagation();
+					this._drag(e);
+					break;
+				case 'dragend':
+				case 'flick':
+					this.options.stopPropagation && e.stopPropagation();
+					this._flick(e);
+					break;
+				case $.EVENT_CANCEL:
+				case $.EVENT_END:
+					this._end(e);
+					break;
+				case 'webkitTransitionEnd':
+					this.transitionTimer && this.transitionTimer.cancel();
+					this._transitionEnd(e);
+					break;
+				case 'scrollstart':
+					this._handleIndicatorScrollstart(e);
+					break;
+				case 'scrollend':
+					this._handleIndicatorScrollend(e);
+					this._scrollend(e);
+					e.stopPropagation();
+					break;
+				case 'orientationchange':
+				case 'resize':
+					this._resize();
+					break;
+				case 'swiperight':
+					e.stopPropagation();
+					break;
+				case 'refresh':
+					this._handleIndicatorRefresh(e);
+					break;
+
+			}
+		},
+		_start: function(e) {
+			this.moved = this.needReset = false;
+			this._transitionTime();
+			if (this.isInTransition) {
+				this.needReset = true;
+				this.isInTransition = false;
+				var pos = $.parseTranslateMatrix($.getStyles(this.scroller, 'webkitTransform'));
+				this.setTranslate(Math.round(pos.x), Math.round(pos.y));
+				//				this.resetPosition(); //reset
+				$.trigger(this.scroller, 'scrollend', this);
+				//				e.stopPropagation();
+				e.preventDefault();
+			}
+			this.reLayout();
+			$.trigger(this.scroller, 'beforescrollstart', this);
+		},
+		_getDirectionByAngle: function(angle) {
+			if (angle < -80 && angle > -100) {
+				return 'up';
+			} else if (angle >= 80 && angle < 100) {
+				return 'down';
+			} else if (angle >= 170 || angle <= -170) {
+				return 'left';
+			} else if (angle >= -35 && angle <= 10) {
+				return 'right';
+			}
+			return null;
+		},
+		_drag: function(e) {
+			//			if (this.needReset) {
+			//				e.stopPropagation(); //disable parent drag(nested scroller)
+			//				return;
+			//			}
+			var detail = e.detail;
+			if (this.options.scrollY || detail.direction === 'up' || detail.direction === 'down') { //如果是竖向滚动或手势方向是上或下
+				//ios8 hack
+				if ($.os.ios && parseFloat($.os.version) >= 8) { //多webview时,离开当前webview会导致后续touch事件不触发
+					var clientY = detail.gesture.touches[0].clientY;
+					//下拉刷新 or 上拉加载
+					if ((clientY + 10) > window.innerHeight || clientY < 10) {
+						this.resetPosition(this.options.bounceTime);
+						return;
+					}
+				}
+			}
+			var isPreventDefault = isReturn = false;
+			var direction = this._getDirectionByAngle(detail.angle);
+			if (detail.direction === 'left' || detail.direction === 'right') {
+				if (this.options.scrollX) {
+					isPreventDefault = true;
+					if (!this.moved) { //识别角度(该角度导致轮播不灵敏)
+						//						if (direction !== 'left' && direction !== 'right') {
+						//							isReturn = true;
+						//						} else {
+						$.gestures.session.lockDirection = true; //锁定方向
+						$.gestures.session.startDirection = detail.direction;
+						//						}
+					}
+				} else if (this.options.scrollY && !this.moved) {
+					isReturn = true;
+				}
+			} else if (detail.direction === 'up' || detail.direction === 'down') {
+				if (this.options.scrollY) {
+					isPreventDefault = true;
+					//					if (!this.moved) { //识别角度,竖向滚动似乎没必要进行小角度验证
+					//						if (direction !== 'up' && direction !== 'down') {
+					//							isReturn = true;
+					//						}
+					//					}
+					if (!this.moved) {
+						$.gestures.session.lockDirection = true; //锁定方向
+						$.gestures.session.startDirection = detail.direction;
+					}
+				} else if (this.options.scrollX && !this.moved) {
+					isReturn = true;
+				}
+			} else {
+				isReturn = true;
+			}
+			if (this.moved || isPreventDefault) {
+				e.stopPropagation(); //阻止冒泡(scroll类嵌套)
+				detail.gesture && detail.gesture.preventDefault();
+			}
+			if (isReturn) { //禁止非法方向滚动
+				return;
+			}
+			if (!this.moved) {
+				$.trigger(this.scroller, 'scrollstart', this);
+			} else {
+				e.stopPropagation(); //move期间阻止冒泡(scroll嵌套)
+			}
+			var deltaX = 0;
+			var deltaY = 0;
+			if (!this.moved) { //start
+				deltaX = detail.deltaX;
+				deltaY = detail.deltaY;
+			} else { //move
+				deltaX = detail.deltaX - $.gestures.session.prevTouch.deltaX;
+				deltaY = detail.deltaY - $.gestures.session.prevTouch.deltaY;
+			}
+			var absDeltaX = Math.abs(detail.deltaX);
+			var absDeltaY = Math.abs(detail.deltaY);
+			if (absDeltaX > absDeltaY + this.options.directionLockThreshold) {
+				deltaY = 0;
+			} else if (absDeltaY >= absDeltaX + this.options.directionLockThreshold) {
+				deltaX = 0;
+			}
+
+			deltaX = this.hasHorizontalScroll ? deltaX : 0;
+			deltaY = this.hasVerticalScroll ? deltaY : 0;
+			var newX = this.x + deltaX;
+			var newY = this.y + deltaY;
+			// Slow down if outside of the boundaries
+			if (newX > 0 || newX < this.maxScrollX) {
+				newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX;
+			}
+			if (newY > 0 || newY < this.maxScrollY) {
+				newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY;
+			}
+
+			if (!this.requestAnimationFrame) {
+				this._updateTranslate();
+			}
+			this.direction = detail.deltaX > 0 ? 'right' : 'left';
+			this.moved = true;
+			this.x = newX;
+			this.y = newY;
+			$.trigger(this.scroller, 'scroll', this);
+		},
+		_flick: function(e) {
+			//			if (!this.moved || this.needReset) {
+			//				return;
+			//			}
+			if (!this.moved) {
+				return;
+			}
+			e.stopPropagation();
+			var detail = e.detail;
+			this._clearRequestAnimationFrame();
+			if (e.type === 'dragend' && detail.flick) { //dragend
+				return;
+			}
+
+			var newX = Math.round(this.x);
+			var newY = Math.round(this.y);
+
+			this.isInTransition = false;
+			// reset if we are outside of the boundaries
+			if (this.resetPosition(this.options.bounceTime)) {
+				return;
+			}
+
+			this.scrollTo(newX, newY); // ensures that the last position is rounded
+
+			if (e.type === 'dragend') { //dragend
+				$.trigger(this.scroller, 'scrollend', this);
+				return;
+			}
+			var time = 0;
+			var easing = '';
+			// start momentum animation if needed
+			if (this.options.momentum && detail.flickTime < 300) {
+				momentumX = this.hasHorizontalScroll ? this._momentum(this.x, detail.flickDistanceX, detail.flickTime, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options.deceleration) : {
+					destination: newX,
+					duration: 0
+				};
+				momentumY = this.hasVerticalScroll ? this._momentum(this.y, detail.flickDistanceY, detail.flickTime, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration) : {
+					destination: newY,
+					duration: 0
+				};
+				newX = momentumX.destination;
+				newY = momentumY.destination;
+				time = Math.max(momentumX.duration, momentumY.duration);
+				this.isInTransition = true;
+			}
+
+			if (newX != this.x || newY != this.y) {
+				if (newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY) {
+					easing = ease.quadratic;
+				}
+				this.scrollTo(newX, newY, time, easing);
+				return;
+			}
+
+			$.trigger(this.scroller, 'scrollend', this);
+			//			e.stopPropagation();
+		},
+		_end: function(e) {
+			this.needReset = false;
+			if ((!this.moved && this.needReset) || e.type === $.EVENT_CANCEL) {
+				this.resetPosition();
+			}
+		},
+		_transitionEnd: function(e) {
+			if (e.target != this.scroller || !this.isInTransition) {
+				return;
+			}
+			this._transitionTime();
+			if (!this.resetPosition(this.options.bounceTime)) {
+				this.isInTransition = false;
+				$.trigger(this.scroller, 'scrollend', this);
+			}
+		},
+		_scrollend: function(e) {
+			if ((this.y === 0 && this.maxScrollY === 0) || (Math.abs(this.y) > 0 && this.y <= this.maxScrollY)) {
+				$.trigger(this.scroller, 'scrollbottom', this);
+			}
+		},
+		_resize: function() {
+			var that = this;
+			clearTimeout(that.resizeTimeout);
+			that.resizeTimeout = setTimeout(function() {
+				that.refresh();
+			}, that.options.resizePolling);
+		},
+		_transitionTime: function(time) {
+			time = time || 0;
+			this.scrollerStyle['webkitTransitionDuration'] = time + 'ms';
+			if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果
+				this.parallaxStyle['webkitTransitionDuration'] = time + 'ms';
+			}
+			if (this.options.fixedBadAndorid && !time && $.os.isBadAndroid) {
+				this.scrollerStyle['webkitTransitionDuration'] = '0.001s';
+				if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果
+					this.parallaxStyle['webkitTransitionDuration'] = '0.001s';
+				}
+			}
+			if (this.indicators) {
+				for (var i = this.indicators.length; i--;) {
+					this.indicators[i].transitionTime(time);
+				}
+			}
+			if (time) { //自定义timer,保证webkitTransitionEnd始终触发
+				this.transitionTimer && this.transitionTimer.cancel();
+				this.transitionTimer = $.later(function() {
+					$.trigger(this.scroller, 'webkitTransitionEnd');
+				}, time + 100, this);
+			}
+		},
+		_transitionTimingFunction: function(easing) {
+			this.scrollerStyle['webkitTransitionTimingFunction'] = easing;
+			if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果
+				this.parallaxStyle['webkitTransitionDuration'] = easing;
+			}
+			if (this.indicators) {
+				for (var i = this.indicators.length; i--;) {
+					this.indicators[i].transitionTimingFunction(easing);
+				}
+			}
+		},
+		_translate: function(x, y) {
+			this.x = x;
+			this.y = y;
+		},
+		_clearRequestAnimationFrame: function() {
+			if (this.requestAnimationFrame) {
+				cancelAnimationFrame(this.requestAnimationFrame);
+				this.requestAnimationFrame = null;
+			}
+		},
+		_updateTranslate: function() {
+			var self = this;
+			if (self.x !== self.lastX || self.y !== self.lastY) {
+				self.setTranslate(self.x, self.y);
+			}
+			self.requestAnimationFrame = requestAnimationFrame(function() {
+				self._updateTranslate();
+			});
+		},
+		_createScrollBar: function(clazz) {
+			var scrollbar = document.createElement('div');
+			var indicator = document.createElement('div');
+			scrollbar.className = CLASS_SCROLLBAR + ' ' + clazz;
+			indicator.className = CLASS_INDICATOR;
+			scrollbar.appendChild(indicator);
+			if (clazz === CLASS_SCROLLBAR_VERTICAL) {
+				this.scrollbarY = scrollbar;
+				this.scrollbarIndicatorY = indicator;
+			} else if (clazz === CLASS_SCROLLBAR_HORIZONTAL) {
+				this.scrollbarX = scrollbar;
+				this.scrollbarIndicatorX = indicator;
+			}
+			this.wrapper.appendChild(scrollbar);
+			return scrollbar;
+		},
+		_preventDefaultException: function(el, exceptions) {
+			for (var i in exceptions) {
+				if (exceptions[i].test(el[i])) {
+					return true;
+				}
+			}
+			return false;
+		},
+		_reLayout: function() {
+			if (!this.hasHorizontalScroll) {
+				this.maxScrollX = 0;
+				this.scrollerWidth = this.wrapperWidth;
+			}
+
+			if (!this.hasVerticalScroll) {
+				this.maxScrollY = 0;
+				this.scrollerHeight = this.wrapperHeight;
+			}
+
+			this.indicators.map(function(indicator) {
+				indicator.refresh();
+			});
+
+			//以防slider类嵌套使用
+			if (this.options.snap && typeof this.options.snap === 'string') {
+				var items = this.scroller.querySelectorAll(this.options.snap);
+				this.itemLength = 0;
+				this.snaps = [];
+				for (var i = 0, len = items.length; i < len; i++) {
+					var item = items[i];
+					if (item.parentNode === this.scroller) {
+						this.itemLength++;
+						this.snaps.push(item);
+					}
+				}
+				this._initSnap(); //需要每次都_initSnap么。其实init的时候执行一次,后续resize的时候执行一次就行了吧.先这么做吧,如果影响性能,再调整
+			}
+		},
+		_momentum: function(current, distance, time, lowerMargin, wrapperSize, deceleration) {
+			var speed = parseFloat(Math.abs(distance) / time),
+				destination,
+				duration;
+
+			deceleration = deceleration === undefined ? 0.0006 : deceleration;
+			destination = current + (speed * speed) / (2 * deceleration) * (distance < 0 ? -1 : 1);
+			duration = speed / deceleration;
+			if (destination < lowerMargin) {
+				destination = wrapperSize ? lowerMargin - (wrapperSize / 2.5 * (speed / 8)) : lowerMargin;
+				distance = Math.abs(destination - current);
+				duration = distance / speed;
+			} else if (destination > 0) {
+				destination = wrapperSize ? wrapperSize / 2.5 * (speed / 8) : 0;
+				distance = Math.abs(current) + destination;
+				duration = distance / speed;
+			}
+
+			return {
+				destination: Math.round(destination),
+				duration: duration
+			};
+		},
+		_getTranslateStr: function(x, y) {
+			if (this.options.hardwareAccelerated) {
+				return 'translate3d(' + x + 'px,' + y + 'px,0px) ' + this.translateZ;
+			}
+			return 'translate(' + x + 'px,' + y + 'px) ';
+		},
+		//API
+		setStopped: function(stopped) {
+			// this.stopped = !!stopped;
+
+			// fixed ios双webview模式下拉刷新
+			if(stopped) {
+				this.disablePullupToRefresh();
+				this.disablePulldownToRefresh();
+			} else {
+				this.enablePullupToRefresh();
+				this.enablePulldownToRefresh();
+			}
+		},
+		setTranslate: function(x, y) {
+			this.x = x;
+			this.y = y;
+			this.scrollerStyle['webkitTransform'] = this._getTranslateStr(x, y);
+			if (this.parallaxElement && this.options.scrollY) { //目前仅支持竖向视差效果
+				var parallaxY = y * this.options.parallaxRatio;
+				var scale = 1 + parallaxY / ((this.parallaxHeight - parallaxY) / 2);
+				if (scale > 1) {
+					this.parallaxImgStyle['opacity'] = 1 - parallaxY / 100 * this.options.parallaxRatio;
+					this.parallaxStyle['webkitTransform'] = this._getTranslateStr(0, -parallaxY) + ' scale(' + scale + ',' + scale + ')';
+				} else {
+					this.parallaxImgStyle['opacity'] = 1;
+					this.parallaxStyle['webkitTransform'] = this._getTranslateStr(0, -1) + ' scale(1,1)';
+				}
+			}
+			if (this.indicators) {
+				for (var i = this.indicators.length; i--;) {
+					this.indicators[i].updatePosition();
+				}
+			}
+			this.lastX = this.x;
+			this.lastY = this.y;
+			$.trigger(this.scroller, 'scroll', this);
+		},
+		reLayout: function() {
+			this.wrapper.offsetHeight;
+
+			var paddingLeft = parseFloat($.getStyles(this.wrapper, 'padding-left')) || 0;
+			var paddingRight = parseFloat($.getStyles(this.wrapper, 'padding-right')) || 0;
+			var paddingTop = parseFloat($.getStyles(this.wrapper, 'padding-top')) || 0;
+			var paddingBottom = parseFloat($.getStyles(this.wrapper, 'padding-bottom')) || 0;
+
+			var clientWidth = this.wrapper.clientWidth;
+			var clientHeight = this.wrapper.clientHeight;
+
+			this.scrollerWidth = this.scroller.offsetWidth;
+			this.scrollerHeight = this.scroller.offsetHeight;
+
+			this.wrapperWidth = clientWidth - paddingLeft - paddingRight;
+			this.wrapperHeight = clientHeight - paddingTop - paddingBottom;
+
+			this.maxScrollX = Math.min(this.wrapperWidth - this.scrollerWidth, 0);
+			this.maxScrollY = Math.min(this.wrapperHeight - this.scrollerHeight, 0);
+			this.hasHorizontalScroll = this.options.scrollX && this.maxScrollX < 0;
+			this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0;
+			this._reLayout();
+		},
+		resetPosition: function(time) {
+			var x = this.x,
+				y = this.y;
+
+			time = time || 0;
+			if (!this.hasHorizontalScroll || this.x > 0) {
+				x = 0;
+			} else if (this.x < this.maxScrollX) {
+				x = this.maxScrollX;
+			}
+
+			if (!this.hasVerticalScroll || this.y > 0) {
+				y = 0;
+			} else if (this.y < this.maxScrollY) {
+				y = this.maxScrollY;
+			}
+
+			if (x == this.x && y == this.y) {
+				return false;
+			}
+			this.scrollTo(x, y, time, this.options.scrollEasing);
+
+			return true;
+		},
+		_reInit: function() {
+			var groups = this.wrapper.querySelectorAll('.' + CLASS_SCROLL);
+			for (var i = 0, len = groups.length; i < len; i++) {
+				if (groups[i].parentNode === this.wrapper) {
+					this.scroller = groups[i];
+					break;
+				}
+			}
+			this.scrollerStyle = this.scroller && this.scroller.style;
+		},
+		refresh: function() {
+			this._reInit();
+			this.reLayout();
+			$.trigger(this.scroller, 'refresh', this);
+			this.resetPosition();
+		},
+		scrollTo: function(x, y, time, easing) {
+			var easing = easing || ease.circular;
+			//			this.isInTransition = time > 0 && (this.lastX != x || this.lastY != y);
+			//暂不严格判断x,y,否则会导致部分版本上不正常触发轮播
+			this.isInTransition = time > 0;
+			if (this.isInTransition) {
+				this._clearRequestAnimationFrame();
+				this._transitionTimingFunction(easing.style);
+				this._transitionTime(time);
+				this.setTranslate(x, y);
+			} else {
+				this.setTranslate(x, y);
+			}
+
+		},
+		scrollToBottom: function(time, easing) {
+			time = time || this.options.scrollTime;
+			this.scrollTo(0, this.maxScrollY, time, easing);
+		},
+		gotoPage: function(index) {
+			this._gotoPage(index);
+		},
+		destroy: function() {
+			this._initEvent(true); //detach
+			delete $.data[this.wrapper.getAttribute('data-scroll')];
+			this.wrapper.setAttribute('data-scroll', '');
+		}
+	});
+	//Indicator
+	var Indicator = function(scroller, options) {
+		this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el;
+		this.wrapperStyle = this.wrapper.style;
+		this.indicator = this.wrapper.children[0];
+		this.indicatorStyle = this.indicator.style;
+		this.scroller = scroller;
+
+		this.options = $.extend({
+			listenX: true,
+			listenY: true,
+			fade: false,
+			speedRatioX: 0,
+			speedRatioY: 0
+		}, options);
+
+		this.sizeRatioX = 1;
+		this.sizeRatioY = 1;
+		this.maxPosX = 0;
+		this.maxPosY = 0;
+
+		if (this.options.fade) {
+			this.wrapperStyle['webkitTransform'] = this.scroller.translateZ;
+			this.wrapperStyle['webkitTransitionDuration'] = this.options.fixedBadAndorid && $.os.isBadAndroid ? '0.001s' : '0ms';
+			this.wrapperStyle.opacity = '0';
+		}
+	}
+	Indicator.prototype = {
+		handleEvent: function(e) {
+
+		},
+		transitionTime: function(time) {
+			time = time || 0;
+			this.indicatorStyle['webkitTransitionDuration'] = time + 'ms';
+			if (this.scroller.options.fixedBadAndorid && !time && $.os.isBadAndroid) {
+				this.indicatorStyle['webkitTransitionDuration'] = '0.001s';
+			}
+		},
+		transitionTimingFunction: function(easing) {
+			this.indicatorStyle['webkitTransitionTimingFunction'] = easing;
+		},
+		refresh: function() {
+			this.transitionTime();
+
+			if (this.options.listenX && !this.options.listenY) {
+				this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none';
+			} else if (this.options.listenY && !this.options.listenX) {
+				this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none';
+			} else {
+				this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none';
+			}
+
+			this.wrapper.offsetHeight; // force refresh
+
+			if (this.options.listenX) {
+				this.wrapperWidth = this.wrapper.clientWidth;
+				this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8);
+				this.indicatorStyle.width = this.indicatorWidth + 'px';
+
+				this.maxPosX = this.wrapperWidth - this.indicatorWidth;
+
+				this.minBoundaryX = 0;
+				this.maxBoundaryX = this.maxPosX;
+
+				this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX));
+			}
+
+			if (this.options.listenY) {
+				this.wrapperHeight = this.wrapper.clientHeight;
+				this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8);
+				this.indicatorStyle.height = this.indicatorHeight + 'px';
+
+				this.maxPosY = this.wrapperHeight - this.indicatorHeight;
+
+				this.minBoundaryY = 0;
+				this.maxBoundaryY = this.maxPosY;
+
+				this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY));
+			}
+
+			this.updatePosition();
+		},
+
+		updatePosition: function() {
+			var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0,
+				y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0;
+
+			if (x < this.minBoundaryX) {
+				this.width = Math.max(this.indicatorWidth + x, 8);
+				this.indicatorStyle.width = this.width + 'px';
+				x = this.minBoundaryX;
+			} else if (x > this.maxBoundaryX) {
+				this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8);
+				this.indicatorStyle.width = this.width + 'px';
+				x = this.maxPosX + this.indicatorWidth - this.width;
+			} else if (this.width != this.indicatorWidth) {
+				this.width = this.indicatorWidth;
+				this.indicatorStyle.width = this.width + 'px';
+			}
+
+			if (y < this.minBoundaryY) {
+				this.height = Math.max(this.indicatorHeight + y * 3, 8);
+				this.indicatorStyle.height = this.height + 'px';
+				y = this.minBoundaryY;
+			} else if (y > this.maxBoundaryY) {
+				this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8);
+				this.indicatorStyle.height = this.height + 'px';
+				y = this.maxPosY + this.indicatorHeight - this.height;
+			} else if (this.height != this.indicatorHeight) {
+				this.height = this.indicatorHeight;
+				this.indicatorStyle.height = this.height + 'px';
+			}
+
+			this.x = x;
+			this.y = y;
+
+			this.indicatorStyle['webkitTransform'] = this.scroller._getTranslateStr(x, y);
+
+		},
+		fade: function(val, hold) {
+			if (hold && !this.visible) {
+				return;
+			}
+
+			clearTimeout(this.fadeTimeout);
+			this.fadeTimeout = null;
+
+			var time = val ? 250 : 500,
+				delay = val ? 0 : 300;
+
+			val = val ? '1' : '0';
+
+			this.wrapperStyle['webkitTransitionDuration'] = time + 'ms';
+
+			this.fadeTimeout = setTimeout((function(val) {
+				this.wrapperStyle.opacity = val;
+				this.visible = +val;
+			}).bind(this, val), delay);
+		}
+	};
+
+	$.Scroll = Scroll;
+
+	$.fn.scroll = function(options) {
+		var scrollApis = [];
+		this.each(function() {
+			var scrollApi = null;
+			var self = this;
+			var id = self.getAttribute('data-scroll');
+			if (!id) {
+				id = ++$.uuid;
+				var _options = $.extend({}, options);
+				if (self.classList.contains('mui-segmented-control')) {
+					_options = $.extend(_options, {
+						scrollY: false,
+						scrollX: true,
+						indicators: false,
+						snap: '.mui-control-item'
+					});
+				}
+				$.data[id] = scrollApi = new Scroll(self, _options);
+				self.setAttribute('data-scroll', id);
+			} else {
+				scrollApi = $.data[id];
+			}
+			scrollApis.push(scrollApi);
+		});
+		return scrollApis.length === 1 ? scrollApis[0] : scrollApis;
+	};
+})(mui, window, document);
+(function($, window, document, undefined) {
+
+    var CLASS_VISIBILITY = 'mui-visibility';
+    var CLASS_HIDDEN = 'mui-hidden';
+
+    var PullRefresh = $.Scroll.extend($.extend({
+        handleEvent: function(e) {
+            this._super(e);
+            if (e.type === 'scrollbottom') {
+                if (e.target === this.scroller) {
+                    this._scrollbottom();
+                }
+            }
+        },
+        _scrollbottom: function() {
+            if (!this.pulldown && !this.loading) {
+                this.pulldown = false;
+                this._initPullupRefresh();
+                this.pullupLoading();
+            }
+        },
+        _start: function(e) {
+            //仅下拉刷新在start阻止默认事件
+            if (e.touches && e.touches.length && e.touches[0].clientX > 30) {
+                e.target && !this._preventDefaultException(e.target, this.options.preventDefaultException) && e.preventDefault();
+            }
+            if (!this.loading) {
+                this.pulldown = this.pullPocket = this.pullCaption = this.pullLoading = false
+            }
+            this._super(e);
+        },
+        _drag: function(e) {
+            if (this.y >= 0 && this.disablePulldown && e.detail.direction === 'down') { //禁用下拉刷新
+                return;
+            }
+            this._super(e);
+            if (!this.pulldown && !this.loading && this.topPocket && e.detail.direction === 'down' && this.y >= 0) {
+                this._initPulldownRefresh();
+            }
+            if (this.pulldown) {
+                this._setCaption(this.y > this.options.down.height ? this.options.down.contentover : this.options.down.contentdown);
+            }
+        },
+
+        _reLayout: function() {
+            this.hasVerticalScroll = true;
+            this._super();
+        },
+        //API
+        resetPosition: function(time) {
+            if (this.pulldown && !this.disablePulldown) {
+                if (this.y >= this.options.down.height) {
+                    this.pulldownLoading(undefined, time || 0);
+                    return true;
+                } else {
+                    !this.loading && this.topPocket.classList.remove(CLASS_VISIBILITY);
+                }
+            }
+            return this._super(time);
+        },
+        pulldownLoading: function(y, time) {
+            typeof y === 'undefined' && (y = this.options.down.height); //默认高度
+            this.scrollTo(0, y, time, this.options.bounceEasing);
+            if (this.loading) {
+                return;
+            }
+            //			if (!this.pulldown) {
+            this._initPulldownRefresh();
+            //			}
+            this._setCaption(this.options.down.contentrefresh);
+            this.loading = true;
+            this.indicators.map(function(indicator) {
+                indicator.fade(0);
+            });
+            var callback = this.options.down.callback;
+            callback && callback.call(this);
+        },
+        endPulldownToRefresh: function() {
+            var self = this;
+            if (self.topPocket && self.loading && this.pulldown) {
+                self.scrollTo(0, 0, self.options.bounceTime, self.options.bounceEasing);
+                self.loading = false;
+                self._setCaption(self.options.down.contentdown, true);
+                setTimeout(function() {
+                    self.loading || self.topPocket.classList.remove(CLASS_VISIBILITY);
+                }, 350);
+            }
+        },
+        pullupLoading: function(callback, x, time) {
+            x = x || 0;
+            this.scrollTo(x, this.maxScrollY, time, this.options.bounceEasing);
+            if (this.loading) {
+                return;
+            }
+            this._initPullupRefresh();
+            this._setCaption(this.options.up.contentrefresh);
+            this.indicators.map(function(indicator) {
+                indicator.fade(0);
+            });
+            this.loading = true;
+            callback = callback || this.options.up.callback;
+            callback && callback.call(this);
+        },
+        endPullupToRefresh: function(finished) {
+            var self = this;
+            if (self.bottomPocket) { // && self.loading && !this.pulldown
+                self.loading = false;
+                if (finished) {
+                    this.finished = true;
+                    self._setCaption(self.options.up.contentnomore);
+                    //					self.bottomPocket.classList.remove(CLASS_VISIBILITY);
+                    //					self.bottomPocket.classList.add(CLASS_HIDDEN);
+                    self.wrapper.removeEventListener('scrollbottom', self);
+                } else {
+                    self._setCaption(self.options.up.contentdown);
+                    //					setTimeout(function() {
+                    self.loading || self.bottomPocket.classList.remove(CLASS_VISIBILITY);
+                    //					}, 300);
+                }
+            }
+        },
+        disablePullupToRefresh: function() {
+            this._initPullupRefresh();
+            this.bottomPocket.className = 'mui-pull-bottom-pocket' + ' ' + CLASS_HIDDEN;
+            this.wrapper.removeEventListener('scrollbottom', this);
+        },
+        disablePulldownToRefresh: function() {
+            this._initPulldownRefresh();
+            this.topPocket.className = 'mui-pull-top-pocket' + ' ' + CLASS_HIDDEN;
+            this.disablePulldown = true;
+        },
+        enablePulldownToRefresh: function() {
+            this._initPulldownRefresh();
+            this.topPocket.classList.remove(CLASS_HIDDEN);
+            this._setCaption(this.options.down.contentdown);
+            this.disablePulldown = false;
+        },
+        enablePullupToRefresh: function() {
+            this._initPullupRefresh();
+            this.bottomPocket.classList.remove(CLASS_HIDDEN);
+            this._setCaption(this.options.up.contentdown);
+            this.wrapper.addEventListener('scrollbottom', this);
+        },
+        refresh: function(isReset) {
+            if (isReset && this.finished) {
+                this.enablePullupToRefresh();
+                this.finished = false;
+            }
+            this._super();
+        },
+    }, $.PullRefresh));
+    $.fn.pullRefresh = function(options) {
+        if (this.length === 1) {
+            var self = this[0];
+            var pullRefreshApi = null;
+            var id = self.getAttribute('data-pullrefresh');
+            if (!id && typeof options === 'undefined') {
+                return false;
+            }
+            options = options || {};
+            if (!id) {
+                id = ++$.uuid;
+                $.data[id] = pullRefreshApi = new PullRefresh(self, options);
+                self.setAttribute('data-pullrefresh', id);
+            } else {
+                pullRefreshApi = $.data[id];
+            }
+            if (options.down && options.down.auto) { //如果设置了auto,则自动下拉一次
+                pullRefreshApi.pulldownLoading(options.down.autoY);
+            } else if (options.up && options.up.auto) { //如果设置了auto,则自动上拉一次
+                pullRefreshApi.pullupLoading();
+            }
+            //暂不提供这种调用方式吧			
+            //			if (typeof options === 'string') {
+            //				var methodValue = pullRefreshApi[options].apply(pullRefreshApi, $.slice.call(arguments, 1));
+            //				if (methodValue !== undefined) {
+            //					return methodValue;
+            //				}
+            //			}
+            return pullRefreshApi;
+        }
+    };
+})(mui, window, document);
+/**
+ * snap 重构
+ * @param {Object} $
+ * @param {Object} window
+ */
+(function($, window) {
+	var CLASS_SLIDER = 'mui-slider';
+	var CLASS_SLIDER_GROUP = 'mui-slider-group';
+	var CLASS_SLIDER_LOOP = 'mui-slider-loop';
+	var CLASS_SLIDER_INDICATOR = 'mui-slider-indicator';
+	var CLASS_ACTION_PREVIOUS = 'mui-action-previous';
+	var CLASS_ACTION_NEXT = 'mui-action-next';
+	var CLASS_SLIDER_ITEM = 'mui-slider-item';
+
+	var CLASS_ACTIVE = 'mui-active';
+
+	var SELECTOR_SLIDER_ITEM = '.' + CLASS_SLIDER_ITEM;
+	var SELECTOR_SLIDER_INDICATOR = '.' + CLASS_SLIDER_INDICATOR;
+	var SELECTOR_SLIDER_PROGRESS_BAR = '.mui-slider-progress-bar';
+
+	var Slider = $.Slider = $.Scroll.extend({
+		init: function(element, options) {
+			this._super(element, $.extend(true, {
+				fingers: 1,
+				interval: 0, //设置为0,则不定时轮播
+				scrollY: false,
+				scrollX: true,
+				indicators: false,
+				scrollTime: 1000,
+				startX: false,
+				slideTime: 0, //滑动动画时间
+				snap: SELECTOR_SLIDER_ITEM
+			}, options));
+			if (this.options.startX) {
+				//				$.trigger(this.wrapper, 'scrollend', this);
+			}
+		},
+		_init: function() {
+			this._reInit();
+			if (this.scroller) {
+				this.scrollerStyle = this.scroller.style;
+				this.progressBar = this.wrapper.querySelector(SELECTOR_SLIDER_PROGRESS_BAR);
+				if (this.progressBar) {
+					this.progressBarWidth = this.progressBar.offsetWidth;
+					this.progressBarStyle = this.progressBar.style;
+				}
+				//忘记这个代码是干什么的了?
+				//				this.x = this._getScroll();
+				//				if (this.options.startX === false) {
+				//					this.options.startX = this.x;
+				//				}
+				//根据active修正startX
+
+				this._super();
+				this._initTimer();
+			}
+		},
+		_triggerSlide: function() {
+			var self = this;
+			self.isInTransition = false;
+			var page = self.currentPage;
+			self.slideNumber = self._fixedSlideNumber();
+			if (self.loop) {
+				if (self.slideNumber === 0) {
+					self.setTranslate(self.pages[1][0].x, 0);
+				} else if (self.slideNumber === self.itemLength - 3) {
+					self.setTranslate(self.pages[self.itemLength - 2][0].x, 0);
+				}
+			}
+			if (self.lastSlideNumber != self.slideNumber) {
+				self.lastSlideNumber = self.slideNumber;
+				self.lastPage = self.currentPage;
+				$.trigger(self.wrapper, 'slide', {
+					slideNumber: self.slideNumber
+				});
+			}
+			self._initTimer();
+		},
+		_handleSlide: function(e) {
+			var self = this;
+			if (e.target !== self.wrapper) {
+				return;
+			}
+			var detail = e.detail;
+			detail.slideNumber = detail.slideNumber || 0;
+			var temps = self.scroller.querySelectorAll(SELECTOR_SLIDER_ITEM);
+			var items = [];
+			for (var i = 0, len = temps.length; i < len; i++) {
+				var item = temps[i];
+				if (item.parentNode === self.scroller) {
+					items.push(item);
+				}
+			}
+			var _slideNumber = detail.slideNumber;
+			if (self.loop) {
+				_slideNumber += 1;
+			}
+			if (!self.wrapper.classList.contains('mui-segmented-control')) {
+				for (var i = 0, len = items.length; i < len; i++) {
+					var item = items[i];
+					if (item.parentNode === self.scroller) {
+						if (i === _slideNumber) {
+							item.classList.add(CLASS_ACTIVE);
+						} else {
+							item.classList.remove(CLASS_ACTIVE);
+						}
+					}
+				}
+			}
+			var indicatorWrap = self.wrapper.querySelector('.mui-slider-indicator');
+			if (indicatorWrap) {
+				if (indicatorWrap.getAttribute('data-scroll')) { //scroll
+					$(indicatorWrap).scroll().gotoPage(detail.slideNumber);
+				}
+				var indicators = indicatorWrap.querySelectorAll('.mui-indicator');
+				if (indicators.length > 0) { //图片轮播
+					for (var i = 0, len = indicators.length; i < len; i++) {
+						indicators[i].classList[i === detail.slideNumber ? 'add' : 'remove'](CLASS_ACTIVE);
+					}
+				} else {
+					var number = indicatorWrap.querySelector('.mui-number span');
+					if (number) { //图文表格
+						number.innerText = (detail.slideNumber + 1);
+					} else { //segmented controls
+						var controlItems = indicatorWrap.querySelectorAll('.mui-control-item');
+						for (var i = 0, len = controlItems.length; i < len; i++) {
+							controlItems[i].classList[i === detail.slideNumber ? 'add' : 'remove'](CLASS_ACTIVE);
+						}
+					}
+				}
+			}
+			e.stopPropagation();
+		},
+		_handleTabShow: function(e) {
+			var self = this;
+			self.gotoItem((e.detail.tabNumber || 0), self.options.slideTime);
+		},
+		_handleIndicatorTap: function(event) {
+			var self = this;
+			var target = event.target;
+			if (target.classList.contains(CLASS_ACTION_PREVIOUS) || target.classList.contains(CLASS_ACTION_NEXT)) {
+				self[target.classList.contains(CLASS_ACTION_PREVIOUS) ? 'prevItem' : 'nextItem']();
+				event.stopPropagation();
+			}
+		},
+		_initEvent: function(detach) {
+			var self = this;
+			self._super(detach);
+			var action = detach ? 'removeEventListener' : 'addEventListener';
+			self.wrapper[action]('slide', this);
+			self.wrapper[action]($.eventName('shown', 'tab'), this);
+		},
+		handleEvent: function(e) {
+			this._super(e);
+			switch (e.type) {
+				case 'slide':
+					this._handleSlide(e);
+					break;
+				case $.eventName('shown', 'tab'):
+					if (~this.snaps.indexOf(e.target)) { //避免嵌套监听错误的tab show
+						this._handleTabShow(e);
+					}
+					break;
+			}
+		},
+		_scrollend: function(e) {
+			this._super(e);
+			this._triggerSlide(e);
+		},
+		_drag: function(e) {
+			this._super(e);
+			var direction = e.detail.direction;
+			if (direction === 'left' || direction === 'right') {
+				//拖拽期间取消定时
+				var slidershowTimer = this.wrapper.getAttribute('data-slidershowTimer');
+				slidershowTimer && window.clearTimeout(slidershowTimer);
+
+				e.stopPropagation();
+			}
+		},
+		_initTimer: function() {
+			var self = this;
+			var slider = self.wrapper;
+			var interval = self.options.interval;
+			var slidershowTimer = slider.getAttribute('data-slidershowTimer');
+			slidershowTimer && window.clearTimeout(slidershowTimer);
+			if (interval) {
+				slidershowTimer = window.setTimeout(function() {
+					if (!slider) {
+						return;
+					}
+					//仅slider显示状态进行自动轮播
+					if (!!(slider.offsetWidth || slider.offsetHeight)) {
+						self.nextItem(true);
+						//下一个
+					}
+					self._initTimer();
+				}, interval);
+				slider.setAttribute('data-slidershowTimer', slidershowTimer);
+			}
+		},
+
+		_fixedSlideNumber: function(page) {
+			page = page || this.currentPage;
+			var slideNumber = page.pageX;
+			if (this.loop) {
+				if (page.pageX === 0) {
+					slideNumber = this.itemLength - 3;
+				} else if (page.pageX === (this.itemLength - 1)) {
+					slideNumber = 0;
+				} else {
+					slideNumber = page.pageX - 1;
+				}
+			}
+			return slideNumber;
+		},
+		_reLayout: function() {
+			this.hasHorizontalScroll = true;
+			this.loop = this.scroller.classList.contains(CLASS_SLIDER_LOOP);
+			this._super();
+		},
+		_getScroll: function() {
+			var result = $.parseTranslateMatrix($.getStyles(this.scroller, 'webkitTransform'));
+			return result ? result.x : 0;
+		},
+		_transitionEnd: function(e) {
+			if (e.target !== this.scroller || !this.isInTransition) {
+				return;
+			}
+			this._transitionTime();
+			this.isInTransition = false;
+			$.trigger(this.wrapper, 'scrollend', this);
+		},
+		_flick: function(e) {
+			if (!this.moved) { //无moved
+				return;
+			}
+			var detail = e.detail;
+			var direction = detail.direction;
+			this._clearRequestAnimationFrame();
+			this.isInTransition = true;
+			//			if (direction === 'up' || direction === 'down') {
+			//				this.resetPosition(this.options.bounceTime);
+			//				return;
+			//			}
+			if (e.type === 'flick') {
+				if (detail.deltaTime < 200) { //flick,太容易触发,额外校验一下deltaTime
+					this.x = this._getPage((this.slideNumber + (direction === 'right' ? -1 : 1)), true).x;
+				}
+				this.resetPosition(this.options.bounceTime);
+			} else if (e.type === 'dragend' && !detail.flick) {
+				this.resetPosition(this.options.bounceTime);
+			}
+			e.stopPropagation();
+		},
+		_initSnap: function() {
+			this.scrollerWidth = this.itemLength * this.scrollerWidth;
+			this.maxScrollX = Math.min(this.wrapperWidth - this.scrollerWidth, 0);
+			this._super();
+			if (!this.currentPage.x) {
+				//当slider处于隐藏状态时,导致snap计算是错误的,临时先这么判断一下,后续要考虑解决所有scroll在隐藏状态下初始化属性不正确的问题
+				var currentPage = this.pages[this.loop ? 1 : 0];
+				currentPage = currentPage || this.pages[0];
+				if (!currentPage) {
+					return;
+				}
+				this.currentPage = currentPage[0];
+				this.slideNumber = 0;
+				this.lastSlideNumber = typeof this.lastSlideNumber === 'undefined' ? 0 : this.lastSlideNumber;
+			} else {
+				this.slideNumber = this._fixedSlideNumber();
+				this.lastSlideNumber = typeof this.lastSlideNumber === 'undefined' ? this.slideNumber : this.lastSlideNumber;
+			}
+			this.options.startX = this.currentPage.x || 0;
+		},
+		_getSnapX: function(offsetLeft) {
+			return Math.max(-offsetLeft, this.maxScrollX);
+		},
+		_getPage: function(slideNumber, isFlick) {
+			if (this.loop) {
+				if (slideNumber > (this.itemLength - (isFlick ? 2 : 3))) {
+					slideNumber = 1;
+					time = 0;
+				} else if (slideNumber < (isFlick ? -1 : 0)) {
+					slideNumber = this.itemLength - 2;
+					time = 0;
+				} else {
+					slideNumber += 1;
+				}
+			} else {
+				if (!isFlick) {
+					if (slideNumber > (this.itemLength - 1)) {
+						slideNumber = 0;
+						time = 0;
+					} else if (slideNumber < 0) {
+						slideNumber = this.itemLength - 1;
+						time = 0;
+					}
+				}
+				slideNumber = Math.min(Math.max(0, slideNumber), this.itemLength - 1);
+			}
+			return this.pages[slideNumber][0];
+		},
+		_gotoItem: function(slideNumber, time) {
+			this.currentPage = this._getPage(slideNumber, true); //此处传true。可保证程序切换时,动画与人手操作一致(第一张,最后一张的切换动画)
+			this.scrollTo(this.currentPage.x, 0, time, this.options.scrollEasing);
+			if (time === 0) {
+				$.trigger(this.wrapper, 'scrollend', this);
+			}
+		},
+		//API
+		setTranslate: function(x, y) {
+			this._super(x, y);
+			var progressBar = this.progressBar;
+			if (progressBar) {
+				this.progressBarStyle.webkitTransform = this._getTranslateStr((-x * (this.progressBarWidth / this.wrapperWidth)), 0);
+			}
+		},
+		resetPosition: function(time) {
+			time = time || 0;
+			if (this.x > 0) {
+				this.x = 0;
+			} else if (this.x < this.maxScrollX) {
+				this.x = this.maxScrollX;
+			}
+			this.currentPage = this._nearestSnap(this.x);
+			this.scrollTo(this.currentPage.x, 0, time, this.options.scrollEasing);
+			return true;
+		},
+		gotoItem: function(slideNumber, time) {
+			this._gotoItem(slideNumber, typeof time === 'undefined' ? this.options.scrollTime : time);
+		},
+		nextItem: function() {
+			this._gotoItem(this.slideNumber + 1, this.options.scrollTime);
+		},
+		prevItem: function() {
+			this._gotoItem(this.slideNumber - 1, this.options.scrollTime);
+		},
+		getSlideNumber: function() {
+			return this.slideNumber || 0;
+		},
+		_reInit: function() {
+			var groups = this.wrapper.querySelectorAll('.' + CLASS_SLIDER_GROUP);
+			for (var i = 0, len = groups.length; i < len; i++) {
+				if (groups[i].parentNode === this.wrapper) {
+					this.scroller = groups[i];
+					break;
+				}
+			}
+			this.scrollerStyle = this.scroller && this.scroller.style;
+			if (this.progressBar) {
+				this.progressBarWidth = this.progressBar.offsetWidth;
+				this.progressBarStyle = this.progressBar.style;
+			}
+		},
+		refresh: function(options) {
+			if (options) {
+				$.extend(this.options, options);
+				this._super();
+				this._initTimer();
+			} else {
+				this._super();
+			}
+		},
+		destroy: function() {
+			this._initEvent(true); //detach
+			delete $.data[this.wrapper.getAttribute('data-slider')];
+			this.wrapper.setAttribute('data-slider', '');
+		}
+	});
+	$.fn.slider = function(options) {
+		var slider = null;
+		this.each(function() {
+			var sliderElement = this;
+			if (!this.classList.contains(CLASS_SLIDER)) {
+				sliderElement = this.querySelector('.' + CLASS_SLIDER);
+			}
+			if (sliderElement && sliderElement.querySelector(SELECTOR_SLIDER_ITEM)) {
+				var id = sliderElement.getAttribute('data-slider');
+				if (!id) {
+					id = ++$.uuid;
+					$.data[id] = slider = new Slider(sliderElement, options);
+					sliderElement.setAttribute('data-slider', id);
+				} else {
+					slider = $.data[id];
+					if (slider && options) {
+						slider.refresh(options);
+					}
+				}
+			}
+		});
+		return slider;
+	};
+	$.ready(function() {
+		//		setTimeout(function() {
+		$('.mui-slider').slider();
+		$('.mui-scroll-wrapper.mui-slider-indicator.mui-segmented-control').scroll({
+			scrollY: false,
+			scrollX: true,
+			indicators: false,
+			snap: '.mui-control-item'
+		});
+		//		}, 500); //临时处理slider宽度计算不正确的问题(初步确认是scrollbar导致的)
+
+	});
+})(mui, window);
+/**
+ * pullRefresh 5+
+ * @param {type} $
+ * @returns {undefined}
+ */
+(function($, document) {
+    if (!($.os.plus)) { //仅在5+android支持多webview的使用
+        return;
+    }
+    $.plusReady(function() {
+        if (window.__NWin_Enable__ === false) { //不支持多webview,则不用5+下拉刷新
+            return;
+        }
+        var CLASS_PLUS_PULLREFRESH = 'mui-plus-pullrefresh';
+        var CLASS_VISIBILITY = 'mui-visibility';
+        var CLASS_HIDDEN = 'mui-hidden';
+        var CLASS_BLOCK = 'mui-block';
+
+        var CLASS_PULL_CAPTION = 'mui-pull-caption';
+        var CLASS_PULL_CAPTION_DOWN = 'mui-pull-caption-down';
+        var CLASS_PULL_CAPTION_REFRESH = 'mui-pull-caption-refresh';
+        var CLASS_PULL_CAPTION_NOMORE = 'mui-pull-caption-nomore';
+
+        var PlusPullRefresh = $.Class.extend({
+            init: function(element, options) {
+                this.element = element;
+                this.options = options;
+                this.wrapper = this.scroller = element;
+                this._init();
+                this._initPulldownRefreshEvent();
+            },
+            _init: function() {
+                var self = this;
+                //document.addEventListener('plusscrollbottom', this);
+                window.addEventListener('dragup', self);
+                document.addEventListener("plusscrollbottom", self);
+                self.scrollInterval = window.setInterval(function() {
+                    if (self.isScroll && !self.loading) {
+                        if (window.pageYOffset + window.innerHeight + 10 >= document.documentElement.scrollHeight) {
+                            self.isScroll = false; //放在这里是因为快速滚动的话,有可能检测时,还没到底,所以只要有滚动,没到底之前一直检测高度变化
+                            if (self.bottomPocket) {
+                                self.pullupLoading();
+                            }
+                        }
+                    }
+                }, 100);
+            },
+            _initPulldownRefreshEvent: function() {
+                var self = this;
+                $.plusReady(function() {
+                    if (self.options.down.style == "circle") {
+                        //单webview、原生转圈
+                        self.options.webview = plus.webview.currentWebview();
+                        self.options.webview.setPullToRefresh({
+                            support: true,
+                            color: self.options.down.color || '#2BD009',
+                            height: self.options.down.height || '50px',
+                            range: self.options.down.range || '100px',
+                            style: 'circle',
+                            offset: self.options.down.offset || '0px'
+                        }, function() {
+                            self.options.down.callback();
+                        });
+                    } else if (self.topPocket && self.options.webviewId) {
+                        var webview = plus.webview.getWebviewById(self.options.webviewId); //子窗口
+                        if (!webview) {
+                            return;
+                        }
+                        self.options.webview = webview;
+                        var downOptions = self.options.down;
+                        var height = downOptions.height;
+                        webview.addEventListener('close', function() {
+                            var attrWebviewId = self.options.webviewId && self.options.webviewId.replace(/\//g, "_"); //替换所有"/" 
+                            self.element.removeAttribute('data-pullrefresh-plus-' + attrWebviewId);
+                        });
+                        webview.addEventListener("dragBounce", function(e) {
+                            if (!self.pulldown) {
+                                self._initPulldownRefresh();
+                            } else {
+                                self.pullPocket.classList.add(CLASS_BLOCK);
+                            }
+                            switch (e.status) {
+                                case "beforeChangeOffset": //下拉可刷新状态
+                                    self._setCaption(downOptions.contentdown);
+                                    break;
+                                case "afterChangeOffset": //松开可刷新状态
+                                    self._setCaption(downOptions.contentover);
+                                    break;
+                                case "dragEndAfterChangeOffset": //正在刷新状态
+                                    //执行下拉刷新所在webview的回调函数
+                                    webview.evalJS("window.mui&&mui.options.pullRefresh.down.callback()");
+                                    self._setCaption(downOptions.contentrefresh);
+                                    break;
+                                default:
+                                    break;
+                            }
+                        }, false);
+
+                        webview.setBounce({
+                            position: {
+                                top: height * 2 + 'px'
+                            },
+                            changeoffset: {
+                                top: height + 'px'
+                            }
+                        });
+
+                    }
+                });
+            },
+            handleEvent: function(e) {
+                var self = this;
+                if (self.stopped) {
+                    return;
+                }
+                self.isScroll = false;
+                if (e.type === 'dragup' || e.type === 'plusscrollbottom') {
+                    self.isScroll = true;
+                    setTimeout(function() {
+                        self.isScroll = false;
+                    }, 1000);
+                }
+            }
+        }).extend($.extend({
+            setStopped: function(stopped) { //该方法是子页面调用的
+                this.stopped = !!stopped;
+                // TODO 此处需要设置当前webview的bounce为none,目前5+有BUG
+                if (this.stopped) {
+                    this.disablePullupToRefresh();
+                    this.disablePulldownToRefresh();
+                } else {
+                    this.enablePullupToRefresh();
+                    this.enablePulldownToRefresh();
+                }
+            },
+            beginPulldown: function() {
+                var self = this;
+                $.plusReady(function() {
+                    //这里延时的目的是为了保证下拉刷新组件初始化完成,后续应该做成有状态的
+                    setTimeout(function() {
+                        if (self.options.down.style == "circle") { //单webview下拉刷新
+                            plus.webview.currentWebview().beginPullToRefresh();
+                        } else { //双webview模式
+                            var webview = self.options.webview;
+                            if (webview) {
+                                webview.setBounce({
+                                    offset: {
+                                        top: self.options.down.height + "px"
+                                    }
+                                });
+                            }
+                        }
+                    }, 15);
+                }.bind(this));
+            },
+            pulldownLoading: function() { //该方法是子页面调用的,兼容老的历史API
+                this.beginPulldown();
+            },
+            _pulldownLoading: function() { //该方法是父页面调用的
+                var self = this;
+                $.plusReady(function() {
+                    var childWebview = plus.webview.getWebviewById(self.options.webviewId);
+                    childWebview && childWebview.setBounce({
+                        offset: {
+                            top: self.options.down.height + "px"
+                        }
+                    });
+                });
+            },
+            endPulldown: function() {
+                var _wv = plus.webview.currentWebview();
+                //双webview的下拉刷新,需要修改父窗口提示信息
+                if (_wv.parent() && this.options.down.style !== "circle") {
+                    _wv.parent().evalJS("mui&&mui(document.querySelector('.mui-content')).pullRefresh('" + JSON.stringify({
+                        webviewId: _wv.id
+                    }) + "')._endPulldownToRefresh()");
+                } else {
+                    _wv.endPullToRefresh();
+                }
+            },
+            endPulldownToRefresh: function() { //该方法是子页面调用的,兼容老的历史API
+                this.endPulldown();
+            },
+            _endPulldownToRefresh: function() { //该方法是父页面调用的
+                var self = this;
+                if (self.topPocket && self.options.webview) {
+                    self.options.webview.endPullToRefresh(); //下拉刷新所在webview回弹
+                    self.loading = false;
+                    self._setCaption(self.options.down.contentdown, true);
+                    setTimeout(function() {
+                        self.loading || self.topPocket.classList.remove(CLASS_BLOCK);
+                    }, 350);
+                }
+            },
+            beginPullup: function(callback) { //开始上拉加载
+                var self = this;
+                if (self.isLoading) return;
+                self.isLoading = true;
+                if (self.pulldown !== false) {
+                    self._initPullupRefresh();
+                } else {
+                    this.pullPocket.classList.add(CLASS_BLOCK);
+                }
+                setTimeout(function() {
+                    self.pullLoading.classList.add(CLASS_VISIBILITY);
+                    self.pullLoading.classList.remove(CLASS_HIDDEN);
+                    self.pullCaption.innerHTML = ''; //修正5+里边第一次加载时,文字显示的bug(还会显示出来个“多”,猜测应该是渲染问题导致的)
+                    self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_REFRESH;
+                    self.pullCaption.innerHTML = self.options.up.contentrefresh;
+                    callback = callback || self.options.up.callback;
+                    callback && callback.call(self);
+                }, 300);
+            },
+            pullupLoading: function(callback) { //兼容老的API
+                this.beginPullup(callback);
+            },
+            endPullup: function(finished) { //上拉加载结束
+                var self = this;
+                if (self.pullLoading) {
+                    self.pullLoading.classList.remove(CLASS_VISIBILITY);
+                    self.pullLoading.classList.add(CLASS_HIDDEN);
+                    self.isLoading = false;
+                    if (finished) {
+                        self.finished = true;
+                        self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_NOMORE;
+                        self.pullCaption.innerHTML = self.options.up.contentnomore;
+                        //取消5+的plusscrollbottom事件
+                        document.removeEventListener('plusscrollbottom', self);
+                        window.removeEventListener('dragup', self);
+                    } else { //初始化时隐藏,后续不再隐藏
+                        self.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN;
+                        self.pullCaption.innerHTML = self.options.up.contentdown;
+                    }
+                }
+            },
+            endPullupToRefresh: function(finished) { //上拉加载结束,兼容老的API
+                this.endPullup(finished);
+            },
+            disablePulldownToRefresh: function() {
+                var webview = plus.webview.currentWebview();
+                if (this.options.down.style && this.options.down.style == 'circle') { // 单webview模式禁止原生下拉刷新
+                    this.options.webview.setPullToRefresh({
+                        support: false,
+                        style: 'circle'
+                    });
+                } else { // 双webview模式禁止下拉刷新
+                    webview.setStyle({
+                        bounce: 'none'
+                    });
+                    webview.setBounce({
+                        position: {
+                            top: 'none'
+                        }
+                    });
+                }
+            },
+            enablePulldownToRefresh: function() {
+                var self = this,
+                    webview = plus.webview.currentWebview(),
+                    height = this.options.down.height;
+                // 单webview模式禁止原生下拉刷新
+                if (this.options.down.style && this.options.down.style == 'circle') {
+                    webview.setPullToRefresh({
+                        support: true,
+                        height: height || '50px',
+                        range: self.options.down.range || '100px',
+                        style: 'circle',
+                        offset: self.options.down.offset || '0px'
+                    });
+                } else { // 重新初始化双webview模式下拉刷新
+                    webview.setStyle({
+                        bounce: 'vertical'
+                    });
+                    webview.setBounce({
+                        position: {
+                            top: height * 2 + 'px'
+                        },
+                        changeoffset: {
+                            top: height + 'px'
+                        }
+                    });
+                }
+            },
+            disablePullupToRefresh: function() {
+                this._initPullupRefresh();
+                this.bottomPocket.className = 'mui-pull-bottom-pocket' + ' ' + CLASS_HIDDEN;
+                window.removeEventListener('dragup', this);
+            },
+            enablePullupToRefresh: function() {
+                this._initPullupRefresh();
+                this.bottomPocket.classList.remove(CLASS_HIDDEN);
+                this.pullCaption.className = CLASS_PULL_CAPTION + ' ' + CLASS_PULL_CAPTION_DOWN;
+                this.pullCaption.innerHTML = this.options.up.contentdown;
+                document.addEventListener("plusscrollbottom", this);
+                window.addEventListener('dragup', this);
+            },
+            scrollTo: function(x, y, time) {
+                $.scrollTo(y, time);
+            },
+            scrollToBottom: function(time) {
+                $.scrollTo(document.documentElement.scrollHeight, time);
+            },
+            refresh: function(isReset) {
+                if (isReset && this.finished) {
+                    this.enablePullupToRefresh();
+                    this.finished = false;
+                }
+            }
+        }, $.PullRefresh));
+
+        //override h5 pullRefresh
+        $.fn.pullRefresh_native = function(options) {
+            var self;
+            if (this.length === 0) {
+                self = document.createElement('div');
+                self.className = 'mui-content';
+                document.body.appendChild(self);
+            } else {
+                self = this[0];
+            }
+            var args = options;
+            //一个父需要支持多个子下拉刷新
+            options = options || {}
+            if (typeof options === 'string') {
+                options = $.parseJSON(options);
+            };
+            !options.webviewId && (options.webviewId = (plus.webview.currentWebview().id || plus.webview.currentWebview().getURL()));
+            var pullRefreshApi = null;
+            var attrWebviewId = options.webviewId && options.webviewId.replace(/\//g, "_"); //替换所有"/"
+            var id = self.getAttribute('data-pullrefresh-plus-' + attrWebviewId);
+            if (!id && typeof args === 'undefined') {
+                return false;
+            }
+            if (!id) { //避免重复初始化5+ pullrefresh
+                id = ++$.uuid;
+                self.setAttribute('data-pullrefresh-plus-' + attrWebviewId, id);
+                document.body.classList.add(CLASS_PLUS_PULLREFRESH);
+                $.data[id] = pullRefreshApi = new PlusPullRefresh(self, options);
+            } else {
+                pullRefreshApi = $.data[id];
+            }
+            if (options.down && options.down.auto) { //如果设置了auto,则自动下拉一次
+                //pullRefreshApi._pulldownLoading(); //parent webview
+                pullRefreshApi.beginPulldown();
+            } else if (options.up && options.up.auto) { //如果设置了auto,则自动上拉一次
+                pullRefreshApi.beginPullup();
+            }
+            return pullRefreshApi;
+        };
+    });
+
+})(mui, document);
+/**
+ * off-canvas
+ * @param {type} $
+ * @param {type} window
+ * @param {type} document
+ * @param {type} action
+ * @returns {undefined}
+ */
+(function($, window, document, name) {
+	var CLASS_OFF_CANVAS_LEFT = 'mui-off-canvas-left';
+	var CLASS_OFF_CANVAS_RIGHT = 'mui-off-canvas-right';
+	var CLASS_ACTION_BACKDROP = 'mui-off-canvas-backdrop';
+	var CLASS_OFF_CANVAS_WRAP = 'mui-off-canvas-wrap';
+
+	var CLASS_SLIDE_IN = 'mui-slide-in';
+	var CLASS_ACTIVE = 'mui-active';
+
+
+	var CLASS_TRANSITIONING = 'mui-transitioning';
+
+	var SELECTOR_INNER_WRAP = '.mui-inner-wrap';
+
+
+	var OffCanvas = $.Class.extend({
+		init: function(element, options) {
+			this.wrapper = this.element = element;
+			this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP);
+			this.classList = this.wrapper.classList;
+			if (this.scroller) {
+				this.options = $.extend(true, {
+					dragThresholdX: 10,
+					scale: 0.8,
+					opacity: 0.1,
+					preventDefaultException: {
+						tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|VIDEO)$/
+					},
+				}, options);
+				document.body.classList.add('mui-fullscreen'); //fullscreen
+				this.refresh();
+				this.initEvent();
+			}
+		},
+		_preventDefaultException: function(el, exceptions) {
+			for (var i in exceptions) {
+				if (exceptions[i].test(el[i])) {
+					return true;
+				}
+			}
+			return false;
+		},
+		refresh: function(offCanvas) {
+			//			offCanvas && !offCanvas.classList.contains(CLASS_ACTIVE) && this.classList.remove(CLASS_ACTIVE);
+			this.slideIn = this.classList.contains(CLASS_SLIDE_IN);
+			this.scalable = this.classList.contains('mui-scalable') && !this.slideIn;
+			this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP);
+			//			!offCanvas && this.scroller.classList.remove(CLASS_TRANSITIONING);
+			//			!offCanvas && this.scroller.setAttribute('style', '');
+			this.offCanvasLefts = this.wrapper.querySelectorAll('.' + CLASS_OFF_CANVAS_LEFT);
+			this.offCanvasRights = this.wrapper.querySelectorAll('.' + CLASS_OFF_CANVAS_RIGHT);
+			if (offCanvas) {
+				if (offCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT)) {
+					this.offCanvasLeft = offCanvas;
+				} else if (offCanvas.classList.contains(CLASS_OFF_CANVAS_RIGHT)) {
+					this.offCanvasRight = offCanvas;
+				}
+			} else {
+				this.offCanvasRight = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT);
+				this.offCanvasLeft = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT);
+			}
+			this.offCanvasRightWidth = this.offCanvasLeftWidth = 0;
+			this.offCanvasLeftSlideIn = this.offCanvasRightSlideIn = false;
+			if (this.offCanvasRight) {
+				this.offCanvasRightWidth = this.offCanvasRight.offsetWidth;
+				this.offCanvasRightSlideIn = this.slideIn && (this.offCanvasRight.parentNode === this.wrapper);
+				//				this.offCanvasRight.classList.remove(CLASS_TRANSITIONING);
+				//				this.offCanvasRight.classList.remove(CLASS_ACTIVE);
+				//				this.offCanvasRight.setAttribute('style', '');
+			}
+			if (this.offCanvasLeft) {
+				this.offCanvasLeftWidth = this.offCanvasLeft.offsetWidth;
+				this.offCanvasLeftSlideIn = this.slideIn && (this.offCanvasLeft.parentNode === this.wrapper);
+				//				this.offCanvasLeft.classList.remove(CLASS_TRANSITIONING);
+				//				this.offCanvasLeft.classList.remove(CLASS_ACTIVE);
+				//				this.offCanvasLeft.setAttribute('style', '');
+			}
+			this.backdrop = this.scroller.querySelector('.' + CLASS_ACTION_BACKDROP);
+
+			this.options.dragThresholdX = this.options.dragThresholdX || 10;
+
+			this.visible = false;
+			this.startX = null;
+			this.lastX = null;
+			this.offsetX = null;
+			this.lastTranslateX = null;
+		},
+		handleEvent: function(e) {
+			switch (e.type) {
+				case $.EVENT_START:
+					e.target && !this._preventDefaultException(e.target, this.options.preventDefaultException) && e.preventDefault();
+					break;
+				case 'webkitTransitionEnd': //有个bug需要处理,需要考虑假设没有触发webkitTransitionEnd的情况
+					if (e.target === this.scroller) {
+						this._dispatchEvent();
+					}
+					break;
+				case 'drag':
+					var detail = e.detail;
+					if (!this.startX) {
+						this.startX = detail.center.x;
+						this.lastX = this.startX;
+					} else {
+						this.lastX = detail.center.x;
+					}
+					if (!this.isDragging && Math.abs(this.lastX - this.startX) > this.options.dragThresholdX && (detail.direction === 'left' || (detail.direction === 'right'))) {
+						if (this.slideIn) {
+							this.scroller = this.wrapper.querySelector(SELECTOR_INNER_WRAP);
+							if (this.classList.contains(CLASS_ACTIVE)) {
+								if (this.offCanvasRight && this.offCanvasRight.classList.contains(CLASS_ACTIVE)) {
+									this.offCanvas = this.offCanvasRight;
+									this.offCanvasWidth = this.offCanvasRightWidth;
+								} else {
+									this.offCanvas = this.offCanvasLeft;
+									this.offCanvasWidth = this.offCanvasLeftWidth;
+								}
+							} else {
+								if (detail.direction === 'left' && this.offCanvasRight) {
+									this.offCanvas = this.offCanvasRight;
+									this.offCanvasWidth = this.offCanvasRightWidth;
+								} else if (detail.direction === 'right' && this.offCanvasLeft) {
+									this.offCanvas = this.offCanvasLeft;
+									this.offCanvasWidth = this.offCanvasLeftWidth;
+								} else {
+									this.scroller = null;
+								}
+							}
+						} else {
+							if (this.classList.contains(CLASS_ACTIVE)) {
+								if (detail.direction === 'left') {
+									this.offCanvas = this.offCanvasLeft;
+									this.offCanvasWidth = this.offCanvasLeftWidth;
+								} else {
+									this.offCanvas = this.offCanvasRight;
+									this.offCanvasWidth = this.offCanvasRightWidth;
+								}
+							} else {
+								if (detail.direction === 'right') {
+									this.offCanvas = this.offCanvasLeft;
+									this.offCanvasWidth = this.offCanvasLeftWidth;
+								} else {
+									this.offCanvas = this.offCanvasRight;
+									this.offCanvasWidth = this.offCanvasRightWidth;
+								}
+							}
+						}
+						if (this.offCanvas && this.scroller) {
+							this.startX = this.lastX;
+							this.isDragging = true;
+
+							$.gestures.session.lockDirection = true; //锁定方向
+							$.gestures.session.startDirection = detail.direction;
+
+							this.offCanvas.classList.remove(CLASS_TRANSITIONING);
+							this.scroller.classList.remove(CLASS_TRANSITIONING);
+							this.offsetX = this.getTranslateX();
+							this._initOffCanvasVisible();
+						}
+					}
+					if (this.isDragging) {
+						this.updateTranslate(this.offsetX + (this.lastX - this.startX));
+						detail.gesture.preventDefault();
+						e.stopPropagation();
+					}
+					break;
+				case 'dragend':
+					if (this.isDragging) {
+						var detail = e.detail;
+						var direction = detail.direction;
+						this.isDragging = false;
+						this.offCanvas.classList.add(CLASS_TRANSITIONING);
+						this.scroller.classList.add(CLASS_TRANSITIONING);
+						var ratio = 0;
+						var x = this.getTranslateX();
+						if (!this.slideIn) {
+							if (x >= 0) {
+								ratio = (this.offCanvasLeftWidth && (x / this.offCanvasLeftWidth)) || 0;
+							} else {
+								ratio = (this.offCanvasRightWidth && (x / this.offCanvasRightWidth)) || 0;
+							}
+							if (ratio === 0) {
+								this.openPercentage(0);
+								this._dispatchEvent(); //此处不触发webkitTransitionEnd,所以手动dispatch
+								return;
+							}
+							if (direction === 'right' && ratio >= 0 && (ratio >= 0.5 || detail.swipe)) { //右滑打开
+								this.openPercentage(100);
+							} else if (direction === 'right' && ratio < 0 && (ratio > -0.5 || detail.swipe)) { //右滑关闭
+								this.openPercentage(0);
+							} else if (direction === 'right' && ratio > 0 && ratio < 0.5) { //右滑还原关闭
+								this.openPercentage(0);
+							} else if (direction === 'right' && ratio < 0.5) { //右滑还原打开
+								this.openPercentage(-100);
+							} else if (direction === 'left' && ratio <= 0 && (ratio <= -0.5 || detail.swipe)) { //左滑打开
+								this.openPercentage(-100);
+							} else if (direction === 'left' && ratio > 0 && (ratio <= 0.5 || detail.swipe)) { //左滑关闭
+								this.openPercentage(0);
+							} else if (direction === 'left' && ratio < 0 && ratio >= -0.5) { //左滑还原关闭
+								this.openPercentage(0);
+							} else if (direction === 'left' && ratio > 0.5) { //左滑还原打开
+								this.openPercentage(100);
+							} else { //默认关闭
+								this.openPercentage(0);
+							}
+							if (ratio === 1 || ratio === -1) { //此处不触发webkitTransitionEnd,所以手动dispatch
+								this._dispatchEvent();
+							}
+						} else {
+							if (x >= 0) {
+								ratio = (this.offCanvasRightWidth && (x / this.offCanvasRightWidth)) || 0;
+							} else {
+								ratio = (this.offCanvasLeftWidth && (x / this.offCanvasLeftWidth)) || 0;
+							}
+							if (direction === 'right' && ratio <= 0 && (ratio >= -0.5 || detail.swipe)) { //右滑打开
+								this.openPercentage(100);
+							} else if (direction === 'right' && ratio > 0 && (ratio >= 0.5 || detail.swipe)) { //右滑关闭
+								this.openPercentage(0);
+							} else if (direction === 'right' && ratio <= -0.5) { //右滑还原关闭
+								this.openPercentage(0);
+							} else if (direction === 'right' && ratio > 0 && ratio <= 0.5) { //右滑还原打开
+								this.openPercentage(-100);
+							} else if (direction === 'left' && ratio >= 0 && (ratio <= 0.5 || detail.swipe)) { //左滑打开
+								this.openPercentage(-100);
+							} else if (direction === 'left' && ratio < 0 && (ratio <= -0.5 || detail.swipe)) { //左滑关闭
+								this.openPercentage(0);
+							} else if (direction === 'left' && ratio >= 0.5) { //左滑还原关闭
+								this.openPercentage(0);
+							} else if (direction === 'left' && ratio >= -0.5 && ratio < 0) { //左滑还原打开
+								this.openPercentage(100);
+							} else {
+								this.openPercentage(0);
+							}
+							if (ratio === 1 || ratio === -1 || ratio === 0) {
+								this._dispatchEvent();
+								return;
+							}
+
+						}
+					}
+					break;
+			}
+		},
+		_dispatchEvent: function() {
+			if (this.classList.contains(CLASS_ACTIVE)) {
+				$.trigger(this.wrapper, 'shown', this);
+			} else {
+				$.trigger(this.wrapper, 'hidden', this);
+			}
+		},
+		_initOffCanvasVisible: function() {
+			if (!this.visible) {
+				this.visible = true;
+				if (this.offCanvasLeft) {
+					this.offCanvasLeft.style.visibility = 'visible';
+				}
+				if (this.offCanvasRight) {
+					this.offCanvasRight.style.visibility = 'visible';
+				}
+			}
+		},
+		initEvent: function() {
+			var self = this;
+			if (self.backdrop) {
+				self.backdrop.addEventListener('tap', function(e) {
+					self.close();
+					e.detail.gesture.preventDefault();
+				});
+			}
+			if (this.classList.contains('mui-draggable')) {
+				this.wrapper.addEventListener($.EVENT_START, this); //临时处理
+				this.wrapper.addEventListener('drag', this);
+				this.wrapper.addEventListener('dragend', this);
+			}
+			this.wrapper.addEventListener('webkitTransitionEnd', this);
+		},
+		openPercentage: function(percentage) {
+			var p = percentage / 100;
+			if (!this.slideIn) {
+				if (this.offCanvasLeft && percentage >= 0) {
+					this.updateTranslate(this.offCanvasLeftWidth * p);
+					this.offCanvasLeft.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
+				} else if (this.offCanvasRight && percentage <= 0) {
+					this.updateTranslate(this.offCanvasRightWidth * p);
+					this.offCanvasRight.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
+				}
+				this.classList[p !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
+			} else {
+				if (this.offCanvasLeft && percentage >= 0) {
+					p = p === 0 ? -1 : 0;
+					this.updateTranslate(this.offCanvasLeftWidth * p);
+					this.offCanvasLeft.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
+				} else if (this.offCanvasRight && percentage <= 0) {
+					p = p === 0 ? 1 : 0;
+					this.updateTranslate(this.offCanvasRightWidth * p);
+					this.offCanvasRight.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
+				}
+				this.classList[percentage !== 0 ? 'add' : 'remove'](CLASS_ACTIVE);
+			}
+		},
+		updateTranslate: function(x) {
+			if (x !== this.lastTranslateX) {
+				if (!this.slideIn) {
+					if ((!this.offCanvasLeft && x > 0) || (!this.offCanvasRight && x < 0)) {
+						this.setTranslateX(0);
+						return;
+					}
+					if (this.leftShowing && x > this.offCanvasLeftWidth) {
+						this.setTranslateX(this.offCanvasLeftWidth);
+						return;
+					}
+					if (this.rightShowing && x < -this.offCanvasRightWidth) {
+						this.setTranslateX(-this.offCanvasRightWidth);
+						return;
+					}
+					this.setTranslateX(x);
+					if (x >= 0) {
+						this.leftShowing = true;
+						this.rightShowing = false;
+						if (x > 0) {
+							if (this.offCanvasLeft) {
+								$.each(this.offCanvasLefts, function(index, offCanvas) {
+									if (offCanvas === this.offCanvasLeft) {
+										this.offCanvasLeft.style.zIndex = 0;
+									} else {
+										offCanvas.style.zIndex = -1;
+									}
+								}.bind(this));
+							}
+							if (this.offCanvasRight) {
+								this.offCanvasRight.style.zIndex = -1;
+							}
+						}
+					} else {
+						this.rightShowing = true;
+						this.leftShowing = false;
+						if (this.offCanvasRight) {
+							$.each(this.offCanvasRights, function(index, offCanvas) {
+								if (offCanvas === this.offCanvasRight) {
+									offCanvas.style.zIndex = 0;
+								} else {
+									offCanvas.style.zIndex = -1;
+								}
+							}.bind(this));
+						}
+						if (this.offCanvasLeft) {
+							this.offCanvasLeft.style.zIndex = -1;
+						}
+					}
+				} else {
+					if (this.offCanvas.classList.contains(CLASS_OFF_CANVAS_RIGHT)) {
+						if (x < 0) {
+							this.setTranslateX(0);
+							return;
+						}
+						if (x > this.offCanvasRightWidth) {
+							this.setTranslateX(this.offCanvasRightWidth);
+							return;
+						}
+					} else {
+						if (x > 0) {
+							this.setTranslateX(0);
+							return;
+						}
+						if (x < -this.offCanvasLeftWidth) {
+							this.setTranslateX(-this.offCanvasLeftWidth);
+							return;
+						}
+					}
+					this.setTranslateX(x);
+				}
+				this.lastTranslateX = x;
+			}
+		},
+		setTranslateX: $.animationFrame(function(x) {
+			if (this.scroller) {
+				if (this.scalable && this.offCanvas.parentNode === this.wrapper) {
+					var percent = Math.abs(x) / this.offCanvasWidth;
+					var zoomOutScale = 1 - (1 - this.options.scale) * percent;
+					var zoomInScale = this.options.scale + (1 - this.options.scale) * percent;
+					var zoomOutOpacity = 1 - (1 - this.options.opacity) * percent;
+					var zoomInOpacity = this.options.opacity + (1 - this.options.opacity) * percent;
+					if (this.offCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT)) {
+						this.offCanvas.style.webkitTransformOrigin = '-100%';
+						this.scroller.style.webkitTransformOrigin = 'left';
+					} else {
+						this.offCanvas.style.webkitTransformOrigin = '200%';
+						this.scroller.style.webkitTransformOrigin = 'right';
+					}
+					this.offCanvas.style.opacity = zoomInOpacity;
+					this.offCanvas.style.webkitTransform = 'translate3d(0,0,0) scale(' + zoomInScale + ')';
+					this.scroller.style.webkitTransform = 'translate3d(' + x + 'px,0,0) scale(' + zoomOutScale + ')';
+				} else {
+					if (this.slideIn) {
+						this.offCanvas.style.webkitTransform = 'translate3d(' + x + 'px,0,0)';
+					} else {
+						this.scroller.style.webkitTransform = 'translate3d(' + x + 'px,0,0)';
+					}
+				}
+			}
+		}),
+		getTranslateX: function() {
+			if (this.offCanvas) {
+				var scroller = this.slideIn ? this.offCanvas : this.scroller;
+				var result = $.parseTranslateMatrix($.getStyles(scroller, 'webkitTransform'));
+				return (result && result.x) || 0;
+			}
+			return 0;
+		},
+		isShown: function(direction) {
+			var shown = false;
+			if (!this.slideIn) {
+				var x = this.getTranslateX();
+				if (direction === 'right') {
+					shown = this.classList.contains(CLASS_ACTIVE) && x < 0;
+				} else if (direction === 'left') {
+					shown = this.classList.contains(CLASS_ACTIVE) && x > 0;
+				} else {
+					shown = this.classList.contains(CLASS_ACTIVE) && x !== 0;
+				}
+			} else {
+				if (direction === 'left') {
+					shown = this.classList.contains(CLASS_ACTIVE) && this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE);
+				} else if (direction === 'right') {
+					shown = this.classList.contains(CLASS_ACTIVE) && this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE);
+				} else {
+					shown = this.classList.contains(CLASS_ACTIVE) && (this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE) || this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE));
+				}
+			}
+			return shown;
+		},
+		close: function() {
+			this._initOffCanvasVisible();
+			this.offCanvas = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT + '.' + CLASS_ACTIVE) || this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_LEFT + '.' + CLASS_ACTIVE);
+			this.offCanvasWidth = this.offCanvas.offsetWidth;
+			if (this.scroller) {
+				this.offCanvas.offsetHeight;
+				this.offCanvas.classList.add(CLASS_TRANSITIONING);
+				this.scroller.classList.add(CLASS_TRANSITIONING);
+				this.openPercentage(0);
+			}
+		},
+		show: function(direction) {
+			this._initOffCanvasVisible();
+			if (this.isShown(direction)) {
+				return false;
+			}
+			if (!direction) {
+				direction = this.wrapper.querySelector('.' + CLASS_OFF_CANVAS_RIGHT) ? 'right' : 'left';
+			}
+			if (direction === 'right') {
+				this.offCanvas = this.offCanvasRight;
+				this.offCanvasWidth = this.offCanvasRightWidth;
+			} else {
+				this.offCanvas = this.offCanvasLeft;
+				this.offCanvasWidth = this.offCanvasLeftWidth;
+			}
+			if (this.scroller) {
+				this.offCanvas.offsetHeight;
+				this.offCanvas.classList.add(CLASS_TRANSITIONING);
+				this.scroller.classList.add(CLASS_TRANSITIONING);
+				this.openPercentage(direction === 'left' ? 100 : -100);
+			}
+			return true;
+		},
+		toggle: function(directionOrOffCanvas) {
+			var direction = directionOrOffCanvas;
+			if (directionOrOffCanvas && directionOrOffCanvas.classList) {
+				direction = directionOrOffCanvas.classList.contains(CLASS_OFF_CANVAS_LEFT) ? 'left' : 'right';
+				this.refresh(directionOrOffCanvas);
+			}
+			if (!this.show(direction)) {
+				this.close();
+			}
+		}
+	});
+
+	//hash to offcanvas
+	var findOffCanvasContainer = function(target) {
+		parentNode = target.parentNode;
+		if (parentNode) {
+			if (parentNode.classList.contains(CLASS_OFF_CANVAS_WRAP)) {
+				return parentNode;
+			} else {
+				parentNode = parentNode.parentNode;
+				if (parentNode.classList.contains(CLASS_OFF_CANVAS_WRAP)) {
+					return parentNode;
+				}
+			}
+		}
+	};
+	var handle = function(event, target) {
+		if (target.tagName === 'A' && target.hash) {
+			var offcanvas = document.getElementById(target.hash.replace('#', ''));
+			if (offcanvas) {
+				var container = findOffCanvasContainer(offcanvas);
+				if (container) {
+					$.targets._container = container;
+					return offcanvas;
+				}
+			}
+		}
+		return false;
+	};
+
+	$.registerTarget({
+		name: name,
+		index: 60,
+		handle: handle,
+		target: false,
+		isReset: false,
+		isContinue: true
+	});
+
+	window.addEventListener('tap', function(e) {
+		if (!$.targets.offcanvas) {
+			return;
+		}
+		//TODO 此处类型的代码后续考虑统一优化(target机制),现在的实现费力不讨好
+		var target = e.target;
+		for (; target && target !== document; target = target.parentNode) {
+			if (target.tagName === 'A' && target.hash && target.hash === ('#' + $.targets.offcanvas.id)) {
+				e.detail && e.detail.gesture && e.detail.gesture.preventDefault(); //fixed hashchange
+				$($.targets._container).offCanvas().toggle($.targets.offcanvas);
+				$.targets.offcanvas = $.targets._container = null;
+				break;
+			}
+		}
+	});
+
+	$.fn.offCanvas = function(options) {
+		var offCanvasApis = [];
+		this.each(function() {
+			var offCanvasApi = null;
+			var self = this;
+			//hack old version
+			if (!self.classList.contains(CLASS_OFF_CANVAS_WRAP)) {
+				self = findOffCanvasContainer(self);
+			}
+			var id = self.getAttribute('data-offCanvas');
+			if (!id) {
+				id = ++$.uuid;
+				$.data[id] = offCanvasApi = new OffCanvas(self, options);
+				self.setAttribute('data-offCanvas', id);
+			} else {
+				offCanvasApi = $.data[id];
+			}
+			if (options === 'show' || options === 'close' || options === 'toggle') {
+				offCanvasApi.toggle();
+			}
+			offCanvasApis.push(offCanvasApi);
+		});
+		return offCanvasApis.length === 1 ? offCanvasApis[0] : offCanvasApis;
+	};
+	$.ready(function() {
+		$('.mui-off-canvas-wrap').offCanvas();
+	});
+})(mui, window, document, 'offcanvas');
+/**
+ * actions
+ * @param {type} $
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, name) {
+	var CLASS_ACTION = 'mui-action';
+
+	var handle = function(event, target) {
+		var className = target.className || '';
+		if (typeof className !== 'string') { //svg className(SVGAnimatedString)
+			className = '';
+		}
+		if (className && ~className.indexOf(CLASS_ACTION)) {
+			if (target.classList.contains('mui-action-back')) {
+				event.preventDefault();
+			}
+			return target;
+		}
+		return false;
+	};
+
+	$.registerTarget({
+		name: name,
+		index: 50,
+		handle: handle,
+		target: false,
+		isContinue: true
+	});
+
+})(mui, 'action');
+/**
+ * Modals
+ * @param {type} $
+ * @param {type} window
+ * @param {type} document
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, window, document, name) {
+	var CLASS_MODAL = 'mui-modal';
+
+	var handle = function(event, target) {
+		if (target.tagName === 'A' && target.hash) {
+			var modal = document.getElementById(target.hash.replace('#', ''));
+			if (modal && modal.classList.contains(CLASS_MODAL)) {
+				return modal;
+			}
+		}
+		return false;
+	};
+
+	$.registerTarget({
+		name: name,
+		index: 50,
+		handle: handle,
+		target: false,
+		isReset: false,
+		isContinue: true
+	});
+
+	window.addEventListener('tap', function(event) {
+		if ($.targets.modal) {
+			event.detail.gesture.preventDefault(); //fixed hashchange
+			$.targets.modal.classList.toggle('mui-active');
+		}
+	});
+})(mui, window, document, 'modal');
+/**
+ * Popovers
+ * @param {type} $
+ * @param {type} window
+ * @param {type} document
+ * @param {type} name
+ * @param {type} undefined
+ * @returns {undefined}
+ */
+(function($, window, document, name) {
+
+	var CLASS_POPOVER = 'mui-popover';
+	var CLASS_POPOVER_ARROW = 'mui-popover-arrow';
+	var CLASS_ACTION_POPOVER = 'mui-popover-action';
+	var CLASS_BACKDROP = 'mui-backdrop';
+	var CLASS_BAR_POPOVER = 'mui-bar-popover';
+	var CLASS_BAR_BACKDROP = 'mui-bar-backdrop';
+	var CLASS_ACTION_BACKDROP = 'mui-backdrop-action';
+	var CLASS_ACTIVE = 'mui-active';
+	var CLASS_BOTTOM = 'mui-bottom';
+
+
+
+	var handle = function(event, target) {
+		if (target.tagName === 'A' && target.hash) {
+			$.targets._popover = document.getElementById(target.hash.replace('#', ''));
+			if ($.targets._popover && $.targets._popover.classList.contains(CLASS_POPOVER)) {
+				return target;
+			} else {
+				$.targets._popover = null;
+			}
+		}
+		return false;
+	};
+
+	$.registerTarget({
+		name: name,
+		index: 60,
+		handle: handle,
+		target: false,
+		isReset: false,
+		isContinue: true
+	});
+
+	var onPopoverShown = function(e) {
+		this.removeEventListener('webkitTransitionEnd', onPopoverShown);
+		this.addEventListener($.EVENT_MOVE, $.preventDefault);
+		$.trigger(this, 'shown', this);
+	}
+	var onPopoverHidden = function(e) {
+		setStyle(this, 'none');
+		this.removeEventListener('webkitTransitionEnd', onPopoverHidden);
+		this.removeEventListener($.EVENT_MOVE, $.preventDefault);
+		$.trigger(this, 'hidden', this);
+	};
+
+	var backdrop = (function() {
+		var element = document.createElement('div');
+		element.classList.add(CLASS_BACKDROP);
+		element.addEventListener($.EVENT_MOVE, $.preventDefault);
+		element.addEventListener('tap', function(e) {
+			var popover = $.targets._popover;
+			if (popover) {
+				popover.addEventListener('webkitTransitionEnd', onPopoverHidden);
+				popover.classList.remove(CLASS_ACTIVE);
+				removeBackdrop(popover);
+			}
+		});
+
+		return element;
+	}());
+	var removeBackdropTimer;
+	var removeBackdrop = function(popover) {
+		backdrop.setAttribute('style', 'opacity:0');
+		$.targets.popover = $.targets._popover = null; //reset
+		removeBackdropTimer = $.later(function() {
+			if (!popover.classList.contains(CLASS_ACTIVE) && backdrop.parentNode && backdrop.parentNode === document.body) {
+				document.body.removeChild(backdrop);
+			}
+		}, 350);
+	};
+	window.addEventListener('tap', function(e) {
+		if (!$.targets.popover) {
+			return;
+		}
+		var toggle = false;
+		var target = e.target;
+		for (; target && target !== document; target = target.parentNode) {
+			if (target === $.targets.popover) {
+				toggle = true;
+			}
+		}
+		if (toggle) {
+			e.detail.gesture.preventDefault(); //fixed hashchange
+			togglePopover($.targets._popover, $.targets.popover);
+		}
+
+	});
+
+	var togglePopover = function(popover, anchor, state) {
+		if ((state === 'show' && popover.classList.contains(CLASS_ACTIVE)) || (state === 'hide' && !popover.classList.contains(CLASS_ACTIVE))) {
+			return;
+		}
+		removeBackdropTimer && removeBackdropTimer.cancel(); //取消remove的timer
+		//remove一遍,以免来回快速切换,导致webkitTransitionEnd不触发,无法remove
+		popover.removeEventListener('webkitTransitionEnd', onPopoverShown);
+		popover.removeEventListener('webkitTransitionEnd', onPopoverHidden);
+		backdrop.classList.remove(CLASS_BAR_BACKDROP);
+		backdrop.classList.remove(CLASS_ACTION_BACKDROP);
+		var _popover = document.querySelector('.mui-popover.mui-active');
+		if (_popover) {
+			//			_popover.setAttribute('style', '');
+			_popover.addEventListener('webkitTransitionEnd', onPopoverHidden);
+			_popover.classList.remove(CLASS_ACTIVE);
+			//			_popover.removeEventListener('webkitTransitionEnd', onPopoverHidden);
+			//同一个弹出则直接返回,解决同一个popover的toggle
+			if (popover === _popover) {
+				removeBackdrop(_popover);
+				return;
+			}
+		}
+		var isActionSheet = false;
+		if (popover.classList.contains(CLASS_BAR_POPOVER) || popover.classList.contains(CLASS_ACTION_POPOVER)) { //navBar
+			if (popover.classList.contains(CLASS_ACTION_POPOVER)) { //action sheet popover
+				isActionSheet = true;
+				backdrop.classList.add(CLASS_ACTION_BACKDROP);
+			} else { //bar popover
+				backdrop.classList.add(CLASS_BAR_BACKDROP);
+				//				if (anchor) {
+				//					if (anchor.parentNode) {
+				//						var offsetWidth = anchor.offsetWidth;
+				//						var offsetLeft = anchor.offsetLeft;
+				//						var innerWidth = window.innerWidth;
+				//						popover.style.left = (Math.min(Math.max(offsetLeft, defaultPadding), innerWidth - offsetWidth - defaultPadding)) + "px";
+				//					} else {
+				//						//TODO anchor is position:{left,top,bottom,right}
+				//					}
+				//				}
+			}
+		}
+		setStyle(popover, 'block'); //actionsheet transform
+		popover.offsetHeight;
+		popover.classList.add(CLASS_ACTIVE);
+		backdrop.setAttribute('style', '');
+		document.body.appendChild(backdrop);
+		calPosition(popover, anchor, isActionSheet); //position
+		backdrop.classList.add(CLASS_ACTIVE);
+		popover.addEventListener('webkitTransitionEnd', onPopoverShown);
+	};
+	var setStyle = function(popover, display, top, left) {
+		var style = popover.style;
+		if (typeof display !== 'undefined')
+			style.display = display;
+		if (typeof top !== 'undefined')
+			style.top = top + 'px';
+		if (typeof left !== 'undefined')
+			style.left = left + 'px';
+	};
+	var calPosition = function(popover, anchor, isActionSheet) {
+		if (!popover || !anchor) {
+			return;
+		}
+
+		if (isActionSheet) { //actionsheet
+			setStyle(popover, 'block')
+			return;
+		}
+
+		var wWidth = window.innerWidth;
+		var wHeight = window.innerHeight;
+
+		var pWidth = popover.offsetWidth;
+		var pHeight = popover.offsetHeight;
+
+		var aWidth = anchor.offsetWidth;
+		var aHeight = anchor.offsetHeight;
+		var offset = $.offset(anchor);
+
+		var arrow = popover.querySelector('.' + CLASS_POPOVER_ARROW);
+		if (!arrow) {
+			arrow = document.createElement('div');
+			arrow.className = CLASS_POPOVER_ARROW;
+			popover.appendChild(arrow);
+		}
+		var arrowSize = arrow && arrow.offsetWidth / 2 || 0;
+
+
+
+		var pTop = 0;
+		var pLeft = 0;
+		var diff = 0;
+		var arrowLeft = 0;
+		var defaultPadding = popover.classList.contains(CLASS_ACTION_POPOVER) ? 0 : 5;
+
+		var position = 'top';
+		if ((pHeight + arrowSize) < (offset.top - window.pageYOffset)) { //top
+			pTop = offset.top - pHeight - arrowSize;
+		} else if ((pHeight + arrowSize) < (wHeight - (offset.top - window.pageYOffset) - aHeight)) { //bottom
+			position = 'bottom';
+			pTop = offset.top + aHeight + arrowSize;
+		} else { //middle
+			position = 'middle';
+			pTop = Math.max((wHeight - pHeight) / 2 + window.pageYOffset, 0);
+			pLeft = Math.max((wWidth - pWidth) / 2 + window.pageXOffset, 0);
+		}
+		if (position === 'top' || position === 'bottom') {
+			pLeft = aWidth / 2 + offset.left - pWidth / 2;
+			diff = pLeft;
+			if (pLeft < defaultPadding) pLeft = defaultPadding;
+			if (pLeft + pWidth > wWidth) pLeft = wWidth - pWidth - defaultPadding;
+
+			if (arrow) {
+				if (position === 'top') {
+					arrow.classList.add(CLASS_BOTTOM);
+				} else {
+					arrow.classList.remove(CLASS_BOTTOM);
+				}
+				diff = diff - pLeft;
+				arrowLeft = (pWidth / 2 - arrowSize / 2 + diff);
+				arrowLeft = Math.max(Math.min(arrowLeft, pWidth - arrowSize * 2 - 6), 6);
+				arrow.setAttribute('style', 'left:' + arrowLeft + 'px');
+			}
+		} else if (position === 'middle') {
+			arrow.setAttribute('style', 'display:none');
+		}
+		setStyle(popover, 'block', pTop, pLeft);
+	};
+
+	$.createMask = function(callback) {
+		var element = document.createElement('div');
+		element.classList.add(CLASS_BACKDROP);
+		element.addEventListener($.EVENT_MOVE, $.preventDefault);
+		element.addEventListener('tap', function() {
+			mask.close();
+		});
+		var mask = [element];
+		mask._show = false;
+		mask.show = function() {
+			mask._show = true;
+			element.setAttribute('style', 'opacity:1');
+			document.body.appendChild(element);
+			return mask;
+		};
+		mask._remove = function() {
+			if (mask._show) {
+				mask._show = false;
+				element.setAttribute('style', 'opacity:0');
+				$.later(function() {
+					var body = document.body;
+					element.parentNode === body && body.removeChild(element);
+				}, 350);
+			}
+			return mask;
+		};
+		mask.close = function() {
+			if (callback) {
+				if (callback() !== false) {
+					mask._remove();
+				}
+			} else {
+				mask._remove();
+			}
+		};
+		return mask;
+	};
+	$.fn.popover = function() {
+		var args = arguments;
+		this.each(function() {
+			$.targets._popover = this;
+			if (args[0] === 'show' || args[0] === 'hide' || args[0] === 'toggle') {
+				togglePopover(this, args[1], args[0]);
+			}
+		});
+	};
+
+})(mui, window, document, 'popover');
+/**
+ * segmented-controllers
+ * @param {type} $
+ * @param {type} window
+ * @param {type} document
+ * @param {type} undefined
+ * @returns {undefined}
+ */
+(function($, window, document, name, undefined) {
+
+    var CLASS_CONTROL_ITEM = 'mui-control-item';
+    var CLASS_SEGMENTED_CONTROL = 'mui-segmented-control';
+    var CLASS_SEGMENTED_CONTROL_VERTICAL = 'mui-segmented-control-vertical';
+    var CLASS_CONTROL_CONTENT = 'mui-control-content';
+    var CLASS_TAB_BAR = 'mui-bar-tab';
+    var CLASS_TAB_ITEM = 'mui-tab-item';
+    var CLASS_SLIDER_ITEM = 'mui-slider-item';
+
+   var handle = function(event, target) {
+        if (target.classList && (target.classList.contains(CLASS_CONTROL_ITEM) || target.classList.contains(CLASS_TAB_ITEM))) {
+            if (target.parentNode && target.parentNode.classList && target.parentNode.classList.contains(CLASS_SEGMENTED_CONTROL_VERTICAL)) {
+                //vertical 如果preventDefault会导致无法滚动
+            } else {
+
+                    event.preventDefault();      
+                    // if(target.tagName == 'A') {
+                    //     // fixed 底部选项卡href 无法跳转 && stop hash change
+                    //     var curr_href = location.hostname + location.pathname,
+                    //         target_href = target.hostname + target.pathname;
+                   
+                    //     if (curr_href == target_href && target.hash !== "") {
+                    //         event.preventDefault();
+                    //         return target;
+                    //     }else{
+                    //             return false
+                    //     }
+                    // }
+            }
+            //          if (target.hash) {
+            return target;
+            //          }
+        }
+        return false;
+    };
+
+    $.registerTarget({
+        name: name,
+        index: 80,
+        handle: handle,
+        target: false
+    });
+
+    window.addEventListener('tap', function(e) {
+
+        var targetTab = $.targets.tab;
+        if (!targetTab) {
+            return;
+        }
+        var activeTab;
+        var activeBodies;
+        var targetBody;
+        var className = 'mui-active';
+        var classSelector = '.' + className;
+        var segmentedControl = targetTab.parentNode;
+
+        for (; segmentedControl && segmentedControl !== document; segmentedControl = segmentedControl.parentNode) {
+            if (segmentedControl.classList.contains(CLASS_SEGMENTED_CONTROL)) {
+                activeTab = segmentedControl.querySelector(classSelector + '.' + CLASS_CONTROL_ITEM);
+                break;
+            } else if (segmentedControl.classList.contains(CLASS_TAB_BAR)) {
+                activeTab = segmentedControl.querySelector(classSelector + '.' + CLASS_TAB_ITEM);
+            }
+        }
+
+        if (activeTab) {
+            activeTab.classList.remove(className);
+        }
+
+        var isLastActive = targetTab === activeTab;
+        if (targetTab) {
+            targetTab.classList.add(className);
+        }
+
+        if (!targetTab.hash) {
+            return;
+        }
+        targetBody = document.getElementById(targetTab.hash.replace('#', ''));
+
+        if (!targetBody) {
+            return;
+        }
+        if (!targetBody.classList.contains(CLASS_CONTROL_CONTENT)) { //tab bar popover
+            targetTab.classList[isLastActive ? 'remove' : 'add'](className);
+            return;
+        }
+        if (isLastActive) { //same
+            return;
+        }
+        var parentNode = targetBody.parentNode;
+        activeBodies = parentNode.querySelectorAll('.' + CLASS_CONTROL_CONTENT + classSelector);
+        for (var i = 0; i < activeBodies.length; i++) {
+            var activeBody = activeBodies[i];
+            activeBody.parentNode === parentNode && activeBody.classList.remove(className);
+        }
+
+        targetBody.classList.add(className);
+
+        var contents = [];
+        var _contents = parentNode.querySelectorAll('.' + CLASS_CONTROL_CONTENT);
+        for (var i = 0; i < _contents.length; i++) { //查找直属子节点
+            _contents[i].parentNode === parentNode && (contents.push(_contents[i]));
+        }
+        $.trigger(targetBody, $.eventName('shown', name), {
+            tabNumber: Array.prototype.indexOf.call(contents, targetBody)
+        });
+        e.detail && e.detail.gesture.preventDefault(); //fixed hashchange
+    });
+
+})(mui, window, document, 'tab');
+/**
+ * Toggles switch
+ * @param {type} $
+ * @param {type} window
+ * @param {type} name
+ * @returns {undefined}
+ */
+(function($, window, name) {
+
+	var CLASS_SWITCH = 'mui-switch';
+	var CLASS_SWITCH_HANDLE = 'mui-switch-handle';
+	var CLASS_ACTIVE = 'mui-active';
+	var CLASS_DRAGGING = 'mui-dragging';
+
+	var CLASS_DISABLED = 'mui-disabled';
+
+	var SELECTOR_SWITCH_HANDLE = '.' + CLASS_SWITCH_HANDLE;
+
+	var handle = function(event, target) {
+		if (target.classList && target.classList.contains(CLASS_SWITCH)) {
+			return target;
+		}
+		return false;
+	};
+
+	$.registerTarget({
+		name: name,
+		index: 100,
+		handle: handle,
+		target: false
+	});
+
+
+	var Toggle = function(element) {
+		this.element = element;
+		this.classList = this.element.classList;
+		this.handle = this.element.querySelector(SELECTOR_SWITCH_HANDLE);
+		this.init();
+		this.initEvent();
+	};
+	Toggle.prototype.init = function() {
+		this.toggleWidth = this.element.offsetWidth;
+		this.handleWidth = this.handle.offsetWidth;
+		this.handleX = this.toggleWidth - this.handleWidth - 3;
+	};
+	Toggle.prototype.initEvent = function() {
+		this.element.addEventListener($.EVENT_START, this);
+		this.element.addEventListener('drag', this);
+		this.element.addEventListener('swiperight', this);
+		this.element.addEventListener($.EVENT_END, this);
+		this.element.addEventListener($.EVENT_CANCEL, this);
+
+	};
+	Toggle.prototype.handleEvent = function(e) {
+		if (this.classList.contains(CLASS_DISABLED)) {
+			return;
+		}
+		switch (e.type) {
+			case $.EVENT_START:
+				this.start(e);
+				break;
+			case 'drag':
+				this.drag(e);
+				break;
+			case 'swiperight':
+				this.swiperight();
+				break;
+			case $.EVENT_END:
+			case $.EVENT_CANCEL:
+				this.end(e);
+				break;
+		}
+	};
+	Toggle.prototype.start = function(e) {
+		this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '.2s';
+		this.classList.add(CLASS_DRAGGING);
+		if (this.toggleWidth === 0 || this.handleWidth === 0) { //当switch处于隐藏状态时,width为0,需要重新初始化
+			this.init();
+		}
+	};
+	Toggle.prototype.drag = function(e) {
+		var detail = e.detail;
+		if (!this.isDragging) {
+			if (detail.direction === 'left' || detail.direction === 'right') {
+				this.isDragging = true;
+				this.lastChanged = undefined;
+				this.initialState = this.classList.contains(CLASS_ACTIVE);
+			}
+		}
+		if (this.isDragging) {
+			this.setTranslateX(detail.deltaX);
+			e.stopPropagation();
+			detail.gesture.preventDefault();
+		}
+	};
+	Toggle.prototype.swiperight = function(e) {
+		if (this.isDragging) {
+			e.stopPropagation();
+		}
+	};
+	Toggle.prototype.end = function(e) {
+		this.classList.remove(CLASS_DRAGGING);
+		if (this.isDragging) {
+			this.isDragging = false;
+			e.stopPropagation();
+			$.trigger(this.element, 'toggle', {
+				isActive: this.classList.contains(CLASS_ACTIVE)
+			});
+		} else {
+			this.toggle();
+		}
+	};
+	Toggle.prototype.toggle = function(animate) {
+		var classList = this.classList;
+		if (animate === false) {
+			this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '0s';
+		} else {
+			this.handle.style.webkitTransitionDuration = this.element.style.webkitTransitionDuration = '.2s';
+		}
+		if (classList.contains(CLASS_ACTIVE)) {
+			classList.remove(CLASS_ACTIVE);
+			this.handle.style.webkitTransform = 'translate(0,0)';
+		} else {
+			classList.add(CLASS_ACTIVE);
+			this.handle.style.webkitTransform = 'translate(' + this.handleX + 'px,0)';
+		}
+		$.trigger(this.element, 'toggle', {
+			isActive: this.classList.contains(CLASS_ACTIVE)
+		});
+	};
+	Toggle.prototype.setTranslateX = $.animationFrame(function(x) {
+		if (!this.isDragging) {
+			return;
+		}
+		var isChanged = false;
+		if ((this.initialState && -x > (this.handleX / 2)) || (!this.initialState && x > (this.handleX / 2))) {
+			isChanged = true;
+		}
+		if (this.lastChanged !== isChanged) {
+			if (isChanged) {
+				this.handle.style.webkitTransform = 'translate(' + (this.initialState ? 0 : this.handleX) + 'px,0)';
+				this.classList[this.initialState ? 'remove' : 'add'](CLASS_ACTIVE);
+			} else {
+				this.handle.style.webkitTransform = 'translate(' + (this.initialState ? this.handleX : 0) + 'px,0)';
+				this.classList[this.initialState ? 'add' : 'remove'](CLASS_ACTIVE);
+			}
+			this.lastChanged = isChanged;
+		}
+
+	});
+
+	$.fn['switch'] = function(options) {
+		var switchApis = [];
+		this.each(function() {
+			var switchApi = null;
+			var id = this.getAttribute('data-switch');
+			if (!id) {
+				id = ++$.uuid;
+				$.data[id] = new Toggle(this);
+				this.setAttribute('data-switch', id);
+			} else {
+				switchApi = $.data[id];
+			}
+			switchApis.push(switchApi);
+		});
+		return switchApis.length > 1 ? switchApis : switchApis[0];
+	};
+	$.ready(function() {
+		$('.' + CLASS_SWITCH)['switch']();
+	});
+})(mui, window, 'toggle');
+/**
+ * Tableviews
+ * @param {type} $
+ * @param {type} window
+ * @param {type} document
+ * @returns {undefined}
+ */
+(function($, window, document) {
+
+	var CLASS_ACTIVE = 'mui-active';
+	var CLASS_SELECTED = 'mui-selected';
+	var CLASS_GRID_VIEW = 'mui-grid-view';
+	var CLASS_RADIO_VIEW = 'mui-table-view-radio';
+	var CLASS_TABLE_VIEW_CELL = 'mui-table-view-cell';
+	var CLASS_COLLAPSE_CONTENT = 'mui-collapse-content';
+	var CLASS_DISABLED = 'mui-disabled';
+	var CLASS_TOGGLE = 'mui-switch';
+	var CLASS_BTN = 'mui-btn';
+
+	var CLASS_SLIDER_HANDLE = 'mui-slider-handle';
+	var CLASS_SLIDER_LEFT = 'mui-slider-left';
+	var CLASS_SLIDER_RIGHT = 'mui-slider-right';
+	var CLASS_TRANSITIONING = 'mui-transitioning';
+
+
+	var SELECTOR_SLIDER_HANDLE = '.' + CLASS_SLIDER_HANDLE;
+	var SELECTOR_SLIDER_LEFT = '.' + CLASS_SLIDER_LEFT;
+	var SELECTOR_SLIDER_RIGHT = '.' + CLASS_SLIDER_RIGHT;
+	var SELECTOR_SELECTED = '.' + CLASS_SELECTED;
+	var SELECTOR_BUTTON = '.' + CLASS_BTN;
+	var overFactor = 0.8;
+	var cell, a;
+
+	var isMoved = isOpened = openedActions = progress = false;
+	var sliderHandle = sliderActionLeft = sliderActionRight = buttonsLeft = buttonsRight = sliderDirection = sliderRequestAnimationFrame = false;
+	var timer = translateX = lastTranslateX = sliderActionLeftWidth = sliderActionRightWidth = 0;
+
+
+
+	var toggleActive = function(isActive) {
+		if (isActive) {
+			if (a) {
+				a.classList.add(CLASS_ACTIVE);
+			} else if (cell) {
+				cell.classList.add(CLASS_ACTIVE);
+			}
+		} else {
+			timer && timer.cancel();
+			if (a) {
+				a.classList.remove(CLASS_ACTIVE);
+			} else if (cell) {
+				cell.classList.remove(CLASS_ACTIVE);
+			}
+		}
+	};
+
+	var updateTranslate = function() {
+		if (translateX !== lastTranslateX) {
+			if (buttonsRight && buttonsRight.length > 0) {
+				progress = translateX / sliderActionRightWidth;
+				if (translateX < -sliderActionRightWidth) {
+					translateX = -sliderActionRightWidth - Math.pow(-translateX - sliderActionRightWidth, overFactor);
+				}
+				for (var i = 0, len = buttonsRight.length; i < len; i++) {
+					var buttonRight = buttonsRight[i];
+					if (typeof buttonRight._buttonOffset === 'undefined') {
+						buttonRight._buttonOffset = buttonRight.offsetLeft;
+					}
+					buttonOffset = buttonRight._buttonOffset;
+					setTranslate(buttonRight, (translateX - buttonOffset * (1 + Math.max(progress, -1))));
+				}
+			}
+			if (buttonsLeft && buttonsLeft.length > 0) {
+				progress = translateX / sliderActionLeftWidth;
+				if (translateX > sliderActionLeftWidth) {
+					translateX = sliderActionLeftWidth + Math.pow(translateX - sliderActionLeftWidth, overFactor);
+				}
+				for (var i = 0, len = buttonsLeft.length; i < len; i++) {
+					var buttonLeft = buttonsLeft[i];
+					if (typeof buttonLeft._buttonOffset === 'undefined') {
+						buttonLeft._buttonOffset = sliderActionLeftWidth - buttonLeft.offsetLeft - buttonLeft.offsetWidth;
+					}
+					buttonOffset = buttonLeft._buttonOffset;
+					if (buttonsLeft.length > 1) {
+						buttonLeft.style.zIndex = buttonsLeft.length - i;
+					}
+					setTranslate(buttonLeft, (translateX + buttonOffset * (1 - Math.min(progress, 1))));
+				}
+			}
+			setTranslate(sliderHandle, translateX);
+			lastTranslateX = translateX;
+		}
+		sliderRequestAnimationFrame = requestAnimationFrame(function() {
+			updateTranslate();
+		});
+	};
+	var setTranslate = function(element, x) {
+		if (element) {
+			element.style.webkitTransform = 'translate(' + x + 'px,0)';
+		}
+	};
+
+	window.addEventListener($.EVENT_START, function(event) {
+		if (cell) {
+			toggleActive(false);
+		}
+		cell = a = false;
+		isMoved = isOpened = openedActions = false;
+		var target = event.target;
+		var isDisabled = false;
+		for (; target && target !== document; target = target.parentNode) {
+			if (target.classList) {
+				var classList = target.classList;
+				if ((target.tagName === 'INPUT' && target.type !== 'radio' && target.type !== 'checkbox') || target.tagName === 'BUTTON' || classList.contains(CLASS_TOGGLE) || classList.contains(CLASS_BTN) || classList.contains(CLASS_DISABLED)) {
+					isDisabled = true;
+				}
+				if (classList.contains(CLASS_COLLAPSE_CONTENT)) { //collapse content
+					break;
+				}
+				if (classList.contains(CLASS_TABLE_VIEW_CELL)) {
+					cell = target;
+					//TODO swipe to delete close
+					var selected = cell.parentNode.querySelector(SELECTOR_SELECTED);
+					if (!cell.parentNode.classList.contains(CLASS_RADIO_VIEW) && selected && selected !== cell) {
+						$.swipeoutClose(selected);
+						cell = isDisabled = false;
+						return;
+					}
+					if (!cell.parentNode.classList.contains(CLASS_GRID_VIEW)) {
+						var link = cell.querySelector('a');
+						if (link && link.parentNode === cell) { //li>a
+							a = link;
+						}
+					}
+					var handle = cell.querySelector(SELECTOR_SLIDER_HANDLE);
+					if (handle) {
+						toggleEvents(cell);
+						event.stopPropagation();
+					}
+					if (!isDisabled) {
+						if (handle) {
+							if (timer) {
+								timer.cancel();
+							}
+							timer = $.later(function() {
+								toggleActive(true);
+							}, 100);
+						} else {
+							toggleActive(true);
+						}
+					}
+					break;
+				}
+			}
+		}
+	});
+	window.addEventListener($.EVENT_MOVE, function(event) {
+		toggleActive(false);
+	});
+
+	var handleEvent = {
+		handleEvent: function(event) {
+			switch (event.type) {
+				case 'drag':
+					this.drag(event);
+					break;
+				case 'dragend':
+					this.dragend(event);
+					break;
+				case 'flick':
+					this.flick(event);
+					break;
+				case 'swiperight':
+					this.swiperight(event);
+					break;
+				case 'swipeleft':
+					this.swipeleft(event);
+					break;
+			}
+		},
+		drag: function(event) {
+			if (!cell) {
+				return;
+			}
+			if (!isMoved) { //init
+				sliderHandle = sliderActionLeft = sliderActionRight = buttonsLeft = buttonsRight = sliderDirection = sliderRequestAnimationFrame = false;
+				sliderHandle = cell.querySelector(SELECTOR_SLIDER_HANDLE);
+				if (sliderHandle) {
+					sliderActionLeft = cell.querySelector(SELECTOR_SLIDER_LEFT);
+					sliderActionRight = cell.querySelector(SELECTOR_SLIDER_RIGHT);
+					if (sliderActionLeft) {
+						sliderActionLeftWidth = sliderActionLeft.offsetWidth;
+						buttonsLeft = sliderActionLeft.querySelectorAll(SELECTOR_BUTTON);
+					}
+					if (sliderActionRight) {
+						sliderActionRightWidth = sliderActionRight.offsetWidth;
+						buttonsRight = sliderActionRight.querySelectorAll(SELECTOR_BUTTON);
+					}
+					cell.classList.remove(CLASS_TRANSITIONING);
+					isOpened = cell.classList.contains(CLASS_SELECTED);
+					if (isOpened) {
+						openedActions = cell.querySelector(SELECTOR_SLIDER_LEFT + SELECTOR_SELECTED) ? 'left' : 'right';
+					}
+				}
+			}
+			var detail = event.detail;
+			var direction = detail.direction;
+			var angle = detail.angle;
+			if (direction === 'left' && (angle > 150 || angle < -150)) {
+				if (buttonsRight || (buttonsLeft && isOpened)) { //存在右侧按钮或存在左侧按钮且是已打开状态
+					isMoved = true;
+				}
+			} else if (direction === 'right' && (angle > -30 && angle < 30)) {
+				if (buttonsLeft || (buttonsRight && isOpened)) { //存在左侧按钮或存在右侧按钮且是已打开状态
+					isMoved = true;
+				}
+			}
+			if (isMoved) {
+				event.stopPropagation();
+				event.detail.gesture.preventDefault();
+				var translate = event.detail.deltaX;
+				if (isOpened) {
+					if (openedActions === 'right') {
+						translate = translate - sliderActionRightWidth;
+					} else {
+						translate = translate + sliderActionLeftWidth;
+					}
+				}
+				if ((translate > 0 && !buttonsLeft) || (translate < 0 && !buttonsRight)) {
+					if (!isOpened) {
+						return;
+					}
+					translate = 0;
+				}
+				if (translate < 0) {
+					sliderDirection = 'toLeft';
+				} else if (translate > 0) {
+					sliderDirection = 'toRight';
+				} else {
+					if (!sliderDirection) {
+						sliderDirection = 'toLeft';
+					}
+				}
+				if (!sliderRequestAnimationFrame) {
+					updateTranslate();
+				}
+				translateX = translate;
+			}
+		},
+		flick: function(event) {
+			if (isMoved) {
+				event.stopPropagation();
+			}
+		},
+		swipeleft: function(event) {
+			if (isMoved) {
+				event.stopPropagation();
+			}
+		},
+		swiperight: function(event) {
+			if (isMoved) {
+				event.stopPropagation();
+			}
+		},
+		dragend: function(event) {
+			if (!isMoved) {
+				return;
+			}
+			event.stopPropagation();
+			if (sliderRequestAnimationFrame) {
+				cancelAnimationFrame(sliderRequestAnimationFrame);
+				sliderRequestAnimationFrame = null;
+			}
+			var detail = event.detail;
+			isMoved = false;
+			var action = 'close';
+			var actionsWidth = sliderDirection === 'toLeft' ? sliderActionRightWidth : sliderActionLeftWidth;
+			var isToggle = detail.swipe || (Math.abs(translateX) > actionsWidth / 2);
+			if (isToggle) {
+				if (!isOpened) {
+					action = 'open';
+				} else if (detail.direction === 'left' && openedActions === 'right') {
+					action = 'open';
+				} else if (detail.direction === 'right' && openedActions === 'left') {
+					action = 'open';
+				}
+
+			}
+			cell.classList.add(CLASS_TRANSITIONING);
+			var buttons;
+			if (action === 'open') {
+				var newTranslate = sliderDirection === 'toLeft' ? -actionsWidth : actionsWidth;
+				setTranslate(sliderHandle, newTranslate);
+				buttons = sliderDirection === 'toLeft' ? buttonsRight : buttonsLeft;
+				if (typeof buttons !== 'undefined') {
+					var button = null;
+					for (var i = 0; i < buttons.length; i++) {
+						button = buttons[i];
+						setTranslate(button, newTranslate);
+					}
+					button.parentNode.classList.add(CLASS_SELECTED);
+					cell.classList.add(CLASS_SELECTED);
+					if (!isOpened) {
+						$.trigger(cell, sliderDirection === 'toLeft' ? 'slideleft' : 'slideright');
+					}
+				}
+			} else {
+				setTranslate(sliderHandle, 0);
+				sliderActionLeft && sliderActionLeft.classList.remove(CLASS_SELECTED);
+				sliderActionRight && sliderActionRight.classList.remove(CLASS_SELECTED);
+				cell.classList.remove(CLASS_SELECTED);
+			}
+			var buttonOffset;
+			if (buttonsLeft && buttonsLeft.length > 0 && buttonsLeft !== buttons) {
+				for (var i = 0, len = buttonsLeft.length; i < len; i++) {
+					var buttonLeft = buttonsLeft[i];
+					buttonOffset = buttonLeft._buttonOffset;
+					if (typeof buttonOffset === 'undefined') {
+						buttonLeft._buttonOffset = sliderActionLeftWidth - buttonLeft.offsetLeft - buttonLeft.offsetWidth;
+					}
+					setTranslate(buttonLeft, buttonOffset);
+				}
+			}
+			if (buttonsRight && buttonsRight.length > 0 && buttonsRight !== buttons) {
+				for (var i = 0, len = buttonsRight.length; i < len; i++) {
+					var buttonRight = buttonsRight[i];
+					buttonOffset = buttonRight._buttonOffset;
+					if (typeof buttonOffset === 'undefined') {
+						buttonRight._buttonOffset = buttonRight.offsetLeft;
+					}
+					setTranslate(buttonRight, -buttonOffset);
+				}
+			}
+		}
+	};
+
+	function toggleEvents(element, isRemove) {
+		var method = !!isRemove ? 'removeEventListener' : 'addEventListener';
+		element[method]('drag', handleEvent);
+		element[method]('dragend', handleEvent);
+		element[method]('swiperight', handleEvent);
+		element[method]('swipeleft', handleEvent);
+		element[method]('flick', handleEvent);
+	};
+	/**
+	 * 打开滑动菜单
+	 * @param {Object} el
+	 * @param {Object} direction
+	 */
+	$.swipeoutOpen = function(el, direction) {
+		if (!el) return;
+		var classList = el.classList;
+		if (classList.contains(CLASS_SELECTED)) return;
+		if (!direction) {
+			if (el.querySelector(SELECTOR_SLIDER_RIGHT)) {
+				direction = 'right';
+			} else {
+				direction = 'left';
+			}
+		}
+		var swipeoutAction = el.querySelector($.classSelector(".slider-" + direction));
+		if (!swipeoutAction) return;
+		swipeoutAction.classList.add(CLASS_SELECTED);
+		classList.add(CLASS_SELECTED);
+		classList.remove(CLASS_TRANSITIONING);
+		var buttons = swipeoutAction.querySelectorAll(SELECTOR_BUTTON);
+		var swipeoutWidth = swipeoutAction.offsetWidth;
+		var translate = (direction === 'right') ? -swipeoutWidth : swipeoutWidth;
+		var length = buttons.length;
+		var button;
+		for (var i = 0; i < length; i++) {
+			button = buttons[i];
+			if (direction === 'right') {
+				setTranslate(button, -button.offsetLeft);
+			} else {
+				setTranslate(button, (swipeoutWidth - button.offsetWidth - button.offsetLeft));
+			}
+		}
+		classList.add(CLASS_TRANSITIONING);
+		for (var i = 0; i < length; i++) {
+			setTranslate(buttons[i], translate);
+		}
+		setTranslate(el.querySelector(SELECTOR_SLIDER_HANDLE), translate);
+	};
+	/**
+	 * 关闭滑动菜单
+	 * @param {Object} el
+	 */
+	$.swipeoutClose = function(el) {
+		if (!el) return;
+		var classList = el.classList;
+		if (!classList.contains(CLASS_SELECTED)) return;
+		var direction = el.querySelector(SELECTOR_SLIDER_RIGHT + SELECTOR_SELECTED) ? 'right' : 'left';
+		var swipeoutAction = el.querySelector($.classSelector(".slider-" + direction));
+		if (!swipeoutAction) return;
+		swipeoutAction.classList.remove(CLASS_SELECTED);
+		classList.remove(CLASS_SELECTED);
+		classList.add(CLASS_TRANSITIONING);
+		var buttons = swipeoutAction.querySelectorAll(SELECTOR_BUTTON);
+		var swipeoutWidth = swipeoutAction.offsetWidth;
+		var length = buttons.length;
+		var button;
+		setTranslate(el.querySelector(SELECTOR_SLIDER_HANDLE), 0);
+		for (var i = 0; i < length; i++) {
+			button = buttons[i];
+			if (direction === 'right') {
+				setTranslate(button, (-button.offsetLeft));
+			} else {
+				setTranslate(button, (swipeoutWidth - button.offsetWidth - button.offsetLeft));
+			}
+		}
+	};
+
+	window.addEventListener($.EVENT_END, function(event) { //使用touchend来取消高亮,避免一次点击既不触发tap,doubletap,longtap的事件
+		if (!cell) {
+			return;
+		}
+		toggleActive(false);
+		sliderHandle && toggleEvents(cell, true);
+	});
+	window.addEventListener($.EVENT_CANCEL, function(event) { //使用touchcancel来取消高亮,避免一次点击既不触发tap,doubletap,longtap的事件
+		if (!cell) {
+			return;
+		}
+		toggleActive(false);
+		sliderHandle && toggleEvents(cell, true);
+	});
+	var radioOrCheckboxClick = function(event) {
+		var type = event.target && event.target.type || '';
+		if (type === 'radio' || type === 'checkbox') {
+			return;
+		}
+		var classList = cell.classList;
+		if (classList.contains('mui-radio')) {
+			var input = cell.querySelector('input[type=radio]');
+			if (input) {
+				//				input.click();
+				if (!input.disabled && !input.readOnly) {
+					input.checked = !input.checked;
+					$.trigger(input, 'change');
+				}
+			}
+		} else if (classList.contains('mui-checkbox')) {
+			var input = cell.querySelector('input[type=checkbox]');
+			if (input) {
+				//				input.click();
+				if (!input.disabled && !input.readOnly) {
+					input.checked = !input.checked;
+					$.trigger(input, 'change');
+				}
+			}
+		}
+	};
+	//fixed hashchange(android)
+	window.addEventListener($.EVENT_CLICK, function(e) {
+		if (cell && cell.classList.contains('mui-collapse')) {
+			e.preventDefault();
+		}
+	});
+	window.addEventListener('doubletap', function(event) {
+		if (cell) {
+			radioOrCheckboxClick(event);
+		}
+	});
+	var preventDefaultException = /^(INPUT|TEXTAREA|BUTTON|SELECT)$/;
+	window.addEventListener('tap', function(event) {
+		if (!cell) {
+			return;
+		}
+		var isExpand = false;
+		var classList = cell.classList;
+		var ul = cell.parentNode;
+		if (ul && ul.classList.contains(CLASS_RADIO_VIEW)) {
+			if (classList.contains(CLASS_SELECTED)) {
+				return;
+			}
+			var selected = ul.querySelector('li' + SELECTOR_SELECTED);
+			if (selected) {
+				selected.classList.remove(CLASS_SELECTED);
+			}
+			classList.add(CLASS_SELECTED);
+			$.trigger(cell, 'selected', {
+				el: cell
+			});
+			return;
+		}
+		if (classList.contains('mui-collapse') && !cell.parentNode.classList.contains('mui-unfold')) {
+			if (!preventDefaultException.test(event.target.tagName)) {
+				event.detail.gesture.preventDefault();
+			}
+
+			if (!classList.contains(CLASS_ACTIVE)) { //展开时,需要收缩其他同类
+				var collapse = cell.parentNode.querySelector('.mui-collapse.mui-active');
+				if (collapse) {
+					collapse.classList.remove(CLASS_ACTIVE);
+				}
+				isExpand = true;
+			}
+			classList.toggle(CLASS_ACTIVE);
+			if (isExpand) {
+				//触发展开事件
+				$.trigger(cell, 'expand');
+
+				//scroll
+				//暂不滚动
+				// var offsetTop = $.offset(cell).top;
+				// var scrollTop = document.body.scrollTop;
+				// var height = window.innerHeight;
+				// var offsetHeight = cell.offsetHeight;
+				// var cellHeight = (offsetTop - scrollTop + offsetHeight);
+				// if (offsetHeight > height) {
+				// 	$.scrollTo(offsetTop, 300);
+				// } else if (cellHeight > height) {
+				// 	$.scrollTo(cellHeight - height + scrollTop, 300);
+				// }
+			}
+		} else {
+			radioOrCheckboxClick(event);
+		}
+	});
+})(mui, window, document);
+(function($, window) {
+	/**
+	 * 警告消息框
+	 */
+	$.alert = function(message, title, btnValue, callback) {
+		if ($.os.plus) {
+			if (typeof message === 'undefined') {
+				return;
+			} else {
+				if (typeof title === 'function') {
+					callback = title;
+					title = null;
+					btnValue = '确定';
+				} else if (typeof btnValue === 'function') {
+					callback = btnValue;
+					btnValue = null;
+				}
+				$.plusReady(function() {
+					plus.nativeUI.alert(message, callback, title, btnValue);
+				});
+			}
+
+		} else {
+			//TODO H5版本
+			window.alert(message);
+		}
+	};
+
+})(mui, window);
+(function($, window) {
+	/**
+	 * 确认消息框
+	 */
+	$.confirm = function(message, title, btnArray, callback) {
+		if ($.os.plus) {
+			if (typeof message === 'undefined') {
+				return;
+			} else {
+				if (typeof title === 'function') {
+					callback = title;
+					title = null;
+					btnArray = null;
+				} else if (typeof btnArray === 'function') {
+					callback = btnArray;
+					btnArray = null;
+				}
+				$.plusReady(function() {
+					plus.nativeUI.confirm(message, callback, title, btnArray);
+				});
+			}
+
+		} else {
+			//H5版本,0为确认,1为取消
+			if (window.confirm(message)) {
+				callback({
+					index: 0
+				});
+			} else {
+				callback({
+					index: 1
+				});
+			}
+		}
+	};
+
+})(mui, window);
+(function($, window) {
+	/**
+	 * 输入对话框
+	 */
+	$.prompt = function(text, defaultText, title, btnArray, callback) {
+		if ($.os.plus) {
+			if (typeof message === 'undefined') {
+				return;
+			} else {
+
+				if (typeof defaultText === 'function') {
+					callback = defaultText;
+					defaultText = null;
+					title = null;
+					btnArray = null;
+				} else if (typeof title === 'function') {
+					callback = title;
+					title = null;
+					btnArray = null;
+				} else if (typeof btnArray === 'function') {
+					callback = btnArray;
+					btnArray = null;
+				}
+				$.plusReady(function() {
+					plus.nativeUI.prompt(text, callback, title, defaultText, btnArray);
+				});
+			}
+
+		} else {
+			//H5版本(确认index为0,取消index为1)
+			var result = window.prompt(text);
+			if (result) {
+				callback({
+					index: 0,
+					value: result
+				});
+			} else {
+				callback({
+					index: 1,
+					value: ''
+				});
+			}
+		}
+	};
+
+})(mui, window);
+(function($, window) {
+	var CLASS_ACTIVE = 'mui-active';
+	/**
+	 * 自动消失提示框
+	 */
+	$.toast = function(message,options) {
+		var durations = {
+		    'long': 3500,
+		    'short': 2000
+		};
+
+		//计算显示时间
+		 options = $.extend({
+	        duration: 'short'
+	    }, options || {});
+
+
+		if ($.os.plus && options.type !== 'div') {
+			//默认显示在底部;
+			$.plusReady(function() {
+				plus.nativeUI.toast(message, {
+					verticalAlign: 'bottom',
+					duration:options.duration
+				});
+			});
+		} else {
+			if (typeof options.duration === 'number') {
+		        duration = options.duration>0 ? options.duration:durations['short'];
+		    } else {
+		        duration = durations[options.duration];
+		    }
+		    if (!duration) {
+		        duration = durations['short'];
+		    }
+			var toast = document.createElement('div');
+			toast.classList.add('mui-toast-container');
+			toast.innerHTML = '<div class="' + 'mui-toast-message' + '">' + message + '</div>';
+			toast.addEventListener('webkitTransitionEnd', function() {
+				if (!toast.classList.contains(CLASS_ACTIVE)) {
+					toast.parentNode.removeChild(toast);
+					toast = null;
+				}
+			});
+			//点击则自动消失
+			toast.addEventListener('click', function() {
+		        toast.parentNode.removeChild(toast);
+		        toast = null;
+		    });
+			document.body.appendChild(toast);
+			toast.offsetHeight;
+			toast.classList.add(CLASS_ACTIVE);
+			setTimeout(function() {
+				toast && toast.classList.remove(CLASS_ACTIVE);
+			}, duration);
+			
+			return {
+		        isVisible: function() {return !!toast;}
+		    }
+		}   
+	};
+
+})(mui, window);
+/**
+ * Popup(alert,confirm,prompt)  
+ * @param {Object} $
+ * @param {Object} window
+ * @param {Object} document
+ */
+(function($, window, document) {
+    var CLASS_POPUP = 'mui-popup';
+    var CLASS_POPUP_BACKDROP = 'mui-popup-backdrop';
+    var CLASS_POPUP_IN = 'mui-popup-in';
+    var CLASS_POPUP_OUT = 'mui-popup-out';
+    var CLASS_POPUP_INNER = 'mui-popup-inner';
+    var CLASS_POPUP_TITLE = 'mui-popup-title';
+    var CLASS_POPUP_TEXT = 'mui-popup-text';
+    var CLASS_POPUP_INPUT = 'mui-popup-input';
+    var CLASS_POPUP_BUTTONS = 'mui-popup-buttons';
+    var CLASS_POPUP_BUTTON = 'mui-popup-button';
+    var CLASS_POPUP_BUTTON_BOLD = 'mui-popup-button-bold';
+    var CLASS_POPUP_BACKDROP = 'mui-popup-backdrop';
+    var CLASS_ACTIVE = 'mui-active';
+
+    var popupStack = [];
+    var backdrop = (function() {
+        var element = document.createElement('div');
+        element.classList.add(CLASS_POPUP_BACKDROP);
+        element.addEventListener($.EVENT_MOVE, $.preventDefault);
+        element.addEventListener('webkitTransitionEnd', function() {
+            if (!this.classList.contains(CLASS_ACTIVE)) {
+                element.parentNode && element.parentNode.removeChild(element);
+            }
+        });
+        return element;
+    }());
+
+    var createInput = function(placeholder) {
+        return '<div class="' + CLASS_POPUP_INPUT + '"><input type="text" autofocus placeholder="' + (placeholder || '') + '"/></div>';
+    };
+    var createInner = function(message, title, extra) {
+        return '<div class="' + CLASS_POPUP_INNER + '"><div class="' + CLASS_POPUP_TITLE + '">' + title + '</div><div class="' + CLASS_POPUP_TEXT + '">' + message.replace(/\r\n/g, "<br/>").replace(/\n/g, "<br/>") + '</div>' + (extra || '') + '</div>';
+    };
+    var createButtons = function(btnArray) {
+        var length = btnArray.length;
+        var btns = [];
+        for (var i = 0; i < length; i++) {
+            btns.push('<span class="' + CLASS_POPUP_BUTTON + (i === length - 1 ? (' ' + CLASS_POPUP_BUTTON_BOLD) : '') + '">' + btnArray[i] + '</span>');
+        }
+        return '<div class="' + CLASS_POPUP_BUTTONS + '">' + btns.join('') + '</div>';
+    };
+
+    var createPopup = function(html, callback) {
+        var popupElement = document.createElement('div');
+        popupElement.className = CLASS_POPUP;
+        popupElement.innerHTML = html;
+        var removePopupElement = function() {
+            popupElement.parentNode && popupElement.parentNode.removeChild(popupElement);
+            popupElement = null;
+        };
+        popupElement.addEventListener($.EVENT_MOVE, $.preventDefault);
+        popupElement.addEventListener('webkitTransitionEnd', function(e) {
+            if (popupElement && e.target === popupElement && popupElement.classList.contains(CLASS_POPUP_OUT)) {
+                removePopupElement();
+            }
+        });
+        popupElement.style.display = 'block';
+        document.body.appendChild(popupElement);
+        popupElement.offsetHeight;
+        popupElement.classList.add(CLASS_POPUP_IN);
+
+        if (!backdrop.classList.contains(CLASS_ACTIVE)) {
+            backdrop.style.display = 'block';
+            document.body.appendChild(backdrop);
+            backdrop.offsetHeight;
+            backdrop.classList.add(CLASS_ACTIVE);
+        }
+        var btns = $.qsa('.' + CLASS_POPUP_BUTTON, popupElement);
+        var input = popupElement.querySelector('.' + CLASS_POPUP_INPUT + ' input');
+        var popup = {
+            element: popupElement,
+            close: function(index, animate) {
+                if (popupElement) {
+                    var result = callback && callback({
+                        index: index || 0,
+                        value: input && input.value || ''
+                    });
+                    if (result === false) { //返回false则不关闭当前popup
+                        return;
+                    }
+                    if (animate !== false) {
+                        popupElement.classList.remove(CLASS_POPUP_IN);
+                        popupElement.classList.add(CLASS_POPUP_OUT);
+                    } else {
+                        removePopupElement();
+                    }
+                    popupStack.pop();
+                    //如果还有其他popup,则不remove backdrop
+                    if (popupStack.length) {
+                        popupStack[popupStack.length - 1]['show'](animate);
+                    } else {
+                        backdrop.classList.remove(CLASS_ACTIVE);
+                    }
+                }
+            }
+        };
+        var handleEvent = function(e) {
+            popup.close(btns.indexOf(e.target));
+        };
+        $(popupElement).on('tap', '.' + CLASS_POPUP_BUTTON, handleEvent);
+        if (popupStack.length) {
+            popupStack[popupStack.length - 1]['hide']();
+        }
+        popupStack.push({
+            close: popup.close,
+            show: function(animate) {
+                popupElement.style.display = 'block';
+                popupElement.offsetHeight;
+                popupElement.classList.add(CLASS_POPUP_IN);
+            },
+            hide: function() {
+                popupElement.style.display = 'none';
+                popupElement.classList.remove(CLASS_POPUP_IN);
+            }
+        });
+        return popup;
+    };
+    var createAlert = function(message, title, btnValue, callback, type) {
+        if (typeof message === 'undefined') {
+            return;
+        } else {
+            if (typeof title === 'function') {
+                callback = title;
+                type = btnValue;
+                title = null;
+                btnValue = null;
+            } else if (typeof btnValue === 'function') {
+                type = callback;
+                callback = btnValue;
+                btnValue = null;
+            }
+        }
+        if (!$.os.plus || type === 'div') {
+            return createPopup(createInner(message, title || '提示') + createButtons([btnValue || '确定']), callback);
+        }
+        return plus.nativeUI.alert(message, callback, title || '提示', btnValue || '确定');
+    };
+    var createConfirm = function(message, title, btnArray, callback, type) {
+        if (typeof message === 'undefined') {
+            return;
+        } else {
+            if (typeof title === 'function') {
+                callback = title;
+                type = btnArray;
+                title = null;
+                btnArray = null;
+            } else if (typeof btnArray === 'function') {
+                type = callback;
+                callback = btnArray;
+                btnArray = null;
+            }
+        }
+        if (!$.os.plus || type === 'div') {
+            return createPopup(createInner(message, title || '提示') + createButtons(btnArray || ['取消', '确认']), callback);
+        }
+        return plus.nativeUI.confirm(message, callback, title, btnArray || ['取消', '确认']);
+    };
+    var createPrompt = function(message, placeholder, title, btnArray, callback, type) {
+        if (typeof message === 'undefined') {
+            return;
+        } else {
+            if (typeof placeholder === 'function') {
+                callback = placeholder;
+                type = title;
+                placeholder = null;
+                title = null;
+                btnArray = null;
+            } else if (typeof title === 'function') {
+                callback = title;
+                type = btnArray;
+                title = null;
+                btnArray = null;
+            } else if (typeof btnArray === 'function') {
+                type = callback;
+                callback = btnArray;
+                btnArray = null;
+            }
+        }
+        if (!$.os.plus || type === 'div') {
+            return createPopup(createInner(message, title || '提示', createInput(placeholder)) + createButtons(btnArray || ['取消', '确认']), callback);
+        }
+        return plus.nativeUI.prompt(message, callback, title || '提示', placeholder, btnArray || ['取消', '确认']);
+    };
+    var closePopup = function() {
+        if (popupStack.length) {
+            popupStack[popupStack.length - 1]['close']();
+            return true;
+        } else {
+            return false;
+        }
+    };
+    var closePopups = function() {
+        while (popupStack.length) {
+            popupStack[popupStack.length - 1]['close']();
+        }
+    };
+
+    $.closePopup = closePopup;
+    $.closePopups = closePopups;
+    $.alert = createAlert;
+    $.confirm = createConfirm;
+    $.prompt = createPrompt;
+})(mui, window, document);
+(function($, document) {
+	var CLASS_PROGRESSBAR = 'mui-progressbar';
+	var CLASS_PROGRESSBAR_IN = 'mui-progressbar-in';
+	var CLASS_PROGRESSBAR_OUT = 'mui-progressbar-out';
+	var CLASS_PROGRESSBAR_INFINITE = 'mui-progressbar-infinite';
+
+	var SELECTOR_PROGRESSBAR = '.mui-progressbar';
+
+	var _findProgressbar = function(container) {
+		container = $(container || 'body');
+		if (container.length === 0) return;
+		container = container[0];
+		if (container.classList.contains(CLASS_PROGRESSBAR)) {
+			return container;
+		}
+		var progressbars = container.querySelectorAll(SELECTOR_PROGRESSBAR);
+		if (progressbars) {
+			for (var i = 0, len = progressbars.length; i < len; i++) {
+				var progressbar = progressbars[i];
+				if (progressbar.parentNode === container) {
+					return progressbar;
+				}
+			}
+		}
+	};
+	/**
+	 * 创建并显示进度条 
+	 * @param {Object} container  可选,默认body,支持selector,DOM Node,mui wrapper
+	 * @param {Object} progress 可选,undefined表示循环,数字表示具体进度
+	 * @param {Object} color 可选,指定颜色样式(目前暂未提供实际样式,可暂时不暴露此参数)
+	 */
+	var showProgressbar = function(container, progress, color) {
+		if (typeof container === 'number') {
+			color = progress;
+			progress = container;
+			container = 'body';
+		}
+		container = $(container || 'body');
+		if (container.length === 0) return;
+		container = container[0];
+		var progressbar;
+		if (container.classList.contains(CLASS_PROGRESSBAR)) {
+			progressbar = container;
+		} else {
+			var progressbars = container.querySelectorAll(SELECTOR_PROGRESSBAR + ':not(.' + CLASS_PROGRESSBAR_OUT + ')');
+			if (progressbars) {
+				for (var i = 0, len = progressbars.length; i < len; i++) {
+					var _progressbar = progressbars[i];
+					if (_progressbar.parentNode === container) {
+						progressbar = _progressbar;
+						break;
+					}
+				}
+			}
+			if (!progressbar) {
+				progressbar = document.createElement('span');
+				progressbar.className = CLASS_PROGRESSBAR + ' ' + CLASS_PROGRESSBAR_IN + (typeof progress !== 'undefined' ? '' : (' ' + CLASS_PROGRESSBAR_INFINITE)) + (color ? (' ' + CLASS_PROGRESSBAR + '-' + color) : '');
+				if (typeof progress !== 'undefined') {
+					progressbar.innerHTML = '<span></span>';
+				}
+				container.appendChild(progressbar);
+			} else {
+				progressbar.classList.add(CLASS_PROGRESSBAR_IN);
+			}
+		}
+		if (progress) setProgressbar(container, progress);
+		return progressbar;
+	};
+	/**
+	 * 关闭进度条 
+	 * @param {Object} container 可选,默认body,支持selector,DOM Node,mui wrapper
+	 */
+	var hideProgressbar = function(container) {
+		var progressbar = _findProgressbar(container);
+		if (!progressbar) {
+			return;
+		}
+		var classList = progressbar.classList;
+		if (!classList.contains(CLASS_PROGRESSBAR_IN) || classList.contains(CLASS_PROGRESSBAR_OUT)) {
+			return;
+		}
+		classList.remove(CLASS_PROGRESSBAR_IN);
+		classList.add(CLASS_PROGRESSBAR_OUT);
+		progressbar.addEventListener('webkitAnimationEnd', function() {
+			progressbar.parentNode && progressbar.parentNode.removeChild(progressbar);
+			progressbar = null;
+		});
+		return;
+	};
+	/**
+	 * 设置指定进度条进度 
+	 * @param {Object} container  可选,默认body,支持selector,DOM Node,mui wrapper
+	 * @param {Object} progress 可选,默认0 取值范围[0-100]
+	 * @param {Object} speed 进度条动画时间
+	 */
+	var setProgressbar = function(container, progress, speed) {
+		if (typeof container === 'number') {
+			speed = progress;
+			progress = container;
+			container = false;
+		}
+		var progressbar = _findProgressbar(container);
+		if (!progressbar || progressbar.classList.contains(CLASS_PROGRESSBAR_INFINITE)) {
+			return;
+		}
+		if (progress) progress = Math.min(Math.max(progress, 0), 100);
+		progressbar.offsetHeight;
+		var span = progressbar.querySelector('span');
+		if (span) {
+			var style = span.style;
+			style.webkitTransform = 'translate3d(' + (-100 + progress) + '%,0,0)';
+			if (typeof speed !== 'undefined') {
+				style.webkitTransitionDuration = speed + 'ms';
+			} else {
+				style.webkitTransitionDuration = '';
+			}
+		}
+		return progressbar;
+	};
+	$.fn.progressbar = function(options) {
+		var progressbarApis = [];
+		options = options || {};
+		this.each(function() {
+			var self = this;
+			var progressbarApi = self.mui_plugin_progressbar;
+			if (!progressbarApi) {
+				self.mui_plugin_progressbar = progressbarApi = {
+					options: options,
+					setOptions: function(options) {
+						this.options = options;
+					},
+					show: function() {
+						return showProgressbar(self, this.options.progress, this.options.color);
+					},
+					setProgress: function(progress) {
+						return setProgressbar(self, progress);
+					},
+					hide: function() {
+						return hideProgressbar(self);
+					}
+				};
+			} else if (options) {
+				progressbarApi.setOptions(options);
+			}
+			progressbarApis.push(progressbarApi);
+		});
+		return progressbarApis.length === 1 ? progressbarApis[0] : progressbarApis;
+	};
+	//	$.setProgressbar = setProgressbar;
+	//	$.showProgressbar = showProgressbar;
+	//	$.hideProgressbar = hideProgressbar;
+})(mui, document);
+/**
+ * Input(TODO resize)
+ * @param {type} $
+ * @param {type} window
+ * @param {type} document
+ * @returns {undefined}
+ */
+(function($, window, document) {
+	var CLASS_ICON = 'mui-icon';
+	var CLASS_ICON_CLEAR = 'mui-icon-clear';
+	var CLASS_ICON_SPEECH = 'mui-icon-speech';
+	var CLASS_ICON_SEARCH = 'mui-icon-search';
+	var CLASS_ICON_PASSWORD = 'mui-icon-eye';
+	var CLASS_INPUT_ROW = 'mui-input-row';
+	var CLASS_PLACEHOLDER = 'mui-placeholder';
+	var CLASS_TOOLTIP = 'mui-tooltip';
+	var CLASS_HIDDEN = 'mui-hidden';
+	var CLASS_FOCUSIN = 'mui-focusin';
+	var SELECTOR_ICON_CLOSE = '.' + CLASS_ICON_CLEAR;
+	var SELECTOR_ICON_SPEECH = '.' + CLASS_ICON_SPEECH;
+	var SELECTOR_ICON_PASSWORD = '.' + CLASS_ICON_PASSWORD;
+	var SELECTOR_PLACEHOLDER = '.' + CLASS_PLACEHOLDER;
+	var SELECTOR_TOOLTIP = '.' + CLASS_TOOLTIP;
+
+	var findRow = function(target) {
+		for (; target && target !== document; target = target.parentNode) {
+			if (target.classList && target.classList.contains(CLASS_INPUT_ROW)) {
+				return target;
+			}
+		}
+		return null;
+	};
+	var Input = function(element, options) {
+		this.element = element;
+		this.options = options || {
+			actions: 'clear'
+		};
+		if (~this.options.actions.indexOf('slider')) { //slider
+			this.sliderActionClass = CLASS_TOOLTIP + ' ' + CLASS_HIDDEN;
+			this.sliderActionSelector = SELECTOR_TOOLTIP;
+		} else { //clear,speech,search
+			if (~this.options.actions.indexOf('clear')) {
+				this.clearActionClass = CLASS_ICON + ' ' + CLASS_ICON_CLEAR + ' ' + CLASS_HIDDEN;
+				this.clearActionSelector = SELECTOR_ICON_CLOSE;
+			}
+			if (~this.options.actions.indexOf('speech')) { //only for 5+
+				this.speechActionClass = CLASS_ICON + ' ' + CLASS_ICON_SPEECH;
+				this.speechActionSelector = SELECTOR_ICON_SPEECH;
+			}
+			if (~this.options.actions.indexOf('search')) {
+				this.searchActionClass = CLASS_PLACEHOLDER;
+				this.searchActionSelector = SELECTOR_PLACEHOLDER;
+			}
+			if (~this.options.actions.indexOf('password')) {
+				this.passwordActionClass = CLASS_ICON + ' ' + CLASS_ICON_PASSWORD;
+				this.passwordActionSelector = SELECTOR_ICON_PASSWORD;
+			}
+		}
+		this.init();
+	};
+	Input.prototype.init = function() {
+		this.initAction();
+		this.initElementEvent();
+	};
+	Input.prototype.initAction = function() {
+		var self = this;
+
+		var row = self.element.parentNode;
+		if (row) {
+			if (self.sliderActionClass) {
+				self.sliderAction = self.createAction(row, self.sliderActionClass, self.sliderActionSelector);
+			} else {
+				if (self.searchActionClass) {
+					self.searchAction = self.createAction(row, self.searchActionClass, self.searchActionSelector);
+					self.searchAction.addEventListener('tap', function(e) {
+						$.focus(self.element);
+						e.stopPropagation();
+					});
+				}
+				if (self.speechActionClass) {
+					self.speechAction = self.createAction(row, self.speechActionClass, self.speechActionSelector);
+					self.speechAction.addEventListener('click', $.stopPropagation);
+					self.speechAction.addEventListener('tap', function(event) {
+						self.speechActionClick(event);
+					});
+				}
+				if (self.clearActionClass) {
+					self.clearAction = self.createAction(row, self.clearActionClass, self.clearActionSelector);
+					self.clearAction.addEventListener('tap', function(event) {
+						self.clearActionClick(event);
+					});
+				}
+				if (self.passwordActionClass) {
+					self.passwordAction = self.createAction(row, self.passwordActionClass, self.passwordActionSelector);
+					self.passwordAction.addEventListener('tap', function(event) {
+						self.passwordActionClick(event);
+					});
+				}
+			}
+		}
+	};
+	Input.prototype.createAction = function(row, actionClass, actionSelector) {
+		var action = row.querySelector(actionSelector);
+		if (!action) {
+			var action = document.createElement('span');
+			action.className = actionClass;
+			if (actionClass === this.searchActionClass) {
+				action.innerHTML = '<span class="' + CLASS_ICON + ' ' + CLASS_ICON_SEARCH + '"></span><span>' + this.element.getAttribute('placeholder') + '</span>';
+				this.element.setAttribute('placeholder', '');
+				if (this.element.value.trim()) {
+					row.classList.add('mui-active');
+				}
+			}
+			row.insertBefore(action, this.element.nextSibling);
+		}
+		return action;
+	};
+	Input.prototype.initElementEvent = function() {
+		var element = this.element;
+
+		if (this.sliderActionClass) {
+			var tooltip = this.sliderAction;
+			var timer = null;
+			var showTip = function() { //每次重新计算是因为控件可能被隐藏,初始化时计算是不正确的
+				tooltip.classList.remove(CLASS_HIDDEN);
+				var offsetLeft = element.offsetLeft;
+				var width = element.offsetWidth - 28;
+				var tooltipWidth = tooltip.offsetWidth;
+				var distince = Math.abs(element.max - element.min);
+				var scaleWidth = (width / distince) * Math.abs(element.value - element.min);
+				tooltip.style.left = (14 + offsetLeft + scaleWidth - tooltipWidth / 2) + 'px';
+				tooltip.innerText = element.value;
+				if (timer) {
+					clearTimeout(timer);
+				}
+				timer = setTimeout(function() {
+					tooltip.classList.add(CLASS_HIDDEN);
+				}, 1000);
+			};
+			element.addEventListener('input', showTip);
+			element.addEventListener('tap', showTip);
+			element.addEventListener($.EVENT_MOVE, function(e) {
+				e.stopPropagation();
+			});
+		} else {
+			if (this.clearActionClass) {
+				var action = this.clearAction;
+				if (!action) {
+					return;
+				}
+				$.each(['keyup', 'change', 'input', 'focus', 'cut', 'paste'], function(index, type) {
+					(function(type) {
+						element.addEventListener(type, function() {
+							action.classList[element.value.trim() ? 'remove' : 'add'](CLASS_HIDDEN);
+						});
+					})(type);
+				});
+				element.addEventListener('blur', function() {
+					action.classList.add(CLASS_HIDDEN);
+				});
+			}
+			if (this.searchActionClass) {
+				element.addEventListener('focus', function() {
+					element.parentNode.classList.add('mui-active');
+				});
+				element.addEventListener('blur', function() {
+					if (!element.value.trim()) {
+						element.parentNode.classList.remove('mui-active');
+					}
+				});
+			}
+		}
+	};
+	Input.prototype.setPlaceholder = function(text) {
+		if (this.searchActionClass) {
+			var placeholder = this.element.parentNode.querySelector(SELECTOR_PLACEHOLDER);
+			placeholder && (placeholder.getElementsByTagName('span')[1].innerText = text);
+		} else {
+			this.element.setAttribute('placeholder', text);
+		}
+	};
+	Input.prototype.passwordActionClick = function(event) {
+		if (this.element.type === 'text') {
+			this.element.type = 'password';
+		} else {
+			this.element.type = 'text';
+		}
+		this.passwordAction.classList.toggle('mui-active');
+		event.preventDefault();
+	};
+	Input.prototype.clearActionClick = function(event) {
+		var self = this;
+		self.element.value = '';
+		$.focus(self.element);
+		self.clearAction.classList.add(CLASS_HIDDEN);
+		event.preventDefault();
+	};
+	Input.prototype.speechActionClick = function(event) {
+		if (window.plus) {
+			var self = this;
+			var oldValue = self.element.value;
+			self.element.value = '';
+			document.body.classList.add(CLASS_FOCUSIN);
+			plus.speech.startRecognize({
+				engine: 'iFly'
+			}, function(s) {
+				self.element.value += s;
+				$.focus(self.element);
+				plus.speech.stopRecognize();
+				$.trigger(self.element, 'recognized', {
+					value: self.element.value
+				});
+				if (oldValue !== self.element.value) {
+					$.trigger(self.element, 'change');
+					$.trigger(self.element, 'input');
+				}
+				// document.body.classList.remove(CLASS_FOCUSIN);
+			}, function(e) {
+				document.body.classList.remove(CLASS_FOCUSIN);
+			});
+		} else {
+			alert('only for 5+');
+		}
+		event.preventDefault();
+	};
+	$.fn.input = function(options) {
+		var inputApis = [];
+		this.each(function() {
+			var inputApi = null;
+			var actions = [];
+			var row = findRow(this.parentNode);
+			if (this.type === 'range' && row.classList.contains('mui-input-range')) {
+				actions.push('slider');
+			} else {
+				var classList = this.classList;
+				if (classList.contains('mui-input-clear')) {
+					actions.push('clear');
+				}
+				if (!($.os.android && $.os.stream) && classList.contains('mui-input-speech')) {
+					actions.push('speech');
+				}
+				if (classList.contains('mui-input-password')) {
+					actions.push('password');
+				}
+				if (this.type === 'search' && row.classList.contains('mui-search')) {
+					actions.push('search');
+				}
+			}
+			var id = this.getAttribute('data-input-' + actions[0]);
+			if (!id) {
+				id = ++$.uuid;
+				inputApi = $.data[id] = new Input(this, {
+					actions: actions.join(',')
+				});
+				for (var i = 0, len = actions.length; i < len; i++) {
+					this.setAttribute('data-input-' + actions[i], id);
+				}
+			} else {
+				inputApi = $.data[id];
+			}
+			inputApis.push(inputApi);
+		});
+		return inputApis.length === 1 ? inputApis[0] : inputApis;
+	};
+	$.ready(function() {
+		$('.mui-input-row input').input();
+	});
+})(mui, window, document);
+(function($, window) {
+    var CLASS_ACTIVE = 'mui-active';
+    var rgbaRegex = /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*(?:\.\d+)?)\)$/;
+    var getColor = function(colorStr) {
+        var matches = colorStr.match(rgbaRegex);
+        if (matches && matches.length === 5) {
+            return [
+                matches[1],
+                matches[2],
+                matches[3],
+                matches[4]
+            ];
+        }
+        return [];
+    };
+    var Transparent = function(element, options) {
+        this.element = element;
+        this.options = $.extend({
+            top: 0, //距离顶部高度(到达该高度即触发)
+            offset: 150, //滚动透明距离
+            duration: 16, //过渡时间
+            scrollby: window//监听滚动距离容器
+        }, options || {});
+
+        this.scrollByElem = this.options.scrollby || window;
+        if (!this.scrollByElem) {
+            throw new Error("监听滚动的元素不存在");
+        }
+        this.isNativeScroll = false;
+        if (this.scrollByElem === window) {
+            this.isNativeScroll = true;
+        } else if (!~this.scrollByElem.className.indexOf('mui-scroll-wrapper')) {
+            this.isNativeScroll = true;
+        }
+
+        this._style = this.element.style;
+        this._bgColor = this._style.backgroundColor;
+        var color = getColor(mui.getStyles(this.element, 'backgroundColor'));
+        if (color.length) {
+            this._R = color[0];
+            this._G = color[1];
+            this._B = color[2];
+            this._A = parseFloat(color[3]);
+            this.lastOpacity = this._A;
+            this._bufferFn = $.buffer(this.handleScroll, this.options.duration, this);
+            this.initEvent();
+        } else {
+            throw new Error("元素背景颜色必须为RGBA");
+        }
+    };
+
+    Transparent.prototype.initEvent = function() {
+        this.scrollByElem.addEventListener('scroll', this._bufferFn);
+        if (this.isNativeScroll) { //原生scroll
+            this.scrollByElem.addEventListener($.EVENT_MOVE, this._bufferFn);
+        }
+    }
+    Transparent.prototype.handleScroll = function(e) {
+        var y = window.scrollY;
+        if (!this.isNativeScroll && e && e.detail) {
+            y = -e.detail.y;
+        }
+        var opacity = (y - this.options.top) / this.options.offset + this._A;
+        opacity = Math.min(Math.max(this._A, opacity), 1);
+        this._style.backgroundColor = 'rgba(' + this._R + ',' + this._G + ',' + this._B + ',' + opacity + ')';
+        if (opacity > this._A) {
+            this.element.classList.add(CLASS_ACTIVE);
+        } else {
+            this.element.classList.remove(CLASS_ACTIVE);
+        }
+        if (this.lastOpacity !== opacity) {
+            $.trigger(this.element, 'alpha', {
+                alpha: opacity
+            });
+            this.lastOpacity = opacity;
+        }
+    };
+    Transparent.prototype.destory = function() {
+        this.scrollByElem.removeEventListener('scroll', this._bufferFn);
+        this.scrollByElem.removeEventListener($.EVENT_MOVE, this._bufferFn);
+        this.element.style.backgroundColor = this._bgColor;
+        this.element.mui_plugin_transparent = null;
+    };
+    $.fn.transparent = function(options) {
+        options = options || {};
+        var transparentApis = [];
+        this.each(function() {
+            var transparentApi = this.mui_plugin_transparent;
+            if (!transparentApi) {
+                var top = this.getAttribute('data-top');
+                var offset = this.getAttribute('data-offset');
+                var duration = this.getAttribute('data-duration');
+                var scrollby = this.getAttribute('data-scrollby');
+                if (top !== null && typeof options.top === 'undefined') {
+                    options.top = top;
+                }
+                if (offset !== null && typeof options.offset === 'undefined') {
+                    options.offset = offset;
+                }
+                if (duration !== null && typeof options.duration === 'undefined') {
+                    options.duration = duration;
+                }
+                if (scrollby !== null && typeof options.scrollby === 'undefined') {
+                    options.scrollby = document.querySelector(scrollby) || window;
+                }
+                transparentApi = this.mui_plugin_transparent = new Transparent(this, options);
+            }
+            transparentApis.push(transparentApi);
+        });
+        return transparentApis.length === 1 ? transparentApis[0] : transparentApis;
+    };
+    $.ready(function() {
+        $('.mui-bar-transparent').transparent();
+    });
+})(mui, window);
+/**
+ * 数字输入框
+ * varstion 1.0.1
+ * by Houfeng
+ * Houfeng@DCloud.io
+ */
+
+(function($) {
+
+    var touchSupport = ('ontouchstart' in document);
+    var tapEventName = touchSupport ? 'tap' : 'click';
+    var changeEventName = 'change';
+    var holderClassName = 'mui-numbox';
+    var plusClassSelector = '.mui-btn-numbox-plus,.mui-numbox-btn-plus';
+    var minusClassSelector = '.mui-btn-numbox-minus,.mui-numbox-btn-minus';
+    var inputClassSelector = '.mui-input-numbox,.mui-numbox-input';
+
+    var Numbox = $.Numbox = $.Class.extend({
+        /**
+         * 构造函数
+         **/
+        init: function(holder, options) {
+            var self = this;
+            if (!holder) {
+                throw "构造 numbox 时缺少容器元素";
+            }
+            self.holder = holder;
+            options = options || {};
+            options.step = parseInt(options.step || 1);
+            self.options = options;
+            self.input = $.qsa(inputClassSelector, self.holder)[0];
+            self.plus = $.qsa(plusClassSelector, self.holder)[0];
+            self.minus = $.qsa(minusClassSelector, self.holder)[0];
+            self.checkValue();
+            self.initEvent();
+        },
+        /**
+         * 初始化事件绑定
+         **/
+        initEvent: function() {
+            var self = this;
+            self.plus.addEventListener(tapEventName, function(event) {
+                var val = parseInt(self.input.value) + self.options.step;
+                self.input.value = val.toString();
+                $.trigger(self.input, changeEventName, null);
+            });
+            self.minus.addEventListener(tapEventName, function(event) {
+                var val = parseInt(self.input.value) - self.options.step;
+                self.input.value = val.toString();
+                $.trigger(self.input, changeEventName, null);
+            });
+            self.input.addEventListener(changeEventName, function(event) {
+                self.checkValue();
+                var val = parseInt(self.input.value);
+                //触发顶层容器
+                $.trigger(self.holder, changeEventName, {
+                    value: val
+                });
+            });
+        },
+        /**
+         * 获取当前值
+         **/
+        getValue: function() {
+            var self = this;
+            return parseInt(self.input.value);
+        },
+        /**
+         * 验证当前值是法合法
+         **/
+        checkValue: function() {
+            var self = this;
+            var val = self.input.value;
+            if (val == null || val == '' || isNaN(val)) {
+                self.input.value = self.options.min || 0;
+                self.minus.disabled = self.options.min != null;
+            } else {
+                var val = parseInt(val);
+                if (self.options.max != null && !isNaN(self.options.max) && val >= parseInt(self.options.max)) {
+                    val = self.options.max;
+                    self.plus.disabled = true;
+                } else {
+                    self.plus.disabled = false;
+                }
+                if (self.options.min != null && !isNaN(self.options.min) && val <= parseInt(self.options.min)) {
+                    val = self.options.min;
+                    self.minus.disabled = true;
+                } else {
+                    self.minus.disabled = false;
+                }
+                self.input.value = val;
+            }
+        },
+        /**
+         * 更新选项
+         **/
+        setOption: function(name, value) {
+            var self = this;
+            self.options[name] = value;
+        },
+        /**
+         * 动态设置新值
+         **/
+        setValue: function(value) {
+            this.input.value = value;
+            this.checkValue();
+        }
+    });
+
+    $.fn.numbox = function(options) {
+        var instanceArray = [];
+        //遍历选择的元素
+        this.each(function(i, element) {
+            if (element.numbox) {
+                return;
+            }
+            if (options) {
+                element.numbox = new Numbox(element, options);
+            } else {
+                var optionsText = element.getAttribute('data-numbox-options');
+                var options = optionsText ? JSON.parse(optionsText) : {};
+                options.step = element.getAttribute('data-numbox-step') || options.step;
+                options.min = element.getAttribute('data-numbox-min') || options.min;
+                options.max = element.getAttribute('data-numbox-max') || options.max;
+                element.numbox = new Numbox(element, options);
+            }
+        });
+        return this[0] ? this[0].numbox : null;
+    }
+
+    //自动处理 class='mui-locker' 的 dom
+    $.ready(function() {
+        $('.' + holderClassName).numbox();
+    });
+
+}(mui));
+/**
+ * Button
+ * @param {type} $
+ * @param {type} window
+ * @param {type} document
+ * @returns {undefined}
+ */
+(function($, window, document) {
+    var CLASS_ICON = 'mui-icon';
+    var CLASS_DISABLED = 'mui-disabled';
+
+    var STATE_RESET = 'reset';
+    var STATE_LOADING = 'loading';
+
+    var defaultOptions = {
+        loadingText: 'Loading...', //文案
+        loadingIcon: 'mui-spinner' + ' ' + 'mui-spinner-white', //图标,可为空
+        loadingIconPosition: 'left' //图标所处位置,仅支持left|right
+    };
+
+    var Button = function(element, options) {
+        this.element = element;
+        this.options = $.extend({}, defaultOptions, options);
+        if (!this.options.loadingText) {
+            this.options.loadingText = defaultOptions.loadingText;
+        }
+        if (this.options.loadingIcon === null) {
+            this.options.loadingIcon = 'mui-spinner';
+            if ($.getStyles(this.element, 'color') === 'rgb(255, 255, 255)') {
+                this.options.loadingIcon += ' ' + 'mui-spinner-white';
+            }
+        }
+        this.isInput = this.element.tagName === 'INPUT';
+        this.resetHTML = this.isInput ? this.element.value : this.element.innerHTML;
+        this.state = '';
+    };
+    Button.prototype.loading = function() {
+        this.setState(STATE_LOADING);
+    };
+    Button.prototype.reset = function() {
+        this.setState(STATE_RESET);
+    };
+    Button.prototype.setState = function(state) {
+        if (this.state === state) {
+            return false;
+        }
+        this.state = state;
+        if (state === STATE_RESET) {
+            this.element.disabled = false;
+            this.element.classList.remove(CLASS_DISABLED);
+            this.setHtml(this.resetHTML);
+        } else if (state === STATE_LOADING) {
+            this.element.disabled = true;
+            this.element.classList.add(CLASS_DISABLED);
+            var html = this.isInput ? this.options.loadingText : ('<span>' + this.options.loadingText + '</span>');
+            if (this.options.loadingIcon && !this.isInput) {
+                if (this.options.loadingIconPosition === 'right') {
+                    html += '&nbsp;<span class="' + this.options.loadingIcon + '"></span>';
+                } else {
+                    html = '<span class="' + this.options.loadingIcon + '"></span>&nbsp;' + html;
+                }
+            }
+            this.setHtml(html);
+        }
+    };
+    Button.prototype.setHtml = function(html) {
+        if (this.isInput) {
+            this.element.value = html;
+        } else {
+            this.element.innerHTML = html;
+        }
+    }
+    $.fn.button = function(state) {
+        var buttonApis = [];
+        this.each(function() {
+            var buttonApi = this.mui_plugin_button;
+            if (!buttonApi) {
+                var loadingText = this.getAttribute('data-loading-text');
+                var loadingIcon = this.getAttribute('data-loading-icon');
+                var loadingIconPosition = this.getAttribute('data-loading-icon-position');
+                this.mui_plugin_button = buttonApi = new Button(this, {
+                    loadingText: loadingText,
+                    loadingIcon: loadingIcon,
+                    loadingIconPosition: loadingIconPosition
+                });
+            }
+            if (state === STATE_LOADING || state === STATE_RESET) {
+                buttonApi.setState(state);
+            }
+            buttonApis.push(buttonApi);
+        });
+        return buttonApis.length === 1 ? buttonApis[0] : buttonApis;
+    };
+})(mui, window, document);

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 5 - 0
hybrid/html/xuanfu/js/mui.min.js


+ 20 - 0
index.html

@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+	<script>
+	  var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
+	    CSS.supports('top: constant(a)'))
+	  document.write(
+	    '<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
+	    (coverSupport ? ', viewport-fit=cover' : '') + '" />')
+	</script>
+    <title></title>
+    <!--preload-links-->
+    <!--app-context-->
+  </head>
+  <body>
+    <div id="app"><!--app-html--></div>
+    <script type="module" src="/main.js"></script>
+  </body>
+</html>

+ 24 - 0
locale/en.json

@@ -0,0 +1,24 @@
+{
+  "locale.auto": "System",
+  "locale.en": "English",
+  "locale.zh-hans": "简体中文",
+  "locale.zh-hant": "繁体中文",
+  "locale.ja": "日语",
+  "index.title": "Hello i18n",
+  "index.home": "Home",
+  "index.component": "Component",
+  "index.api": "API",
+  "index.schema": "Schema",
+  "index.demo": "uni-app globalization",
+  "index.demo-description": "Include uni-framework, manifest.json, pages.json, tabbar, Page, Component, API, Schema",
+  "index.detail": "Detail",
+  "index.language": "Language",
+  "index.language-info": "Settings",
+  "index.system-language": "System language",
+  "index.application-language": "Application language",
+  "index.language-change-confirm": "Applying this setting will restart the app",
+  "api.message": "Message",
+  "schema.name": "Name",
+  "schema.add": "Add",
+  "schema.add-success": "Add success"
+}

+ 14 - 0
locale/index.js

@@ -0,0 +1,14 @@
+import en from './en.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+import ja from './ja.json'
+import yuenan from './yuenan.json'
+
+export default {
+	en,
+	'zh-Hans': zhHans,
+	'zh-Hant': zhHant,
+	ja,
+	'yuenan':yuenan,
+	'uni.chooseImage.cancel':'取消'
+}

+ 23 - 0
locale/ja.json

@@ -0,0 +1,23 @@
+{
+  "locale.auto": "システム",
+  "locale.en": "英語",
+  "locale.zh-hans": "简体中文",
+  "locale.zh-hant": "繁体中文",
+  "locale.ja": "日语",
+  "index.title": "Hello i18n",
+  "index.home": "ホーム",
+  "index.component": "コンポーネント",
+  "index.api": "API",
+  "index.schema": "Schema",
+  "index.demo": "uni-app globalization",
+  "index.demo-description": "ユニフレームワーク、manifest.json、pages.json、タブバー、ページ、コンポーネント、APIを含める、Schema",
+  "index.detail": "詳細",
+  "index.language": "言語",
+  "index.language-info": "設定",
+  "index.system-language": "システム言語",
+  "index.application-language": "アプリケーション言語",
+  "index.language-change-confirm": "この設定を適用すると、アプリが再起動します",
+  "api.message": "メッセージ",
+  "schema.add": "追加",
+  "schema.add-success": "成功を追加"
+}

+ 36 - 0
locale/uni-app.ja.json

@@ -0,0 +1,36 @@
+{
+  "common": {
+    "uni.app.quit": "もう一度押すと、アプリケーションが終了します",
+    "uni.async.error": "サーバーへの接続がタイムアウトしました。画面をクリックして再試行してください",
+    "uni.showActionSheet.cancel": "キャンセル",
+    "uni.showToast.unpaired": "使用するには、showToastとhideToastをペアにする必要があることに注意してください",
+    "uni.showLoading.unpaired": "使用するには、showLoadingとhideLoadingをペアにする必要があることに注意してください",
+    "uni.showModal.cancel": "キャンセル",
+    "uni.showModal.confirm": "OK",
+    "uni.chooseImage.cancel": "キャンセル",
+    "uni.chooseImage.sourceType.album": "アルバムから選択",
+    "uni.chooseImage.sourceType.camera": "カメラ",
+    "uni.chooseVideo.cancel": "キャンセル",
+    "uni.chooseVideo.sourceType.album": "アルバムから選択",
+    "uni.chooseVideo.sourceType.camera": "カメラ",
+    "uni.previewImage.cancel": "キャンセル",
+    "uni.previewImage.button.save": "画像を保存",
+    "uni.previewImage.save.success": "画像をアルバムに正常に保存します",
+    "uni.previewImage.save.fail": "画像をアルバムに保存できませんでした",
+    "uni.setClipboardData.success": "コンテンツがコピーされました",
+    "uni.scanCode.title": "スキャンコード",
+    "uni.scanCode.album": "アルバム",
+    "uni.scanCode.fail": "認識に失敗しました",
+    "uni.scanCode.flash.on": "タッチして点灯",
+    "uni.scanCode.flash.off": "タップして閉じる",
+    "uni.startSoterAuthentication.authContent": "指紋認識...",
+    "uni.picker.done": "完了",
+    "uni.picker.cancel": "キャンセル",
+    "uni.video.danmu": "「弾幕」",
+    "uni.video.volume": "ボリューム",
+    "uni.button.feedback.title": "質問のフィードバック",
+    "uni.button.feedback.send": "送信"
+  },
+  "ios": {},
+  "android": {}
+}

+ 352 - 0
locale/yuenan.json

@@ -0,0 +1,352 @@
+{
+"api.dingweishibai": "Không định vị được vị trí !",
+"api.huobidanwei": "₫",
+"api.message": "Gợi ý",
+"api.nqdbddh": "Bạn có chắc chắn thực hiện cuộc gọi không?",
+"audioCall.cteyhcall": "Người dùng CTE IM Call",
+"audioCall.hujiaosb": "Thông tin người dùng bất thường và cuộc gọi không thành công.",
+"audioCall.imtitle": "IM Cuộc gọi thoại",
+"audioCall.jieshuth": "Kết thúc cuộc gọi",
+"audioCall.jietingyy": "Chấp nhận cuộc gọi",
+"audioCall.jujuejieting": "Từ chối trả lời",
+"audioCall.weilianjie": "Ngoại tuyến",
+"audioCall.wfjt": "Không thể kết nối",
+"audioCall.yiguanduan": "Bị ngắt",
+"audioCall.yijietong": "Đã kết nối",
+"audioCall.yilianjie": "Trực tuyến",
+"audioCall.zhengzhj": "Đang gọi",
+"audioCall.zhengzjt": "Đang kết nối",
+"exchange.chakanxinxi": "Thông tin",
+"exchange.cteyhmsg": "Thông tin người dùng CTE IM",
+"exchange.qingshurxx": "Vui lòng nhập thông tin",
+"exchange.quxiao": "Hủy bỏ",
+"exchange.tupian": "Hình ảnh",
+"exchange.wenjian": "Tài liệu",
+"exchange.xinxi": "Tin nhắn",
+"GoeasyExchange.anzhuly": "Giữ ghi âm",
+"GoeasyExchange.chehui": "Thu hồi",
+"GoeasyExchange.chongxbj": "Sửa lại",
+"GoeasyExchange.dingdanhao": "Số đơn hàng",
+"GoeasyExchange.dingdanxx": "Thông tin đơn hàng",
+"GoeasyExchange.duoxuan": "Nhiều lựa chọn",
+"GoeasyExchange.fasong": "Gửi",
+"GoeasyExchange.fasongxx": "Gửi tin nhắn",
+"GoeasyExchange.gethistory": "Click để nhận tin nhắn lịch sử",
+"GoeasyExchange.gong": "Tổng",
+"GoeasyExchange.huoquqxsb": "Lỗi khi lấy quyền ghi âm",
+"GoeasyExchange.jian": "Cái",
+"GoeasyExchange.luyincw": "Ghi âm thất bại",
+"GoeasyExchange.luyinshib": "Ghi âm không thành công vui lòng kiểm tra quyền micrô",
+"GoeasyExchange.luyinsjtd": "Thời gian ghi âm quá ngắn",
+"GoeasyExchange.nichlytxx": "Thu hồi tin nhắn",
+"GoeasyExchange.nohistory": "Không còn tin tức lịch sử nào nữa.",
+"GoeasyExchange.qingshcs": "Vui lòng thử lại sau",
+"GoeasyExchange.qingxsqly": "Vui lòng cho phép trước khi gửi tin nhắn thoại!",
+"GoeasyExchange.qingxuanzdd": "Vui lòng chọn một đơn hàng",
+"GoeasyExchange.querensanc": "Xác nhận xóa?",
+"GoeasyExchange.quxiao": "Hủy bỏ",
+"GoeasyExchange.sanchu": "Xoá",
+"GoeasyExchange.shipinxx": "Tin nhắn video",
+"GoeasyExchange.songkfs": "Thả Gửi",
+"GoeasyExchange.tonghua": "Gọi điện",
+"GoeasyExchange.tupian": "Hình ảnh",
+"GoeasyExchange.tupianxx": "Thông tin hình ảnh",
+"GoeasyExchange.weidu": "Chưa đọc",
+"GoeasyExchange.yidu": "Đã đọc",
+"GoeasyExchange.yuyinxx": "[Tin nhắn thoại]",
+"index.api": "API",
+"index.application-language": "Ngôn ngữ ứng dụng",
+"index.component": "Thành phần",
+"index.detail": "Chi tiết",
+"index.djjwty": "Nhấp vào Đăng nhập/Đăng ký để đồng ý",
+"index.gengxintx": "Lời nhắc cập nhật",
+"index.gjqhxz": "Vui lòng chọn mã quốc gia",
+"index.home": "Trang chủ",
+"index.huodaofukan": "Trả tiền khi nhận hàng",
+"index.jiedanfengx": "Thanh toán khi nhận hàng, tài xế ứng tiền trước, đảm bảo trách nhiệm.",
+"index.language": "Ngôn ngữ",
+"index.language-change-confirm": "Áp dụng cài đặt này sẽ khởi động lại Ứng dụng",
+"index.language-info": "Thông tin ngôn ngữ",
+"index.qiangzhigx": "Buộc cập nhật lên phiên bản mới nhất",
+"index.queren": "Xác nhận",
+"index.quxiao": "Hủy bỏ",
+"index.schema": "Lược đồ",
+"index.shoukuanwc": "Thanh toán khi nhận hàng. Đã thu tiền?",
+"index.system-language": "Ngôn ngữ hệ thống",
+"index.tijiao": "Lưu",
+"index.title": "Xin chào i18n",
+"index.tuijiangx": "Đề xuất phiên bản mới hơn hủy để tiếp tục sử dụng phiên bản hiện tại",
+"index.yinsizc": "《Chính Sách Bảo Mật》",
+"index.yonghuxiey": "《Quy Định Người Dùng》",
+"index.youhuiq": "Phiếu ưu đãi",
+"index.yuedu": "Đọc",
+"index.zhoubianfw": "Phạm vi hoạt động",
+"kefu.dingdandb": "Vui lòng chụp màn hình đơn đặt hàng trên điện thoại và chụp ảnh so sánh đơn đặt hàng giấy.",
+"kefu.pzcanksl": "Ví dụ về chụp hình ",
+"kefu.shangptp": "Vui lòng tải lên sản phẩm bạn đã nhận được",
+"kefu.weishiyong": "Không sử dụng",
+"kefu.wentileix": "Vui lòng chọn loại câu hỏi",
+"kefu.yishiyong": "Đã sử dụng",
+"locale.auto": "Hệ thống",
+"locale.en": "Tiếng Anh",
+"locale.ja": "Tiếng Nhật",
+"locale.yuenan": "Tiếng Việt",
+"locale.zh-hans": "Tiếng Trung giản thể",
+"locale.zh-hant": "Tiếng Trung phồn thể",
+"order.benyue": "Tháng này",
+"order.candianyw": "Bữa ăn bị nhầm",
+"order.chakantp": "Xem ảnh",
+"order.chongpaidd": "Đặt hàng lại",
+"order.chongxuan": "Chọn lại",
+"order.daiquhuo": "Đang đợi lấy hàng",
+"order.dangqmydd": "Hiện tại chưa có đơn hàng nào",
+"order.danweidan": "Đơn ",
+"order.dingdanjin": "Tổng thu đơn hàng",
+"order.haimeixinxi": "Còn hay không thông tin phản hồi",
+"order.haimeiysj": "Chưa có dữ liệu",
+"order.jinri": "Hôm nay",
+"order.jintian": "Hôm nay",
+"order.juli": "Khoảng cách",
+"order.kefujs": "Liên hệ hỗ trợ CSKH",
+"order.kefuliuy": "Chăm sóc khách hàng trả lời",
+"order.lianxi": "Điện thoại",
+"order.lianxikef": "Liên hệ hỗ trợ CKSH",
+"order.luxian": "Tuyến đường",
+"order.menpaizp": "Hình ảnh số nhà",
+"order.peisongfei": "Phí giao hàng",
+"order.peisonglc": "Khoảng cách giao hàng",
+"order.peisongzh": "Đang giao hàng",
+"order.qingxiansctp": "Vui lòng tải lên hình ảnh",
+"order.qingxuanz": "Vui lòng chọn",
+"order.qishouly": "Tin nhắn tài xế",
+"order.qishouyhts": "Chi phí chêch lệch từ phí giao hàng và ưu đãi giảm giá từ điểm thưởng sẽ do công ty kết toán với nhân viên giao hàng.",
+"order.qiszhifts": "Vui lòng thanh toán cho người bán theo tổng số tiền hàng hóa",
+"order.qrcandianyw": "Xác nhận bữa ăn có sai không?",
+"order.qrqucanshib": "Xác nhận lấy thức ăn thất bại không?",
+"order.qucanshib": "Nhận thức ăn thất bại",
+"order.querendaodian": "Đã xác nhận tới cửa hàng",
+"order.quhuodian": "Điểm lấy hàng ",
+"order.qupaishe": "Chụp ảnh",
+"order.qushangc": "Chọn từ album",
+"order.quxiaodingdan": "Hủy đơn hàng",
+"order.ridingdan": "Đặt hàng hàng ngày",
+"order.shanchutp": "Xóa ảnh?",
+"order.shangjiayqrcc": "Người bán đã xác nhận đơn đặt hàng.",
+"order.shangpinxj": "Tổng tiền sản phẩm",
+"order.shouhou": "Hoàn tiền/Hậu mãi",
+"order.shouhuodian": "Điểm giao hàng",
+"order.shouhwc": "Hoàn thành hậu mãi",
+"order.shuaxinList": "Làm mới nhiệm vụ",
+"order.songda": "Giao Xong",
+"order.tian": "Ngày",
+"order.wancheng": "Hoàn thành",
+"order.wanchengdingd": "Hoàn thành đơn hàng",
+"order.wanchengquhuo": "Hoàn thành lấy hàng ",
+"order.weizhifu": "Chưa thanh toán",
+"order.wentimiaos": "Vui lòng nhập mô tả vấn đề...",
+"order.wodedingdan": "Đơn hàng của tôi",
+"order.xingqi": "Tuần",
+"order.xinrenwu": "Nhiệm vụ mới",
+"order.xuanzeriqi": "Chọn ngày",
+"order.yinhangculz": "Ngân hàng đang xử lý",
+"order.yishouli": "Đã được chấp nhận",
+"order.yizhifu": "Đã trả tiền ",
+"order.yonghuly": "Tin nhắn người dùng",
+"order.youhuijine": "Ưu đãi giá giảm",
+"order.youxindd": "Có đơn hàng mới vui lòng bấm vào 'làm mới danh sách'",
+"order.yue": "Tháng ",
+"order.yuedingdan": "Đặt hàng hàng tháng",
+"order.zaixianduihua": "Trò chuyện trực tuyến",
+"order.zhangdan": "Hóa đơn",
+"order.zhi": "ĐẾN",
+"order.zhifuchg": "Thanh toán thành công",
+"order.zhifushib": "Thanh toán thất bại",
+"order.zuotian": "Hôm qua",
+"schema.add": "Thêm mới",
+"schema.add-success": "Thêm thành công",
+"schema.name": "Họ Tên",
+"shouye.changzhuqy": "Khu vực cố định",
+"shouye.dangqianjdms": "Chế độ nhận đơn hiện tại",
+"shouye.jieshoudd": "Chấp nhận đơn hàng",
+"shouye.jindanms": "Chế độ gần đơn",
+"shouye.paidanshez": "Cài đặt phân đơn",
+"shouye.querenkaig": "Xác nhận bắt đầu công việc",
+"shouye.querenkaigN": "Sau khi bắt đầu công việc hệ thống sẽ giao cho bạn đơn hàng phù hợp",
+"shouye.querenxiax": "Xác nhận ngoại tuyến",
+"shouye.querenxiaxN": "Sau khi offline hệ thống sẽ không giao đơn hàng cho bạn nữa",
+"shouye.qushezhi": "Đi tới cài đặt",
+"shouye.shezhijdms": "Chọn chế độ đặt hàng",
+"shouye.tongshijdl": "Số lượng đặt hàng đồng thời",
+"shouye.zhidongjpd": "Nhận điều đơn tự động",
+"shouye.zhidongjpdN": "Lo lắng về việc thiếu đơn đặt hàng? Sau khi được bật nó sẽ tự động được nhận cho bạn sau khi đếm ngược đến lệnh giao hàng kết thúc",
+"tixian.bangdingyhk": "Liên kết thẻ ngân hàng",
+"tixian.baozhengjgz": "Quy tắc ký quỹ",
+"tixian.bdyhk": "Bạn chưa liên kết thẻ ngân hàng. Hãy thiết lập ngay!",
+"tixian.chikaren": "Chủ thẻ",
+"tixian.chongzhi": "Nạp tiền",
+"tixian.fencheng": "Doanh thu",
+"tixian.jiaonabzj": "Nạp phí đảm bảo",
+"tixian.jiaoyimima": "Mật khẩu giao dịch",
+"tixian.jiebang": "Huỷ liên kết",
+"tixian.jieshouka": "Nhận thẻ",
+"tixian.jiner": "Số tiền",
+"tixian.kahao": "Số thẻ",
+"tixian.kezhuancdk": "Có thể chuyển ra thẻ",
+"tixian.qingbangdbryhk": "Hãy liên kết tài khoản ngân hàng của bạn",
+"tixian.qingshubzjje": "Vui lòng nhập số tiền ký quỹ",
+"tixian.qingshuckrxm": "Vui lòng nhập tên chủ thẻ",
+"tixian.qingshujymm": "Vui lòng nhập mật khẩu giao dịch",
+"tixian.qingshukh": "Vui lòng nhập số thẻ",
+"tixian.qingtxwzyhkxx": "Vui lòng nhập thông tin ngân hàng hoàn chỉnh",
+"tixian.quanbu": "Tất cả",
+"tixian.querenjieb": "Xác nhận hủy liên kết",
+"tixian.querentixian": "Xác nhận rút tiền",
+"tixian.shenqingshenhe": "Đăng kí xét duyệt",
+"tixian.shenqingshij": "Thời gian đăng kí",
+"tixian.shuishikt": "Có thể rút bất cứ lúc nào",
+"tixian.tianjayhk": "+ Thêm thẻ ngân hàng",
+"tixian.tixian": "Rút tiền",
+"tixian.tuibaozj": "Trả lại phí đảm bảo",
+"tixian.txdzts": "Dự kiến ​​sẽ đến trong vòng 24 giờ sau khi rút tiền vui lòng kiên nhẫn chờ đợi",
+"tixian.txyhk": "Thẻ rút tiền mặt",
+"tixian.wodeyhk": "Thẻ ngân hàng của tôi",
+"tixian.xuanzeyanhang": "Vui lòng điền tài khoản ngân hàng",
+"tixian.yhkguanli": "Chỉnh sửa thẻ ngân hàng",
+"tixian.yinghang": "Ngân hàng",
+"tixian.zijinanquan": "An ninh tài chính",
+"user.anquanzhongxin": "Trung tâm an toàn ",
+"user.anzhuangsbcs": "Cài đặt không thành công vui lòng thử lại sau",
+"user.appleNav": "Bản đồ Apple",
+"user.baiduNav": "Bản đồ Baidu",
+"user.bangdingsj": "Số điện thoại liên kết",
+"user.caozuojid": "Hoạt động dễ dàng",
+"user.chengyaojm": "Chân Thành Mời Bạn Tham Gia!",
+"user.chepaihao": "Biển số xe",
+"user.chongxinhq": "Lấy lại",
+"user.chongzhimima": "Đặt lại mật khẩu",
+"user.dangqianbb": "Phiên bản hiện tại",
+"user.denglu": "Đăng nhập",
+"user.denglucg": "Đăng nhập thành công",
+"user.denglumima": "Mật khẩu đăng nhập",
+"user.denglushib": "Đăng nhập thất bại",
+"user.denglushixiao": "Đăng nhập không hợp lệ vui lòng đăng nhập lại",
+"user.dengluzhuce": "Đăng nhập/Đăng ký",
+"user.duolaodd": "Làm nhiều có nhiều thu nhập phong phú",
+"user.fadan": "Đơn phạt ",
+"user.gaodeNav": "Bản đồ Cao Đức",
+"user.gerenxinxi": "Thông tin cá nhân",
+"user.gerenzhongxin": "Trung tâm cá nhân",
+"user.googleNav": "Bản đồ Google",
+"user.hailiangdd": "Nhiều đơn đặt hàng",
+"user.huoquyanzhegm": "Lấy mã xác thực",
+"user.huoquzxbb": "Phiên bản mới nhất",
+"user.jiangtonggj": "Phương tiện di chuyển",
+"user.jiankangzh": "Giấy chứng nhận sức khỏe",
+"user.jiedanshezhi": "Cài đặt nhận hàng",
+"user.kaishixiaz": "Đã bắt đầu tải xuống",
+"user.kefuzhongxin": "Dịch vụ chăm sóc khách hàng",
+"user.lijizhuce": "Đăng ký ngay",
+"user.meiyouzhanghao": "Không có tài khoản? ",
+"user.mimadenglu": "Mật khẩu đăng nhập",
+"user.navType": "Phương tiện hoạt động",
+"user.navTypeby": "Xe máy",
+"user.navTypedr": "Lái xe",
+"user.nicheng": "Họ Tên",
+"user.peixunzhongx": "Trung tâm đào tạo",
+"user.pingjia": "Đánh giá",
+"user.qianwsmrz": "Đi đến xác thực tên thật",
+"user.qingshezfmm": "Vui lòng đặt mật khẩu thanh toán",
+"user.qingshezmim": "Vui lòng đặt mật khẩu đăng nhập mới",
+"user.qingshurmim": "Vui lòng nhập mật khẩu của bạn",
+"user.qingshurnc": "Hãy nhập một tên gọi",
+"user.qingshursfzh": "Vui lòng nhập số căn cước ",
+"user.qingshurxm": "Vui lòng nhập tên của bạn",
+"user.qingshuydlmm": "Vui lòng nhập mật khẩu đăng nhập ban đầu",
+"user.qingshuyzfmm": "Vui lòng nhập mật khẩu thanh toán ban đầu",
+"user.qingsryaoqing": "Vui lòng nhập mã mời (tùy chọn)",
+"user.qingzaisryc": "Vui lòng nhập lại",
+"user.qsrchepaihao": "Vui lòng nhập biển số xe",
+"user.qsrshouihao": "Vui lòng nhập số điện thoại",
+"user.qsrzhanghao": "Vui lòng nhập tài khoản của bạn",
+"user.querenscdzt": "Bạn có chắc chắn xóa hình ảnh 'x' không? ",
+"user.querentcdq": "Bạn có muốn đăng xuất khỏi tài khoản hiện tại không?",
+"user.sanchutp": "Xóa hình ảnh",
+"user.shangxianzh": "Đang trực tuyến",
+"user.shenhezhong": "Đang xét duyệt",
+"user.shenqingshcg": "Đăng kí xét duyệt thành công",
+"user.shezhichengg": "Thiết lập thành công",
+"user.shenfenzh": "CMND/CCCD/Hộ chiếu",
+"user.shezhinc": "Cài đặt tên gọi người dùng",
+"user.shezhishibai": "Thiết lập không thành công",
+"user.shifbaiduNav": "Mở 'Baidu Map' để điều hướng không?",
+"user.shifgaodeNav": "Mở 'Gauder bản đồ' để điều hướng?",
+"user.shifougengxin": "Bạn có muốn cập nhật lên phiên bản mới nhất không?",
+"user.shimingwsmrz": " Định danh cá nhân",
+"user.shirkek": "Thu nhập xứng đáng",
+"user.tuichudengl": "Đăng xuất",
+"user.tupiansccg": "Hình ảnh được tải lên thành công",
+"user.wangjimima": "Quên mật khẩu? ",
+"user.weianzhuangapp": "Ứng dụng bản đồ đã chỉ định chưa được cài đặt cục bộ",
+"user.weirenzheng": "Chưa xác minh",
+"user.weishezhi": "Chưa thiết lập",
+"user.xiaxianzh": "Ngoại tuyến",
+"user.xiazaijindu": "Tiến độ tải xuống",
+"user.xiazaizhong": "Đang tải xuống vui lòng không thoát",
+"user.xieyiguiz": "Quy tắc thoả thuận",
+"user.xiugai": "Sửa lại",
+"user.xuanzedaoh": "Chọn ứng dụng bản đồ",
+"user.yanzhengma": "Vui lòng nhập mã xác thực",
+"user.yanzhengmdl": "Đăng nhập mã xác minh",
+"user.yirenzheng": "Đã xác thực",
+"user.yishizxbb": "Đã là phiên bản mới nhất",
+"user.yiyouzhhdl": "Đã có tài khoản Đăng nhập",
+"user.zhanghaowsh": "Tài khoản chưa được xét duyệt",
+"user.zhegnjiants": "Vui lòng upload mặt trước và mặt sau CMND sổ hộ khẩu công chứng lý lịch tư pháp",
+"user.zhifumima": "mật khẩu thanh toán",
+"user.zhuce": "Đăng ký",
+"user.zhucechengg": "Đăng ký thành công",
+"user.zhuxiaodqzh": "Xóa tài khoản hiện tại?",
+"user.zhuxiaozh": "Xóa tài khoản",
+"zhanghu.baozhegnjin": "Phí bảo đảm",
+"zhanghu.benqiwcdl": "Tổng cộng hoàn thành đơn đặt hàng trong kỳ này",
+"zhanghu.benqleijsr": "Thu nhập tích lũy kỳ này",
+"zhanghu.chakanmx": "Xem chi tiết",
+"zhanghu.daozhang": "Tài khoản",
+"zhanghu.huodongsr": "Thu nhập từ sự kiện",
+"zhanghu.jinrishour": "Thu nhập hôm nay",
+"zhanghu.jinriwanch": "Đã hoàn thành hôm nay",
+"zhanghu.jinrizhangd": "Hóa đơn hôm nay",
+"zhanghu.peisongsr": "Doanh thu giao hàng",
+"zhanghu.qingxuanzbzje": "Vui lòng chọn số tiền đảm bảo để nạp tiền",
+"zhanghu.querenzhifubzj": "Xác nhận thanh toán tiền ký quỹ?",
+"zhanghu.shouzhitj": "Thống kê thu nhập và chi tiêu",
+"zhanghu.shujutj": "Thống kê dữ liệu",
+"zhanghu.tixianjil": "Lịch sử rút tiền",
+"zhanghu.wodezhanghu": "Tài khoản của tôi",
+"zhanghu.xuanzezhif": "Vui lòng chọn phương thức thanh toán",
+"zhanghu.yinhangka": "Thẻ ngân hàng",
+"zhanghu.yuer": "Số dư ",
+"zhanghu.yuji": "Ước tính",
+"zhanghu.yujishouru": "Thu nhập ước tính",
+"zhanghu.yujizhichu": "Chi tiêu ước tính",
+"zhanghu.zhanghumingxi": "Chi tiết tài khoản",
+"zhanghu.zhuangtai": "Trạng thái",
+"tixian.baozhengjyt":"Quy tắc ký quỹ",
+"tixian.baozhengjsm":"Nếu số tiền ký quỹ không đáp ứng các điều kiện giá trị đơn hàng, bạn sẽ không thể nhận các loại đơn này. Bạn nên duy trì đủ số tiền ký quỹ.",
+"user.cheshourenzh":"Chứng nhận lái xe",
+"user.jiashizhe":"Giấy chứng nhận đăng ký xe ( Cavet Xe )",
+"user.shifajlzm":" Phiếu lý lịch tư pháp",
+"user.xingshizh":"Giấy phép lái xe",
+"user.cheliangtp":"Hình ảnh xe",
+"user.dingweiquanxian":"Có bật quyền định vị không?",
+"RegisterView.zucelc":"Các bước để trở thành đối tác",
+"user.guanyuwm": "Thông tin công ty chủ sở hữu ",
+"user.baomizc": "Chính Sách Bảo Mật",
+"user.fuwutiaok": "Điều Khoản Dịch Vụ",
+"user.caozuogz": "Quy Chế Hoạt Động",
+"user.zengyihts": "Chính sách giải quyết khiếu nại",
+"index.yiyouxinban":"Đã có phiên bản mới",
+"index.qiangzhiyiyouxinban":"Để đảm bảo an toàn tài sản của bạn, hãy nâng cấp rồi mới sử dụng !",
+"index.shengji":"Nâng cấp",
+"jifen.jifendikou":"Đổi Điểm Giảm Giá"
+}

+ 352 - 0
locale/zh-Hans.json

@@ -0,0 +1,352 @@
+{
+"api.dingweishibai":"获取位置失败!",
+"api.huobidanwei":"₫",
+"api.message":"提示",
+"api.nqdbddh":"您确定拨打电话?",
+"audioCall.cteyhcall":"CTE 用户IM通话",
+"audioCall.hujiaosb":"用户信息异常呼叫失败。",
+"audioCall.imtitle":"IM 语音通话",
+"audioCall.jieshuth":"结束通话",
+"audioCall.jietingyy":"接听语音",
+"audioCall.jujuejieting":"拒绝接听",
+"audioCall.weilianjie":"离线",
+"audioCall.wfjt":"无法接通",
+"audioCall.yiguanduan":"已挂断",
+"audioCall.yijietong":"已接通",
+"audioCall.yilianjie":"在线",
+"audioCall.zhengzhj":"正在呼叫",
+"audioCall.zhengzjt":"正在接通",
+"exchange.chakanxinxi":"查看信息",
+"exchange.cteyhmsg":"CTE 用户IM信息",
+"exchange.qingshurxx":"请输入信息",
+"exchange.quxiao":"取消",
+"exchange.tupian":"图片",
+"exchange.wenjian":"文件",
+"exchange.xinxi":"信息",
+"GoeasyExchange.anzhuly":"按住录音",
+"GoeasyExchange.chehui":"撤回",
+"GoeasyExchange.chongxbj":"重新编辑",
+"GoeasyExchange.dingdanhao":"订单号",
+"GoeasyExchange.dingdanxx":"订单消息",
+"GoeasyExchange.duoxuan":"多选",
+"GoeasyExchange.fasong":"发送",
+"GoeasyExchange.fasongxx":"发送消息",
+"GoeasyExchange.gethistory":"点击获取历史消息",
+"GoeasyExchange.gong":"共",
+"GoeasyExchange.huoquqxsb":"获取录音权限失败",
+"GoeasyExchange.jian":"件",
+"GoeasyExchange.luyincw":"录音错误",
+"GoeasyExchange.luyinshib":"录音失败请检查麦克风权限",
+"GoeasyExchange.luyinsjtd":"录音时间太短",
+"GoeasyExchange.nichlytxx":"撤回了一条消息",
+"GoeasyExchange.nohistory":"已经没有更多的历史消息",
+"GoeasyExchange.qingshcs":"请稍后再重试",
+"GoeasyExchange.qingxsqly":"请先授权才能发送语音消息!",
+"GoeasyExchange.qingxuanzdd":"请选择一个订单",
+"GoeasyExchange.querensanc":"确认删除?",
+"GoeasyExchange.quxiao":"取消",
+"GoeasyExchange.sanchu":"删除",
+"GoeasyExchange.shipinxx":"视频消息",
+"GoeasyExchange.songkfs":"松开发送",
+"GoeasyExchange.tonghua":"通话",
+"GoeasyExchange.tupian":"图片",
+"GoeasyExchange.tupianxx":"图片消息",
+"GoeasyExchange.weidu":"未读",
+"GoeasyExchange.yidu":"已读",
+"GoeasyExchange.yuyinxx":"[语音消息]",
+"index.api":"API",
+"index.application-language":"应用语言",
+"index.component":"组件",
+"index.detail":"详情",
+"index.djjwty":"点击“登录/注册”即为同意",
+"index.gengxintx":"更新提醒",
+"index.gjqhxz":"请选择国家区号",
+"index.home":"主页",
+"index.huodaofukan":"货到付款",
+"index.jiedanfengx":"货到付款骑手垫付风险自担",
+"index.language":"语言",
+"index.language-change-confirm":"应用此设置将重启App",
+"index.language-info":"语言信息",
+"index.qiangzhigx":"强制更新到最新版本",
+"index.queren":"确认",
+"index.quxiao":"取消",
+"index.schema":"Schema",
+"index.shoukuanwc":"货到付款收到钱了吗?",
+"index.system-language":"系统语言",
+"index.tijiao":"提交",
+"index.title":"Hello i18n",
+"index.tuijiangx":"推荐更新版本取消则继续使用当前版本",
+"index.yinsizc":"《隐私政策》",
+"index.yonghuxiey":"《用户协议》",
+"index.youhuiq":"优惠券",
+"index.yuedu":"阅读",
+"index.zhoubianfw":"服务范围",
+"kefu.dingdandb":"请截图手机订单和拍照打印订单对比",
+"kefu.pzcanksl":"拍照参考示例",
+"kefu.shangptp":"请上传您收到的订单产品",
+"kefu.weishiyong":"未使用",
+"kefu.wentileix":"请选择问题类型",
+"kefu.yishiyong":"已使用",
+"locale.auto":"系统",
+"locale.en":"English",
+"locale.ja":"日语",
+"locale.yuenan":"越南语",
+"locale.zh-hans":"简体中文",
+"locale.zh-hant":"繁体中文",
+"order.benyue":"本月",
+"order.candianyw":"餐点有误",
+"order.chakantp":"查看图片",
+"order.chongpaidd":"重派订单",
+"order.chongxuan":"重选",
+"order.daiquhuo":"待取货",
+"order.dangqmydd":"当前没有订单",
+"order.danweidan":"单",
+"order.dingdanjin":"订单金额",
+"order.haimeixinxi":"还有没有反馈信息",
+"order.haimeiysj":"还没有数据",
+"order.jinri":"今日",
+"order.jintian":"今天",
+"order.juli":"距离",
+"order.kefujs":"客服介入",
+"order.kefuliuy":"客服回复",
+"order.lianxi":"电话",
+"order.lianxikef":"联系客服",
+"order.luxian":"路线",
+"order.menpaizp":"门牌照片",
+"order.peisongfei":"配送费",
+"order.peisonglc":"配送里程",
+"order.peisongzh":"配送中",
+"order.qingxiansctp":"请先上传图片",
+"order.qingxuanz":"请选择",
+"order.qishouly":"骑手留言",
+"order.qishouyhts":"配送费和积分抵扣相关优惠产生的差额由平台向骑手另行结算",
+"order.qiszhifts":"请按商品合计金额支付给商家",
+"order.qrcandianyw":"确认餐点有误吗?",
+"order.qrqucanshib":"确认取餐失败吗?",
+"order.qucanshib":"取餐失败",
+"order.querendaodian":"确认到店",
+"order.quhuodian":"取货点",
+"order.qupaishe":"去拍摄",
+"order.qushangc":"从相册选择",
+"order.quxiaodingdan":"取消订单",
+"order.ridingdan":"日订单",
+"order.shanchutp":"删除图片?",
+"order.shangjiayqrcc":"商家已确认出餐",
+"order.shangpinxj":"商品合计",
+"order.shouhou":"退款/售后",
+"order.shouhuodian":"收货点",
+"order.shouhwc":"售后完成",
+"order.shuaxinList":"刷新任务",
+"order.songda":"送达",
+"order.tian":"天",
+"order.wancheng":"完成",
+"order.wanchengdingd":"完成订单",
+"order.wanchengquhuo":"完成取货",
+"order.weizhifu":"未支付",
+"order.wentimiaos":"请输入问题描述...",
+"order.wodedingdan":"我的订单",
+"order.xingqi":"星期",
+"order.xinrenwu":"新任务",
+"order.xuanzeriqi":"选择日期",
+"order.yinhangculz":"银行处理中",
+"order.yishouli":"已受理",
+"order.yizhifu":"已支付",
+"order.yonghuly":"用户留言",
+"order.youhuijine":"优惠金额",
+"order.youxindd":"有新订单请点击‘刷新列表’",
+"order.yue":"月",
+"order.yuedingdan":"月订单",
+"order.zaixianduihua":"在线对话",
+"order.zhangdan":"账单",
+"order.zhi":"至",
+"order.zhifuchg":"支付成功",
+"order.zhifushib":"支付失败",
+"order.zuotian":"昨天",
+"schema.add":"新增",
+"schema.add-success":"新增成功",
+"schema.name":"姓名",
+"shouye.changzhuqy":"常驻区域",
+"shouye.dangqianjdms":"当前接单模式",
+"shouye.jieshoudd":"接受订单",
+"shouye.jindanms":"近单模式",
+"shouye.paidanshez":"派单设置",
+"shouye.querenkaig":"确认开工",
+"shouye.querenkaigN":"开工后系统将为您指派合适的订单",
+"shouye.querenxiax":"确认下线",
+"shouye.querenxiaxN":"下线后系统将不再为您派送订单",
+"shouye.qushezhi":"去设置",
+"shouye.shezhijdms":"选择接单模式",
+"shouye.tongshijdl":"同时接单量",
+"shouye.zhidongjpd":"自动接派单",
+"shouye.zhidongjpdN":"担心漏单?开启后在派单倒计时结束后为您自动接取",
+"tixian.bangdingyhk":"绑定银行卡",
+"tixian.baozhengjgz":"保证金规则",
+"tixian.bdyhk":"您还没绑定银行卡快去绑定吧!",
+"tixian.chikaren":"持卡人",
+"tixian.chongzhi":"充值",
+"tixian.fencheng":"分成",
+"tixian.jiaonabzj":"缴纳保证金",
+"tixian.jiaoyimima":"交易密码",
+"tixian.jiebang":"解绑",
+"tixian.jieshouka":"接收卡",
+"tixian.jiner":"金额",
+"tixian.kahao":"卡号",
+"tixian.kezhuancdk":"可转出到卡",
+"tixian.qingbangdbryhk":"请绑定本人银行卡",
+"tixian.qingshubzjje":"请输入保证金额",
+"tixian.qingshuckrxm":"请输入持卡人姓名",
+"tixian.qingshujymm":"请输入交易密码",
+"tixian.qingshukh":"请输入卡号",
+"tixian.qingtxwzyhkxx":"请填写完整银行卡信息",
+"tixian.quanbu":"全部",
+"tixian.querenjieb":"确认解绑",
+"tixian.querentixian":"确认提现",
+"tixian.shenqingshenhe":"申请审核",
+"tixian.shenqingshij":"申请时间",
+"tixian.shuishikt":"随时可退",
+"tixian.tianjayhk":"+添加银行卡",
+"tixian.tixian":"提现",
+"tixian.tuibaozj":"退保证金",
+"tixian.txdzts":"提现后预计24小时到账请耐心等待",
+"tixian.txyhk":"提现银行卡",
+"tixian.wodeyhk":"我的银行卡",
+"tixian.xuanzeyanhang":"请填写开户银行",
+"tixian.yhkguanli":"银行卡编辑",
+"tixian.yinghang":"银行",
+"tixian.zijinanquan":"资金安全",
+"user.anquanzhongxin":"安全中心",
+"user.anzhuangsbcs":"安装失败请稍候重试",
+"user.appleNav":"苹果地图",
+"user.baiduNav":"百度地图",
+"user.bangdingsj":"绑定手机",
+"user.caozuojid":"操作简单",
+"user.chengyaojm":"诚邀您加盟!",
+"user.chepaihao":"车牌号",
+"user.chongxinhq":"重新获取",
+"user.chongzhimima":"重置密码",
+"user.dangqianbb":"当前版本",
+"user.denglu":"登录",
+"user.denglucg":"登录成功",
+"user.denglumima":"登录密码",
+"user.denglushib":"登录失败",
+"user.denglushixiao":"登录失效请重新登录",
+"user.dengluzhuce":"登录/注册",
+"user.duolaodd":"收入丰厚多劳多得",
+"user.fadan":"罚单",
+"user.gaodeNav":"高德地图",
+"user.gerenxinxi":"个人信息",
+"user.gerenzhongxin":"个人中心",
+"user.googleNav":"谷歌地图",
+"user.hailiangdd":"海量订单",
+"user.huoquyanzhegm":"获取验证码",
+"user.huoquzxbb":"最新版本",
+"user.jiangtonggj":"交通工具",
+"user.jiankangzh":"健康证",
+"user.jiedanshezhi":"接单设置",
+"user.kaishixiaz":"开始下载了",
+"user.kefuzhongxin":"客服中心",
+"user.lijizhuce":"立即注册",
+"user.meiyouzhanghao":"没有账号?",
+"user.mimadenglu":"密码登录",
+"user.navType":"导航方式",
+"user.navTypeby":"骑行",
+"user.navTypedr":"驾车",
+"user.nicheng":"昵称",
+"user.peixunzhongx":"培训中心",
+"user.pingjia":"评价",
+"user.qianwsmrz":"前往实名认证",
+"user.qingshezfmm":"请设置支付密码",
+"user.qingshezmim":"请设置新登录密码",
+"user.qingshurmim":"请输入登录密码",
+"user.qingshurnc":"请输入昵称",
+"user.shenfenzh": "身份证/护照",
+"user.qingshursfzh":"请输入身份证号",
+"user.qingshurxm":"请输入姓名",
+"user.qingshuydlmm":"请输入原登录密码",
+"user.qingshuyzfmm":"请输入原支付密码",
+"user.qingsryaoqing":"请输入邀请码(选填)",
+"user.qingzaisryc":"请再输入一次",
+"user.qsrchepaihao":"请输入车牌号",
+"user.qsrshouihao":"请输入手机号",
+"user.qsrzhanghao":"请输入帐号",
+"user.querenscdzt":"确认删除第'x'张图片?",
+"user.querentcdq":"是否退出当前账号?",
+"user.sanchutp":"删除图片",
+"user.shangxianzh":"上线中",
+"user.shenhezhong":"审核中",
+"user.shenqingshcg":"申请审核成功",
+"user.shezhichengg":"设置成功",
+"user.shezhinc":"用户昵称设置",
+"user.shezhishibai":"设置失败",
+"user.shifbaiduNav":"是否打开“百度地图”进行导航?",
+"user.shifgaodeNav":"是否打开“高德地图”进行导航?",
+"user.shifougengxin":"是否更新到最新版本?",
+"user.shimingwsmrz":"实名认证",
+"user.shirkek":"收入可靠",
+"user.tuichudengl":"退出登录",
+"user.tupiansccg":"图片上传成功",
+"user.wangjimima":"忘记密码?",
+"user.weianzhuangapp":"本机未安装指定的地图应用",
+"user.weirenzheng":"未认证",
+"user.weishezhi":"未设置",
+"user.xiaxianzh":"下线中",
+"user.xiazaijindu":"下载进度",
+"user.xiazaizhong":"下载中请勿退出",
+"user.xieyiguiz":"协议规则",
+"user.xiugai":"修改",
+"user.xuanzedaoh":"选择地图应用",
+"user.yanzhengma":"请输入验证码",
+"user.yanzhengmdl":"验证码登录",
+"user.yirenzheng":"已认证",
+"user.yishizxbb":"已是最新版本",
+"user.yiyouzhhdl":"已有账号登录",
+"user.zhanghaowsh":"账号未审核",
+"user.zhegnjiants":"请上传身份證正反面、戶口名簿、無犯罪紀錄公證",
+"user.zhifumima":"支付密码",
+"user.zhuce":"注册",
+"user.zhucechengg":"注册成功",
+"user.zhuxiaodqzh":"删除当前账号?",
+"user.zhuxiaozh":"删除账号",
+"zhanghu.baozhegnjin":"保证金",
+"zhanghu.benqiwcdl":"本期累计完成订单",
+"zhanghu.benqleijsr":"本期累计收入",
+"zhanghu.chakanmx":"查看明细",
+"zhanghu.daozhang":"到账",
+"zhanghu.huodongsr":"活动收入",
+"zhanghu.jinrishour":"今日收入",
+"zhanghu.jinriwanch":"今日完成",
+"zhanghu.jinrizhangd":"今日账单",
+"zhanghu.peisongsr":"配送收入",
+"zhanghu.qingxuanzbzje":"请选择要充值的保证金额",
+"zhanghu.querenzhifubzj":"确认支付保证金?",
+"zhanghu.shouzhitj":"收支统计",
+"zhanghu.shujutj":"数据统计",
+"zhanghu.tixianjil":"提现记录",
+"zhanghu.wodezhanghu":"我的账户",
+"zhanghu.xuanzezhif":"请选择支付方式",
+"zhanghu.yinhangka":"银行卡",
+"zhanghu.yuer":"余额",
+"zhanghu.yuji":"预计",
+"zhanghu.yujishouru":"预计收入",
+"zhanghu.yujizhichu":"预计支出",
+"zhanghu.zhanghumingxi":"账户明细",
+"zhanghu.zhuangtai":"状态",
+"tixian.baozhengjyt":"保证金用途",
+"tixian.baozhengjsm":"保证金不满足部分订单保证金条件时,您将无法接此类型的订单,建议您保留足够保证金。",
+"user.cheshourenzh":"车手认证",
+"user.jiashizhe":"驾驶证",
+"user.shifajlzm":"司法记录证明",
+"user.xingshizh":"行驶证",
+"user.cheliangtp":"车辆图片",
+"user.dingweiquanxian":"是否开启定位权限?",
+"RegisterView.zucelc":"注册流程",
+"user.baomizc": "保密政策",
+"user.fuwutiaok": "服务条款",
+"user.caozuogz": "操作规章",
+"user.zengyihts": "争议和投诉解决程序",
+"user.guanyuwm": "关于我们",
+"index.yiyouxinban":"已经有新的版本了",
+"index.qiangzhiyiyouxinban":"为保证您的财产安全,请更新后再使用!",
+"index.shengji":"升级",
+"jifen.jifendikou":"积分抵扣"
+}

+ 352 - 0
locale/zh-Hant.json

@@ -0,0 +1,352 @@
+{
+"api.dingweishibai":"獲取位置失敗!",
+"api.huobidanwei":"₫",
+"api.message":"提示",
+"api.nqdbddh":"您確定撥打電話?",
+"audioCall.cteyhcall":"CTE 用戶IM通話",
+"audioCall.hujiaosb":"用戶信息異常呼叫失敗。",
+"audioCall.imtitle":"IM 語音通話",
+"audioCall.jieshuth":"結束通話",
+"audioCall.jietingyy":"接聽語音",
+"audioCall.jujuejieting":"拒絕接聽",
+"audioCall.weilianjie":"離線",
+"audioCall.wfjt":"无法接通",
+"audioCall.yiguanduan":"已掛斷",
+"audioCall.yijietong":"已接通",
+"audioCall.yilianjie":"在線",
+"audioCall.zhengzhj":"正在呼叫",
+"audioCall.zhengzjt":"正在接通",
+"exchange.chakanxinxi":"查看信息",
+"exchange.cteyhmsg":"CTE 用戶IM信息",
+"exchange.qingshurxx":"請輸入信息",
+"exchange.quxiao":"取消",
+"exchange.tupian":"图片",
+"exchange.wenjian":"文件",
+"exchange.xinxi":"信息",
+"GoeasyExchange.anzhuly":"按住錄音",
+"GoeasyExchange.chehui":"撤回",
+"GoeasyExchange.chongxbj":"重新編輯",
+"GoeasyExchange.dingdanhao":"訂單號",
+"GoeasyExchange.dingdanxx":"訂單消息",
+"GoeasyExchange.duoxuan":"多選",
+"GoeasyExchange.fasong":"發送",
+"GoeasyExchange.fasongxx":"發送消息",
+"GoeasyExchange.gethistory":"點擊獲取歷史消息",
+"GoeasyExchange.gong":"共",
+"GoeasyExchange.huoquqxsb":"獲取錄音權限失敗",
+"GoeasyExchange.jian":"件",
+"GoeasyExchange.luyincw":"錄音錯誤",
+"GoeasyExchange.luyinshib":"錄音失敗請檢查麥克風權限",
+"GoeasyExchange.luyinsjtd":"錄音時間太短",
+"GoeasyExchange.nichlytxx":"撤回了一條消息",
+"GoeasyExchange.nohistory":"已經沒有更多的歷史消息",
+"GoeasyExchange.qingshcs":"請稍後再重試",
+"GoeasyExchange.qingxsqly":"請先授權才能發送語音消息!",
+"GoeasyExchange.qingxuanzdd":"請選擇一個訂單",
+"GoeasyExchange.querensanc":"確認刪除?",
+"GoeasyExchange.quxiao":"取消",
+"GoeasyExchange.sanchu":"刪除",
+"GoeasyExchange.shipinxx":"視頻消息",
+"GoeasyExchange.songkfs":"松開發送",
+"GoeasyExchange.tonghua":"通話",
+"GoeasyExchange.tupian":"圖片",
+"GoeasyExchange.tupianxx":"圖片消息",
+"GoeasyExchange.weidu":"未讀",
+"GoeasyExchange.yidu":"已讀",
+"GoeasyExchange.yuyinxx":"[語音消息]",
+"index.api":"API",
+"index.application-language":"應用語言",
+"index.component":"組件",
+"index.detail":"詳情",
+"index.djjwty":"點擊「登錄/註冊」即為同意",
+"index.gengxintx":"更新提醒",
+"index.gjqhxz":"請選擇國家區號",
+"index.home":"主頁",
+"index.huodaofukan":"貨到付款",
+"index.jiedanfengx":"貨到付款騎手墊付風險自擔",
+"index.language":"語言",
+"index.language-change-confirm":"應用此設置將重啟App",
+"index.language-info":"語言信息",
+"index.qiangzhigx":"強製更新到最新版本",
+"index.queren":"確認",
+"index.quxiao":"取消",
+"index.schema":"Schema",
+"index.shoukuanwc":"貨到付款收到錢了嗎?",
+"index.system-language":"系統語言",
+"index.tijiao":"提交",
+"index.title":"Hello i18n",
+"index.tuijiangx":"推薦更新版本取消則繼續使用當前版本",
+"index.yinsizc":"《隱私政策》",
+"index.yonghuxiey":"《用戶協議》",
+"index.youhuiq":"優惠券",
+"index.yuedu":"閱讀",
+"index.zhoubianfw":"服務範圍",
+"kefu.dingdandb":"請截圖手機訂單和拍照打印訂單對比",
+"kefu.pzcanksl":"拍照參考示例",
+"kefu.shangptp":"請上傳您收到的訂單產品",
+"kefu.weishiyong":"未使用",
+"kefu.wentileix":"請選擇問題類型",
+"kefu.yishiyong":"已使用",
+"locale.auto":"系統",
+"locale.en":"English",
+"locale.ja":"日語",
+"locale.yuenan":"越南語",
+"locale.zh-hans":"簡體中文",
+"locale.zh-hant":"繁體中文",
+"order.benyue":"本月",
+"order.candianyw":"餐點有誤",
+"order.chakantp":"查看圖片",
+"order.chongpaidd":"重派訂單",
+"order.chongxuan":"重選",
+"order.daiquhuo":"待取貨",
+"order.dangqmydd":"當前沒有訂單",
+"order.danweidan":"單",
+"order.dingdanjin":"訂單金額",
+"order.haimeixinxi":"還有沒有反饋信息",
+"order.haimeiysj":"還沒有數據",
+"order.jinri":"今日",
+"order.jintian":"今天",
+"order.juli":"距離",
+"order.kefujs":"客服介入",
+"order.kefuliuy":"客服回復",
+"order.lianxi":"電話",
+"order.lianxikef":"聯系客服",
+"order.luxian":"路線",
+"order.menpaizp":"門牌照片",
+"order.peisongfei":"配送費",
+"order.peisonglc":"配送裏程",
+"order.peisongzh":"配送中",
+"order.qingxiansctp":"請先上傳圖片",
+"order.qingxuanz":"請選擇",
+"order.qishouly":"騎手留言",
+"order.qishouyhts":"配送費和積分抵扣相關優惠產生的差額由平臺向騎手另行結算",
+"order.qiszhifts":"請按商品合計金額支付給商家",
+"order.qrcandianyw":"確認餐點有誤吗?",
+"order.qrqucanshib":"確認取餐失敗嗎?",
+"order.qucanshib":"取餐失敗",
+"order.querendaodian":"確認到店",
+"order.quhuodian":"取貨點",
+"order.qupaishe":"去拍攝",
+"order.qushangc":"從相冊選擇",
+"order.quxiaodingdan":"取消訂單",
+"order.ridingdan":"日訂單",
+"order.shanchutp":"刪除圖片?",
+"order.shangjiayqrcc":"商家已確認出餐",
+"order.shangpinxj":"商品合計",
+"order.shouhou":"退款/售後",
+"order.shouhuodian":"收貨點",
+"order.shouhwc":"售後完成",
+"order.shuaxinList":"刷新任務",
+"order.songda":"送達",
+"order.tian":"天",
+"order.wancheng":"完成",
+"order.wanchengdingd":"完成訂單",
+"order.wanchengquhuo":"完成取貨",
+"order.weizhifu":"未支付",
+"order.wentimiaos":"請輸入問題描述...",
+"order.wodedingdan":"我的訂單",
+"order.xingqi":"星期",
+"order.xinrenwu":"新任務",
+"order.xuanzeriqi":"選擇日期",
+"order.yinhangculz":"銀行處理中",
+"order.yishouli":"已受理",
+"order.yizhifu":"已支付",
+"order.yonghuly":"用戶留言",
+"order.youhuijine":"優惠金額",
+"order.youxindd":"有新訂單請點擊『刷新列表』",
+"order.yue":"月",
+"order.yuedingdan":"月訂單",
+"order.zaixianduihua":"在線對話",
+"order.zhangdan":"賬單",
+"order.zhi":"至",
+"order.zhifuchg":"支付成功",
+"order.zhifushib":"支付失敗",
+"order.zuotian":"昨天",
+"schema.add":"新增",
+"schema.add-success":"新增成功",
+"schema.name":"姓名",
+"shouye.changzhuqy":"常駐區域",
+"shouye.dangqianjdms":"當前接單模式",
+"shouye.jieshoudd":"接受訂單",
+"shouye.jindanms":"近單模式",
+"shouye.paidanshez":"派單設置",
+"shouye.querenkaig":"確認開工",
+"shouye.querenkaigN":"開工後系統將為您指派合適的訂單",
+"shouye.querenxiax":"確認下線",
+"shouye.querenxiaxN":"下線後系統將不再為您派送訂單",
+"shouye.qushezhi":"去設置",
+"shouye.shezhijdms":"選擇接單模式",
+"shouye.tongshijdl":"同時接單量",
+"shouye.zhidongjpd":"自動接派單",
+"shouye.zhidongjpdN":"擔心漏單?開啟後在派單倒計時結束後為您自動接取",
+"tixian.bangdingyhk":"綁定銀行卡",
+"tixian.baozhengjgz":"保證金規則",
+"tixian.bdyhk":"您還沒綁定銀行卡快去綁定吧!",
+"tixian.chikaren":"持卡人",
+"tixian.chongzhi":"充值",
+"tixian.fencheng":"分成",
+"tixian.jiaonabzj":"繳納保證金",
+"tixian.jiaoyimima":"交易密碼",
+"tixian.jiebang":"解綁",
+"tixian.jieshouka":"接收卡",
+"tixian.jiner":"金額",
+"tixian.kahao":"卡號",
+"tixian.kezhuancdk":"可轉出到卡",
+"tixian.qingbangdbryhk":"請綁定本人銀行卡",
+"tixian.qingshubzjje":"請輸入保證金額",
+"tixian.qingshuckrxm":"請輸入持卡人姓名",
+"tixian.qingshujymm":"請輸入交易密碼",
+"tixian.qingshukh":"請輸入卡號",
+"tixian.qingtxwzyhkxx":"請填寫完整銀行卡信息",
+"tixian.quanbu":"全部",
+"tixian.querenjieb":"確認解綁",
+"tixian.querentixian":"確認提現",
+"tixian.shenqingshenhe":"申請審核",
+"tixian.shenqingshij":"申請時間",
+"tixian.shuishikt":"隨時可退",
+"tixian.tianjayhk":"+添加銀行卡",
+"tixian.tixian":"提現",
+"tixian.tuibaozj":"退保證金",
+"tixian.txdzts":"提現後預計24小時到賬請耐心等待",
+"tixian.txyhk":"提現銀行卡",
+"tixian.wodeyhk":"我的銀行卡",
+"tixian.xuanzeyanhang":"請填寫開戶銀行",
+"tixian.yhkguanli":"銀行卡編輯",
+"tixian.yinghang":"銀行",
+"tixian.zijinanquan":"資金安全",
+"user.anquanzhongxin":"安全中心",
+"user.anzhuangsbcs":"安裝失敗請稍候重試",
+"user.appleNav":"蘋果地圖",
+"user.baiduNav":"百度地圖",
+"user.bangdingsj":"綁定手機",
+"user.caozuojid":"操作簡單",
+"user.chengyaojm":"誠邀您加盟!",
+"user.chepaihao":"車牌號",
+"user.chongxinhq":"重新獲取",
+"user.chongzhimima":"重置密碼",
+"user.dangqianbb":"當前版本",
+"user.denglu":"登錄",
+"user.denglucg":"登錄成功",
+"user.denglumima":"登錄密碼",
+"user.denglushib":"登錄失敗",
+"user.denglushixiao":"登錄失效請重新登錄",
+"user.dengluzhuce":"登錄/註冊",
+"user.duolaodd":"收入豐厚多勞多得",
+"user.fadan":"罰單",
+"user.gaodeNav":"高德地圖",
+"user.gerenxinxi":"個人信息",
+"user.gerenzhongxin":"個人中心",
+"user.googleNav":"谷歌地圖",
+"user.hailiangdd":"海量訂單",
+"user.huoquyanzhegm":"獲取驗證碼",
+"user.huoquzxbb":"最新版本",
+"user.jiangtonggj":"交通工具",
+"user.jiankangzh":"健康證",
+"user.jiedanshezhi":"接單設置",
+"user.kaishixiaz":"開始下載了",
+"user.kefuzhongxin":"客服中心",
+"user.lijizhuce":"立即註冊",
+"user.meiyouzhanghao":"沒有賬號?",
+"user.mimadenglu":"密碼登錄",
+"user.navType":"導航方式",
+"user.navTypeby":"騎行",
+"user.navTypedr":"駕車",
+"user.nicheng":"昵稱",
+"user.peixunzhongx":"培訓中心",
+"user.pingjia":"評價",
+"user.qianwsmrz":"前往實名認證",
+"user.qingshezfmm":"請設置支付密碼",
+"user.qingshezmim":"請設置新登錄密碼",
+"user.qingshurmim":"請輸入登錄密碼",
+"user.qingshurnc":"請輸入昵稱",
+"user.qingshursfzh":"請輸入身份證號",
+"user.shenfenzh": "身份證/護照",
+"user.qingshurxm":"請輸入姓名",
+"user.qingshuydlmm":"請輸入原登錄密碼",
+"user.qingshuyzfmm":"請輸入原支付密碼",
+"user.qingsryaoqing":"請輸入邀請碼(選填)",
+"user.qingzaisryc":"請再輸入一次",
+"user.qsrchepaihao":"請輸入車牌號",
+"user.qsrshouihao":"請輸入手機號",
+"user.qsrzhanghao":"請輸入帳號",
+"user.querenscdzt":"確認刪除第'x'張圖片?",
+"user.querentcdq":"是否退出當前賬號?",
+"user.sanchutp":"刪除圖片",
+"user.shangxianzh":"上線中",
+"user.shenhezhong":"審核中",
+"user.shenqingshcg":"申請審核成功",
+"user.shezhichengg":"設置成功",
+"user.shezhinc":"用戶昵稱設置",
+"user.shezhishibai":"設置失敗",
+"user.shifbaiduNav":"是否打開「百度地圖」進行導航?",
+"user.shifgaodeNav":"是否打開「高德地圖」進行導航?",
+"user.shifougengxin":"是否更新到最新版本?",
+"user.shimingwsmrz":"實名認證",
+"user.shirkek":"收入可靠",
+"user.tuichudengl":"退出登錄",
+"user.tupiansccg":"圖片上傳成功",
+"user.wangjimima":"忘記密碼?",
+"user.weianzhuangapp":"本機未安裝指定的地圖應用",
+"user.weirenzheng":"未認證",
+"user.weishezhi":"未設置",
+"user.xiaxianzh":"下線中",
+"user.xiazaijindu":"下載進度",
+"user.xiazaizhong":"下載中請勿退出",
+"user.xieyiguiz":"協議規則",
+"user.xiugai":"修改",
+"user.xuanzedaoh":"選擇地圖應用",
+"user.yanzhengma":"請輸入驗證碼",
+"user.yanzhengmdl":"驗證碼登錄",
+"user.yirenzheng":"已認證",
+"user.yishizxbb":"已是最新版本",
+"user.yiyouzhhdl":"已有賬號登錄",
+"user.zhanghaowsh":"賬號未審核",
+"user.zhegnjiants":"請上傳身份證正反面、戶口名簿、無犯罪紀錄公證",
+"user.zhifumima":"支付密碼",
+"user.zhuce":"註冊",
+"user.zhucechengg":"註冊成功",
+"user.zhuxiaodqzh":"刪除當前賬號?",
+"user.zhuxiaozh":"刪除賬號",
+"zhanghu.baozhegnjin":"保證金",
+"zhanghu.benqiwcdl":"本期累計完成訂單",
+"zhanghu.benqleijsr":"本期累計收入",
+"zhanghu.chakanmx":"查看明細",
+"zhanghu.daozhang":"到賬",
+"zhanghu.huodongsr":"活動收入",
+"zhanghu.jinrishour":"今日收入",
+"zhanghu.jinriwanch":"今日完成",
+"zhanghu.jinrizhangd":"今日賬單",
+"zhanghu.peisongsr":"配送收入",
+"zhanghu.qingxuanzbzje":"請選擇要充值的保證金額",
+"zhanghu.querenzhifubzj":"確認支付保證金?",
+"zhanghu.shouzhitj":"收支統計",
+"zhanghu.shujutj":"數據統計",
+"zhanghu.tixianjil":"提現記錄",
+"zhanghu.wodezhanghu":"我的賬戶",
+"zhanghu.xuanzezhif":"請選擇支付方式",
+"zhanghu.yinhangka":"銀行卡",
+"zhanghu.yuer":"余額",
+"zhanghu.yuji":"預計",
+"zhanghu.yujishouru":"預計收入",
+"zhanghu.yujizhichu":"預計支出",
+"zhanghu.zhanghumingxi":"賬戶明細",
+"zhanghu.zhuangtai":"狀態",
+"tixian.baozhengjyt":"保證金用途",
+"tixian.baozhengjsm":"保證金不滿足部分訂單保證金條件時,您將無法接此類型的訂單,建議您保留足夠保證金。",
+"user.cheshourenzh":"車手認證",
+"user.jiashizhe":"駕駛證",
+"user.shifajlzm":"司法記錄證明",
+"user.xingshizh":"行駛證",
+"user.cheliangtp":"車輛圖片",
+"user.dingweiquanxian":"是否開啟定位權限?",
+"RegisterView.zucelc":"註冊流程",
+"user.baomizc": "保密政策",
+"user.fuwutiaok": "服務條款",
+"user.caozuogz": "操作規章",
+"user.zengyihts": "爭議和投訴解決程序",
+"user.guanyuwm": "關於我們",
+"index.yiyouxinban":"已經有新的版本了",
+"index.qiangzhiyiyouxinban":"為保證您的財產安全,請更新後再使用!",
+"index.shengji":"升級",
+"jifen.jifendikou":"積分抵扣"
+}

+ 133 - 0
main.js

@@ -0,0 +1,133 @@
+import App from './App'
+import messages from './locale/index'
+import GoEasy from 'goeasy'
+
+// 引入全局方法
+import {http} from '@/utils/request';
+import mytool from '@/utils/tool';
+
+// 挂载全局自定义方法
+Vue.prototype.$http = http;
+Vue.prototype.$mytool = mytool;
+
+// Vue.prototype.$baseurl = 'https://api.cityexpress168.com.vn';//生产环境
+Vue.prototype.$baseurl = 'https://api.amazeway.com.cn'//预发布
+
+const goEasy = GoEasy.getInstance({
+    host:"singapore.goeasy.io",  //若是新加坡区域:singapore.goeasy.io
+    appkey:"BC-118535b236de4c83a1ad0341830d1c04",
+    modules:['im','pubsub'],//根据需要,传入'im’或'pubusub',或数组方式同时传入
+	allowNotification: false,  // true表示支持通知栏提醒,false则表示不需要通知栏提醒
+});
+
+// goEasy.im.on(GoEasy.IM_EVENT.CONVERSATIONS_UPDATED, setUnreadNumber);
+
+// function setUnreadNumber (content) {
+//     let unreadTotal = content.unreadTotal;
+//     if(unreadTotal > 0) {
+//         uni.setTabBarBadge({
+//             index: 0,
+//             text: unreadTotal.toString()
+//         });
+//     }else{
+//         uni.removeTabBarBadge({index: 0});
+//     }
+//     // #ifdef APP-PLUS
+//     goEasy.setBadge({
+//       badge: unreadTotal,
+//       onSuccess: function () {
+//         console.log("setBadge successfully.")
+//       },
+//       onFailed: function (error) {
+//         console.log("Failed to setBadge,error:" + error);
+//       }
+//     });
+//     // #endif
+// }
+
+goEasy.onClickNotification((message) => {
+    // let currentUrl;
+    // const routes = getCurrentPages();
+
+    // if (routes && routes.length) {
+    //     const curRoute = routes[routes.length - 1].route;
+    //     const curParam = routes[routes.length - 1].options;
+    //     currentUrl = '/' + curRoute + `?to=${curParam.to}`;
+    // }
+
+    // let newUrl;
+    // switch (message.toType) {
+    //     case GoEasy.IM_SCENE.PRIVATE:
+    //         newUrl = '/pages/privateChat?to=' + message.senderId;
+    //         break;
+    //     case GoEasy.IM_SCENE.GROUP:
+    //         newUrl = '/pages/groupChat?to=' + message.groupId;
+    //         break;
+    // }
+
+    // if (currentUrl !== newUrl) {
+    //     uni.navigateTo({
+    //         url: newUrl,
+    //     });
+    // }
+
+});
+
+Vue.prototype.GoEasy = GoEasy;
+Vue.prototype.goEasy = goEasy;
+
+Vue.prototype.$formPr = function(price){
+	
+	var number = '0';
+	var type = typeof(price);
+	if(type=='string'){
+		number = price
+	}
+	if(type=='number'){
+		number = price.toString(); // 确保输入是字符串
+	}
+	const pattern = /(-?\d+)(\d{3})/;
+	while (pattern.test(number)) {
+		number = number.replace(pattern, "$1,$2");
+	}
+	return number;
+	  
+	if(price%1000==0){
+		return price;//price/1000+'k'
+	}
+	else{
+		return price;
+	}
+};
+
+let i18nConfig = {
+  locale: uni.getLocale(),
+  messages
+}
+
+// #ifndef VUE3
+import Vue from 'vue'
+import VueI18n from 'vue-i18n'
+Vue.use(VueI18n)
+const i18n = new VueI18n(i18nConfig)
+Vue.config.productionTip = false
+App.mpType = 'app'
+const app = new Vue({
+  i18n,
+  ...App
+})
+app.$mount()
+// #endif
+
+// #ifdef VUE3
+import { createSSRApp } from 'vue'
+import { createI18n } from 'vue-i18n'
+const i18n = createI18n(i18nConfig)
+export function createApp() {
+  const app = createSSRApp(App)
+  app.use(i18n)
+  return {
+    app
+  }
+}
+// #endif

+ 224 - 0
manifest.json

@@ -0,0 +1,224 @@
+{
+    "name" : "CTE.partner",
+    "appid" : "__UNI__674B799",
+    "description" : "CTE. partner",
+    "versionName" : "1.1.12",
+    "versionCode" : 1112,
+    "transformPx" : false,
+    /* 5+App特有相关 */
+    "app-plus" : {
+        "usingComponents" : true,
+        "nvueStyleCompiler" : "uni-app",
+        "compilerVersion" : 3,
+        "splashscreen" : {
+            "alwaysShowBeforeRender" : true,
+            "waiting" : true,
+            "autoclose" : true,
+            "delay" : 0
+        },
+        /* 模块配置 */
+        "modules" : {
+            "Push" : {},
+            "Geolocation" : {},
+            "Maps" : {},
+            "Camera" : {},
+            "Record" : {},
+            "VideoPlayer" : {}
+        },
+        /* 应用发布信息 */
+        "distribute" : {
+            /* android打包配置 */
+            "android" : {
+                "permissions" : [
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
+                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
+                    "<uses-permission android:name=\"android.permission.RECEIVE_BOOT_COMPLETED\"/>",
+                    "<uses-permission android:name=\"android.permission.POST_NOTIFICATIONS\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\" />",
+                    "<uses-permission android:name=\"android.permission.ACCESS_BACKGROUND_LOCATION\" />"
+                ],
+                "abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ],
+                "minSdkVersion" : 23,
+                "targetSdkVersion" : 33
+            },
+            /* ios打包配置 */
+            "ios" : {
+                "dSYMs" : false,
+                "privacyDescription" : {
+                    "NSUserTrackingUsageDescription" : "Xin yên tâm, quyền mở chỉ dùng để nhận dạng thiết bị và đảm bảo trải nghiệm duyệt an toàn và nhắc nhở dịch vụ, không nhận được thông tin về quyền riêng tư của các trạm khác.",
+                    "NSLocationAlwaysAndWhenInUseUsageDescription" : "Thông tin định vị được sử dụng cho các dịch vụ giao hàng và giao hàng chuyển phát nhanh đơn đặt hàng.",
+                    "NSLocationAlwaysUsageDescription" : "Thông tin định vị được sử dụng cho các dịch vụ giao hàng và giao hàng chuyển phát nhanh đơn đặt hàng.",
+                    "NSLocationWhenInUseUsageDescription" : "Thông tin định vị được sử dụng cho các dịch vụ giao hàng và giao hàng chuyển phát nhanh đơn đặt hàng.",
+                    "NSPhotoLibraryUsageDescription" : "Để duy trì avatar người dùng.",
+                    "NSPhotoLibraryAddUsageDescription" : "Để duy trì avatar người dùng.",
+                    "NSCameraUsageDescription" : "Để duy trì avatar người dùng."
+                },
+                "capabilities" : {
+                    "plists" : {
+                        "MBXAccessToken" : "sk.eyJ1IjoiY2l0eWV4cHJlc3MxNjg4IiwiYSI6ImNsd202cTR1ajBtdDYya254MzF6eG11a2gifQ.5pM2blzxmW-Qz4X2_-Qz7w"
+                    }
+                },
+                "UIBackgroundModes" : "location,audio",
+                "urltypes" : "cityexpress1688ptqs",
+                "idfa" : true
+            },
+            /* SDK配置 */
+            "sdkConfigs" : {
+                "ad" : {},
+                "push" : {
+                    "unipush" : {
+                        "version" : "2",
+                        "offline" : true
+                    }
+                },
+                "geolocation" : {
+                    "system" : {
+                        "__platform__" : [ "ios", "android" ]
+                    }
+                },
+                "maps" : {
+                    "google" : {
+                        "APIKey_ios" : "AIzaSyDWE8S24a9ZeMZycmx9qxV01kXPCCUnUhI",
+                        "APIKey_android" : "AIzaSyDWE8S24a9ZeMZycmx9qxV01kXPCCUnUhI"
+                    }
+                }
+            },
+            "icons" : {
+                "android" : {
+                    "hdpi" : "unpackage/res/icons/72x72.png",
+                    "xhdpi" : "unpackage/res/icons/96x96.png",
+                    "xxhdpi" : "unpackage/res/icons/144x144.png",
+                    "xxxhdpi" : "unpackage/res/icons/192x192.png"
+                },
+                "ios" : {
+                    "appstore" : "unpackage/res/icons/1024x1024.png",
+                    "ipad" : {
+                        "app" : "unpackage/res/icons/76x76.png",
+                        "app@2x" : "unpackage/res/icons/152x152.png",
+                        "notification" : "unpackage/res/icons/20x20.png",
+                        "notification@2x" : "unpackage/res/icons/40x40.png",
+                        "proapp@2x" : "unpackage/res/icons/167x167.png",
+                        "settings" : "unpackage/res/icons/29x29.png",
+                        "settings@2x" : "unpackage/res/icons/58x58.png",
+                        "spotlight" : "unpackage/res/icons/40x40.png",
+                        "spotlight@2x" : "unpackage/res/icons/80x80.png"
+                    },
+                    "iphone" : {
+                        "app@2x" : "unpackage/res/icons/120x120.png",
+                        "app@3x" : "unpackage/res/icons/180x180.png",
+                        "notification@2x" : "unpackage/res/icons/40x40.png",
+                        "notification@3x" : "unpackage/res/icons/60x60.png",
+                        "settings@2x" : "unpackage/res/icons/58x58.png",
+                        "settings@3x" : "unpackage/res/icons/87x87.png",
+                        "spotlight@2x" : "unpackage/res/icons/80x80.png",
+                        "spotlight@3x" : "unpackage/res/icons/120x120.png"
+                    }
+                }
+            }
+        },
+        "nativePlugins" : {
+            "TRTCCloudUniPlugin-TRTCCloudImpl" : {
+                "__plugin_info__" : {
+                    "name" : "【官方】腾讯云实时音视频SDK",
+                    "description" : "uni-app TRTC SDK 是腾讯云实时音视频通讯解决方案在 uni-app 上的 SDK,提供实时音视频服务",
+                    "platforms" : "Android,iOS",
+                    "url" : "https://ext.dcloud.net.cn/plugin?id=7774",
+                    "android_package_name" : "com.cityexpress1688.ptqs",
+                    "ios_bundle_id" : "com.paotuiwang.qishou",
+                    "isCloud" : true,
+                    "bought" : 1,
+                    "pid" : "7774",
+                    "parameters" : {}
+                }
+            },
+            "Ba-CallerID" : {
+                "__plugin_info__" : {
+                    "name" : "来电显示悬浮窗插件(支持锁屏) Ba-CallerID",
+                    "description" : "Ba-CallerID 是一款定制的来电显示悬浮窗插件插件,有其他定制需要可联系作者。",
+                    "platforms" : "Android",
+                    "url" : "https://ext.dcloud.net.cn/plugin?id=11933",
+                    "android_package_name" : "com.cityexpress1688.ptqs",
+                    "ios_bundle_id" : "com.paotuiwang.qishou",
+                    "isCloud" : true,
+                    "bought" : 1,
+                    "pid" : "11933",
+                    "parameters" : {}
+                }
+            },
+            "KJ-Pip" : {
+                "__plugin_info__" : {
+                    "name" : "应用外、全局、后台悬浮窗、画中画、在其他应用上层显示(ios)",
+                    "description" : "应用外、全局、后台悬浮窗、画中画、在其他应用上层显示(ios) 、请试用合适再购买、请试用合适再购买、请试用合适再购买",
+                    "platforms" : "iOS",
+                    "url" : "https://ext.dcloud.net.cn/plugin?id=12064",
+                    "android_package_name" : "com.cityexpress1688.ptqs",
+                    "ios_bundle_id" : "com.paotuiwang.qishou",
+                    "isCloud" : true,
+                    "bought" : 1,
+                    "pid" : "12064",
+                    "parameters" : {}
+                }
+            },
+            "MapBox-Plugin" : {
+                "MapBox AccessToken" : "sk.eyJ1IjoiY2l0eWV4cHJlc3MxNjg4IiwiYSI6ImNseDA5bmt2MzBkdW4ya3F1b2ZpYmpudm8ifQ.LnJW7X5-9hnTvhSSdI45LA",
+                "__plugin_info__" : {
+                    "name" : "MapBox地图导航插件(Android和iOS)",
+                    "description" : "MapBox地图导航双端插件",
+                    "platforms" : "Android,iOS",
+                    "url" : "https://ext.dcloud.net.cn/plugin?id=10465",
+                    "android_package_name" : "com.cityexpress1688.ptqs",
+                    "ios_bundle_id" : "com.paotuiwang.qishou",
+                    "isCloud" : true,
+                    "bought" : 1,
+                    "pid" : "10465",
+                    "parameters" : {
+                        "MapBox AccessToken" : {
+                            "des" : "MBXAccessToken",
+                            "key" : "MBXAccessToken",
+                            "value" : ""
+                        }
+                    }
+                }
+            }
+        }
+    },
+    /* 快应用特有相关 */
+    "quickapp" : {},
+    /* 小程序特有相关 */
+    "mp-weixin" : {
+        "appid" : "",
+        "setting" : {
+            "urlCheck" : false
+        },
+        "usingComponents" : true
+    },
+    "mp-alipay" : {
+        "usingComponents" : true
+    },
+    "mp-baidu" : {
+        "usingComponents" : true
+    },
+    "mp-toutiao" : {
+        "usingComponents" : true
+    },
+    "uniStatistics" : {
+        "enable" : false
+    },
+    "vueVersion" : "2",
+    "locale" : "zh-Hans",
+    "fallbackLocale" : "yuenan"
+}

BIN
nativeResources/android/res/drawable/not.png


+ 11 - 0
nativeResources/android/res/values/themes.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <style name="HooliganActivityStyle">
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowContentOverlay">@null</item>
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowNoDisplay">false</item>
+        <item name="android:windowDisablePreview">true</item>
+    </style>
+</resources>

BIN
nativeplugins/MapBox-Plugin/.DS_Store


+ 1 - 0
nativeplugins/MapBox-Plugin/android-exclude.txt

@@ -0,0 +1 @@
+mapbox-android-release.aar

BIN
nativeplugins/MapBox-Plugin/android/.DS_Store


BIN
nativeplugins/MapBox-Plugin/android/libbd.aar


BIN
nativeplugins/MapBox-Plugin/android/res/.DS_Store


+ 3 - 0
nativeplugins/MapBox-Plugin/android/res/values/strings.xml

@@ -0,0 +1,3 @@
+<resources>
+    <string name="mapbox_access_token">pk.eyJ1IjoiY2l0eWV4cHJlc3MxNjg4IiwiYSI6ImNsd2xpcHBtZTA1dzIyanBvenBkcGI2aW0ifQ.azi4w1LoND2oYlJFkpFchg</string>
+</resources>

BIN
nativeplugins/MapBox-Plugin/ios/.DS_Store


BIN
nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/.DS_Store


+ 21 - 0
nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXAccuracyAuthorization.h

@@ -0,0 +1,21 @@
+// This file is generated and will be overwritten automatically.
+
+#import <Foundation/Foundation.h>
+
+/** Accuracy authorization granted by user to the app. */
+// NOLINTNEXTLINE(modernize-use-using)
+typedef NS_ENUM(NSInteger, MBXAccuracyAuthorization)
+{
+    /**  An app is not authorized to access location. */
+    MBXAccuracyAuthorizationNone,
+    /** An app is authorized to received as precise as possible location. */
+    MBXAccuracyAuthorizationExact,
+    /**
+     * An app is authorized to receive rough location only.
+     *
+     * Depends on a platform the accuracy is within a city block.
+     */
+    MBXAccuracyAuthorizationInexact
+} NS_SWIFT_NAME(AccuracyAuthorization);
+
+NSString* MBXAccuracyAuthorizationToString(MBXAccuracyAuthorization accuracy_authorization);

+ 28 - 0
nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXCancelable.h

@@ -0,0 +1,28 @@
+// This file is generated and will be overwritten automatically.
+
+#import <Foundation/Foundation.h>
+
+/**
+ * Allows to cancel the associated asynchronous operation
+ *
+ * The associated asynchronous operation is not automatically canceled if this
+ * object goes out of scope.
+ */
+NS_SWIFT_NAME(Cancelable)
+__attribute__((visibility ("default")))
+@interface MBXCancelable : NSObject
+
+// This class provides custom init which should be called
+- (nonnull instancetype)init NS_UNAVAILABLE;
+
+// This class provides custom init which should be called
++ (nonnull instancetype)new NS_UNAVAILABLE;
+
+/**
+ * Cancels the associated asynchronous operation
+ *
+ * If the associated asynchronous operation has already finished, this call is ignored.
+ */
+- (void)cancel;
+
+@end

+ 27 - 0
nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXDownloadError.h

@@ -0,0 +1,27 @@
+// This file is generated and will be overwritten automatically.
+
+#import <Foundation/Foundation.h>
+#import <MapboxCommon/MBXDownloadErrorCode.h>
+
+/** Structure to hold error information about download request. */
+NS_SWIFT_NAME(DownloadError)
+__attribute__((visibility ("default")))
+@interface MBXDownloadError : NSObject
+
+// This class provides custom init which should be called
+- (nonnull instancetype)init NS_UNAVAILABLE;
+
+// This class provides custom init which should be called
++ (nonnull instancetype)new NS_UNAVAILABLE;
+
+- (nonnull instancetype)initWithCode:(MBXDownloadErrorCode)code
+                             message:(nonnull NSString *)message;
+
+/** Download error code. */
+@property (nonatomic, readonly) MBXDownloadErrorCode code;
+
+/** Human readable string describing an error. */
+@property (nonatomic, readonly, nonnull, copy) NSString *message;
+
+
+@end

+ 15 - 0
nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXDownloadErrorCode.h

@@ -0,0 +1,15 @@
+// This file is generated and will be overwritten automatically.
+
+#import <Foundation/Foundation.h>
+
+/** Enum which represents different error cases which could happen during download session. */
+// NOLINTNEXTLINE(modernize-use-using)
+typedef NS_ENUM(NSInteger, MBXDownloadErrorCode)
+{
+    /** General filesystem related error code. For cases like: write error, no such file or directory, not enough space and etc. */
+    MBXDownloadErrorCodeFileSystemError,
+    /** General network related error. Should be probably representation of HttpRequestError. */
+    MBXDownloadErrorCodeNetworkError
+} NS_SWIFT_NAME(DownloadErrorCode);
+
+NSString* MBXDownloadErrorCodeToString(MBXDownloadErrorCode download_error_code);

+ 41 - 0
nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXDownloadOptions.h

@@ -0,0 +1,41 @@
+// This file is generated and will be overwritten automatically.
+
+#import <Foundation/Foundation.h>
+
+@class MBXHttpRequest;
+
+/** Structure to configure download session. */
+NS_SWIFT_NAME(DownloadOptions)
+__attribute__((visibility ("default")))
+@interface MBXDownloadOptions : NSObject
+
+// This class provides custom init which should be called
+- (nonnull instancetype)init NS_UNAVAILABLE;
+
+// This class provides custom init which should be called
++ (nonnull instancetype)new NS_UNAVAILABLE;
+
+- (nonnull instancetype)initWithRequest:(nonnull MBXHttpRequest *)request
+                              localPath:(nonnull NSString *)localPath;
+
+- (nonnull instancetype)initWithRequest:(nonnull MBXHttpRequest *)request
+                              localPath:(nonnull NSString *)localPath
+                                 resume:(BOOL)resume;
+
+/**
+ * Structure which contains parameters to use for sending HTTP request.
+ * Http method will be ignored from this request.
+ */
+@property (nonatomic, readwrite, nonnull) MBXHttpRequest *request;
+
+/**
+ * Absolute path where to store downloaded file. If a file with the specified name already exists and resume is set to
+ * false, the existing file is overwritten.
+ */
+@property (nonatomic, readonly, nonnull, copy) NSString *localPath;
+
+/** If localPath points to an existing file on disk, resume the download starting from an offset equal to file size. */
+@property (nonatomic, readwrite, getter=isResume) BOOL resume;
+
+
+@end

+ 17 - 0
nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXDownloadState.h

@@ -0,0 +1,17 @@
+// This file is generated and will be overwritten automatically.
+
+#import <Foundation/Foundation.h>
+
+/** Enum representing state of download session. */
+// NOLINTNEXTLINE(modernize-use-using)
+typedef NS_ENUM(NSInteger, MBXDownloadState)
+{
+    /** Download session initiated but not started yet. */
+    MBXDownloadStatePending,
+    /** Download session is in progress. */
+    MBXDownloadStateDownloading,
+    /** Download session failed. */
+    MBXDownloadStateFailed,
+    /** Download session successfully finished. */
+    MBXDownloadStateFinished
+} NS_SWIFT_NAME(DownloadState);

+ 52 - 0
nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXDownloadStatus.h

@@ -0,0 +1,52 @@
+// This file is generated and will be overwritten automatically.
+
+#import <Foundation/Foundation.h>
+#import <MapboxCommon/MBXDownloadState.h>
+@class MBXExpected<__covariant Value, __covariant Error>;
+
+@class MBXDownloadError;
+@class MBXDownloadOptions;
+@class MBXHttpRequestError;
+@class MBXHttpResponseData;
+
+/** Structure to hold current status information about ongoing download session. */
+NS_SWIFT_NAME(DownloadStatus)
+__attribute__((visibility ("default")))
+@interface MBXDownloadStatus : NSObject
+
+// This class provides custom init which should be called
+- (nonnull instancetype)init NS_UNAVAILABLE;
+
+// This class provides custom init which should be called
++ (nonnull instancetype)new NS_UNAVAILABLE;
+
+
+/** Download id which was created by download request. */
+@property (nonatomic, readwrite) uint64_t downloadId;
+
+/** State of download request. */
+@property (nonatomic, readwrite) MBXDownloadState state;
+
+/** The optional which contains error information in case of failure when state is set to DownloadState::Failed. */
+@property (nonatomic, readwrite, nullable) MBXDownloadError *error;
+
+/** Total amount of bytes to receive. In some cases this value is unknown until we get final part of the file. */
+@property (nonatomic, readwrite, nullable) NSNumber *totalBytes NS_REFINED_FOR_SWIFT;
+
+/**
+ * Amount of bytes already received and saved on the disk. Includes previous download attempts for a resumed
+ * download.
+ */
+@property (nonatomic, readwrite) uint64_t receivedBytes;
+
+/**
+ * Amount of bytes received during the current resume attempt. For downloads that weren't resumed,
+ * this value will be the same as receivedBytes.
+ */
+@property (nonatomic, readwrite) uint64_t transferredBytes;
+
+/** Download options used to send the download request. */
+@property (nonatomic, readwrite, nonnull) MBXDownloadOptions *downloadOptions;
+
+
+@end

+ 12 - 0
nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXDownloadStatusCallback.h

@@ -0,0 +1,12 @@
+// This file is generated and will be overwritten automatically.
+
+#import <Foundation/Foundation.h>
+
+@class MBXDownloadStatus;
+
+/**
+ * Callback which is getting called to report changes in download session.
+ * This callback can be invoked from any thread at the moment and the client is responsible for posting it back to a desired thread.
+ */
+NS_SWIFT_NAME(DownloadStatusCallback)
+typedef void (^MBXDownloadStatusCallback)(MBXDownloadStatus * _Nonnull status); // NOLINT(modernize-use-using)

+ 23 - 0
nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXFeature.h

@@ -0,0 +1,23 @@
+#import <Foundation/Foundation.h>
+
+@class MBXGeometry;
+
+NS_SWIFT_NAME(Feature)
+__attribute__((visibility ("default")))
+@interface MBXFeature: NSObject
+
+@property (readonly, retain, nonnull) NSObject *identifier;
+@property (readonly, retain, nonnull) MBXGeometry *geometry;
+@property(readonly, retain, nonnull) NSDictionary<NSString *, NSObject *> *properties;
+
+- (nonnull instancetype)initWithIdentifier:(nonnull NSObject *)identifier
+                                  geometry:(nonnull MBXGeometry *)geometry
+                                properties:(nonnull NSDictionary<NSString *, NSObject *> *)properties;
+
+// This class provides custom init which should be called
+- (nonnull instancetype)init NS_UNAVAILABLE;
+
+// This class provides custom init which should be called
++ (nonnull instancetype)new NS_UNAVAILABLE;
+
+@end

+ 36 - 0
nativeplugins/MapBox-Plugin/ios/MapboxCommon.framework/Headers/MBXGeometry.h

@@ -0,0 +1,36 @@
+#import <Foundation/Foundation.h>
+
+// NOLINTNEXTLINE(modernize-use-using)
+typedef enum {
+    MBXGeometryType_Empty NS_SWIFT_NAME(GeometryType_Empty),
+    MBXGeometryType_Point NS_SWIFT_NAME(GeometryType_Point),
+    MBXGeometryType_Line NS_SWIFT_NAME(GeometryType_Line),
+    MBXGeometryType_Polygon NS_SWIFT_NAME(GeometryType_Polygon),
+    MBXGeometryType_MultiPoint NS_SWIFT_NAME(GeometryType_MultiPoint),
+    MBXGeometryType_MultiLine NS_SWIFT_NAME(GeometryType_MultiLine),
+    MBXGeometryType_MultiPolygon NS_SWIFT_NAME(GeometryType_MultiPolygon),
+    MBXGeometryType_GeometryCollection NS_SWIFT_NAME(GeometryType_GeometryCollection)
+} MBXGeometryType NS_SWIFT_NAME(GeometryType);
+
+NS_SWIFT_NAME(Geometry)
+__attribute__((visibility ("default")))
+@interface MBXGeometry: NSObject
+
+@property (readonly, assign) MBXGeometryType geometryType;
+@property (readonly, assign, nonnull) void *geometry;
+
+- (instancetype _Nonnull )initWithPoint:(NSValue* _Nonnull )location;
+- (instancetype _Nonnull )initWithLine:(NSArray<NSValue*>* _Nonnull )locations;
+- (instancetype _Nonnull )initWithPolygon:(NSArray<NSArray<NSValue*> *> *_Nonnull)locations;
+- (instancetype _Nonnull )initWithMultiPoint:(NSArray<NSValue*>* _Nonnull )locations;
+- (instancetype _Nonnull )initWithMultiLine:(NSArray<NSArray<NSValue*> *> *_Nonnull)locations;
+- (instancetype _Nonnull )initWithMultiPolygon:(NSArray<NSArray<NSArray<NSValue*> *> *> * _Nonnull )locations;
+- (instancetype _Nonnull )initWithGeometryCollection:(NSArray<MBXGeometry*> *_Nonnull)geometries;
+
+-(nullable NSValue* )extractLocations;
+-(nullable NSArray<NSValue*>* )extractLocationsArray;
+-(nullable NSArray<NSArray<NSValue*> *> *)extractLocations2DArray;
+-(nullable NSArray<NSArray<NSArray<NSValue*> *> *> *)extractLocations3DArray;
+-(nullable NSArray<MBXGeometry*> *)extractGeometriesArray;
+
+@end

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно