hyperbook 0.35.2 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/client.js +32 -0
- package/dist/assets/code.css +13 -0
- package/dist/assets/content.css +90 -3
- package/dist/assets/qrcode.js +424 -0
- package/dist/index.js +2 -2
- package/package.json +4 -4
package/dist/assets/client.js
CHANGED
|
@@ -33,6 +33,36 @@ var hyperbook = (function () {
|
|
|
33
33
|
const tocDrawerEl = document.getElementById("toc-drawer");
|
|
34
34
|
tocDrawerEl.open = !tocDrawerEl.open;
|
|
35
35
|
}
|
|
36
|
+
|
|
37
|
+
function qrcodeOpen() {
|
|
38
|
+
const qrCodeDialog = document.getElementById("qrcode-dialog");
|
|
39
|
+
const qrcodeEls = qrCodeDialog.getElementsByClassName("make-qrcode");
|
|
40
|
+
const urlEls = qrCodeDialog.getElementsByClassName("url");
|
|
41
|
+
const qrcodeEl = qrcodeEls[0];
|
|
42
|
+
const urlEl = urlEls[0];
|
|
43
|
+
const qrcode = new window.QRCode({
|
|
44
|
+
content: window.location.href,
|
|
45
|
+
padding: 0,
|
|
46
|
+
join: true,
|
|
47
|
+
color: "var(--color-text)",
|
|
48
|
+
container: "svg-viewbox",
|
|
49
|
+
background: "var(--color-background)",
|
|
50
|
+
ecl: "M",
|
|
51
|
+
});
|
|
52
|
+
qrcodeEl.innerHTML = qrcode.svg();
|
|
53
|
+
for (let urlEl of urlEls[0].children) {
|
|
54
|
+
const href = urlEl.getAttribute("data-href");
|
|
55
|
+
urlEl.innerHTML = `${window.location.origin}${href}`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
qrCodeDialog.showModal();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function qrcodeClose() {
|
|
62
|
+
const qrCodeDialog = document.getElementById("qrcode-dialog");
|
|
63
|
+
qrCodeDialog.close();
|
|
64
|
+
}
|
|
65
|
+
|
|
36
66
|
function navToggle() {
|
|
37
67
|
const navDrawerEl = document.getElementById("nav-drawer");
|
|
38
68
|
navDrawerEl.open = !navDrawerEl.open;
|
|
@@ -83,5 +113,7 @@ var hyperbook = (function () {
|
|
|
83
113
|
toggleBookmark,
|
|
84
114
|
navToggle,
|
|
85
115
|
tocToggle,
|
|
116
|
+
qrcodeOpen,
|
|
117
|
+
qrcodeClose,
|
|
86
118
|
};
|
|
87
119
|
})();
|
package/dist/assets/code.css
CHANGED
|
@@ -2,6 +2,19 @@ pre {
|
|
|
2
2
|
overflow-x: auto;
|
|
3
3
|
}
|
|
4
4
|
|
|
5
|
+
pre:has(code) {
|
|
6
|
+
position: relative;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
pre code:not(:where(.not-content *)) {
|
|
10
|
+
all: unset;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
pre>code {
|
|
14
|
+
counter-reset: line !important;
|
|
15
|
+
overflow-x: auto !important;
|
|
16
|
+
}
|
|
17
|
+
|
|
5
18
|
figure[data-rehype-pretty-code-figure] pre {
|
|
6
19
|
font-size: 85%;
|
|
7
20
|
border-color: var(--color-spacer);
|
package/dist/assets/content.css
CHANGED
|
@@ -370,7 +370,8 @@ figure {
|
|
|
370
370
|
background-color: var(--color-text);
|
|
371
371
|
}
|
|
372
372
|
|
|
373
|
-
.hyperbook-markdown #toc-toggle
|
|
373
|
+
.hyperbook-markdown #toc-toggle,
|
|
374
|
+
.hyperbook-markdown #qrcode-open {
|
|
374
375
|
background: var(--color-background);
|
|
375
376
|
border-color: var(--color-nav-border);
|
|
376
377
|
cursor: pointer;
|
|
@@ -399,7 +400,88 @@ figure {
|
|
|
399
400
|
text-decoration: underline;
|
|
400
401
|
}
|
|
401
402
|
|
|
402
|
-
.hyperbook-markdown #
|
|
403
|
+
.hyperbook-markdown #qrcode-dialog {
|
|
404
|
+
background: var(--color-background);
|
|
405
|
+
border: 1px solid var(--color-brand);
|
|
406
|
+
width: 100%;
|
|
407
|
+
height: 100%;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
#qrcode-dialog .container {
|
|
411
|
+
position: absolute;
|
|
412
|
+
top: 0;
|
|
413
|
+
bottom: 0;
|
|
414
|
+
right: 0;
|
|
415
|
+
left: 0;
|
|
416
|
+
padding: 16px;
|
|
417
|
+
display: flex;
|
|
418
|
+
flex-direction: column;
|
|
419
|
+
align-items: center;
|
|
420
|
+
justify-content: center;
|
|
421
|
+
gap: 8px;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
#qrcode-dialog .name {
|
|
425
|
+
color: var(--color-text);
|
|
426
|
+
text-align: center;
|
|
427
|
+
font-size: 2rem;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
#qrcode-dialog .url {
|
|
431
|
+
color: var(--color-text);
|
|
432
|
+
text-align: center;
|
|
433
|
+
font-size: 1.25rem;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
#qrcode-dialog .close {
|
|
437
|
+
background: none;
|
|
438
|
+
border: none;
|
|
439
|
+
font-size: 2rem;
|
|
440
|
+
color: var(--color-text);
|
|
441
|
+
cursor: pointer;
|
|
442
|
+
position: absolute;
|
|
443
|
+
font: monospace;
|
|
444
|
+
top: 0px;
|
|
445
|
+
right: 0px;
|
|
446
|
+
width: 48px;
|
|
447
|
+
height: 48px;
|
|
448
|
+
display: flex;
|
|
449
|
+
justify-content: center;
|
|
450
|
+
align-items: center;
|
|
451
|
+
background: var(--color-background);
|
|
452
|
+
border-radius: 8px;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
#qrcode-dialog .close:hover .close-icon {
|
|
456
|
+
background-color: var(--color-brand);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
.hyperbook-markdown #qrcode-dialog .make-qrcode {
|
|
460
|
+
width: 100%;
|
|
461
|
+
max-width: 512px;
|
|
462
|
+
margin: 0 auto;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
.hyperbook-markdown #qrcode-dialog svg {
|
|
466
|
+
width: 100%;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
.hyperbook-markdown .close-icon {
|
|
470
|
+
background-color: var(--color-text);
|
|
471
|
+
width: 32px;
|
|
472
|
+
height: 32px;
|
|
473
|
+
mask-image: url('data:image/svg+xml,<svg width="32px" height="32px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5.29289 5.29289C5.68342 4.90237 6.31658 4.90237 6.70711 5.29289L12 10.5858L17.2929 5.29289C17.6834 4.90237 18.3166 4.90237 18.7071 5.29289C19.0976 5.68342 19.0976 6.31658 18.7071 6.70711L13.4142 12L18.7071 17.2929C19.0976 17.6834 19.0976 18.3166 18.7071 18.7071C18.3166 19.0976 17.6834 19.0976 17.2929 18.7071L12 13.4142L6.70711 18.7071C6.31658 19.0976 5.68342 19.0976 5.29289 18.7071C4.90237 18.3166 4.90237 17.6834 5.29289 17.2929L10.5858 12L5.29289 6.70711C4.90237 6.31658 4.90237 5.68342 5.29289 5.29289Z" fill="%230F1729"/></svg>');
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
.hyperbook-markdown .qrcode-icon {
|
|
477
|
+
background-color: var(--color-text);
|
|
478
|
+
width: 32px;
|
|
479
|
+
height: 32px;
|
|
480
|
+
mask-image: url('data:image/svg+xml,<svg width="32px" height="32px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M3 9h6V3H3zm1-5h4v4H4zm1 1h2v2H5zm10 4h6V3h-6zm1-5h4v4h-4zm1 1h2v2h-2zM3 21h6v-6H3zm1-5h4v4H4zm1 1h2v2H5zm15 2h1v2h-2v-3h1zm0-3h1v1h-1zm0-1v1h-1v-1zm-10 2h1v4h-1v-4zm-4-7v2H4v-1H3v-1h3zm4-3h1v1h-1zm3-3v2h-1V3h2v1zm-3 0h1v1h-1zm10 8h1v2h-2v-1h1zm-1-2v1h-2v2h-2v-1h1v-2h3zm-7 4h-1v-1h-1v-1h2v2zm6 2h1v1h-1zm2-5v1h-1v-1zm-9 3v1h-1v-1zm6 5h1v2h-2v-2zm-3 0h1v1h-1v1h-2v-1h1v-1zm0-1v-1h2v1zm0-5h1v3h-1v1h-1v1h-1v-2h-1v-1h3v-1h-1v-1zm-9 0v1H4v-1zm12 4h-1v-1h1zm1-2h-2v-1h2zM8 10h1v1H8v1h1v2H8v-1H7v1H6v-2h1v-2zm3 0V8h3v3h-2v-1h1V9h-1v1zm0-4h1v1h-1zm-1 4h1v1h-1zm3-3V6h1v1z"/><path fill="none" d="M0 0h24v24H0z"/></svg>');
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
.hyperbook-markdown #toc-toggle,
|
|
484
|
+
.hyperbook-markdown #qrcode-open {
|
|
403
485
|
position: fixed;
|
|
404
486
|
padding: 4px;
|
|
405
487
|
top: 90px;
|
|
@@ -413,7 +495,12 @@ figure {
|
|
|
413
495
|
z-index: 1000;
|
|
414
496
|
}
|
|
415
497
|
|
|
416
|
-
.hyperbook-markdown #
|
|
498
|
+
.hyperbook-markdown #qrcode-open {
|
|
499
|
+
top: 140px;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
.hyperbook-markdown #toc-toggle:hover,
|
|
503
|
+
.hyperbook-markdown #qrcode-toggle:hover {
|
|
417
504
|
opacity: 1;
|
|
418
505
|
}
|
|
419
506
|
|
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview
|
|
3
|
+
* - modified davidshimjs/qrcodejs library for use in node.js
|
|
4
|
+
* - Using the 'QRCode for Javascript library'
|
|
5
|
+
* - Fixed dataset of 'QRCode for Javascript library' for support full-spec.
|
|
6
|
+
* - this library has no dependencies.
|
|
7
|
+
*
|
|
8
|
+
* @version 0.9.1 (2016-02-12)
|
|
9
|
+
* @author davidshimjs, papnkukn
|
|
10
|
+
* @see <a href="http://www.d-project.com/" target="_blank">http://www.d-project.com/</a>
|
|
11
|
+
* @see <a href="http://jeromeetienne.github.com/jquery-qrcode/" target="_blank">http://jeromeetienne.github.com/jquery-qrcode/</a>
|
|
12
|
+
* @see <a href="https://github.com/davidshimjs/qrcodejs" target="_blank">https://github.com/davidshimjs/qrcodejs</a>
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
//---------------------------------------------------------------------
|
|
16
|
+
// QRCode for JavaScript
|
|
17
|
+
//
|
|
18
|
+
// Copyright (c) 2009 Kazuhiko Arase
|
|
19
|
+
//
|
|
20
|
+
// URL: http://www.d-project.com/
|
|
21
|
+
//
|
|
22
|
+
// Licensed under the MIT license:
|
|
23
|
+
// http://www.opensource.org/licenses/mit-license.php
|
|
24
|
+
//
|
|
25
|
+
// The word "QR Code" is registered trademark of
|
|
26
|
+
// DENSO WAVE INCORPORATED
|
|
27
|
+
// http://www.denso-wave.com/qrcode/faqpatent-e.html
|
|
28
|
+
//
|
|
29
|
+
//---------------------------------------------------------------------
|
|
30
|
+
function QR8bitByte(data) {
|
|
31
|
+
this.mode = QRMode.MODE_8BIT_BYTE;
|
|
32
|
+
this.data = data;
|
|
33
|
+
this.parsedData = [];
|
|
34
|
+
|
|
35
|
+
// Added to support UTF-8 Characters
|
|
36
|
+
for (var i = 0, l = this.data.length; i < l; i++) {
|
|
37
|
+
var byteArray = [];
|
|
38
|
+
var code = this.data.charCodeAt(i);
|
|
39
|
+
|
|
40
|
+
if (code > 0x10000) {
|
|
41
|
+
byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18);
|
|
42
|
+
byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12);
|
|
43
|
+
byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6);
|
|
44
|
+
byteArray[3] = 0x80 | (code & 0x3F);
|
|
45
|
+
} else if (code > 0x800) {
|
|
46
|
+
byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12);
|
|
47
|
+
byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6);
|
|
48
|
+
byteArray[2] = 0x80 | (code & 0x3F);
|
|
49
|
+
} else if (code > 0x80) {
|
|
50
|
+
byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6);
|
|
51
|
+
byteArray[1] = 0x80 | (code & 0x3F);
|
|
52
|
+
} else {
|
|
53
|
+
byteArray[0] = code;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
this.parsedData.push(byteArray);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
this.parsedData = Array.prototype.concat.apply([], this.parsedData);
|
|
60
|
+
|
|
61
|
+
if (this.parsedData.length != this.data.length) {
|
|
62
|
+
this.parsedData.unshift(191);
|
|
63
|
+
this.parsedData.unshift(187);
|
|
64
|
+
this.parsedData.unshift(239);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
QR8bitByte.prototype = {
|
|
69
|
+
getLength: function (buffer) {
|
|
70
|
+
return this.parsedData.length;
|
|
71
|
+
},
|
|
72
|
+
write: function (buffer) {
|
|
73
|
+
for (var i = 0, l = this.parsedData.length; i < l; i++) {
|
|
74
|
+
buffer.put(this.parsedData[i], 8);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
function QRCodeModel(typeNumber, errorCorrectLevel) {
|
|
80
|
+
this.typeNumber = typeNumber;
|
|
81
|
+
this.errorCorrectLevel = errorCorrectLevel;
|
|
82
|
+
this.modules = null;
|
|
83
|
+
this.moduleCount = 0;
|
|
84
|
+
this.dataCache = null;
|
|
85
|
+
this.dataList = [];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
QRCodeModel.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData);this.dataCache=null;},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col){throw new Error(row+","+col);}
|
|
89
|
+
return this.modules[row][col];},getModuleCount:function(){return this.moduleCount;},make:function(){this.makeImpl(false,this.getBestMaskPattern());},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17;this.modules=new Array(this.moduleCount);for(var row=0;row<this.moduleCount;row++){this.modules[row]=new Array(this.moduleCount);for(var col=0;col<this.moduleCount;col++){this.modules[row][col]=null;}}
|
|
90
|
+
this.setupPositionProbePattern(0,0);this.setupPositionProbePattern(this.moduleCount-7,0);this.setupPositionProbePattern(0,this.moduleCount-7);this.setupPositionAdjustPattern();this.setupTimingPattern();this.setupTypeInfo(test,maskPattern);if(this.typeNumber>=7){this.setupTypeNumber(test);}
|
|
91
|
+
if(this.dataCache==null){this.dataCache=QRCodeModel.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);}
|
|
92
|
+
this.mapData(this.dataCache,maskPattern);},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}},getBestMaskPattern:function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i++){this.makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}}
|
|
93
|
+
return pattern;},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth);var cs=1;this.make();for(var row=0;row<this.modules.length;row++){var y=row*cs;for(var col=0;col<this.modules[row].length;col++){var x=col*cs;var dark=this.modules[row][col];if(dark){qr_mc.beginFill(0,100);qr_mc.moveTo(x,y);qr_mc.lineTo(x+cs,y);qr_mc.lineTo(x+cs,y+cs);qr_mc.lineTo(x,y+cs);qr_mc.endFill();}}}
|
|
94
|
+
return qr_mc;},setupTimingPattern:function(){for(var r=8;r<this.moduleCount-8;r++){if(this.modules[r][6]!=null){continue;}
|
|
95
|
+
this.modules[r][6]=(r%2==0);}
|
|
96
|
+
for(var c=8;c<this.moduleCount-8;c++){if(this.modules[6][c]!=null){continue;}
|
|
97
|
+
this.modules[6][c]=(c%2==0);}},setupPositionAdjustPattern:function(){var pos=QRUtil.getPatternPosition(this.typeNumber);for(var i=0;i<pos.length;i++){for(var j=0;j<pos.length;j++){var row=pos[i];var col=pos[j];if(this.modules[row][col]!=null){continue;}
|
|
98
|
+
for(var r=-2;r<=2;r++){for(var c=-2;c<=2;c++){if(r==-2||r==2||c==-2||c==2||(r==0&&c==0)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}}}},setupTypeNumber:function(test){var bits=QRUtil.getBCHTypeNumber(this.typeNumber);for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;}
|
|
99
|
+
for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[i%3+this.moduleCount-8-3][Math.floor(i/3)]=mod;}},setupTypeInfo:function(test,maskPattern){var data=(this.errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<6){this.modules[i][8]=mod;}else if(i<8){this.modules[i+1][8]=mod;}else{this.modules[this.moduleCount-15+i][8]=mod;}}
|
|
100
|
+
for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<8){this.modules[8][this.moduleCount-i-1]=mod;}else if(i<9){this.modules[8][15-i-1+1]=mod;}else{this.modules[8][15-i-1]=mod;}}
|
|
101
|
+
this.modules[this.moduleCount-8][8]=(!test);},mapData:function(data,maskPattern){var inc=-1;var row=this.moduleCount-1;var bitIndex=7;var byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col==6)col--;while(true){for(var c=0;c<2;c++){if(this.modules[row][col-c]==null){var dark=false;if(byteIndex<data.length){dark=(((data[byteIndex]>>>bitIndex)&1)==1);}
|
|
102
|
+
var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask){dark=!dark;}
|
|
103
|
+
this.modules[row][col-c]=dark;bitIndex--;if(bitIndex==-1){byteIndex++;bitIndex=7;}}}
|
|
104
|
+
row+=inc;if(row<0||this.moduleCount<=row){row-=inc;inc=-inc;break;}}}}};QRCodeModel.PAD0=0xEC;QRCodeModel.PAD1=0x11;QRCodeModel.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=new QRBitBuffer();for(var i=0;i<dataList.length;i++){var data=dataList[i];buffer.put(data.mode,4);buffer.put(data.getLength(),QRUtil.getLengthInBits(data.mode,typeNumber));data.write(buffer);}
|
|
105
|
+
var totalDataCount=0;for(var i=0;i<rsBlocks.length;i++){totalDataCount+=rsBlocks[i].dataCount;}
|
|
106
|
+
if(buffer.getLengthInBits()>totalDataCount*8){throw new Error("code length overflow. ("
|
|
107
|
+
+buffer.getLengthInBits()
|
|
108
|
+
+">"
|
|
109
|
+
+totalDataCount*8
|
|
110
|
+
+")");}
|
|
111
|
+
if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);}
|
|
112
|
+
while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);}
|
|
113
|
+
while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;}
|
|
114
|
+
buffer.put(QRCodeModel.PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;}
|
|
115
|
+
buffer.put(QRCodeModel.PAD1,8);}
|
|
116
|
+
return QRCodeModel.createBytes(buffer,rsBlocks);};QRCodeModel.createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r<rsBlocks.length;r++){var dcCount=rsBlocks[r].dataCount;var ecCount=rsBlocks[r].totalCount-dcCount;maxDcCount=Math.max(maxDcCount,dcCount);maxEcCount=Math.max(maxEcCount,ecCount);dcdata[r]=new Array(dcCount);for(var i=0;i<dcdata[r].length;i++){dcdata[r][i]=0xff&buffer.buffer[i+offset];}
|
|
117
|
+
offset+=dcCount;var rsPoly=QRUtil.getErrorCorrectPolynomial(ecCount);var rawPoly=new QRPolynomial(dcdata[r],rsPoly.getLength()-1);var modPoly=rawPoly.mod(rsPoly);ecdata[r]=new Array(rsPoly.getLength()-1);for(var i=0;i<ecdata[r].length;i++){var modIndex=i+modPoly.getLength()-ecdata[r].length;ecdata[r][i]=(modIndex>=0)?modPoly.get(modIndex):0;}}
|
|
118
|
+
var totalCodeCount=0;for(var i=0;i<rsBlocks.length;i++){totalCodeCount+=rsBlocks[i].totalCount;}
|
|
119
|
+
var data=new Array(totalCodeCount);var index=0;for(var i=0;i<maxDcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<dcdata[r].length){data[index++]=dcdata[r][i];}}}
|
|
120
|
+
for(var i=0;i<maxEcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<ecdata[r].length){data[index++]=ecdata[r][i];}}}
|
|
121
|
+
return data;};var QRMode={MODE_NUMBER:1<<0,MODE_ALPHA_NUM:1<<1,MODE_8BIT_BYTE:1<<2,MODE_KANJI:1<<3};var QRErrorCorrectLevel={L:1,M:0,Q:3,H:2};var QRMaskPattern={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};var QRUtil={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:(1<<10)|(1<<8)|(1<<5)|(1<<4)|(1<<2)|(1<<1)|(1<<0),G18:(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<5)|(1<<2)|(1<<0),G15_MASK:(1<<14)|(1<<12)|(1<<10)|(1<<4)|(1<<1),getBCHTypeInfo:function(data){var d=data<<10;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)>=0){d^=(QRUtil.G15<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)));}
|
|
122
|
+
return((data<<10)|d)^QRUtil.G15_MASK;},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0){d^=(QRUtil.G18<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)));}
|
|
123
|
+
return(data<<12)|d;},getBCHDigit:function(data){var digit=0;while(data!=0){digit++;data>>>=1;}
|
|
124
|
+
return digit;},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1];},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2==0;case QRMaskPattern.PATTERN001:return i%2==0;case QRMaskPattern.PATTERN010:return j%3==0;case QRMaskPattern.PATTERN011:return(i+j)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2==0;case QRMaskPattern.PATTERN101:return(i*j)%2+(i*j)%3==0;case QRMaskPattern.PATTERN110:return((i*j)%2+(i*j)%3)%2==0;case QRMaskPattern.PATTERN111:return((i*j)%3+(i+j)%2)%2==0;default:throw new Error("bad maskPattern:"+maskPattern);}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i<errorCorrectLength;i++){a=a.multiply(new QRPolynomial([1,QRMath.gexp(i)],0));}
|
|
125
|
+
return a;},getLengthInBits:function(mode,type){if(1<=type&&type<10){switch(mode){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw new Error("mode:"+mode);}}else if(type<27){switch(mode){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw new Error("mode:"+mode);}}else if(type<41){switch(mode){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw new Error("mode:"+mode);}}else{throw new Error("type:"+type);}},getLostPoint:function(qrCode){var moduleCount=qrCode.getModuleCount();var lostPoint=0;for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount;col++){var sameCount=0;var dark=qrCode.isDark(row,col);for(var r=-1;r<=1;r++){if(row+r<0||moduleCount<=row+r){continue;}
|
|
126
|
+
for(var c=-1;c<=1;c++){if(col+c<0||moduleCount<=col+c){continue;}
|
|
127
|
+
if(r==0&&c==0){continue;}
|
|
128
|
+
if(dark==qrCode.isDark(row+r,col+c)){sameCount++;}}}
|
|
129
|
+
if(sameCount>5){lostPoint+=(3+sameCount-5);}}}
|
|
130
|
+
for(var row=0;row<moduleCount-1;row++){for(var col=0;col<moduleCount-1;col++){var count=0;if(qrCode.isDark(row,col))count++;if(qrCode.isDark(row+1,col))count++;if(qrCode.isDark(row,col+1))count++;if(qrCode.isDark(row+1,col+1))count++;if(count==0||count==4){lostPoint+=3;}}}
|
|
131
|
+
for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount-6;col++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row,col+1)&&qrCode.isDark(row,col+2)&&qrCode.isDark(row,col+3)&&qrCode.isDark(row,col+4)&&!qrCode.isDark(row,col+5)&&qrCode.isDark(row,col+6)){lostPoint+=40;}}}
|
|
132
|
+
for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount-6;row++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row+1,col)&&qrCode.isDark(row+2,col)&&qrCode.isDark(row+3,col)&&qrCode.isDark(row+4,col)&&!qrCode.isDark(row+5,col)&&qrCode.isDark(row+6,col)){lostPoint+=40;}}}
|
|
133
|
+
var darkCount=0;for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount;row++){if(qrCode.isDark(row,col)){darkCount++;}}}
|
|
134
|
+
var ratio=Math.abs(100*darkCount/moduleCount/moduleCount-50)/5;lostPoint+=ratio*10;return lostPoint;}};var QRMath={glog:function(n){if(n<1){throw new Error("glog("+n+")");}
|
|
135
|
+
return QRMath.LOG_TABLE[n];},gexp:function(n){while(n<0){n+=255;}
|
|
136
|
+
while(n>=256){n-=255;}
|
|
137
|
+
return QRMath.EXP_TABLE[n];},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(var i=0;i<8;i++){QRMath.EXP_TABLE[i]=1<<i;}
|
|
138
|
+
for(var i=8;i<256;i++){QRMath.EXP_TABLE[i]=QRMath.EXP_TABLE[i-4]^QRMath.EXP_TABLE[i-5]^QRMath.EXP_TABLE[i-6]^QRMath.EXP_TABLE[i-8];}
|
|
139
|
+
for(var i=0;i<255;i++){QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]]=i;}
|
|
140
|
+
function QRPolynomial(num,shift){if(num.length==undefined){throw new Error(num.length+"/"+shift);}
|
|
141
|
+
var offset=0;while(offset<num.length&&num[offset]==0){offset++;}
|
|
142
|
+
this.num=new Array(num.length-offset+shift);for(var i=0;i<num.length-offset;i++){this.num[i]=num[i+offset];}}
|
|
143
|
+
QRPolynomial.prototype={get:function(index){return this.num[index];},getLength:function(){return this.num.length;},multiply:function(e){var num=new Array(this.getLength()+e.getLength()-1);for(var i=0;i<this.getLength();i++){for(var j=0;j<e.getLength();j++){num[i+j]^=QRMath.gexp(QRMath.glog(this.get(i))+QRMath.glog(e.get(j)));}}
|
|
144
|
+
return new QRPolynomial(num,0);},mod:function(e){if(this.getLength()-e.getLength()<0){return this;}
|
|
145
|
+
var ratio=QRMath.glog(this.get(0))-QRMath.glog(e.get(0));var num=new Array(this.getLength());for(var i=0;i<this.getLength();i++){num[i]=this.get(i);}
|
|
146
|
+
for(var i=0;i<e.getLength();i++){num[i]^=QRMath.gexp(QRMath.glog(e.get(i))+ratio);}
|
|
147
|
+
return new QRPolynomial(num,0).mod(e);}};function QRRSBlock(totalCount,dataCount){this.totalCount=totalCount;this.dataCount=dataCount;}
|
|
148
|
+
QRRSBlock.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];QRRSBlock.getRSBlocks=function(typeNumber,errorCorrectLevel){var rsBlock=QRRSBlock.getRsBlockTable(typeNumber,errorCorrectLevel);if(rsBlock==undefined){throw new Error("bad rs block @ typeNumber:"+typeNumber+"/errorCorrectLevel:"+errorCorrectLevel);}
|
|
149
|
+
var length=rsBlock.length/3;var list=[];for(var i=0;i<length;i++){var count=rsBlock[i*3+0];var totalCount=rsBlock[i*3+1];var dataCount=rsBlock[i*3+2];for(var j=0;j<count;j++){list.push(new QRRSBlock(totalCount,dataCount));}}
|
|
150
|
+
return list;};QRRSBlock.getRsBlockTable=function(typeNumber,errorCorrectLevel){switch(errorCorrectLevel){case QRErrorCorrectLevel.L:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+0];case QRErrorCorrectLevel.M:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+1];case QRErrorCorrectLevel.Q:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+2];case QRErrorCorrectLevel.H:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+3];default:return undefined;}};function QRBitBuffer(){this.buffer=[];this.length=0;}
|
|
151
|
+
QRBitBuffer.prototype={get:function(index){var bufIndex=Math.floor(index/8);return((this.buffer[bufIndex]>>>(7-index%8))&1)==1;},put:function(num,length){for(var i=0;i<length;i++){this.putBit(((num>>>(length-i-1))&1)==1);}},getLengthInBits:function(){return this.length;},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex){this.buffer.push(0);}
|
|
152
|
+
if(bit){this.buffer[bufIndex]|=(0x80>>>(this.length%8));}
|
|
153
|
+
this.length++;}};var QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]];
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
/** Constructor */
|
|
157
|
+
function QRCode(options) {
|
|
158
|
+
var instance = this;
|
|
159
|
+
|
|
160
|
+
//Default options
|
|
161
|
+
this.options = {
|
|
162
|
+
padding: 4,
|
|
163
|
+
width: 256,
|
|
164
|
+
height: 256,
|
|
165
|
+
typeNumber: 4,
|
|
166
|
+
color: "#000000",
|
|
167
|
+
background: "#ffffff",
|
|
168
|
+
ecl: "M"
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
//In case the options is string
|
|
172
|
+
if (typeof options === 'string') {
|
|
173
|
+
options = {
|
|
174
|
+
content: options
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
//Merge options
|
|
179
|
+
if (options) {
|
|
180
|
+
for (var i in options) {
|
|
181
|
+
this.options[i] = options[i];
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (typeof this.options.content !== 'string') {
|
|
186
|
+
throw new Error("Expected 'content' as string!");
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (this.options.content.length === 0 /* || this.options.content.length > 7089 */) {
|
|
190
|
+
throw new Error("Expected 'content' to be non-empty!");
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (!(this.options.padding >= 0)) {
|
|
194
|
+
throw new Error("Expected 'padding' value to be non-negative!");
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (!(this.options.width > 0) || !(this.options.height > 0)) {
|
|
198
|
+
throw new Error("Expected 'width' or 'height' value to be higher than zero!");
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
//Gets the error correction level
|
|
202
|
+
function _getErrorCorrectLevel(ecl) {
|
|
203
|
+
switch (ecl) {
|
|
204
|
+
case "L":
|
|
205
|
+
return QRErrorCorrectLevel.L;
|
|
206
|
+
|
|
207
|
+
case "M":
|
|
208
|
+
return QRErrorCorrectLevel.M;
|
|
209
|
+
|
|
210
|
+
case "Q":
|
|
211
|
+
return QRErrorCorrectLevel.Q;
|
|
212
|
+
|
|
213
|
+
case "H":
|
|
214
|
+
return QRErrorCorrectLevel.H;
|
|
215
|
+
|
|
216
|
+
default:
|
|
217
|
+
throw new Error("Unknwon error correction level: " + ecl);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
//Get type number
|
|
222
|
+
function _getTypeNumber(content, ecl) {
|
|
223
|
+
var length = _getUTF8Length(content);
|
|
224
|
+
|
|
225
|
+
var type = 1;
|
|
226
|
+
var limit = 0;
|
|
227
|
+
for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) {
|
|
228
|
+
var table = QRCodeLimitLength[i];
|
|
229
|
+
if (!table) {
|
|
230
|
+
throw new Error("Content too long: expected " + limit + " but got " + length);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
switch (ecl) {
|
|
234
|
+
case "L":
|
|
235
|
+
limit = table[0];
|
|
236
|
+
break;
|
|
237
|
+
|
|
238
|
+
case "M":
|
|
239
|
+
limit = table[1];
|
|
240
|
+
break;
|
|
241
|
+
|
|
242
|
+
case "Q":
|
|
243
|
+
limit = table[2];
|
|
244
|
+
break;
|
|
245
|
+
|
|
246
|
+
case "H":
|
|
247
|
+
limit = table[3];
|
|
248
|
+
break;
|
|
249
|
+
|
|
250
|
+
default:
|
|
251
|
+
throw new Error("Unknwon error correction level: " + ecl);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (length <= limit) {
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
type++;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (type > QRCodeLimitLength.length) {
|
|
262
|
+
throw new Error("Content too long");
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return type;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
//Gets text length
|
|
269
|
+
function _getUTF8Length(content) {
|
|
270
|
+
var result = encodeURI(content).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a');
|
|
271
|
+
return result.length + (result.length != content ? 3 : 0);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
//Generate QR Code matrix
|
|
275
|
+
var content = this.options.content;
|
|
276
|
+
var type = _getTypeNumber(content, this.options.ecl);
|
|
277
|
+
var ecl = _getErrorCorrectLevel(this.options.ecl);
|
|
278
|
+
this.qrcode = new QRCodeModel(type, ecl);
|
|
279
|
+
this.qrcode.addData(content);
|
|
280
|
+
this.qrcode.make();
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/** Generates QR Code as SVG image */
|
|
284
|
+
QRCode.prototype.svg = function(opt) {
|
|
285
|
+
var options = this.options || { };
|
|
286
|
+
var modules = this.qrcode.modules;
|
|
287
|
+
|
|
288
|
+
if (typeof opt == "undefined") {
|
|
289
|
+
opt = { container: options.container || "svg" };
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
//Apply new lines and indents in SVG?
|
|
293
|
+
var pretty = typeof options.pretty != "undefined" ? !!options.pretty : true;
|
|
294
|
+
|
|
295
|
+
var indent = pretty ? ' ' : '';
|
|
296
|
+
var EOL = pretty ? '\r\n' : '';
|
|
297
|
+
var width = options.width;
|
|
298
|
+
var height = options.height;
|
|
299
|
+
var length = modules.length;
|
|
300
|
+
var xsize = width / (length + 2 * options.padding);
|
|
301
|
+
var ysize = height / (length + 2 * options.padding);
|
|
302
|
+
|
|
303
|
+
//Join (union, merge) rectangles into one shape?
|
|
304
|
+
var join = typeof options.join != "undefined" ? !!options.join : false;
|
|
305
|
+
|
|
306
|
+
//Swap the X and Y modules, pull request #2
|
|
307
|
+
var swap = typeof options.swap != "undefined" ? !!options.swap : false;
|
|
308
|
+
|
|
309
|
+
//Apply <?xml...?> declaration in SVG?
|
|
310
|
+
var xmlDeclaration = typeof options.xmlDeclaration != "undefined" ? !!options.xmlDeclaration : true;
|
|
311
|
+
|
|
312
|
+
//Populate with predefined shape instead of "rect" elements, thanks to @kkocdko
|
|
313
|
+
var predefined = typeof options.predefined != "undefined" ? !!options.predefined : false;
|
|
314
|
+
var defs = predefined ? indent + '<defs><path id="qrmodule" d="M0 0 h' + ysize + ' v' + xsize + ' H0 z" style="fill:' + options.color + ';shape-rendering:crispEdges;" /></defs>' + EOL : '';
|
|
315
|
+
|
|
316
|
+
//Background rectangle
|
|
317
|
+
var bgrect = indent + '<rect x="0" y="0" width="' + width + '" height="' + height + '" style="fill:' + options.background + ';shape-rendering:crispEdges;"/>' + EOL;
|
|
318
|
+
|
|
319
|
+
//Rectangles representing modules
|
|
320
|
+
var modrect = '';
|
|
321
|
+
var pathdata = '';
|
|
322
|
+
|
|
323
|
+
for (var y = 0; y < length; y++) {
|
|
324
|
+
for (var x = 0; x < length; x++) {
|
|
325
|
+
var module = modules[x][y];
|
|
326
|
+
if (module) {
|
|
327
|
+
|
|
328
|
+
var px = (x * xsize + options.padding * xsize);
|
|
329
|
+
var py = (y * ysize + options.padding * ysize);
|
|
330
|
+
|
|
331
|
+
//Some users have had issues with the QR Code, thanks to @danioso for the solution
|
|
332
|
+
if (swap) {
|
|
333
|
+
var t = px;
|
|
334
|
+
px = py;
|
|
335
|
+
py = t;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (join) {
|
|
339
|
+
//Module as a part of svg path data, thanks to @danioso
|
|
340
|
+
var w = xsize + px
|
|
341
|
+
var h = ysize + py
|
|
342
|
+
|
|
343
|
+
px = (Number.isInteger(px))? Number(px): px.toFixed(2);
|
|
344
|
+
py = (Number.isInteger(py))? Number(py): py.toFixed(2);
|
|
345
|
+
w = (Number.isInteger(w))? Number(w): w.toFixed(2);
|
|
346
|
+
h = (Number.isInteger(h))? Number(h): h.toFixed(2);
|
|
347
|
+
|
|
348
|
+
pathdata += ('M' + px + ',' + py + ' V' + h + ' H' + w + ' V' + py + ' H' + px + ' Z ');
|
|
349
|
+
}
|
|
350
|
+
else if (predefined) {
|
|
351
|
+
//Module as a predefined shape, thanks to @kkocdko
|
|
352
|
+
modrect += indent + '<use x="' + px.toString() + '" y="' + py.toString() + '" href="#qrmodule" />' + EOL;
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
//Module as rectangle element
|
|
356
|
+
modrect += indent + '<rect x="' + px.toString() + '" y="' + py.toString() + '" width="' + xsize + '" height="' + ysize + '" style="fill:' + options.color + ';shape-rendering:crispEdges;"/>' + EOL;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
if (join) {
|
|
363
|
+
modrect = indent + '<path x="0" y="0" style="fill:' + options.color + ';shape-rendering:crispEdges;" d="' + pathdata + '" />';
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
var svg = "";
|
|
367
|
+
switch (opt.container) {
|
|
368
|
+
//Wrapped in SVG document
|
|
369
|
+
case "svg":
|
|
370
|
+
if (xmlDeclaration) {
|
|
371
|
+
svg += '<?xml version="1.0" standalone="yes"?>' + EOL;
|
|
372
|
+
}
|
|
373
|
+
svg += '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="' + width + '" height="' + height + '">' + EOL;
|
|
374
|
+
svg += defs + bgrect + modrect;
|
|
375
|
+
svg += '</svg>';
|
|
376
|
+
break;
|
|
377
|
+
|
|
378
|
+
//Viewbox for responsive use in a browser, thanks to @danioso
|
|
379
|
+
case "svg-viewbox":
|
|
380
|
+
if (xmlDeclaration) {
|
|
381
|
+
svg += '<?xml version="1.0" standalone="yes"?>' + EOL;
|
|
382
|
+
}
|
|
383
|
+
svg += '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 ' + width + ' ' + height + '">' + EOL;
|
|
384
|
+
svg += defs + bgrect + modrect;
|
|
385
|
+
svg += '</svg>';
|
|
386
|
+
break;
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
//Wrapped in group element
|
|
390
|
+
case "g":
|
|
391
|
+
svg += '<g width="' + width + '" height="' + height + '">' + EOL;
|
|
392
|
+
svg += defs + bgrect + modrect;
|
|
393
|
+
svg += '</g>';
|
|
394
|
+
break;
|
|
395
|
+
|
|
396
|
+
//Without a container
|
|
397
|
+
default:
|
|
398
|
+
svg += (defs + bgrect + modrect).replace(/^\s+/, ""); //Clear indents on each line
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
return svg;
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
/** Writes QR Code image to a file */
|
|
406
|
+
QRCode.prototype.save = function(file, callback) {
|
|
407
|
+
var data = this.svg();
|
|
408
|
+
if (typeof callback != "function") {
|
|
409
|
+
callback = function(error, result) { };
|
|
410
|
+
}
|
|
411
|
+
try {
|
|
412
|
+
//Package 'fs' is available in node.js but not in a web browser
|
|
413
|
+
var fs = require('fs');
|
|
414
|
+
fs.writeFile(file, data, callback);
|
|
415
|
+
}
|
|
416
|
+
catch (e) {
|
|
417
|
+
//Sorry, 'fs' is not available
|
|
418
|
+
callback(e);
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
if (typeof module != "undefined") {
|
|
423
|
+
module.exports = QRCode;
|
|
424
|
+
}
|