@sythos/js_barcode_universal 1.5.13 → 1.5.15

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 (137) hide show
  1. package/LICENSE +22 -4
  2. package/NOTICE.md +10 -1
  3. package/README.md +416 -22
  4. package/bundle/sythos-barcode.esm.js +22176 -11991
  5. package/bundle/sythos-barcode.js +22059 -11991
  6. package/licenses/README.md +12 -1
  7. package/licenses/codablockf.license +51 -0
  8. package/licenses/code16k.license +52 -0
  9. package/licenses/code25.license +58 -0
  10. package/licenses/code32.license +51 -0
  11. package/licenses/dotcode.license +66 -0
  12. package/licenses/gs1-composite.license +106 -0
  13. package/licenses/gs1-databar.license +21 -14
  14. package/licenses/hanxin.license +95 -0
  15. package/licenses/maxicode.license +62 -0
  16. package/licenses/postal.license +61 -0
  17. package/licenses/pzn.license +53 -0
  18. package/licenses/telepen.license +73 -0
  19. package/llms.txt +62 -6
  20. package/package.json +47 -3
  21. package/src/index.d.ts +111 -6
  22. package/src/index.js +362 -13
  23. package/src/js/codablockf/decoder.js +198 -0
  24. package/src/js/codablockf/encoder.js +97 -0
  25. package/src/js/codablockf/index.js +3 -0
  26. package/src/js/code16k/decoder.js +303 -0
  27. package/src/js/code16k/detector.js +187 -0
  28. package/src/js/code16k/encoder.js +153 -0
  29. package/src/js/code16k/index.js +14 -0
  30. package/src/js/code16k/tables.js +152 -0
  31. package/src/js/composite/index.js +570 -0
  32. package/src/js/core/detection-contract.js +185 -0
  33. package/src/js/core/symbol-layout.js +155 -0
  34. package/src/js/databar/expanded.js +968 -0
  35. package/src/js/databar/index.js +4 -0
  36. package/src/js/databar/layout.js +192 -0
  37. package/src/js/databar/limited.js +533 -0
  38. package/src/js/databar/stacked-omnidirectional.js +548 -0
  39. package/src/js/databar/stacked.js +528 -0
  40. package/src/js/dotcode/decoder.js +548 -0
  41. package/src/js/dotcode/detector.js +251 -0
  42. package/src/js/dotcode/encoder.js +453 -0
  43. package/src/js/dotcode/index.js +34 -0
  44. package/src/js/dotcode/tables.js +168 -0
  45. package/src/js/hanxin/decoder.js +299 -0
  46. package/src/js/hanxin/detector.js +122 -0
  47. package/src/js/hanxin/encoder.js +259 -0
  48. package/src/js/hanxin/index.js +16 -0
  49. package/src/js/hanxin/tables.js +316 -0
  50. package/src/js/image/height-coded.js +164 -0
  51. package/src/js/maxicode/decoder.js +275 -0
  52. package/src/js/maxicode/detector.js +118 -0
  53. package/src/js/maxicode/encoder.js +438 -0
  54. package/src/js/maxicode/index.js +34 -0
  55. package/src/js/maxicode/tables.js +132 -0
  56. package/src/js/oned/code25.js +148 -0
  57. package/src/js/oned/index.js +21 -3
  58. package/src/js/oned/postal.js +889 -0
  59. package/src/js/oned/reader.js +272 -7
  60. package/src/js/oned/telepen.js +361 -0
  61. package/src/js/oned/writers.js +186 -12
  62. package/src/js/stacked128/common.js +208 -0
  63. package/src/ts/codablockf/decoder.ts +212 -0
  64. package/src/ts/codablockf/encoder.ts +128 -0
  65. package/src/ts/codablockf/index.d.ts +31 -0
  66. package/src/ts/codablockf/index.ts +6 -0
  67. package/src/ts/code16k/decoder.d.ts +25 -0
  68. package/src/ts/code16k/decoder.ts +313 -0
  69. package/src/ts/code16k/detector.d.ts +21 -0
  70. package/src/ts/code16k/detector.ts +203 -0
  71. package/src/ts/code16k/encoder.d.ts +26 -0
  72. package/src/ts/code16k/encoder.ts +198 -0
  73. package/src/ts/code16k/index.d.ts +10 -0
  74. package/src/ts/code16k/index.ts +47 -0
  75. package/src/ts/code16k/tables.d.ts +54 -0
  76. package/src/ts/code16k/tables.ts +195 -0
  77. package/src/ts/composite/index.d.ts +74 -0
  78. package/src/ts/composite/index.ts +547 -0
  79. package/src/ts/core/detection-contract.d.ts +119 -0
  80. package/src/ts/core/detection-contract.ts +267 -0
  81. package/src/ts/core/symbol-layout.d.ts +108 -0
  82. package/src/ts/core/symbol-layout.ts +236 -0
  83. package/src/ts/databar/expanded.d.ts +40 -0
  84. package/src/ts/databar/expanded.ts +948 -0
  85. package/src/ts/databar/index.d.ts +48 -0
  86. package/src/ts/databar/index.ts +48 -0
  87. package/src/ts/databar/layout.d.ts +122 -0
  88. package/src/ts/databar/layout.ts +275 -0
  89. package/src/ts/databar/limited.d.ts +85 -0
  90. package/src/ts/databar/limited.ts +553 -0
  91. package/src/ts/databar/stacked-omnidirectional.d.ts +128 -0
  92. package/src/ts/databar/stacked-omnidirectional.ts +559 -0
  93. package/src/ts/databar/stacked.d.ts +96 -0
  94. package/src/ts/databar/stacked.ts +549 -0
  95. package/src/ts/dotcode/decoder.d.ts +58 -0
  96. package/src/ts/dotcode/decoder.ts +467 -0
  97. package/src/ts/dotcode/detector.d.ts +63 -0
  98. package/src/ts/dotcode/detector.ts +263 -0
  99. package/src/ts/dotcode/encoder.d.ts +69 -0
  100. package/src/ts/dotcode/encoder.ts +427 -0
  101. package/src/ts/dotcode/index.d.ts +37 -0
  102. package/src/ts/dotcode/index.ts +72 -0
  103. package/src/ts/dotcode/tables.d.ts +74 -0
  104. package/src/ts/dotcode/tables.ts +174 -0
  105. package/src/ts/hanxin/decoder.d.ts +48 -0
  106. package/src/ts/hanxin/decoder.ts +314 -0
  107. package/src/ts/hanxin/detector.d.ts +45 -0
  108. package/src/ts/hanxin/detector.ts +124 -0
  109. package/src/ts/hanxin/encoder.d.ts +41 -0
  110. package/src/ts/hanxin/encoder.ts +290 -0
  111. package/src/ts/hanxin/index.d.ts +16 -0
  112. package/src/ts/hanxin/index.ts +18 -0
  113. package/src/ts/hanxin/tables.d.ts +80 -0
  114. package/src/ts/hanxin/tables.ts +348 -0
  115. package/src/ts/image/height-coded.d.ts +101 -0
  116. package/src/ts/image/height-coded.ts +227 -0
  117. package/src/ts/index.d.ts +46 -2
  118. package/src/ts/index.ts +380 -13
  119. package/src/ts/maxicode/decoder.ts +265 -0
  120. package/src/ts/maxicode/detector.ts +109 -0
  121. package/src/ts/maxicode/encoder.ts +414 -0
  122. package/src/ts/maxicode/index.d.ts +96 -0
  123. package/src/ts/maxicode/index.ts +44 -0
  124. package/src/ts/maxicode/tables.ts +136 -0
  125. package/src/ts/oned/code25.d.ts +42 -0
  126. package/src/ts/oned/code25.ts +170 -0
  127. package/src/ts/oned/index.d.ts +7 -2
  128. package/src/ts/oned/index.ts +45 -3
  129. package/src/ts/oned/postal.d.ts +44 -0
  130. package/src/ts/oned/postal.ts +819 -0
  131. package/src/ts/oned/reader.d.ts +35 -0
  132. package/src/ts/oned/reader.ts +261 -7
  133. package/src/ts/oned/telepen.d.ts +65 -0
  134. package/src/ts/oned/telepen.ts +368 -0
  135. package/src/ts/oned/writers.d.ts +32 -0
  136. package/src/ts/oned/writers.ts +184 -13
  137. package/src/ts/stacked128/common.ts +225 -0
