@sythos/js_barcode_universal 1.5.8 → 1.5.9

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.
Files changed (179) hide show
  1. package/LICENSE +5 -4
  2. package/NOTICE.md +2 -2
  3. package/README.md +17 -13
  4. package/bundle/sythos-barcode.esm.js +11658 -11244
  5. package/bundle/sythos-barcode.js +11658 -11244
  6. package/package.json +10 -3
  7. package/src/index.d.ts +1 -1
  8. package/src/index.js +508 -516
  9. package/src/js/aztec/decoder.js +208 -199
  10. package/src/js/aztec/detector.js +153 -126
  11. package/src/js/aztec/encoder.js +172 -153
  12. package/src/js/aztec/high-level.js +106 -101
  13. package/src/js/aztec/index.js +1 -12
  14. package/src/js/aztec/tables.js +106 -120
  15. package/src/js/aztecrune/decoder.js +76 -85
  16. package/src/js/aztecrune/detector.js +107 -93
  17. package/src/js/aztecrune/encoder.js +50 -68
  18. package/src/js/aztecrune/index.js +1 -16
  19. package/src/js/aztecrune/tables.js +59 -54
  20. package/src/js/compactpdf417/decoder.js +69 -74
  21. package/src/js/compactpdf417/detector.js +74 -75
  22. package/src/js/compactpdf417/encoder.js +68 -81
  23. package/src/js/compactpdf417/index.js +1 -13
  24. package/src/js/compactpdf417/tables.js +71 -80
  25. package/src/js/core/bit-buffer.js +106 -122
  26. package/src/js/core/bit-matrix.js +196 -194
  27. package/src/js/core/errors.js +13 -15
  28. package/src/js/core/galois-field.js +119 -133
  29. package/src/js/core/index.js +2 -19
  30. package/src/js/core/reed-solomon.js +195 -204
  31. package/src/js/databar/codec.js +93 -108
  32. package/src/js/databar/decoder.js +149 -140
  33. package/src/js/databar/encoder.js +47 -55
  34. package/src/js/databar/gs1.js +122 -123
  35. package/src/js/databar/index.js +4 -36
  36. package/src/js/databar/patterns.js +81 -85
  37. package/src/js/databar/tables.js +51 -52
  38. package/src/js/datamatrix/decoder.js +216 -182
  39. package/src/js/datamatrix/detector.js +161 -132
  40. package/src/js/datamatrix/encoder.js +192 -133
  41. package/src/js/datamatrix/index.js +1 -9
  42. package/src/js/datamatrix/tables.js +68 -69
  43. package/src/js/frameqr/decoder.js +102 -125
  44. package/src/js/frameqr/detector.js +101 -94
  45. package/src/js/frameqr/encoder.js +67 -80
  46. package/src/js/frameqr/index.js +1 -10
  47. package/src/js/frameqr/tables.js +145 -163
  48. package/src/js/image/binarizer.js +146 -162
  49. package/src/js/image/grid-sampler.js +63 -79
  50. package/src/js/image/index.js +0 -2
  51. package/src/js/image/luminance.js +129 -140
  52. package/src/js/image/perspective.js +112 -149
  53. package/src/js/micropdf417/compaction.js +64 -65
  54. package/src/js/micropdf417/decoder.js +106 -109
  55. package/src/js/micropdf417/detector.js +73 -70
  56. package/src/js/micropdf417/encoder.js +129 -154
  57. package/src/js/micropdf417/error-correction.js +6 -11
  58. package/src/js/micropdf417/index.js +2 -16
  59. package/src/js/micropdf417/tables.js +112 -99
  60. package/src/js/microqr/decoder.js +177 -182
  61. package/src/js/microqr/detector.js +240 -256
  62. package/src/js/microqr/encoder.js +239 -194
  63. package/src/js/microqr/index.js +0 -2
  64. package/src/js/microqr/tables.js +208 -200
  65. package/src/js/oned/addons.js +167 -191
  66. package/src/js/oned/index.js +27 -58
  67. package/src/js/oned/patterns.js +194 -213
  68. package/src/js/oned/reader.js +1003 -984
  69. package/src/js/oned/writers.js +411 -466
  70. package/src/js/pdf417/compaction.js +315 -222
  71. package/src/js/pdf417/decoder.js +71 -36
  72. package/src/js/pdf417/detector.js +377 -361
  73. package/src/js/pdf417/encoder.js +57 -46
  74. package/src/js/pdf417/error-correction.js +5 -8
  75. package/src/js/pdf417/tables.js +248 -250
  76. package/src/js/qr/decoder.js +311 -347
  77. package/src/js/qr/detector.js +378 -395
  78. package/src/js/qr/encoder.js +514 -599
  79. package/src/js/qr/index.js +0 -2
  80. package/src/js/qr/tables.js +375 -422
  81. package/src/js/render/image-data.js +57 -62
  82. package/src/js/render/index.js +21 -23
  83. package/src/js/render/options.js +82 -90
  84. package/src/js/render/png.js +144 -169
  85. package/src/js/render/svg.js +41 -44
  86. package/src/js/render/webgl.js +103 -109
  87. package/src/js/render/webgpu.js +205 -217
  88. package/src/js/rmqr/decoder.js +161 -53
  89. package/src/js/rmqr/detector.js +73 -41
  90. package/src/js/rmqr/encoder.js +253 -104
  91. package/src/js/rmqr/index.js +1 -5
  92. package/src/js/rmqr/tables.js +108 -85
  93. package/src/ts/aztec/decoder.ts +317 -0
  94. package/src/ts/aztec/detector.ts +224 -0
  95. package/src/ts/aztec/encoder.ts +257 -0
  96. package/src/ts/aztec/high-level.ts +211 -0
  97. package/src/ts/aztec/index.ts +45 -0
  98. package/src/ts/aztec/tables.ts +210 -0
  99. package/src/ts/aztecrune/decoder.ts +155 -0
  100. package/src/ts/aztecrune/detector.ts +166 -0
  101. package/src/ts/aztecrune/encoder.ts +121 -0
  102. package/src/ts/aztecrune/index.ts +49 -0
  103. package/src/ts/aztecrune/tables.ts +137 -0
  104. package/src/ts/compactpdf417/decoder.ts +128 -0
  105. package/src/ts/compactpdf417/detector.ts +139 -0
  106. package/src/ts/compactpdf417/encoder.ts +140 -0
  107. package/src/ts/compactpdf417/index.ts +17 -0
  108. package/src/ts/compactpdf417/tables.ts +173 -0
  109. package/src/ts/core/bit-buffer.ts +174 -0
  110. package/src/ts/core/bit-matrix.ts +241 -0
  111. package/src/ts/core/errors.ts +61 -0
  112. package/src/ts/core/galois-field.ts +207 -0
  113. package/src/ts/core/index.ts +56 -0
  114. package/src/ts/core/reed-solomon.ts +327 -0
  115. package/src/ts/databar/codec.ts +181 -0
  116. package/src/ts/databar/decoder.ts +215 -0
  117. package/src/ts/databar/encoder.ts +96 -0
  118. package/src/ts/databar/gs1.ts +177 -0
  119. package/src/ts/databar/index.ts +68 -0
  120. package/src/ts/databar/patterns.ts +143 -0
  121. package/src/ts/databar/tables.ts +124 -0
  122. package/src/ts/datamatrix/decoder.ts +262 -0
  123. package/src/ts/datamatrix/detector.ts +225 -0
  124. package/src/ts/datamatrix/encoder.ts +191 -0
  125. package/src/ts/datamatrix/index.ts +42 -0
  126. package/src/ts/datamatrix/tables.ts +123 -0
  127. package/src/ts/frameqr/decoder.ts +239 -0
  128. package/src/ts/frameqr/detector.ts +192 -0
  129. package/src/ts/frameqr/encoder.ts +156 -0
  130. package/src/ts/frameqr/index.ts +42 -0
  131. package/src/ts/frameqr/tables.ts +270 -0
  132. package/src/ts/image/binarizer.ts +270 -0
  133. package/src/ts/image/grid-sampler.ts +164 -0
  134. package/src/ts/image/index.ts +40 -0
  135. package/src/ts/image/luminance.ts +196 -0
  136. package/src/ts/image/perspective.ts +195 -0
  137. package/src/ts/index.d.ts +1 -1
  138. package/src/ts/index.ts +790 -0
  139. package/src/ts/micropdf417/compaction.ts +116 -0
  140. package/src/ts/micropdf417/decoder.ts +183 -0
  141. package/src/ts/micropdf417/detector.ts +149 -0
  142. package/src/ts/micropdf417/encoder.ts +209 -0
  143. package/src/ts/micropdf417/error-correction.ts +55 -0
  144. package/src/ts/micropdf417/index.ts +49 -0
  145. package/src/ts/micropdf417/tables.ts +184 -0
  146. package/src/ts/microqr/decoder.ts +245 -0
  147. package/src/ts/microqr/detector.ts +355 -0
  148. package/src/ts/microqr/encoder.ts +269 -0
  149. package/src/ts/microqr/index.ts +36 -0
  150. package/src/ts/microqr/tables.ts +316 -0
  151. package/src/ts/oned/addons.ts +420 -0
  152. package/src/ts/oned/index.ts +106 -0
  153. package/src/ts/oned/patterns.ts +384 -0
  154. package/src/ts/oned/reader.ts +1364 -0
  155. package/src/ts/oned/writers.ts +746 -0
  156. package/src/ts/pdf417/compaction.ts +298 -0
  157. package/src/ts/pdf417/decoder.ts +75 -0
  158. package/src/ts/pdf417/detector.ts +468 -0
  159. package/src/ts/pdf417/encoder.ts +91 -0
  160. package/src/ts/pdf417/error-correction.ts +47 -0
  161. package/src/ts/pdf417/index.ts +6 -0
  162. package/src/ts/pdf417/tables.ts +317 -0
  163. package/src/ts/qr/decoder.ts +575 -0
  164. package/src/ts/qr/detector.ts +630 -0
  165. package/src/ts/qr/encoder.ts +958 -0
  166. package/src/ts/qr/index.ts +44 -0
  167. package/src/ts/qr/tables.ts +737 -0
  168. package/src/ts/render/image-data.ts +125 -0
  169. package/src/ts/render/index.ts +130 -0
  170. package/src/ts/render/options.ts +160 -0
  171. package/src/ts/render/png.ts +295 -0
  172. package/src/ts/render/svg.ts +120 -0
  173. package/src/ts/render/webgl.ts +206 -0
  174. package/src/ts/render/webgpu.ts +369 -0
  175. package/src/ts/rmqr/decoder.ts +101 -0
  176. package/src/ts/rmqr/detector.ts +90 -0
  177. package/src/ts/rmqr/encoder.ts +172 -0
  178. package/src/ts/rmqr/index.ts +37 -0
  179. package/src/ts/rmqr/tables.ts +154 -0
