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