PluginProbe
Two Factor Authentication / 1.2.15
Two Factor Authentication v1.2.15
1.12.2 1.13.0 1.14.10 1.14.11 1.14.14 1.14.15 1.14.16 1.14.17 1.14.23 1.14.24 1.14.26 1.14.27 1.14.3 1.14.4 1.14.5 1.14.7 1.14.8 1.15.5 1.16.0 1.2.10 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 All 98 releases
two-factor-authentication / includes / jquery-qrcode / jquery.qrcode.js

jquery.qrcode.js in Two Factor Authentication 1.2.15, at includes/jquery-qrcode/jquery.qrcode.js

2,288 lines 63.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /* jQuery.qrcode 0.11.0 - http://larsjung.de/jquery-qrcode/ - uses //github.com/kazuhikoarase/qrcode-generator (MIT) */
2 (function () {
3 'use strict';
4
5 var $ = jQuery;
6
7 // Wrapper for the original QR code generator.
8 function QRCode(text, level, version, quiet) {
9
10 // `qrcode` is the single public function that will be defined by the `QR Code Generator`
11 // at the end of the file.
12 var qr = qrcode(version, level);
13 qr.addData(text);
14 qr.make();
15
16 quiet = quiet || 0;
17
18 var qrModuleCount = qr.getModuleCount();
19 var quietModuleCount = qr.getModuleCount() + 2*quiet;
20
21 function isDark(row, col) {
22
23 row -= quiet;
24 col -= quiet;
25
26 if (row < 0 || row >= qrModuleCount || col < 0 || col >= qrModuleCount) {
27 return false;
28 }
29
30 return qr.isDark(row, col);
31 }
32
33 var addBlank = function (l, t, r, b) {
34
35 var prevIsDark = this.isDark;
36 var moduleSize = 1 / quietModuleCount;
37
38 this.isDark = function (row, col) {
39
40 var ml = col * moduleSize;
41 var mt = row * moduleSize;
42 var mr = ml + moduleSize;
43 var mb = mt + moduleSize;
44
45 return prevIsDark(row, col) && (l > mr || ml > r || t > mb || mt > b);
46 };
47 };
48
49 this.text = text;
50 this.level = level;
51 this.version = version;
52 this.moduleCount = quietModuleCount;
53 this.isDark = isDark;
54 this.addBlank = addBlank;
55 }
56
57 // Check if canvas is available in the browser (as Modernizr does)
58 var hasCanvas = (function () {
59
60 var elem = document.createElement('canvas');
61 return !!(elem.getContext && elem.getContext('2d'));
62 }());
63 var hasArcTo = Object.prototype.toString.call(window.opera) !== '[object Opera]';
64
65 // Returns a minimal QR code for the given text starting with version `minVersion`.
66 // Returns `undefined` if `text` is too long to be encoded in `maxVersion`.
67 function createQRCode(text, level, minVersion, maxVersion, quiet) {
68
69 minVersion = Math.max(1, minVersion || 1);
70 maxVersion = Math.min(40, maxVersion || 40);
71 for (var version = minVersion; version <= maxVersion; version += 1) {
72 try {
73 return new QRCode(text, level, version, quiet);
74 } catch (err) {}
75 }
76 }
77
78 function drawBackgroundLabel(qr, context, settings) {
79
80 var size = settings.size;
81 var font = "bold " + (settings.mSize * size) + "px " + settings.fontname;
82 var ctx = $('<canvas/>')[0].getContext("2d");
83
84 ctx.font = font;
85
86 var w = ctx.measureText(settings.label).width;
87 var sh = settings.mSize;
88 var sw = w / size;
89 var sl = (1 - sw) * settings.mPosX;
90 var st = (1 - sh) * settings.mPosY;
91 var sr = sl + sw;
92 var sb = st + sh;
93 var pad = 0.01;
94
95 if (settings.mode === 1) {
96 // Strip
97 qr.addBlank(0, st - pad, size, sb + pad);
98 } else {
99 // Box
100 qr.addBlank(sl - pad, st - pad, sr + pad, sb + pad);
101 }
102
103 context.fillStyle = settings.fontcolor;
104 context.font = font;
105 context.fillText(settings.label, sl*size, st*size + 0.75 * settings.mSize * size);
106 }
107
108 function drawBackgroundImage(qr, context, settings) {
109
110 var size = settings.size;
111 var w = settings.image.naturalWidth || 1;
112 var h = settings.image.naturalHeight || 1;
113 var sh = settings.mSize;
114 var sw = sh * w / h;
115 var sl = (1 - sw) * settings.mPosX;
116 var st = (1 - sh) * settings.mPosY;
117 var sr = sl + sw;
118 var sb = st + sh;
119 var pad = 0.01;
120
121 if (settings.mode === 3) {
122 // Strip
123 qr.addBlank(0, st - pad, size, sb + pad);
124 } else {
125 // Box
126 qr.addBlank(sl - pad, st - pad, sr + pad, sb + pad);
127 }
128
129 context.drawImage(settings.image, sl*size, st*size, sw*size, sh*size);
130 }
131
132 function drawBackground(qr, context, settings) {
133
134 if ($(settings.background).is('img')) {
135 context.drawImage(settings.background, 0, 0, settings.size, settings.size);
136 } else if (settings.background) {
137 context.fillStyle = settings.background;
138 context.fillRect(settings.left, settings.top, settings.size, settings.size);
139 }
140
141 var mode = settings.mode;
142 if (mode === 1 || mode === 2) {
143 drawBackgroundLabel(qr, context, settings);
144 } else if (mode === 3 || mode === 4) {
145 drawBackgroundImage(qr, context, settings);
146 }
147 }
148
149 function drawModuleDefault(qr, context, settings, left, top, width, row, col) {
150
151 if (qr.isDark(row, col)) {
152 context.rect(left, top, width, width);
153 }
154 }
155
156 function drawModuleRoundedDark(ctx, l, t, r, b, rad, nw, ne, se, sw) {
157
158 if (nw) {
159 ctx.moveTo(l + rad, t);
160 } else {
161 ctx.moveTo(l, t);
162 }
163
164 if (ne) {
165 ctx.lineTo(r - rad, t);
166 ctx.arcTo(r, t, r, b, rad);
167 } else {
168 ctx.lineTo(r, t);
169 }
170
171 if (se) {
172 ctx.lineTo(r, b - rad);
173 ctx.arcTo(r, b, l, b, rad);
174 } else {
175 ctx.lineTo(r, b);
176 }
177
178 if (sw) {
179 ctx.lineTo(l + rad, b);
180 ctx.arcTo(l, b, l, t, rad);
181 } else {
182 ctx.lineTo(l, b);
183 }
184
185 if (nw) {
186 ctx.lineTo(l, t + rad);
187 ctx.arcTo(l, t, r, t, rad);
188 } else {
189 ctx.lineTo(l, t);
190 }
191 }
192
193 function drawModuleRoundendLight(ctx, l, t, r, b, rad, nw, ne, se, sw) {
194
195 if (nw) {
196 ctx.moveTo(l + rad, t);
197 ctx.lineTo(l, t);
198 ctx.lineTo(l, t + rad);
199 ctx.arcTo(l, t, l + rad, t, rad);
200 }
201
202 if (ne) {
203 ctx.moveTo(r - rad, t);
204 ctx.lineTo(r, t);
205 ctx.lineTo(r, t + rad);
206 ctx.arcTo(r, t, r - rad, t, rad);
207 }
208
209 if (se) {
210 ctx.moveTo(r - rad, b);
211 ctx.lineTo(r, b);
212 ctx.lineTo(r, b - rad);
213 ctx.arcTo(r, b, r - rad, b, rad);
214 }
215
216 if (sw) {
217 ctx.moveTo(l + rad, b);
218 ctx.lineTo(l, b);
219 ctx.lineTo(l, b - rad);
220 ctx.arcTo(l, b, l + rad, b, rad);
221 }
222 }
223
224 function drawModuleRounded(qr, context, settings, left, top, width, row, col) {
225
226 var isDark = qr.isDark;
227 var right = left + width;
228 var bottom = top + width;
229 var radius = settings.radius * width;
230 var rowT = row - 1;
231 var rowB = row + 1;
232 var colL = col - 1;
233 var colR = col + 1;
234 var center = isDark(row, col);
235 var northwest = isDark(rowT, colL);
236 var north = isDark(rowT, col);
237 var northeast = isDark(rowT, colR);
238 var east = isDark(row, colR);
239 var southeast = isDark(rowB, colR);
240 var south = isDark(rowB, col);
241 var southwest = isDark(rowB, colL);
242 var west = isDark(row, colL);
243
244 if (center) {
245 drawModuleRoundedDark(context, left, top, right, bottom, radius, !north && !west, !north && !east, !south && !east, !south && !west);
246 } else {
247 drawModuleRoundendLight(context, left, top, right, bottom, radius, north && west && northwest, north && east && northeast, south && east && southeast, south && west && southwest);
248 }
249 }
250
251 function drawModules(qr, context, settings) {
252
253 var moduleCount = qr.moduleCount;
254 var moduleSize = settings.size / moduleCount;
255 var fn = drawModuleDefault;
256 var row, col;
257
258 if (hasArcTo && settings.radius > 0 && settings.radius <= 0.5) {
259 fn = drawModuleRounded;
260 }
261
262 context.beginPath();
263 for (row = 0; row < moduleCount; row += 1) {
264 for (col = 0; col < moduleCount; col += 1) {
265
266 var l = settings.left + col * moduleSize,
267 t = settings.top + row * moduleSize,
268 w = moduleSize;
269
270 fn(qr, context, settings, l, t, w, row, col);
271 }
272 }
273 if ($(settings.fill).is('img')) {
274 context.strokeStyle = 'rgba(0,0,0,0.5)';
275 context.lineWidth = 2;
276 context.stroke();
277 var prev = context.globalCompositeOperation;
278 context.globalCompositeOperation = "destination-out";
279 context.fill();
280 context.globalCompositeOperation = prev;
281
282 context.clip();
283 context.drawImage(settings.fill, 0, 0, settings.size, settings.size);
284 context.restore();
285 } else {
286 context.fillStyle = settings.fill;
287 context.fill();
288 }
289 }
290
291 // Draws QR code to the given `canvas` and returns it.
292 function drawOnCanvas(canvas, settings) {
293
294 var qr = createQRCode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
295 if (!qr) {
296 return null;
297 }
298
299 var $canvas = $(canvas).data('qrcode', qr);
300 var context = $canvas[0].getContext('2d');
301
302 drawBackground(qr, context, settings);
303 drawModules(qr, context, settings);
304
305 return $canvas;
306 }
307
308 // Returns a `canvas` element representing the QR code for the given settings.
309 function createCanvas(settings) {
310
311 var $canvas = $('<canvas/>').attr('width', settings.size).attr('height', settings.size);
312 return drawOnCanvas($canvas, settings);
313 }
314
315 // Returns an `image` element representing the QR code for the given settings.
316 function createImage(settings) {
317
318 return $('<img/>').attr('src', createCanvas(settings)[0].toDataURL('image/png'));
319 }
320
321 // Returns a `div` element representing the QR code for the given settings.
322 function createDiv(settings) {
323
324 var qr = createQRCode(settings.text, settings.ecLevel, settings.minVersion, settings.maxVersion, settings.quiet);
325 if (!qr) {
326 return null;
327 }
328
329 // some shortcuts to improve compression
330 var settings_size = settings.size;
331 var settings_bgColor = settings.background;
332 var math_floor = Math.floor;
333
334 var moduleCount = qr.moduleCount;
335 var moduleSize = math_floor(settings_size / moduleCount);
336 var offset = math_floor(0.5 * (settings_size - moduleSize * moduleCount));
337
338 var row, col;
339
340 var containerCSS = {
341 position: 'relative',
342 left: 0,
343 top: 0,
344 padding: 0,
345 margin: 0,
346 width: settings_size,
347 height: settings_size
348 };
349 var darkCSS = {
350 position: 'absolute',
351 padding: 0,
352 margin: 0,
353 width: moduleSize,
354 height: moduleSize,
355 'background-color': settings.fill
356 };
357
358 var $div = $('<div/>').data('qrcode', qr).css(containerCSS);
359
360 if (settings_bgColor) {
361 $div.css('background-color', settings_bgColor);
362 }
363
364 for (row = 0; row < moduleCount; row += 1) {
365 for (col = 0; col < moduleCount; col += 1) {
366 if (qr.isDark(row, col)) {
367 $('<div/>')
368 .css(darkCSS)
369 .css({
370 left: offset + col * moduleSize,
371 top: offset + row * moduleSize
372 })
373 .appendTo($div);
374 }
375 }
376 }
377
378 return $div;
379 }
380
381 function createHTML(settings) {
382
383 if (hasCanvas && settings.render === 'canvas') {
384 return createCanvas(settings);
385 } else if (hasCanvas && settings.render === 'image') {
386 return createImage(settings);
387 }
388
389 return createDiv(settings);
390 }
391
392 // Plugin
393 // ======
394
395 // Default settings
396 // ----------------
397 var defaults = {
398
399 // render method: `'canvas'`, `'image'` or `'div'`
400 render: 'canvas',
401
402 // version range somewhere in 1 .. 40
403 minVersion: 1,
404 maxVersion: 40,
405
406 // error correction level: `'L'`, `'M'`, `'Q'` or `'H'`
407 ecLevel: 'L',
408
409 // offset in pixel if drawn onto existing canvas
410 left: 0,
411 top: 0,
412
413 // size in pixel
414 size: 200,
415
416 // code color or image element
417 fill: '#000',
418
419 // background color or image element, `null` for transparent background
420 background: null,
421
422 // content
423 text: 'no text',
424
425 // corner radius relative to module width: 0.0 .. 0.5
426 radius: 0,
427
428 // quiet zone in modules
429 quiet: 0,
430
431 // modes
432 // 0: normal
433 // 1: label strip
434 // 2: label box
435 // 3: image strip
436 // 4: image box
437 mode: 0,
438
439 mSize: 0.1,
440 mPosX: 0.5,
441 mPosY: 0.5,
442
443 label: 'no label',
444 fontname: 'sans',
445 fontcolor: '#000',
446
447 image: null
448 };
449
450 // Register the plugin
451 // -------------------
452 $.fn.qrcode = function(options) {
453
454 var settings = $.extend({}, defaults, options);
455
456 return this.each(function () {
457
458 if (this.nodeName.toLowerCase() === 'canvas') {
459 drawOnCanvas(this, settings);
460 } else {
461 $(this).append(createHTML(settings));
462 }
463 });
464 };
465
466 // jQuery.qrcode plug in code ends here
467
468
469 // QR Code Generator
470 // =================
471 //---------------------------------------------------------------------
472 //
473 // QR Code Generator for JavaScript
474 //
475 // Copyright (c) 2009 Kazuhiko Arase
476 //
477 // URL: http://www.d-project.com/
478 //
479 // Licensed under the MIT license:
480 // http://www.opensource.org/licenses/mit-license.php
481 //
482 // The word 'QR Code' is registered trademark of
483 // DENSO WAVE INCORPORATED
484 // http://www.denso-wave.com/qrcode/faqpatent-e.html
485 //
486 //---------------------------------------------------------------------
487
488 var qrcode = function() {
489
490 //---------------------------------------------------------------------
491 // qrcode
492 //---------------------------------------------------------------------
493
494 /**
495 * qrcode
496 * @param typeNumber 1 to 10
497 * @param errorCorrectLevel 'L','M','Q','H'
498 */
499 var qrcode = function(typeNumber, errorCorrectLevel) {
500
501 var PAD0 = 0xEC;
502 var PAD1 = 0x11;
503
504 var _typeNumber = typeNumber;
505 var _errorCorrectLevel = QRErrorCorrectLevel[errorCorrectLevel];
506 var _modules = null;
507 var _moduleCount = 0;
508 var _dataCache = null;
509 var _dataList = new Array();
510
511 var _this = {};
512
513 var makeImpl = function(test, maskPattern) {
514
515 _moduleCount = _typeNumber * 4 + 17;
516 _modules = function(moduleCount) {
517 var modules = new Array(moduleCount);
518 for (var row = 0; row < moduleCount; row += 1) {
519 modules[row] = new Array(moduleCount);
520 for (var col = 0; col < moduleCount; col += 1) {
521 modules[row][col] = null;
522 }
523 }
524 return modules;
525 }(_moduleCount);
526
527 setupPositionProbePattern(0, 0);
528 setupPositionProbePattern(_moduleCount - 7, 0);
529 setupPositionProbePattern(0, _moduleCount - 7);
530 setupPositionAdjustPattern();
531 setupTimingPattern();
532 setupTypeInfo(test, maskPattern);
533
534 if (_typeNumber >= 7) {
535 setupTypeNumber(test);
536 }
537
538 if (_dataCache == null) {
539 _dataCache = createData(_typeNumber, _errorCorrectLevel, _dataList);
540 }
541
542 mapData(_dataCache, maskPattern);
543 };
544
545 var setupPositionProbePattern = function(row, col) {
546
547 for (var r = -1; r <= 7; r += 1) {
548
549 if (row + r <= -1 || _moduleCount <= row + r) continue;
550
551 for (var c = -1; c <= 7; c += 1) {
552
553 if (col + c <= -1 || _moduleCount <= col + c) continue;
554
555 if ( (0 <= r && r <= 6 && (c == 0 || c == 6) )
556 || (0 <= c && c <= 6 && (r == 0 || r == 6) )
557 || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) {
558 _modules[row + r][col + c] = true;
559 } else {
560 _modules[row + r][col + c] = false;
561 }
562 }
563 }
564 };
565
566 var getBestMaskPattern = function() {
567
568 var minLostPoint = 0;
569 var pattern = 0;
570
571 for (var i = 0; i < 8; i += 1) {
572
573 makeImpl(true, i);
574
575 var lostPoint = QRUtil.getLostPoint(_this);
576
577 if (i == 0 || minLostPoint > lostPoint) {
578 minLostPoint = lostPoint;
579 pattern = i;
580 }
581 }
582
583 return pattern;
584 };
585
586 var setupTimingPattern = function() {
587
588 for (var r = 8; r < _moduleCount - 8; r += 1) {
589 if (_modules[r][6] != null) {
590 continue;
591 }
592 _modules[r][6] = (r % 2 == 0);
593 }
594
595 for (var c = 8; c < _moduleCount - 8; c += 1) {
596 if (_modules[6][c] != null) {
597 continue;
598 }
599 _modules[6][c] = (c % 2 == 0);
600 }
601 };
602
603 var setupPositionAdjustPattern = function() {
604
605 var pos = QRUtil.getPatternPosition(_typeNumber);
606
607 for (var i = 0; i < pos.length; i += 1) {
608
609 for (var j = 0; j < pos.length; j += 1) {
610
611 var row = pos[i];
612 var col = pos[j];
613
614 if (_modules[row][col] != null) {
615 continue;
616 }
617
618 for (var r = -2; r <= 2; r += 1) {
619
620 for (var c = -2; c <= 2; c += 1) {
621
622 if (r == -2 || r == 2 || c == -2 || c == 2
623 || (r == 0 && c == 0) ) {
624 _modules[row + r][col + c] = true;
625 } else {
626 _modules[row + r][col + c] = false;
627 }
628 }
629 }
630 }
631 }
632 };
633
634 var setupTypeNumber = function(test) {
635
636 var bits = QRUtil.getBCHTypeNumber(_typeNumber);
637
638 for (var i = 0; i < 18; i += 1) {
639 var mod = (!test && ( (bits >> i) & 1) == 1);
640 _modules[Math.floor(i / 3)][i % 3 + _moduleCount - 8 - 3] = mod;
641 }
642
643 for (var i = 0; i < 18; i += 1) {
644 var mod = (!test && ( (bits >> i) & 1) == 1);
645 _modules[i % 3 + _moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
646 }
647 };
648
649 var setupTypeInfo = function(test, maskPattern) {
650
651 var data = (_errorCorrectLevel << 3) | maskPattern;
652 var bits = QRUtil.getBCHTypeInfo(data);
653
654 // vertical
655 for (var i = 0; i < 15; i += 1) {
656
657 var mod = (!test && ( (bits >> i) & 1) == 1);
658
659 if (i < 6) {
660 _modules[i][8] = mod;
661 } else if (i < 8) {
662 _modules[i + 1][8] = mod;
663 } else {
664 _modules[_moduleCount - 15 + i][8] = mod;
665 }
666 }
667
668 // horizontal
669 for (var i = 0; i < 15; i += 1) {
670
671 var mod = (!test && ( (bits >> i) & 1) == 1);
672
673 if (i < 8) {
674 _modules[8][_moduleCount - i - 1] = mod;
675 } else if (i < 9) {
676 _modules[8][15 - i - 1 + 1] = mod;
677 } else {
678 _modules[8][15 - i - 1] = mod;
679 }
680 }
681
682 // fixed module
683 _modules[_moduleCount - 8][8] = (!test);
684 };
685
686 var mapData = function(data, maskPattern) {
687
688 var inc = -1;
689 var row = _moduleCount - 1;
690 var bitIndex = 7;
691 var byteIndex = 0;
692 var maskFunc = QRUtil.getMaskFunction(maskPattern);
693
694 for (var col = _moduleCount - 1; col > 0; col -= 2) {
695
696 if (col == 6) col -= 1;
697
698 while (true) {
699
700 for (var c = 0; c < 2; c += 1) {
701
702 if (_modules[row][col - c] == null) {
703
704 var dark = false;
705
706 if (byteIndex < data.length) {
707 dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1);
708 }
709
710 var mask = maskFunc(row, col - c);
711
712 if (mask) {
713 dark = !dark;
714 }
715
716 _modules[row][col - c] = dark;
717 bitIndex -= 1;
718
719 if (bitIndex == -1) {
720 byteIndex += 1;
721 bitIndex = 7;
722 }
723 }
724 }
725
726 row += inc;
727
728 if (row < 0 || _moduleCount <= row) {
729 row -= inc;
730 inc = -inc;
731 break;
732 }
733 }
734 }
735 };
736
737 var createBytes = function(buffer, rsBlocks) {
738
739 var offset = 0;
740
741 var maxDcCount = 0;
742 var maxEcCount = 0;
743
744 var dcdata = new Array(rsBlocks.length);
745 var ecdata = new Array(rsBlocks.length);
746
747 for (var r = 0; r < rsBlocks.length; r += 1) {
748
749 var dcCount = rsBlocks[r].dataCount;
750 var ecCount = rsBlocks[r].totalCount - dcCount;
751
752 maxDcCount = Math.max(maxDcCount, dcCount);
753 maxEcCount = Math.max(maxEcCount, ecCount);
754
755 dcdata[r] = new Array(dcCount);
756
757 for (var i = 0; i < dcdata[r].length; i += 1) {
758 dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset];
759 }
760 offset += dcCount;
761
762 var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
763 var rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1);
764
765 var modPoly = rawPoly.mod(rsPoly);
766 ecdata[r] = new Array(rsPoly.getLength() - 1);
767 for (var i = 0; i < ecdata[r].length; i += 1) {
768 var modIndex = i + modPoly.getLength() - ecdata[r].length;
769 ecdata[r][i] = (modIndex >= 0)? modPoly.get(modIndex) : 0;
770 }
771 }
772
773 var totalCodeCount = 0;
774 for (var i = 0; i < rsBlocks.length; i += 1) {
775 totalCodeCount += rsBlocks[i].totalCount;
776 }
777
778 var data = new Array(totalCodeCount);
779 var index = 0;
780
781 for (var i = 0; i < maxDcCount; i += 1) {
782 for (var r = 0; r < rsBlocks.length; r += 1) {
783 if (i < dcdata[r].length) {
784 data[index] = dcdata[r][i];
785 index += 1;
786 }
787 }
788 }
789
790 for (var i = 0; i < maxEcCount; i += 1) {
791 for (var r = 0; r < rsBlocks.length; r += 1) {
792 if (i < ecdata[r].length) {
793 data[index] = ecdata[r][i];
794 index += 1;
795 }
796 }
797 }
798
799 return data;
800 };
801
802 var createData = function(typeNumber, errorCorrectLevel, dataList) {
803
804 var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
805
806 var buffer = qrBitBuffer();
807
808 for (var i = 0; i < dataList.length; i += 1) {
809 var data = dataList[i];
810 buffer.put(data.getMode(), 4);
811 buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) );
812 data.write(buffer);
813 }
814
815 // calc num max data.
816 var totalDataCount = 0;
817 for (var i = 0; i < rsBlocks.length; i += 1) {
818 totalDataCount += rsBlocks[i].dataCount;
819 }
820
821 if (buffer.getLengthInBits() > totalDataCount * 8) {
822 throw new Error('code length overflow. ('
823 + buffer.getLengthInBits()
824 + '>'
825 + totalDataCount * 8
826 + ')');
827 }
828
829 // end code
830 if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
831 buffer.put(0, 4);
832 }
833
834 // padding
835 while (buffer.getLengthInBits() % 8 != 0) {
836 buffer.putBit(false);
837 }
838
839 // padding
840 while (true) {
841
842 if (buffer.getLengthInBits() >= totalDataCount * 8) {
843 break;
844 }
845 buffer.put(PAD0, 8);
846
847 if (buffer.getLengthInBits() >= totalDataCount * 8) {
848 break;
849 }
850 buffer.put(PAD1, 8);
851 }
852
853 return createBytes(buffer, rsBlocks);
854 };
855
856 _this.addData = function(data) {
857 var newData = qr8BitByte(data);
858 _dataList.push(newData);
859 _dataCache = null;
860 };
861
862 _this.isDark = function(row, col) {
863 if (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) {
864 throw new Error(row + ',' + col);
865 }
866 return _modules[row][col];
867 };
868
869 _this.getModuleCount = function() {
870 return _moduleCount;
871 };
872
873 _this.make = function() {
874 makeImpl(false, getBestMaskPattern() );
875 };
876
877 _this.createTableTag = function(cellSize, margin) {
878
879 cellSize = cellSize || 2;
880 margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
881
882 var qrHtml = '';
883
884 qrHtml += '<table style="';
885 qrHtml += ' border-width: 0px; border-style: none;';
886 qrHtml += ' border-collapse: collapse;';
887 qrHtml += ' padding: 0px; margin: ' + margin + 'px;';
888 qrHtml += '">';
889 qrHtml += '<tbody>';
890
891 for (var r = 0; r < _this.getModuleCount(); r += 1) {
892
893 qrHtml += '<tr>';
894
895 for (var c = 0; c < _this.getModuleCount(); c += 1) {
896 qrHtml += '<td style="';
897 qrHtml += ' border-width: 0px; border-style: none;';
898 qrHtml += ' border-collapse: collapse;';
899 qrHtml += ' padding: 0px; margin: 0px;';
900 qrHtml += ' width: ' + cellSize + 'px;';
901 qrHtml += ' height: ' + cellSize + 'px;';
902 qrHtml += ' background-color: ';
903 qrHtml += _this.isDark(r, c)? '#000000' : '#ffffff';
904 qrHtml += ';';
905 qrHtml += '"/>';
906 }
907
908 qrHtml += '</tr>';
909 }
910
911 qrHtml += '</tbody>';
912 qrHtml += '</table>';
913
914 return qrHtml;
915 };
916
917 _this.createImgTag = function(cellSize, margin) {
918
919 cellSize = cellSize || 2;
920 margin = (typeof margin == 'undefined')? cellSize * 4 : margin;
921
922 var size = _this.getModuleCount() * cellSize + margin * 2;
923 var min = margin;
924 var max = size - margin;
925
926 return createImgTag(size, size, function(x, y) {
927 if (min <= x && x < max && min <= y && y < max) {
928 var c = Math.floor( (x - min) / cellSize);
929 var r = Math.floor( (y - min) / cellSize);
930 return _this.isDark(r, c)? 0 : 1;
931 } else {
932 return 1;
933 }
934 } );
935 };
936
937 return _this;
938 };
939
940 //---------------------------------------------------------------------
941 // qrcode.stringToBytes
942 //---------------------------------------------------------------------
943
944 qrcode.stringToBytes = function(s) {
945 var bytes = new Array();
946 for (var i = 0; i < s.length; i += 1) {
947 var c = s.charCodeAt(i);
948 bytes.push(c & 0xff);
949 }
950 return bytes;
951 };
952
953 //---------------------------------------------------------------------
954 // qrcode.createStringToBytes
955 //---------------------------------------------------------------------
956
957 /**
958 * @param unicodeData base64 string of byte array.
959 * [16bit Unicode],[16bit Bytes], ...
960 * @param numChars
961 */
962 qrcode.createStringToBytes = function(unicodeData, numChars) {
963
964 // create conversion map.
965
966 var unicodeMap = function() {
967
968 var bin = base64DecodeInputStream(unicodeData);
969 var read = function() {
970 var b = bin.read();
971 if (b == -1) throw new Error();
972 return b;
973 };
974
975 var count = 0;
976 var unicodeMap = {};
977 while (true) {
978 var b0 = bin.read();
979 if (b0 == -1) break;
980 var b1 = read();
981 var b2 = read();
982 var b3 = read();
983 var k = String.fromCharCode( (b0 << 8) | b1);
984 var v = (b2 << 8) | b3;
985 unicodeMap[k] = v;
986 count += 1;
987 }
988 if (count != numChars) {
989 throw new Error(count + ' != ' + numChars);
990 }
991
992 return unicodeMap;
993 }();
994
995 var unknownChar = '?'.charCodeAt(0);
996
997 return function(s) {
998 var bytes = new Array();
999 for (var i = 0; i < s.length; i += 1) {
1000 var c = s.charCodeAt(i);
1001 if (c < 128) {
1002 bytes.push(c);
1003 } else {
1004 var b = unicodeMap[s.charAt(i)];
1005 if (typeof b == 'number') {
1006 if ( (b & 0xff) == b) {
1007 // 1byte
1008 bytes.push(b);
1009 } else {
1010 // 2bytes
1011 bytes.push(b >>> 8);
1012 bytes.push(b & 0xff);
1013 }
1014 } else {
1015 bytes.push(unknownChar);
1016 }
1017 }
1018 }
1019 return bytes;
1020 };
1021 };
1022
1023 //---------------------------------------------------------------------
1024 // QRMode
1025 //---------------------------------------------------------------------
1026
1027 var QRMode = {
1028 MODE_NUMBER : 1 << 0,
1029 MODE_ALPHA_NUM : 1 << 1,
1030 MODE_8BIT_BYTE : 1 << 2,
1031 MODE_KANJI : 1 << 3
1032 };
1033
1034 //---------------------------------------------------------------------
1035 // QRErrorCorrectLevel
1036 //---------------------------------------------------------------------
1037
1038 var QRErrorCorrectLevel = {
1039 L : 1,
1040 M : 0,
1041 Q : 3,
1042 H : 2
1043 };
1044
1045 //---------------------------------------------------------------------
1046 // QRMaskPattern
1047 //---------------------------------------------------------------------
1048
1049 var QRMaskPattern = {
1050 PATTERN000 : 0,
1051 PATTERN001 : 1,
1052 PATTERN010 : 2,
1053 PATTERN011 : 3,
1054 PATTERN100 : 4,
1055 PATTERN101 : 5,
1056 PATTERN110 : 6,
1057 PATTERN111 : 7
1058 };
1059
1060 //---------------------------------------------------------------------
1061 // QRUtil
1062 //---------------------------------------------------------------------
1063
1064 var QRUtil = function() {
1065
1066 var PATTERN_POSITION_TABLE = [
1067 [],
1068 [6, 18],
1069 [6, 22],
1070 [6, 26],
1071 [6, 30],
1072 [6, 34],
1073 [6, 22, 38],
1074 [6, 24, 42],
1075 [6, 26, 46],
1076 [6, 28, 50],
1077 [6, 30, 54],
1078 [6, 32, 58],
1079 [6, 34, 62],
1080 [6, 26, 46, 66],
1081 [6, 26, 48, 70],
1082 [6, 26, 50, 74],
1083 [6, 30, 54, 78],
1084 [6, 30, 56, 82],
1085 [6, 30, 58, 86],
1086 [6, 34, 62, 90],
1087 [6, 28, 50, 72, 94],
1088 [6, 26, 50, 74, 98],
1089 [6, 30, 54, 78, 102],
1090 [6, 28, 54, 80, 106],
1091 [6, 32, 58, 84, 110],
1092 [6, 30, 58, 86, 114],
1093 [6, 34, 62, 90, 118],
1094 [6, 26, 50, 74, 98, 122],
1095 [6, 30, 54, 78, 102, 126],
1096 [6, 26, 52, 78, 104, 130],
1097 [6, 30, 56, 82, 108, 134],
1098 [6, 34, 60, 86, 112, 138],
1099 [6, 30, 58, 86, 114, 142],
1100 [6, 34, 62, 90, 118, 146],
1101 [6, 30, 54, 78, 102, 126, 150],
1102 [6, 24, 50, 76, 102, 128, 154],
1103 [6, 28, 54, 80, 106, 132, 158],
1104 [6, 32, 58, 84, 110, 136, 162],
1105 [6, 26, 54, 82, 110, 138, 166],
1106 [6, 30, 58, 86, 114, 142, 170]
1107 ];
1108 var G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0);
1109 var G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0);
1110 var G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1);
1111
1112 var _this = {};
1113
1114 var getBCHDigit = function(data) {
1115 var digit = 0;
1116 while (data != 0) {
1117 digit += 1;
1118 data >>>= 1;
1119 }
1120 return digit;
1121 };
1122
1123 _this.getBCHTypeInfo = function(data) {
1124 var d = data << 10;
1125 while (getBCHDigit(d) - getBCHDigit(G15) >= 0) {
1126 d ^= (G15 << (getBCHDigit(d) - getBCHDigit(G15) ) );
1127 }
1128 return ( (data << 10) | d) ^ G15_MASK;
1129 };
1130
1131 _this.getBCHTypeNumber = function(data) {
1132 var d = data << 12;
1133 while (getBCHDigit(d) - getBCHDigit(G18) >= 0) {
1134 d ^= (G18 << (getBCHDigit(d) - getBCHDigit(G18) ) );
1135 }
1136 return (data << 12) | d;
1137 };
1138
1139 _this.getPatternPosition = function(typeNumber) {
1140 return PATTERN_POSITION_TABLE[typeNumber - 1];
1141 };
1142
1143 _this.getMaskFunction = function(maskPattern) {
1144
1145 switch (maskPattern) {
1146
1147 case QRMaskPattern.PATTERN000 :
1148 return function(i, j) { return (i + j) % 2 == 0; };
1149 case QRMaskPattern.PATTERN001 :
1150 return function(i, j) { return i % 2 == 0; };
1151 case QRMaskPattern.PATTERN010 :
1152 return function(i, j) { return j % 3 == 0; };
1153 case QRMaskPattern.PATTERN011 :
1154 return function(i, j) { return (i + j) % 3 == 0; };
1155 case QRMaskPattern.PATTERN100 :
1156 return function(i, j) { return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0; };
1157 case QRMaskPattern.PATTERN101 :
1158 return function(i, j) { return (i * j) % 2 + (i * j) % 3 == 0; };
1159 case QRMaskPattern.PATTERN110 :
1160 return function(i, j) { return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; };
1161 case QRMaskPattern.PATTERN111 :
1162 return function(i, j) { return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; };
1163
1164 default :
1165 throw new Error('bad maskPattern:' + maskPattern);
1166 }
1167 };
1168
1169 _this.getErrorCorrectPolynomial = function(errorCorrectLength) {
1170 var a = qrPolynomial([1], 0);
1171 for (var i = 0; i < errorCorrectLength; i += 1) {
1172 a = a.multiply(qrPolynomial([1, QRMath.gexp(i)], 0) );
1173 }
1174 return a;
1175 };
1176
1177 _this.getLengthInBits = function(mode, type) {
1178
1179 if (1 <= type && type < 10) {
1180
1181 // 1 - 9
1182
1183 switch(mode) {
1184 case QRMode.MODE_NUMBER : return 10;
1185 case QRMode.MODE_ALPHA_NUM : return 9;
1186 case QRMode.MODE_8BIT_BYTE : return 8;
1187 case QRMode.MODE_KANJI : return 8;
1188 default :
1189 throw new Error('mode:' + mode);
1190 }
1191
1192 } else if (type < 27) {
1193
1194 // 10 - 26
1195
1196 switch(mode) {
1197 case QRMode.MODE_NUMBER : return 12;
1198 case QRMode.MODE_ALPHA_NUM : return 11;
1199 case QRMode.MODE_8BIT_BYTE : return 16;
1200 case QRMode.MODE_KANJI : return 10;
1201 default :
1202 throw new Error('mode:' + mode);
1203 }
1204
1205 } else if (type < 41) {
1206
1207 // 27 - 40
1208
1209 switch(mode) {
1210 case QRMode.MODE_NUMBER : return 14;
1211 case QRMode.MODE_ALPHA_NUM : return 13;
1212 case QRMode.MODE_8BIT_BYTE : return 16;
1213 case QRMode.MODE_KANJI : return 12;
1214 default :
1215 throw new Error('mode:' + mode);
1216 }
1217
1218 } else {
1219 throw new Error('type:' + type);
1220 }
1221 };
1222
1223 _this.getLostPoint = function(qrcode) {
1224
1225 var moduleCount = qrcode.getModuleCount();
1226
1227 var lostPoint = 0;
1228
1229 // LEVEL1
1230
1231 for (var row = 0; row < moduleCount; row += 1) {
1232 for (var col = 0; col < moduleCount; col += 1) {
1233
1234 var sameCount = 0;
1235 var dark = qrcode.isDark(row, col);
1236
1237 for (var r = -1; r <= 1; r += 1) {
1238
1239 if (row + r < 0 || moduleCount <= row + r) {
1240 continue;
1241 }
1242
1243 for (var c = -1; c <= 1; c += 1) {
1244
1245 if (col + c < 0 || moduleCount <= col + c) {
1246 continue;
1247 }
1248
1249 if (r == 0 && c == 0) {
1250 continue;
1251 }
1252
1253 if (dark == qrcode.isDark(row + r, col + c) ) {
1254 sameCount += 1;
1255 }
1256 }
1257 }
1258
1259 if (sameCount > 5) {
1260 lostPoint += (3 + sameCount - 5);
1261 }
1262 }
1263 };
1264
1265 // LEVEL2
1266
1267 for (var row = 0; row < moduleCount - 1; row += 1) {
1268 for (var col = 0; col < moduleCount - 1; col += 1) {
1269 var count = 0;
1270 if (qrcode.isDark(row, col) ) count += 1;
1271 if (qrcode.isDark(row + 1, col) ) count += 1;
1272 if (qrcode.isDark(row, col + 1) ) count += 1;
1273 if (qrcode.isDark(row + 1, col + 1) ) count += 1;
1274 if (count == 0 || count == 4) {
1275 lostPoint += 3;
1276 }
1277 }
1278 }
1279
1280 // LEVEL3
1281
1282 for (var row = 0; row < moduleCount; row += 1) {
1283 for (var col = 0; col < moduleCount - 6; col += 1) {
1284 if (qrcode.isDark(row, col)
1285 && !qrcode.isDark(row, col + 1)
1286 && qrcode.isDark(row, col + 2)
1287 && qrcode.isDark(row, col + 3)
1288 && qrcode.isDark(row, col + 4)
1289 && !qrcode.isDark(row, col + 5)
1290 && qrcode.isDark(row, col + 6) ) {
1291 lostPoint += 40;
1292 }
1293 }
1294 }
1295
1296 for (var col = 0; col < moduleCount; col += 1) {
1297 for (var row = 0; row < moduleCount - 6; row += 1) {
1298 if (qrcode.isDark(row, col)
1299 && !qrcode.isDark(row + 1, col)
1300 && qrcode.isDark(row + 2, col)
1301 && qrcode.isDark(row + 3, col)
1302 && qrcode.isDark(row + 4, col)
1303 && !qrcode.isDark(row + 5, col)
1304 && qrcode.isDark(row + 6, col) ) {
1305 lostPoint += 40;
1306 }
1307 }
1308 }
1309
1310 // LEVEL4
1311
1312 var darkCount = 0;
1313
1314 for (var col = 0; col < moduleCount; col += 1) {
1315 for (var row = 0; row < moduleCount; row += 1) {
1316 if (qrcode.isDark(row, col) ) {
1317 darkCount += 1;
1318 }
1319 }
1320 }
1321
1322 var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
1323 lostPoint += ratio * 10;
1324
1325 return lostPoint;
1326 };
1327
1328 return _this;
1329 }();
1330
1331 //---------------------------------------------------------------------
1332 // QRMath
1333 //---------------------------------------------------------------------
1334
1335 var QRMath = function() {
1336
1337 var EXP_TABLE = new Array(256);
1338 var LOG_TABLE = new Array(256);
1339
1340 // initialize tables
1341 for (var i = 0; i < 8; i += 1) {
1342 EXP_TABLE[i] = 1 << i;
1343 }
1344 for (var i = 8; i < 256; i += 1) {
1345 EXP_TABLE[i] = EXP_TABLE[i - 4]
1346 ^ EXP_TABLE[i - 5]
1347 ^ EXP_TABLE[i - 6]
1348 ^ EXP_TABLE[i - 8];
1349 }
1350 for (var i = 0; i < 255; i += 1) {
1351 LOG_TABLE[EXP_TABLE[i] ] = i;
1352 }
1353
1354 var _this = {};
1355
1356 _this.glog = function(n) {
1357
1358 if (n < 1) {
1359 throw new Error('glog(' + n + ')');
1360 }
1361
1362 return LOG_TABLE[n];
1363 };
1364
1365 _this.gexp = function(n) {
1366
1367 while (n < 0) {
1368 n += 255;
1369 }
1370
1371 while (n >= 256) {
1372 n -= 255;
1373 }
1374
1375 return EXP_TABLE[n];
1376 };
1377
1378 return _this;
1379 }();
1380
1381 //---------------------------------------------------------------------
1382 // qrPolynomial
1383 //---------------------------------------------------------------------
1384
1385 function qrPolynomial(num, shift) {
1386
1387 if (typeof num.length == 'undefined') {
1388 throw new Error(num.length + '/' + shift);
1389 }
1390
1391 var _num = function() {
1392 var offset = 0;
1393 while (offset < num.length && num[offset] == 0) {
1394 offset += 1;
1395 }
1396 var _num = new Array(num.length - offset + shift);
1397 for (var i = 0; i < num.length - offset; i += 1) {
1398 _num[i] = num[i + offset];
1399 }
1400 return _num;
1401 }();
1402
1403 var _this = {};
1404
1405 _this.get = function(index) {
1406 return _num[index];
1407 };
1408
1409 _this.getLength = function() {
1410 return _num.length;
1411 };
1412
1413 _this.multiply = function(e) {
1414
1415 var num = new Array(_this.getLength() + e.getLength() - 1);
1416
1417 for (var i = 0; i < _this.getLength(); i += 1) {
1418 for (var j = 0; j < e.getLength(); j += 1) {
1419 num[i + j] ^= QRMath.gexp(QRMath.glog(_this.get(i) ) + QRMath.glog(e.get(j) ) );
1420 }
1421 }
1422
1423 return qrPolynomial(num, 0);
1424 };
1425
1426 _this.mod = function(e) {
1427
1428 if (_this.getLength() - e.getLength() < 0) {
1429 return _this;
1430 }
1431
1432 var ratio = QRMath.glog(_this.get(0) ) - QRMath.glog(e.get(0) );
1433
1434 var num = new Array(_this.getLength() );
1435 for (var i = 0; i < _this.getLength(); i += 1) {
1436 num[i] = _this.get(i);
1437 }
1438
1439 for (var i = 0; i < e.getLength(); i += 1) {
1440 num[i] ^= QRMath.gexp(QRMath.glog(e.get(i) ) + ratio);
1441 }
1442
1443 // recursive call
1444 return qrPolynomial(num, 0).mod(e);
1445 };
1446
1447 return _this;
1448 };
1449
1450 //---------------------------------------------------------------------
1451 // QRRSBlock
1452 //---------------------------------------------------------------------
1453
1454 var QRRSBlock = function() {
1455
1456 var RS_BLOCK_TABLE = [
1457
1458 // L
1459 // M
1460 // Q
1461 // H
1462
1463 // 1
1464 [1, 26, 19],
1465 [1, 26, 16],
1466 [1, 26, 13],
1467 [1, 26, 9],
1468
1469 // 2
1470 [1, 44, 34],
1471 [1, 44, 28],
1472 [1, 44, 22],
1473 [1, 44, 16],
1474
1475 // 3
1476 [1, 70, 55],
1477 [1, 70, 44],
1478 [2, 35, 17],
1479 [2, 35, 13],
1480
1481 // 4
1482 [1, 100, 80],
1483 [2, 50, 32],
1484 [2, 50, 24],
1485 [4, 25, 9],
1486
1487 // 5
1488 [1, 134, 108],
1489 [2, 67, 43],
1490 [2, 33, 15, 2, 34, 16],
1491 [2, 33, 11, 2, 34, 12],
1492
1493 // 6
1494 [2, 86, 68],
1495 [4, 43, 27],
1496 [4, 43, 19],
1497 [4, 43, 15],
1498
1499 // 7
1500 [2, 98, 78],
1501 [4, 49, 31],
1502 [2, 32, 14, 4, 33, 15],
1503 [4, 39, 13, 1, 40, 14],
1504
1505 // 8
1506 [2, 121, 97],
1507 [2, 60, 38, 2, 61, 39],
1508 [4, 40, 18, 2, 41, 19],
1509 [4, 40, 14, 2, 41, 15],
1510
1511 // 9
1512 [2, 146, 116],
1513 [3, 58, 36, 2, 59, 37],
1514 [4, 36, 16, 4, 37, 17],
1515 [4, 36, 12, 4, 37, 13],
1516
1517 // 10
1518 [2, 86, 68, 2, 87, 69],
1519 [4, 69, 43, 1, 70, 44],
1520 [6, 43, 19, 2, 44, 20],
1521 [6, 43, 15, 2, 44, 16],
1522
1523 // 11
1524 [4, 101, 81],
1525 [1, 80, 50, 4, 81, 51],
1526 [4, 50, 22, 4, 51, 23],
1527 [3, 36, 12, 8, 37, 13],
1528
1529 // 12
1530 [2, 116, 92, 2, 117, 93],
1531 [6, 58, 36, 2, 59, 37],
1532 [4, 46, 20, 6, 47, 21],
1533 [7, 42, 14, 4, 43, 15],
1534
1535 // 13
1536 [4, 133, 107],
1537 [8, 59, 37, 1, 60, 38],
1538 [8, 44, 20, 4, 45, 21],
1539 [12, 33, 11, 4, 34, 12],
1540
1541 // 14
1542 [3, 145, 115, 1, 146, 116],
1543 [4, 64, 40, 5, 65, 41],
1544 [11, 36, 16, 5, 37, 17],
1545 [11, 36, 12, 5, 37, 13],
1546
1547 // 15
1548 [5, 109, 87, 1, 110, 88],
1549 [5, 65, 41, 5, 66, 42],
1550 [5, 54, 24, 7, 55, 25],
1551 [11, 36, 12],
1552
1553 // 16
1554 [5, 122, 98, 1, 123, 99],
1555 [7, 73, 45, 3, 74, 46],
1556 [15, 43, 19, 2, 44, 20],
1557 [3, 45, 15, 13, 46, 16],
1558
1559 // 17
1560 [1, 135, 107, 5, 136, 108],
1561 [10, 74, 46, 1, 75, 47],
1562 [1, 50, 22, 15, 51, 23],
1563 [2, 42, 14, 17, 43, 15],
1564
1565 // 18
1566 [5, 150, 120, 1, 151, 121],
1567 [9, 69, 43, 4, 70, 44],
1568 [17, 50, 22, 1, 51, 23],
1569 [2, 42, 14, 19, 43, 15],
1570
1571 // 19
1572 [3, 141, 113, 4, 142, 114],
1573 [3, 70, 44, 11, 71, 45],
1574 [17, 47, 21, 4, 48, 22],
1575 [9, 39, 13, 16, 40, 14],
1576
1577 // 20
1578 [3, 135, 107, 5, 136, 108],
1579 [3, 67, 41, 13, 68, 42],
1580 [15, 54, 24, 5, 55, 25],
1581 [15, 43, 15, 10, 44, 16],
1582
1583 // 21
1584 [4, 144, 116, 4, 145, 117],
1585 [17, 68, 42],
1586 [17, 50, 22, 6, 51, 23],
1587 [19, 46, 16, 6, 47, 17],
1588
1589 // 22
1590 [2, 139, 111, 7, 140, 112],
1591 [17, 74, 46],
1592 [7, 54, 24, 16, 55, 25],
1593 [34, 37, 13],
1594
1595 // 23
1596 [4, 151, 121, 5, 152, 122],
1597 [4, 75, 47, 14, 76, 48],
1598 [11, 54, 24, 14, 55, 25],
1599 [16, 45, 15, 14, 46, 16],
1600
1601 // 24
1602 [6, 147, 117, 4, 148, 118],
1603 [6, 73, 45, 14, 74, 46],
1604 [11, 54, 24, 16, 55, 25],
1605 [30, 46, 16, 2, 47, 17],
1606
1607 // 25
1608 [8, 132, 106, 4, 133, 107],
1609 [8, 75, 47, 13, 76, 48],
1610 [7, 54, 24, 22, 55, 25],
1611 [22, 45, 15, 13, 46, 16],
1612
1613 // 26
1614 [10, 142, 114, 2, 143, 115],
1615 [19, 74, 46, 4, 75, 47],
1616 [28, 50, 22, 6, 51, 23],
1617 [33, 46, 16, 4, 47, 17],
1618
1619 // 27
1620 [8, 152, 122, 4, 153, 123],
1621 [22, 73, 45, 3, 74, 46],
1622 [8, 53, 23, 26, 54, 24],
1623 [12, 45, 15, 28, 46, 16],
1624
1625 // 28
1626 [3, 147, 117, 10, 148, 118],
1627 [3, 73, 45, 23, 74, 46],
1628 [4, 54, 24, 31, 55, 25],
1629 [11, 45, 15, 31, 46, 16],
1630
1631 // 29
1632 [7, 146, 116, 7, 147, 117],
1633 [21, 73, 45, 7, 74, 46],
1634 [1, 53, 23, 37, 54, 24],
1635 [19, 45, 15, 26, 46, 16],
1636
1637 // 30
1638 [5, 145, 115, 10, 146, 116],
1639 [19, 75, 47, 10, 76, 48],
1640 [15, 54, 24, 25, 55, 25],
1641 [23, 45, 15, 25, 46, 16],
1642
1643 // 31
1644 [13, 145, 115, 3, 146, 116],
1645 [2, 74, 46, 29, 75, 47],
1646 [42, 54, 24, 1, 55, 25],
1647 [23, 45, 15, 28, 46, 16],
1648
1649 // 32
1650 [17, 145, 115],
1651 [10, 74, 46, 23, 75, 47],
1652 [10, 54, 24, 35, 55, 25],
1653 [19, 45, 15, 35, 46, 16],
1654
1655 // 33
1656 [17, 145, 115, 1, 146, 116],
1657 [14, 74, 46, 21, 75, 47],
1658 [29, 54, 24, 19, 55, 25],
1659 [11, 45, 15, 46, 46, 16],
1660
1661 // 34
1662 [13, 145, 115, 6, 146, 116],
1663 [14, 74, 46, 23, 75, 47],
1664 [44, 54, 24, 7, 55, 25],
1665 [59, 46, 16, 1, 47, 17],
1666
1667 // 35
1668 [12, 151, 121, 7, 152, 122],
1669 [12, 75, 47, 26, 76, 48],
1670 [39, 54, 24, 14, 55, 25],
1671 [22, 45, 15, 41, 46, 16],
1672
1673 // 36
1674 [6, 151, 121, 14, 152, 122],
1675 [6, 75, 47, 34, 76, 48],
1676 [46, 54, 24, 10, 55, 25],
1677 [2, 45, 15, 64, 46, 16],
1678
1679 // 37
1680 [17, 152, 122, 4, 153, 123],
1681 [29, 74, 46, 14, 75, 47],
1682 [49, 54, 24, 10, 55, 25],
1683 [24, 45, 15, 46, 46, 16],
1684
1685 // 38
1686 [4, 152, 122, 18, 153, 123],
1687 [13, 74, 46, 32, 75, 47],
1688 [48, 54, 24, 14, 55, 25],
1689 [42, 45, 15, 32, 46, 16],
1690
1691 // 39
1692 [20, 147, 117, 4, 148, 118],
1693 [40, 75, 47, 7, 76, 48],
1694 [43, 54, 24, 22, 55, 25],
1695 [10, 45, 15, 67, 46, 16],
1696
1697 // 40
1698 [19, 148, 118, 6, 149, 119],
1699 [18, 75, 47, 31, 76, 48],
1700 [34, 54, 24, 34, 55, 25],
1701 [20, 45, 15, 61, 46, 16]
1702 ];
1703
1704 var qrRSBlock = function(totalCount, dataCount) {
1705 var _this = {};
1706 _this.totalCount = totalCount;
1707 _this.dataCount = dataCount;
1708 return _this;
1709 };
1710
1711 var _this = {};
1712
1713 var getRsBlockTable = function(typeNumber, errorCorrectLevel) {
1714
1715 switch(errorCorrectLevel) {
1716 case QRErrorCorrectLevel.L :
1717 return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
1718 case QRErrorCorrectLevel.M :
1719 return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
1720 case QRErrorCorrectLevel.Q :
1721 return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
1722 case QRErrorCorrectLevel.H :
1723 return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
1724 default :
1725 return undefined;
1726 }
1727 };
1728
1729 _this.getRSBlocks = function(typeNumber, errorCorrectLevel) {
1730
1731 var rsBlock = getRsBlockTable(typeNumber, errorCorrectLevel);
1732
1733 if (typeof rsBlock == 'undefined') {
1734 throw new Error('bad rs block @ typeNumber:' + typeNumber +
1735 '/errorCorrectLevel:' + errorCorrectLevel);
1736 }
1737
1738 var length = rsBlock.length / 3;
1739
1740 var list = new Array();
1741
1742 for (var i = 0; i < length; i += 1) {
1743
1744 var count = rsBlock[i * 3 + 0];
1745 var totalCount = rsBlock[i * 3 + 1];
1746 var dataCount = rsBlock[i * 3 + 2];
1747
1748 for (var j = 0; j < count; j += 1) {
1749 list.push(qrRSBlock(totalCount, dataCount) );
1750 }
1751 }
1752
1753 return list;
1754 };
1755
1756 return _this;
1757 }();
1758
1759 //---------------------------------------------------------------------
1760 // qrBitBuffer
1761 //---------------------------------------------------------------------
1762
1763 var qrBitBuffer = function() {
1764
1765 var _buffer = new Array();
1766 var _length = 0;
1767
1768 var _this = {};
1769
1770 _this.getBuffer = function() {
1771 return _buffer;
1772 };
1773
1774 _this.get = function(index) {
1775 var bufIndex = Math.floor(index / 8);
1776 return ( (_buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1;
1777 };
1778
1779 _this.put = function(num, length) {
1780 for (var i = 0; i < length; i += 1) {
1781 _this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1);
1782 }
1783 };
1784
1785 _this.getLengthInBits = function() {
1786 return _length;
1787 };
1788
1789 _this.putBit = function(bit) {
1790
1791 var bufIndex = Math.floor(_length / 8);
1792 if (_buffer.length <= bufIndex) {
1793 _buffer.push(0);
1794 }
1795
1796 if (bit) {
1797 _buffer[bufIndex] |= (0x80 >>> (_length % 8) );
1798 }
1799
1800 _length += 1;
1801 };
1802
1803 return _this;
1804 };
1805
1806 //---------------------------------------------------------------------
1807 // qr8BitByte
1808 //---------------------------------------------------------------------
1809
1810 var qr8BitByte = function(data) {
1811
1812 var _mode = QRMode.MODE_8BIT_BYTE;
1813 var _data = data;
1814 var _bytes = qrcode.stringToBytes(data);
1815
1816 var _this = {};
1817
1818 _this.getMode = function() {
1819 return _mode;
1820 };
1821
1822 _this.getLength = function(buffer) {
1823 return _bytes.length;
1824 };
1825
1826 _this.write = function(buffer) {
1827 for (var i = 0; i < _bytes.length; i += 1) {
1828 buffer.put(_bytes[i], 8);
1829 }
1830 };
1831
1832 return _this;
1833 };
1834
1835 //=====================================================================
1836 // GIF Support etc.
1837 //
1838
1839 //---------------------------------------------------------------------
1840 // byteArrayOutputStream
1841 //---------------------------------------------------------------------
1842
1843 var byteArrayOutputStream = function() {
1844
1845 var _bytes = new Array();
1846
1847 var _this = {};
1848
1849 _this.writeByte = function(b) {
1850 _bytes.push(b & 0xff);
1851 };
1852
1853 _this.writeShort = function(i) {
1854 _this.writeByte(i);
1855 _this.writeByte(i >>> 8);
1856 };
1857
1858 _this.writeBytes = function(b, off, len) {
1859 off = off || 0;
1860 len = len || b.length;
1861 for (var i = 0; i < len; i += 1) {
1862 _this.writeByte(b[i + off]);
1863 }
1864 };
1865
1866 _this.writeString = function(s) {
1867 for (var i = 0; i < s.length; i += 1) {
1868 _this.writeByte(s.charCodeAt(i) );
1869 }
1870 };
1871
1872 _this.toByteArray = function() {
1873 return _bytes;
1874 };
1875
1876 _this.toString = function() {
1877 var s = '';
1878 s += '[';
1879 for (var i = 0; i < _bytes.length; i += 1) {
1880 if (i > 0) {
1881 s += ',';
1882 }
1883 s += _bytes[i];
1884 }
1885 s += ']';
1886 return s;
1887 };
1888
1889 return _this;
1890 };
1891
1892 //---------------------------------------------------------------------
1893 // base64EncodeOutputStream
1894 //---------------------------------------------------------------------
1895
1896 var base64EncodeOutputStream = function() {
1897
1898 var _buffer = 0;
1899 var _buflen = 0;
1900 var _length = 0;
1901 var _base64 = '';
1902
1903 var _this = {};
1904
1905 var writeEncoded = function(b) {
1906 _base64 += String.fromCharCode(encode(b & 0x3f) );
1907 };
1908
1909 var encode = function(n) {
1910 if (n < 0) {
1911 // error.
1912 } else if (n < 26) {
1913 return 0x41 + n;
1914 } else if (n < 52) {
1915 return 0x61 + (n - 26);
1916 } else if (n < 62) {
1917 return 0x30 + (n - 52);
1918 } else if (n == 62) {
1919 return 0x2b;
1920 } else if (n == 63) {
1921 return 0x2f;
1922 }
1923 throw new Error('n:' + n);
1924 };
1925
1926 _this.writeByte = function(n) {
1927
1928 _buffer = (_buffer << 8) | (n & 0xff);
1929 _buflen += 8;
1930 _length += 1;
1931
1932 while (_buflen >= 6) {
1933 writeEncoded(_buffer >>> (_buflen - 6) );
1934 _buflen -= 6;
1935 }
1936 };
1937
1938 _this.flush = function() {
1939
1940 if (_buflen > 0) {
1941 writeEncoded(_buffer << (6 - _buflen) );
1942 _buffer = 0;
1943 _buflen = 0;
1944 }
1945
1946 if (_length % 3 != 0) {
1947 // padding
1948 var padlen = 3 - _length % 3;
1949 for (var i = 0; i < padlen; i += 1) {
1950 _base64 += '=';
1951 }
1952 }
1953 };
1954
1955 _this.toString = function() {
1956 return _base64;
1957 };
1958
1959 return _this;
1960 };
1961
1962 //---------------------------------------------------------------------
1963 // base64DecodeInputStream
1964 //---------------------------------------------------------------------
1965
1966 var base64DecodeInputStream = function(str) {
1967
1968 var _str = str;
1969 var _pos = 0;
1970 var _buffer = 0;
1971 var _buflen = 0;
1972
1973 var _this = {};
1974
1975 _this.read = function() {
1976
1977 while (_buflen < 8) {
1978
1979 if (_pos >= _str.length) {
1980 if (_buflen == 0) {
1981 return -1;
1982 }
1983 throw new Error('unexpected end of file./' + _buflen);
1984 }
1985
1986 var c = _str.charAt(_pos);
1987 _pos += 1;
1988
1989 if (c == '=') {
1990 _buflen = 0;
1991 return -1;
1992 } else if (c.match(/^\s$/) ) {
1993 // ignore if whitespace.
1994 continue;
1995 }
1996
1997 _buffer = (_buffer << 6) | decode(c.charCodeAt(0) );
1998 _buflen += 6;
1999 }
2000
2001 var n = (_buffer >>> (_buflen - 8) ) & 0xff;
2002 _buflen -= 8;
2003 return n;
2004 };
2005
2006 var decode = function(c) {
2007 if (0x41 <= c && c <= 0x5a) {
2008 return c - 0x41;
2009 } else if (0x61 <= c && c <= 0x7a) {
2010 return c - 0x61 + 26;
2011 } else if (0x30 <= c && c <= 0x39) {
2012 return c - 0x30 + 52;
2013 } else if (c == 0x2b) {
2014 return 62;
2015 } else if (c == 0x2f) {
2016 return 63;
2017 } else {
2018 throw new Error('c:' + c);
2019 }
2020 };
2021
2022 return _this;
2023 };
2024
2025 //---------------------------------------------------------------------
2026 // gifImage (B/W)
2027 //---------------------------------------------------------------------
2028
2029 var gifImage = function(width, height) {
2030
2031 var _width = width;
2032 var _height = height;
2033 var _data = new Array(width * height);
2034
2035 var _this = {};
2036
2037 _this.setPixel = function(x, y, pixel) {
2038 _data[y * _width + x] = pixel;
2039 };
2040
2041 _this.write = function(out) {
2042
2043 //---------------------------------
2044 // GIF Signature
2045
2046 out.writeString('GIF87a');
2047
2048 //---------------------------------
2049 // Screen Descriptor
2050
2051 out.writeShort(_width);
2052 out.writeShort(_height);
2053
2054 out.writeByte(0x80); // 2bit
2055 out.writeByte(0);
2056 out.writeByte(0);
2057
2058 //---------------------------------
2059 // Global Color Map
2060
2061 // black
2062 out.writeByte(0x00);
2063 out.writeByte(0x00);
2064 out.writeByte(0x00);
2065
2066 // white
2067 out.writeByte(0xff);
2068 out.writeByte(0xff);
2069 out.writeByte(0xff);
2070
2071 //---------------------------------
2072 // Image Descriptor
2073
2074 out.writeString(',');
2075 out.writeShort(0);
2076 out.writeShort(0);
2077 out.writeShort(_width);
2078 out.writeShort(_height);
2079 out.writeByte(0);
2080
2081 //---------------------------------
2082 // Local Color Map
2083
2084 //---------------------------------
2085 // Raster Data
2086
2087 var lzwMinCodeSize = 2;
2088 var raster = getLZWRaster(lzwMinCodeSize);
2089
2090 out.writeByte(lzwMinCodeSize);
2091
2092 var offset = 0;
2093
2094 while (raster.length - offset > 255) {
2095 out.writeByte(255);
2096 out.writeBytes(raster, offset, 255);
2097 offset += 255;
2098 }
2099
2100 out.writeByte(raster.length - offset);
2101 out.writeBytes(raster, offset, raster.length - offset);
2102 out.writeByte(0x00);
2103
2104 //---------------------------------
2105 // GIF Terminator
2106 out.writeString(';');
2107 };
2108
2109 var bitOutputStream = function(out) {
2110
2111 var _out = out;
2112 var _bitLength = 0;
2113 var _bitBuffer = 0;
2114
2115 var _this = {};
2116
2117 _this.write = function(data, length) {
2118
2119 if ( (data >>> length) != 0) {
2120 throw new Error('length over');
2121 }
2122
2123 while (_bitLength + length >= 8) {
2124 _out.writeByte(0xff & ( (data << _bitLength) | _bitBuffer) );
2125 length -= (8 - _bitLength);
2126 data >>>= (8 - _bitLength);
2127 _bitBuffer = 0;
2128 _bitLength = 0;
2129 }
2130
2131 _bitBuffer = (data << _bitLength) | _bitBuffer;
2132 _bitLength = _bitLength + length;
2133 };
2134
2135 _this.flush = function() {
2136 if (_bitLength > 0) {
2137 _out.writeByte(_bitBuffer);
2138 }
2139 };
2140
2141 return _this;
2142 };
2143
2144 var getLZWRaster = function(lzwMinCodeSize) {
2145
2146 var clearCode = 1 << lzwMinCodeSize;
2147 var endCode = (1 << lzwMinCodeSize) + 1;
2148 var bitLength = lzwMinCodeSize + 1;
2149
2150 // Setup LZWTable
2151 var table = lzwTable();
2152
2153 for (var i = 0; i < clearCode; i += 1) {
2154 table.add(String.fromCharCode(i) );
2155 }
2156 table.add(String.fromCharCode(clearCode) );
2157 table.add(String.fromCharCode(endCode) );
2158
2159 var byteOut = byteArrayOutputStream();
2160 var bitOut = bitOutputStream(byteOut);
2161
2162 // clear code
2163 bitOut.write(clearCode, bitLength);
2164
2165 var dataIndex = 0;
2166
2167 var s = String.fromCharCode(_data[dataIndex]);
2168 dataIndex += 1;
2169
2170 while (dataIndex < _data.length) {
2171
2172 var c = String.fromCharCode(_data[dataIndex]);
2173 dataIndex += 1;
2174
2175 if (table.contains(s + c) ) {
2176
2177 s = s + c;
2178
2179 } else {
2180
2181 bitOut.write(table.indexOf(s), bitLength);
2182
2183 if (table.size() < 0xfff) {
2184
2185 if (table.size() == (1 << bitLength) ) {
2186 bitLength += 1;
2187 }
2188
2189 table.add(s + c);
2190 }
2191
2192 s = c;
2193 }
2194 }
2195
2196 bitOut.write(table.indexOf(s), bitLength);
2197
2198 // end code
2199 bitOut.write(endCode, bitLength);
2200
2201 bitOut.flush();
2202
2203 return byteOut.toByteArray();
2204 };
2205
2206 var lzwTable = function() {
2207
2208 var _map = {};
2209 var _size = 0;
2210
2211 var _this = {};
2212
2213 _this.add = function(key) {
2214 if (_this.contains(key) ) {
2215 throw new Error('dup key:' + key);
2216 }
2217 _map[key] = _size;
2218 _size += 1;
2219 };
2220
2221 _this.size = function() {
2222 return _size;
2223 };
2224
2225 _this.indexOf = function(key) {
2226 return _map[key];
2227 };
2228
2229 _this.contains = function(key) {
2230 return typeof _map[key] != 'undefined';
2231 };
2232
2233 return _this;
2234 };
2235
2236 return _this;
2237 };
2238
2239 var createImgTag = function(width, height, getPixel, alt) {
2240
2241 var gif = gifImage(width, height);
2242 for (var y = 0; y < height; y += 1) {
2243 for (var x = 0; x < width; x += 1) {
2244 gif.setPixel(x, y, getPixel(x, y) );
2245 }
2246 }
2247
2248 var b = byteArrayOutputStream();
2249 gif.write(b);
2250
2251 var base64 = base64EncodeOutputStream();
2252 var bytes = b.toByteArray();
2253 for (var i = 0; i < bytes.length; i += 1) {
2254 base64.writeByte(bytes[i]);
2255 }
2256 base64.flush();
2257
2258 var img = '';
2259 img += '<img';
2260 img += '\u0020src="';
2261 img += 'data:image/gif;base64,';
2262 img += base64;
2263 img += '"';
2264 img += '\u0020width="';
2265 img += width;
2266 img += '"';
2267 img += '\u0020height="';
2268 img += height;
2269 img += '"';
2270 if (alt) {
2271 img += '\u0020alt="';
2272 img += alt;
2273 img += '"';
2274 }
2275 img += '/>';
2276
2277 return img;
2278 };
2279
2280 //---------------------------------------------------------------------
2281 // returns qrcode function.
2282
2283 return qrcode;
2284 }();
2285
2286
2287 }());
2288