@@ -27,7 +27,6 @@
27
27
  *
28
28
  * Original work. No code from any other barcode implementation.
29
29
  */
30
-
31
30
  /**
32
31
  * Linear barcode writers.
33
32
  *
@@ -38,24 +37,12 @@
38
37
  *
39
38
  * @module oned/writers
40
39
  */
41
-
42
40
  import { BitMatrix } from '../core/bit-matrix.js';
43
41
  import { EncodeError } from '../core/errors.js';
44
- import {
45
- EAN_L, EAN_G, EAN_R, EAN13_PARITY, UPCE_PARITY,
46
- EAN_START_END, EAN_MIDDLE, UPCE_END,
47
- CODE39, CODE39_CHECK_SET, CODE39_EXTENDED,
48
- CODE93, CODE93_VALUES, CODE93_START_STOP,
49
- CODE128, CODE128_START_B, CODE128_START_C,
50
- CODE128_STOP, CODE128_FNC1, CODE128_CODE_A, CODE128_CODE_B, CODE128_CODE_C,
51
- ITF, CODABAR, CODABAR_START_STOP, CODE11, CODE11_START_STOP,
52
- MSI_BIT, MSI_START, MSI_STOP,
53
- } from './patterns.js';
54
-
42
+ import { EAN_L, EAN_G, EAN_R, EAN13_PARITY, UPCE_PARITY, EAN_START_END, EAN_MIDDLE, UPCE_END, CODE39, CODE39_CHECK_SET, CODE39_EXTENDED, CODE93, CODE93_VALUES, CODE93_START_STOP, CODE128, CODE128_START_B, CODE128_START_C, CODE128_STOP, CODE128_FNC1, CODE128_CODE_A, CODE128_CODE_B, CODE128_CODE_C, ITF, CODABAR, CODABAR_START_STOP, CODE11, CODE11_START_STOP, MSI_BIT, MSI_START, MSI_STOP, } from './patterns.js';
55
43
  /* ------------------------------------------------------------------ *
56
44
  * Shared helpers
57
45
  * ------------------------------------------------------------------ */
58
-
59
46
  /**
60
47
  * Expand an n/w width pattern into a module string, starting with a bar.
61
48
  *
@@ -64,14 +51,13 @@ import {
64
51
  * @returns {string} Module string, '1' = dark.
65
52
  */
66
53
  function expandNarrowWide(pattern, wide = 3) {
67
- let out = '';
68
- for (let i = 0; i < pattern.length; i++) {
69
- const width = pattern[i] === 'w' ? wide : 1;
70
- out += (i % 2 === 0 ? '1' : '0').repeat(width);
71
- }
72
- return out;
54
+ let out = '';
55
+ for (let i = 0; i < pattern.length; i++) {
56
+ const width = pattern[i] === 'w' ? wide : 1;
57
+ out += (i % 2 === 0 ? '1' : '0').repeat(width);
58
+ }
59
+ return out;
73
60
  }
74
-
75
61
  /**
76
62
  * Expand a digit-width pattern into a module string, starting with a bar.
77
63
  *
@@ -79,35 +65,33 @@ function expandNarrowWide(pattern, wide = 3) {
79
65
  * @returns {string}
80
66
  */
