@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
package/LICENSE CHANGED
@@ -104,22 +104,26 @@ excerpt the specification documents.
104
104
  ISO/IEC 24778 (Aztec) ISO/IEC — copyrighted, paywalled
105
105
  ISO/IEC 16023 (MaxiCode) ISO/IEC — copyrighted, paywalled
106
106
  ISO/IEC 15417 (Code 128) ISO/IEC — copyrighted, paywalled
107
+ Codablock-F / Code 16K AIM / public descriptions; terms vary
108
+ [TO VERIFY]
107
109
  ISO/IEC 16388 (Code 39) ISO/IEC — copyrighted, paywalled
108
110
  ISO/IEC 16390 (ITF) ISO/IEC — copyrighted, paywalled
111
+ AIM USS Code 25 / 2-of-5 family AIM Inc. — terms vary [TO VERIFY]
109
112
  ISO/IEC 15420 (EAN/UPC) ISO/IEC — copyrighted, paywalled
110
113
  ISO/IEC 23941 (rMQR) ISO/IEC — copyrighted, paywalled
111
114
  ISO/IEC 24724 (GS1 DataBar) ISO/IEC — copyrighted, paywalled
112
115
  ISO 2108 (ISBN numbering) ISO — copyrighted; the numbering
113
116
  scheme, not a symbology
114
- ISO/IEC 24723-5 (GS1 Composite,
115
- DataBar, DotCode
116
- and related) ISO/IEC — copyrighted, paywalled
117
+ ISO/IEC 24723 (GS1 Composite) ISO/IEC — copyrighted, paywalled
117
118
  GS1 General Specifications GS1 — freely downloadable; redistribution
118
119
  terms are GS1's own [TO VERIFY]
119
120
  AIM symbology specifications AIM Inc. — terms vary [TO VERIFY]
120
121
  GB/T 21049 (Han Xin Code) SAC (China) [TO VERIFY]
121
122
  USPS publications (POSTNET,
122
123
  PLANET, Intelligent Mail) USPS — published openly [TO VERIFY]
124
+ Royal Mail RM4SCC, KIX,
125
+ Australia Post, Japan Post respective postal operators; public
126
+ material and usage terms vary [TO VERIFY]
123
127
 
124
128
 
125
129
  4. PATENT POSITIONS
@@ -151,11 +155,23 @@ INDEPENDENTLY VERIFIED BY THE AUTHOR. Treat every entry as a research pointer.
151
155
  public use [TO VERIFY]
152
156
  DotCode AIM open AIM standard [TO VERIFY]
153
157
  Han Xin Code Chinese nat'l std status under GB/T 21049 [TO VERIFY]
158
+ GS1 Composite GS1 / ISO/IEC 24723 component and patent status require
159
+ current jurisdictional review [TO VERIFY]
154
160
  DataBar/GS1 GS1 published for open use [TO VERIFY]
155
161
  Code 128 / 39 /
156
162
  93 / Codabar / ITF / MSI /
157
163
  Code 11 / Telepen / Pharmacode originating patents long expired
158
164
  [TO VERIFY]
165
+ Code 25 / Industrial 2-of-5 /
166
+ IATA 2-of-5 / Code 32 / PZN application profiles and
167
+ originating patents require current
168
+ status review [TO VERIFY]
169
+ Postal 4-state family operator-specific rights and
170
+ indicia/certification terms require
171
+ jurisdictional review [TO VERIFY]
172
+ Codablock-F / Code 16K originating patents and current
173
+ trademark positions require review
174
+ [TO VERIFY]
159
175
 
160
176
  Formats whose status could not be established as clearly redistributable are
161
177
  NOT IMPLEMENTED by this project. See section 6.
@@ -179,6 +195,8 @@ names and presents itself.
179
195
  GS1 DataMatrix, GS1-128 GS1 AISBL
180
196
  Data Matrix [status TO VERIFY]
181
197
  Telepen SB Electronic Systems Ltd [TO VERIFY]
198
+ Code 32 / PZN descriptive pharmaceutical identifiers;
199
+ no proprietary mark asserted here [TO VERIFY]
182
200
 
183
201
  All marks are the property of their respective owners and are used here in a
184
202
  purely descriptive, nominative sense — to identify which symbologies this
@@ -221,4 +239,4 @@ change to the dependency set, the oracle tools, or the implemented format list
221
239
  MUST update this file in the same commit. A "[TO VERIFY]" marker may only be
222
240
  removed together with a citation recorded in NOTICE.md.
223
241
 
224
- Last reviewed: 2026-08-13
242
+ Last reviewed: 2026-08-31
package/NOTICE.md CHANGED
@@ -105,8 +105,17 @@ date of transcription.
105
105
  | FrameQR Code | DENSO WAVE's [FrameQR overview](https://www.qrcode.com/en/codes/frameqr.html), [product page](https://www.denso-wave.com/en/system/qr/product/frame.html) and [public announcement](https://www.denso-wave.com/en/adcd/info/detail__272.html) were consulted on 2026-08-13. The public material is used only to document the proprietary-format boundary; the distributed implementation is the separate non-certified `sythos-canvas-qr/1` profile. ZXing Java 3.5.3 was used only as an independent black-box runtime check: QR Model 2 control passed, `FRAME_QR` native capability was unavailable, and the profile was decoded as ordinary QR. No ZXing source code or tables are copied or shipped; native DENSO interoperability is not claimed. |
106
106
  | Aztec Rune and Compact PDF417 | ISO/IEC public technical descriptions and ZXing-C++ 3.1.1 were consulted on 2026-08-13. ZXing-C++ was used exclusively as an independent black-box validation tool; no source code or table is copied or shipped. Aztec Rune values were compared exhaustively; Compact PDF417 geometry and payload vectors were compared independently. |
107
107
  | EAN-2 and EAN-5 supplements | ISO/IEC 15420, GS1 public specifications and ZXing-C++ 3.1.1 were consulted on 2026-08-13. The add-on parity, guard and checksum routines are original Sythos code; ZXing-C++ was used only for independent add-on validation. |
