| /*  | 
 |  * QR Code generator library (JavaScript) | 
 |  *  | 
 |  * Copyright (c) Project Nayuki. (MIT License) | 
 |  * https://www.nayuki.io/page/qr-code-generator-library | 
 |  *  | 
 |  * Permission is hereby granted, free of charge, to any person obtaining a copy of | 
 |  * this software and associated documentation files (the "Software"), to deal in | 
 |  * the Software without restriction, including without limitation the rights to | 
 |  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of | 
 |  * the Software, and to permit persons to whom the Software is furnished to do so, | 
 |  * subject to the following conditions: | 
 |  * - The above copyright notice and this permission notice shall be included in | 
 |  *   all copies or substantial portions of the Software. | 
 |  * - The Software is provided "as is", without warranty of any kind, express or | 
 |  *   implied, including but not limited to the warranties of merchantability, | 
 |  *   fitness for a particular purpose and noninfringement. In no event shall the | 
 |  *   authors or copyright holders be liable for any claim, damages or other | 
 |  *   liability, whether in an action of contract, tort or otherwise, arising from, | 
 |  *   out of or in connection with the Software or the use or other dealings in the | 
 |  *   Software. | 
 |  */ | 
 |  | 
 | "use strict"; | 
 |  | 
 |  | 
 | /*  | 
 |  * Module "qrcodegen", public members: | 
 |  * - Class QrCode: | 
 |  *   - Function encodeText(str text, QrCode.Ecc ecl) -> QrCode | 
 |  *   - Function encodeBinary(list<byte> data, QrCode.Ecc ecl) -> QrCode | 
 |  *   - Function encodeSegments(list<QrSegment> segs, QrCode.Ecc ecl, | 
 |  *         int minVersion=1, int maxVersion=40, mask=-1, boostEcl=true) -> QrCode | 
 |  *   - Constants int MIN_VERSION, MAX_VERSION | 
 |  *   - Constructor QrCode(list<int> datacodewords, int mask, int version, QrCode.Ecc ecl) | 
 |  *   - Fields int version, size, mask | 
 |  *   - Field QrCode.Ecc errorCorrectionLevel | 
 |  *   - Method getModule(int x, int y) -> bool | 
 |  *   - Method drawCanvas(int scale, int border, HTMLCanvasElement canvas) -> void | 
 |  *   - Method toSvgString(int border) -> str | 
 |  *   - Enum Ecc: | 
 |  *     - Constants LOW, MEDIUM, QUARTILE, HIGH | 
 |  *     - Field int ordinal | 
 |  * - Class QrSegment: | 
 |  *   - Function makeBytes(list<int> data) -> QrSegment | 
 |  *   - Function makeNumeric(str data) -> QrSegment | 
 |  *   - Function makeAlphanumeric(str data) -> QrSegment | 
 |  *   - Function makeSegments(str text) -> list<QrSegment> | 
 |  *   - Function makeEci(int assignVal) -> QrSegment | 
 |  *   - Constructor QrSegment(QrSegment.Mode mode, int numChars, list<int> bitData) | 
 |  *   - Field QrSegment.Mode mode | 
 |  *   - Field int numChars | 
 |  *   - Method getBits() -> list<int> | 
 |  *   - Constants RegExp NUMERIC_REGEX, ALPHANUMERIC_REGEX | 
 |  *   - Enum Mode: | 
 |  *     - Constants NUMERIC, ALPHANUMERIC, BYTE, KANJI, ECI | 
 |  */ | 
 | var qrcodegen = new function() { | 
 | 	 | 
 | 	/*---- QR Code symbol class ----*/ | 
 | 	 | 
 | 	/*  | 
 | 	 * A class that represents an immutable square grid of black and white cells for a QR Code symbol, | 
 | 	 * with associated static functions to create a QR Code from user-supplied textual or binary data. | 
 | 	 * This class covers the QR Code model 2 specification, supporting all versions (sizes) | 
 | 	 * from 1 to 40, all 4 error correction levels. | 
 | 	 * This constructor creates a new QR Code symbol with the given version number, error correction level, binary data array, | 
 | 	 * and mask number. mask = -1 is for automatic choice, or 0 to 7 for fixed choice. This is a cumbersome low-level constructor | 
 | 	 * that should not be invoked directly by the user. To go one level up, see the QrCode.encodeSegments() function. | 
 | 	 */ | 
 | 	this.QrCode = function(datacodewords, mask, version, errCorLvl) { | 
 | 		 | 
 | 		/*---- Constructor ----*/ | 
 | 		 | 
 | 		// Check arguments and handle simple scalar fields | 
 | 		if (mask < -1 || mask > 7) | 
 | 			throw "Mask value out of range"; | 
 | 		if (version < MIN_VERSION || version > MAX_VERSION) | 
 | 			throw "Version value out of range"; | 
 | 		var size = version * 4 + 17; | 
 | 		 | 
 | 		// Initialize both grids to be size*size arrays of Boolean false | 
 | 		var row = []; | 
 | 		for (var i = 0; i < size; i++) | 
 | 			row.push(false); | 
 | 		var modules = []; | 
 | 		var isFunction = []; | 
 | 		for (var i = 0; i < size; i++) { | 
 | 			modules.push(row.slice()); | 
 | 			isFunction.push(row.slice()); | 
 | 		} | 
 | 		 | 
 | 		// Handle grid fields, draw function patterns, draw all codewords | 
 | 		drawFunctionPatterns(); | 
 | 		var allCodewords = appendErrorCorrection(datacodewords); | 
 | 		drawCodewords(allCodewords); | 
 | 		 | 
 | 		// Handle masking | 
 | 		if (mask == -1) {  // Automatically choose best mask | 
 | 			var minPenalty = Infinity; | 
 | 			for (var i = 0; i < 8; i++) { | 
 | 				drawFormatBits(i); | 
 | 				applyMask(i); | 
 | 				var penalty = getPenaltyScore(); | 
 | 				if (penalty < minPenalty) { | 
 | 					mask = i; | 
 | 					minPenalty = penalty; | 
 | 				} | 
 | 				applyMask(i);  // Undoes the mask due to XOR | 
 | 			} | 
 | 		} | 
 | 		if (mask < 0 || mask > 7) | 
 | 			throw "Assertion error"; | 
 | 		drawFormatBits(mask);  // Overwrite old format bits | 
 | 		applyMask(mask);  // Apply the final choice of mask | 
 | 		 | 
 | 		 | 
 | 		/*---- Read-only instance properties ----*/ | 
 | 		 | 
 | 		// This QR Code symbol's version number, which is always between 1 and 40 (inclusive). | 
 | 		Object.defineProperty(this, "version", {value:version}); | 
 | 		 | 
 | 		// The width and height of this QR Code symbol, measured in modules. | 
 | 		// Always equal to version * 4 + 17, in the range 21 to 177. | 
 | 		Object.defineProperty(this, "size", {value:size}); | 
 | 		 | 
 | 		// The error correction level used in this QR Code symbol. | 
 | 		Object.defineProperty(this, "errorCorrectionLevel", {value:errCorLvl}); | 
 | 		 | 
 | 		// The mask pattern used in this QR Code symbol, in the range 0 to 7 (i.e. unsigned 3-bit integer). | 
 | 		// Note that even if the constructor was called with automatic masking requested | 
 | 		// (mask = -1), the resulting object will still have a mask value between 0 and 7. | 
 | 		Object.defineProperty(this, "mask", {value:mask}); | 
 | 		 | 
 | 		 | 
 | 		/*---- Accessor methods ----*/ | 
 | 		 | 
 | 		// (Public) Returns the color of the module (pixel) at the given coordinates, which is either | 
 | 		// false for white or true for black. The top left corner has the coordinates (x=0, y=0). | 
 | 		// If the given coordinates are out of bounds, then false (white) is returned. | 
 | 		this.getModule = function(x, y) { | 
 | 			return 0 <= x && x < size && 0 <= y && y < size && modules[y][x]; | 
 | 		}; | 
 | 		 | 
 | 		// (Package-private) Tests whether the module at the given coordinates is a function module (true) or not (false). | 
 | 		// The top left corner has the coordinates (x=0, y=0). If the given coordinates are out of bounds, then false is returned. | 
 | 		// The JavaScript version of this library has this method because it is impossible to access private variables of another object. | 
 | 		this.isFunctionModule = function(x, y) { | 
 | 			if (0 <= x && x < size && 0 <= y && y < size) | 
 | 				return isFunction[y][x]; | 
 | 			else | 
 | 				return false;  // Infinite border | 
 | 		}; | 
 | 		 | 
 | 		 | 
 | 		/*---- Public instance methods ----*/ | 
 | 		 | 
 | 		// Draws this QR Code symbol with the given module scale and number of modules onto the given HTML canvas element. | 
 | 		// The canvas will be resized to a width and height of (this.size + border * 2) * scale. The painted image will be purely | 
 | 		// black and white with no transparent regions. The scale must be a positive integer, and the border must be a non-negative integer. | 
 | 		this.drawCanvas = function(scale, border, canvas) { | 
 | 			if (scale <= 0 || border < 0) | 
 | 				throw "Value out of range"; | 
 | 			var width = (size + border * 2) * scale; | 
 | 			canvas.width = width; | 
 | 			canvas.height = width; | 
 | 			var ctx = canvas.getContext("2d"); | 
 | 			for (var y = -border; y < size + border; y++) { | 
 | 				for (var x = -border; x < size + border; x++) { | 
 | 					ctx.fillStyle = this.getModule(x, y) ? "#000000" : "#FFFFFF"; | 
 | 					ctx.fillRect((x + border) * scale, (y + border) * scale, scale, scale); | 
 | 				} | 
 | 			} | 
 | 		}; | 
 | 		 | 
 | 		// Based on the given number of border modules to add as padding, this returns a | 
 | 		// string whose contents represents an SVG XML file that depicts this QR Code symbol. | 
 | 		// Note that Unix newlines (\n) are always used, regardless of the platform. | 
 | 		this.toSvgString = function(border) { | 
 | 			if (border < 0) | 
 | 				throw "Border must be non-negative"; | 
 | 			var result = '<?xml version="1.0" encoding="UTF-8"?>\n'; | 
 | 			result += '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n'; | 
 | 			result += '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 ' + | 
 | 				(size + border * 2) + ' ' + (size + border * 2) + '" stroke="none">\n'; | 
 | 			result += '\t<rect width="100%" height="100%" fill="#FFFFFF"/>\n'; | 
 | 			result += '\t<path d="'; | 
 | 			var head = true; | 
 | 			for (var y = -border; y < size + border; y++) { | 
 | 				for (var x = -border; x < size + border; x++) { | 
 | 					if (this.getModule(x, y)) { | 
 | 						if (head) | 
 | 							head = false; | 
 | 						else | 
 | 							result += " "; | 
 | 						result += "M" + (x + border) + "," + (y + border) + "h1v1h-1z"; | 
 | 					} | 
 | 				} | 
 | 			} | 
 | 			result += '" fill="#000000"/>\n'; | 
 | 			result += '</svg>\n'; | 
 | 			return result; | 
 | 		}; | 
 | 		 | 
 | 		 | 
 | 		/*---- Private helper methods for constructor: Drawing function modules ----*/ | 
 | 		 | 
 | 		function drawFunctionPatterns() { | 
 | 			// Draw horizontal and vertical timing patterns | 
 | 			for (var i = 0; i < size; i++) { | 
 | 				setFunctionModule(6, i, i % 2 == 0); | 
 | 				setFunctionModule(i, 6, i % 2 == 0); | 
 | 			} | 
 | 			 | 
 | 			// Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules) | 
 | 			drawFinderPattern(3, 3); | 
 | 			drawFinderPattern(size - 4, 3); | 
 | 			drawFinderPattern(3, size - 4); | 
 | 			 | 
 | 			// Draw numerous alignment patterns | 
 | 			var alignPatPos = QrCode.getAlignmentPatternPositions(version); | 
 | 			var numAlign = alignPatPos.length; | 
 | 			for (var i = 0; i < numAlign; i++) { | 
 | 				for (var j = 0; j < numAlign; j++) { | 
 | 					if (i == 0 && j == 0 || i == 0 && j == numAlign - 1 || i == numAlign - 1 && j == 0) | 
 | 						continue;  // Skip the three finder corners | 
 | 					else | 
 | 						drawAlignmentPattern(alignPatPos[i], alignPatPos[j]); | 
 | 				} | 
 | 			} | 
 | 			 | 
 | 			// Draw configuration data | 
 | 			drawFormatBits(0);  // Dummy mask value; overwritten later in the constructor | 
 | 			drawVersion(); | 
 | 		} | 
 | 		 | 
 | 		 | 
 | 		// Draws two copies of the format bits (with its own error correction code) | 
 | 		// based on the given mask and this object's error correction level field. | 
 | 		function drawFormatBits(mask) { | 
 | 			// Calculate error correction code and pack bits | 
 | 			var data = errCorLvl.formatBits << 3 | mask;  // errCorrLvl is uint2, mask is uint3 | 
 | 			var rem = data; | 
 | 			for (var i = 0; i < 10; i++) | 
 | 				rem = (rem << 1) ^ ((rem >>> 9) * 0x537); | 
 | 			data = data << 10 | rem; | 
 | 			data ^= 0x5412;  // uint15 | 
 | 			if (data >>> 15 != 0) | 
 | 				throw "Assertion error"; | 
 | 			 | 
 | 			// Draw first copy | 
 | 			for (var i = 0; i <= 5; i++) | 
 | 				setFunctionModule(8, i, ((data >>> i) & 1) != 0); | 
 | 			setFunctionModule(8, 7, ((data >>> 6) & 1) != 0); | 
 | 			setFunctionModule(8, 8, ((data >>> 7) & 1) != 0); | 
 | 			setFunctionModule(7, 8, ((data >>> 8) & 1) != 0); | 
 | 			for (var i = 9; i < 15; i++) | 
 | 				setFunctionModule(14 - i, 8, ((data >>> i) & 1) != 0); | 
 | 			 | 
 | 			// Draw second copy | 
 | 			for (var i = 0; i <= 7; i++) | 
 | 				setFunctionModule(size - 1 - i, 8, ((data >>> i) & 1) != 0); | 
 | 			for (var i = 8; i < 15; i++) | 
 | 				setFunctionModule(8, size - 15 + i, ((data >>> i) & 1) != 0); | 
 | 			setFunctionModule(8, size - 8, true); | 
 | 		} | 
 | 		 | 
 | 		 | 
 | 		// Draws two copies of the version bits (with its own error correction code), | 
 | 		// based on this object's version field (which only has an effect for 7 <= version <= 40). | 
 | 		function drawVersion() { | 
 | 			if (version < 7) | 
 | 				return; | 
 | 			 | 
 | 			// Calculate error correction code and pack bits | 
 | 			var rem = version;  // version is uint6, in the range [7, 40] | 
 | 			for (var i = 0; i < 12; i++) | 
 | 				rem = (rem << 1) ^ ((rem >>> 11) * 0x1F25); | 
 | 			var data = version << 12 | rem;  // uint18 | 
 | 			if (data >>> 18 != 0) | 
 | 				throw "Assertion error"; | 
 | 			 | 
 | 			// Draw two copies | 
 | 			for (var i = 0; i < 18; i++) { | 
 | 				var bit = ((data >>> i) & 1) != 0; | 
 | 				var a = size - 11 + i % 3, b = Math.floor(i / 3); | 
 | 				setFunctionModule(a, b, bit); | 
 | 				setFunctionModule(b, a, bit); | 
 | 			} | 
 | 		} | 
 | 		 | 
 | 		 | 
 | 		// Draws a 9*9 finder pattern including the border separator, with the center module at (x, y). | 
 | 		function drawFinderPattern(x, y) { | 
 | 			for (var i = -4; i <= 4; i++) { | 
 | 				for (var j = -4; j <= 4; j++) { | 
 | 					var dist = Math.max(Math.abs(i), Math.abs(j));  // Chebyshev/infinity norm | 
 | 					var xx = x + j, yy = y + i; | 
 | 					if (0 <= xx && xx < size && 0 <= yy && yy < size) | 
 | 						setFunctionModule(xx, yy, dist != 2 && dist != 4); | 
 | 				} | 
 | 			} | 
 | 		} | 
 | 		 | 
 | 		 | 
 | 		// Draws a 5*5 alignment pattern, with the center module at (x, y). | 
 | 		function drawAlignmentPattern(x, y) { | 
 | 			for (var i = -2; i <= 2; i++) { | 
 | 				for (var j = -2; j <= 2; j++) | 
 | 					setFunctionModule(x + j, y + i, Math.max(Math.abs(i), Math.abs(j)) != 1); | 
 | 			} | 
 | 		} | 
 | 		 | 
 | 		 | 
 | 		// Sets the color of a module and marks it as a function module. | 
 | 		// Only used by the constructor. Coordinates must be in range. | 
 | 		function setFunctionModule(x, y, isBlack) { | 
 | 			modules[y][x] = isBlack; | 
 | 			isFunction[y][x] = true; | 
 | 		} | 
 | 		 | 
 | 		 | 
 | 		/*---- Private helper methods for constructor: Codewords and masking ----*/ | 
 | 		 | 
 | 		// Returns a new byte string representing the given data with the appropriate error correction | 
 | 		// codewords appended to it, based on this object's version and error correction level. | 
 | 		function appendErrorCorrection(data) { | 
 | 			if (data.length != QrCode.getNumDataCodewords(version, errCorLvl)) | 
 | 				throw "Invalid argument"; | 
 | 			 | 
 | 			// Calculate parameter numbers | 
 | 			var numBlocks = QrCode.NUM_ERROR_CORRECTION_BLOCKS[errCorLvl.ordinal][version]; | 
 | 			var blockEccLen = QrCode.ECC_CODEWORDS_PER_BLOCK[errCorLvl.ordinal][version]; | 
 | 			var rawCodewords = Math.floor(QrCode.getNumRawDataModules(version) / 8); | 
 | 			var numShortBlocks = numBlocks - rawCodewords % numBlocks; | 
 | 			var shortBlockLen = Math.floor(rawCodewords / numBlocks); | 
 | 			 | 
 | 			// Split data into blocks and append ECC to each block | 
 | 			var blocks = []; | 
 | 			var rs = new ReedSolomonGenerator(blockEccLen); | 
 | 			for (var i = 0, k = 0; i < numBlocks; i++) { | 
 | 				var dat = data.slice(k, k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1)); | 
 | 				k += dat.length; | 
 | 				var ecc = rs.getRemainder(dat); | 
 | 				if (i < numShortBlocks) | 
 | 					dat.push(0); | 
 | 				ecc.forEach(function(b) { | 
 | 					dat.push(b); | 
 | 				}); | 
 | 				blocks.push(dat); | 
 | 			} | 
 | 			 | 
 | 			// Interleave (not concatenate) the bytes from every block into a single sequence | 
 | 			var result = []; | 
 | 			for (var i = 0; i < blocks[0].length; i++) { | 
 | 				for (var j = 0; j < blocks.length; j++) { | 
 | 					// Skip the padding byte in short blocks | 
 | 					if (i != shortBlockLen - blockEccLen || j >= numShortBlocks) | 
 | 						result.push(blocks[j][i]); | 
 | 				} | 
 | 			} | 
 | 			if (result.length != rawCodewords) | 
 | 				throw "Assertion error"; | 
 | 			return result; | 
 | 		} | 
 | 		 | 
 | 		 | 
 | 		// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire | 
 | 		// data area of this QR Code symbol. Function modules need to be marked off before this is called. | 
 | 		function drawCodewords(data) { | 
 | 			if (data.length != Math.floor(QrCode.getNumRawDataModules(version) / 8)) | 
 | 				throw "Invalid argument"; | 
 | 			var i = 0;  // Bit index into the data | 
 | 			// Do the funny zigzag scan | 
 | 			for (var right = size - 1; right >= 1; right -= 2) {  // Index of right column in each column pair | 
 | 				if (right == 6) | 
 | 					right = 5; | 
 | 				for (var vert = 0; vert < size; vert++) {  // Vertical counter | 
 | 					for (var j = 0; j < 2; j++) { | 
 | 						var x = right - j;  // Actual x coordinate | 
 | 						var upward = ((right + 1) & 2) == 0; | 
 | 						var y = upward ? size - 1 - vert : vert;  // Actual y coordinate | 
 | 						if (!isFunction[y][x] && i < data.length * 8) { | 
 | 							modules[y][x] = ((data[i >>> 3] >>> (7 - (i & 7))) & 1) != 0; | 
 | 							i++; | 
 | 						} | 
 | 						// If there are any remainder bits (0 to 7), they are already | 
 | 						// set to 0/false/white when the grid of modules was initialized | 
 | 					} | 
 | 				} | 
 | 			} | 
 | 			if (i != data.length * 8) | 
 | 				throw "Assertion error"; | 
 | 		} | 
 | 		 | 
 | 		 | 
 | 		// XORs the data modules in this QR Code with the given mask pattern. Due to XOR's mathematical | 
 | 		// properties, calling applyMask(m) twice with the same value is equivalent to no change at all. | 
 | 		// This means it is possible to apply a mask, undo it, and try another mask. Note that a final | 
 | 		// well-formed QR Code symbol needs exactly one mask applied (not zero, not two, etc.). | 
 | 		function applyMask(mask) { | 
 | 			if (mask < 0 || mask > 7) | 
 | 				throw "Mask value out of range"; | 
 | 			for (var y = 0; y < size; y++) { | 
 | 				for (var x = 0; x < size; x++) { | 
 | 					var invert; | 
 | 					switch (mask) { | 
 | 						case 0:  invert = (x + y) % 2 == 0;                                  break; | 
 | 						case 1:  invert = y % 2 == 0;                                        break; | 
 | 						case 2:  invert = x % 3 == 0;                                        break; | 
 | 						case 3:  invert = (x + y) % 3 == 0;                                  break; | 
 | 						case 4:  invert = (Math.floor(x / 3) + Math.floor(y / 2)) % 2 == 0;  break; | 
 | 						case 5:  invert = x * y % 2 + x * y % 3 == 0;                        break; | 
 | 						case 6:  invert = (x * y % 2 + x * y % 3) % 2 == 0;                  break; | 
 | 						case 7:  invert = ((x + y) % 2 + x * y % 3) % 2 == 0;                break; | 
 | 						default:  throw "Assertion error"; | 
 | 					} | 
 | 					modules[y][x] ^= invert & !isFunction[y][x]; | 
 | 				} | 
 | 			} | 
 | 		} | 
 | 		 | 
 | 		 | 
 | 		// Calculates and returns the penalty score based on state of this QR Code's current modules. | 
 | 		// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score. | 
 | 		function getPenaltyScore() { | 
 | 			var result = 0; | 
 | 			 | 
 | 			// Adjacent modules in row having same color | 
 | 			for (var y = 0; y < size; y++) { | 
 | 				for (var x = 0, runX, colorX; x < size; x++) { | 
 | 					if (x == 0 || modules[y][x] != colorX) { | 
 | 						colorX = modules[y][x]; | 
 | 						runX = 1; | 
 | 					} else { | 
 | 						runX++; | 
 | 						if (runX == 5) | 
 | 							result += QrCode.PENALTY_N1; | 
 | 						else if (runX > 5) | 
 | 							result++; | 
 | 					} | 
 | 				} | 
 | 			} | 
 | 			// Adjacent modules in column having same color | 
 | 			for (var x = 0; x < size; x++) { | 
 | 				for (var y = 0, runY, colorY; y < size; y++) { | 
 | 					if (y == 0 || modules[y][x] != colorY) { | 
 | 						colorY = modules[y][x]; | 
 | 						runY = 1; | 
 | 					} else { | 
 | 						runY++; | 
 | 						if (runY == 5) | 
 | 							result += QrCode.PENALTY_N1; | 
 | 						else if (runY > 5) | 
 | 							result++; | 
 | 					} | 
 | 				} | 
 | 			} | 
 | 			 | 
 | 			// 2*2 blocks of modules having same color | 
 | 			for (var y = 0; y < size - 1; y++) { | 
 | 				for (var x = 0; x < size - 1; x++) { | 
 | 					var   color = modules[y][x]; | 
 | 					if (  color == modules[y][x + 1] && | 
 | 					      color == modules[y + 1][x] && | 
 | 					      color == modules[y + 1][x + 1]) | 
 | 						result += QrCode.PENALTY_N2; | 
 | 				} | 
 | 			} | 
 | 			 | 
 | 			// Finder-like pattern in rows | 
 | 			for (var y = 0; y < size; y++) { | 
 | 				for (var x = 0, bits = 0; x < size; x++) { | 
 | 					bits = ((bits << 1) & 0x7FF) | (modules[y][x] ? 1 : 0); | 
 | 					if (x >= 10 && (bits == 0x05D || bits == 0x5D0))  // Needs 11 bits accumulated | 
 | 						result += QrCode.PENALTY_N3; | 
 | 				} | 
 | 			} | 
 | 			// Finder-like pattern in columns | 
 | 			for (var x = 0; x < size; x++) { | 
 | 				for (var y = 0, bits = 0; y < size; y++) { | 
 | 					bits = ((bits << 1) & 0x7FF) | (modules[y][x] ? 1 : 0); | 
 | 					if (y >= 10 && (bits == 0x05D || bits == 0x5D0))  // Needs 11 bits accumulated | 
 | 						result += QrCode.PENALTY_N3; | 
 | 				} | 
 | 			} | 
 | 			 | 
 | 			// Balance of black and white modules | 
 | 			var black = 0; | 
 | 			modules.forEach(function(row) { | 
 | 				row.forEach(function(color) { | 
 | 					if (color) | 
 | 						black++; | 
 | 				}); | 
 | 			}); | 
 | 			var total = size * size; | 
 | 			// Find smallest k such that (45-5k)% <= dark/total <= (55+5k)% | 
 | 			for (var k = 0; black*20 < (9-k)*total || black*20 > (11+k)*total; k++) | 
 | 				result += QrCode.PENALTY_N4; | 
 | 			return result; | 
 | 		} | 
 | 	}; | 
 | 	 | 
 | 	 | 
 | 	/*---- Public static factory functions for QrCode ----*/ | 
 | 	 | 
 | 	/*  | 
 | 	 * Returns a QR Code symbol representing the specified Unicode text string at the specified error correction level. | 
 | 	 * As a conservative upper bound, this function is guaranteed to succeed for strings that have 738 or fewer | 
 | 	 * Unicode code points (not UTF-16 code units) if the low error correction level is used. The smallest possible | 
 | 	 * QR Code version is automatically chosen for the output. The ECC level of the result may be higher than the | 
 | 	 * ecl argument if it can be done without increasing the version. | 
 | 	 */ | 
 | 	this.QrCode.encodeText = function(text, ecl) { | 
 | 		var segs = qrcodegen.QrSegment.makeSegments(text); | 
 | 		return this.encodeSegments(segs, ecl); | 
 | 	}; | 
 | 	 | 
 | 	 | 
 | 	/*  | 
 | 	 * Returns a QR Code symbol representing the given binary data string at the given error correction level. | 
 | 	 * This function always encodes using the binary segment mode, not any text mode. The maximum number of | 
 | 	 * bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output. | 
 | 	 * The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version. | 
 | 	 */ | 
 | 	this.QrCode.encodeBinary = function(data, ecl) { | 
 | 		var seg = qrcodegen.QrSegment.makeBytes(data); | 
 | 		return this.encodeSegments([seg], ecl); | 
 | 	}; | 
 | 	 | 
 | 	 | 
 | 	/*  | 
 | 	 * Returns a QR Code symbol representing the given data segments with the given encoding parameters. | 
 | 	 * The smallest possible QR Code version within the given range is automatically chosen for the output. | 
 | 	 * This function allows the user to create a custom sequence of segments that switches | 
 | 	 * between modes (such as alphanumeric and binary) to encode text more efficiently. | 
 | 	 * This function is considered to be lower level than simply encoding text or binary data. | 
 | 	 */ | 
 | 	this.QrCode.encodeSegments = function(segs, ecl, minVersion, maxVersion, mask, boostEcl) { | 
 | 		if (minVersion == undefined) minVersion = MIN_VERSION; | 
 | 		if (maxVersion == undefined) maxVersion = MAX_VERSION; | 
 | 		if (mask == undefined) mask = -1; | 
 | 		if (boostEcl == undefined) boostEcl = true; | 
 | 		if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7) | 
 | 			throw "Invalid value"; | 
 | 		 | 
 | 		// Find the minimal version number to use | 
 | 		var version, dataUsedBits; | 
 | 		for (version = minVersion; ; version++) { | 
 | 			var dataCapacityBits = QrCode.getNumDataCodewords(version, ecl) * 8;  // Number of data bits available | 
 | 			dataUsedBits = qrcodegen.QrSegment.getTotalBits(segs, version); | 
 | 			if (dataUsedBits != null && dataUsedBits <= dataCapacityBits) | 
 | 				break;  // This version number is found to be suitable | 
 | 			if (version >= maxVersion)  // All versions in the range could not fit the given data | 
 | 				throw "Data too long"; | 
 | 		} | 
 | 		 | 
 | 		// Increase the error correction level while the data still fits in the current version number | 
 | 		[this.Ecc.MEDIUM, this.Ecc.QUARTILE, this.Ecc.HIGH].forEach(function(newEcl) { | 
 | 			if (boostEcl && dataUsedBits <= QrCode.getNumDataCodewords(version, newEcl) * 8) | 
 | 				ecl = newEcl; | 
 | 		}); | 
 | 		 | 
 | 		// Create the data bit string by concatenating all segments | 
 | 		var dataCapacityBits = QrCode.getNumDataCodewords(version, ecl) * 8; | 
 | 		var bb = new BitBuffer(); | 
 | 		segs.forEach(function(seg) { | 
 | 			bb.appendBits(seg.mode.modeBits, 4); | 
 | 			bb.appendBits(seg.numChars, seg.mode.numCharCountBits(version)); | 
 | 			seg.getBits().forEach(function(bit) { | 
 | 				bb.push(bit); | 
 | 			}); | 
 | 		}); | 
 | 		 | 
 | 		// Add terminator and pad up to a byte if applicable | 
 | 		bb.appendBits(0, Math.min(4, dataCapacityBits - bb.length)); | 
 | 		bb.appendBits(0, (8 - bb.length % 8) % 8); | 
 | 		 | 
 | 		// Pad with alternate bytes until data capacity is reached | 
 | 		for (var padByte = 0xEC; bb.length < dataCapacityBits; padByte ^= 0xEC ^ 0x11) | 
 | 			bb.appendBits(padByte, 8); | 
 | 		if (bb.length % 8 != 0) | 
 | 			throw "Assertion error"; | 
 | 		 | 
 | 		// Create the QR Code symbol | 
 | 		return new this(bb.getBytes(), mask, version, ecl); | 
 | 	}; | 
 | 	 | 
 | 	 | 
 | 	/*---- Public constants for QrCode ----*/ | 
 | 	 | 
 | 	var MIN_VERSION =  1; | 
 | 	var MAX_VERSION = 40; | 
 | 	Object.defineProperty(this.QrCode, "MIN_VERSION", {value:MIN_VERSION}); | 
 | 	Object.defineProperty(this.QrCode, "MAX_VERSION", {value:MAX_VERSION}); | 
 | 	 | 
 | 	 | 
 | 	/*---- Private static helper functions QrCode ----*/ | 
 | 	 | 
 | 	var QrCode = {};  // Private object to assign properties to. Not the same object as 'this.QrCode'. | 
 | 	 | 
 | 	 | 
 | 	// Returns a sequence of positions of the alignment patterns in ascending order. These positions are | 
 | 	// used on both the x and y axes. Each value in the resulting sequence is in the range [0, 177). | 
 | 	// This stateless pure function could be implemented as table of 40 variable-length lists of integers. | 
 | 	QrCode.getAlignmentPatternPositions = function(ver) { | 
 | 		if (ver < MIN_VERSION || ver > MAX_VERSION) | 
 | 			throw "Version number out of range"; | 
 | 		else if (ver == 1) | 
 | 			return []; | 
 | 		else { | 
 | 			var size = ver * 4 + 17; | 
 | 			var numAlign = Math.floor(ver / 7) + 2; | 
 | 			var step; | 
 | 			if (ver != 32) | 
 | 				step = Math.ceil((size - 13) / (2 * numAlign - 2)) * 2; | 
 | 			else  // C-C-C-Combo breaker! | 
 | 				step = 26; | 
 | 			 | 
 | 			var result = [6]; | 
 | 			for (var i = 0, pos = size - 7; i < numAlign - 1; i++, pos -= step) | 
 | 				result.splice(1, 0, pos); | 
 | 			return result; | 
 | 		} | 
 | 	}; | 
 | 	 | 
 | 	 | 
 | 	// Returns the number of data bits that can be stored in a QR Code of the given version number, after | 
 | 	// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8. | 
 | 	// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table. | 
 | 	QrCode.getNumRawDataModules = function(ver) { | 
 | 		if (ver < MIN_VERSION || ver > MAX_VERSION) | 
 | 			throw "Version number out of range"; | 
 | 		var result = (16 * ver + 128) * ver + 64; | 
 | 		if (ver >= 2) { | 
 | 			var numAlign = Math.floor(ver / 7) + 2; | 
 | 			result -= (25 * numAlign - 10) * numAlign - 55; | 
 | 			if (ver >= 7) | 
 | 				result -= 18 * 2;  // Subtract version information | 
 | 		} | 
 | 		return result; | 
 | 	}; | 
 | 	 | 
 | 	 | 
 | 	// Returns the number of 8-bit data (i.e. not error correction) codewords contained in any | 
 | 	// QR Code of the given version number and error correction level, with remainder bits discarded. | 
 | 	// This stateless pure function could be implemented as a (40*4)-cell lookup table. | 
 | 	QrCode.getNumDataCodewords = function(ver, ecl) { | 
 | 		if (ver < MIN_VERSION || ver > MAX_VERSION) | 
 | 			throw "Version number out of range"; | 
 | 		return Math.floor(QrCode.getNumRawDataModules(ver) / 8) - | 
 | 			QrCode.ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver] * | 
 | 			QrCode.NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver]; | 
 | 	}; | 
 | 	 | 
 | 	 | 
 | 	/*---- Private tables of constants for QrCode ----*/ | 
 | 	 | 
 | 	// For use in getPenaltyScore(), when evaluating which mask is best. | 
 | 	QrCode.PENALTY_N1 = 3; | 
 | 	QrCode.PENALTY_N2 = 3; | 
 | 	QrCode.PENALTY_N3 = 40; | 
 | 	QrCode.PENALTY_N4 = 10; | 
 | 	 | 
 | 	QrCode.ECC_CODEWORDS_PER_BLOCK = [ | 
 | 		// Version: (note that index 0 is for padding, and is set to an illegal value) | 
 | 		//  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40    Error correction level | 
 | 		[null,  7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],  // Low | 
 | 		[null, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28],  // Medium | 
 | 		[null, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],  // Quartile | 
 | 		[null, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30],  // High | 
 | 	]; | 
 | 	 | 
 | 	QrCode.NUM_ERROR_CORRECTION_BLOCKS = [ | 
 | 		// Version: (note that index 0 is for padding, and is set to an illegal value) | 
 | 		//  0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40    Error correction level | 
 | 		[null, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4,  4,  4,  4,  4,  6,  6,  6,  6,  7,  8,  8,  9,  9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25],  // Low | 
 | 		[null, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5,  5,  8,  9,  9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49],  // Medium | 
 | 		[null, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8,  8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68],  // Quartile | 
 | 		[null, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81],  // High | 
 | 	]; | 
 | 	 | 
 | 	 | 
 | 	/*---- Public helper enumeration ----*/ | 
 | 	 | 
 | 	/*  | 
 | 	 * Represents the error correction level used in a QR Code symbol. | 
 | 	 */ | 
 | 	this.QrCode.Ecc = { | 
 | 		// Constants declared in ascending order of error protection | 
 | 		LOW     : new Ecc(0, 1), | 
 | 		MEDIUM  : new Ecc(1, 0), | 
 | 		QUARTILE: new Ecc(2, 3), | 
 | 		HIGH    : new Ecc(3, 2), | 
 | 	}; | 
 | 	 | 
 | 	 | 
 | 	// Private constructor. | 
 | 	function Ecc(ord, fb) { | 
 | 		// (Public) In the range 0 to 3 (unsigned 2-bit integer) | 
 | 		Object.defineProperty(this, "ordinal", {value:ord}); | 
 | 		 | 
 | 		// (Package-private) In the range 0 to 3 (unsigned 2-bit integer) | 
 | 		Object.defineProperty(this, "formatBits", {value:fb}); | 
 | 	} | 
 | 	 | 
 | 	 | 
 | 	 | 
 | 	/*---- Data segment class ----*/ | 
 | 	 | 
 | 	/*  | 
 | 	 * A public class that represents a character string to be encoded in a QR Code symbol. | 
 | 	 * Each segment has a mode, and a sequence of characters that is already encoded as | 
 | 	 * a sequence of bits. Instances of this class are immutable. | 
 | 	 * This segment class imposes no length restrictions, but QR Codes have restrictions. | 
 | 	 * Even in the most favorable conditions, a QR Code can only hold 7089 characters of data. | 
 | 	 * Any segment longer than this is meaningless for the purpose of generating QR Codes. | 
 | 	 */ | 
 | 	this.QrSegment = function(mode, numChars, bitData) { | 
 | 		if (numChars < 0 || !(mode instanceof Mode)) | 
 | 			throw "Invalid argument"; | 
 | 		bitData = bitData.slice();  // Make defensive copy | 
 | 		 | 
 | 		// The mode indicator for this segment. | 
 | 		Object.defineProperty(this, "mode", {value:mode}); | 
 | 		 | 
 | 		// The length of this segment's unencoded data, measured in characters. Always zero or positive. | 
 | 		Object.defineProperty(this, "numChars", {value:numChars}); | 
 | 		 | 
 | 		// Returns a copy of all bits, which is an array of 0s and 1s. | 
 | 		this.getBits = function() { | 
 | 			return bitData.slice();  // Make defensive copy | 
 | 		}; | 
 | 	}; | 
 | 	 | 
 | 	 | 
 | 	/*---- Public static factory functions for QrSegment ----*/ | 
 | 	 | 
 | 	/*  | 
 | 	 * Returns a segment representing the given binary data encoded in byte mode. | 
 | 	 */ | 
 | 	this.QrSegment.makeBytes = function(data) { | 
 | 		var bb = new BitBuffer(); | 
 | 		data.forEach(function(b) { | 
 | 			bb.appendBits(b, 8); | 
 | 		}); | 
 | 		return new this(this.Mode.BYTE, data.length, bb); | 
 | 	}; | 
 | 	 | 
 | 	 | 
 | 	/*  | 
 | 	 * Returns a segment representing the given string of decimal digits encoded in numeric mode. | 
 | 	 */ | 
 | 	this.QrSegment.makeNumeric = function(digits) { | 
 | 		if (!this.NUMERIC_REGEX.test(digits)) | 
 | 			throw "String contains non-numeric characters"; | 
 | 		var bb = new BitBuffer(); | 
 | 		var i; | 
 | 		for (i = 0; i + 3 <= digits.length; i += 3)  // Process groups of 3 | 
 | 			bb.appendBits(parseInt(digits.substr(i, 3), 10), 10); | 
 | 		var rem = digits.length - i; | 
 | 		if (rem > 0)  // 1 or 2 digits remaining | 
 | 			bb.appendBits(parseInt(digits.substring(i), 10), rem * 3 + 1); | 
 | 		return new this(this.Mode.NUMERIC, digits.length, bb); | 
 | 	}; | 
 | 	 | 
 | 	 | 
 | 	/*  | 
 | 	 * Returns a segment representing the given text string encoded in alphanumeric mode. | 
 | 	 * The characters allowed are: 0 to 9, A to Z (uppercase only), space, | 
 | 	 * dollar, percent, asterisk, plus, hyphen, period, slash, colon. | 
 | 	 */ | 
 | 	this.QrSegment.makeAlphanumeric = function(text) { | 
 | 		if (!this.ALPHANUMERIC_REGEX.test(text)) | 
 | 			throw "String contains unencodable characters in alphanumeric mode"; | 
 | 		var bb = new BitBuffer(); | 
 | 		var i; | 
 | 		for (i = 0; i + 2 <= text.length; i += 2) {  // Process groups of 2 | 
 | 			var temp = QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)) * 45; | 
 | 			temp += QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i + 1)); | 
 | 			bb.appendBits(temp, 11); | 
 | 		} | 
 | 		if (i < text.length)  // 1 character remaining | 
 | 			bb.appendBits(QrSegment.ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)), 6); | 
 | 		return new this(this.Mode.ALPHANUMERIC, text.length, bb); | 
 | 	}; | 
 | 	 | 
 | 	 | 
 | 	/*  | 
 | 	 * Returns a new mutable list of zero or more segments to represent the given Unicode text string. | 
 | 	 * The result may use various segment modes and switch modes to optimize the length of the bit stream. | 
 | 	 */ | 
 | 	this.QrSegment.makeSegments = function(text) { | 
 | 		// Select the most efficient segment encoding automatically | 
 | 		if (text == "") | 
 | 			return []; | 
 | 		else if (this.NUMERIC_REGEX.test(text)) | 
 | 			return [this.makeNumeric(text)]; | 
 | 		else if (this.ALPHANUMERIC_REGEX.test(text)) | 
 | 			return [this.makeAlphanumeric(text)]; | 
 | 		else | 
 | 			return [this.makeBytes(toUtf8ByteArray(text))]; | 
 | 	}; | 
 | 	 | 
 | 	 | 
 | 	/*  | 
 | 	 * Returns a segment representing an Extended Channel Interpretation | 
 | 	 * (ECI) designator with the given assignment value. | 
 | 	 */ | 
 | 	this.QrSegment.makeEci = function(assignVal) { | 
 | 		var bb = new BitBuffer(); | 
 | 		if (0 <= assignVal && assignVal < (1 << 7)) | 
 | 			bb.appendBits(assignVal, 8); | 
 | 		else if ((1 << 7) <= assignVal && assignVal < (1 << 14)) { | 
 | 			bb.appendBits(2, 2); | 
 | 			bb.appendBits(assignVal, 14); | 
 | 		} else if ((1 << 14) <= assignVal && assignVal < 1000000) { | 
 | 			bb.appendBits(6, 3); | 
 | 			bb.appendBits(assignVal, 21); | 
 | 		} else | 
 | 			throw "ECI assignment value out of range"; | 
 | 		return new this(this.Mode.ECI, 0, bb); | 
 | 	}; | 
 | 	 | 
 | 	 | 
 | 	// Package-private helper function. | 
 | 	this.QrSegment.getTotalBits = function(segs, version) { | 
 | 		if (version < MIN_VERSION || version > MAX_VERSION) | 
 | 			throw "Version number out of range"; | 
 | 		var result = 0; | 
 | 		for (var i = 0; i < segs.length; i++) { | 
 | 			var seg = segs[i]; | 
 | 			var ccbits = seg.mode.numCharCountBits(version); | 
 | 			// Fail if segment length value doesn't fit in the length field's bit-width | 
 | 			if (seg.numChars >= (1 << ccbits)) | 
 | 				return null; | 
 | 			result += 4 + ccbits + seg.getBits().length; | 
 | 		} | 
 | 		return result; | 
 | 	}; | 
 | 	 | 
 | 	 | 
 | 	/*---- Constants for QrSegment ----*/ | 
 | 	 | 
 | 	var QrSegment = {};  // Private object to assign properties to. Not the same object as 'this.QrSegment'. | 
 | 	 | 
 | 	// (Public) Can test whether a string is encodable in numeric mode (such as by using QrSegment.makeNumeric()). | 
 | 	this.QrSegment.NUMERIC_REGEX = /^[0-9]*$/; | 
 | 	 | 
 | 	// (Public) Can test whether a string is encodable in alphanumeric mode (such as by using QrSegment.makeAlphanumeric()). | 
 | 	this.QrSegment.ALPHANUMERIC_REGEX = /^[A-Z0-9 $%*+.\/:-]*$/; | 
 | 	 | 
 | 	// (Private) The set of all legal characters in alphanumeric mode, where each character value maps to the index in the string. | 
 | 	QrSegment.ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"; | 
 | 	 | 
 | 	 | 
 | 	/*---- Public helper enumeration ----*/ | 
 | 	 | 
 | 	/*  | 
 | 	 * Represents the mode field of a segment. Immutable. | 
 | 	 */ | 
 | 	this.QrSegment.Mode = {  // Constants | 
 | 		NUMERIC     : new Mode(0x1, [10, 12, 14]), | 
 | 		ALPHANUMERIC: new Mode(0x2, [ 9, 11, 13]), | 
 | 		BYTE        : new Mode(0x4, [ 8, 16, 16]), | 
 | 		KANJI       : new Mode(0x8, [ 8, 10, 12]), | 
 | 		ECI         : new Mode(0x7, [ 0,  0,  0]), | 
 | 	}; | 
 | 	 | 
 | 	 | 
 | 	// Private constructor. | 
 | 	function Mode(mode, ccbits) { | 
 | 		// (Package-private) An unsigned 4-bit integer value (range 0 to 15) representing the mode indicator bits for this mode object. | 
 | 		Object.defineProperty(this, "modeBits", {value:mode}); | 
 | 		 | 
 | 		// (Package-private) Returns the bit width of the segment character count field for this mode object at the given version number. | 
 | 		this.numCharCountBits = function(ver) { | 
 | 			if      ( 1 <= ver && ver <=  9)  return ccbits[0]; | 
 | 			else if (10 <= ver && ver <= 26)  return ccbits[1]; | 
 | 			else if (27 <= ver && ver <= 40)  return ccbits[2]; | 
 | 			else  throw "Version number out of range"; | 
 | 		}; | 
 | 	} | 
 | 	 | 
 | 	 | 
 | 	 | 
 | 	/*---- Private helper functions and classes ----*/ | 
 | 	 | 
 | 	// Returns a new array of bytes representing the given string encoded in UTF-8. | 
 | 	function toUtf8ByteArray(str) { | 
 | 		str = encodeURI(str); | 
 | 		var result = []; | 
 | 		for (var i = 0; i < str.length; i++) { | 
 | 			if (str.charAt(i) != "%") | 
 | 				result.push(str.charCodeAt(i)); | 
 | 			else { | 
 | 				result.push(parseInt(str.substr(i + 1, 2), 16)); | 
 | 				i += 2; | 
 | 			} | 
 | 		} | 
 | 		return result; | 
 | 	} | 
 | 	 | 
 | 	 | 
 | 	 | 
 | 	/*  | 
 | 	 * A private helper class that computes the Reed-Solomon error correction codewords for a sequence of | 
 | 	 * data codewords at a given degree. Objects are immutable, and the state only depends on the degree. | 
 | 	 * This class exists because each data block in a QR Code shares the same the divisor polynomial. | 
 | 	 * This constructor creates a Reed-Solomon ECC generator for the given degree. This could be implemented | 
 | 	 * as a lookup table over all possible parameter values, instead of as an algorithm. | 
 | 	 */ | 
 | 	function ReedSolomonGenerator(degree) { | 
 | 		if (degree < 1 || degree > 255) | 
 | 			throw "Degree out of range"; | 
 | 		 | 
 | 		// Coefficients of the divisor polynomial, stored from highest to lowest power, excluding the leading term which | 
 | 		// is always 1. For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array {255, 8, 93}. | 
 | 		var coefficients = []; | 
 | 		 | 
 | 		// Start with the monomial x^0 | 
 | 		for (var i = 0; i < degree - 1; i++) | 
 | 			coefficients.push(0); | 
 | 		coefficients.push(1); | 
 | 		 | 
 | 		// Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}), | 
 | 		// drop the highest term, and store the rest of the coefficients in order of descending powers. | 
 | 		// Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D). | 
 | 		var root = 1; | 
 | 		for (var i = 0; i < degree; i++) { | 
 | 			// Multiply the current product by (x - r^i) | 
 | 			for (var j = 0; j < coefficients.length; j++) { | 
 | 				coefficients[j] = ReedSolomonGenerator.multiply(coefficients[j], root); | 
 | 				if (j + 1 < coefficients.length) | 
 | 					coefficients[j] ^= coefficients[j + 1]; | 
 | 			} | 
 | 			root = ReedSolomonGenerator.multiply(root, 0x02); | 
 | 		} | 
 | 		 | 
 | 		// Computes and returns the Reed-Solomon error correction codewords for the given | 
 | 		// sequence of data codewords. The returned object is always a new byte array. | 
 | 		// This method does not alter this object's state (because it is immutable). | 
 | 		this.getRemainder = function(data) { | 
 | 			// Compute the remainder by performing polynomial division | 
 | 			var result = coefficients.map(function() { return 0; }); | 
 | 			data.forEach(function(b) { | 
 | 				var factor = b ^ result.shift(); | 
 | 				result.push(0); | 
 | 				for (var i = 0; i < result.length; i++) | 
 | 					result[i] ^= ReedSolomonGenerator.multiply(coefficients[i], factor); | 
 | 			}); | 
 | 			return result; | 
 | 		}; | 
 | 	} | 
 | 	 | 
 | 	// This static function returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and | 
 | 	// result are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8. | 
 | 	ReedSolomonGenerator.multiply = function(x, y) { | 
 | 		if (x >>> 8 != 0 || y >>> 8 != 0) | 
 | 			throw "Byte out of range"; | 
 | 		// Russian peasant multiplication | 
 | 		var z = 0; | 
 | 		for (var i = 7; i >= 0; i--) { | 
 | 			z = (z << 1) ^ ((z >>> 7) * 0x11D); | 
 | 			z ^= ((y >>> i) & 1) * x; | 
 | 		} | 
 | 		if (z >>> 8 != 0) | 
 | 			throw "Assertion error"; | 
 | 		return z; | 
 | 	}; | 
 | 	 | 
 | 	 | 
 | 	 | 
 | 	/*  | 
 | 	 * A private helper class that represents an appendable sequence of bits. | 
 | 	 * This constructor creates an empty bit buffer (length 0). | 
 | 	 */ | 
 | 	function BitBuffer() { | 
 | 		 | 
 | 		// Packs this buffer's bits into bytes in big endian, | 
 | 		// padding with '0' bit values, and returns the new array. | 
 | 		this.getBytes = function() { | 
 | 			var result = []; | 
 | 			while (result.length * 8 < this.length) | 
 | 				result.push(0); | 
 | 			this.forEach(function(bit, i) { | 
 | 				result[i >>> 3] |= bit << (7 - (i & 7)); | 
 | 			}); | 
 | 			return result; | 
 | 		}; | 
 | 		 | 
 | 		// Appends the given number of low bits of the given value | 
 | 		// to this sequence. Requires 0 <= val < 2^len. | 
 | 		this.appendBits = function(val, len) { | 
 | 			if (len < 0 || len > 31 || val >>> len != 0) | 
 | 				throw "Value out of range"; | 
 | 			for (var i = len - 1; i >= 0; i--)  // Append bit by bit | 
 | 				this.push((val >>> i) & 1); | 
 | 		}; | 
 | 	} | 
 | 	 | 
 | 	BitBuffer.prototype = Object.create(Array.prototype); | 
 | 	 | 
 | }; |