81
67
  function expandWidths(pattern) {
82
- let out = '';
83
- for (let i = 0; i < pattern.length; i++) {
84
- out += (i % 2 === 0 ? '1' : '0').repeat(Number(pattern[i]));
85
- }
86
- return out;
68
+ let out = '';
69
+ for (let i = 0; i < pattern.length; i++) {
70
+ out += (i % 2 === 0 ? '1' : '0').repeat(Number(pattern[i]));
71
+ }
72
+ return out;
87
73
  }
88
-
89
74
  /**
90
75
  * @param {string} modules
91
76
  * @returns {BitMatrix} One row tall.
92
77
  */
93
78
  function toMatrix(modules) {
94
- const m = new BitMatrix(modules.length, 1);
95
- for (let x = 0; x < modules.length; x++) {
96
- if (modules[x] === '1') m.set(x, 0);
97
- }
98
- return m;
79
+ const m = new BitMatrix(modules.length, 1);
80
+ for (let x = 0; x < modules.length; x++) {
81
+ if (modules[x] === '1')
82
+ m.set(x, 0);
83
+ }
84
+ return m;
99
85
  }
100
-
101
86
  /**
102
87
  * @param {string} value
103
88
  * @param {string} format
104
89
  */
105
90
  function requireDigits(value, format) {
106
- if (!/^[0-9]+$/.test(value)) {
107
- throw new EncodeError(`${format}: payload must be digits only, got "${value}"`);
108
- }
91
+ if (!/^[0-9]+$/.test(value)) {
92
+ throw new EncodeError(`${format}: payload must be digits only, got "${value}"`);
93
+ }
109
94
  }
110
-
111
95
  /**
112
96
  * Modulo-10 check digit for the EAN/UPC family.
113
97
  *
@@ -120,18 +104,16 @@ function requireDigits(value, format) {
120
104
  * @returns {number}
121
105
  */
122
106
  export function ean13CheckDigit(payload) {
123
- let sum = 0;
124
- for (let i = 0; i < payload.length; i++) {
125
- const fromRight = payload.length - 1 - i;
126
- sum += Number(payload[i]) * (fromRight % 2 === 0 ? 3 : 1);
127
- }
128
- return (10 - (sum % 10)) % 10;
107
+ let sum = 0;
108
+ for (let i = 0; i < payload.length; i++) {
109
+ const fromRight = payload.length - 1 - i;
110
+ sum += Number(payload[i]) * (fromRight % 2 === 0 ? 3 : 1);
111
+ }
112
+ return (10 - (sum % 10)) % 10;
129
113
  }
130
-
131
114
  /* ------------------------------------------------------------------ *
132
115
  * EAN / UPC
133
116
  * ------------------------------------------------------------------ */
134
-
135
117
  /**
136
118
  * EAN-13. Accepts 12 digits (check digit appended) or 13 (verified).
137
119
  *
@@ -139,32 +121,32 @@ export function ean13CheckDigit(payload) {
139
121
  * @returns {BitMatrix}
140
122
  */
141
123
  export function encodeEAN13(value) {
142
- requireDigits(value, 'EAN-13');
143
- let digits = value;
144
- if (digits.length === 12) {
145
- digits += String(ean13CheckDigit(digits));
146
- } else if (digits.length === 13) {
147
- const expected = ean13CheckDigit(digits.slice(0, 12));
148
- if (Number(digits[12]) !== expected) {
149
- throw new EncodeError(`EAN-13: check digit is ${digits[12]}, expected ${expected}`);
150
- }
151
- } else {
152
- throw new EncodeError(`EAN-13: needs 12 or 13 digits, got ${digits.length}`);
153
- }
154
-
155
- const parity = EAN13_PARITY[Number(digits[0])];
156
- let modules = EAN_START_END;
157
- for (let i = 0; i < 6; i++) {
158
- const d = Number(digits[i + 1]);
159
- modules += parity[i] === 'L' ? EAN_L[d] : EAN_G[d];
160
- }
161
- modules += EAN_MIDDLE;
162
- for (let i = 7; i < 13; i++) modules += EAN_R[Number(digits[i])];
163
- modules += EAN_START_END;
164
-
165
- return toMatrix(modules);
124
+ requireDigits(value, 'EAN-13');
125
+ let digits = value;
126
+ if (digits.length === 12) {
127
+ digits += String(ean13CheckDigit(digits));
128
+ }
129
+ else if (digits.length === 13) {
130
+ const expected = ean13CheckDigit(digits.slice(0, 12));
131
+ if (Number(digits[12]) !== expected) {
132
+ throw new EncodeError(`EAN-13: check digit is ${digits[12]}, expected ${expected}`);
133
+ }
134
+ }
135
+ else {
136
+ throw new EncodeError(`EAN-13: needs 12 or 13 digits, got ${digits.length}`);
137
+ }
138
+ const parity = EAN13_PARITY[Number(digits[0])];
139
+ let modules = EAN_START_END;
140
+ for (let i = 0; i < 6; i++) {
141
+ const d = Number(digits[i + 1]);
142
+ modules += parity[i] === 'L' ? EAN_L[d] : EAN_G[d];
143
+ }
144
+ modules += EAN_MIDDLE;
145
+ for (let i = 7; i < 13; i++)
146
+ modules += EAN_R[Number(digits[i])];
147
+ modules += EAN_START_END;
148
+ return toMatrix(modules);
166
149
  }
167
-
168
150
  /**
169
151
  * EAN-8. Accepts 7 digits (check digit appended) or 8 (verified).
170
152
  *
@@ -172,28 +154,29 @@ export function encodeEAN13(value) {
172
154
  * @returns {BitMatrix}
173
155
  */
174
156
  export function encodeEAN8(value) {
175
- requireDigits(value, 'EAN-8');
176
- let digits = value;
177
- if (digits.length === 7) {
178
- digits += String(ean13CheckDigit(digits));
179
- } else if (digits.length === 8) {
180
- const expected = ean13CheckDigit(digits.slice(0, 7));
181
- if (Number(digits[7]) !== expected) {
182
- throw new EncodeError(`EAN-8: check digit is ${digits[7]}, expected ${expected}`);
183
- }
184
- } else {
185
- throw new EncodeError(`EAN-8: needs 7 or 8 digits, got ${digits.length}`);
186
- }
187
-
188
- let modules = EAN_START_END;
189
- for (let i = 0; i < 4; i++) modules += EAN_L[Number(digits[i])];
190
- modules += EAN_MIDDLE;
191
- for (let i = 4; i < 8; i++) modules += EAN_R[Number(digits[i])];
192
- modules += EAN_START_END;
193
-
194
- return toMatrix(modules);
157
+ requireDigits(value, 'EAN-8');
158
+ let digits = value;
159
+ if (digits.length === 7) {
160
+ digits += String(ean13CheckDigit(digits));
161
+ }
162
+ else if (digits.length === 8) {
163
+ const expected = ean13CheckDigit(digits.slice(0, 7));
164
+ if (Number(digits[7]) !== expected) {
165
+ throw new EncodeError(`EAN-8: check digit is ${digits[7]}, expected ${expected}`);
166
+ }
167
+ }
168
+ else {
169
+ throw new EncodeError(`EAN-8: needs 7 or 8 digits, got ${digits.length}`);
170
+ }
171
+ let modules = EAN_START_END;
172
+ for (let i = 0; i < 4; i++)
173
+ modules += EAN_L[Number(digits[i])];
174
+ modules += EAN_MIDDLE;
175
+ for (let i = 4; i < 8; i++)
176
+ modules += EAN_R[Number(digits[i])];
177
+ modules += EAN_START_END;
178
+ return toMatrix(modules);
195
179
  }
