Passed
Push — master ( 89d1f0...c413c6 )
by Guangyu
10:50 queued 12s
created

admin/js/angular/qrcode.js   F

Complexity

Total Complexity 353
Complexity/F 2.92

Size

Lines of Code 2280
Function Count 121

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 353
eloc 1309
mnd 232
bc 232
fnc 121
dl 0
loc 2280
rs 0.8
bpm 1.9173
cpm 2.9173
noi 16
c 0
b 0
f 0

2 Functions

Rating   Name   Duplication   Size   Complexity  
F qrcode.js ➔ toUTF8Array 0 30 128
F qrcode.js ➔ qrPolynomial 0 64 221

How to fix   Complexity   

Complexity

Complex classes like admin/js/angular/qrcode.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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