108
- | GS1 DataBar Omnidirectional and Truncated | ISO/IEC 24724 and public GS1 material were consulted on 2026-08-13. The physical encoder/decoder uses original Sythos arithmetic and was compared bit-for-bit with Zint 2.16.0 and read bidirectionally with ZXing-C++ 3.1.1 as black boxes. No Zint or ZXing source code or table is copied or shipped. Limited, stacked and expanded physical variants remain outside this release. |
108
+ | GS1 DataBar physical variants | ISO/IEC 24724 and public GS1 material were consulted on 2026-08-30. The Omnidirectional/Truncated, Limited, Stacked, Stacked Omnidirectional and Expanded encoders/decoders use original Sythos arithmetic and strict geometry checks. The Expanded reader covers the general-purpose path plus the common compressed GTIN-14 method; its detector remains a clean, single-symbol linear profile. Independent implementations were used only as black-box verification; no third-party source code or table is copied or shipped. |
109
+ | MaxiCode | ISO/IEC 16023 public descriptions and independent implementation behavior were consulted on 2026-08-30. The fixed-grid placement, Modes 2–5 primary/secondary handling, ISO-8859-1 Code Sets A–E and Reed–Solomon path are original Sythos code. Independent runtimes were used only for black-box review; no third-party source code or table is copied or shipped. The detector is limited to one clean, prominent 30×33 symbol and does not claim arbitrary perspective or multi-symbol scene support. |
109
110
  | Code 11 and MSI Plessey image readers | Published format descriptions and the existing Sythos writer tables were used to implement the scanline readers on 2026-08-13. No third-party source code or table is copied or shipped; checksum and start/stop validation remain original Sythos code. |
111
+ | Telepen Alpha and Numeric | Public Telepen descriptions were consulted on 2026-08-30 for seven-bit parity, narrow/wide glyph rules, Numeric pair compaction and modulo-127 checksum behavior. The implementation generates its glyph mapping algorithmically in original Sythos TypeScript; no third-party table or source is copied or shipped. ZXing-C++ and BWIPP/bwip-js were used solely as independent black-box validation tools. |
112
+ | Code 25 family | Public descriptions of Code 25/Standard 2 of 5, Industrial 2 of 5 and IATA 2 of 5 were consulted on 2026-08-30 for the two-wide-bar digit grammar and guard frames. Original Sythos TypeScript expands the run-width rules algorithmically and validates structure/check digits. BWIPP/bwip-js was used only as a local black-box counter-check; no third-party source or table is copied or shipped. |
113
+ | Code 32 and PZN | Public descriptions and independent format behaviour were consulted on 2026-08-30 for Code 32 base-32/vowel-skipping/check-digit rules and PZN-7/PZN-8 modulo-11 validation. The carrier and arithmetic are original Sythos code. BWIPP/bwip-js was used only as a local black-box counter-check; no third-party source or table is copied or shipped. |
114
+ | Postal 4-state family | Public descriptions of USPS POSTNET/PLANET/IMb, Royal Mail RM4SCC, KIX, Australia Post and Japan Post were consulted on 2026-08-31 for their operator-specific state alphabets, framing, checks and payload envelopes. The shared classifier, check routines, Australia GF(64) parity and IMb combinatorial mapping are original Sythos TypeScript. BWIPP/bwip-js was used exclusively as a local black-box validation tool for all seven formats; no third-party source, table or runtime dependency is copied or shipped. See `licenses/postal.license`. |
115
+ | Codablock-F and Code 16K | Public stacked Code 128 descriptions and the USS Code 16K reference were consulted on 2026-08-31 for row geometry, Code 128 framing and check boundaries. The encoders, readers and detectors are original Sythos TypeScript. Independent implementations, when used, are black-box validation only; no third-party source, table or runtime dependency is copied or shipped. Patent, trademark and specification licensing positions remain subject to legal review. |
116
+ | DotCode | Public AIM/GS1 descriptions, the DotCode overview and Zint's public backend were consulted on 2026-08-31 for the alternating-dot geometry, five-of-nine patterns, masks and correction profile. The encoder, reader and detector are original Sythos TypeScript. Zint, ZXing and other software are independent black-box references only; no third-party source, table or runtime dependency is copied or shipped. Patent, trademark and specification licensing positions remain subject to legal review. |
117
+ | Han Xin Code | Public Han Xin format descriptions and independent implementation behaviour were consulted on 2026-08-31 for the bounded compact versions 1–3 profile. The encoder, reader, detector and GF(256) correction path are original Sythos TypeScript. Independent software is used only as a black-box validation reference; no third-party source, table or runtime dependency is copied or shipped. Version, patent, trademark and specification licensing positions remain subject to legal review. |
118
+ | GS1 DataBar Composite | ISO/IEC 24723 and public GS1 material were consulted on 2026-08-31 for the bounded Sythos profile that links one validated DataBar host to one strict MicroPDF417-derived CC-A or CC-B component. The marker, composition, linkage and detector are original Sythos TypeScript. Independent implementations are black-box validation tools only; no third-party source, table or runtime dependency is copied or shipped. This profile does not claim complete ISO/IEC 24723 conformance or certification; patent, trademark and specification positions remain subject to legal review. |
110
119
  | GS1-128 semantic layer | The existing shared GS1 Application Identifier metadata and public GS1 descriptions were reused on 2026-08-13. FNC1 classification and parsing are original Sythos integration code; no third-party decoder is a runtime dependency. |
111
120
 
112
121
  ## Verification log
package/README.md CHANGED
@@ -89,18 +89,22 @@ const svg = toSVG(encodeQR('https://example.com', { ecc: 'M' }), { scale: 8 });
89
89
  | `@sythos/js_barcode_universal` | The whole surface: `encode`, `decode`, every renderer, every error type |
90
90
  | `@sythos/js_barcode_universal/core` | `BitMatrix`, `GaloisField`, Reed–Solomon, the error classes |
91
91
  | `@sythos/js_barcode_universal/image` | `LuminanceSource`, the binarizers, grid sampling, `PerspectiveTransform` |
92
- | `@sythos/js_barcode_universal/oned` | The per-format 1D writers (`encodeEAN13`, `encodeCode128`, …) and `decodeOneD` |
92
+ | `@sythos/js_barcode_universal/oned` | The per-format 1D writers (`encodeEAN13`, `encodeCode128`, `encodeCode32`, `encodePZN`, `encodeTelepen`, `encodePostnet`, `encodePlanet`, `encodeRM4SCC`, `encodeKIX`, `encodeAustraliaPost`, `encodeJapanPost`, `encodeIMB`, …), Code 25 variants and `decodeOneD` |
93
93
  | `@sythos/js_barcode_universal/qr` | `encodeQR`, `decodeQR`, `detectQR`, `detectAndDecodeQR` |