196
-
197
180
  /**
198
181
  * ISBN, as its printed EAN-13 ("Bookland") symbol.
199
182
  *
@@ -211,34 +194,29 @@ export function encodeEAN8(value) {
211
194
  * @returns {BitMatrix}
212
195
  */
213
196
  export function encodeISBN(value) {
214
- const cleaned = String(value).replace(/[\s-]/g, '').toUpperCase();
215
-
216
- if (/^[0-9]{9}[0-9X]$/.test(cleaned)) {
217
- // ISBN-10: verify its modulo-11 check, then convert to the 978 form.
218
- let sum = 0;
219
- for (let i = 0; i < 9; i++) sum += Number(cleaned[i]) * (10 - i);
220
- sum += cleaned[9] === 'X' ? 10 : Number(cleaned[9]);
221
- if (sum % 11 !== 0) {
222
- throw new EncodeError(`ISBN-10: check digit "${cleaned[9]}" fails the modulo-11 test`);
223
- }
224
- // The check digit does not carry over — encodeEAN13 computes the new one.
225
- return encodeEAN13('978' + cleaned.slice(0, 9));
226
- }
227
-
228
- if (/^[0-9]{12,13}$/.test(cleaned)) {
229
- const prefix = cleaned.slice(0, 3);
230
- if (prefix !== '978' && prefix !== '979') {
231
- throw new EncodeError(`ISBN-13 must begin with 978 or 979, got ${prefix}`);
232
- }
233
- // encodeEAN13 appends the check digit at 12, or verifies it at 13.
234
- return encodeEAN13(cleaned);
235
- }
236
-
237
- throw new EncodeError(
238
- `ISBN: expected 10 or 13 digits, hyphens optional — got "${value}"`
239
- );
197
+ const cleaned = String(value).replace(/[\s-]/g, '').toUpperCase();
198
+ if (/^[0-9]{9}[0-9X]$/.test(cleaned)) {
199
+ // ISBN-10: verify its modulo-11 check, then convert to the 978 form.
200
+ let sum = 0;
201
+ for (let i = 0; i < 9; i++)
202
+ sum += Number(cleaned[i]) * (10 - i);
203
+ sum += cleaned[9] === 'X' ? 10 : Number(cleaned[9]);
204
+ if (sum % 11 !== 0) {
205
+ throw new EncodeError(`ISBN-10: check digit "${cleaned[9]}" fails the modulo-11 test`);
206
+ }
207
+ // The check digit does not carry over — encodeEAN13 computes the new one.
208
+ return encodeEAN13('978' + cleaned.slice(0, 9));
209
+ }
210
+ if (/^[0-9]{12,13}$/.test(cleaned)) {
211
+ const prefix = cleaned.slice(0, 3);
212
+ if (prefix !== '978' && prefix !== '979') {
213
+ throw new EncodeError(`ISBN-13 must begin with 978 or 979, got ${prefix}`);
214
+ }
215
+ // encodeEAN13 appends the check digit at 12, or verifies it at 13.
216
+ return encodeEAN13(cleaned);
217
+ }
218
+ throw new EncodeError(`ISBN: expected 10 or 13 digits, hyphens optional — got "${value}"`);
240
219
  }
241
-
242
220
  /**
243
221
  * UPC-A. Structurally an EAN-13 whose first digit is zero.
244
222
  *
@@ -246,13 +224,12 @@ export function encodeISBN(value) {
246
224
  * @returns {BitMatrix}
247
225
  */
248
226
  export function encodeUPCA(value) {
249
- requireDigits(value, 'UPC-A');
250
- if (value.length !== 11 && value.length !== 12) {
251
- throw new EncodeError(`UPC-A: needs 11 or 12 digits, got ${value.length}`);
252
- }
253
- return encodeEAN13('0' + value);
227
+ requireDigits(value, 'UPC-A');
228
+ if (value.length !== 11 && value.length !== 12) {
229
+ throw new EncodeError(`UPC-A: needs 11 or 12 digits, got ${value.length}`);
230
+ }
231
+ return encodeEAN13('0' + value);
254
232
  }
255
-
256
233
  /**
257
234
  * Expand a UPC-E body to the 11 digits preceding the check digit.
258
235
  *
@@ -261,21 +238,23 @@ export function encodeUPCA(value) {
261
238
  * @returns {string} 11 digits.
262
239
  */
263
240
  export function upceToUpcaBody(system, body) {
264
- const d = body;
265
- const last = Number(d[5]);
266
- let middle;
267
- if (last <= 2) {
268
- middle = d.slice(0, 2) + String(last) + '0000' + d.slice(2, 5);
269
- } else if (last === 3) {
270
- middle = d.slice(0, 3) + '00000' + d.slice(3, 5);
271
- } else if (last === 4) {
272
- middle = d.slice(0, 4) + '00000' + d[4];
273
- } else {
274
- middle = d.slice(0, 5) + '0000' + String(last);
275
- }
276
- return String(system) + middle;
241
+ const d = body;
242
+ const last = Number(d[5]);
243
+ let middle;
244
+ if (last <= 2) {
245
+ middle = d.slice(0, 2) + String(last) + '0000' + d.slice(2, 5);
246
+ }
247
+ else if (last === 3) {
248
+ middle = d.slice(0, 3) + '00000' + d.slice(3, 5);
249
+ }
250
+ else if (last === 4) {
251
+ middle = d.slice(0, 4) + '00000' + d[4];
252
+ }
253
+ else {
254
+ middle = d.slice(0, 5) + '0000' + String(last);
255
+ }
256
+ return String(system) + middle;
277
257
  }
278
-
279
258
  /**
280
259
  * UPC-E, the zero-suppressed form of UPC-A.
281
260
  *
@@ -283,46 +262,43 @@ export function upceToUpcaBody(system, body) {
283
262
  * @returns {BitMatrix}
284
263
  */