@@ -0,0 +1,148 @@
1
+ /*!
2
+ * Sythos Barcode Suite
3
+ *
4
+ * MIT License
5
+ *
6
+ * Copyright (c) 2026 Sythos
7
+ * SPDX-FileCopyrightText: 2026 Sythos (https://www.sythos.net)
8
+ *
9
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ * of this software and associated documentation files (the "Software"), to deal
11
+ * in the Software without restriction, including without limitation the rights
12
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ * copies of the Software, and to permit persons to whom the Software is
14
+ * furnished to do so, subject to the following conditions:
15
+ *
16
+ * The above copyright notice and this permission notice shall be included in all
17
+ * copies or substantial portions of the Software.
18
+ *
19
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ * SOFTWARE.
26
+ *
27
+ * SPDX-License-Identifier: MIT
28
+ *
29
+ * Original work. No code from any other barcode implementation.
30
+ */
31
+ /**
32
+ * Code 25 family writers.
33
+ *
34
+ * Code 25 (also called Standard or Industrial 2 of 5) represents each digit
35
+ * with five alternating bar/space elements, exactly two of the bars being wide.
36
+ * IATA 2 of 5 uses the same digit grammar with a shorter start/stop frame.
37
+ * The width descriptions below are expressed as module counts rather than
38
+ * copied implementation tables and are checked by the focused test suite.
39
+ *
40
+ * @module oned/code25
41
+ */
42
+ import { BitMatrix } from '../core/bit-matrix.js';
43
+ import { EncodeError } from '../core/errors.js';
44
+ /** The ten digit patterns, each with five bars and five spaces. */
45
+ export const CODE25_DIGIT_PATTERNS = [
46
+ '1111313111', '3111111131', '1131111131', '3131111111',
47
+ '1111311131', '3111311111', '1131311111', '1111113131',
48
+ '3111113111', '1131113111',
49
+ ];
50
+ /** Start/stop run widths for the three public names. */
51
+ export const CODE25_VARIANTS = {
52
+ // Code 25 and Industrial 2 of 5 share the discrete two-wide-bar grammar
53
+ // and canonical industrial frame. `standard` is the friendly API alias.
54
+ standard: { id: 'industrial2of5', label: 'Standard 2 of 5 (Code 25)', start: '313111', stop: '31113' },
55
+ industrial: { id: 'industrial2of5', label: 'Industrial 2 of 5', start: '313111', stop: '31113' },
56
+ iata: { id: 'iata2of5', label: 'IATA 2 of 5', start: '1111', stop: '311' },
57
+ };
58
+ const MAX_CODE25_DIGITS = 500;
59
+ function requireDigits(value, label) {
60
+ const text = String(value);
61
+ if (!/^[0-9]+$/u.test(text)) {
62
+ throw new EncodeError(`${label}: payload must be digits only, got "${value}"`);
63
+ }
64
+ if (text.length === 0 || text.length > MAX_CODE25_DIGITS) {
65
+ throw new EncodeError(`${label}: payload length must be in 1..${MAX_CODE25_DIGITS}`);
66
+ }
67
+ return text;
68
+ }
69
+ /** Modulo-10 Code 25 check digit (alternating weights from the right). */
70
+ export function code25CheckDigit(value) {
71
+ let sum = 0;
72
+ for (let i = 0; i < value.length; i++) {
73
+ const fromRight = value.length - 1 - i;
74
+ sum += Number(value[i]) * (fromRight % 2 === 0 ? 3 : 1);
75
+ }
76
+ return (10 - (sum % 10)) % 10;
77
+ }
78
+ function expandWidths(widths, wideRatio) {
79
+ let modules = '';
80
+ for (let i = 0; i < widths.length; i++) {
81
+ const width = Number(widths[i]);
82
+ const count = width > 1 ? wideRatio : 1;
83
+ modules += (i % 2 === 0 ? '1' : '0').repeat(count);
84
+ }
85
+ return modules;
86
+ }
87
+ function toMatrix(modules) {
88
+ const matrix = new BitMatrix(modules.length, 1);
89
+ for (let x = 0; x < modules.length; x++) {
90
+ if (modules[x] === '1')
91
+ matrix.set(x, 0);
92
+ }
93
+ return matrix;
94
+ }
95
+ function resolveVariant(value) {
96
+ const variant = String(value ?? 'standard').toLowerCase();
97
+ if (variant === 'industrial' || variant === 'industrial2of5' || variant === 'industrial-2-of-5')
98
+ return 'industrial';
99
+ if (variant === 'iata' || variant === 'iata2of5' || variant === 'iata-2-of-5')
100
+ return 'iata';
101
+ if (variant === 'standard' || variant === 'code2of5' || variant === 'code-2-of-5' || variant === 'standard2of5' || variant === 'standard-2-of-5')
102
+ return 'standard';
103
+ throw new EncodeError(`Code 25: unknown variant "${value}"`);
104
+ }
105
+ /**
106
+ * Encode one of the Code 25 family profiles.
107
+ *
108
+ * `checkDigit` is opt-in because the base symbologies do not require one. A
109
+ * camera-profile decoder will require and validate it before promoting a read.
110
+ *
111
+ * @param {string} value Numeric payload.
112
+ * @param {object} [options]
113
+ * @param {Code25Variant|string} [options.variant='standard'] Framing profile.
114
+ * @param {boolean} [options.checkDigit] Append a modulo-10 check digit.
115
+ * @param {number} [options.wideRatio=3] Number of modules in a wide bar.
116
+ * @returns {BitMatrix}
117
+ */
118
+ export function encodeCode25(value, options = {}) {
119
+ const variant = resolveVariant(options.variant);
120
+ const profile = CODE25_VARIANTS[variant];
121
+ const label = profile.label;
122
+ const ratio = options.wideRatio ?? 3;
123
+ if (!Number.isInteger(ratio) || ratio < 2 || ratio > 8) {
124
+ throw new EncodeError(`${label}: wideRatio must be an integer in 2..8`);
125
+ }
126
+ let digits = requireDigits(value, label);
127
+ if (options.checkDigit === true)
128
+ digits += String(code25CheckDigit(digits));
129
+ let modules = expandWidths(profile.start, ratio);
130
+ for (const digit of digits)
131
+ modules += expandWidths(CODE25_DIGIT_PATTERNS[Number(digit)], ratio);
132
+ modules += expandWidths(profile.stop, ratio);
133
+ return toMatrix(modules);
134
+ }
135
+ /** Encode Standard 2 of 5 (the canonical Code 25 frame). */
136
+ export function encodeStandard2of5(value, options = {}) {
137
+ return encodeCode25(value, { ...options, variant: 'standard' });
138
+ }
139
+ /** Encode Industrial 2 of 5. */
140
+ export function encodeIndustrial2of5(value, options = {}) {
141
+ return encodeCode25(value, { ...options, variant: 'industrial' });
142
+ }
143
+ /** Encode IATA 2 of 5. */
144
+ export function encodeIATA2of5(value, options = {}) {
145
+ return encodeCode25(value, { ...options, variant: 'iata' });
146
+ }
147
+ /** Internal limit used by the scanline reader and its safety checks. */
148
+ export const CODE25_MAX_DIGITS = MAX_CODE25_DIGITS;
@@ -32,12 +32,18 @@
32
32
  *