94
94
  | `@sythos/js_barcode_universal/datamatrix` | `encodeDataMatrix`, `decodeDataMatrix`, `detectDataMatrix`, `detectAndDecodeDataMatrix` |
95
95
  | `@sythos/js_barcode_universal/aztec` | `encodeAztec`, `decodeAztec`, `detectAztec`, `detectAndDecodeAztec` |
96
96
  | `@sythos/js_barcode_universal/aztecrune` | `encodeAztecRune`, `decodeAztecRune`, `detectAztecRune`, `detectAndDecodeAztecRune` |
97
97
  | `@sythos/js_barcode_universal/pdf417` | `encodePDF417`, `decodePDF417`, `detectPDF417`, `detectAndDecodePDF417` |
98
98
  | `@sythos/js_barcode_universal/compactpdf417` | `encodeCompactPDF417`, `decodeCompactPDF417`, `detectCompactPDF417`, `detectAndDecodeCompactPDF417` |
99
- | `@sythos/js_barcode_universal/databar` | GS1 DataBar GTIN/AI codecs plus Omnidirectional/Truncated physical helpers |
99
+ | `@sythos/js_barcode_universal/databar` | GS1 DataBar GTIN/AI codecs plus Omnidirectional/Truncated, Limited, Stacked, Stacked Omnidirectional and Expanded physical helpers |
100
100
  | `@sythos/js_barcode_universal/micropdf417` | `encodeMicroPDF417`, `decodeMicroPDF417`, `detectMicroPDF417`, `detectAndDecodeMicroPDF417` |
101
101
  | `@sythos/js_barcode_universal/microqr` | `encodeMicroQR`, `decodeMicroQR`, `detectMicroQR`, `detectAndDecodeMicroQR` |
102
102
  | `@sythos/js_barcode_universal/rmqr` | `encodeRMQR`, `decodeRMQR`, `detectRMQR`, `detectAndDecodeRMQR` |
103
103
  | `@sythos/js_barcode_universal/frameqr` | `encodeFrameQR`, `decodeFrameQR`, `detectFrameQR`, `detectAndDecodeFrameQR` |
104
+ | `@sythos/js_barcode_universal/maxicode` | `encodeMaxiCode`, `decodeMaxiCode`, `detectMaxiCode`, `detectAndDecodeMaxiCode` |
105
+ | `@sythos/js_barcode_universal/dotcode` | `encodeDotCode`, `decodeDotCode`, `detectDotCode`, `detectAndDecodeDotCode` |
106
+ | `@sythos/js_barcode_universal/hanxin` | `encodeHanXin`, `encodeHanXinBytes`, `decodeHanXin`, `detectHanXin`, `detectAndDecodeHanXin` |
107
+ | `@sythos/js_barcode_universal/composite` | `encodeGS1Composite`, `decodeGS1Composite`, `detectGS1Composite`, `detectAndDecodeGS1Composite` |
104
108
  | `@sythos/js_barcode_universal/render` | Every renderer plus `isWebGL2Available` / `isWebGPUAvailable` |
105
109
  | `@sythos/js_barcode_universal/render/svg` | `toSVG`, `toSVGDataURI` |
106
110
  | `@sythos/js_barcode_universal/render/png` | `toPNG`, `toPNGDataURI` |
@@ -112,8 +116,8 @@ The `unpkg` and `jsdelivr` fields point at the IIFE bundle, so a CDN needs no in
112
116
 
113
117
  ```html
114
118
  <script src="https://unpkg.com/@sythos/js_barcode_universal"></script>
115
- <script src="https://unpkg.com/@sythos/js_barcode_universal@1.5.13"></script>
116
- <script src="https://cdn.jsdelivr.net/npm/@sythos/js_barcode_universal@1.5.13"></script>
119
+ <script src="https://unpkg.com/@sythos/js_barcode_universal@1.5.15"></script>
120
+ <script src="https://cdn.jsdelivr.net/npm/@sythos/js_barcode_universal@1.5.15"></script>
117
121
  ```
118
122
 
119
123
  Pin the version for anything you ship; the unpinned form resolves to `latest` and will move under
@@ -248,10 +252,23 @@ time.
248
252
  | Code 93 | `code93` | 1D | ✅ | ✅ |
249
253
  | ITF (Interleaved 2 of 5) | `itf` | 1D | ✅ | ✅ |
250
254
  | ITF-14 | `itf14` | 1D | ✅ | ✅ [^1] |
255
+ | Code 25 / Standard 2 of 5 | `standard2of5` | 1D | ✅ | ✅ [^4] |
256
+ | Industrial 2 of 5 | `industrial2of5` | 1D | ✅ | ✅ [^4] |
257
+ | IATA 2 of 5 | `iata2of5` | 1D | ✅ | ✅ [^4] |
251
258
  | Codabar | `codabar` | 1D | ✅ | ✅ |
252
259
  | Code 11 | `code11` | 1D | ✅ | ✅ |
253
260
  | MSI Plessey | `msi` | 1D | ✅ | ✅ |
261
+ | Telepen (ASCII and Numeric) | `telepen` | 1D | ✅ | ✅ [^3] |
262
+ | Code 32 (Italian Pharmacode) | `code32` | 1D | ✅ | ✅ |
263
+ | PZN-7 / PZN-8 | `pzn` | 1D | ✅ | ✅ |
254
264
  | Pharmacode | `pharmacode` | 1D | ✅ | — |
265
+ | USPS POSTNET | `postnet` | 1D | ✅ | ✅ |
266
+ | USPS PLANET | `planet` | 1D | ✅ | ✅ |
267
+ | Royal Mail 4-State (RM4SCC) | `rm4scc` | 1D | ✅ | ✅ |
268
+ | KIX postal code | `kix` | 1D | ✅ | ✅ |
269
+ | Australia Post 4-State | `auspost` | 1D | ✅ | ✅ |
270
+ | Japan Post 4-State | `japanpost` | 1D | ✅ | ✅ |
271
+ | USPS Intelligent Mail (IMb / OneCode) | `imb` | 1D | ✅ | ✅ |
255
272
  | QR Code | `qr` | 2D | ✅ | ✅ |