285
264
  export function encodeUPCE(value) {
286
- requireDigits(value, 'UPC-E');
287
-
288
- let system, body, check;
289
- if (value.length === 6) {
290
- system = 0;
291
- body = value;
292
- check = ean13CheckDigit(upceToUpcaBody(0, body));
293
- } else if (value.length === 7) {
294
- system = Number(value[0]);
295
- body = value.slice(1);
296
- check = ean13CheckDigit(upceToUpcaBody(system, body));
297
- } else if (value.length === 8) {
298
- system = Number(value[0]);
299
- body = value.slice(1, 7);
300
- check = Number(value[7]);
301
- } else {
302
- throw new EncodeError(`UPC-E: needs 6, 7 or 8 digits, got ${value.length}`);
303
- }
304
-
305
- if (system !== 0 && system !== 1) {
306
- throw new EncodeError(`UPC-E: number system must be 0 or 1, got ${system}`);
307
- }
308
-
309
- const parity = UPCE_PARITY[check];
310
- let modules = EAN_START_END;
311
- for (let i = 0; i < 6; i++) {
312
- const d = Number(body[i]);
313
- // Number system 1 inverts the entire parity pattern relative to system 0.
314
- const even = system === 0 ? parity[i] === 'E' : parity[i] === 'O';
315
- modules += even ? EAN_G[d] : EAN_L[d];
316
- }
317
- modules += UPCE_END;
318
-
319
- return toMatrix(modules);
265
+ requireDigits(value, 'UPC-E');
266
+ let system, body, check;
267
+ if (value.length === 6) {
268
+ system = 0;
269
+ body = value;
270
+ check = ean13CheckDigit(upceToUpcaBody(0, body));
271
+ }
272
+ else if (value.length === 7) {
273
+ system = Number(value[0]);
274
+ body = value.slice(1);
275
+ check = ean13CheckDigit(upceToUpcaBody(system, body));
276
+ }
277
+ else if (value.length === 8) {
278
+ system = Number(value[0]);
279
+ body = value.slice(1, 7);
280
+ check = Number(value[7]);
281
+ }
282
+ else {
283
+ throw new EncodeError(`UPC-E: needs 6, 7 or 8 digits, got ${value.length}`);
284
+ }
285
+ if (system !== 0 && system !== 1) {
286
+ throw new EncodeError(`UPC-E: number system must be 0 or 1, got ${system}`);
287
+ }
288
+ const parity = UPCE_PARITY[check];
289
+ let modules = EAN_START_END;
290
+ for (let i = 0; i < 6; i++) {
291
+ const d = Number(body[i]);
292
+ // Number system 1 inverts the entire parity pattern relative to system 0.
293
+ const even = system === 0 ? parity[i] === 'E' : parity[i] === 'O';
294
+ modules += even ? EAN_G[d] : EAN_L[d];
295
+ }
296
+ modules += UPCE_END;
297
+ return toMatrix(modules);
320
298
  }
321
-
322
299
  /* ------------------------------------------------------------------ *
323
300
  * Code 39
324
301
  * ------------------------------------------------------------------ */
325
-
326
302
  /**
327
303
  * Code 39.
328
304
  *
@@ -334,49 +310,43 @@ export function encodeUPCE(value) {
334
310
  * @returns {BitMatrix}
335
311
  */
336
312
  export function encodeCode39(value, options = {}) {
337
- const { checkDigit = false, fullAscii = false, wideRatio = 3 } = options;
338
- if (wideRatio < 2 || wideRatio > 3) {
339
- throw new EncodeError(`Code 39: wide ratio must be 2 or 3, got ${wideRatio}`);
340
- }
341
-
342
- let text = value;
343
- if (fullAscii) {
344
- text = '';
345
- for (const ch of value) {
346
- const code = ch.charCodeAt(0);
347
- if (code > 127) throw new EncodeError(`Code 39: '${ch}' is outside ASCII`);
348
- text += CODE39_EXTENDED[code];
349
- }
350
- }
351
-
352
- for (const ch of text) {
353
- if (ch === '*') {
354
- throw new EncodeError("Code 39: '*' is reserved as the start/stop character");
355
- }
356
- if (!CODE39[ch]) {
357
- throw new EncodeError(
358
- `Code 39: character '${ch}' is not encodable` +
359
- (fullAscii ? '' : ' — try the fullAscii option')
360
- );
361
- }
362
- }
363
-
364
- let payload = text;
365
- if (checkDigit) {
366
- let sum = 0;
367
- for (const ch of text) sum += CODE39_CHECK_SET.indexOf(ch);
368
- payload += CODE39_CHECK_SET[sum % 43];
369
- }
370
-
371
- // Characters are separated by a narrow inter-character gap.
372
- const parts = ['*', ...payload, '*'].map((ch) => expandNarrowWide(CODE39[ch], wideRatio));
373
- return toMatrix(parts.join('0'));
313
+ const { checkDigit = false, fullAscii = false, wideRatio = 3 } = options;
314
+ if (wideRatio < 2 || wideRatio > 3) {
315
+ throw new EncodeError(`Code 39: wide ratio must be 2 or 3, got ${wideRatio}`);
316
+ }
317
+ let text = value;
318
+ if (fullAscii) {
319
+ text = '';
320
+ for (const ch of value) {
321
+ const code = ch.charCodeAt(0);
322
+ if (code > 127)
323
+ throw new EncodeError(`Code 39: '${ch}' is outside ASCII`);
324
+ text += CODE39_EXTENDED[code];
325
+ }
326
+ }
327
+ for (const ch of text) {
328
+ if (ch === '*') {
329
+ throw new EncodeError("Code 39: '*' is reserved as the start/stop character");
330
+ }
331
+ if (!CODE39[ch]) {
332
+ throw new EncodeError(`Code 39: character '${ch}' is not encodable` +
333
+ (fullAscii ? '' : ' — try the fullAscii option'));
334
+ }
335
+ }
336
+ let payload = text;
337
+ if (checkDigit) {
338
+ let sum = 0;
339
+ for (const ch of text)
340
+ sum += CODE39_CHECK_SET.indexOf(ch);
341
+ payload += CODE39_CHECK_SET[sum % 43];
342
+ }
343
+ // Characters are separated by a narrow inter-character gap.
344
+ const parts = ['*', ...payload, '*'].map((ch) => expandNarrowWide(CODE39[ch], wideRatio));
345
+ return toMatrix(parts.join('0'));
374
346
  }
375
-
376
347
  /* ------------------------------------------------------------------ *
377
348
  * Code 93
378
349
  * ------------------------------------------------------------------ */
379
-
380
350
  /**
381
351
  * Code 93, always with its two mandatory check characters.
382
352
  *
@@ -384,42 +354,37 @@ export function encodeCode39(value, options = {}) {
384
354
  * @returns {BitMatrix}
385
355
  */
386
356
  export function encodeCode93(value) {
387
- const values = [];
388
- for (const ch of value) {
389
- const idx = CODE93_VALUES.indexOf(ch);
390
- if (idx < 0) throw new EncodeError(`Code 93: character '${ch}' is not encodable`);
391
- values.push(idx);
392
- }
393
-
394
- // Check character C weights the payload 1..20 from the right; K then repeats
395
- // the exercise over the payload plus C, weighted 1..15.
396
- const weighted = (data, maxWeight) => {
397
- let sum = 0;
398
- for (let i = 0; i < data.length; i++) {
399
- const weight = ((data.length - 1 - i) % maxWeight) + 1;
400
- sum += weight * data[i];
401
- }
402
- return sum % 47;
403
- };
404
-
405
- values.push(weighted(values, 20));
406
- values.push(weighted(values, 15));
407
-
408
- let modules = expandWidths(CODE93_START_STOP);
409
- for (const v of values) modules += expandWidths(CODE93[CODE93_VALUES[v]]);
410
- modules += expandWidths(CODE93_START_STOP);
411
- modules += '1'; // termination bar
412
-
413
- return toMatrix(modules);
357
+ const values = [];
358
+ for (const ch of value) {
359
+ const idx = CODE93_VALUES.indexOf(ch);
360
+ if (idx < 0)
361
+ throw new EncodeError(`Code 93: character '${ch}' is not encodable`);
362
+ values.push(idx);
363
+ }
364
+ // Check character C weights the payload 1..20 from the right; K then repeats
365
+ // the exercise over the payload plus C, weighted 1..15.
366
+ const weighted = (data, maxWeight) => {
367
+ let sum = 0;
368
+ for (let i = 0; i < data.length; i++) {
369
+ const weight = ((data.length - 1 - i) % maxWeight) + 1;
370
+ sum += weight * data[i];
371
+ }
372
+ return sum % 47;
373
+ };
374
+ values.push(weighted(values, 20));
375
+ values.push(weighted(values, 15));
376
+ let modules = expandWidths(CODE93_START_STOP);
377
+ for (const v of values)
378
+ modules += expandWidths(CODE93[CODE93_VALUES[v]]);
379
+ modules += expandWidths(CODE93_START_STOP);
380
+ modules += '1'; // termination bar
381
+ return toMatrix(modules);
414
382
  }
