diff --git a/static/js/http.api.js b/static/js/http.api.js
new file mode 100644
index 0000000..04193bb
--- /dev/null
+++ b/static/js/http.api.js
@@ -0,0 +1,59 @@
+// 如果没有通过拦截器配置域名的话，可以在这里写上完整的URL(加上域名部分)
+let bindcardcodeApi = '/v1/bindcardcode'; //绑卡验证码
+let unbindcardApi = '/v1/unbindcard'; //解绑银行卡
+let unsignbxyApi = '/v1/unsignbxy'; //解约
+let qrcodeApi = '/v1/qrcode'; //二维码
+let idtypesApi = '/v1/idtypes'; //绑卡证件类型
+let cardinforApi = '/v1/cardinfor'; //银行卡信息
+let pwdsetApi = '/v1/pwdset'; //登录密码设置
+let billdetailApi = '/v1/billdetail'; //账单详情
+let billsApi = '/v1/bills'; //获取账单列表
+let cardlostApi = '/v1/cardlost'; //市民卡挂失
+let signbxyApi = '/v1/signbxy'; //签约
+let bxyApi = '/v1/bxy'; //协议
+let paypwdApi = '/v1/paypwd'; //支付密码设置
+let codeApi = '/v1/code'; //验证码获取
+let checkcodeApi = '/v1/checkcode'; //验证码验证
+let bindcardApi = '/v1/bindcard'; //绑定银行卡
+let inforApi = '/v1/infor'; //token是否失效
+let registerApi = '/i/register'; //注册
+let checkcodeRegApi = '/i/checkcode'; //注册验证码
+let uxyApi = '/i/uxy'; //用户协议
+let codeRegApi = '/i/code'; //注册验证码
+let timeApi = '/i/time'; //注册验证码
+let loginApi = '/login'; //登录
+
+const install = (Vue, vm) => {
+
+	let bindCardCode = (params = {}) => vm.$u.post(bindcardcodeApiApi, params);
+	let unbindCard = (params = {}) => vm.$u.post(unbindcardApi, params);
+	let unSignBxy = (params = {}) => vm.$u.post(unsignbxyApi, params);
+	let qrcode = (params = {}) => vm.$u.post(qrcodeApi, params);
+	let idTypes = (params = {}) => vm.$u.post(idtypesApi, params);
+	let cardInfor = (params = {}) => vm.$u.post(cardinforApi, params);
+	let setPwd = (params = {}) => vm.$u.post(pwdsetApi, params);
+	let GetBillsDetail = (params = {}) => vm.$u.post(billdetailApi, params);
+	let getBills = (params = {}) => vm.$u.post(billsApi, params);
+	let cardLost = (params = {}) => vm.$u.post(cardlostApi, params);
+	let signBxy = (params = {}) => vm.$u.post(signbxyApi, params);
+	let getBxy = (params = {}) => vm.$u.post(bxyApi, params);
+	let setPayPwd = (params = {}) => vm.$u.post(paypwdApi, params);
+	let getCode = (params = {}) => vm.$u.post(codeApi, params);
+	let checkCode = (params = {}) => vm.$u.post(checkcodeApi, params);
+	let bindCard = (params = {}) => vm.$u.post(bindcardApi, params);
+	let infor = (params = {}) => vm.$u.post(inforApi, params);
+	let register = (params = {}) => vm.$u.post(registerApi, params);
+	let checkRegCode = (params = {}) => vm.$u.post(checkcodeRegApi, params);
+	let getRegCode = (params = {}) => vm.$u.post(codeRegApi, params);
+	let getUxy = (params = {}) => vm.$u.post(uxyApi, params);
+	let time = (params = {}) => vm.$u.post(timeApi, params);
+	let login = (params = {}) => vm.$u.post(loginApi, params);
+
+	// 将各个定义的接口名称，统一放进对象挂载到vm.$u.api(因为vm就是this，也即this.$u.api)下
+	vm.$u.api = {
+		bindCardCode,unbindCard,unSignBxy,qrcode,idTypes,cardInfor,setPwd,GetBillsDetail,getBills,cardLost,signBxy,getBxy,setPayPwd,getCode,checkCode,bindCard,infor,register,checkRegCode,getRegCode,getUxy,time,login
+	};
+}
+
+// export default install
+module.exports = install
diff --git a/static/js/http.interceptor.js b/static/js/http.interceptor.js
new file mode 100644
index 0000000..89d1562
--- /dev/null
+++ b/static/js/http.interceptor.js
@@ -0,0 +1,100 @@
+const install = (Vue, vm) => {
+	// 此为自定义配置参数，具体参数见上方说明
+	Vue.prototype.$u.http.setConfig({
+		// baseUrl: 'https://yy.dlsmk.cn/payapi/mobileapi', // 大理智警域名 
+		baseUrl:'https://yy.dlsmk.cn/portal/mobileapi', //正式地址
+		// baseUrl:'http://yy.dlsmk.cn:8080/portal/mobileapi', //测试地址
+		// baseUrl: "http://172.28.43.20:8089/portal/mobileapi",//本地地址
+		// method: 'POST',
+		// 设置为json，返回后会对数据进行一次JSON.parse()
+		dataType: 'json',
+		// sslVerify:false,
+		showLoading: true, // 是否显示请求中的loading
+		loadingText: '请求中...', // 请求loading中的文字提示
+		loadingTime: 800, // 在此时间内，请求还没回来的话，就显示加载中动画，单位ms
+		originalData: true, // 是否在拦截器中返回服务端的原始数据
+		loadingMask: true, // 展示loading的时候，是否给一个透明的蒙层，防止触摸穿透
+		// 配置请求头信息
+		header: {
+			'content-type': 'application/x-www-form-urlencoded'
+		},
+	});
+	// 请求拦截部分，如配置，每次请求前都会执行
+	Vue.prototype.$u.http.interceptor.request = (config) => {
+		const token = uni.getStorageSync('token');
+		const tenantid = uni.getStorageSync('tenantid');
+		if (token) {
+			config.header['Authorization'] = "Bearer " + token;
+		}else{
+			config.header['Authorization'] = ''
+		}
+		//console.log(config.url,config.header['Authorization'])
+		config.header["X-TENANT-ID"] = tenantid;
+		if (config.url == "/i/activity" || config.url == "/v1/feedback/release" || config.url == '/medicineapi/medicalcard/add') {
+			config.header['content-type'] = "application/json";
+		} else {
+			config.header['content-type'] = "application/x-www-form-urlencoded";
+		}
+		return config;
+	}
+	// 响应拦截，如配置，每次请求结束都会执行本方法
+	Vue.prototype.$u.http.interceptor.response = (res) => {
+		// console.log(res)
+		if (res.statusCode == 200) {
+			// res为服务端返回值，可能有code，result等字段
+			// 这里对res.result进行返回，将会在this.$u.post(url).then(res => {})的then回调中的res的到
+			// 如果配置了originalData为true，请留意这里的返回值
+			if (res.data.code == 200) {
+				return res.data
+			} else if(res.data.code == 500){
+				uni.showModal({
+					title: "提示",
+					content: res.data.code + ":" + res.data.msg,
+					showCancel: false,
+				})
+				return false;
+			} else {
+				uni.showModal({
+					title: "错误",
+					content: res.data.code + ":" + res.data.msg,
+					showCancel: false,
+				})
+				return false;
+			}
+		} else if (res.statusCode == 401) {
+			uni.showToast({
+				title: "登录状态失效,请重新登录",
+				icon: "none",
+				mask:true,
+				duration: 1500,
+				complete(res) {
+					setTimeout(() => {
+						uni.reLaunch({
+							url: "/pages/sub_basic/login/index"
+						})
+					}, 1500)
+				}
+			})
+
+			return false;
+		} else {
+			// 如果返回false，则会调用Promise的reject回调，
+			// 并将进入this.$u.post(url).then().catch(res=>{})的catch回调中，res为服务端的返回值
+			if(res.errMsg.indexOf('fail') == -1){
+				uni.showModal({
+					title: "错误",
+					content: res.data.status + ":" + res.data.message,
+					// content: `${res.data.status}:${res.data.message}`,
+					showCancel: false,
+				})
+			}
+			return false;
+		}
+	}
+
+}
+
+
+// export default install
+module.exports = install
+
diff --git a/static/js/uqrcode.js b/static/js/uqrcode.js
new file mode 100644
index 0000000..099993f
--- /dev/null
+++ b/static/js/uqrcode.js
@@ -0,0 +1,1383 @@
+//---------------------------------------------------------------------
+// github https://github.com/Sansnn/uQRCode
+//---------------------------------------------------------------------
+
+let uQRCode = {};
+
+(function() {
+	//---------------------------------------------------------------------
+	// QRCode for JavaScript
+	//
+	// Copyright (c) 2009 Kazuhiko Arase
+	//
+	// URL: http://www.d-project.com/
+	//
+	// Licensed under the MIT license:
+	//   http://www.opensource.org/licenses/mit-license.php
+	//
+	// The word "QR Code" is registered trademark of 
+	// DENSO WAVE INCORPORATED
+	//   http://www.denso-wave.com/qrcode/faqpatent-e.html
+	//
+	//---------------------------------------------------------------------
+
+	//---------------------------------------------------------------------
+	// QR8bitByte
+	//---------------------------------------------------------------------
+
+	function QR8bitByte(data) {
+		this.mode = QRMode.MODE_8BIT_BYTE;
+		this.data = data;
+	}
+
+	QR8bitByte.prototype = {
+
+		getLength: function(buffer) {
+			return this.data.length;
+		},
+
+		write: function(buffer) {
+			for (var i = 0; i < this.data.length; i++) {
+				// not JIS ...
+				buffer.put(this.data.charCodeAt(i), 8);
+			}
+		}
+	};
+
+	//---------------------------------------------------------------------
+	// QRCode
+	//---------------------------------------------------------------------
+
+	function QRCode(typeNumber, errorCorrectLevel) {
+		this.typeNumber = typeNumber;
+		this.errorCorrectLevel = errorCorrectLevel;
+		this.modules = null;
+		this.moduleCount = 0;
+		this.dataCache = null;
+		this.dataList = new Array();
+	}
+
+	QRCode.prototype = {
+
+		addData: function(data) {
+			var newData = new QR8bitByte(data);
+			this.dataList.push(newData);
+			this.dataCache = null;
+		},
+
+		isDark: function(row, col) {
+			if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {
+				throw new Error(row + "," + col);
+			}
+			return this.modules[row][col];
+		},
+
+		getModuleCount: function() {
+			return this.moduleCount;
+		},
+
+		make: function() {
+			// Calculate automatically typeNumber if provided is < 1
+			if (this.typeNumber < 1) {
+				var typeNumber = 1;
+				for (typeNumber = 1; typeNumber < 40; typeNumber++) {
+					var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel);
+
+					var buffer = new QRBitBuffer();
+					var totalDataCount = 0;
+					for (var i = 0; i < rsBlocks.length; i++) {
+						totalDataCount += rsBlocks[i].dataCount;
+					}
+
+					for (var i = 0; i < this.dataList.length; i++) {
+						var data = this.dataList[i];
+						buffer.put(data.mode, 4);
+						buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber));
+						data.write(buffer);
+					}
+					if (buffer.getLengthInBits() <= totalDataCount * 8)
+						break;
+				}
+				this.typeNumber = typeNumber;
+			}
+			this.makeImpl(false, this.getBestMaskPattern());
+		},
+
+		makeImpl: function(test, maskPattern) {
+
+			this.moduleCount = this.typeNumber * 4 + 17;
+			this.modules = new Array(this.moduleCount);
+
+			for (var row = 0; row < this.moduleCount; row++) {
+
+				this.modules[row] = new Array(this.moduleCount);
+
+				for (var col = 0; col < this.moduleCount; col++) {
+					this.modules[row][col] = null; //(col + row) % 3;
+				}
+			}
+
+			this.setupPositionProbePattern(0, 0);
+			this.setupPositionProbePattern(this.moduleCount - 7, 0);
+			this.setupPositionProbePattern(0, this.moduleCount - 7);
+			this.setupPositionAdjustPattern();
+			this.setupTimingPattern();
+			this.setupTypeInfo(test, maskPattern);
+
+			if (this.typeNumber >= 7) {
+				this.setupTypeNumber(test);
+			}
+
+			if (this.dataCache == null) {
+				this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList);
+			}
+
+			this.mapData(this.dataCache, maskPattern);
+		},
+
+		setupPositionProbePattern: function(row, col) {
+
+			for (var r = -1; r <= 7; r++) {
+
+				if (row + r <= -1 || this.moduleCount <= row + r) continue;
+
+				for (var c = -1; c <= 7; c++) {
+
+					if (col + c <= -1 || this.moduleCount <= col + c) continue;
+
+					if ((0 <= r && r <= 6 && (c == 0 || c == 6)) ||
+						(0 <= c && c <= 6 && (r == 0 || r == 6)) ||
+						(2 <= r && r <= 4 && 2 <= c && c <= 4)) {
+						this.modules[row + r][col + c] = true;
+					} else {
+						this.modules[row + r][col + c] = false;
+					}
+				}
+			}
+		},
+
+		getBestMaskPattern: function() {
+
+			var minLostPoint = 0;
+			var pattern = 0;
+
+			for (var i = 0; i < 8; i++) {
+
+				this.makeImpl(true, i);
+
+				var lostPoint = QRUtil.getLostPoint(this);
+
+				if (i == 0 || minLostPoint > lostPoint) {
+					minLostPoint = lostPoint;
+					pattern = i;
+				}
+			}
+
+			return pattern;
+		},
+
+		createMovieClip: function(target_mc, instance_name, depth) {
+
+			var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth);
+			var cs = 1;
+
+			this.make();
+
+			for (var row = 0; row < this.modules.length; row++) {
+
+				var y = row * cs;
+
+				for (var col = 0; col < this.modules[row].length; col++) {
+
+					var x = col * cs;
+					var dark = this.modules[row][col];
+
+					if (dark) {
+						qr_mc.beginFill(0, 100);
+						qr_mc.moveTo(x, y);
+						qr_mc.lineTo(x + cs, y);
+						qr_mc.lineTo(x + cs, y + cs);
+						qr_mc.lineTo(x, y + cs);
+						qr_mc.endFill();
+					}
+				}
+			}
+
+			return qr_mc;
+		},
+
+		setupTimingPattern: function() {
+
+			for (var r = 8; r < this.moduleCount - 8; r++) {
+				if (this.modules[r][6] != null) {
+					continue;
+				}
+				this.modules[r][6] = (r % 2 == 0);
+			}
+
+			for (var c = 8; c < this.moduleCount - 8; c++) {
+				if (this.modules[6][c] != null) {
+					continue;
+				}
+				this.modules[6][c] = (c % 2 == 0);
+			}
+		},
+
+		setupPositionAdjustPattern: function() {
+
+			var pos = QRUtil.getPatternPosition(this.typeNumber);
+
+			for (var i = 0; i < pos.length; i++) {
+
+				for (var j = 0; j < pos.length; j++) {
+
+					var row = pos[i];
+					var col = pos[j];
+
+					if (this.modules[row][col] != null) {
+						continue;
+					}
+
+					for (var r = -2; r <= 2; r++) {
+
+						for (var c = -2; c <= 2; c++) {
+
+							if (r == -2 || r == 2 || c == -2 || c == 2 ||
+								(r == 0 && c == 0)) {
+								this.modules[row + r][col + c] = true;
+							} else {
+								this.modules[row + r][col + c] = false;
+							}
+						}
+					}
+				}
+			}
+		},
+
+		setupTypeNumber: function(test) {
+
+			var bits = QRUtil.getBCHTypeNumber(this.typeNumber);
+
+			for (var i = 0; i < 18; i++) {
+				var mod = (!test && ((bits >> i) & 1) == 1);
+				this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;
+			}
+
+			for (var i = 0; i < 18; i++) {
+				var mod = (!test && ((bits >> i) & 1) == 1);
+				this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
+			}
+		},
+
+		setupTypeInfo: function(test, maskPattern) {
+
+			var data = (this.errorCorrectLevel << 3) | maskPattern;
+			var bits = QRUtil.getBCHTypeInfo(data);
+
+			// vertical		
+			for (var i = 0; i < 15; i++) {
+
+				var mod = (!test && ((bits >> i) & 1) == 1);
+
+				if (i < 6) {
+					this.modules[i][8] = mod;
+				} else if (i < 8) {
+					this.modules[i + 1][8] = mod;
+				} else {
+					this.modules[this.moduleCount - 15 + i][8] = mod;
+				}
+			}
+
+			// horizontal
+			for (var i = 0; i < 15; i++) {
+
+				var mod = (!test && ((bits >> i) & 1) == 1);
+
+				if (i < 8) {
+					this.modules[8][this.moduleCount - i - 1] = mod;
+				} else if (i < 9) {
+					this.modules[8][15 - i - 1 + 1] = mod;
+				} else {
+					this.modules[8][15 - i - 1] = mod;
+				}
+			}
+
+			// fixed module
+			this.modules[this.moduleCount - 8][8] = (!test);
+
+		},
+
+		mapData: function(data, maskPattern) {
+
+			var inc = -1;
+			var row = this.moduleCount - 1;
+			var bitIndex = 7;
+			var byteIndex = 0;
+
+			for (var col = this.moduleCount - 1; col > 0; col -= 2) {
+
+				if (col == 6) col--;
+
+				while (true) {
+
+					for (var c = 0; c < 2; c++) {
+
+						if (this.modules[row][col - c] == null) {
+
+							var dark = false;
+
+							if (byteIndex < data.length) {
+								dark = (((data[byteIndex] >>> bitIndex) & 1) == 1);
+							}
+
+							var mask = QRUtil.getMask(maskPattern, row, col - c);
+
+							if (mask) {
+								dark = !dark;
+							}
+
+							this.modules[row][col - c] = dark;
+							bitIndex--;
+
+							if (bitIndex == -1) {
+								byteIndex++;
+								bitIndex = 7;
+							}
+						}
+					}
+
+					row += inc;
+
+					if (row < 0 || this.moduleCount <= row) {
+						row -= inc;
+						inc = -inc;
+						break;
+					}
+				}
+			}
+
+		}
+
+	};
+
+	QRCode.PAD0 = 0xEC;
+	QRCode.PAD1 = 0x11;
+
+	QRCode.createData = function(typeNumber, errorCorrectLevel, dataList) {
+
+		var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
+
+		var buffer = new QRBitBuffer();
+
+		for (var i = 0; i < dataList.length; i++) {
+			var data = dataList[i];
+			buffer.put(data.mode, 4);
+			buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber));
+			data.write(buffer);
+		}
+
+		// calc num max data.
+		var totalDataCount = 0;
+		for (var i = 0; i < rsBlocks.length; i++) {
+			totalDataCount += rsBlocks[i].dataCount;
+		}
+
+		if (buffer.getLengthInBits() > totalDataCount * 8) {
+			throw new Error("code length overflow. (" +
+				buffer.getLengthInBits() +
+				">" +
+				totalDataCount * 8 +
+				")");
+		}
+
+		// end code
+		if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
+			buffer.put(0, 4);
+		}
+
+		// padding
+		while (buffer.getLengthInBits() % 8 != 0) {
+			buffer.putBit(false);
+		}
+
+		// padding
+		while (true) {
+
+			if (buffer.getLengthInBits() >= totalDataCount * 8) {
+				break;
+			}
+			buffer.put(QRCode.PAD0, 8);
+
+			if (buffer.getLengthInBits() >= totalDataCount * 8) {
+				break;
+			}
+			buffer.put(QRCode.PAD1, 8);
+		}
+
+		return QRCode.createBytes(buffer, rsBlocks);
+	}
+
+	QRCode.createBytes = function(buffer, rsBlocks) {
+
+		var offset = 0;
+
+		var maxDcCount = 0;
+		var maxEcCount = 0;
+
+		var dcdata = new Array(rsBlocks.length);
+		var ecdata = new Array(rsBlocks.length);
+
+		for (var r = 0; r < rsBlocks.length; r++) {
+
+			var dcCount = rsBlocks[r].dataCount;
+			var ecCount = rsBlocks[r].totalCount - dcCount;
+
+			maxDcCount = Math.max(maxDcCount, dcCount);
+			maxEcCount = Math.max(maxEcCount, ecCount);
+
+			dcdata[r] = new Array(dcCount);
+
+			for (var i = 0; i < dcdata[r].length; i++) {
+				dcdata[r][i] = 0xff & buffer.buffer[i + offset];
+			}
+			offset += dcCount;
+
+			var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
+			var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1);
+
+			var modPoly = rawPoly.mod(rsPoly);
+			ecdata[r] = new Array(rsPoly.getLength() - 1);
+			for (var i = 0; i < ecdata[r].length; i++) {
+				var modIndex = i + modPoly.getLength() - ecdata[r].length;
+				ecdata[r][i] = (modIndex >= 0) ? modPoly.get(modIndex) : 0;
+			}
+
+		}
+
+		var totalCodeCount = 0;
+		for (var i = 0; i < rsBlocks.length; i++) {
+			totalCodeCount += rsBlocks[i].totalCount;
+		}
+
+		var data = new Array(totalCodeCount);
+		var index = 0;
+
+		for (var i = 0; i < maxDcCount; i++) {
+			for (var r = 0; r < rsBlocks.length; r++) {
+				if (i < dcdata[r].length) {
+					data[index++] = dcdata[r][i];
+				}
+			}
+		}
+
+		for (var i = 0; i < maxEcCount; i++) {
+			for (var r = 0; r < rsBlocks.length; r++) {
+				if (i < ecdata[r].length) {
+					data[index++] = ecdata[r][i];
+				}
+			}
+		}
+
+		return data;
+
+	}
+
+	//---------------------------------------------------------------------
+	// QRMode
+	//---------------------------------------------------------------------
+
+	var QRMode = {
+		MODE_NUMBER: 1 << 0,
+		MODE_ALPHA_NUM: 1 << 1,
+		MODE_8BIT_BYTE: 1 << 2,
+		MODE_KANJI: 1 << 3
+	};
+
+	//---------------------------------------------------------------------
+	// QRErrorCorrectLevel
+	//---------------------------------------------------------------------
+
+	var QRErrorCorrectLevel = {
+		L: 1,
+		M: 0,
+		Q: 3,
+		H: 2
+	};
+
+	//---------------------------------------------------------------------
+	// QRMaskPattern
+	//---------------------------------------------------------------------
+
+	var QRMaskPattern = {
+		PATTERN000: 0,
+		PATTERN001: 1,
+		PATTERN010: 2,
+		PATTERN011: 3,
+		PATTERN100: 4,
+		PATTERN101: 5,
+		PATTERN110: 6,
+		PATTERN111: 7
+	};
+
+	//---------------------------------------------------------------------
+	// QRUtil
+	//---------------------------------------------------------------------
+
+	var QRUtil = {
+
+		PATTERN_POSITION_TABLE: [
+			[],
+			[6, 18],
+			[6, 22],
+			[6, 26],
+			[6, 30],
+			[6, 34],
+			[6, 22, 38],
+			[6, 24, 42],
+			[6, 26, 46],
+			[6, 28, 50],
+			[6, 30, 54],
+			[6, 32, 58],
+			[6, 34, 62],
+			[6, 26, 46, 66],
+			[6, 26, 48, 70],
+			[6, 26, 50, 74],
+			[6, 30, 54, 78],
+			[6, 30, 56, 82],
+			[6, 30, 58, 86],
+			[6, 34, 62, 90],
+			[6, 28, 50, 72, 94],
+			[6, 26, 50, 74, 98],
+			[6, 30, 54, 78, 102],
+			[6, 28, 54, 80, 106],
+			[6, 32, 58, 84, 110],
+			[6, 30, 58, 86, 114],
+			[6, 34, 62, 90, 118],
+			[6, 26, 50, 74, 98, 122],
+			[6, 30, 54, 78, 102, 126],
+			[6, 26, 52, 78, 104, 130],
+			[6, 30, 56, 82, 108, 134],
+			[6, 34, 60, 86, 112, 138],
+			[6, 30, 58, 86, 114, 142],
+			[6, 34, 62, 90, 118, 146],
+			[6, 30, 54, 78, 102, 126, 150],
+			[6, 24, 50, 76, 102, 128, 154],
+			[6, 28, 54, 80, 106, 132, 158],
+			[6, 32, 58, 84, 110, 136, 162],
+			[6, 26, 54, 82, 110, 138, 166],
+			[6, 30, 58, 86, 114, 142, 170]
+		],
+
+		G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
+		G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
+		G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
+
+		getBCHTypeInfo: function(data) {
+			var d = data << 10;
+			while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
+				d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15)));
+			}
+			return ((data << 10) | d) ^ QRUtil.G15_MASK;
+		},
+
+		getBCHTypeNumber: function(data) {
+			var d = data << 12;
+			while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
+				d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18)));
+			}
+			return (data << 12) | d;
+		},
+
+		getBCHDigit: function(data) {
+
+			var digit = 0;
+
+			while (data != 0) {
+				digit++;
+				data >>>= 1;
+			}
+
+			return digit;
+		},
+
+		getPatternPosition: function(typeNumber) {
+			return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
+		},
+
+		getMask: function(maskPattern, i, j) {
+
+			switch (maskPattern) {
+
+				case QRMaskPattern.PATTERN000:
+					return (i + j) % 2 == 0;
+				case QRMaskPattern.PATTERN001:
+					return i % 2 == 0;
+				case QRMaskPattern.PATTERN010:
+					return j % 3 == 0;
+				case QRMaskPattern.PATTERN011:
+					return (i + j) % 3 == 0;
+				case QRMaskPattern.PATTERN100:
+					return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0;
+				case QRMaskPattern.PATTERN101:
+					return (i * j) % 2 + (i * j) % 3 == 0;
+				case QRMaskPattern.PATTERN110:
+					return ((i * j) % 2 + (i * j) % 3) % 2 == 0;
+				case QRMaskPattern.PATTERN111:
+					return ((i * j) % 3 + (i + j) % 2) % 2 == 0;
+
+				default:
+					throw new Error("bad maskPattern:" + maskPattern);
+			}
+		},
+
+		getErrorCorrectPolynomial: function(errorCorrectLength) {
+
+			var a = new QRPolynomial([1], 0);
+
+			for (var i = 0; i < errorCorrectLength; i++) {
+				a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0));
+			}
+
+			return a;
+		},
+
+		getLengthInBits: function(mode, type) {
+
+			if (1 <= type && type < 10) {
+
+				// 1 - 9
+
+				switch (mode) {
+					case QRMode.MODE_NUMBER:
+						return 10;
+					case QRMode.MODE_ALPHA_NUM:
+						return 9;
+					case QRMode.MODE_8BIT_BYTE:
+						return 8;
+					case QRMode.MODE_KANJI:
+						return 8;
+					default:
+						throw new Error("mode:" + mode);
+				}
+
+			} else if (type < 27) {
+
+				// 10 - 26
+
+				switch (mode) {
+					case QRMode.MODE_NUMBER:
+						return 12;
+					case QRMode.MODE_ALPHA_NUM:
+						return 11;
+					case QRMode.MODE_8BIT_BYTE:
+						return 16;
+					case QRMode.MODE_KANJI:
+						return 10;
+					default:
+						throw new Error("mode:" + mode);
+				}
+
+			} else if (type < 41) {
+
+				// 27 - 40
+
+				switch (mode) {
+					case QRMode.MODE_NUMBER:
+						return 14;
+					case QRMode.MODE_ALPHA_NUM:
+						return 13;
+					case QRMode.MODE_8BIT_BYTE:
+						return 16;
+					case QRMode.MODE_KANJI:
+						return 12;
+					default:
+						throw new Error("mode:" + mode);
+				}
+
+			} else {
+				throw new Error("type:" + type);
+			}
+		},
+
+		getLostPoint: function(qrCode) {
+
+			var moduleCount = qrCode.getModuleCount();
+
+			var lostPoint = 0;
+
+			// LEVEL1
+
+			for (var row = 0; row < moduleCount; row++) {
+
+				for (var col = 0; col < moduleCount; col++) {
+
+					var sameCount = 0;
+					var dark = qrCode.isDark(row, col);
+
+					for (var r = -1; r <= 1; r++) {
+
+						if (row + r < 0 || moduleCount <= row + r) {
+							continue;
+						}
+
+						for (var c = -1; c <= 1; c++) {
+
+							if (col + c < 0 || moduleCount <= col + c) {
+								continue;
+							}
+
+							if (r == 0 && c == 0) {
+								continue;
+							}
+
+							if (dark == qrCode.isDark(row + r, col + c)) {
+								sameCount++;
+							}
+						}
+					}
+
+					if (sameCount > 5) {
+						lostPoint += (3 + sameCount - 5);
+					}
+				}
+			}
+
+			// LEVEL2
+
+			for (var row = 0; row < moduleCount - 1; row++) {
+				for (var col = 0; col < moduleCount - 1; col++) {
+					var count = 0;
+					if (qrCode.isDark(row, col)) count++;
+					if (qrCode.isDark(row + 1, col)) count++;
+					if (qrCode.isDark(row, col + 1)) count++;
+					if (qrCode.isDark(row + 1, col + 1)) count++;
+					if (count == 0 || count == 4) {
+						lostPoint += 3;
+					}
+				}
+			}
+
+			// LEVEL3
+
+			for (var row = 0; row < moduleCount; row++) {
+				for (var col = 0; col < moduleCount - 6; col++) {
+					if (qrCode.isDark(row, col) &&
+						!qrCode.isDark(row, col + 1) &&
+						qrCode.isDark(row, col + 2) &&
+						qrCode.isDark(row, col + 3) &&
+						qrCode.isDark(row, col + 4) &&
+						!qrCode.isDark(row, col + 5) &&
+						qrCode.isDark(row, col + 6)) {
+						lostPoint += 40;
+					}
+				}
+			}
+
+			for (var col = 0; col < moduleCount; col++) {
+				for (var row = 0; row < moduleCount - 6; row++) {
+					if (qrCode.isDark(row, col) &&
+						!qrCode.isDark(row + 1, col) &&
+						qrCode.isDark(row + 2, col) &&
+						qrCode.isDark(row + 3, col) &&
+						qrCode.isDark(row + 4, col) &&
+						!qrCode.isDark(row + 5, col) &&
+						qrCode.isDark(row + 6, col)) {
+						lostPoint += 40;
+					}
+				}
+			}
+
+			// LEVEL4
+
+			var darkCount = 0;
+
+			for (var col = 0; col < moduleCount; col++) {
+				for (var row = 0; row < moduleCount; row++) {
+					if (qrCode.isDark(row, col)) {
+						darkCount++;
+					}
+				}
+			}
+
+			var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
+			lostPoint += ratio * 10;
+
+			return lostPoint;
+		}
+
+	};
+
+
+	//---------------------------------------------------------------------
+	// QRMath
+	//---------------------------------------------------------------------
+
+	var QRMath = {
+
+		glog: function(n) {
+
+			if (n < 1) {
+				throw new Error("glog(" + n + ")");
+			}
+
+			return QRMath.LOG_TABLE[n];
+		},
+
+		gexp: function(n) {
+
+			while (n < 0) {
+				n += 255;
+			}
+
+			while (n >= 256) {
+				n -= 255;
+			}
+
+			return QRMath.EXP_TABLE[n];
+		},
+
+		EXP_TABLE: new Array(256),
+
+		LOG_TABLE: new Array(256)
+
+	};
+
+	for (var i = 0; i < 8; i++) {
+		QRMath.EXP_TABLE[i] = 1 << i;
+	}
+	for (var i = 8; i < 256; i++) {
+		QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^
+			QRMath.EXP_TABLE[i - 5] ^
+			QRMath.EXP_TABLE[i - 6] ^
+			QRMath.EXP_TABLE[i - 8];
+	}
+	for (var i = 0; i < 255; i++) {
+		QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i;
+	}
+
+	//---------------------------------------------------------------------
+	// QRPolynomial
+	//---------------------------------------------------------------------
+
+	function QRPolynomial(num, shift) {
+
+		if (num.length == undefined) {
+			throw new Error(num.length + "/" + shift);
+		}
+
+		var offset = 0;
+
+		while (offset < num.length && num[offset] == 0) {
+			offset++;
+		}
+
+		this.num = new Array(num.length - offset + shift);
+		for (var i = 0; i < num.length - offset; i++) {
+			this.num[i] = num[i + offset];
+		}
+	}
+
+	QRPolynomial.prototype = {
+
+		get: function(index) {
+			return this.num[index];
+		},
+
+		getLength: function() {
+			return this.num.length;
+		},
+
+		multiply: function(e) {
+
+			var num = new Array(this.getLength() + e.getLength() - 1);
+
+			for (var i = 0; i < this.getLength(); i++) {
+				for (var j = 0; j < e.getLength(); j++) {
+					num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)));
+				}
+			}
+
+			return new QRPolynomial(num, 0);
+		},
+
+		mod: function(e) {
+
+			if (this.getLength() - e.getLength() < 0) {
+				return this;
+			}
+
+			var ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0));
+
+			var num = new Array(this.getLength());
+
+			for (var i = 0; i < this.getLength(); i++) {
+				num[i] = this.get(i);
+			}
+
+			for (var i = 0; i < e.getLength(); i++) {
+				num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio);
+			}
+
+			// recursive call
+			return new QRPolynomial(num, 0).mod(e);
+		}
+	};
+
+	//---------------------------------------------------------------------
+	// QRRSBlock
+	//---------------------------------------------------------------------
+
+	function QRRSBlock(totalCount, dataCount) {
+		this.totalCount = totalCount;
+		this.dataCount = dataCount;
+	}
+
+	QRRSBlock.RS_BLOCK_TABLE = [
+
+		// L
+		// M
+		// Q
+		// H
+
+		// 1
+		[1, 26, 19],
+		[1, 26, 16],
+		[1, 26, 13],
+		[1, 26, 9],
+
+		// 2
+		[1, 44, 34],
+		[1, 44, 28],
+		[1, 44, 22],
+		[1, 44, 16],
+
+		// 3
+		[1, 70, 55],
+		[1, 70, 44],
+		[2, 35, 17],
+		[2, 35, 13],
+
+		// 4		
+		[1, 100, 80],
+		[2, 50, 32],
+		[2, 50, 24],
+		[4, 25, 9],
+
+		// 5
+		[1, 134, 108],
+		[2, 67, 43],
+		[2, 33, 15, 2, 34, 16],
+		[2, 33, 11, 2, 34, 12],
+
+		// 6
+		[2, 86, 68],
+		[4, 43, 27],
+		[4, 43, 19],
+		[4, 43, 15],
+
+		// 7		
+		[2, 98, 78],
+		[4, 49, 31],
+		[2, 32, 14, 4, 33, 15],
+		[4, 39, 13, 1, 40, 14],
+
+		// 8
+		[2, 121, 97],
+		[2, 60, 38, 2, 61, 39],
+		[4, 40, 18, 2, 41, 19],
+		[4, 40, 14, 2, 41, 15],
+
+		// 9
+		[2, 146, 116],
+		[3, 58, 36, 2, 59, 37],
+		[4, 36, 16, 4, 37, 17],
+		[4, 36, 12, 4, 37, 13],
+
+		// 10		
+		[2, 86, 68, 2, 87, 69],
+		[4, 69, 43, 1, 70, 44],
+		[6, 43, 19, 2, 44, 20],
+		[6, 43, 15, 2, 44, 16],
+
+		// 11
+		[4, 101, 81],
+		[1, 80, 50, 4, 81, 51],
+		[4, 50, 22, 4, 51, 23],
+		[3, 36, 12, 8, 37, 13],
+
+		// 12
+		[2, 116, 92, 2, 117, 93],
+		[6, 58, 36, 2, 59, 37],
+		[4, 46, 20, 6, 47, 21],
+		[7, 42, 14, 4, 43, 15],
+
+		// 13
+		[4, 133, 107],
+		[8, 59, 37, 1, 60, 38],
+		[8, 44, 20, 4, 45, 21],
+		[12, 33, 11, 4, 34, 12],
+
+		// 14
+		[3, 145, 115, 1, 146, 116],
+		[4, 64, 40, 5, 65, 41],
+		[11, 36, 16, 5, 37, 17],
+		[11, 36, 12, 5, 37, 13],
+
+		// 15
+		[5, 109, 87, 1, 110, 88],
+		[5, 65, 41, 5, 66, 42],
+		[5, 54, 24, 7, 55, 25],
+		[11, 36, 12],
+
+		// 16
+		[5, 122, 98, 1, 123, 99],
+		[7, 73, 45, 3, 74, 46],
+		[15, 43, 19, 2, 44, 20],
+		[3, 45, 15, 13, 46, 16],
+
+		// 17
+		[1, 135, 107, 5, 136, 108],
+		[10, 74, 46, 1, 75, 47],
+		[1, 50, 22, 15, 51, 23],
+		[2, 42, 14, 17, 43, 15],
+
+		// 18
+		[5, 150, 120, 1, 151, 121],
+		[9, 69, 43, 4, 70, 44],
+		[17, 50, 22, 1, 51, 23],
+		[2, 42, 14, 19, 43, 15],
+
+		// 19
+		[3, 141, 113, 4, 142, 114],
+		[3, 70, 44, 11, 71, 45],
+		[17, 47, 21, 4, 48, 22],
+		[9, 39, 13, 16, 40, 14],
+
+		// 20
+		[3, 135, 107, 5, 136, 108],
+		[3, 67, 41, 13, 68, 42],
+		[15, 54, 24, 5, 55, 25],
+		[15, 43, 15, 10, 44, 16],
+
+		// 21
+		[4, 144, 116, 4, 145, 117],
+		[17, 68, 42],
+		[17, 50, 22, 6, 51, 23],
+		[19, 46, 16, 6, 47, 17],
+
+		// 22
+		[2, 139, 111, 7, 140, 112],
+		[17, 74, 46],
+		[7, 54, 24, 16, 55, 25],
+		[34, 37, 13],
+
+		// 23
+		[4, 151, 121, 5, 152, 122],
+		[4, 75, 47, 14, 76, 48],
+		[11, 54, 24, 14, 55, 25],
+		[16, 45, 15, 14, 46, 16],
+
+		// 24
+		[6, 147, 117, 4, 148, 118],
+		[6, 73, 45, 14, 74, 46],
+		[11, 54, 24, 16, 55, 25],
+		[30, 46, 16, 2, 47, 17],
+
+		// 25
+		[8, 132, 106, 4, 133, 107],
+		[8, 75, 47, 13, 76, 48],
+		[7, 54, 24, 22, 55, 25],
+		[22, 45, 15, 13, 46, 16],
+
+		// 26
+		[10, 142, 114, 2, 143, 115],
+		[19, 74, 46, 4, 75, 47],
+		[28, 50, 22, 6, 51, 23],
+		[33, 46, 16, 4, 47, 17],
+
+		// 27
+		[8, 152, 122, 4, 153, 123],
+		[22, 73, 45, 3, 74, 46],
+		[8, 53, 23, 26, 54, 24],
+		[12, 45, 15, 28, 46, 16],
+
+		// 28
+		[3, 147, 117, 10, 148, 118],
+		[3, 73, 45, 23, 74, 46],
+		[4, 54, 24, 31, 55, 25],
+		[11, 45, 15, 31, 46, 16],
+
+		// 29
+		[7, 146, 116, 7, 147, 117],
+		[21, 73, 45, 7, 74, 46],
+		[1, 53, 23, 37, 54, 24],
+		[19, 45, 15, 26, 46, 16],
+
+		// 30
+		[5, 145, 115, 10, 146, 116],
+		[19, 75, 47, 10, 76, 48],
+		[15, 54, 24, 25, 55, 25],
+		[23, 45, 15, 25, 46, 16],
+
+		// 31
+		[13, 145, 115, 3, 146, 116],
+		[2, 74, 46, 29, 75, 47],
+		[42, 54, 24, 1, 55, 25],
+		[23, 45, 15, 28, 46, 16],
+
+		// 32
+		[17, 145, 115],
+		[10, 74, 46, 23, 75, 47],
+		[10, 54, 24, 35, 55, 25],
+		[19, 45, 15, 35, 46, 16],
+
+		// 33
+		[17, 145, 115, 1, 146, 116],
+		[14, 74, 46, 21, 75, 47],
+		[29, 54, 24, 19, 55, 25],
+		[11, 45, 15, 46, 46, 16],
+
+		// 34
+		[13, 145, 115, 6, 146, 116],
+		[14, 74, 46, 23, 75, 47],
+		[44, 54, 24, 7, 55, 25],
+		[59, 46, 16, 1, 47, 17],
+
+		// 35
+		[12, 151, 121, 7, 152, 122],
+		[12, 75, 47, 26, 76, 48],
+		[39, 54, 24, 14, 55, 25],
+		[22, 45, 15, 41, 46, 16],
+
+		// 36
+		[6, 151, 121, 14, 152, 122],
+		[6, 75, 47, 34, 76, 48],
+		[46, 54, 24, 10, 55, 25],
+		[2, 45, 15, 64, 46, 16],
+
+		// 37
+		[17, 152, 122, 4, 153, 123],
+		[29, 74, 46, 14, 75, 47],
+		[49, 54, 24, 10, 55, 25],
+		[24, 45, 15, 46, 46, 16],
+
+		// 38
+		[4, 152, 122, 18, 153, 123],
+		[13, 74, 46, 32, 75, 47],
+		[48, 54, 24, 14, 55, 25],
+		[42, 45, 15, 32, 46, 16],
+
+		// 39
+		[20, 147, 117, 4, 148, 118],
+		[40, 75, 47, 7, 76, 48],
+		[43, 54, 24, 22, 55, 25],
+		[10, 45, 15, 67, 46, 16],
+
+		// 40
+		[19, 148, 118, 6, 149, 119],
+		[18, 75, 47, 31, 76, 48],
+		[34, 54, 24, 34, 55, 25],
+		[20, 45, 15, 61, 46, 16]
+	];
+
+	QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) {
+
+		var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
+
+		if (rsBlock == undefined) {
+			throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel);
+		}
+
+		var length = rsBlock.length / 3;
+
+		var list = new Array();
+
+		for (var i = 0; i < length; i++) {
+
+			var count = rsBlock[i * 3 + 0];
+			var totalCount = rsBlock[i * 3 + 1];
+			var dataCount = rsBlock[i * 3 + 2];
+
+			for (var j = 0; j < count; j++) {
+				list.push(new QRRSBlock(totalCount, dataCount));
+			}
+		}
+
+		return list;
+	}
+
+	QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) {
+
+		switch (errorCorrectLevel) {
+			case QRErrorCorrectLevel.L:
+				return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
+			case QRErrorCorrectLevel.M:
+				return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
+			case QRErrorCorrectLevel.Q:
+				return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
+			case QRErrorCorrectLevel.H:
+				return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
+			default:
+				return undefined;
+		}
+	}
+
+	//---------------------------------------------------------------------
+	// QRBitBuffer
+	//---------------------------------------------------------------------
+
+	function QRBitBuffer() {
+		this.buffer = new Array();
+		this.length = 0;
+	}
+
+	QRBitBuffer.prototype = {
+
+		get: function(index) {
+			var bufIndex = Math.floor(index / 8);
+			return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1) == 1;
+		},
+
+		put: function(num, length) {
+			for (var i = 0; i < length; i++) {
+				this.putBit(((num >>> (length - i - 1)) & 1) == 1);
+			}
+		},
+
+		getLengthInBits: function() {
+			return this.length;
+		},
+
+		putBit: function(bit) {
+
+			var bufIndex = Math.floor(this.length / 8);
+			if (this.buffer.length <= bufIndex) {
+				this.buffer.push(0);
+			}
+
+			if (bit) {
+				this.buffer[bufIndex] |= (0x80 >>> (this.length % 8));
+			}
+
+			this.length++;
+		}
+	};
+
+	//---------------------------------------------------------------------
+	// Support Chinese
+	//---------------------------------------------------------------------
+	function utf16To8(text) {
+		var result = '';
+		var c;
+		for (var i = 0; i < text.length; i++) {
+			c = text.charCodeAt(i);
+			if (c >= 0x0001 && c <= 0x007F) {
+				result += text.charAt(i);
+			} else if (c > 0x07FF) {
+				result += String.fromCharCode(0xE0 | c >> 12 & 0x0F);
+				result += String.fromCharCode(0x80 | c >> 6 & 0x3F);
+				result += String.fromCharCode(0x80 | c >> 0 & 0x3F);
+			} else {
+				result += String.fromCharCode(0xC0 | c >> 6 & 0x1F);
+				result += String.fromCharCode(0x80 | c >> 0 & 0x3F);
+			}
+		}
+		return result;
+	}
+
+	uQRCode = {
+		
+		errorCorrectLevel: QRErrorCorrectLevel,
+		
+		defaults: {
+			size: 354,
+			margin: 0,
+			backgroundColor: '#ffffff',
+			foregroundColor: '#000000',
+			fileType: 'png', // 'jpg', 'png'
+			errorCorrectLevel: QRErrorCorrectLevel.H,
+			typeNumber: -1
+		},
+
+		make: function(options) {
+			var defaultOptions = {
+				canvasId: options.canvasId,
+				componentInstance: options.componentInstance,
+				text: options.text,
+				size: this.defaults.size,
+				margin: this.defaults.margin,
+				backgroundColor: this.defaults.backgroundColor,
+				foregroundColor: this.defaults.foregroundColor,
+				fileType: this.defaults.fileType,
+				errorCorrectLevel: this.defaults.errorCorrectLevel,
+				typeNumber: this.defaults.typeNumber
+			};
+			if (options) {
+				for (var i in options) {
+					defaultOptions[i] = options[i];
+				}
+			}
+			options = defaultOptions;
+			if (!options.canvasId) {
+				console.error('uQRCode: Please set canvasId!');
+				return;
+			}
+
+			function createCanvas() {
+				var qrcode = new QRCode(options.typeNumber, options.errorCorrectLevel);
+				qrcode.addData(utf16To8(options.text));
+				qrcode.make();
+
+				var ctx = uni.createCanvasContext(options.canvasId, options.componentInstance);
+				ctx.setFillStyle(options.backgroundColor);
+				ctx.fillRect(0, 0, options.size, options.size);
+
+				var tileW = (options.size - options.margin * 2) / qrcode.getModuleCount();
+				var tileH = tileW;
+
+				for (var row = 0; row < qrcode.getModuleCount(); row++) {
+					for (var col = 0; col < qrcode.getModuleCount(); col++) {
+						var style = qrcode.isDark(row, col) ? options.foregroundColor : options.backgroundColor;
+						ctx.setFillStyle(style);
+						var x = Math.round(col * tileW) + options.margin;
+						var y = Math.round(row * tileH) + options.margin;
+						var w = Math.ceil((col + 1) * tileW) - Math.floor(col * tileW);
+						var h = Math.ceil((row + 1) * tileW) - Math.floor(row * tileW);
+						ctx.fillRect(x, y, w, h);
+					}
+				}
+
+				setTimeout(function() {
+					ctx.draw(false, (function() {
+						setTimeout(function() {
+							uni.canvasToTempFilePath({
+								canvasId: options.canvasId,
+								fileType: options.fileType,
+								width: options.size,
+								height: options.size,
+								destWidth: options.size,
+								destHeight: options.size,
+								success: function(res) {
+									options.success && options.success(res.tempFilePath);
+								},
+								fail: function(error) {
+									options.fail && options.fail(error);
+								},
+								complete: function(res) {
+									options.complete && options.complete(res);
+								}
+							}, options.componentInstance);
+						}, options.text.length + 100);
+					})());
+				}, 150);
+			}
+			
+			createCanvas();
+		}
+
+	}
+
+})()
+
+// export default uQRCode
+module.exports = uQRCode