256
273
  | Data Matrix ECC 200 | `datamatrix` | 2D | ✅ | ✅ |
257
274
  | Aztec Code | `aztec` | 2D | ✅ | ✅ |
@@ -263,19 +280,144 @@ time.
263
280
  | Aztec Rune | `aztecrune` | 2D | ✅ | ✅ |
264
281
  | Compact PDF417 | `compactpdf417` | 2D | ✅ | ✅ |
265
282
  | GS1 DataBar Omnidirectional / Truncated | `gs1databar14` | 1D | ✅ | ✅ |
283
+ | GS1 DataBar Stacked | `gs1databar-stacked` | 1D | ✅ | ✅ |
284
+ | GS1 DataBar Stacked Omnidirectional | `gs1databar-stacked-omnidirectional` | 1D | ✅ | ✅ |
285
+ | GS1 DataBar Limited | `gs1databar-limited` | 1D | ✅ | ✅ |
286
+ | GS1 DataBar Expanded | `gs1databar-expanded` | 1D | ✅ | ✅ |
287
+ | MaxiCode | `maxicode` | 2D | ✅ | ✅ |
288
+ | Codablock-F | `codablockf` | 2D | ✅ | ✅ |
289
+ | Code 16K | `code16k` | 2D | ✅ | ✅ |
290
+ | DotCode | `dotcode` | 2D | ✅ | ✅ |
291
+ | Han Xin Code | `hanxin` | 2D | ✅ | ✅ |
292
+ | GS1 DataBar Composite (bounded Sythos profile) | `gs1composite` | 2D | ✅ | ✅ |
266
293
  | EAN-2 supplement | `ean2` | 1D | ✅ | ✅ [^2] |
267
294
  | EAN-5 supplement | `ean5` | 1D | ✅ | ✅ [^2] |
268
295
 