33
33
  * @module oned
34
34
  */
35
- export { encodeEAN13, encodeEAN8, encodeUPCA, encodeUPCE, encodeISBN, encodeCode39, encodeCode93, encodeCode128, encodeITF, encodeITF14, encodeCodabar, encodeCode11, encodeMSI, encodePharmacode, ean13CheckDigit, } from './writers.js';
35
+ export { encodeEAN13, encodeEAN8, encodeUPCA, encodeUPCE, encodeISBN, encodeCode39, encodeCode93, encodeCode128, code128DataCodewords, encodeITF, encodeITF14, encodeCodabar, encodeCode11, encodeMSI, encodePharmacode, encodeCode32, encodePZN, code32CheckDigit, decodeCode32Payload, decodePZNPayload, ean13CheckDigit, } from './writers.js';
36
+ export { CODE25_DIGIT_PATTERNS, CODE25_VARIANTS, CODE25_MAX_DIGITS, code25CheckDigit, encodeCode25, encodeStandard2of5, encodeIndustrial2of5, encodeIATA2of5, } from './code25.js';
37
+ export { TELEPEN_START_VALUE, TELEPEN_STOP_VALUE, TELEPEN_MAX_LENGTH, telepenPattern, encodeTelepen, encodeTelepenNumeric, decodeTelepen, decodeTelepenNumeric, } from './telepen.js';
36
38
  export { EAN2_PARITY, EAN5_PARITY, EAN2_WIDTH, EAN5_WIDTH, EAN_ADDON_START, EAN_ADDON_SEPARATOR, ean2Parity, ean5Checksum, ean5CheckDigit, ean5Parity, encodeEAN2, encodeEAN5, encodeEANAddon, encodeEANAddOn, decodeEAN2, decodeEAN5, decodeEANAddon, decodeEANAddOn, composeEANAddon, encodeEAN13WithAddon, encodeEAN8WithAddon, encodeUPCAWithAddon, encodeUPCEWithAddon, } from './addons.js';
