PageSourceSearch

https://www.ubo.cl/wp-content/plugins/ht-qrcode-generator/assets/js/easy.qrcode.min.js?ver=2.3.7

js ubo.cl collected 2026-10-02 04:42:02 UTC 58,150 bytes, 1,932 lines download raw bytes

1/**
2 * EasyQRCodeJS
3 * 
4 * Cross-browser QRCode generator for pure javascript. Support Dot style, Logo, Background image, Colorful, Title, etc. Support Angular, Vue.js, React framework. (Running with DOM on client side)
5 * 
6 * Version 3.4.0
7 * 
8 * @author [ [email protected] ]
9 * 
10 * @see https://github.com/ushelp/EasyQRCodeJS 
11 * @see http://www.easyproject.cn/easyqrcodejs/tryit.html
12 * @see https://github.com/ushelp/EasyQRCodeJS-NodeJS
13 * 
14 * Copyright 2017 Ray, EasyProject
15 * Released under the MIT license
16 * 
17 * [Support AMD, CMD, CommonJS/Node.js]
18 * 
19 */
20 ;(function() {
21
22	// 启用严格模式
23	"use strict";
24
25	// 自定义局部 undefined 变量
26	var undefined;
27
28	/** Node.js global 检测. */
29	var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
30
31	/** `self` 变量检测. */
32	var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
33
34	/** 全局对象检测. */
35	var root = freeGlobal || freeSelf || Function('return this')();
36
37	/** `exports` 变量检测. */
38	var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
39
40	/** `module` 变量检测. */
41	var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
42
43	var _QRCode = root.QRCode;
44
45	var QRCode;
46
47	function QR8bitByte(data) {
48		this.mode = QRMode.MODE_8BIT_BYTE;
49		this.data = data;
50		this.parsedData = [];
51
52		// Added to support UTF-8 Characters
53		for (var i = 0, l = this.data.length; i < l; i++) {
54			var byteArray = [];
55			var code = this.data.charCodeAt(i);
56
57			if (code > 0x10000) {
58				byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18);
59				byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12);
60				byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6);
61				byteArray[3] = 0x80 | (code & 0x3F);
62			} else if (code > 0x800) {
63				byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12);
64				byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6);
65				byteArray[2] = 0x80 | (code & 0x3F);
66			} else if (code > 0x80) {
67				byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6);
68				byteArray[1] = 0x80 | (code & 0x3F);
69			} else {
70				byteArray[0] = code;
71			}
72
73			this.parsedData.push(byteArray);
74		}
75
76		this.parsedData = Array.prototype.concat.apply([], this.parsedData);
77
78		if (this.parsedData.length != this.data.length) {
79			this.parsedData.unshift(191);
80			this.parsedData.unshift(187);
81			this.parsedData.unshift(239);
82		}
83	}
84
85	QR8bitByte.prototype = {
86		getLength: function(buffer) {
87			return this.parsedData.length;
88		},
89		write: function(buffer) {
90			for (var i = 0, l = this.parsedData.length; i < l; i++) {
91				buffer.put(this.parsedData[i], 8);
92			}
93		}
94	};
95
96	function QRCodeModel(typeNumber, errorCorrectLevel) {
97		this.typeNumber = typeNumber;
98		this.errorCorrectLevel = errorCorrectLevel;
99		this.modules = null;
100		this.moduleCount = 0;
101		this.dataCache = null;
102		this.dataList = [];
103	}
104
105	QRCodeModel.prototype = {
106		addData: function(data) {
107			var newData = new QR8bitByte(data);
108			this.dataList.push(newData);
109			this.dataCache = null;
110		},
111		isDark: function(row, col) {
112			if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {
113				throw new Error(row + "," + col);
114			}
115			return this.modules[row][col][0];
116		},
117		getEye: function(row, col) {
118			if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {
119				throw new Error(row + "," + col);
120			}
121
122			var block = this.modules[row][col]; // [isDark(ture/false), EyeOuterOrInner(O/I), Position(TL/TR/BL/A) ]
123
124			if (block[1]) {
125				var type = 'P' + block[1] + '_' + block[2]; //PO_TL, PI_TL, PO_TR, PI_TR, PO_BL, PI_BL
126				if (block[2] == 'A') {
127					type = 'A' + block[1]; // AI, AO
128				}
129
130				return {
131					isDark: block[0],
132					type: type
133				};
134			} else {
135				return null;
136			}
137		},
138		getModuleCount: function() {
139			return this.moduleCount;
140		},
141		make: function() {
142			this.makeImpl(false, this.getBestMaskPattern());
143		},
144		makeImpl: function(test, maskPattern) {
145			this.moduleCount = this.typeNumber * 4 + 17;
146			this.modules = new Array(this.moduleCount);
147			for (var row = 0; row < this.moduleCount; row++) {
148				this.modules[row] = new Array(this.moduleCount);
149				for (var col = 0; col < this.moduleCount; col++) {
150					this.modules[row][col] = []; // [isDark(ture/false), EyeOuterOrInner(O/I), Position(TL/TR/BL) ]
151				}
152			}
153			this.setupPositionProbePattern(0, 0, 'TL'); // TopLeft, TL
154			this.setupPositionProbePattern(this.moduleCount - 7, 0, 'BL'); // BotoomLeft, BL
155			this.setupPositionProbePattern(0, this.moduleCount - 7, 'TR'); // TopRight, TR
156			this.setupPositionAdjustPattern('A'); // Alignment, A 
157			this.setupTimingPattern();
158			this.setupTypeInfo(test, maskPattern);
159			if (this.typeNumber >= 7) {
160				this.setupTypeNumber(test);
161			}
162			if (this.dataCache == null) {
163				this.dataCache = QRCodeModel.createData(this.typeNumber, this.errorCorrectLevel, this.dataList);
164			}
165			this.mapData(this.dataCache, maskPattern);
166		},
167		setupPositionProbePattern: function(row, col, posName) {
168			for (var r = -1; r <= 7; r++) {
169				if (row + r <= -1 || this.moduleCount <= row + r) continue;
170				for (var c = -1; c <= 7; c++) {
171					if (col + c <= -1 || this.moduleCount <= col + c) continue;
172					if ((0 <= r && r <= 6 && (c == 0 || c == 6)) || (0 <= c && c <= 6 && (r == 0 || r == 6)) || (2 <= r && r <= 4 &&
173							2 <= c && c <= 4)) {
174						this.modules[row + r][col + c][0] = true;
175
176						this.modules[row + r][col + c][2] = posName; // Position
177						if (r == -0 || c == -0 || r == 6 || c == 6) {
178							this.modules[row + r][col + c][1] = 'O'; // Position Outer
179						} else {
180							this.modules[row + r][col + c][1] = 'I'; // Position Inner
181						}
182					} else {
183						this.modules[row + r][col + c][0] = false;
184					}
185				}
186			}
187		},
188		getBestMaskPattern: function() {
189			var minLostPoint = 0;
190			var pattern = 0;
191			for (var i = 0; i < 8; i++) {
192				this.makeImpl(true, i);
193				var lostPoint = QRUtil.getLostPoint(this);
194				if (i == 0 || minLostPoint > lostPoint) {
195					minLostPoint = lostPoint;
196					pattern = i;
197				}
198			}
199			return pattern;
200		},
201		createMovieClip: function(target_mc, instance_name, depth) {
202			var qr_mc = target_mc.createEmptyMovieClip(instance_name, depth);
203			var cs = 1;
204			this.make();
205			for (var row = 0; row < this.modules.length; row++) {
206				var y = row * cs;
207				for (var col = 0; col < this.modules[row].length; col++) {
208					var x = col * cs;
209					var dark = this.modules[row][col][0];
210					if (dark) {
211						qr_mc.beginFill(0, 100);
212						qr_mc.moveTo(x, y);
213						qr_mc.lineTo(x + cs, y);
214						qr_mc.lineTo(x + cs, y + cs);
215						qr_mc.lineTo(x, y + cs);
216						qr_mc.endFill();
217					}
218				}
219			}
220			return qr_mc;
221		},
222		setupTimingPattern: function() {
223			for (var r = 8; r < this.moduleCount - 8; r++) {
224				if (this.modules[r][6][0] != null) {
225					continue;
226				}
227				this.modules[r][6][0] = (r % 2 == 0);
228			}
229			for (var c = 8; c < this.moduleCount - 8; c++) {
230				if (this.modules[6][c][0] != null) {
231					continue;
232				}
233				this.modules[6][c][0] = (c % 2 == 0);
234			}
235		},
236		setupPositionAdjustPattern: function(posName) {
237			var pos = QRUtil.getPatternPosition(this.typeNumber);
238			for (var i = 0; i < pos.length; i++) {
239				for (var j = 0; j < pos.length; j++) {
240					var row = pos[i];
241					var col = pos[j];
242					if (this.modules[row][col][0] != null) {
243						continue;
244					}
245					for (var r = -2; r <= 2; r++) {
246						for (var c = -2; c <= 2; c++) {
247							if (r == -2 || r == 2 || c == -2 || c == 2 || (r == 0 && c == 0)) {
248								this.modules[row + r][col + c][0] = true;
249								this.modules[row + r][col + c][2] = posName; // Position
250								if (r == -2 || c == -2 || r == 2 || c == 2) {
251									this.modules[row + r][col + c][1] = 'O'; // Position Outer
252								} else {
253									this.modules[row + r][col + c][1] = 'I'; // Position Inner
254								}
255							} else {
256								this.modules[row + r][col + c][0] = false;
257							}
258						}
259					}
260				}
261			}
262		},
263		setupTypeNumber: function(test) {
264			var bits = QRUtil.getBCHTypeNumber(this.typeNumber);
265			for (var i = 0; i < 18; i++) {
266				var mod = (!test && ((bits >> i) & 1) == 1);
267				this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3][0] = mod;
268			}
269			for (var i = 0; i < 18; i++) {
270				var mod = (!test && ((bits >> i) & 1) == 1);
271				this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)][0] = mod;
272			}
273		},
274		setupTypeInfo: function(test, maskPattern) {
275			var data = (this.errorCorrectLevel << 3) | maskPattern;
276			var bits = QRUtil.getBCHTypeInfo(data);
277			for (var i = 0; i < 15; i++) {
278				var mod = (!test && ((bits >> i) & 1) == 1);
279				if (i < 6) {
280					this.modules[i][8][0] = mod;
281				} else if (i < 8) {
282					this.modules[i + 1][8][0] = mod;
283				} else {
284					this.modules[this.moduleCount - 15 + i][8][0] = mod;
285				}
286			}
287			for (var i = 0; i < 15; i++) {
288				var mod = (!test && ((bits >> i) & 1) == 1);
289				if (i < 8) {
290					this.modules[8][this.moduleCount - i - 1][0] = mod;
291				} else if (i < 9) {
292					this.modules[8][15 - i - 1 + 1][0] = mod;
293				} else {
294					this.modules[8][15 - i - 1][0] = mod;
295				}
296			}
297			this.modules[this.moduleCount - 8][8][0] = (!test);
298		},
299		mapData: function(data, maskPattern) {
300			var inc = -1;
301			var row = this.moduleCount - 1;
302			var bitIndex = 7;
303			var byteIndex = 0;
304			for (var col = this.moduleCount - 1; col > 0; col -= 2) {
305				if (col == 6) col--;
306				while (true) {
307					for (var c = 0; c < 2; c++) {
308						if (this.modules[row][col - c][0] == null) {
309							var dark = false;
310							if (byteIndex < data.length) {
311								dark = (((data[byteIndex] >>> bitIndex) & 1) == 1);
312							}
vendor: 18,502 bytes, lines 313-973
313							var mask = QRUtil.getMask(maskPattern, row, col - c);
314							if (mask) {
315								dark = !dark;
316							}
317							this.modules[row][col - c][0] = dark;
318							bitIndex--;
319							if (bitIndex == -1) {
320								byteIndex++;
321								bitIndex = 7;
322							}
323						}
324					}
325					row += inc;
326					if (row < 0 || this.moduleCount <= row) {
327						row -= inc;
328						inc = -inc;
329						break;
330					}
331				}
332			}
333		}
334	};
335	QRCodeModel.PAD0 = 0xEC;
336	QRCodeModel.PAD1 = 0x11;
337	QRCodeModel.createData = function(typeNumber, errorCorrectLevel, dataList) {
338		var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
339		var buffer = new QRBitBuffer();
340		for (var i = 0; i < dataList.length; i++) {
341			var data = dataList[i];
342			buffer.put(data.mode, 4);
343			buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber));
344			data.write(buffer);
345		}
346		var totalDataCount = 0;
347		for (var i = 0; i < rsBlocks.length; i++) {
348			totalDataCount += rsBlocks[i].dataCount;
349		}
350		if (buffer.getLengthInBits() > totalDataCount * 8) {
351			throw new Error("code length overflow. (" +
352				buffer.getLengthInBits() +
353				">" +
354				totalDataCount * 8 +
355				")");
356		}
357		if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
358			buffer.put(0, 4);
359		}
360		while (buffer.getLengthInBits() % 8 != 0) {
361			buffer.putBit(false);
362		}
363		while (true) {
364			if (buffer.getLengthInBits() >= totalDataCount * 8) {
365				break;
366			}
367			buffer.put(QRCodeModel.PAD0, 8);
368			if (buffer.getLengthInBits() >= totalDataCount * 8) {
369				break;
370			}
371			buffer.put(QRCodeModel.PAD1, 8);
372		}
373		return QRCodeModel.createBytes(buffer, rsBlocks);
374	};
375	QRCodeModel.createBytes = function(buffer, rsBlocks) {
376		var offset = 0;
377		var maxDcCount = 0;
378		var maxEcCount = 0;
379		var dcdata = new Array(rsBlocks.length);
380		var ecdata = new Array(rsBlocks.length);
381		for (var r = 0; r < rsBlocks.length; r++) {
382			var dcCount = rsBlocks[r].dataCount;
383			var ecCount = rsBlocks[r].totalCount - dcCount;
384			maxDcCount = Math.max(maxDcCount, dcCount);
385			maxEcCount = Math.max(maxEcCount, ecCount);
386			dcdata[r] = new Array(dcCount);
387			for (var i = 0; i < dcdata[r].length; i++) {
388				dcdata[r][i] = 0xff & buffer.buffer[i + offset];
389			}
390			offset += dcCount;
391			var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
392			var rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1);
393			var modPoly = rawPoly.mod(rsPoly);
394			ecdata[r] = new Array(rsPoly.getLength() - 1);
395			for (var i = 0; i < ecdata[r].length; i++) {
396				var modIndex = i + modPoly.getLength() - ecdata[r].length;
397				ecdata[r][i] = (modIndex >= 0) ? modPoly.get(modIndex) : 0;
398			}
399		}
400		var totalCodeCount = 0;
401		for (var i = 0; i < rsBlocks.length; i++) {
402			totalCodeCount += rsBlocks[i].totalCount;
403		}
404		var data = new Array(totalCodeCount);
405		var index = 0;
406		for (var i = 0; i < maxDcCount; i++) {
407			for (var r = 0; r < rsBlocks.length; r++) {
408				if (i < dcdata[r].length) {
409					data[index++] = dcdata[r][i];
410				}
411			}
412		}
413		for (var i = 0; i < maxEcCount; i++) {
414			for (var r = 0; r < rsBlocks.length; r++) {
415				if (i < ecdata[r].length) {
416					data[index++] = ecdata[r][i];
417				}
418			}
419		}
420		return data;
421	};
422	var QRMode = {
423		MODE_NUMBER: 1 << 0,
424		MODE_ALPHA_NUM: 1 << 1,
425		MODE_8BIT_BYTE: 1 << 2,
426		MODE_KANJI: 1 << 3
427	};
428	var QRErrorCorrectLevel = {
429		L: 1,
430		M: 0,
431		Q: 3,
432		H: 2
433	};
434	var QRMaskPattern = {
435		PATTERN000: 0,
436		PATTERN001: 1,
437		PATTERN010: 2,
438		PATTERN011: 3,
439		PATTERN100: 4,
440		PATTERN101: 5,
441		PATTERN110: 6,
442		PATTERN111: 7
443	};
444	var QRUtil = {
445		PATTERN_POSITION_TABLE: [
446			[],
447			[6, 18],
448			[6, 22],
449			[6, 26],
450			[6, 30],
451			[6, 34],
452			[6, 22, 38],
453			[6, 24, 42],
454			[6, 26, 46],
455			[6, 28, 50],
456			[6, 30, 54],
457			[6, 32, 58],
458			[6, 34, 62],
459			[6, 26, 46, 66],
460			[6, 26, 48, 70],
461			[6, 26, 50, 74],
462			[6, 30, 54, 78],
463			[6, 30, 56, 82],
464			[6, 30, 58, 86],
465			[6, 34, 62, 90],
466			[6, 28, 50, 72, 94],
467			[6, 26, 50, 74, 98],
468			[6, 30, 54, 78, 102],
469			[6, 28, 54, 80, 106],
470			[6, 32, 58, 84, 110],
471			[6, 30, 58, 86, 114],
472			[6, 34, 62, 90, 118],
473			[6, 26, 50, 74, 98, 122],
474			[6, 30, 54, 78, 102, 126],
475			[6, 26, 52, 78, 104, 130],
476			[6, 30, 56, 82, 108, 134],
477			[6, 34, 60, 86, 112, 138],
478			[6, 30, 58, 86, 114, 142],
479			[6, 34, 62, 90, 118, 146],
480			[6, 30, 54, 78, 102, 126, 150],
481			[6, 24, 50, 76, 102, 128, 154],
482			[6, 28, 54, 80, 106, 132, 158],
483			[6, 32, 58, 84, 110, 136, 162],
484			[6, 26, 54, 82, 110, 138, 166],
485			[6, 30, 58, 86, 114, 142, 170]
486		],
487		G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
488		G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
489		G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
490		getBCHTypeInfo: function(data) {
491			var d = data << 10;
492			while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
493				d ^= (QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15)));
494			}
495			return ((data << 10) | d) ^ QRUtil.G15_MASK;
496		},
497		getBCHTypeNumber: function(data) {
498			var d = data << 12;
499			while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
500				d ^= (QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18)));
501			}
502			return (data << 12) | d;
503		},
504		getBCHDigit: function(data) {
505			var digit = 0;
506			while (data != 0) {
507				digit++;
508				data >>>= 1;
509			}
510			return digit;
511		},
512		getPatternPosition: function(typeNumber) {
513			return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
514		},
515		getMask: function(maskPattern, i, j) {
516			switch (maskPattern) {
517				case QRMaskPattern.PATTERN000:
518					return (i + j) % 2 == 0;
519				case QRMaskPattern.PATTERN001:
520					return i % 2 == 0;
521				case QRMaskPattern.PATTERN010:
522					return j % 3 == 0;
523				case QRMaskPattern.PATTERN011:
524					return (i + j) % 3 == 0;
525				case QRMaskPattern.PATTERN100:
526					return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0;
527				case QRMaskPattern.PATTERN101:
528					return (i * j) % 2 + (i * j) % 3 == 0;
529				case QRMaskPattern.PATTERN110:
530					return ((i * j) % 2 + (i * j) % 3) % 2 == 0;
531				case QRMaskPattern.PATTERN111:
532					return ((i * j) % 3 + (i + j) % 2) % 2 == 0;
533				default:
534					throw new Error("bad maskPattern:" + maskPattern);
535			}
536		},
537		getErrorCorrectPolynomial: function(errorCorrectLength) {
538			var a = new QRPolynomial([1], 0);
539			for (var i = 0; i < errorCorrectLength; i++) {
540				a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0));
541			}
542			return a;
543		},
544		getLengthInBits: function(mode, type) {
545			if (1 <= type && type < 10) {
546				switch (mode) {
547					case QRMode.MODE_NUMBER:
548						return 10;
549					case QRMode.MODE_ALPHA_NUM:
550						return 9;
551					case QRMode.MODE_8BIT_BYTE:
552						return 8;
553					case QRMode.MODE_KANJI:
554						return 8;
555					default:
556						throw new Error("mode:" + mode);
557				}
558			} else if (type < 27) {
559				switch (mode) {
560					case QRMode.MODE_NUMBER:
561						return 12;
562					case QRMode.MODE_ALPHA_NUM:
563						return 11;
564					case QRMode.MODE_8BIT_BYTE:
565						return 16;
566					case QRMode.MODE_KANJI:
567						return 10;
568					default:
569						throw new Error("mode:" + mode);
570				}
571			} else if (type < 41) {
572				switch (mode) {
573					case QRMode.MODE_NUMBER:
574						return 14;
575					case QRMode.MODE_ALPHA_NUM:
576						return 13;
577					case QRMode.MODE_8BIT_BYTE:
578						return 16;
579					case QRMode.MODE_KANJI:
580						return 12;
581					default:
582						throw new Error("mode:" + mode);
583				}
584			} else {
585				throw new Error("type:" + type);
586			}
587		},
588		getLostPoint: function(qrCode) {
589			var moduleCount = qrCode.getModuleCount();
590			var lostPoint = 0;
591			for (var row = 0; row < moduleCount; row++) {
592				for (var col = 0; col < moduleCount; col++) {
593					var sameCount = 0;
594					var dark = qrCode.isDark(row, col);
595					for (var r = -1; r <= 1; r++) {
596						if (row + r < 0 || moduleCount <= row + r) {
597							continue;
598						}
599						for (var c = -1; c <= 1; c++) {
600							if (col + c < 0 || moduleCount <= col + c) {
601								continue;
602							}
603							if (r == 0 && c == 0) {
604								continue;
605							}
606							if (dark == qrCode.isDark(row + r, col + c)) {
607								sameCount++;
608							}
609						}
610					}
611					if (sameCount > 5) {
612						lostPoint += (3 + sameCount - 5);
613					}
614				}
615			}
616			for (var row = 0; row < moduleCount - 1; row++) {
617				for (var col = 0; col < moduleCount - 1; col++) {
618					var count = 0;
619					if (qrCode.isDark(row, col)) count++;
620					if (qrCode.isDark(row + 1, col)) count++;
621					if (qrCode.isDark(row, col + 1)) count++;
622					if (qrCode.isDark(row + 1, col + 1)) count++;
623					if (count == 0 || count == 4) {
624						lostPoint += 3;
625					}
626				}
627			}
628			for (var row = 0; row < moduleCount; row++) {
629				for (var col = 0; col < moduleCount - 6; col++) {
630					if (qrCode.isDark(row, col) && !qrCode.isDark(row, col + 1) && qrCode.isDark(row, col + 2) && qrCode.isDark(
631							row,
632							col + 3) && qrCode.isDark(row, col + 4) && !qrCode.isDark(row, col + 5) && qrCode.isDark(row, col + 6)) {
633						lostPoint += 40;
634					}
635				}
636			}
637			for (var col = 0; col < moduleCount; col++) {
638				for (var row = 0; row < moduleCount - 6; row++) {
639					if (qrCode.isDark(row, col) && !qrCode.isDark(row + 1, col) && qrCode.isDark(row + 2, col) && qrCode.isDark(
640							row +
641							3, col) && qrCode.isDark(row + 4, col) && !qrCode.isDark(row + 5, col) && qrCode.isDark(row + 6, col)) {
642						lostPoint += 40;
643					}
644				}
645			}
646			var darkCount = 0;
647			for (var col = 0; col < moduleCount; col++) {
648				for (var row = 0; row < moduleCount; row++) {
649					if (qrCode.isDark(row, col)) {
650						darkCount++;
651					}
652				}
653			}
654			var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
655			lostPoint += ratio * 10;
656			return lostPoint;
657		}
658	};
659	var QRMath = {
660		glog: function(n) {
661			if (n < 1) {
662				throw new Error("glog(" + n + ")");
663			}
664			return QRMath.LOG_TABLE[n];
665		},
666		gexp: function(n) {
667			while (n < 0) {
668				n += 255;
669			}
670			while (n >= 256) {
671				n -= 255;
672			}
673			return QRMath.EXP_TABLE[n];
674		},
675		EXP_TABLE: new Array(256),
676		LOG_TABLE: new Array(256)
677	};
678	for (var i = 0; i < 8; i++) {
679		QRMath.EXP_TABLE[i] = 1 << i;
680	}
681	for (var i = 8; i < 256; i++) {
682		QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^ QRMath.EXP_TABLE[i - 5] ^ QRMath.EXP_TABLE[i - 6] ^ QRMath.EXP_TABLE[
683			i - 8];
684	}
685	for (var i = 0; i < 255; i++) {
686		QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i;
687	}
688
689	function QRPolynomial(num, shift) {
690		if (num.length == undefined) {
691			throw new Error(num.length + "/" + shift);
692		}
693		var offset = 0;
694		while (offset < num.length && num[offset] == 0) {
695			offset++;
696		}
697		this.num = new Array(num.length - offset + shift);
698		for (var i = 0; i < num.length - offset; i++) {
699			this.num[i] = num[i + offset];
700		}
701	}
702	QRPolynomial.prototype = {
703		get: function(index) {
704			return this.num[index];
705		},
706		getLength: function() {
707			return this.num.length;
708		},
709		multiply: function(e) {
710			var num = new Array(this.getLength() + e.getLength() - 1);
711			for (var i = 0; i < this.getLength(); i++) {
712				for (var j = 0; j < e.getLength(); j++) {
713					num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)));
714				}
715			}
716			return new QRPolynomial(num, 0);
717		},
718		mod: function(e) {
719			if (this.getLength() - e.getLength() < 0) {
720				return this;
721			}
722			var ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0));
723			var num = new Array(this.getLength());
724			for (var i = 0; i < this.getLength(); i++) {
725				num[i] = this.get(i);
726			}
727			for (var i = 0; i < e.getLength(); i++) {
728				num[i] ^= QRMath.gexp(QRMath.glog(e.get(i)) + ratio);
729			}
730			return new QRPolynomial(num, 0).mod(e);
731		}
732	};
733
734	function QRRSBlock(totalCount, dataCount) {
735		this.totalCount = totalCount;
736		this.dataCount = dataCount;
737	}
738	QRRSBlock.RS_BLOCK_TABLE = [
739		[1, 26, 19],
740		[1, 26, 16],
741		[1, 26, 13],
742		[1, 26, 9],
743		[1, 44, 34],
744		[1, 44, 28],
745		[1, 44, 22],
746		[1, 44, 16],
747		[1, 70, 55],
748		[1, 70, 44],
749		[2, 35, 17],
750		[2, 35, 13],
751		[1, 100, 80],
752		[2, 50, 32],
753		[2, 50, 24],
754		[4, 25, 9],
755		[1, 134, 108],
756		[2, 67, 43],
757		[2, 33, 15, 2, 34, 16],
758		[2, 33, 11, 2, 34, 12],
759		[2, 86, 68],
760		[4, 43, 27],
761		[4, 43, 19],
762		[4, 43, 15],
763		[2, 98, 78],
764		[4, 49, 31],
765		[2, 32, 14, 4, 33, 15],
766		[4, 39, 13, 1, 40, 14],
767		[2, 121, 97],
768		[2, 60, 38, 2, 61, 39],
769		[4, 40, 18, 2, 41, 19],
770		[4, 40, 14, 2, 41, 15],
771		[2, 146, 116],
772		[3, 58, 36, 2, 59, 37],
773		[4, 36, 16, 4, 37, 17],
774		[4, 36, 12, 4, 37, 13],
775		[2, 86, 68, 2, 87, 69],
776		[4, 69, 43, 1, 70, 44],
777		[6, 43, 19, 2, 44, 20],
778		[6, 43, 15, 2, 44, 16],
779		[4, 101, 81],
780		[1, 80, 50, 4, 81, 51],
781		[4, 50, 22, 4, 51, 23],
782		[3, 36, 12, 8, 37, 13],
783		[2, 116, 92, 2, 117, 93],
784		[6, 58, 36, 2, 59, 37],
785		[4, 46, 20, 6, 47, 21],
786		[7, 42, 14, 4, 43, 15],
787		[4, 133, 107],
788		[8, 59, 37, 1, 60, 38],
789		[8, 44, 20, 4, 45, 21],
790		[12, 33, 11, 4, 34, 12],
791		[3, 145, 115, 1, 146, 116],
792		[4, 64, 40, 5, 65, 41],
793		[11, 36, 16, 5, 37, 17],
794		[11, 36, 12, 5, 37, 13],
795		[5, 109, 87, 1, 110, 88],
796		[5, 65, 41, 5, 66, 42],
797		[5, 54, 24, 7, 55, 25],
798		[11, 36, 12],
799		[5, 122, 98, 1, 123, 99],
800		[7, 73, 45, 3, 74, 46],
801		[15, 43, 19, 2, 44, 20],
802		[3, 45, 15, 13, 46, 16],
803		[1, 135, 107, 5, 136, 108],
804		[10, 74, 46, 1, 75, 47],
805		[1, 50, 22, 15, 51, 23],
806		[2, 42, 14, 17, 43, 15],
807		[5, 150, 120, 1, 151, 121],
808		[9, 69, 43, 4, 70, 44],
809		[17, 50, 22, 1, 51, 23],
810		[2, 42, 14, 19, 43, 15],
811		[3, 141, 113, 4, 142, 114],
812		[3, 70, 44, 11, 71, 45],
813		[17, 47, 21, 4, 48, 22],
814		[9, 39, 13, 16, 40, 14],
815		[3, 135, 107, 5, 136, 108],
816		[3, 67, 41, 13, 68, 42],
817		[15, 54, 24, 5, 55, 25],
818		[15, 43, 15, 10, 44, 16],
819		[4, 144, 116, 4, 145, 117],
820		[17, 68, 42],
821		[17, 50, 22, 6, 51, 23],
822		[19, 46, 16, 6, 47, 17],
823		[2, 139, 111, 7, 140, 112],
824		[17, 74, 46],
825		[7, 54, 24, 16, 55, 25],
826		[34, 37, 13],
827		[4, 151, 121, 5, 152, 122],
828		[4, 75, 47, 14, 76, 48],
829		[11, 54, 24, 14, 55, 25],
830		[16, 45, 15, 14, 46, 16],
831		[6, 147, 117, 4, 148, 118],
832		[6, 73, 45, 14, 74, 46],
833		[11, 54, 24, 16, 55, 25],
834		[30, 46, 16, 2, 47, 17],
835		[8, 132, 106, 4, 133, 107],
836		[8, 75, 47, 13, 76, 48],
837		[7, 54, 24, 22, 55, 25],
838		[22, 45, 15, 13, 46, 16],
839		[10, 142, 114, 2, 143, 115],
840		[19, 74, 46, 4, 75, 47],
841		[28, 50, 22, 6, 51, 23],
842		[33, 46, 16, 4, 47, 17],
843		[8, 152, 122, 4, 153, 123],
844		[22, 73, 45, 3, 74, 46],
845		[8, 53, 23, 26, 54, 24],
846		[12, 45, 15, 28, 46, 16],
847		[3, 147, 117, 10, 148, 118],
848		[3, 73, 45, 23, 74, 46],
849		[4, 54, 24, 31, 55, 25],
850		[11, 45, 15, 31, 46, 16],
851		[7, 146, 116, 7, 147, 117],
852		[21, 73, 45, 7, 74, 46],
853		[1, 53, 23, 37, 54, 24],
854		[19, 45, 15, 26, 46, 16],
855		[5, 145, 115, 10, 146, 116],
856		[19, 75, 47, 10, 76, 48],
857		[15, 54, 24, 25, 55, 25],
858		[23, 45, 15, 25, 46, 16],
859		[13, 145, 115, 3, 146, 116],
860		[2, 74, 46, 29, 75, 47],
861		[42, 54, 24, 1, 55, 25],
862		[23, 45, 15, 28, 46, 16],
863		[17, 145, 115],
864		[10, 74, 46, 23, 75, 47],
865		[10, 54, 24, 35, 55, 25],
866		[19, 45, 15, 35, 46, 16],
867		[17, 145, 115, 1, 146, 116],
868		[14, 74, 46, 21, 75, 47],
869		[29, 54, 24, 19, 55, 25],
870		[11, 45, 15, 46, 46, 16],
871		[13, 145, 115, 6, 146, 116],
872		[14, 74, 46, 23, 75, 47],
873		[44, 54, 24, 7, 55, 25],
874		[59, 46, 16, 1, 47, 17],
875		[12, 151, 121, 7, 152, 122],
876		[12, 75, 47, 26, 76, 48],
877		[39, 54, 24, 14, 55, 25],
878		[22, 45, 15, 41, 46, 16],
879		[6, 151, 121, 14, 152, 122],
880		[6, 75, 47, 34, 76, 48],
881		[46, 54, 24, 10, 55, 25],
882		[2, 45, 15, 64, 46, 16],
883		[17, 152, 122, 4, 153, 123],
884		[29, 74, 46, 14, 75, 47],
885		[49, 54, 24, 10, 55, 25],
886		[24, 45, 15, 46, 46, 16],
887		[4, 152, 122, 18, 153, 123],
888		[13, 74, 46, 32, 75, 47],
889		[48, 54, 24, 14, 55, 25],
890		[42, 45, 15, 32, 46, 16],
891		[20, 147, 117, 4, 148, 118],
892		[40, 75, 47, 7, 76, 48],
893		[43, 54, 24, 22, 55, 25],
894		[10, 45, 15, 67, 46, 16],
895		[19, 148, 118, 6, 149, 119],
896		[18, 75, 47, 31, 76, 48],
897		[34, 54, 24, 34, 55, 25],
898		[20, 45, 15, 61, 46, 16]
899	];
900	QRRSBlock.getRSBlocks = function(typeNumber, errorCorrectLevel) {
901		var rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
902		if (rsBlock == undefined) {
903			throw new Error("bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel);
904		}
905		var length = rsBlock.length / 3;
906		var list = [];
907		for (var i = 0; i < length; i++) {
908			var count = rsBlock[i * 3 + 0];
909			var totalCount = rsBlock[i * 3 + 1];
910			var dataCount = rsBlock[i * 3 + 2];
911			for (var j = 0; j < count; j++) {
912				list.push(new QRRSBlock(totalCount, dataCount));
913			}
914		}
915		return list;
916	};
917	QRRSBlock.getRsBlockTable = function(typeNumber, errorCorrectLevel) {
918		switch (errorCorrectLevel) {
919			case QRErrorCorrectLevel.L:
920				return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
921			case QRErrorCorrectLevel.M:
922				return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
923			case QRErrorCorrectLevel.Q:
924				return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
925			case QRErrorCorrectLevel.H:
926				return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
927			default:
928				return undefined;
929		}
930	};
931
932	function QRBitBuffer() {
933		this.buffer = [];
934		this.length = 0;
935	}
936	QRBitBuffer.prototype = {
937		get: function(index) {
938			var bufIndex = Math.floor(index / 8);
939			return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1) == 1;
940		},
941		put: function(num, length) {
942			for (var i = 0; i < length; i++) {
943				this.putBit(((num >>> (length - i - 1)) & 1) == 1);
944			}
945		},
946		getLengthInBits: function() {
947			return this.length;
948		},
949		putBit: function(bit) {
950			var bufIndex = Math.floor(this.length / 8);
951			if (this.buffer.length <= bufIndex) {
952				this.buffer.push(0);
953			}
954			if (bit) {
955				this.buffer[bufIndex] |= (0x80 >>> (this.length % 8));
956			}
957			this.length++;
958		}
959	};
960	var QRCodeLimitLength = [
961		[17, 14, 11, 7],
962		[32, 26, 20, 14],
963		[53, 42, 32, 24],
964		[78, 62, 46, 34],
965		[106, 84, 60, 44],
966		[134, 106, 74, 58],
967		[154, 122, 86, 64],
968		[192, 152, 108, 84],
969		[230, 180, 130, 98],
970		[271, 213, 151, 119],
971		[321, 251, 177, 137],
972		[367, 287, 203, 155],
973		[425, 331, 241, 177],
974		[458, 362, 258, 194],
975		[520, 412, 292, 220],
976		[586, 450, 322, 250],
977		[644, 504, 364, 280],
978		[718, 560, 394, 310],
979		[792, 624, 442, 338],
980		[858, 666, 482, 382],
981		[929, 711, 509, 403],
982		[1003, 779, 565, 439],
983		[1091, 857, 611, 461],
984		[1171, 911, 661, 511],
985		[1273, 997, 715, 535],
986		[1367, 1059, 751, 593],
987		[1465, 1125, 805, 625],
988		[1528, 1190, 868, 658],
989		[1628, 1264, 908, 698],
990		[1732, 1370, 982, 742],
991		[1840, 1452, 1030, 790],
992		[1952, 1538, 1112, 842],
993		[2068, 1628, 1168, 898],
994		[2188, 1722, 1228, 958],
995		[2303, 1809, 1283, 983],
996		[2431, 1911, 1351, 1051],
997		[2563, 1989, 1423, 1093],
998		[2699, 2099, 1499, 1139],
999		[2809, 2213, 1579, 1219],
1000		[2953, 2331, 1663, 1273]
1001	];
1002
1003	function _isSupportCanvas() {
1004		return typeof CanvasRenderingContext2D != "undefined";
1005	}
1006
1007	// android 2.x doesn't support Data-URI spec
1008	function _getAndroid() {
1009		var android = false;
1010		var sAgent = navigator.userAgent;
1011
1012		if (/android/i.test(sAgent)) { // android
1013			android = true;
1014			var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i);
1015
1016			if (aMat && aMat[1]) {
1017				android = parseFloat(aMat[1]);
1018			}
1019		}
1020
1021		return android;
1022	}
1023
1024	var svgDrawer = (function() {
1025
1026		var Drawing = function(el, htOption) {
1027			this._el = el;
1028			this._htOption = htOption;
1029		};
1030
1031		Drawing.prototype.draw = function(oQRCode) {
1032			var _htOption = this._htOption;
1033			var _el = this._el;
1034			var nCount = oQRCode.getModuleCount();
1035			var nWidth = Math.floor(_htOption.width / nCount);
1036			var nHeight = Math.floor(_htOption.height / nCount);
1037
1038			this.clear();
1039
1040			function makeSVG(tag, attrs) {
1041				var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
1042				for (var k in attrs)
1043					if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]);
1044				return el;
1045			}
1046
1047			var svg = makeSVG("svg", {
1048				'viewBox': '0 0 ' + String(nCount) + " " + String(nCount),
1049				'width': '100%',
1050				'height': '100%',
1051				'fill': _htOption.colorLight
1052			});
1053			svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
1054			_el.appendChild(svg);
1055
1056			svg.appendChild(makeSVG("rect", {
1057				"fill": _htOption.colorLight,
1058				"width": "100%",
1059				"height": "100%"
1060			}));
1061			svg.appendChild(makeSVG("rect", {
1062				"fill": _htOption.colorDark,
1063				"width": "1",
1064				"height": "1",
1065				"id": "template"
1066			}));
1067
1068			for (var row = 0; row < nCount; row++) {
1069				for (var col = 0; col < nCount; col++) {
1070					if (oQRCode.isDark(row, col)) {
1071						var child = makeSVG("use", {
1072							"x": String(col),
1073							"y": String(row)
1074						});
1075						child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template")
1076						svg.appendChild(child);
1077					}
1078				}
1079			}
1080		};
1081		Drawing.prototype.clear = function() {
1082			while (this._el.hasChildNodes())
1083				this._el.removeChild(this._el.lastChild);
1084		};
1085		return Drawing;
1086	})();
1087
1088	var useSVG = document.documentElement.tagName.toLowerCase() === "svg";
1089
1090	// Drawing in DOM by using Table tag
1091	var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function() {
1092		var Drawing = function(el, htOption) {
1093			this._el = el;
1094			this._htOption = htOption;
1095		};
1096
1097		/**
1098		 * Draw the QRCode
1099		 * 
1100		 * @param {QRCode} oQRCode
1101		 */
1102		Drawing.prototype.draw = function(oQRCode) {
1103			var _htOption = this._htOption;
1104			var _el = this._el;
1105			var nCount = oQRCode.getModuleCount();
1106			var nWidth = Math.round(_htOption.width / nCount);
1107			var nHeight = Math.round((_htOption.height - _htOption.titleHeight) / nCount);
1108
1109			this._htOption.width = nWidth * nCount;
1110			this._htOption.height = nHeight * nCount + _htOption.titleHeight;
1111
1112			this._htOption.quietZone = Math.round(this._htOption.quietZone);
1113
1114
1115			var aHTML = [];
1116
1117			var divStyle = '';
1118
1119			var drawWidth = Math.round(nWidth * _htOption.dotScale);
1120			var drawHeight = Math.round(nHeight * _htOption.dotScale);
1121			if (drawWidth < 4) {
1122				drawWidth = 4;
1123				drawHeight = 4;
1124			}
1125
1126			var nonRequiredColorDark = _htOption.colorDark;
1127			var nonRequiredcolorLight = _htOption.colorLight;
1128			if (_htOption.backgroundImage) {
1129				if (_htOption.autoColor) {
1130					_htOption.colorDark =
1131						"rgba(0, 0, 0, .6);filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr='#99000000', EndColorStr='#99000000');";
1132					_htOption.colorLight =
1133						"rgba(255, 255, 255, .7);filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr='#B2FFFFFF', EndColorStr='#B2FFFFFF');";
1134
1135					// _htOption.colorDark="rgba(0, 0, 0, .6)";
1136					// _htOption.colorLight='rgba(255, 255, 255, .7)';
1137				} else {
1138					_htOption.colorLight = 'transparent';
1139				}
1140
1141
1142				var backgroundImageEle = '<div style="display:inline-block; z-index:-10;position:absolute;"><img src="' +
1143					_htOption.backgroundImage + '" widht="' + (_htOption.width + _htOption.quietZone * 2) + '" height="' + (
1144						_htOption.height + _htOption.quietZone * 2) + '" style="opacity:' + _htOption.backgroundImageAlpha +
1145					';filter:alpha(opacity=' + (_htOption.backgroundImageAlpha * 100) + '); "/></div>';
1146				aHTML.push(backgroundImageEle);
1147			}
1148
1149			if (_htOption.quietZone) {
1150				divStyle = 'padding:' + _htOption.quietZone + 'px; display:inline-block; width:' + (_htOption.width +
1151					_htOption.quietZone * 2) + 'px; height:' + (_htOption.width +
1152					_htOption.quietZone * 2) + 'px;background:'+_htOption.quietZoneColor+'; text-align:center;';
1153			}
1154			aHTML.push('<div style="font-size:0;' + divStyle + '">');
1155
1156			aHTML.push(
1157				'<table  style="font-size:0;border:0;border-collapse:collapse; margin-top:0;" border="0" cellspacing="0" cellspadding="0" align="center" valign="middle">'
1158			);
1159			aHTML.push('<tr height="' + _htOption.titleHeight +
1160				'" align="center"><td style="border:0;border-collapse:collapse;margin:0;padding:0" colspan="' + nCount +
1161				'">')
1162			if (_htOption.title) {
1163				var c = _htOption.titleColor;
1164				var f = _htOption.titleFont;
1165				aHTML.push('<div style="width:100%;margin-top:' + _htOption.titleTop + 'px;color:' + c + ';font:' + f +
1166					';background:' + _htOption.titleBackgroundColor + '">' +
1167					_htOption.title + '</div>');
1168			}
1169			if (_htOption.subTitle) {
1170				aHTML.push('<div style="width:100%;margin-top:' + (_htOption.subTitleTop - _htOption.titleTop) + 'px;color:' +
1171					_htOption.subTitleColor + '; font:' + _htOption.subTitleFont +
1172					'">' + _htOption.subTitle + '</div>');
1173			}
1174			aHTML.push('</td></tr>')
1175			for (var row = 0; row < nCount; row++) {
1176				aHTML.push('<tr style="border:0; padding:0; margin:0;" height="7">');
1177
1178				for (var col = 0; col < nCount; col++) {
1179
1180					var bIsDark = oQRCode.isDark(row, col);
1181
1182					var eye = oQRCode.getEye(row, col); // { isDark: true/false, type: PO_TL, PI_TL, PO_TR, PI_TR, PO_BL, PI_BL };
1183
1184					if (eye) {
1185						// Is eye
1186						bIsDark = eye.isDark;
1187						var type = eye.type;
1188
1189						// PX_XX, PX, colorDark, colorLight
1190						var eyeColorDark = _htOption[type] || _htOption[type.substring(0, 2)] || nonRequiredColorDark;
1191						aHTML.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:' + nWidth + 'px;height:' +
1192							nHeight + 'px;">' +
1193							'<span style="width:' + nWidth + 'px;height:' + nHeight + 'px;background-color:' + (bIsDark ?
1194								eyeColorDark : nonRequiredcolorLight) + ';display:inline-block"></span></td>');
1195
1196					} else {
1197
1198						// Timing Pattern 
1199						var nowDarkColor = _htOption.colorDark;
1200						if (row == 6) {
1201							nowDarkColor = _htOption.timing_H || _htOption.timing || nonRequiredColorDark;
1202							aHTML.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:' + nWidth +
1203								'px;height:' +
1204								nHeight + 'px;background-color:' + (bIsDark ? nowDarkColor : nonRequiredcolorLight) +
1205								';"></td>');
1206						} else if (col == 6) {
1207							nowDarkColor = _htOption.timing_V || _htOption.timing || nonRequiredColorDark;
1208
1209							aHTML.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:' + nWidth +
1210								'px;height:' +
1211								nHeight + 'px;background-color:' + (bIsDark ? nowDarkColor : nonRequiredcolorLight) +
1212								';"></td>');
1213
1214						} else {
1215							aHTML.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:' + nWidth +
1216								'px;height:' +
1217								nHeight + 'px;">' +
1218								'<div style="display:inline-block;width:' + drawWidth + 'px;height:' + drawHeight +
1219								'px;background-color:' + (bIsDark ? nowDarkColor : _htOption.colorLight) +
1220								';"></div></td>');
1221						}
1222
1223
1224
1225
1226					}
1227
1228
1229				}
1230
1231				aHTML.push('</tr>');
1232			}
1233
1234
1235			aHTML.push('</table>');
1236			aHTML.push('</div>');
1237
1238			if (_htOption.logo) {
1239				var img = new Image();
1240				//img.crossOrigin="Anonymous";
1241				img.src = _htOption.logo;
1242
1243				var imgW = _htOption.width / 3.5;
1244				var imgH = _htOption.height / 3.5;
1245				if (imgW != imgH) {
1246					imgW = imgH;
1247				}
1248
1249				if (_htOption.logoWidth) {
1250					imgW = _htOption.logoWidth;
1251				}
1252				if (_htOption.logoHeight) {
1253					imgH = _htOption.logoHeight;
1254				}
1255
1256				var imgDivStyle = 'position:relative; z-index:1;display:inline-block;top:-' + ((_htOption.height - _htOption.titleHeight) /
1257					2 + imgH / 2 + _htOption.quietZone) + 'px;text-align:center; width:' + imgW + 'px; height:' + imgH + 'px;';
1258				if (!_htOption.logoBackgroundTransparent) {
1259					imgDivStyle += 'background:' + _htOption.logoBackgroundColor;
1260				}
1261				aHTML.push('<div style="' + imgDivStyle + '"><img  src="' + _htOption.logo + '" width="' + imgW +
1262					'" height="' +
1263					imgH + '"  style="" /></div>')
1264			}
1265
1266
1267
1268			if (_htOption.onRenderingStart) {
1269				_htOption.onRenderingStart(_htOption)
1270			}
1271
1272			_el.innerHTML = aHTML.join('');
1273			// Fix the margin values as real size.
1274			var elTable = _el.childNodes[0];
1275			var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2;
1276			var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2;
1277			if (nLeftMarginTable > 0 && nTopMarginTable > 0) {
1278				elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px";
1279			}
1280		};
1281
1282		/**
1283		 * Clear the QRCode
1284		 */
1285		Drawing.prototype.clear = function() {
1286			this._el.innerHTML = '';
1287		};
1288
1289		return Drawing;
1290	})() : (function() { // Drawing in Canvas
1291		function _onMakeImage() {
1292			//this._elImage.crossOrigin='Anonymous';
1293			this._elImage.src = this._elCanvas.toDataURL("image/png");
1294			this._elImage.style.display = "inline";
1295			this._elCanvas.style.display = "none";
1296		}
1297
1298		// Android 2.1 bug workaround
1299		// http://code.google.com/p/android/issues/detail?id=5141
1300		if (root._android && root._android <= 2.1) {
1301			var factor = 1 / window.devicePixelRatio;
1302			var drawImage = CanvasRenderingContext2D.prototype.drawImage;
1303			CanvasRenderingContext2D.prototype.drawImage = function(image, sx, sy, sw, sh, dx, dy, dw, dh) {
1304				if (("nodeName" in image) && /img/i.test(image.nodeName)) {
1305					for (var i = arguments.length - 1; i >= 1; i--) {
1306						arguments[i] = arguments[i] * factor;
1307					}
1308				} else if (typeof dw == "undefined") {
1309					arguments[1] *= factor;
1310					arguments[2] *= factor;
1311					arguments[3] *= factor;
1312					arguments[4] *= factor;
1313				}
1314
1315				drawImage.apply(this, arguments);
1316			};
1317		}
1318
1319		/**
1320		 * Check whether the user's browser supports Data URI or not
1321		 * 
1322		 * @private
1323		 * @param {Function} fSuccess Occurs if it supports Data URI
1324		 * @param {Function} fFail Occurs if it doesn't support Data URI
1325		 */
1326		function _safeSetDataURI(fSuccess, fFail) {
1327			var self = this;
1328			self._fFail = fFail;
1329			self._fSuccess = fSuccess;
1330
1331			// Check it just once
1332			if (self._bSupportDataURI === null) {
1333				var el = document.createElement("img");
1334				var fOnError = function() {
1335					self._bSupportDataURI = false;
1336
1337					if (self._fFail) {
1338						self._fFail.call(self);
1339					}
1340				};
1341				var fOnSuccess = function() {
1342					self._bSupportDataURI = true;
1343
1344					if (self._fSuccess) {
1345						self._fSuccess.call(self);
1346					}
1347				};
1348
1349				el.onabort = fOnError;
1350				el.onerror = fOnError;
1351				el.onload = fOnSuccess;
1352				el.src =
1353					"data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data.
1354				return;
1355			} else if (self._bSupportDataURI === true && self._fSuccess) {
1356				self._fSuccess.call(self);
1357			} else if (self._bSupportDataURI === false && self._fFail) {
1358				self._fFail.call(self);
1359			}
1360		};
1361
1362		/**
1363		 * Drawing QRCode by using canvas
1364		 * 
1365		 * @constructor
1366		 * @param {HTMLElement} el
1367		 * @param {Object} htOption QRCode Options 
1368		 */
1369		var Drawing = function(el, htOption) {
1370			this._bIsPainted = false;
1371			this._android = _getAndroid();
1372
1373			this._htOption = htOption;
1374			this._elCanvas = document.createElement("canvas");
1375			//this._elCanvas.width = htOption.width;
1376			//this._elCanvas.height = htOption.height;
1377			el.appendChild(this._elCanvas);
1378			this._el = el;
1379			this._oContext = this._elCanvas.getContext("2d");
1380			this._bIsPainted = false;
1381			this._elImage = document.createElement("img");
1382			this._elImage.alt = "Scan me!";
1383			this._elImage.style.display = "none";
1384			this._el.appendChild(this._elImage);
1385
1386			this._bSupportDataURI = null;
1387		};
1388
1389		/**
1390		 * Draw the QRCode
1391		 * 
1392		 * @param {QRCode} oQRCode 
1393		 */
1394		Drawing.prototype.draw = function(oQRCode) {
1395
1396			var _elImage = this._elImage;
1397			var _oContext = this._oContext;
1398			var _htOption = this._htOption;
1399
1400
1401			if (!_htOption.title && !_htOption.subTitle) {
1402				_htOption.height -= _htOption.titleHeight;
1403				_htOption.titleHeight = 0;
1404			}
1405
1406            
1407			var nCount = oQRCode.getModuleCount();
1408			var nWidth = Math.round(_htOption.width / nCount);
1409			var nHeight = Math.round((_htOption.height - _htOption.titleHeight) / nCount);
1410
1411			this._htOption.width = nWidth * nCount;
1412			this._htOption.height = nHeight * nCount + _htOption.titleHeight;
1413
1414			this._htOption.quietZone = Math.round(this._htOption.quietZone);
1415
1416
1417			this._elCanvas.width = this._htOption.width + this._htOption.quietZone * 2;
1418			this._elCanvas.height = this._htOption.height + this._htOption.quietZone * 2;
1419             
1420            
1421
1422			_elImage.style.display = "none";
1423			this.clear();
1424
1425			var t = this;
1426            
1427            function drawQuietZoneColor(){
1428                // top
1429                _oContext.lineWidth = 0;
1430                _oContext.fillStyle =  _htOption.quietZoneColor;
1431                _oContext.fillRect(0, 0, t._elCanvas.width, _htOption.quietZone);
1432                // left
1433                 _oContext.fillRect(0, _htOption.quietZone, _htOption.quietZone, t._elCanvas.height-_htOption.quietZone*2);
1434                // right
1435                 _oContext.fillRect(t._elCanvas.width-_htOption.quietZone,  _htOption.quietZone, _htOption.quietZone, t._elCanvas.height-_htOption.quietZone*2);
1436                // bottom
1437                 _oContext.fillRect(0, t._elCanvas.height-_htOption.quietZone, t._elCanvas.width, _htOption.quietZone);
1438            }
1439
1440			if (_htOption.backgroundImage) {
1441
1442				// backgroundImage
1443				var bgImg = new Image();
1444				
1445				bgImg.onload = function() {
1446					_oContext.globalAlpha = 1;
1447
1448					_oContext.globalAlpha = _htOption.backgroundImageAlpha;
1449
1450					_oContext.drawImage(bgImg, 0, _htOption.titleHeight, _htOption.width + _htOption.quietZone * 2, _htOption.height +
1451						_htOption.quietZone * 2 - _htOption.titleHeight);
1452					_oContext.globalAlpha = 1;
1453
1454
1455					drawQrcode.call(t, oQRCode);
1456				}
1457				//bgImg.crossOrigin='Anonymous';
1458				bgImg.src = _htOption.backgroundImage;
1459				// DoSomething
1460			} else {
1461				drawQrcode.call(t, oQRCode);
1462			}
1463
1464			function drawQrcode(oQRCode) {
1465				if (_htOption.onRenderingStart) {
1466					_htOption.onRenderingStart(_htOption)
1467				}
1468               
1469				for (var row = 0; row < nCount; row++) {
1470					for (var col = 0; col < nCount; col++) {
1471						var nLeft = col * nWidth + _htOption.quietZone;
1472						var nTop = row * nHeight + _htOption.quietZone;
1473
1474						var bIsDark = oQRCode.isDark(row, col);
1475
1476						var eye = oQRCode.getEye(row, col); // { isDark: true/false, type: PO_TL, PI_TL, PO_TR, PI_TR, PO_BL, PI_BL };
1477
1478						if (eye) {
1479							// Is eye
1480							bIsDark = eye.isDark;
1481							var type = eye.type;
1482
1483							// PX_XX, PX, colorDark, colorLight
1484							var eyeColorDark = _htOption[type] || _htOption[type.substring(0, 2)] || _htOption.colorDark;
1485
1486							_oContext.lineWidth = 0;
1487							_oContext.strokeStyle = bIsDark ? eyeColorDark : _htOption.colorLight;
1488							_oContext.fillStyle = bIsDark ? eyeColorDark : _htOption.colorLight;
1489
1490							_oContext.fillRect(nLeft, _htOption.titleHeight + nTop, nWidth, nHeight);
1491
1492						} else {
1493							_oContext.lineWidth = 0;
1494							_oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;
1495							_oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;
1496
1497							var nowDotScale = _htOption.dotScale;
1498							if (row == 6) {
1499								// Timing Pattern 
1500								nowDotScale = 1;
1501								var timingHColorDark = _htOption.timing_H || _htOption.timing || _htOption.colorDark;
1502								_oContext.fillStyle = bIsDark ? timingHColorDark : _htOption.colorLight;
1503								_oContext.strokeStyle = _oContext.fillStyle;
1504								_oContext.fillRect(nLeft + nWidth * (1 - nowDotScale) / 2, _htOption.titleHeight + nTop + nHeight * (1 -
1505									nowDotScale) / 2, nWidth * nowDotScale, nHeight * nowDotScale);
1506							} else if (col == 6) {
1507								// Timing Pattern 
1508								nowDotScale = 1;
1509								var timingVColorDark = _htOption.timing_V || _htOption.timing || _htOption.colorDark;
1510								_oContext.fillStyle = bIsDark ? timingVColorDark : _htOption.colorLight;
1511								_oContext.strokeStyle = _oContext.fillStyle;
1512								_oContext.fillRect(nLeft + nWidth * (1 - nowDotScale) / 2, _htOption.titleHeight + nTop + nHeight * (1 -
1513									nowDotScale) / 2, nWidth * nowDotScale, nHeight * nowDotScale);
1514							} else {
1515
1516								if (_htOption.backgroundImage) {
1517
1518									if (_htOption.autoColor) {
1519										_oContext.strokeStyle = bIsDark ? "rgba(0, 0, 0, .6)" : "rgba(255, 255, 255, .7)";
1520										_oContext.fillStyle = bIsDark ? "rgba(0, 0, 0, .6)" : "rgba(255, 255, 255, .7)";
1521									} else {
1522										_oContext.strokeStyle = bIsDark ? _htOption.colorDark : "rgba(0,0,0,0)";
1523										_oContext.fillStyle = bIsDark ? _htOption.colorDark : "rgba(0,0,0,0)";
1524										_oContext.strokeStyle = _oContext.fillStyle;
1525									}
1526									_oContext.fillRect(nLeft + nWidth * (1 - nowDotScale) / 2, _htOption.titleHeight + nTop + nHeight * (1 -
1527										nowDotScale) / 2, nWidth * nowDotScale, nHeight * nowDotScale);
1528								} else {
1529									_oContext.strokeStyle = _oContext.fillStyle;
1530									_oContext.fillRect(nLeft + nWidth * (1 - nowDotScale) / 2, _htOption.titleHeight + nTop + nHeight * (1 -
1531										nowDotScale) / 2, nWidth * nowDotScale, nHeight * nowDotScale);
1532
1533								}
1534							}
1535						}
1536
1537						if (_htOption.dotScale != 1 && !eye) {
1538							_oContext.strokeStyle = _htOption.colorLight;
1539						}
1540
1541					}
1542				}
1543
1544				if (_htOption.title) {
1545				    
1546					_oContext.fillStyle = _htOption.titleBackgroundColor;
1547					_oContext.fillRect(0, 0, this._elCanvas.width, _htOption.titleHeight+_htOption.quietZone);
1548				
1549					_oContext.font = _htOption.titleFont;
1550					_oContext.fillStyle = _htOption.titleColor;
1551					_oContext.textAlign = 'center';
1552					_oContext.fillText(_htOption.title, this._elCanvas.width / 2, +_htOption.quietZone+30);
1553				}
1554				
1555				if (_htOption.subTitle) {
1556					_oContext.font = _htOption.subTitleFont;
1557					_oContext.fillStyle = _htOption.subTitleColor;
1558					_oContext.fillText(_htOption.subTitle, this._elCanvas.width / 2, +_htOption.quietZone+60);
1559				}
1560
1561                    function genratorImg() {
1562						var imgW = Math.round(_htOption.width / 3.5);
1563						var imgH = Math.round(_htOption.height / 3.5);
1564						if (imgW != imgH) {
1565							imgW = imgH;
1566						}
1567
1568						if (_htOption.logoWidth) {
1569							imgW = Math.round(_htOption.logoWidth);
1570						}
1571						if (_htOption.logoHeight) {
1572							imgH = Math.round(_htOption.logoHeight);
1573						}
1574
1575
1576						// Did Not Use Transparent Logo Image
1577						if (!_htOption.logoBackgroundTransparent) {
1578							//if (!_htOption.logoBackgroundColor) {
1579							//_htOption.logoBackgroundColor = '#ffffff';
1580							//}
1581							_oContext.fillStyle = _htOption.logoBackgroundColor;
1582
1583							_oContext.fillRect((_htOption.width + _htOption.quietZone * 2 - imgW) / 2, (_htOption.height + _htOption.titleHeight +
1584								_htOption.quietZone * 2 - imgH) / 2, imgW, imgW);
1585						}
1586
1587						_oContext.drawImage(img, (_htOption.width + _htOption.quietZone * 2 - imgW) / 2, (_htOption.height +
1588							_htOption.titleHeight + _htOption.quietZone * 2 - imgH) / 2, imgW, imgH);
1589                        if(_htOption.quietZone>0 && _htOption.quietZoneColor){
1590                            drawQuietZoneColor();
1591                        }
1592						_this._bIsPainted = true;
1593
1594						_this.makeImage();
1595					}
1596                    
1597				if (_htOption.logo) {
1598					var img = new Image();
1599					
1600					var _this = this;
1601
1602
1603					img.onload = function() {
1604						genratorImg();
1605					}
1606
1607					img.onerror = function(e) {
1608						console.error(e)
1609					}
1610
1611					//img.crossOrigin="Anonymous";
1612					img.src = _htOption.logo;
1613
1614
1615				} else {
1616					this._bIsPainted = true;
1617					this.makeImage();
1618                    
1619				}
1620
1621
1622
1623			}
1624
1625		};
1626
1627		/**
1628		 * Make the image from Canvas if the browser supports Data URI.
1629		 */
1630		Drawing.prototype.makeImage = function() {
1631			if (this._bIsPainted) {
1632				_safeSetDataURI.call(this, _onMakeImage);
1633			}
1634		};
1635
1636		/**
1637		 * Return whether the QRCode is painted or not
1638		 * 
1639		 * @return {Boolean}
1640		 */
1641		Drawing.prototype.isPainted = function() {
1642			return this._bIsPainted;
1643		};
1644
1645		/**
1646		 * Clear the QRCode
1647		 */
1648		Drawing.prototype.clear = function() {
1649			this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height + 50);
1650			this._bIsPainted = false;
1651		};
1652
1653		Drawing.prototype.remove = function() {
1654			this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height + 50);
1655			this._bIsPainted = false;
1656			this._el.innerHTML = '';
1657		};
1658
1659
1660
1661		/**
1662		 * @private
1663		 * @param {Number} nNumber
1664		 */
1665		Drawing.prototype.round = function(nNumber) {
1666			if (!nNumber) {
1667				return nNumber;
1668			}
1669
1670			return Math.floor(nNumber * 1000) / 1000;
1671		};
1672
1673		return Drawing;
1674	})();
1675
1676	/**
1677	 * Get the type by string length
1678	 * 
1679	 * @private
1680	 * @param {String} sText
1681	 * @param {Number} nCorrectLevel
1682	 * @return {Number} type
1683	 */
1684	function _getTypeNumber(sText, nCorrectLevel) {
1685		var nType = 1;
1686		var length = _getUTF8Length(sText);
1687
1688		for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) {
1689			var nLimit = 0;
1690
1691			switch (nCorrectLevel) {
1692				case QRErrorCorrectLevel.L:
1693					nLimit = QRCodeLimitLength[i][0];
1694					break;
1695				case QRErrorCorrectLevel.M:
1696					nLimit = QRCodeLimitLength[i][1];
1697					break;
1698				case QRErrorCorrectLevel.Q:
1699					nLimit = QRCodeLimitLength[i][2];
1700					break;
1701				case QRErrorCorrectLevel.H:
1702					nLimit = QRCodeLimitLength[i][3];
1703					break;
1704			}
1705
1706			if (length <= nLimit) {
1707				break;
1708			} else {
1709				nType++;
1710			}
1711		}
1712
1713		if (nType > QRCodeLimitLength.length) {
1714			throw new Error("Too long data");
1715		}
1716
1717		return nType;
1718	}
1719
1720	function _getUTF8Length(sText) {
1721		var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a');
1722		return replacedText.length + (replacedText.length != sText ? 3 : 0);
1723	}
1724
1725	/**
1726	 * @class QRCode
1727	 * @constructor
1728	 * @example 
1729	 * new QRCode(document.getElementById("test"), "QRCode");
1730	 *
1731	 * @example
1732	 * var oQRCode = new QRCode("test", {
1733	 *    text : "QRCode",
1734	 *    width : 128,
1735	 *    height : 128
1736	 * });
1737	 * 
1738	 * oQRCode.clear(); // Clear the QRCode.
1739	 * oQRCode.makeCode("QRCode"); // Re-create the QRCode.
1740	 *
1741	 * @param {HTMLElement|String} el target element or 'id' attribute of element.
1742	 * @param {Object|String} vOption
1743	 * @param {String} vOption.text QRCode link data
1744	 * @param {Number} [vOption.width=256]
1745	 * @param {Number} [vOption.height=256]
1746	 * @param {String} [vOption.colorDark="#000000"]
1747	 * @param {String} [vOption.colorLight="#ffffff"]
1748	 * @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H] 
1749	 */
1750	QRCode = function(el, vOption) {
1751		this._htOption = {
1752			width: 256,
1753			height: 256,
1754			typeNumber: 4,
1755			colorDark: "#000000",
1756			colorLight: "#ffffff",
1757			correctLevel: QRErrorCorrectLevel.H,
1758
1759			dotScale: 1, // Must be greater than 0, less than or equal to 1. default is 1
1760            
1761            quietZone: 0,
1762            quietZoneColor: 'transparent', 
1763
1764			title: "",
1765			titleFont: "bold 16px Arial",
1766			titleColor: "#000000",
1767			titleBackgroundColor: "#ffffff",
1768			titleHeight: 0, // Title Height, Include subTitle
1769			titleTop: 30, // draws y coordinates. default is 30
1770
1771			subTitle: "",
1772			subTitleFont: "14px Arial",
1773			subTitleColor: "#4F4F4F",
1774			subTitleTop: 0, // draws y coordinates. default is 0
1775
1776			logo: undefined,
1777			logoWidth: undefined,
1778			logoHeight: undefined,
1779			logoBackgroundColor: '#ffffff',
1780			logoBackgroundTransparent: false,
1781
1782			// === Posotion Pattern(Eye) Color
1783			PO: undefined, // Global Posotion Outer color. if not set, the defaut is `colorDark`
1784			PI: undefined, // Global Posotion Inner color. if not set, the defaut is `colorDark`
1785			PO_TL: undefined, // Posotion Outer - Top Left 
1786			PI_TL: undefined, // Posotion Inner - Top Left 
1787			PO_TR: undefined, // Posotion Outer - Top Right 
1788			PI_TR: undefined, // Posotion Inner - Top Right 
1789			PO_BL: undefined, // Posotion Outer - Bottom Left 
1790			PI_BL: undefined, // Posotion Inner - Bottom Left 
1791
1792			// === Alignment Color
1793			AO: undefined, // Alignment Outer. if not set, the defaut is `colorDark`
1794			AI: undefined, // Alignment Inner. if not set, the defaut is `colorDark`
1795
1796			// === Timing Pattern Color
1797			timing: undefined, // Global Timing color. if not set, the defaut is `colorDark`
1798			timing_H: undefined, // Horizontal timing color
1799			timing_V: undefined, // Vertical timing color
1800
1801			// ==== Backgroud Image
1802			backgroundImage: undefined, // Background Image
1803			backgroundImageAlpha: 1, // Background image transparency, value between 0 and 1. default is 1. 
1804			autoColor: false,
1805
1806			// ==== Event Handler
1807			onRenderingStart: undefined
1808
1809		};
1810
1811		if (typeof vOption === 'string') {
1812			vOption = {
1813				text: vOption
1814			};
1815		}
1816
1817		// Overwrites options
1818		if (vOption) {
1819			for (var i in vOption) {
1820				this._htOption[i] = vOption[i];
1821			}
1822		}
1823
1824		if (this._htOption.dotScale < 0 || this._htOption.dotScale > 1) {
1825			console.warn(this._htOption.dotScale +
1826				" , is invalidate, dotScale must greater than 0, less than or equal to 1, now reset to 1. ")
1827			this._htOption.dotScale = 1;
1828		}
1829		if (this._htOption.backgroundImageAlpha < 0 || this._htOption.backgroundImageAlpha > 1) {
1830			console.warn(this._htOption.backgroundImageAlpha +
1831				" , is invalidate, backgroundImageAlpha must between 0 and 1, now reset to 1. ")
1832			this._htOption.backgroundImageAlpha = 1;
1833		}
1834
1835		this._htOption.height = this._htOption.height + this._htOption.titleHeight;
1836		if (typeof el == "string") {
1837			el = document.getElementById(el);
1838		}
1839
1840		if (this._htOption.useSVG) {
1841			Drawing = svgDrawer;
1842		}
1843		
1844		this._android = _getAndroid();
1845		this._el = el;
1846		this._oQRCode = null;
1847		this._oDrawing = new Drawing(this._el, this._htOption);
1848
1849		if (this._htOption.text) {
1850			this.makeCode(this._htOption.text);
1851		}
1852	};
1853
1854	/**
1855	 * Make the QRCode
1856	 * 
1857	 * @param {String} sText link data
1858	 */
1859	QRCode.prototype.makeCode = function(sText) {
1860
1861		this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel);
1862		this._oQRCode.addData(sText);
1863		this._oQRCode.make();
1864		this._el.title = sText;
1865		this._oDrawing.draw(this._oQRCode);
1866		//		this.makeImage();
1867	};
1868
1869	/**
1870	 * Make the Image from Canvas element
1871	 * - It occurs automatically
1872	 * - Android below 3 doesn't support Data-URI spec.
1873	 * 
1874	 * @private
1875	 */
1876	QRCode.prototype.makeImage = function() {
1877		if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) {
1878			this._oDrawing.makeImage();
1879		}
1880	};
1881
1882	/**
1883	 * Clear the QRCode
1884	 */
1885	QRCode.prototype.clear = function() {
1886		this._oDrawing.remove();
1887	};
1888
1889
1890	/**
1891	 * No Conflict
1892	 * @return QRCode object
1893	 */
1894	QRCode.prototype.noConflict = function() {
1895		if (root.QRCode === this) {
1896			root.QRCode = _QRCode;
1897		}
1898		return QRCode;
1899	}
1900
1901	/**
1902	 * @name QRCode.CorrectLevel
1903	 */
1904	QRCode.CorrectLevel = QRErrorCorrectLevel;
1905
1906
1907	/*--------------------------------------------------------------------------*/
1908	// Export QRCode
1909
1910	// AMD & CMD Compatibility
1911	if (typeof define == 'function' && (define.amd || define.cmd)) {
1912
1913		// 1. Define an anonymous module
1914		define([], function() {
1915			return QRCode;
1916		});
1917
1918	}
1919	// CommonJS Compatibility(include NodeJS)
1920	else if (freeModule) {
1921		// Node.js
1922		(freeModule.exports = QRCode).QRCode = QRCode;
1923		// Other CommonJS
1924		freeExports.QRCode = QRCode;
1925	} else {
1926		// Export Global
1927		root.QRCode = QRCode;
1928	}
1929
1930
1931
1932}.call(this));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.