269
- Twenty-eight listed formats are writable and twenty-seven are readable (EAN-2 and EAN-5 are
296
+ Fifty listed formats are writable and forty-nine are readable (EAN-2 and EAN-5 are
270
297
  parent-bound supplements). **Pharmacode remains intentionally write-only in the generic image
271
- pipeline.** Code 11 and MSI Plessey use the scanline reader; GS1 DataBar uses the
272
- Omnidirectional/Truncated scanline layer over the verified GTIN decoder. PDF417 exposes direct matrix decoding, automatic
298
+ pipeline.** Code 11 and MSI Plessey use the scanline reader. Telepen supports both its full
299
+ seven-bit ASCII mode and explicit Numeric pair mode; Numeric reads must request
300
+ `formats: ['telepennumeric']` so digit pairs are never guessed as ASCII control characters. The
301
+ Code 25 family shares one numeric digit grammar while exposing explicit Standard/Industrial and
302
+ IATA guard profiles; Code 32 and PZN validate their pharmaceutical check digits before a read is
303
+ returned. Postal formats use operator-specific four-state alphabets with strict framing and
304
+ checksum validation; KIX deliberately has no check character, while Australia Post supports
305
+ explicit character or numeric customer-data groups and IMb accepts its four legal payload lengths.
306
+ The
307
+ GS1 DataBar physical variants use
308
+ strict clean-raster readers and variant-specific detectors over the verified GTIN/GS1 element-string
309
+ decoder. Expanded also accepts the common compressed GTIN-14 method on the read path. MaxiCode
310
+ uses a fixed 30×33 matrix and a clean binary-raster detector for one prominent symbol. PDF417 exposes direct matrix decoding, automatic
273
311
  camera localization and an assisted quadrilateral sampler through its subpath. Its detector is
274
312
  validated on degraded synthetic photographs and real Pixel 10/Chrome and iPhone 17/Safari camera
275
313
  tests; external black-box vectors from ZXing 3.5.3 and bwip-js also pass in both directions.
276
314
  Text and Numeric vectors are covered bidirectionally; binary byte-for-byte interop remains
277
315
  explicitly unclaimed until a dedicated external byte corpus is added.
278
316
 
317
+ Codablock-F uses stacked Code 128 rows with per-row modulo-103 checks and two
318
+ overall modulo-86 checks. The writer chooses a compact 2–44 row layout (or
319
+ accepts explicit `rows` and `columns`), while the detector returns a result only
320
+ when every expected row and check agrees:
321
+
322
+ ```js
323
+ import { encodeCodablockF, detectAndDecodeCodablockF } from '@sythos/js_barcode_universal/codablockf';
324
+
325
+ const matrix = encodeCodablockF('STACKED ORDER 12345', { rows: 3, columns: 12 });
326
+ const hit = detectAndDecodeCodablockF(matrix);
327
+ console.log(hit?.text, hit?.rows, hit?.columns);
328
+ ```
329
+
330
+ The clean integer-scale detector is designed to reject incomplete or damaged
331
+ rows. It does not promise arbitrary perspective, severe occlusion or
332
+ multi-symbol camera scenes. See [`docs/formats/codablockf.md`](docs/formats/codablockf.md)
333
+ and [`licenses/codablockf.license`](licenses/codablockf.license).
334
+
335
+ Code 16K keeps the Code 128 A/B/C data sets in a compact stacked symbol. The
336
+ writer supports 2–16 rows, five Code 128 symbols per row, optional GS1 modes
337
+ and explicit row or separator heights. The reader validates every row, both
338
+ modulo-107 check characters and the complete geometry before returning text:
339
+
340
+ ```js
341
+ import { encodeCode16K, detectAndDecodeCode16K } from '@sythos/js_barcode_universal/code16k';
342
+
343
+ const matrix = encodeCode16K('INVENTORY 123456', { mode: 'B', rows: 3 });
344
+ const hit = detectAndDecodeCode16K(matrix);
345
+ console.log(hit?.text, hit?.rows, hit?.mode);
346
+ ```
347
+
348
+ The detector accepts clean integer-scale rasters and orthogonal rotations. It
349
+ rejects missing rows, altered modules, invalid checks and ambiguous geometry;
350
+ arbitrary perspective and multi-symbol camera scenes remain outside the
351
+ validated envelope. See [`docs/formats/code16k.md`](docs/formats/code16k.md)
352
+ and [`licenses/code16k.license`](licenses/code16k.license).
353
+
354
+ DotCode uses an alternating dot grid rather than a solid finder pattern. The
355
+ writer and reader cover the bounded five-of-nine pattern set, four masks,
356
+ prime-field Reed–Solomon correction, UTF-8 and byte payloads, with optional
357
+ GS1/FNC1 handling:
358
+
359
+ ```js
360
+ import { encodeDotCode, detectAndDecodeDotCode } from '@sythos/js_barcode_universal/dotcode';
361
+
362
+ const matrix = encodeDotCode('DOTCODE ORDER 123', { width: 29, height: 30, mask: 1 });
363
+ const hits = detectAndDecodeDotCode(matrix.withMargin(3).scale(2), { moduleSize: 2 });
364
+ console.log(hits[0]?.text, hits[0]?.moduleSize);
365
+ ```
366
+
367
+ The detector is intentionally strict: it accepts complete clean binary rasters
368
+ at integer scale, quarter-turn orientations and either polarity, then returns
369
+ only a checksum-validated symbol. Perspective, curved media, severe blur and
370
+ multi-symbol scenes remain outside the supported profile. See
371
+ [`docs/formats/dotcode.md`](docs/formats/dotcode.md) and
372
+ [`licenses/dotcode.license`](licenses/dotcode.license).
373
+
374
+ Han Xin Code is available as a bounded compact profile covering versions 1–3,
375
+ the four `L1`–`L4` error-correction levels, numeric/text/byte modes, four masks
376
+ and strict Reed–Solomon validation. The root dispatcher accepts both
377
+ `format: 'hanxin'` and the compatibility alias `format: 'han-xin'`; the focused
378
+ subpath is useful when byte payloads or format metadata are needed:
379
+
380
+ ```js
381
+ import {
382
+ encodeHanXin,
383
+ detectAndDecodeHanXin,
384
+ } from '@sythos/js_barcode_universal/hanxin';
385
+
386
+ const matrix = encodeHanXin('HAN XIN 2026', { mode: 'text', ecc: 'L2' });
387
+ const hit = detectAndDecodeHanXin(matrix.withMargin(3).scale(2));
388
+ console.log(hit?.text, hit?.version, hit?.moduleSize);
389
+ ```
390
+
391
+ The Han Xin detector accepts one complete, axis-aligned symbol at an integer
392
+ module scale and either polarity. Versions 4–84, Chinese/GB18030 compaction,
393
+ ECI, perspective correction and multi-symbol camera scenes remain outside this
394
+ profile. See [`docs/formats/hanxin.md`](docs/formats/hanxin.md) and
395
+ [`licenses/hanxin.license`](licenses/hanxin.license).
396
+
397
+ GS1 DataBar Composite is available as the bounded `gs1composite` profile. It
398
+ links one validated DataBar host to one strict CC-A or CC-B component and
399
+ requires the complete geometry, linkage flag, private profile marker and
400
+ shared integer module scale to validate before returning data:
401
+
402
+ ```js
403
+ import {
404
+ encodeGS1Composite,
405
+ detectAndDecodeGS1Composite,
406
+ } from '@sythos/js_barcode_universal/composite';
407
+
408
+ const matrix = encodeGS1Composite({
409
+ linear: { format: 'databar14', value: '00012345678905' },
410
+ data: '(01)09506000134352(17)260101',
411
+ });
412
+ const hit = detectAndDecodeGS1Composite(matrix.withMargin(3).scale(2));
413
+ console.log(hit?.text, hit?.linearFormat, hit?.component);
414
+ ```
415
+
416
+ This is an original Sythos engineering profile, not a claim of complete
417
+ ISO/IEC 24723 certification or universal scanner interoperability. Its full
418
+ limits and legal boundary are in [`docs/formats/gs1-composite.md`](docs/formats/gs1-composite.md)
419
+ and [`licenses/gs1-composite.license`](licenses/gs1-composite.license).
420
+
279
421
  [^1]: `itf14` and `isbn` share a decoder with their base format, so an ITF-14 comes back as `itf`
280
422
  and an ISBN as `ean13`. GS1-128 is classified separately as `gs1128` when its leading FNC1 is
281
423
  present and exposes `gs1`, `symbologyIdentifier` and parsed `elements` metadata. The payload is
@@ -285,6 +427,14 @@ with a 978/979 prefix.
285
427
  [^2]: EAN-2 and EAN-5 are recognized only when attached to a validated EAN-13, EAN-8, UPC-A or
286
428
  UPC-E parent; they are not independent generic retail-symbol readers.
287
429
 
430
+ [^3]: Telepen Numeric is an explicit mode because its compact digit-pair glyphs share the same
431
+ guards as Telepen Alpha. Use `format: 'telepennumeric'` when encoding or
432
+ `formats: ['telepennumeric']` when reading.
433
+
434
+ [^4]: Code 25/Standard 2 of 5 and Industrial 2 of 5 use the canonical Industrial frame in this
435
+ SDK; IATA 2 of 5 uses its shorter guard frame. Check digits are optional for ordinary reads and
436
+ are required by the strict camera profile.
437
+
288
438
  ### Code 11 and MSI Plessey image reading
289
439
 
290
440
  The generic image pipeline now recognizes Code 11 and MSI Plessey through the existing
@@ -294,6 +444,132 @@ preserved for MSI and reliably stripped for Code 11 when its C/K grammar is unam
294
444
  reader keeps Pharmacode write-only because its unframed narrow/wide grammar is not safe for
295
445
  unrestricted image autodetection.
296
446
 
447
+ ### Telepen
448
+
449
+ Telepen is available from the `oned` subpath and the root dispatcher. The default
450
+ `telepen` format carries full seven-bit ASCII with an even parity bit and a modulo-127
451
+ check value. The explicit `telepennumeric` format compacts digit pairs and allows `X`
452
+ only as the second character of a pair. Both writers enforce the format grammar, a
453
+ 500-character input limit and complete start/check/stop structure.
454
+
455
+ ```js
456
+ import { encodeTelepen, encodeTelepenNumeric } from '@sythos/js_barcode_universal/oned';
457
+ import { decode, toImageData } from '@sythos/js_barcode_universal';
458
+
459
+ const alpha = encodeTelepen('TELEPEN-ASCII');
460
+ const numeric = encodeTelepenNumeric('00112738999X');
461
+ const image = toImageData(alpha, { scale: 3, margin: 30, barHeight: 64 });
462
+ const [hit] = decode(image, { formats: ['telepen'] });
463
+ console.log(hit?.text); // TELEPEN-ASCII
464
+ ```
465
+
466
+ For Numeric symbols, select the numeric identifier explicitly:
467
+
468
+ ```js
469
+ const numericImage = toImageData(numeric, { scale: 3, margin: 30, barHeight: 64 });
470
+ const [numericHit] = decode(numericImage, { formats: ['telepennumeric'] });
471
+ console.log(numericHit?.text); // 00112738999X
472
+ ```
473
+
474
+ The scanline reader measures the complete symbol at scale-independent run widths,
475
+ rejects ambiguous candidates, verifies parity and the modulo-127 check value, and
476
+ returns no partial result. A camera-profile read additionally requires a coherent
477
+ quiet-zone-qualified symbol across repeated scan samples.
478
+
479
+ ### Code 25, Industrial 2 of 5 and IATA 2 of 5
480
+
481
+ The Code 25 family is available from both the root dispatcher and the `oned`
482
+ subpath. `standard2of5` (also `code2of5`) and `industrial2of5` use the same
483
+ canonical two-wide-bar frame here; `iata2of5` uses the shorter IATA guard. The
484
+ optional modulo-10 check digit is appended by the writer and can be required by
485
+ the reader or by the strict camera profile:
486
+
487
+ ```js
488
+ import { decode, encode, toImageData } from '@sythos/js_barcode_universal';
489
+
490
+ const matrix = encode('01234567', {
491
+ format: 'industrial2of5',
492
+ checkDigit: true,
493
+ wideRatio: 3,
494
+ });
495
+ const [hit] = decode(toImageData(matrix, {
496
+ scale: 3,
497
+ margin: 30,
498
+ barHeight: 64,
499
+ }), {
500
+ formats: ['industrial2of5'],
501
+ checkDigit: true,
502
+ });
503
+ console.log(hit?.text); // 01234567
504
+ ```
505
+
506
+ Use `format: 'iata2of5'` for IATA framing. The reader validates the complete
507
+ start/data/stop structure and rejects clipped or ambiguous candidates; a camera
508
+ read additionally requires a quiet zone and a valid check digit.
509
+
510
+ ### Code 32 and PZN
511
+
512
+ Code 32 (the Italian pharmaceutical code) and PZN-7/PZN-8 are explicit,
513
+ check-digit-validated pharmaceutical formats. Code 32 accepts an eight-digit
514
+ body (or the same body with its validated check digit) and renders the compact
515
+ base-32 payload through the Code 39 carrier. PZN accepts six digits for PZN-7 or
516
+ seven digits with `{ pzn8: true }` for PZN-8; the decoder exposes `pznVariant`.
517
+
518
+ ```js
519
+ import { decode, encode, toImageData } from '@sythos/js_barcode_universal';
520
+
521
+ const code32 = encode('01234567', { format: 'code32' });
522
+ const pzn8 = encode('1234567', { format: 'pzn8' });
523
+ const image = toImageData(pzn8, { scale: 3, margin: 30, barHeight: 64 });
524
+ const [result] = decode(image, { formats: ['pzn8'] });
525
+ console.log(result?.format, result?.pznVariant, result?.text);
526
+ // pzn pzn8 1234567
527
+ ```
528
+
529
+ Both readers return no value when the carrier or pharmaceutical check digit is
530
+ not valid. The format-specific engineering notes and the independent
531
+ black-box validation boundary are recorded in [`licenses/`](licenses/).
532
+
533
+ ### Postal 4-state formats
534
+
535
+ The postal family shares a strict height-coded raster classifier while keeping
536
+ each operator's alphabet and checksum separate. The root dispatcher and the
537
+ `oned` subpath expose USPS POSTNET and PLANET, Royal Mail RM4SCC, Dutch KIX,
538
+ Australia Post, Japan Post and USPS Intelligent Mail (IMb/OneCode):
539
+
540
+ ```js
541
+ import { decode, encode, toImageData } from '@sythos/js_barcode_universal';
542
+
543
+ const matrix = encode('5956439111ABC', {
544
+ format: 'auspost',
545
+ customerEncoding: 'character',
546
+ });
547
+ const image = toImageData(matrix, { scale: 3, margin: 24, barHeight: 72 });
548
+ const [result] = decode(image, {
549
+ formats: ['auspost'],
550
+ customerEncoding: 'character',
551
+ });
552
+ console.log(result?.format, result?.text, result?.checkDigit);
553
+ // auspost 5956439111ABC true
554
+ ```
555
+
556
+ POSTNET accepts 5/9/11 body digits and PLANET 11/13; both append and verify a
557
+ Mod-10 check digit. RM4SCC generates and verifies its row/column check
558
+ character, while KIX has no check character. Japan Post expands its public
559
+ alphabet into fixed groups and verifies a Mod-19 check. Australia Post starts
560
+ with an FCC and eight-digit DPID, supports `customerEncoding: 'character'` or
561
+ `'numeric'` (also `custinfoenc`) and verifies GF(64) parity. IMb accepts exactly
562
+ 20, 25, 29 or 31 digits and verifies its frame check sequence. Convenience
563
+ aliases such as `onecode`, `usps-postnet` and `royal-mail` resolve to the
564
+ canonical ids shown in the format table.
565
+
566
+ The generic image reader returns an empty array for a clipped, ambiguous or
567
+ checksum-invalid symbol. `profile: 'camera'` additionally requires a measurable
568
+ quiet zone on both sides of the bars; it is intentionally conservative for
569
+ blurred, curved, heavily occluded or multi-symbol photographs. See the
570
+ [postal format guide](https://sythos.github.io/JS_Barcode_Universal/formats/postal/)
571
+ for payload limits, direct subpath functions and the complete provenance note.
572
+
297
573
  ### Data Matrix ECC 200
298
574
 
299
575
  `datamatrix` writes and reads the 30 classic ECC 200 square and rectangular symbol sizes. The
@@ -447,19 +723,91 @@ the returned `format`; an absent, malformed or unrequested supplement never reje
447
723
 
448
724
  ### GS1 DataBar
449
725
 
450
- The `databar` subpath exposes original GS1 GTIN/AI codecs plus physical
451
- Omnidirectional and Truncated writers, scanline readers and clean-matrix decoders. Four GTIN
452
- vectors were compared bit-for-bit with Zint 2.16.0 as a black box. Limited,
453
- Stacked, Stacked Omnidirectional and Expanded physical layouts remain planned;
454
- their data-layer helpers do not imply complete scanner support.
726
+ The `databar` subpath exposes original GS1 GTIN/AI codecs and five physical
727
+ variants: Omnidirectional and Truncated through `encodeDataBar14`, Limited through
728
+ `encodeDataBarLimited`, Stacked through `encodeDataBar14Stacked`, Stacked
729
+ Omnidirectional through `encodeDataBarStackedOmnidirectional`, and linear Expanded
730
+ through `encodeDataBarExpanded`. The physical paths encode the fixed GS1 `(01)`
731
+ GTIN element and can carry the standard composite linkage flag. The complete
732
+ bounded composition is exposed separately through the `composite` subpath.
733
+
734
+ The clean readers require a complete dark-on-light or inverted binary raster,
735
+ integer module scaling and valid checksum/guard structure. The Limited and
736
+ Stacked readers accept quarter turns; the Stacked Omnidirectional reader accepts
737
+ the same clean integer-scaled geometry. Their detectors intentionally reject
738
+ partial symbols, arbitrary perspective and grayscale input. Use a binarized
739
+ image or call the matrix decoder after an application-owned perspective sample.
740
+
741
+ The Stacked variant uses a 50-module row with a five-module top row, one-module
742
+ separator and seven-module bottom row. Stacked Omnidirectional uses two 50-module
743
+ rows, a three-module separator and a minimum 33-module row height. Limited uses
744
+ a 79-module row and a minimum 10-module output height; its accepted GTIN
745
+ indicator is 0 or 1. Expanded uses the linear finder sequence and constrained
746
+ 17-module data characters defined by GS1 DataBar; its writer emits the general-
747
+ purpose method and its reader also accepts the common compressed GTIN-14 method.
748
+ These geometry constraints are part of the format API, not an interoperability
749
+ claim for arbitrary photographs.
455
750
 
456
- ### Not implemented
751
+ ```js
752
+ import {
753
+ encodeDataBarLimited,
754
+ encodeDataBar14Stacked,
755
+ encodeDataBarStackedOmnidirectional,
756
+ } from '@sythos/js_barcode_universal/databar';
757
+
758
+ const limited = encodeDataBarLimited('01234567890128', { moduleScale: 2 });
759
+ const stacked = encodeDataBar14Stacked('01234567890128');
760
+ const stackedOmni = encodeDataBarStackedOmnidirectional('01234567890128');
761
+ ```
762
+
763
+ For a GS1 element string, use the Expanded helper. It returns a clean linear
764
+ symbol without a quiet zone, just like the other DataBar writers:
765
+
766
+ ```js
767
+ import {
768
+ decodeDataBarExpanded,
769
+ encodeDataBarExpanded,
770
+ } from '@sythos/js_barcode_universal/databar';
771
+
772
+ const expanded = encodeDataBarExpanded('(01)09506000134352(10)ABC-123');
773
+ const decoded = decodeDataBarExpanded(expanded);
774
+ console.log(decoded.elements, decoded.linkage);
775
+ ```
457
776
 
458
- GS1 DataBar physical support currently covers Omnidirectional and Truncated writing plus
459
- scanline and clean-matrix decoding; Limited, Stacked and Expanded physical layouts remain planned. MaxiCode is
460
- not implemented. Data Matrix ECC
461
- 200 is implemented for its classic square and rectangular symbols;
462
- DMRE remains outside the current scope. See [`PLAN.md`](PLAN.md) for the remaining symbologies.
777
+ Expanded reading accepts a complete dark-on-light or inverted binary raster,
778
+ integer module scaling and a valid finder/checksum structure. The detector is
779
+ deliberately conservative: it handles a single clean linear symbol (including
780
+ quarter turns) and rejects partial, ambiguous, grayscale or arbitrary-perspective
781
+ input instead of returning a guessed GS1 payload.
782
+
783
+ ### MaxiCode
784
+
785
+ The `maxicode` subpath exposes `encodeMaxiCode`, `decodeMaxiCode`,
786
+ `detectMaxiCode` and `detectAndDecodeMaxiCode`. The implementation uses the
787
+ fixed 30×33-module MaxiCode geometry and supports modes 2–5. Modes 2 and 3
788
+ require structured `primary` data (`postalCode`, `countryCode` and
789
+ `serviceClass`); modes 4 and 5 carry an unstructured secondary message. Text
790
+ and byte input are restricted to ISO-8859-1 (`charset: 'latin1'`).
791
+
792
+ ```js
793
+ import { encodeMaxiCode, decodeMaxiCode } from '@sythos/js_barcode_universal/maxicode';
794
+
795
+ const symbol = encodeMaxiCode('HELLO FROM SYTHOS', { mode: 4 });
796
+ const result = decodeMaxiCode(symbol);
797
+ console.log(result.text, result.mode);
798
+ ```
799
+
800
+ `decodeMaxiCode` works on a canonical 30×33 matrix and can validate its
801
+ 180-degree and inverted forms. `detectMaxiCode` is deliberately a clean binary
802
+ detector for one prominent symbol at integer or near-integer scale. It does not
803
+ promise arbitrary perspective, grayscale thresholding, severe occlusion or
804
+ multi-symbol scene handling.
805
+
806
+ ### Remaining out of scope
807
+
808
+ Data Matrix ECC 200 is implemented for its classic square and rectangular symbols;
809
+ DMRE remains outside the current scope. See [`PLAN.md`](PLAN.md) for the remaining
810
+ symbologies.
463
811
 
464
812
  ---
465
813
 
@@ -491,6 +839,23 @@ camera loop that decodes continuously from the video stream.
491
839
 
492
840
  ---
493
841
 
842
+ ## Documentation
843
+
844
+ The full, searchable documentation lives on [GitHub Pages](https://sythos.github.io/JS_Barcode_Universal/)
845
+ and is built from the checked-in [`docs/`](docs/) tree with MkDocs Material. It includes the
846
+ [API reference](https://sythos.github.io/JS_Barcode_Universal/api/overview/),
847
+ [format catalogue](https://sythos.github.io/JS_Barcode_Universal/formats/overview/),
848
+ [camera and image guides](https://sythos.github.io/JS_Barcode_Universal/guides/camera-reading/),
849
+ [practical recipes](https://sythos.github.io/JS_Barcode_Universal/examples/create-barcode/),
850
+ [FAQ](https://sythos.github.io/JS_Barcode_Universal/faq/) and
851
+ [troubleshooting](https://sythos.github.io/JS_Barcode_Universal/troubleshooting/).
852
+
853
+ Every documentation change is checked for local links, navigation coverage and registry drift in
854
+ CI before the Pages build is published. The compact README remains the versioned project
855
+ overview; the Pages site is the place for the longer explanations and copy-ready examples.
856
+
857
+ ---
858
+
494
859
  ## API summary
495
860
 
496
861
  Two functions carry the whole surface. Everything else is a renderer or a format-specific escape
@@ -540,7 +905,7 @@ and go faster), `tryHarder` (retry inverted, default `true`), `binarizer`
540
905
  (`'global' | 'hybrid' | 'auto'`). A `Result` carries at least `text` and `format`; QR results also
541
906
  carry `bytes`, `version` and `ecc`.
542
907
 
543
- For larger clean QR Code and PDF417 rasters, `auto` and `hybrid` retain their primary local-threshold pass and retry once with the global threshold only when that pass finds no result. An explicit `binarizer: 'global'` request remains single-pass.
908
+ For larger clean QR Code, PDF417 and MaxiCode rasters, `auto` and `hybrid` retain their primary local-threshold pass and retry once with the global threshold only when that pass finds no result. An explicit `binarizer: 'global'` request remains single-pass.
544
909
 
545
910
  ```js
546
911
  listFormats() → { id, label, canWrite, canRead, kind }[]
@@ -667,6 +1032,33 @@ repository-level default setup.
667
1032
  references weekly. Updates are repository-development controls only; the published SDK remains
668
1033
  zero-dependency at runtime.
669
1034
 
1035
+ The read-only quality gate in [`.github/workflows/pr-quality.yml`](.github/workflows/pr-quality.yml)
1036
+ runs for pull requests and pushes to `main`. Its Node jobs install the locked development toolchain
1037
+ with `npm ci --ignore-scripts --no-audit --no-fund`, then run ESLint, the TypeScript compiler and
1038
+ public-type checks, package-surface and zero-runtime-dependency checks, documentation checks and
1039
+ the workflow attestation validator. It has no publish credentials and cannot publish a package or
1040
+ create a release.
1041
+
1042
+ Pull-request dependency changes are checked by GitHub's Dependency Review action with read-only
1043
+ permissions. Separate tokenless workflows run OSV Scanner for known dependency vulnerabilities,
1044
+ OSSF Scorecard for repository supply-chain posture and `actionlint` for GitHub Actions syntax and
1045
+ expression mistakes. The allow-list records Blue Oak 1.0.0 only for the development-only `minimatch`
1046
+ transitive dependency; it is not shipped in the SDK package. These checks use repository or
1047
+ GitHub-provided permissions only; they do not add runtime dependencies to the SDK.
1048
+
1049
+ The same pull-request gate runs a bounded, deterministic `fast-check` property suite across the
1050
+ supported 1D and 2D encoders and decoders. It checks matrix invariants and round-trip payloads with
1051
+ small, reproducible inputs; the fuzzing harness stays in development-only test files and is excluded
1052
+ from the published npm package.
1053
+
1054
+ APIsec is intentionally not enabled: this repository is a client-side barcode SDK with no HTTP API
1055
+ or OpenAPI service to scan, and the hosted APIsec action requires an account and secrets. OWASP ZAP
1056
+ API scanning is likewise outside the current boundary because it needs an authorized live target or
1057
+ API specification. `zizmor` is kept out of the mandatory gate while its action remains an early
1058
+ development option, and Gitleaks is not made a required check because organization use can require
1059
+ an external licence. Those tools may be reconsidered only if the repository boundary changes and
1060
+ their no-secret, no-registration requirements can be met.
1061
+
670
1062
  These security workflows report findings and propose maintenance updates. They do not replace
671
1063
  review of barcode conformance, licensing, patent status or release attestations.
672
1064
 
@@ -728,7 +1120,7 @@ attestation confirms build provenance; it is not an ISO barcode-conformance cert
728
1120
  clearance, or a guarantee that the implementation is vulnerability-free.
729
1121
 
730
1122
  Release automation validates the package version against the selected Git tag; it does not invent
731
- or increment versions by itself. The current release is `1.5.13`.
1123
+ or increment versions by itself. The current release is `1.5.15`.
732
1124
 
733
1125
  ---
734
1126
 
@@ -759,9 +1151,11 @@ General Specifications and a leading FNC1. Its engineering provenance, patent an
759
1151
  research notes are recorded in [`licenses/data-matrix.license`](licenses/data-matrix.license),
760
1152
  with unresolved claims kept explicitly marked using scoped review labels.
761
1153
 
762
- PDF417 and MicroPDF417 provenance and legal review notes are recorded in
1154
+ PDF417, MicroPDF417, MaxiCode and GS1 DataBar provenance and legal review notes are recorded in
763
1155
  [`licenses/pdf417.license`](licenses/pdf417.license),
764
- [`licenses/micropdf417.license`](licenses/micropdf417.license) and the attribution log in
1156
+ [`licenses/micropdf417.license`](licenses/micropdf417.license),
1157
+ [`licenses/maxicode.license`](licenses/maxicode.license),
1158
+ [`licenses/gs1-databar.license`](licenses/gs1-databar.license) and the attribution log in
765
1159
  [`NOTICE.md`](NOTICE.md).
766
1160
 
767
1161
  Micro QR and rMQR provenance and scoped legal-review notes are recorded in