37
- export { decodeOneD, decodeOneDStrict, decodeCode11, decodeMSI, patternVariance, recordPattern, toNarrowWidePattern, } from './reader.js';
39
+ export { decodeOneD, decodeOneDStrict, decodeCode32, decodePZN, decodeCode25, decodeStandard2of5, decodeIndustrial2of5, decodeIATA2of5, decodeCode11, decodeMSI, patternVariance, recordPattern, toNarrowWidePattern, } from './reader.js';
40
+ export { POSTAL_FORMATS, POSTAL_ALIASES, STATE_PROFILES, encodePostnet, encodePlanet, encodeRM4SCC, encodeKIX, encodeAustraliaPost, encodeJapanPost, encodeIMB, decodePostal, } from './postal.js';
38
41
  export { validateTables } from './patterns.js';
39
- import { encodeEAN13, encodeEAN8, encodeUPCA, encodeUPCE, encodeISBN, encodeCode39, encodeCode93, encodeCode128, encodeITF, encodeITF14, encodeCodabar, encodeCode11, encodeMSI, encodePharmacode, } from './writers.js';
42
+ import { encodeEAN13, encodeEAN8, encodeUPCA, encodeUPCE, encodeISBN, encodeCode39, encodeCode93, encodeCode128, encodeITF, encodeITF14, encodeCodabar, encodeCode11, encodeMSI, encodePharmacode, encodeCode32, encodePZN, } from './writers.js';
40
43
  import { encodeEAN2, encodeEAN5 } from './addons.js';