415
-
416
383
  /* ------------------------------------------------------------------ *
417
384
  * Code 128
418
385
  * ------------------------------------------------------------------ */
419
-
420
386
  /** Set B maps printable ASCII starting at space to symbol value 0. */
421
387
  const CODE128_B_OFFSET = 32;
422
-
423
388
  /**
424
389
  * Code 128, with automatic code-set selection.
425
390
  *
@@ -434,97 +399,91 @@ const CODE128_B_OFFSET = 32;
434
399
  * @returns {BitMatrix}
435
400
  */
436
401
  export function encodeCode128(value, options = {}) {
437
- const { gs1 = false } = options;
438
- for (const ch of value) {
439
- if (ch.charCodeAt(0) > 127) {
440
- throw new EncodeError(`Code 128: '${ch}' is outside ASCII`);
441
- }
442
- }
443
-
444
- /** Length of the digit run starting at i. */
445
- const digitRun = (i) => {
446
- let n = 0;
447
- while (i + n < value.length && value[i + n] >= '0' && value[i + n] <= '9') n++;
448
- return n;
449
- };
450
-
451
- const codes = [];
452
- let mode;
453
- let i = 0;
454
-
455
- const startRun = digitRun(0);
456
- if (startRun >= 4 && startRun % 2 === 0) {
457
- codes.push(CODE128_START_C);
458
- mode = 'C';
459
- } else {
460
- codes.push(CODE128_START_B);
461
- mode = 'B';
462
- }
463
- if (gs1) codes.push(CODE128_FNC1);
464
-
465
- while (i < value.length) {
466
- if (gs1 && value[i] === '\x1d') {
467
- codes.push(CODE128_FNC1);
468
- i++;
469
- continue;
470
- }
471
- const run = digitRun(i);
472
- const atEnd = i + run === value.length;
473
- const worthC = run >= 6 || (i === 0 && run >= 4) || (atEnd && run >= 4);
474
-
475
- if (mode !== 'C' && worthC && run >= 2) {
476
- codes.push(CODE128_CODE_C);
477
- mode = 'C';
478
- continue;
479
- }
480
-
481
- if (mode === 'C') {
482
- if (run >= 2) {
483
- codes.push(Number(value.substr(i, 2)));
484
- i += 2;
485
- continue;
486
- }
487
- codes.push(CODE128_CODE_B);
488
- mode = 'B';
489
- continue;
490
- }
491
-
492
- const code = value.charCodeAt(i);
493
- if (code < 32) {
494
- // Control characters live in set A only.
495
- if (mode !== 'A') {
496
- codes.push(CODE128_CODE_A);
497
- mode = 'A';
498
- continue;
499
- }
500
- codes.push(code + 64);
501
- } else {
502
- if (mode === 'A' && code >= 96) {
503
- codes.push(CODE128_CODE_B);
402
+ const { gs1 = false } = options;
403
+ for (const ch of value) {
404
+ if (ch.charCodeAt(0) > 127) {
405
+ throw new EncodeError(`Code 128: '${ch}' is outside ASCII`);
406
+ }
407
+ }
408
+ /** Length of the digit run starting at i. */
409
+ const digitRun = (i) => {
410
+ let n = 0;
411
+ while (i + n < value.length && value[i + n] >= '0' && value[i + n] <= '9')
412
+ n++;
413
+ return n;
414
+ };
415
+ const codes = [];
416
+ let mode;
417
+ let i = 0;
418
+ const startRun = digitRun(0);
419
+ if (startRun >= 4 && startRun % 2 === 0) {
420
+ codes.push(CODE128_START_C);
421
+ mode = 'C';
422
+ }
423
+ else {
424
+ codes.push(CODE128_START_B);
504
425
  mode = 'B';
505
- continue;
506
- }
507
- codes.push(code - CODE128_B_OFFSET);
508
- }
509
- i++;
510
- }
511
-
512
- // Checksum: the start value plus each symbol weighted by its position.
513
- let sum = codes[0];
514
- for (let k = 1; k < codes.length; k++) sum += codes[k] * k;
515
- codes.push(sum % 103);
516
- codes.push(CODE128_STOP);
517
-
518
- let modules = '';
519
- for (const c of codes) modules += expandWidths(CODE128[c]);
520
-
521
- return toMatrix(modules);
426
+ }
427
+ if (gs1)
428
+ codes.push(CODE128_FNC1);
429
+ while (i < value.length) {
430
+ if (gs1 && value[i] === '\x1d') {
431
+ codes.push(CODE128_FNC1);
432
+ i++;
433
+ continue;
434
+ }
435
+ const run = digitRun(i);
436
+ const atEnd = i + run === value.length;
437
+ const worthC = run >= 6 || (i === 0 && run >= 4) || (atEnd && run >= 4);
438
+ if (mode !== 'C' && worthC && run >= 2) {
439
+ codes.push(CODE128_CODE_C);
440
+ mode = 'C';
441
+ continue;
442
+ }
443
+ if (mode === 'C') {
444
+ if (run >= 2) {
445
+ codes.push(Number(value.substr(i, 2)));
446
+ i += 2;
447
+ continue;
448
+ }
449
+ codes.push(CODE128_CODE_B);
450
+ mode = 'B';
451
+ continue;
452
+ }
453
+ const code = value.charCodeAt(i);
454
+ if (code < 32) {
455
+ // Control characters live in set A only.
456
+ if (mode !== 'A') {
457
+ codes.push(CODE128_CODE_A);
458
+ mode = 'A';
459
+ continue;
460
+ }
461
+ codes.push(code + 64);
462
+ }
463
+ else {
464
+ if (mode === 'A' && code >= 96) {
465
+ codes.push(CODE128_CODE_B);
466
+ mode = 'B';
467
+ continue;
468
+ }
469
+ codes.push(code - CODE128_B_OFFSET);
470
+ }
471
+ i++;
472
+ }
473
+ // Checksum: the start value plus each symbol weighted by its position.
474
+ let sum = codes[0];
475
+ for (let k = 1; k < codes.length; k++)
476
+ sum += codes[k] * k;
477
+ codes.push(sum % 103);
478
+ codes.push(CODE128_STOP);
479
+ let modules = '';
480
+ for (const c of codes)
481
+ modules += expandWidths(CODE128[c]);
482
+ return toMatrix(modules);
522
483
  }
