dsh-remote-tunnel-easy 1.4.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/lib/qrcode.js ADDED
@@ -0,0 +1,591 @@
1
+ /**
2
+ * Vendored QR encoder, self-contained ESM with no runtime dependencies.
3
+ *
4
+ * This is the QR code generator from `qrcode-terminal` (Kazuhiko Arase's
5
+ * `qrcode-generator`, MIT), collapsed from its original CJS file layout
6
+ * (vendor/QRCode/{QRCode,QR8bitByte,QRUtil,QRPolynomial,QRRSBlock,QRBitBuffer,
7
+ * QRErrorCorrectLevel,QRMode,QRMath,QRMaskPattern}) into this one module.
8
+ *
9
+ * Vendoring (rather than depending on `qrcode-terminal`) is deliberate: when
10
+ * this bundle is installed as a `link:`/`file:` spec, a dependency's package
11
+ * cannot be required from inside the checkout, so the QR step failed with
12
+ * "Cannot find module 'qrcode-terminal/vendor/QRCode'". Encoding a QR matrix
13
+ * needs no network, no native code, and no terminal output, so carrying the
14
+ * ~11 KB MIT encoder in-tree deletes the only remaining runtime dependency and
15
+ * makes `dsh plugin add/remove dsh-remote-tunnel-easy` dependency-free.
16
+ *
17
+ * Original header:
18
+ * QRCode for JavaScript — Copyright (c) 2009 Kazuhiko Arase
19
+ * URL: http://www.d-project.com/
20
+ * Licensed under the MIT license:
21
+ * http://www.opensource.org/licenses/mit-license.php
22
+ */
23
+
24
+ const QRMode = {
25
+ MODE_NUMBER: 1 << 0,
26
+ MODE_ALPHA_NUM: 1 << 1,
27
+ MODE_8BIT_BYTE: 1 << 2,
28
+ MODE_KANJI: 1 << 3,
29
+ }
30
+
31
+ const QRMaskPattern = {
32
+ PATTERN000: 0,
33
+ PATTERN001: 1,
34
+ PATTERN010: 2,
35
+ PATTERN011: 3,
36
+ PATTERN100: 4,
37
+ PATTERN101: 5,
38
+ PATTERN110: 6,
39
+ PATTERN111: 7,
40
+ }
41
+
42
+ const QRErrorCorrectLevel = { L: 1, M: 0, Q: 3, H: 2 }
43
+
44
+ const QRMath = {
45
+ glog(n) {
46
+ if (n < 1) throw new Error(`glog(${n})`)
47
+ return QRMath.LOG_TABLE[n]
48
+ },
49
+ gexp(n) {
50
+ while (n < 0) n += 255
51
+ while (n >= 256) n -= 255
52
+ return QRMath.EXP_TABLE[n]
53
+ },
54
+ EXP_TABLE: new Array(256),
55
+ LOG_TABLE: new Array(256),
56
+ }
57
+ for (let i = 0; i < 8; i++) QRMath.EXP_TABLE[i] = 1 << i
58
+ for (let i = 8; i < 256; i++) {
59
+ QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^ QRMath.EXP_TABLE[i - 5] ^ QRMath.EXP_TABLE[i - 6] ^ QRMath.EXP_TABLE[i - 8]
60
+ }
61
+ for (let i = 0; i < 255; i++) QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i
62
+
63
+ function QRPolynomial(num, shift) {
64
+ if (num.length === undefined) throw new Error(`${num.length}/${shift}`)
65
+ let offset = 0
66
+ while (offset < num.length && num[offset] === 0) offset++
67
+ this.num = new Array(num.length - offset + shift)
68
+ for (let i = 0; i < num.length - offset; i++) this.num[i] = num[i + offset]
69
+ }
70
+ QRPolynomial.prototype = {
71
+ get(index) { return this.num[index] },
72
+ getLength() { return this.num.length },
73
+ multiply(e) {
74
+ const num = new Array(this.getLength() + e.getLength() - 1)
75
+ for (let i = 0; i < this.getLength(); i++) {
76
+ for (let j = 0; j < e.getLength(); j++) {
77
+ num[i + j] ^= QRMath.gexp(QRMath.glog(this.get(i)) + QRMath.glog(e.get(j)))
78
+ }
79
+ }
80
+ return new QRPolynomial(num, 0)
81
+ },
82
+ mod(e) {
83
+ if (this.getLength() - e.getLength() < 0) return this
84
+ const ratio = QRMath.glog(this.get(0)) - QRMath.glog(e.get(0))
85
+ const num = new Array(this.getLength())
86
+ for (let i = 0; i < this.getLength(); i++) num[i] = this.get(i)
87
+ for (let x = 0; x < e.getLength(); x++) num[x] ^= QRMath.gexp(QRMath.glog(e.get(x)) + ratio)
88
+ return new QRPolynomial(num, 0).mod(e)
89
+ },
90
+ }
91
+
92
+ function QR8bitByte(data) {
93
+ this.mode = QRMode.MODE_8BIT_BYTE
94
+ this.data = data
95
+ }
96
+ QR8bitByte.prototype = {
97
+ getLength() { return this.data.length },
98
+ write(buffer) {
99
+ for (let i = 0; i < this.data.length; i++) buffer.put(this.data.charCodeAt(i), 8)
100
+ },
101
+ }
102
+
103
+ function QRBitBuffer() {
104
+ this.buffer = []
105
+ this.length = 0
106
+ }
107
+ QRBitBuffer.prototype = {
108
+ get(index) {
109
+ const bufIndex = Math.floor(index / 8)
110
+ return ((this.buffer[bufIndex] >>> (7 - (index % 8))) & 1) === 1
111
+ },
112
+ put(num, length) {
113
+ for (let i = 0; i < length; i++) this.putBit(((num >>> (length - i - 1)) & 1) === 1)
114
+ },
115
+ getLengthInBits() { return this.length },
116
+ putBit(bit) {
117
+ const bufIndex = Math.floor(this.length / 8)
118
+ if (this.buffer.length <= bufIndex) this.buffer.push(0)
119
+ if (bit) this.buffer[bufIndex] |= 0x80 >>> (this.length % 8)
120
+ this.length++
121
+ },
122
+ }
123
+
124
+ function QRRSBlock(totalCount, dataCount) {
125
+ this.totalCount = totalCount
126
+ this.dataCount = dataCount
127
+ }
128
+ QRRSBlock.RS_BLOCK_TABLE = [
129
+ [1, 26, 19], [1, 26, 16], [1, 26, 13], [1, 26, 9],
130
+ [1, 44, 34], [1, 44, 28], [1, 44, 22], [1, 44, 16],
131
+ [1, 70, 55], [1, 70, 44], [2, 35, 17], [2, 35, 13],
132
+ [1, 100, 80], [2, 50, 32], [2, 50, 24], [4, 25, 9],
133
+ [1, 134, 108], [2, 67, 43], [2, 33, 15, 2, 34, 16], [2, 33, 11, 2, 34, 12],
134
+ [2, 86, 68], [4, 43, 27], [4, 43, 19], [4, 43, 15],
135
+ [2, 98, 78], [4, 49, 31], [2, 32, 14, 4, 33, 15], [4, 39, 13, 1, 40, 14],
136
+ [2, 121, 97], [2, 60, 38, 2, 61, 39], [4, 40, 18, 2, 41, 19], [4, 40, 14, 2, 41, 15],
137
+ [2, 146, 116], [3, 58, 36, 2, 59, 37], [4, 36, 16, 4, 37, 17], [4, 36, 12, 4, 37, 13],
138
+ [2, 86, 68, 2, 87, 69], [4, 69, 43, 1, 70, 44], [6, 43, 19, 2, 44, 20], [6, 43, 15, 2, 44, 16],
139
+ [4, 101, 81], [1, 80, 50, 4, 81, 51], [4, 50, 22, 4, 51, 23], [3, 36, 12, 8, 37, 13],
140
+ [2, 116, 92, 2, 117, 93], [6, 58, 36, 2, 59, 37], [4, 46, 20, 6, 47, 21], [7, 42, 14, 4, 43, 15],
141
+ [4, 133, 107], [8, 59, 37, 1, 60, 38], [8, 44, 20, 4, 45, 21], [12, 33, 11, 4, 34, 12],
142
+ [3, 145, 115, 1, 146, 116], [4, 64, 40, 5, 65, 41], [11, 36, 16, 5, 37, 17], [11, 36, 12, 5, 37, 13],
143
+ [5, 109, 87, 1, 110, 88], [5, 65, 41, 5, 66, 42], [5, 54, 24, 7, 55, 25], [11, 36, 12],
144
+ [5, 122, 98, 1, 123, 99], [7, 73, 45, 3, 74, 46], [15, 43, 19, 2, 44, 20], [3, 45, 15, 13, 46, 16],
145
+ [1, 135, 107, 5, 136, 108], [10, 74, 46, 1, 75, 47], [1, 50, 22, 15, 51, 23], [2, 42, 14, 17, 43, 15],
146
+ [5, 150, 120, 1, 151, 121], [9, 69, 43, 4, 70, 44], [17, 50, 22, 1, 51, 23], [2, 42, 14, 19, 43, 15],
147
+ [3, 141, 113, 4, 142, 114], [3, 70, 44, 11, 71, 45], [17, 47, 21, 4, 48, 22], [9, 39, 13, 16, 40, 14],
148
+ [3, 135, 107, 5, 136, 108], [3, 67, 41, 13, 68, 42], [15, 54, 24, 5, 55, 25], [15, 43, 15, 10, 44, 16],
149
+ [4, 144, 116, 4, 145, 117], [17, 68, 42], [17, 50, 22, 6, 51, 23], [19, 46, 16, 6, 47, 17],
150
+ [2, 139, 111, 7, 140, 112], [17, 74, 46], [7, 54, 24, 16, 55, 25], [34, 37, 13],
151
+ [4, 151, 121, 5, 152, 122], [4, 75, 47, 14, 76, 48], [11, 54, 24, 14, 55, 25], [16, 45, 15, 14, 46, 16],
152
+ [6, 147, 117, 4, 148, 118], [6, 73, 45, 14, 74, 46], [11, 54, 24, 16, 55, 25], [30, 46, 16, 2, 47, 17],
153
+ [8, 132, 106, 4, 133, 107], [8, 75, 47, 13, 76, 48], [7, 54, 24, 22, 55, 25], [22, 45, 15, 13, 46, 16],
154
+ [10, 142, 114, 2, 143, 115], [19, 74, 46, 4, 75, 47], [28, 50, 22, 6, 51, 23], [33, 46, 16, 4, 47, 17],
155
+ [8, 152, 122, 4, 153, 123], [22, 73, 45, 3, 74, 46], [8, 53, 23, 26, 54, 24], [12, 45, 15, 28, 46, 16],
156
+ [3, 147, 117, 10, 148, 118], [3, 73, 45, 23, 74, 46], [4, 54, 24, 31, 55, 25], [11, 45, 15, 31, 46, 16],
157
+ [7, 146, 116, 7, 147, 117], [21, 73, 45, 7, 74, 46], [1, 53, 23, 37, 54, 24], [19, 45, 15, 26, 46, 16],
158
+ [5, 145, 115, 10, 146, 116], [19, 75, 47, 10, 76, 48], [15, 54, 24, 25, 55, 25], [23, 45, 15, 25, 46, 16],
159
+ [13, 145, 115, 3, 146, 116], [2, 74, 46, 29, 75, 47], [42, 54, 24, 1, 55, 25], [23, 45, 15, 28, 46, 16],
160
+ [17, 145, 115], [10, 74, 46, 23, 75, 47], [10, 54, 24, 35, 55, 25], [19, 45, 15, 35, 46, 16],
161
+ [17, 145, 115, 1, 146, 116], [14, 74, 46, 21, 75, 47], [29, 54, 24, 19, 55, 25], [11, 45, 15, 46, 46, 16],
162
+ [13, 145, 115, 6, 146, 116], [14, 74, 46, 23, 75, 47], [44, 54, 24, 7, 55, 25], [59, 46, 16, 1, 47, 17],
163
+ [12, 151, 121, 7, 152, 122], [12, 75, 47, 26, 76, 48], [39, 54, 24, 14, 55, 25], [22, 45, 15, 41, 46, 16],
164
+ [6, 151, 121, 14, 152, 122], [6, 75, 47, 34, 76, 48], [46, 54, 24, 10, 55, 25], [2, 45, 15, 64, 46, 16],
165
+ [17, 152, 122, 4, 153, 123], [29, 74, 46, 14, 75, 47], [49, 54, 24, 10, 55, 25], [24, 45, 15, 46, 46, 16],
166
+ [4, 152, 122, 18, 153, 123], [13, 74, 46, 32, 75, 47], [48, 54, 24, 14, 55, 25], [42, 45, 15, 32, 46, 16],
167
+ [20, 147, 117, 4, 148, 118], [40, 75, 47, 7, 76, 48], [43, 54, 24, 22, 55, 25], [10, 45, 15, 67, 46, 16],
168
+ [19, 148, 118, 6, 149, 119], [18, 75, 47, 31, 76, 48], [34, 54, 24, 34, 55, 25], [20, 45, 15, 61, 46, 16],
169
+ ]
170
+ QRRSBlock.getRSBlocks = function (typeNumber, errorCorrectLevel) {
171
+ const rsBlock = QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel)
172
+ if (rsBlock === undefined) throw new Error(`bad rs block @ typeNumber:${typeNumber}/errorCorrectLevel:${errorCorrectLevel}`)
173
+ const length = rsBlock.length / 3
174
+ const list = []
175
+ for (let i = 0; i < length; i++) {
176
+ const count = rsBlock[i * 3 + 0]
177
+ const totalCount = rsBlock[i * 3 + 1]
178
+ const dataCount = rsBlock[i * 3 + 2]
179
+ for (let j = 0; j < count; j++) list.push(new QRRSBlock(totalCount, dataCount))
180
+ }
181
+ return list
182
+ }
183
+ QRRSBlock.getRsBlockTable = function (typeNumber, errorCorrectLevel) {
184
+ switch (errorCorrectLevel) {
185
+ case QRErrorCorrectLevel.L: return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0]
186
+ case QRErrorCorrectLevel.M: return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1]
187
+ case QRErrorCorrectLevel.Q: return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2]
188
+ case QRErrorCorrectLevel.H: return QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3]
189
+ default: return undefined
190
+ }
191
+ }
192
+
193
+ const QRUtil = {
194
+ PATTERN_POSITION_TABLE: [
195
+ [], [6, 18], [6, 22], [6, 26], [6, 30], [6, 34], [6, 22, 38], [6, 24, 42], [6, 26, 46], [6, 28, 50],
196
+ [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],
197
+ [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],
198
+ [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],
199
+ [6, 30, 54, 78, 102, 126], [6, 26, 52, 78, 104, 130], [6, 30, 56, 82, 108, 134], [6, 34, 60, 86, 112, 138],
200
+ [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],
201
+ [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],
202
+ ],
203
+ G15: (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0),
204
+ G18: (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0),
205
+ G15_MASK: (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1),
206
+ getBCHTypeInfo(data) {
207
+ let d = data << 10
208
+ while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
209
+ d ^= QRUtil.G15 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15))
210
+ }
211
+ return ((data << 10) | d) ^ QRUtil.G15_MASK
212
+ },
213
+ getBCHTypeNumber(data) {
214
+ let d = data << 12
215
+ while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
216
+ d ^= QRUtil.G18 << (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18))
217
+ }
218
+ return (data << 12) | d
219
+ },
220
+ getBCHDigit(data) {
221
+ let digit = 0
222
+ while (data !== 0) { digit++; data >>>= 1 }
223
+ return digit
224
+ },
225
+ getPatternPosition(typeNumber) { return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1] },
226
+ getMask(maskPattern, i, j) {
227
+ switch (maskPattern) {
228
+ case QRMaskPattern.PATTERN000: return (i + j) % 2 === 0
229
+ case QRMaskPattern.PATTERN001: return i % 2 === 0
230
+ case QRMaskPattern.PATTERN010: return j % 3 === 0
231
+ case QRMaskPattern.PATTERN011: return (i + j) % 3 === 0
232
+ case QRMaskPattern.PATTERN100: return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 === 0
233
+ case QRMaskPattern.PATTERN101: return ((i * j) % 2) + ((i * j) % 3) === 0
234
+ case QRMaskPattern.PATTERN110: return (((i * j) % 2) + ((i * j) % 3)) % 2 === 0
235
+ case QRMaskPattern.PATTERN111: return (((i * j) % 3) + ((i + j) % 2)) % 2 === 0
236
+ default: throw new Error(`bad maskPattern:${maskPattern}`)
237
+ }
238
+ },
239
+ getErrorCorrectPolynomial(errorCorrectLength) {
240
+ let a = new QRPolynomial([1], 0)
241
+ for (let i = 0; i < errorCorrectLength; i++) a = a.multiply(new QRPolynomial([1, QRMath.gexp(i)], 0))
242
+ return a
243
+ },
244
+ getLengthInBits(mode, type) {
245
+ if (type >= 1 && type < 10) {
246
+ switch (mode) {
247
+ case QRMode.MODE_NUMBER: return 10
248
+ case QRMode.MODE_ALPHA_NUM: return 9
249
+ case QRMode.MODE_8BIT_BYTE: return 8
250
+ case QRMode.MODE_KANJI: return 8
251
+ default: throw new Error(`mode:${mode}`)
252
+ }
253
+ } else if (type < 27) {
254
+ switch (mode) {
255
+ case QRMode.MODE_NUMBER: return 12
256
+ case QRMode.MODE_ALPHA_NUM: return 11
257
+ case QRMode.MODE_8BIT_BYTE: return 16
258
+ case QRMode.MODE_KANJI: return 10
259
+ default: throw new Error(`mode:${mode}`)
260
+ }
261
+ } else if (type < 41) {
262
+ switch (mode) {
263
+ case QRMode.MODE_NUMBER: return 14
264
+ case QRMode.MODE_ALPHA_NUM: return 13
265
+ case QRMode.MODE_8BIT_BYTE: return 16
266
+ case QRMode.MODE_KANJI: return 12
267
+ default: throw new Error(`mode:${mode}`)
268
+ }
269
+ }
270
+ throw new Error(`type:${type}`)
271
+ },
272
+ getLostPoint(qrCode) {
273
+ const moduleCount = qrCode.getModuleCount()
274
+ let lostPoint = 0
275
+ for (let row = 0; row < moduleCount; row++) {
276
+ for (let col = 0; col < moduleCount; col++) {
277
+ let sameCount = 0
278
+ const dark = qrCode.isDark(row, col)
279
+ for (let r = -1; r <= 1; r++) {
280
+ if (row + r < 0 || moduleCount <= row + r) continue
281
+ for (let c = -1; c <= 1; c++) {
282
+ if (col + c < 0 || moduleCount <= col + c) continue
283
+ if (r === 0 && c === 0) continue
284
+ if (dark === qrCode.isDark(row + r, col + c)) sameCount++
285
+ }
286
+ }
287
+ if (sameCount > 5) lostPoint += 3 + sameCount - 5
288
+ }
289
+ }
290
+ for (let row = 0; row < moduleCount - 1; row++) {
291
+ for (let col = 0; col < moduleCount - 1; col++) {
292
+ let count = 0
293
+ if (qrCode.isDark(row, col)) count++
294
+ if (qrCode.isDark(row + 1, col)) count++
295
+ if (qrCode.isDark(row, col + 1)) count++
296
+ if (qrCode.isDark(row + 1, col + 1)) count++
297
+ if (count === 0 || count === 4) lostPoint += 3
298
+ }
299
+ }
300
+ for (let row = 0; row < moduleCount; row++) {
301
+ for (let col = 0; col < moduleCount - 6; col++) {
302
+ if (qrCode.isDark(row, col)
303
+ && !qrCode.isDark(row, col + 1)
304
+ && qrCode.isDark(row, col + 2)
305
+ && qrCode.isDark(row, col + 3)
306
+ && qrCode.isDark(row, col + 4)
307
+ && !qrCode.isDark(row, col + 5)
308
+ && qrCode.isDark(row, col + 6)) {
309
+ lostPoint += 40
310
+ }
311
+ }
312
+ }
313
+ for (let col = 0; col < moduleCount; col++) {
314
+ for (let row = 0; row < moduleCount - 6; row++) {
315
+ if (qrCode.isDark(row, col)
316
+ && !qrCode.isDark(row + 1, col)
317
+ && qrCode.isDark(row + 2, col)
318
+ && qrCode.isDark(row + 3, col)
319
+ && qrCode.isDark(row + 4, col)
320
+ && !qrCode.isDark(row + 5, col)
321
+ && qrCode.isDark(row + 6, col)) {
322
+ lostPoint += 40
323
+ }
324
+ }
325
+ }
326
+ let darkCount = 0
327
+ for (let col = 0; col < moduleCount; col++) {
328
+ for (let row = 0; row < moduleCount; row++) {
329
+ if (qrCode.isDark(row, col)) darkCount++
330
+ }
331
+ }
332
+ const ratio = Math.abs((100 * darkCount) / moduleCount / moduleCount - 50) / 5
333
+ lostPoint += ratio * 10
334
+ return lostPoint
335
+ },
336
+ }
337
+
338
+ function QRCode(typeNumber, errorCorrectLevel) {
339
+ this.typeNumber = typeNumber
340
+ this.errorCorrectLevel = errorCorrectLevel
341
+ this.modules = null
342
+ this.moduleCount = 0
343
+ this.dataCache = null
344
+ this.dataList = []
345
+ }
346
+ QRCode.prototype = {
347
+ addData(data) {
348
+ this.dataList.push(new QR8bitByte(data))
349
+ this.dataCache = null
350
+ },
351
+ isDark(row, col) {
352
+ if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) throw new Error(`${row},${col}`)
353
+ return this.modules[row][col]
354
+ },
355
+ getModuleCount() { return this.moduleCount },
356
+ make() {
357
+ if (this.typeNumber < 1) {
358
+ let typeNumber = 1
359
+ for (typeNumber = 1; typeNumber < 40; typeNumber++) {
360
+ const rsBlocks = QRRSBlock.getRSBlocks(typeNumber, this.errorCorrectLevel)
361
+ const buffer = new QRBitBuffer()
362
+ let totalDataCount = 0
363
+ for (let i = 0; i < rsBlocks.length; i++) totalDataCount += rsBlocks[i].dataCount
364
+ for (let x = 0; x < this.dataList.length; x++) {
365
+ const data = this.dataList[x]
366
+ buffer.put(data.mode, 4)
367
+ buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber))
368
+ data.write(buffer)
369
+ }
370
+ if (buffer.getLengthInBits() <= totalDataCount * 8) break
371
+ }
372
+ this.typeNumber = typeNumber
373
+ }
374
+ this.makeImpl(false, this.getBestMaskPattern())
375
+ },
376
+ makeImpl(test, maskPattern) {
377
+ this.moduleCount = this.typeNumber * 4 + 17
378
+ this.modules = new Array(this.moduleCount)
379
+ for (let row = 0; row < this.moduleCount; row++) {
380
+ this.modules[row] = new Array(this.moduleCount)
381
+ for (let col = 0; col < this.moduleCount; col++) this.modules[row][col] = null
382
+ }
383
+ this.setupPositionProbePattern(0, 0)
384
+ this.setupPositionProbePattern(this.moduleCount - 7, 0)
385
+ this.setupPositionProbePattern(0, this.moduleCount - 7)
386
+ this.setupPositionAdjustPattern()
387
+ this.setupTimingPattern()
388
+ this.setupTypeInfo(test, maskPattern)
389
+ if (this.typeNumber >= 7) this.setupTypeNumber(test)
390
+ if (this.dataCache === null) this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList)
391
+ this.mapData(this.dataCache, maskPattern)
392
+ },
393
+ setupPositionProbePattern(row, col) {
394
+ for (let r = -1; r <= 7; r++) {
395
+ if (row + r <= -1 || this.moduleCount <= row + r) continue
396
+ for (let c = -1; c <= 7; c++) {
397
+ if (col + c <= -1 || this.moduleCount <= col + c) continue
398
+ if ((r >= 0 && r <= 6 && (c === 0 || c === 6))
399
+ || (c >= 0 && c <= 6 && (r === 0 || r === 6))
400
+ || (r >= 2 && r <= 4 && c >= 2 && c <= 4)) {
401
+ this.modules[row + r][col + c] = true
402
+ } else {
403
+ this.modules[row + r][col + c] = false
404
+ }
405
+ }
406
+ }
407
+ },
408
+ getBestMaskPattern() {
409
+ let minLostPoint = 0
410
+ let pattern = 0
411
+ for (let i = 0; i < 8; i++) {
412
+ this.makeImpl(true, i)
413
+ const lostPoint = QRUtil.getLostPoint(this)
414
+ if (i === 0 || minLostPoint > lostPoint) {
415
+ minLostPoint = lostPoint
416
+ pattern = i
417
+ }
418
+ }
419
+ return pattern
420
+ },
421
+ setupTimingPattern() {
422
+ for (let r = 8; r < this.moduleCount - 8; r++) {
423
+ if (this.modules[r][6] !== null) continue
424
+ this.modules[r][6] = r % 2 === 0
425
+ }
426
+ for (let c = 8; c < this.moduleCount - 8; c++) {
427
+ if (this.modules[6][c] !== null) continue
428
+ this.modules[6][c] = c % 2 === 0
429
+ }
430
+ },
431
+ setupPositionAdjustPattern() {
432
+ const pos = QRUtil.getPatternPosition(this.typeNumber)
433
+ for (let i = 0; i < pos.length; i++) {
434
+ for (let j = 0; j < pos.length; j++) {
435
+ const row = pos[i]
436
+ const col = pos[j]
437
+ if (this.modules[row][col] !== null) continue
438
+ for (let r = -2; r <= 2; r++) {
439
+ for (let c = -2; c <= 2; c++) {
440
+ if (Math.abs(r) === 2 || Math.abs(c) === 2 || (r === 0 && c === 0)) {
441
+ this.modules[row + r][col + c] = true
442
+ } else {
443
+ this.modules[row + r][col + c] = false
444
+ }
445
+ }
446
+ }
447
+ }
448
+ }
449
+ },
450
+ setupTypeNumber(test) {
451
+ const bits = QRUtil.getBCHTypeNumber(this.typeNumber)
452
+ for (let i = 0; i < 18; i++) {
453
+ const mod = !test && ((bits >> i) & 1) === 1
454
+ this.modules[Math.floor(i / 3)][(i % 3) + this.moduleCount - 8 - 3] = mod
455
+ }
456
+ for (let x = 0; x < 18; x++) {
457
+ const mod = !test && ((bits >> x) & 1) === 1
458
+ this.modules[(x % 3) + this.moduleCount - 8 - 3][Math.floor(x / 3)] = mod
459
+ }
460
+ },
461
+ setupTypeInfo(test, maskPattern) {
462
+ const data = (this.errorCorrectLevel << 3) | maskPattern
463
+ const bits = QRUtil.getBCHTypeInfo(data)
464
+ for (let v = 0; v < 15; v++) {
465
+ const mod = !test && ((bits >> v) & 1) === 1
466
+ if (v < 6) this.modules[v][8] = mod
467
+ else if (v < 8) this.modules[v + 1][8] = mod
468
+ else this.modules[this.moduleCount - 15 + v][8] = mod
469
+ }
470
+ for (let h = 0; h < 15; h++) {
471
+ const mod = !test && ((bits >> h) & 1) === 1
472
+ if (h < 8) this.modules[8][this.moduleCount - h - 1] = mod
473
+ else if (h < 9) this.modules[8][15 - h - 1 + 1] = mod
474
+ else this.modules[8][15 - h - 1] = mod
475
+ }
476
+ this.modules[this.moduleCount - 8][8] = !test
477
+ },
478
+ mapData(data, maskPattern) {
479
+ let inc = -1
480
+ let row = this.moduleCount - 1
481
+ let bitIndex = 7
482
+ let byteIndex = 0
483
+ for (let col = this.moduleCount - 1; col > 0; col -= 2) {
484
+ if (col === 6) col--
485
+ while (true) {
486
+ for (let c = 0; c < 2; c++) {
487
+ if (this.modules[row][col - c] === null) {
488
+ let dark = false
489
+ if (byteIndex < data.length) dark = ((data[byteIndex] >>> bitIndex) & 1) === 1
490
+ const mask = QRUtil.getMask(maskPattern, row, col - c)
491
+ if (mask) dark = !dark
492
+ this.modules[row][col - c] = dark
493
+ bitIndex--
494
+ if (bitIndex === -1) { byteIndex++; bitIndex = 7 }
495
+ }
496
+ }
497
+ row += inc
498
+ if (row < 0 || this.moduleCount <= row) {
499
+ row -= inc
500
+ inc = -inc
501
+ break
502
+ }
503
+ }
504
+ }
505
+ },
506
+ }
507
+ QRCode.PAD0 = 0xEC
508
+ QRCode.PAD1 = 0x11
509
+ QRCode.createData = function (typeNumber, errorCorrectLevel, dataList) {
510
+ const rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel)
511
+ const buffer = new QRBitBuffer()
512
+ for (let i = 0; i < dataList.length; i++) {
513
+ const data = dataList[i]
514
+ buffer.put(data.mode, 4)
515
+ buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, typeNumber))
516
+ data.write(buffer)
517
+ }
518
+ let totalDataCount = 0
519
+ for (let x = 0; x < rsBlocks.length; x++) totalDataCount += rsBlocks[x].dataCount
520
+ if (buffer.getLengthInBits() > totalDataCount * 8) {
521
+ throw new Error(`code length overflow. (${buffer.getLengthInBits()}>${totalDataCount * 8})`)
522
+ }
523
+ if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) buffer.put(0, 4)
524
+ while (buffer.getLengthInBits() % 8 !== 0) buffer.putBit(false)
525
+ while (true) {
526
+ if (buffer.getLengthInBits() >= totalDataCount * 8) break
527
+ buffer.put(QRCode.PAD0, 8)
528
+ if (buffer.getLengthInBits() >= totalDataCount * 8) break
529
+ buffer.put(QRCode.PAD1, 8)
530
+ }
531
+ return QRCode.createBytes(buffer, rsBlocks)
532
+ }
533
+ QRCode.createBytes = function (buffer, rsBlocks) {
534
+ let offset = 0
535
+ let maxDcCount = 0
536
+ let maxEcCount = 0
537
+ const dcdata = new Array(rsBlocks.length)
538
+ const ecdata = new Array(rsBlocks.length)
539
+ for (let r = 0; r < rsBlocks.length; r++) {
540
+ const dcCount = rsBlocks[r].dataCount
541
+ const ecCount = rsBlocks[r].totalCount - dcCount
542
+ maxDcCount = Math.max(maxDcCount, dcCount)
543
+ maxEcCount = Math.max(maxEcCount, ecCount)
544
+ dcdata[r] = new Array(dcCount)
545
+ for (let i = 0; i < dcdata[r].length; i++) dcdata[r][i] = 0xff & buffer.buffer[i + offset]
546
+ offset += dcCount
547
+ const rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount)
548
+ const rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1)
549
+ const modPoly = rawPoly.mod(rsPoly)
550
+ ecdata[r] = new Array(rsPoly.getLength() - 1)
551
+ for (let x = 0; x < ecdata[r].length; x++) {
552
+ const modIndex = x + modPoly.getLength() - ecdata[r].length
553
+ ecdata[r][x] = modIndex >= 0 ? modPoly.get(modIndex) : 0
554
+ }
555
+ }
556
+ let totalCodeCount = 0
557
+ for (let y = 0; y < rsBlocks.length; y++) totalCodeCount += rsBlocks[y].totalCount
558
+ const data = new Array(totalCodeCount)
559
+ let index = 0
560
+ for (let z = 0; z < maxDcCount; z++) {
561
+ for (let s = 0; s < rsBlocks.length; s++) {
562
+ if (z < dcdata[s].length) data[index++] = dcdata[s][z]
563
+ }
564
+ }
565
+ for (let xx = 0; xx < maxEcCount; xx++) {
566
+ for (let t = 0; t < rsBlocks.length; t++) {
567
+ if (xx < ecdata[t].length) data[index++] = ecdata[t][xx]
568
+ }
569
+ }
570
+ return data
571
+ }
572
+
573
+ /**
574
+ * Encode `text` into a QR matrix. Returns the module count and a count×count
575
+ * grid of 0/1 cells (row-major) for the browser to render.
576
+ * @param {string} text - payload to encode (8-bit byte mode).
577
+ * @returns {{ count: number, modules: number[][] }}
578
+ */
579
+ export function encodeQrMatrix(text) {
580
+ const qr = new QRCode(-1, QRErrorCorrectLevel.L)
581
+ qr.addData(text)
582
+ qr.make()
583
+ const count = qr.getModuleCount()
584
+ const modules = []
585
+ for (let r = 0; r < count; r++) {
586
+ const row = []
587
+ for (let c = 0; c < count; c++) row.push(qr.isDark(r, c) ? 1 : 0)
588
+ modules.push(row)
589
+ }
590
+ return { count, modules }
591
+ }