44
+ import { encodeTelepen } from './telepen.js';
45
+ import { encodeIndustrial2of5, encodeIATA2of5 } from './code25.js';
46
+ import { encodePostnet, encodePlanet, encodeRM4SCC, encodeKIX, encodeAustraliaPost, encodeJapanPost, encodeIMB, } from './postal.js';
41
47
  /**
42
48
  * Writers by format id, for the top-level `encode()` dispatcher.
43
49
  *
@@ -64,12 +70,24 @@ export const ONED_FORMATS = {
64
70
  code93: { encode: encodeCode93, readable: true, label: 'Code 93' },
65
71
  itf: { encode: encodeITF, readable: true, label: 'ITF (Interleaved 2 of 5)' },
66
72
  itf14: { encode: encodeITF14, readable: true, label: 'ITF-14' },
73
+ industrial2of5: { encode: encodeIndustrial2of5, readable: true, label: 'Industrial 2 of 5' },
74
+ iata2of5: { encode: encodeIATA2of5, readable: true, label: 'IATA 2 of 5' },
67
75
  codabar: { encode: encodeCodabar, readable: true, label: 'Codabar' },
68
76
  code11: { encode: encodeCode11, readable: true, label: 'Code 11' },
69
77
  msi: { encode: encodeMSI, readable: true, label: 'MSI Plessey' },
78
+ code32: { encode: encodeCode32, readable: true, label: 'Code 32 (Italian Pharmacode)' },
79
+ pzn: { encode: encodePZN, readable: true, label: 'PZN (Pharmazentralnummer)' },
80
+ telepen: { encode: encodeTelepen, readable: true, label: 'Telepen' },
70
81
  pharmacode: { encode: encodePharmacode, readable: false, label: 'Pharmacode' },
71
82
  // Supplements are reported as readable capabilities, but the image reader
72
83
  // only accepts them when attached to a validated EAN/UPC parent symbol.
73
84
  ean2: { encode: encodeEAN2, readable: true, role: 'supplement', label: 'EAN-2 supplement' },
74
85
  ean5: { encode: encodeEAN5, readable: true, role: 'supplement', label: 'EAN-5 supplement' },
86
+ postnet: { encode: encodePostnet, readable: true, label: 'USPS POSTNET' },
87
+ planet: { encode: encodePlanet, readable: true, label: 'USPS PLANET' },
88
+ rm4scc: { encode: encodeRM4SCC, readable: true, label: 'Royal Mail 4-State (RM4SCC)' },
89
+ kix: { encode: encodeKIX, readable: true, label: 'KIX postal code' },
90
+ auspost: { encode: encodeAustraliaPost, readable: true, label: 'Australia Post 4-State' },
91
+ japanpost: { encode: encodeJapanPost, readable: true, label: 'Japan Post 4-State' },
92
+ imb: { encode: encodeIMB, readable: true, label: 'USPS Intelligent Mail (IMb)' },
75
93
  };