523
-
524
484
  /* ------------------------------------------------------------------ *
525
485
  * Interleaved 2 of 5
526
486
  * ------------------------------------------------------------------ */
527
-
528
487
  /**
529
488
  * Interleaved 2 of 5.
530
489
  *
@@ -539,30 +498,27 @@ export function encodeCode128(value, options = {}) {
539
498
  * @returns {BitMatrix}
540
499
  */
541
500
  export function encodeITF(value, options = {}) {
542
- const { checkDigit = false, wideRatio = 3 } = options;
543
- requireDigits(value, 'ITF');
544
-
545
- let digits = value;
546
- if (checkDigit) digits += String(ean13CheckDigit(digits));
547
- // A leading zero pads to an even length without changing the value.
548
- if (digits.length % 2 !== 0) digits = '0' + digits;
549
-
550
- let modules = '1010'; // start: four narrow elements
551
-
552
- for (let i = 0; i < digits.length; i += 2) {
553
- const bars = ITF[Number(digits[i])];
554
- const spaces = ITF[Number(digits[i + 1])];
555
- for (let k = 0; k < 5; k++) {
556
- modules += '1'.repeat(bars[k] === 'w' ? wideRatio : 1);
557
- modules += '0'.repeat(spaces[k] === 'w' ? wideRatio : 1);
558
- }
559
- }
560
-
561
- // Stop: wide bar, narrow space, narrow bar.
562
- modules += '1'.repeat(wideRatio) + '0' + '1';
563
- return toMatrix(modules);
501
+ const { checkDigit = false, wideRatio = 3 } = options;
502
+ requireDigits(value, 'ITF');
503
+ let digits = value;
504
+ if (checkDigit)
505
+ digits += String(ean13CheckDigit(digits));
506
+ // A leading zero pads to an even length without changing the value.
507
+ if (digits.length % 2 !== 0)
508
+ digits = '0' + digits;
509
+ let modules = '1010'; // start: four narrow elements
510
+ for (let i = 0; i < digits.length; i += 2) {
511
+ const bars = ITF[Number(digits[i])];
512
+ const spaces = ITF[Number(digits[i + 1])];
513
+ for (let k = 0; k < 5; k++) {
514
+ modules += '1'.repeat(bars[k] === 'w' ? wideRatio : 1);
515
+ modules += '0'.repeat(spaces[k] === 'w' ? wideRatio : 1);
516
+ }
517
+ }
518
+ // Stop: wide bar, narrow space, narrow bar.
519
+ modules += '1'.repeat(wideRatio) + '0' + '1';
520
+ return toMatrix(modules);
564
521
  }
565
-
566
522
  /**
567
523
  * ITF-14, the shipping-container form: exactly 14 digits.
568
524
  *
@@ -570,20 +526,19 @@ export function encodeITF(value, options = {}) {
570
526
  * @returns {BitMatrix}
571
527
  */
572
528
  export function encodeITF14(value) {
573
- requireDigits(value, 'ITF-14');
574
- let digits = value;
575
- if (digits.length === 13) {
576
- digits += String(ean13CheckDigit(digits));
577
- } else if (digits.length !== 14) {
578
- throw new EncodeError(`ITF-14: needs 13 or 14 digits, got ${digits.length}`);
579
- }
580
- return encodeITF(digits);
529
+ requireDigits(value, 'ITF-14');
530
+ let digits = value;
531
+ if (digits.length === 13) {
532
+ digits += String(ean13CheckDigit(digits));
533
+ }
534
+ else if (digits.length !== 14) {
535
+ throw new EncodeError(`ITF-14: needs 13 or 14 digits, got ${digits.length}`);
536
+ }
537
+ return encodeITF(digits);
581
538
  }
582
-
583
539
  /* ------------------------------------------------------------------ *
584
540
  * Codabar
585
541
  * ------------------------------------------------------------------ */
586
-
587
542
  /**
588
543
  * Codabar.
589
544
  *
@@ -595,42 +550,38 @@ export function encodeITF14(value) {
595
550
  * @returns {BitMatrix}
596
551
  */
597
552
  export function encodeCodabar(value, options = {}) {
598
- const { wideRatio = 3 } = options;
599
- let text = value.toUpperCase();
600
- let start = (options.start || '').toUpperCase();
601
- let stop = (options.stop || '').toUpperCase();
602
-
603
- // Accept the common convention of embedding the guards in the payload.
604
- if (!start && text.length >= 2 &&
605
- CODABAR_START_STOP.includes(text[0]) &&
606
- CODABAR_START_STOP.includes(text[text.length - 1])) {
607
- start = text[0];
608
- stop = text[text.length - 1];
609
- text = text.slice(1, -1);
610
- }
611
- if (!start) start = 'A';
612
- if (!stop) stop = 'A';
613
-
614
- if (!CODABAR_START_STOP.includes(start) || !CODABAR_START_STOP.includes(stop)) {
615
- throw new EncodeError('Codabar: start and stop characters must be A, B, C or D');
616
- }
617
- for (const ch of text) {
618
- if (!CODABAR[ch] || CODABAR_START_STOP.includes(ch)) {
619
- throw new EncodeError(`Codabar: character '${ch}' is not encodable in the payload`);
620
- }
621
- }
622
-
623
- const parts = [start, ...text, stop].map((ch) => expandNarrowWide(CODABAR[ch], wideRatio));
624
- return toMatrix(parts.join('0'));
553
+ const { wideRatio = 3 } = options;
554
+ let text = value.toUpperCase();
555
+ let start = (options.start || '').toUpperCase();
556
+ let stop = (options.stop || '').toUpperCase();
557
+ // Accept the common convention of embedding the guards in the payload.
558
+ if (!start && text.length >= 2 &&
559
+ CODABAR_START_STOP.includes(text[0]) &&
560
+ CODABAR_START_STOP.includes(text[text.length - 1])) {
561
+ start = text[0];
562
+ stop = text[text.length - 1];
563
+ text = text.slice(1, -1);
564
+ }
565
+ if (!start)
566
+ start = 'A';
567
+ if (!stop)
568
+ stop = 'A';
569
+ if (!CODABAR_START_STOP.includes(start) || !CODABAR_START_STOP.includes(stop)) {
570
+ throw new EncodeError('Codabar: start and stop characters must be A, B, C or D');
571
+ }
572
+ for (const ch of text) {
573
+ if (!CODABAR[ch] || CODABAR_START_STOP.includes(ch)) {
574
+ throw new EncodeError(`Codabar: character '${ch}' is not encodable in the payload`);
575
+ }
576
+ }
577
+ const parts = [start, ...text, stop].map((ch) => expandNarrowWide(CODABAR[ch], wideRatio));
578
+ return toMatrix(parts.join('0'));
625
579
  }
626
-
627
580
  /* ------------------------------------------------------------------ *
628
581
  * Code 11
629
582
  * ------------------------------------------------------------------ */
630
-
631
583
  /** Code 11 character values, in order. */
632
584
  const CODE11_CHARSET = '0123456789-';
633
-
634
585
  /**
635
586
  * Code 11, digits and hyphen.
636
587
  *
@@ -641,41 +592,37 @@ const CODE11_CHARSET = '0123456789-';
641
592
  * @returns {BitMatrix}
642
593
  */
643
594
  export function encodeCode11(value, options = {}) {
644
- const { checkDigit = true, wideRatio = 3 } = options;
645
-
646
- for (const ch of value) {
647
- if (!CODE11_CHARSET.includes(ch)) {
648
- throw new EncodeError(`Code 11: character '${ch}' is not encodable`);
649
- }
650
- }
651
-
652
- let payload = value;
653
- if (checkDigit) {
654
- const weighted = (text, maxWeight) => {
655
- let sum = 0;
656
- for (let i = 0; i < text.length; i++) {
657
- const weight = ((text.length - 1 - i) % maxWeight) + 1;
658
- sum += weight * CODE11_CHARSET.indexOf(text[i]);
659
- }
660
- return sum;
661
- };
662
- payload += CODE11_CHARSET[weighted(payload, 10) % 11];
663
- // The second check character is conventionally added only to longer payloads.
664
- if (value.length >= 10) payload += CODE11_CHARSET[weighted(payload, 9) % 11];
665
- }
666
-
667
- const parts = [
668
- expandNarrowWide(CODE11_START_STOP, wideRatio),
669
- ...[...payload].map((ch) => expandNarrowWide(CODE11[ch], wideRatio)),
670
- expandNarrowWide(CODE11_START_STOP, wideRatio),
671
- ];
672
- return toMatrix(parts.join('0'));
595
+ const { checkDigit = true, wideRatio = 3 } = options;
596
+ for (const ch of value) {
597
+ if (!CODE11_CHARSET.includes(ch)) {
598
+ throw new EncodeError(`Code 11: character '${ch}' is not encodable`);
599
+ }
600
+ }
601
+ let payload = value;
602
+ if (checkDigit) {
603
+ const weighted = (text, maxWeight) => {
604
+ let sum = 0;
605
+ for (let i = 0; i < text.length; i++) {
606
+ const weight = ((text.length - 1 - i) % maxWeight) + 1;
607
+ sum += weight * CODE11_CHARSET.indexOf(text[i]);
608
+ }
609
+ return sum;
610
+ };
611
+ payload += CODE11_CHARSET[weighted(payload, 10) % 11];
612
+ // The second check character is conventionally added only to longer payloads.
613
+ if (value.length >= 10)
614
+ payload += CODE11_CHARSET[weighted(payload, 9) % 11];
615
+ }
616
+ const parts = [
617
+ expandNarrowWide(CODE11_START_STOP, wideRatio),
618
+ ...[...payload].map((ch) => expandNarrowWide(CODE11[ch], wideRatio)),
619
+ expandNarrowWide(CODE11_START_STOP, wideRatio),
620
+ ];
621
+ return toMatrix(parts.join('0'));
673
622
  }
674
-
675
623
  /* ------------------------------------------------------------------ *
676
624
  * MSI / Plessey
677
625
  * ------------------------------------------------------------------ */
678
-
679
626
  /**
680
627
  * MSI Plessey.
681
628
  *
@@ -685,35 +632,34 @@ export function encodeCode11(value, options = {}) {
685
632
  * @returns {BitMatrix}
686
633
  */
687
634
  export function encodeMSI(value, options = {}) {
688
- const { checkDigit = false } = options;
689
- requireDigits(value, 'MSI');
690
-
691
- let digits = value;
692
- if (checkDigit) {
693
- // Luhn: the odd-positioned digits, read as one number, are doubled.
694
- let odd = '';
695
- for (let i = digits.length - 1; i >= 0; i -= 2) odd = digits[i] + odd;
696
- const doubled = String(Number(odd) * 2);
697
- let sum = 0;
698
- for (const ch of doubled) sum += Number(ch);
699
- for (let i = digits.length - 2; i >= 0; i -= 2) sum += Number(digits[i]);
700
- digits += String((10 - (sum % 10)) % 10);
701
- }
702
-
703
- let modules = MSI_START;
704
- for (const ch of digits) {
705
- const bits = Number(ch).toString(2).padStart(4, '0');
706
- for (const b of bits) modules += MSI_BIT[b];
707
- }
708
- modules += MSI_STOP;
709
-
710
- return toMatrix(modules);
635
+ const { checkDigit = false } = options;
636
+ requireDigits(value, 'MSI');
637
+ let digits = value;
638
+ if (checkDigit) {
639
+ // Luhn: the odd-positioned digits, read as one number, are doubled.
640
+ let odd = '';
641
+ for (let i = digits.length - 1; i >= 0; i -= 2)
642
+ odd = digits[i] + odd;
643
+ const doubled = String(Number(odd) * 2);
644
+ let sum = 0;
645
+ for (const ch of doubled)
646
+ sum += Number(ch);
647
+ for (let i = digits.length - 2; i >= 0; i -= 2)
648
+ sum += Number(digits[i]);
649
+ digits += String((10 - (sum % 10)) % 10);
650
+ }
651
+ let modules = MSI_START;
652
+ for (const ch of digits) {
653
+ const bits = Number(ch).toString(2).padStart(4, '0');
654
+ for (const b of bits)
655
+ modules += MSI_BIT[b];
656
+ }
657
+ modules += MSI_STOP;
658
+ return toMatrix(modules);
711
659
  }
712
-
713
660
  /* ------------------------------------------------------------------ *
714
661
  * Pharmacode
715
662
  * ------------------------------------------------------------------ */
716
-
717
663
  /**
718
664
  * Pharmacode, one-track.
719
665
  *
@@ -725,22 +671,21 @@ export function encodeMSI(value, options = {}) {
725
671
  * @returns {BitMatrix}
726
672
  */
727
673
  export function encodePharmacode(value) {
728
- let n = typeof value === 'string' ? Number(value) : value;
729
- if (!Number.isInteger(n) || n < 3 || n > 131070) {
730
- throw new EncodeError(`Pharmacode: value must be an integer in 3..131070, got ${value}`);
731
- }
732
-
733
- const bars = [];
734
- while (n > 0) {
735
- if (n % 2 === 0) {
736
- bars.push('111'); // wide
737
- n = n / 2 - 1;
738
- } else {
739
- bars.push('1'); // narrow
740
- n = (n - 1) / 2;
741
- }
742
- }
743
- bars.reverse();
744
-
745
- return toMatrix(bars.join('0'));
674
+ let n = typeof value === 'string' ? Number(value) : value;
675
+ if (!Number.isInteger(n) || n < 3 || n > 131070) {
676
+ throw new EncodeError(`Pharmacode: value must be an integer in 3..131070, got ${value}`);
677
+ }
678
+ const bars = [];
679
+ while (n > 0) {
680
+ if (n % 2 === 0) {
681
+ bars.push('111'); // wide
682
+ n = n / 2 - 1;
683
+ }
684
+ else {
685
+ bars.push('1'); // narrow
686
+ n = (n - 1) / 2;
687
+ }
688
+ }
689
+ bars.reverse();
690
+ return toMatrix(bars.join('0'));
746
691
  }