@vielzeug/sigil 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.md +40 -0
  2. package/dist/_dev.cjs +2 -0
  3. package/dist/_dev.cjs.map +1 -0
  4. package/dist/_dev.d.ts +2 -0
  5. package/dist/_dev.d.ts.map +1 -0
  6. package/dist/_dev.js +6 -0
  7. package/dist/_dev.js.map +1 -0
  8. package/dist/_format.cjs +2 -0
  9. package/dist/_format.cjs.map +1 -0
  10. package/dist/_format.d.ts +11 -0
  11. package/dist/_format.d.ts.map +1 -0
  12. package/dist/_format.js +37 -0
  13. package/dist/_format.js.map +1 -0
  14. package/dist/_galois.cjs +2 -0
  15. package/dist/_galois.cjs.map +1 -0
  16. package/dist/_galois.d.ts +13 -0
  17. package/dist/_galois.d.ts.map +1 -0
  18. package/dist/_galois.js +22 -0
  19. package/dist/_galois.js.map +1 -0
  20. package/dist/_mask.cjs +2 -0
  21. package/dist/_mask.cjs.map +1 -0
  22. package/dist/_mask.d.ts +14 -0
  23. package/dist/_mask.d.ts.map +1 -0
  24. package/dist/_mask.js +81 -0
  25. package/dist/_mask.js.map +1 -0
  26. package/dist/_matrix.cjs +2 -0
  27. package/dist/_matrix.cjs.map +1 -0
  28. package/dist/_matrix.d.ts +18 -0
  29. package/dist/_matrix.d.ts.map +1 -0
  30. package/dist/_matrix.js +65 -0
  31. package/dist/_matrix.js.map +1 -0
  32. package/dist/_reed-solomon.cjs +2 -0
  33. package/dist/_reed-solomon.cjs.map +1 -0
  34. package/dist/_reed-solomon.d.ts +3 -0
  35. package/dist/_reed-solomon.d.ts.map +1 -0
  36. package/dist/_reed-solomon.js +22 -0
  37. package/dist/_reed-solomon.js.map +1 -0
  38. package/dist/_segments.cjs +2 -0
  39. package/dist/_segments.cjs.map +1 -0
  40. package/dist/_segments.d.ts +32 -0
  41. package/dist/_segments.d.ts.map +1 -0
  42. package/dist/_segments.js +70 -0
  43. package/dist/_segments.js.map +1 -0
  44. package/dist/_tables.cjs +2 -0
  45. package/dist/_tables.cjs.map +1 -0
  46. package/dist/_tables.d.ts +46 -0
  47. package/dist/_tables.d.ts.map +1 -0
  48. package/dist/_tables.js +409 -0
  49. package/dist/_tables.js.map +1 -0
  50. package/dist/canvas.cjs +2 -0
  51. package/dist/canvas.cjs.map +1 -0
  52. package/dist/canvas.d.ts +9 -0
  53. package/dist/canvas.d.ts.map +1 -0
  54. package/dist/canvas.js +14 -0
  55. package/dist/canvas.js.map +1 -0
  56. package/dist/encode.cjs +2 -0
  57. package/dist/encode.cjs.map +1 -0
  58. package/dist/encode.d.ts +9 -0
  59. package/dist/encode.d.ts.map +1 -0
  60. package/dist/encode.js +112 -0
  61. package/dist/encode.js.map +1 -0
  62. package/dist/errors.cjs +2 -0
  63. package/dist/errors.cjs.map +1 -0
  64. package/dist/errors.d.ts +30 -0
  65. package/dist/errors.d.ts.map +1 -0
  66. package/dist/errors.js +17 -0
  67. package/dist/errors.js.map +1 -0
  68. package/dist/index.cjs +1 -0
  69. package/dist/index.d.ts +7 -0
  70. package/dist/index.d.ts.map +1 -0
  71. package/dist/index.js +6 -0
  72. package/dist/scan.cjs +2 -0
  73. package/dist/scan.cjs.map +1 -0
  74. package/dist/scan.d.ts +12 -0
  75. package/dist/scan.d.ts.map +1 -0
  76. package/dist/scan.js +141 -0
  77. package/dist/scan.js.map +1 -0
  78. package/dist/sigil.cjs +2 -0
  79. package/dist/sigil.cjs.map +1 -0
  80. package/dist/sigil.iife.js +2 -0
  81. package/dist/sigil.iife.js.map +1 -0
  82. package/dist/sigil.js +2 -0
  83. package/dist/sigil.js.map +1 -0
  84. package/dist/svg.cjs +2 -0
  85. package/dist/svg.cjs.map +1 -0
  86. package/dist/svg.d.ts +3 -0
  87. package/dist/svg.d.ts.map +1 -0
  88. package/dist/svg.js +26 -0
  89. package/dist/svg.js.map +1 -0
  90. package/dist/types.d.ts +118 -0
  91. package/dist/types.d.ts.map +1 -0
  92. package/package.json +48 -0
package/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # @vielzeug/sigil
2
+
3
+ > QR code generation and scanning — pure matrix encoder, SVG and canvas renderers, native BarcodeDetector scanning
4
+
5
+ ## Installation
6
+
7
+ ```sh
8
+ pnpm add @vielzeug/sigil
9
+ npm install @vielzeug/sigil
10
+ yarn add @vielzeug/sigil
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ```ts
16
+ import { createQrScanner, encodeQr, toSvg } from '@vielzeug/sigil';
17
+
18
+ // Encode to an inline SVG string — works in Node and the browser.
19
+ const matrix = encodeQr('https://vielzeug.dev');
20
+ document.querySelector('#qr').innerHTML = toSvg(matrix, { label: 'Vielzeug link' });
21
+
22
+ // Scan with the camera (browser only — feature-detect first).
23
+ const scanner = createQrScanner({ video: document.querySelector('video') });
24
+ scanner.onResult(({ value }) => console.log('scanned:', value));
25
+ await scanner.start();
26
+ scanner.dispose();
27
+ ```
28
+
29
+ `toSvg` output uses `currentColor` modules by default — the code themes with ordinary CSS. Scanning requires `BarcodeDetector` and a secure context; call `qrScanSupport()` before showing a scan affordance.
30
+
31
+ ## Documentation
32
+
33
+ - [Overview](https://vielzeug.dev/sigil/)
34
+ - [Usage Guide](https://vielzeug.dev/sigil/usage)
35
+ - [API Reference](https://vielzeug.dev/sigil/api)
36
+ - [Examples](https://vielzeug.dev/sigil/examples)
37
+
38
+ ## License
39
+
40
+ MIT © [Helmuth Saatkamp](https://github.com/helmuthdu) — part of the [Vielzeug](https://github.com/helmuthdu/vielzeug) monorepo.
package/dist/_dev.cjs ADDED
@@ -0,0 +1,2 @@
1
+ function e(e){}exports.warn=e;
2
+ //# sourceMappingURL=_dev.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_dev.cjs","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __SIGIL_PROD__?: boolean }).__SIGIL_PROD__;\n\n/** @internal @security Messages may include user-supplied payload sizes. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/sigil] ${msg}`);\n}\n\n/** @internal — Run fn only in dev builds. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n"],"mappings":"AAGA,SAAgB,EAAK,EAAmB,CAExC"}
package/dist/_dev.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=_dev.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_dev.d.ts","sourceRoot":"","sources":["../src/_dev.ts"],"names":[],"mappings":""}
package/dist/_dev.js ADDED
@@ -0,0 +1,6 @@
1
+ //#region src/_dev.ts
2
+ function e(e) {}
3
+ //#endregion
4
+ export { e as warn };
5
+
6
+ //# sourceMappingURL=_dev.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_dev.js","names":[],"sources":["../src/_dev.ts"],"sourcesContent":["const isDev = !(globalThis as { __SIGIL_PROD__?: boolean }).__SIGIL_PROD__;\n\n/** @internal @security Messages may include user-supplied payload sizes. */\nexport function warn(msg: string): void {\n if (isDev) console.warn(`[@vielzeug/sigil] ${msg}`);\n}\n\n/** @internal — Run fn only in dev builds. */\nexport function devOnly(fn: () => void): void {\n if (isDev) fn();\n}\n"],"mappings":";AAGA,SAAgB,EAAK,GAAmB,CAExC"}
@@ -0,0 +1,2 @@
1
+ const e=require("./_tables.cjs");var t=1335,n=21522,r=7973;function i(r,i){let a=e.FORMAT_EC_BITS[r]<<3|i,o=a;for(let e=0;e<10;e++)o=o<<1^(o>>>9&1)*t;return(a<<10|o&1023)^n}function a(e){let t=e;for(let e=0;e<12;e++)t=t<<1^(t>>>11&1)*r;return e<<12|t&4095}var o=(e,t,n,r)=>{e.modules[n][t]=r,e.isFunction[n][t]=!0};function s(e,t,n){let r=e.size,a=i(t,n),s=e=>(a>>>e&1)==1;for(let t=0;t<=5;t++)o(e,8,t,s(t));o(e,8,7,s(6)),o(e,8,8,s(7)),o(e,7,8,s(8));for(let t=9;t<15;t++)o(e,14-t,8,s(t));for(let t=0;t<8;t++)o(e,r-1-t,8,s(t));for(let t=8;t<15;t++)o(e,8,r-15+t,s(t));o(e,8,r-8,!0)}function c(e,t){if(t<7)return;let n=e.size,r=a(t);for(let t=0;t<18;t++){let i=(r>>>t&1)==1,a=n-11+t%3,s=Math.floor(t/3);o(e,a,s,i),o(e,s,a,i)}}exports.drawFormatInfo=s,exports.drawVersionInfo=c,exports.formatInfoBits=i,exports.versionInfoBits=a;
2
+ //# sourceMappingURL=_format.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_format.cjs","names":[],"sources":["../src/_format.ts"],"sourcesContent":["import type { QrGrid } from './_matrix';\nimport { FORMAT_EC_BITS } from './_tables';\nimport type { QrErrorCorrection } from './types';\n\n/**\n * Format and version information (§7.9, Annexes C–D):\n * - Format: 5 data bits (2 EC + 3 mask) → BCH(15,5) remainder → XOR 0x5412,\n * written twice around the finders.\n * - Version (v≥7): 6 data bits → BCH(18,6) remainder, written twice in the\n * 6×3 blocks at top-right and bottom-left.\n */\n\nconst BCH_FORMAT_POLY = 0b10100110111; // x¹⁰+x⁸+x⁵+x⁴+x²+x+1\nconst BCH_FORMAT_MASK = 0b101010000010010; // 0x5412\nconst BCH_VERSION_POLY = 0b1111100100101; // x¹²+x¹¹+x¹⁰+x⁹+x⁸+x⁵+x²+1\n\n/** 15-bit format information word for (level, mask). */\nexport function formatInfoBits(level: QrErrorCorrection, mask: number): number {\n const data = (FORMAT_EC_BITS[level] << 3) | mask;\n let rem = data;\n for (let i = 0; i < 10; i++) rem = (rem << 1) ^ (((rem >>> 9) & 1) * BCH_FORMAT_POLY);\n return ((data << 10) | (rem & 0x3ff)) ^ BCH_FORMAT_MASK;\n}\n\n/** 18-bit version information word (version ≥ 7). */\nexport function versionInfoBits(version: number): number {\n let rem = version;\n for (let i = 0; i < 12; i++) rem = (rem << 1) ^ (((rem >>> 11) & 1) * BCH_VERSION_POLY);\n return (version << 12) | (rem & 0xfff);\n}\n\nconst setFunction = (grid: QrGrid, x: number, y: number, dark: boolean): void => {\n grid.modules[y][x] = dark;\n grid.isFunction[y][x] = true;\n};\n\n/** Write both copies of the 15-bit format word plus the dark module. */\nexport function drawFormatInfo(grid: QrGrid, level: QrErrorCorrection, mask: number): void {\n const size = grid.size;\n const bits = formatInfoBits(level, mask);\n const bit = (i: number) => ((bits >>> i) & 1) === 1;\n\n // First copy around the top-left finder.\n for (let i = 0; i <= 5; i++) setFunction(grid, 8, i, bit(i));\n setFunction(grid, 8, 7, bit(6));\n setFunction(grid, 8, 8, bit(7));\n setFunction(grid, 7, 8, bit(8));\n for (let i = 9; i < 15; i++) setFunction(grid, 14 - i, 8, bit(i));\n\n // Second copy: row 8 beside the top-right finder (bits 0–7),\n // column 8 beside the bottom-left finder (bits 8–14).\n for (let i = 0; i < 8; i++) setFunction(grid, size - 1 - i, 8, bit(i));\n for (let i = 8; i < 15; i++) setFunction(grid, 8, size - 15 + i, bit(i));\n\n // Always-dark module below the bottom-left strip.\n setFunction(grid, 8, size - 8, true);\n}\n\n/** Write both 6×3 version-information blocks (v≥7). */\nexport function drawVersionInfo(grid: QrGrid, version: number): void {\n if (version < 7) return;\n const size = grid.size;\n const bits = versionInfoBits(version);\n for (let i = 0; i < 18; i++) {\n const dark = ((bits >>> i) & 1) === 1;\n const a = size - 11 + (i % 3);\n const b = Math.floor(i / 3);\n setFunction(grid, a, b, dark); // top-right\n setFunction(grid, b, a, dark); // bottom-left\n }\n}\n"],"mappings":"iCAYA,IAAM,EAAkB,KAClB,EAAkB,MAClB,EAAmB,KAGzB,SAAgB,EAAe,EAA0B,EAAsB,CAC7E,IAAM,EAAQ,EAAA,eAAe,IAAU,EAAK,EACxC,EAAM,EACV,IAAK,IAAI,EAAI,EAAG,EAAI,GAAI,IAAK,EAAO,GAAO,GAAQ,IAAQ,EAAK,GAAK,EACrE,OAAS,GAAQ,GAAO,EAAM,MAAU,CAC1C,CAGA,SAAgB,EAAgB,EAAyB,CACvD,IAAI,EAAM,EACV,IAAK,IAAI,EAAI,EAAG,EAAI,GAAI,IAAK,EAAO,GAAO,GAAQ,IAAQ,GAAM,GAAK,EACtE,OAAQ,GAAW,GAAO,EAAM,IAClC,CAEA,IAAM,GAAe,EAAc,EAAW,EAAW,IAAwB,CAC/E,EAAK,QAAQ,EAAE,CAAC,GAAK,EACrB,EAAK,WAAW,EAAE,CAAC,GAAK,EAC1B,EAGA,SAAgB,EAAe,EAAc,EAA0B,EAAoB,CACzF,IAAM,EAAO,EAAK,KACZ,EAAO,EAAe,EAAO,CAAI,EACjC,EAAO,IAAgB,IAAS,EAAK,IAAO,EAGlD,IAAK,IAAI,EAAI,EAAG,GAAK,EAAG,IAAK,EAAY,EAAM,EAAG,EAAG,EAAI,CAAC,CAAC,EAC3D,EAAY,EAAM,EAAG,EAAG,EAAI,CAAC,CAAC,EAC9B,EAAY,EAAM,EAAG,EAAG,EAAI,CAAC,CAAC,EAC9B,EAAY,EAAM,EAAG,EAAG,EAAI,CAAC,CAAC,EAC9B,IAAK,IAAI,EAAI,EAAG,EAAI,GAAI,IAAK,EAAY,EAAM,GAAK,EAAG,EAAG,EAAI,CAAC,CAAC,EAIhE,IAAK,IAAI,EAAI,EAAG,EAAI,EAAG,IAAK,EAAY,EAAM,EAAO,EAAI,EAAG,EAAG,EAAI,CAAC,CAAC,EACrE,IAAK,IAAI,EAAI,EAAG,EAAI,GAAI,IAAK,EAAY,EAAM,EAAG,EAAO,GAAK,EAAG,EAAI,CAAC,CAAC,EAGvE,EAAY,EAAM,EAAG,EAAO,EAAG,EAAI,CACrC,CAGA,SAAgB,EAAgB,EAAc,EAAuB,CACnE,GAAI,EAAU,EAAG,OACjB,IAAM,EAAO,EAAK,KACZ,EAAO,EAAgB,CAAO,EACpC,IAAK,IAAI,EAAI,EAAG,EAAI,GAAI,IAAK,CAC3B,IAAM,GAAS,IAAS,EAAK,IAAO,EAC9B,EAAI,EAAO,GAAM,EAAI,EACrB,EAAI,KAAK,MAAM,EAAI,CAAC,EAC1B,EAAY,EAAM,EAAG,EAAG,CAAI,EAC5B,EAAY,EAAM,EAAG,EAAG,CAAI,CAC9B,CACF"}
@@ -0,0 +1,11 @@
1
+ import type { QrGrid } from './_matrix';
2
+ import type { QrErrorCorrection } from './types';
3
+ /** 15-bit format information word for (level, mask). */
4
+ export declare function formatInfoBits(level: QrErrorCorrection, mask: number): number;
5
+ /** 18-bit version information word (version ≥ 7). */
6
+ export declare function versionInfoBits(version: number): number;
7
+ /** Write both copies of the 15-bit format word plus the dark module. */
8
+ export declare function drawFormatInfo(grid: QrGrid, level: QrErrorCorrection, mask: number): void;
9
+ /** Write both 6×3 version-information blocks (v≥7). */
10
+ export declare function drawVersionInfo(grid: QrGrid, version: number): void;
11
+ //# sourceMappingURL=_format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_format.d.ts","sourceRoot":"","sources":["../src/_format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAcjD,wDAAwD;AACxD,wBAAgB,cAAc,CAAC,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAK7E;AAED,qDAAqD;AACrD,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIvD;AAOD,wEAAwE;AACxE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAmBzF;AAED,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAWnE"}
@@ -0,0 +1,37 @@
1
+ import { FORMAT_EC_BITS as e } from "./_tables.js";
2
+ //#region src/_format.ts
3
+ var t = 1335, n = 21522, r = 7973;
4
+ function i(r, i) {
5
+ let a = e[r] << 3 | i, o = a;
6
+ for (let e = 0; e < 10; e++) o = o << 1 ^ (o >>> 9 & 1) * t;
7
+ return (a << 10 | o & 1023) ^ n;
8
+ }
9
+ function a(e) {
10
+ let t = e;
11
+ for (let e = 0; e < 12; e++) t = t << 1 ^ (t >>> 11 & 1) * r;
12
+ return e << 12 | t & 4095;
13
+ }
14
+ var o = (e, t, n, r) => {
15
+ e.modules[n][t] = r, e.isFunction[n][t] = !0;
16
+ };
17
+ function s(e, t, n) {
18
+ let r = e.size, a = i(t, n), s = (e) => (a >>> e & 1) == 1;
19
+ for (let t = 0; t <= 5; t++) o(e, 8, t, s(t));
20
+ o(e, 8, 7, s(6)), o(e, 8, 8, s(7)), o(e, 7, 8, s(8));
21
+ for (let t = 9; t < 15; t++) o(e, 14 - t, 8, s(t));
22
+ for (let t = 0; t < 8; t++) o(e, r - 1 - t, 8, s(t));
23
+ for (let t = 8; t < 15; t++) o(e, 8, r - 15 + t, s(t));
24
+ o(e, 8, r - 8, !0);
25
+ }
26
+ function c(e, t) {
27
+ if (t < 7) return;
28
+ let n = e.size, r = a(t);
29
+ for (let t = 0; t < 18; t++) {
30
+ let i = (r >>> t & 1) == 1, a = n - 11 + t % 3, s = Math.floor(t / 3);
31
+ o(e, a, s, i), o(e, s, a, i);
32
+ }
33
+ }
34
+ //#endregion
35
+ export { s as drawFormatInfo, c as drawVersionInfo, i as formatInfoBits, a as versionInfoBits };
36
+
37
+ //# sourceMappingURL=_format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_format.js","names":[],"sources":["../src/_format.ts"],"sourcesContent":["import type { QrGrid } from './_matrix';\nimport { FORMAT_EC_BITS } from './_tables';\nimport type { QrErrorCorrection } from './types';\n\n/**\n * Format and version information (§7.9, Annexes C–D):\n * - Format: 5 data bits (2 EC + 3 mask) → BCH(15,5) remainder → XOR 0x5412,\n * written twice around the finders.\n * - Version (v≥7): 6 data bits → BCH(18,6) remainder, written twice in the\n * 6×3 blocks at top-right and bottom-left.\n */\n\nconst BCH_FORMAT_POLY = 0b10100110111; // x¹⁰+x⁸+x⁵+x⁴+x²+x+1\nconst BCH_FORMAT_MASK = 0b101010000010010; // 0x5412\nconst BCH_VERSION_POLY = 0b1111100100101; // x¹²+x¹¹+x¹⁰+x⁹+x⁸+x⁵+x²+1\n\n/** 15-bit format information word for (level, mask). */\nexport function formatInfoBits(level: QrErrorCorrection, mask: number): number {\n const data = (FORMAT_EC_BITS[level] << 3) | mask;\n let rem = data;\n for (let i = 0; i < 10; i++) rem = (rem << 1) ^ (((rem >>> 9) & 1) * BCH_FORMAT_POLY);\n return ((data << 10) | (rem & 0x3ff)) ^ BCH_FORMAT_MASK;\n}\n\n/** 18-bit version information word (version ≥ 7). */\nexport function versionInfoBits(version: number): number {\n let rem = version;\n for (let i = 0; i < 12; i++) rem = (rem << 1) ^ (((rem >>> 11) & 1) * BCH_VERSION_POLY);\n return (version << 12) | (rem & 0xfff);\n}\n\nconst setFunction = (grid: QrGrid, x: number, y: number, dark: boolean): void => {\n grid.modules[y][x] = dark;\n grid.isFunction[y][x] = true;\n};\n\n/** Write both copies of the 15-bit format word plus the dark module. */\nexport function drawFormatInfo(grid: QrGrid, level: QrErrorCorrection, mask: number): void {\n const size = grid.size;\n const bits = formatInfoBits(level, mask);\n const bit = (i: number) => ((bits >>> i) & 1) === 1;\n\n // First copy around the top-left finder.\n for (let i = 0; i <= 5; i++) setFunction(grid, 8, i, bit(i));\n setFunction(grid, 8, 7, bit(6));\n setFunction(grid, 8, 8, bit(7));\n setFunction(grid, 7, 8, bit(8));\n for (let i = 9; i < 15; i++) setFunction(grid, 14 - i, 8, bit(i));\n\n // Second copy: row 8 beside the top-right finder (bits 0–7),\n // column 8 beside the bottom-left finder (bits 8–14).\n for (let i = 0; i < 8; i++) setFunction(grid, size - 1 - i, 8, bit(i));\n for (let i = 8; i < 15; i++) setFunction(grid, 8, size - 15 + i, bit(i));\n\n // Always-dark module below the bottom-left strip.\n setFunction(grid, 8, size - 8, true);\n}\n\n/** Write both 6×3 version-information blocks (v≥7). */\nexport function drawVersionInfo(grid: QrGrid, version: number): void {\n if (version < 7) return;\n const size = grid.size;\n const bits = versionInfoBits(version);\n for (let i = 0; i < 18; i++) {\n const dark = ((bits >>> i) & 1) === 1;\n const a = size - 11 + (i % 3);\n const b = Math.floor(i / 3);\n setFunction(grid, a, b, dark); // top-right\n setFunction(grid, b, a, dark); // bottom-left\n }\n}\n"],"mappings":";;AAYA,IAAM,IAAkB,MAClB,IAAkB,OAClB,IAAmB;AAGzB,SAAgB,EAAe,GAA0B,GAAsB;CAC7E,IAAM,IAAQ,EAAe,MAAU,IAAK,GACxC,IAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK,IAAO,KAAO,KAAQ,MAAQ,IAAK,KAAK;CACrE,QAAS,KAAQ,KAAO,IAAM,QAAU;AAC1C;AAGA,SAAgB,EAAgB,GAAyB;CACvD,IAAI,IAAM;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK,IAAO,KAAO,KAAQ,MAAQ,KAAM,KAAK;CACtE,OAAQ,KAAW,KAAO,IAAM;AAClC;AAEA,IAAM,KAAe,GAAc,GAAW,GAAW,MAAwB;CAE/E,AADA,EAAK,QAAQ,EAAE,CAAC,KAAK,GACrB,EAAK,WAAW,EAAE,CAAC,KAAK;AAC1B;AAGA,SAAgB,EAAe,GAAc,GAA0B,GAAoB;CACzF,IAAM,IAAO,EAAK,MACZ,IAAO,EAAe,GAAO,CAAI,GACjC,KAAO,OAAgB,MAAS,IAAK,MAAO;CAGlD,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KAAK,EAAY,GAAM,GAAG,GAAG,EAAI,CAAC,CAAC;CAG3D,AAFA,EAAY,GAAM,GAAG,GAAG,EAAI,CAAC,CAAC,GAC9B,EAAY,GAAM,GAAG,GAAG,EAAI,CAAC,CAAC,GAC9B,EAAY,GAAM,GAAG,GAAG,EAAI,CAAC,CAAC;CAC9B,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK,EAAY,GAAM,KAAK,GAAG,GAAG,EAAI,CAAC,CAAC;CAIhE,KAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK,EAAY,GAAM,IAAO,IAAI,GAAG,GAAG,EAAI,CAAC,CAAC;CACrE,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK,EAAY,GAAM,GAAG,IAAO,KAAK,GAAG,EAAI,CAAC,CAAC;CAGvE,EAAY,GAAM,GAAG,IAAO,GAAG,EAAI;AACrC;AAGA,SAAgB,EAAgB,GAAc,GAAuB;CACnE,IAAI,IAAU,GAAG;CACjB,IAAM,IAAO,EAAK,MACZ,IAAO,EAAgB,CAAO;CACpC,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK;EAC3B,IAAM,KAAS,MAAS,IAAK,MAAO,GAC9B,IAAI,IAAO,KAAM,IAAI,GACrB,IAAI,KAAK,MAAM,IAAI,CAAC;EAE1B,AADA,EAAY,GAAM,GAAG,GAAG,CAAI,GAC5B,EAAY,GAAM,GAAG,GAAG,CAAI;CAC9B;AACF"}
@@ -0,0 +1,2 @@
1
+ var e=285,t=new Uint8Array(512),n=new Uint8Array(256);{let r=1;for(let i=0;i<255;i++)t[i]=r,n[r]=i,r<<=1,r&256&&(r^=e);for(let e=255;e<512;e++)t[e]=t[e-255]}function r(e,r){return e===0||r===0?0:t[n[e]+n[r]]}function i(e){return t[e%255]}function a(e,t){let n=Array(e.length+t.length-1).fill(0);for(let i=0;i<e.length;i++)for(let a=0;a<t.length;a++)n[i+a]^=r(e[i],t[a]);return n}exports.gfExp=i,exports.gfMultiply=r,exports.gfPolyMultiply=a;
2
+ //# sourceMappingURL=_galois.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_galois.cjs","names":[],"sources":["../src/_galois.ts"],"sourcesContent":["/**\n * GF(2⁸) arithmetic over the QR primitive polynomial x⁸+x⁴+x³+x²+1 (0x11D).\n * Tables are built once at module load: `EXP[i] = αⁱ` for generator α = 2.\n */\n\nconst PRIMITIVE = 0x11d;\n\nconst EXP = new Uint8Array(512);\nconst LOG = new Uint8Array(256);\n\n{\n let x = 1;\n for (let i = 0; i < 255; i++) {\n EXP[i] = x;\n LOG[x] = i;\n x <<= 1;\n if (x & 0x100) x ^= PRIMITIVE;\n }\n // Duplicate the cycle so `EXP[log(a) + log(b)]` never needs a mod.\n for (let i = 255; i < 512; i++) EXP[i] = EXP[i - 255];\n}\n\n/** `a * b` in GF(256); `0` when either operand is 0. */\nexport function gfMultiply(a: number, b: number): number {\n return a === 0 || b === 0 ? 0 : EXP[LOG[a] + LOG[b]];\n}\n\n/** `αⁱ` — the i-th power of the generator. `i` may exceed 254 (wraps). */\nexport function gfExp(i: number): number {\n return EXP[i % 255];\n}\n\n/** Polynomial evaluation in GF(256): Σ coeffᵢ·xⁱ with coeff[0] highest-degree. */\nexport function gfPolyEval(coeffs: readonly number[], x: number): number {\n let y = 0;\n for (const c of coeffs) y = gfMultiply(y, x) ^ c;\n return y;\n}\n\n/** Multiply two polynomials (coefficients highest-degree first). */\nexport function gfPolyMultiply(p: readonly number[], q: readonly number[]): number[] {\n const out = new Array<number>(p.length + q.length - 1).fill(0);\n for (let i = 0; i < p.length; i++) for (let j = 0; j < q.length; j++) out[i + j] ^= gfMultiply(p[i], q[j]);\n return out;\n}\n"],"mappings":"AAKA,IAAM,EAAY,IAEZ,EAAM,IAAI,WAAW,GAAG,EACxB,EAAM,IAAI,WAAW,GAAG,EAE9B,CACE,IAAI,EAAI,EACR,IAAK,IAAI,EAAI,EAAG,EAAI,IAAK,IACvB,EAAI,GAAK,EACT,EAAI,GAAK,EACT,IAAM,EACF,EAAI,MAAO,GAAK,GAGtB,IAAK,IAAI,EAAI,IAAK,EAAI,IAAK,IAAK,EAAI,GAAK,EAAI,EAAI,IACnD,CAGA,SAAgB,EAAW,EAAW,EAAmB,CACvD,OAAO,IAAM,GAAK,IAAM,EAAI,EAAI,EAAI,EAAI,GAAK,EAAI,GACnD,CAGA,SAAgB,EAAM,EAAmB,CACvC,OAAO,EAAI,EAAI,IACjB,CAUA,SAAgB,EAAe,EAAsB,EAAgC,CACnF,IAAM,EAAU,MAAc,EAAE,OAAS,EAAE,OAAS,CAAC,CAAC,CAAC,KAAK,CAAC,EAC7D,IAAK,IAAI,EAAI,EAAG,EAAI,EAAE,OAAQ,IAAK,IAAK,IAAI,EAAI,EAAG,EAAI,EAAE,OAAQ,IAAK,EAAI,EAAI,IAAM,EAAW,EAAE,GAAI,EAAE,EAAE,EACzG,OAAO,CACT"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * GF(2⁸) arithmetic over the QR primitive polynomial x⁸+x⁴+x³+x²+1 (0x11D).
3
+ * Tables are built once at module load: `EXP[i] = αⁱ` for generator α = 2.
4
+ */
5
+ /** `a * b` in GF(256); `0` when either operand is 0. */
6
+ export declare function gfMultiply(a: number, b: number): number;
7
+ /** `αⁱ` — the i-th power of the generator. `i` may exceed 254 (wraps). */
8
+ export declare function gfExp(i: number): number;
9
+ /** Polynomial evaluation in GF(256): Σ coeffᵢ·xⁱ with coeff[0] highest-degree. */
10
+ export declare function gfPolyEval(coeffs: readonly number[], x: number): number;
11
+ /** Multiply two polynomials (coefficients highest-degree first). */
12
+ export declare function gfPolyMultiply(p: readonly number[], q: readonly number[]): number[];
13
+ //# sourceMappingURL=_galois.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_galois.d.ts","sourceRoot":"","sources":["../src/_galois.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAmBH,wDAAwD;AACxD,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,0EAA0E;AAC1E,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEvC;AAED,kFAAkF;AAClF,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAIvE;AAED,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,CAAC,EAAE,SAAS,MAAM,EAAE,EAAE,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAInF"}
@@ -0,0 +1,22 @@
1
+ //#region src/_galois.ts
2
+ var e = 285, t = /* @__PURE__ */ new Uint8Array(512), n = /* @__PURE__ */ new Uint8Array(256);
3
+ {
4
+ let r = 1;
5
+ for (let i = 0; i < 255; i++) t[i] = r, n[r] = i, r <<= 1, r & 256 && (r ^= e);
6
+ for (let e = 255; e < 512; e++) t[e] = t[e - 255];
7
+ }
8
+ function r(e, r) {
9
+ return e === 0 || r === 0 ? 0 : t[n[e] + n[r]];
10
+ }
11
+ function i(e) {
12
+ return t[e % 255];
13
+ }
14
+ function a(e, t) {
15
+ let n = Array(e.length + t.length - 1).fill(0);
16
+ for (let i = 0; i < e.length; i++) for (let a = 0; a < t.length; a++) n[i + a] ^= r(e[i], t[a]);
17
+ return n;
18
+ }
19
+ //#endregion
20
+ export { i as gfExp, r as gfMultiply, a as gfPolyMultiply };
21
+
22
+ //# sourceMappingURL=_galois.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_galois.js","names":[],"sources":["../src/_galois.ts"],"sourcesContent":["/**\n * GF(2⁸) arithmetic over the QR primitive polynomial x⁸+x⁴+x³+x²+1 (0x11D).\n * Tables are built once at module load: `EXP[i] = αⁱ` for generator α = 2.\n */\n\nconst PRIMITIVE = 0x11d;\n\nconst EXP = new Uint8Array(512);\nconst LOG = new Uint8Array(256);\n\n{\n let x = 1;\n for (let i = 0; i < 255; i++) {\n EXP[i] = x;\n LOG[x] = i;\n x <<= 1;\n if (x & 0x100) x ^= PRIMITIVE;\n }\n // Duplicate the cycle so `EXP[log(a) + log(b)]` never needs a mod.\n for (let i = 255; i < 512; i++) EXP[i] = EXP[i - 255];\n}\n\n/** `a * b` in GF(256); `0` when either operand is 0. */\nexport function gfMultiply(a: number, b: number): number {\n return a === 0 || b === 0 ? 0 : EXP[LOG[a] + LOG[b]];\n}\n\n/** `αⁱ` — the i-th power of the generator. `i` may exceed 254 (wraps). */\nexport function gfExp(i: number): number {\n return EXP[i % 255];\n}\n\n/** Polynomial evaluation in GF(256): Σ coeffᵢ·xⁱ with coeff[0] highest-degree. */\nexport function gfPolyEval(coeffs: readonly number[], x: number): number {\n let y = 0;\n for (const c of coeffs) y = gfMultiply(y, x) ^ c;\n return y;\n}\n\n/** Multiply two polynomials (coefficients highest-degree first). */\nexport function gfPolyMultiply(p: readonly number[], q: readonly number[]): number[] {\n const out = new Array<number>(p.length + q.length - 1).fill(0);\n for (let i = 0; i < p.length; i++) for (let j = 0; j < q.length; j++) out[i + j] ^= gfMultiply(p[i], q[j]);\n return out;\n}\n"],"mappings":";AAKA,IAAM,IAAY,KAEZ,oBAAM,IAAI,WAAW,GAAG,GACxB,oBAAM,IAAI,WAAW,GAAG;AAE9B;CACE,IAAI,IAAI;CACR,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAIvB,AAHA,EAAI,KAAK,GACT,EAAI,KAAK,GACT,MAAM,GACF,IAAI,QAAO,KAAK;CAGtB,KAAK,IAAI,IAAI,KAAK,IAAI,KAAK,KAAK,EAAI,KAAK,EAAI,IAAI;AACnD;AAGA,SAAgB,EAAW,GAAW,GAAmB;CACvD,OAAO,MAAM,KAAK,MAAM,IAAI,IAAI,EAAI,EAAI,KAAK,EAAI;AACnD;AAGA,SAAgB,EAAM,GAAmB;CACvC,OAAO,EAAI,IAAI;AACjB;AAUA,SAAgB,EAAe,GAAsB,GAAgC;CACnF,IAAM,IAAU,MAAc,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;CAC7D,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK,KAAK,IAAI,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK,EAAI,IAAI,MAAM,EAAW,EAAE,IAAI,EAAE,EAAE;CACzG,OAAO;AACT"}
package/dist/_mask.cjs ADDED
@@ -0,0 +1,2 @@
1
+ var e=[(e,t)=>(e+t)%2==0,(e,t)=>t%2==0,e=>e%3==0,(e,t)=>(e+t)%3==0,(e,t)=>(Math.floor(e/3)+Math.floor(t/2))%2==0,(e,t)=>e*t%2+e*t%3==0,(e,t)=>(e*t%2+e*t%3)%2==0,(e,t)=>((e+t)%2+e*t%3)%2==0];function t(t,n){let r=e[n];for(let e=0;e<t.size;e++)for(let n=0;n<t.size;n++)!t.isFunction[e][n]&&r(n,e)&&(t.modules[e][n]=!t.modules[e][n])}var n=3,r=3,i=40,a=10;function o(e){let t=0,r=(e,r)=>(!e&&r>=5&&(t+=n+r-5),e?r+1:1);for(let i=0;i<e.size;i++){let a=1,o=1;for(let t=1;t<e.size;t++)a=r(e.modules[i][t]===e.modules[i][t-1],a),o=r(e.modules[t][i]===e.modules[t-1][i],o);a>=5&&(t+=n+a-5),o>=5&&(t+=n+o-5)}return t}function s(e){let t=0;for(let n=0;n<e.size-1;n++)for(let i=0;i<e.size-1;i++){let a=e.modules[n][i];a===e.modules[n][i+1]&&a===e.modules[n+1][i]&&a===e.modules[n+1][i+1]&&(t+=r)}return t}function c(e){let t=e.size,n=0,r=e=>{for(let r=0;r+11<=t;r++){let t=Array.from({length:11},(t,n)=>e(r+n)),a=[!1,!1,!1,!1,!0,!1,!0,!0,!0,!1,!0],o=[!0,!1,!0,!0,!0,!1,!0,!1,!1,!1,!1];(t.every((e,t)=>e===a[t])||t.every((e,t)=>e===o[t]))&&(n+=i)}};for(let n=0;n<t;n++)r(t=>e.modules[n][t]);for(let n=0;n<t;n++)r(t=>e.modules[t][n]);return n}function l(e){let t=0;for(let n of e.modules)for(let e of n)e&&t++;let n=e.size*e.size;return Math.floor(Math.abs(t*20-n*10)/n)*a}function u(e){return o(e)+s(e)+c(e)+l(e)}exports.MASK_FNS=e,exports.applyMask=t,exports.penaltyScore=u;
2
+ //# sourceMappingURL=_mask.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_mask.cjs","names":[],"sources":["../src/_mask.ts"],"sourcesContent":["import type { QrGrid } from './_matrix';\n\n/**\n * Data masks and penalty scoring (§7.8.2–7.8.3):\n * eight mask functions XORed onto data modules only, then four penalty rules\n * (N1=3 runs, N2=3 blocks, N3=40 finder-like patterns, N4=10 dark ratio).\n */\n\ntype MaskFn = (x: number, y: number) => boolean;\n\nexport const MASK_FNS: readonly MaskFn[] = [\n (x, y) => (x + y) % 2 === 0,\n (_x, y) => y % 2 === 0,\n (x) => x % 3 === 0,\n (x, y) => (x + y) % 3 === 0,\n (x, y) => (Math.floor(x / 3) + Math.floor(y / 2)) % 2 === 0,\n (x, y) => ((x * y) % 2) + ((x * y) % 3) === 0,\n (x, y) => (((x * y) % 2) + ((x * y) % 3)) % 2 === 0,\n (x, y) => (((x + y) % 2) + ((x * y) % 3)) % 2 === 0,\n];\n\n/** XOR mask `m` onto every non-function module. Idempotent per mask. */\nexport function applyMask(grid: QrGrid, mask: number): void {\n const fn = MASK_FNS[mask];\n for (let y = 0; y < grid.size; y++)\n for (let x = 0; x < grid.size; x++)\n if (!grid.isFunction[y][x] && fn(x, y)) grid.modules[y][x] = !grid.modules[y][x];\n}\n\nconst PENALTY_N1 = 3;\nconst PENALTY_N2 = 3;\nconst PENALTY_N3 = 40;\nconst PENALTY_N4 = 10;\n\n// Runs of ≥5 same-color modules in a row or column: N1 + (run − 5).\nfunction penaltyRuns(grid: QrGrid): number {\n let penalty = 0;\n const line = (same: boolean, run: number): number => {\n if (!same && run >= 5) penalty += PENALTY_N1 + run - 5;\n return same ? run + 1 : 1;\n };\n for (let i = 0; i < grid.size; i++) {\n let runRow = 1;\n let runCol = 1;\n for (let j = 1; j < grid.size; j++) {\n runRow = line(grid.modules[i][j] === grid.modules[i][j - 1], runRow);\n runCol = line(grid.modules[j][i] === grid.modules[j - 1][i], runCol);\n }\n if (runRow >= 5) penalty += PENALTY_N1 + runRow - 5;\n if (runCol >= 5) penalty += PENALTY_N1 + runCol - 5;\n }\n return penalty;\n}\n\n// 2×2 blocks of a single color.\nfunction penaltyBlocks(grid: QrGrid): number {\n let penalty = 0;\n for (let y = 0; y < grid.size - 1; y++)\n for (let x = 0; x < grid.size - 1; x++) {\n const c = grid.modules[y][x];\n if (c === grid.modules[y][x + 1] && c === grid.modules[y + 1][x] && c === grid.modules[y + 1][x + 1])\n penalty += PENALTY_N2;\n }\n return penalty;\n}\n\n// 1:1:3:1:1 finder-like patterns with a 4-module light border on either side.\nfunction penaltyFinderLike(grid: QrGrid): number {\n const size = grid.size;\n let penalty = 0;\n const checkLine = (get: (i: number) => boolean): void => {\n for (let i = 0; i + 11 <= size; i++) {\n const window = Array.from({ length: 11 }, (_, k) => get(i + k));\n const coreA = [false, false, false, false, true, false, true, true, true, false, true];\n const coreB = [true, false, true, true, true, false, true, false, false, false, false];\n if (window.every((v, k) => v === coreA[k]) || window.every((v, k) => v === coreB[k])) penalty += PENALTY_N3;\n }\n };\n for (let y = 0; y < size; y++) checkLine((i) => grid.modules[y][i]);\n for (let x = 0; x < size; x++) checkLine((i) => grid.modules[i][x]);\n return penalty;\n}\n\n// Ratio of dark modules: each 5% step away from 50% costs N4.\nfunction penaltyRatio(grid: QrGrid): number {\n let dark = 0;\n for (const row of grid.modules) for (const m of row) if (m) dark++;\n const total = grid.size * grid.size;\n const k = Math.floor(Math.abs(dark * 20 - total * 10) / total);\n return k * PENALTY_N4;\n}\n\n/** Total penalty score for a fully masked matrix. */\nexport function penaltyScore(grid: QrGrid): number {\n return penaltyRuns(grid) + penaltyBlocks(grid) + penaltyFinderLike(grid) + penaltyRatio(grid);\n}\n"],"mappings":"AAUA,IAAa,EAA8B,EACxC,EAAG,KAAO,EAAI,GAAK,GAAM,GACzB,EAAI,IAAM,EAAI,GAAM,EACpB,GAAM,EAAI,GAAM,GAChB,EAAG,KAAO,EAAI,GAAK,GAAM,GACzB,EAAG,KAAO,KAAK,MAAM,EAAI,CAAC,EAAI,KAAK,MAAM,EAAI,CAAC,GAAK,GAAM,GACzD,EAAG,IAAQ,EAAI,EAAK,EAAO,EAAI,EAAK,GAAO,GAC3C,EAAG,KAAS,EAAI,EAAK,EAAO,EAAI,EAAK,GAAM,GAAM,GACjD,EAAG,MAAS,EAAI,GAAK,EAAO,EAAI,EAAK,GAAM,GAAM,CACpD,EAGA,SAAgB,EAAU,EAAc,EAAoB,CAC1D,IAAM,EAAK,EAAS,GACpB,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,KAAM,IAC7B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,KAAM,IACzB,CAAC,EAAK,WAAW,EAAE,CAAC,IAAM,EAAG,EAAG,CAAC,IAAG,EAAK,QAAQ,EAAE,CAAC,GAAK,CAAC,EAAK,QAAQ,EAAE,CAAC,GACpF,CAEA,IAAM,EAAa,EACb,EAAa,EACb,EAAa,GACb,EAAa,GAGnB,SAAS,EAAY,EAAsB,CACzC,IAAI,EAAU,EACR,GAAQ,EAAe,KACvB,CAAC,GAAQ,GAAO,IAAG,GAAW,EAAa,EAAM,GAC9C,EAAO,EAAM,EAAI,GAE1B,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,KAAM,IAAK,CAClC,IAAI,EAAS,EACT,EAAS,EACb,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,KAAM,IAC7B,EAAS,EAAK,EAAK,QAAQ,EAAE,CAAC,KAAO,EAAK,QAAQ,EAAE,CAAC,EAAI,GAAI,CAAM,EACnE,EAAS,EAAK,EAAK,QAAQ,EAAE,CAAC,KAAO,EAAK,QAAQ,EAAI,EAAE,CAAC,GAAI,CAAM,EAEjE,GAAU,IAAG,GAAW,EAAa,EAAS,GAC9C,GAAU,IAAG,GAAW,EAAa,EAAS,EACpD,CACA,OAAO,CACT,CAGA,SAAS,EAAc,EAAsB,CAC3C,IAAI,EAAU,EACd,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,KAAO,EAAG,IACjC,IAAK,IAAI,EAAI,EAAG,EAAI,EAAK,KAAO,EAAG,IAAK,CACtC,IAAM,EAAI,EAAK,QAAQ,EAAE,CAAC,GACtB,IAAM,EAAK,QAAQ,EAAE,CAAC,EAAI,IAAM,IAAM,EAAK,QAAQ,EAAI,EAAE,CAAC,IAAM,IAAM,EAAK,QAAQ,EAAI,EAAE,CAAC,EAAI,KAChG,GAAW,EACf,CACF,OAAO,CACT,CAGA,SAAS,EAAkB,EAAsB,CAC/C,IAAM,EAAO,EAAK,KACd,EAAU,EACR,EAAa,GAAsC,CACvD,IAAK,IAAI,EAAI,EAAG,EAAI,IAAM,EAAM,IAAK,CACnC,IAAM,EAAS,MAAM,KAAK,CAAE,OAAQ,EAAG,GAAI,EAAG,IAAM,EAAI,EAAI,CAAC,CAAC,EACxD,EAAQ,CAAC,GAAO,GAAO,GAAO,GAAO,GAAM,GAAO,GAAM,GAAM,GAAM,GAAO,EAAI,EAC/E,EAAQ,CAAC,GAAM,GAAO,GAAM,GAAM,GAAM,GAAO,GAAM,GAAO,GAAO,GAAO,EAAK,GACjF,EAAO,OAAO,EAAG,IAAM,IAAM,EAAM,EAAE,GAAK,EAAO,OAAO,EAAG,IAAM,IAAM,EAAM,EAAE,KAAG,GAAW,EACnG,CACF,EACA,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,IAAK,EAAW,GAAM,EAAK,QAAQ,EAAE,CAAC,EAAE,EAClE,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,IAAK,EAAW,GAAM,EAAK,QAAQ,EAAE,CAAC,EAAE,EAClE,OAAO,CACT,CAGA,SAAS,EAAa,EAAsB,CAC1C,IAAI,EAAO,EACX,IAAK,IAAM,KAAO,EAAK,QAAS,IAAK,IAAM,KAAK,EAAS,GAAG,IAC5D,IAAM,EAAQ,EAAK,KAAO,EAAK,KAE/B,OADU,KAAK,MAAM,KAAK,IAAI,EAAO,GAAK,EAAQ,EAAE,EAAI,CACjD,EAAI,CACb,CAGA,SAAgB,EAAa,EAAsB,CACjD,OAAO,EAAY,CAAI,EAAI,EAAc,CAAI,EAAI,EAAkB,CAAI,EAAI,EAAa,CAAI,CAC9F"}
@@ -0,0 +1,14 @@
1
+ import type { QrGrid } from './_matrix';
2
+ /**
3
+ * Data masks and penalty scoring (§7.8.2–7.8.3):
4
+ * eight mask functions XORed onto data modules only, then four penalty rules
5
+ * (N1=3 runs, N2=3 blocks, N3=40 finder-like patterns, N4=10 dark ratio).
6
+ */
7
+ type MaskFn = (x: number, y: number) => boolean;
8
+ export declare const MASK_FNS: readonly MaskFn[];
9
+ /** XOR mask `m` onto every non-function module. Idempotent per mask. */
10
+ export declare function applyMask(grid: QrGrid, mask: number): void;
11
+ /** Total penalty score for a fully masked matrix. */
12
+ export declare function penaltyScore(grid: QrGrid): number;
13
+ export {};
14
+ //# sourceMappingURL=_mask.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_mask.d.ts","sourceRoot":"","sources":["../src/_mask.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC;;;;GAIG;AAEH,KAAK,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC;AAEhD,eAAO,MAAM,QAAQ,EAAE,SAAS,MAAM,EASrC,CAAC;AAEF,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAK1D;AAiED,qDAAqD;AACrD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD"}
package/dist/_mask.js ADDED
@@ -0,0 +1,81 @@
1
+ //#region src/_mask.ts
2
+ var e = [
3
+ (e, t) => (e + t) % 2 == 0,
4
+ (e, t) => t % 2 == 0,
5
+ (e) => e % 3 == 0,
6
+ (e, t) => (e + t) % 3 == 0,
7
+ (e, t) => (Math.floor(e / 3) + Math.floor(t / 2)) % 2 == 0,
8
+ (e, t) => e * t % 2 + e * t % 3 == 0,
9
+ (e, t) => (e * t % 2 + e * t % 3) % 2 == 0,
10
+ (e, t) => ((e + t) % 2 + e * t % 3) % 2 == 0
11
+ ];
12
+ function t(t, n) {
13
+ let r = e[n];
14
+ for (let e = 0; e < t.size; e++) for (let n = 0; n < t.size; n++) !t.isFunction[e][n] && r(n, e) && (t.modules[e][n] = !t.modules[e][n]);
15
+ }
16
+ var n = 3, r = 3, i = 40, a = 10;
17
+ function o(e) {
18
+ let t = 0, r = (e, r) => (!e && r >= 5 && (t += n + r - 5), e ? r + 1 : 1);
19
+ for (let i = 0; i < e.size; i++) {
20
+ let a = 1, o = 1;
21
+ for (let t = 1; t < e.size; t++) a = r(e.modules[i][t] === e.modules[i][t - 1], a), o = r(e.modules[t][i] === e.modules[t - 1][i], o);
22
+ a >= 5 && (t += n + a - 5), o >= 5 && (t += n + o - 5);
23
+ }
24
+ return t;
25
+ }
26
+ function s(e) {
27
+ let t = 0;
28
+ for (let n = 0; n < e.size - 1; n++) for (let i = 0; i < e.size - 1; i++) {
29
+ let a = e.modules[n][i];
30
+ a === e.modules[n][i + 1] && a === e.modules[n + 1][i] && a === e.modules[n + 1][i + 1] && (t += r);
31
+ }
32
+ return t;
33
+ }
34
+ function c(e) {
35
+ let t = e.size, n = 0, r = (e) => {
36
+ for (let r = 0; r + 11 <= t; r++) {
37
+ let t = Array.from({ length: 11 }, (t, n) => e(r + n)), a = [
38
+ !1,
39
+ !1,
40
+ !1,
41
+ !1,
42
+ !0,
43
+ !1,
44
+ !0,
45
+ !0,
46
+ !0,
47
+ !1,
48
+ !0
49
+ ], o = [
50
+ !0,
51
+ !1,
52
+ !0,
53
+ !0,
54
+ !0,
55
+ !1,
56
+ !0,
57
+ !1,
58
+ !1,
59
+ !1,
60
+ !1
61
+ ];
62
+ (t.every((e, t) => e === a[t]) || t.every((e, t) => e === o[t])) && (n += i);
63
+ }
64
+ };
65
+ for (let n = 0; n < t; n++) r((t) => e.modules[n][t]);
66
+ for (let n = 0; n < t; n++) r((t) => e.modules[t][n]);
67
+ return n;
68
+ }
69
+ function l(e) {
70
+ let t = 0;
71
+ for (let n of e.modules) for (let e of n) e && t++;
72
+ let n = e.size * e.size;
73
+ return Math.floor(Math.abs(t * 20 - n * 10) / n) * a;
74
+ }
75
+ function u(e) {
76
+ return o(e) + s(e) + c(e) + l(e);
77
+ }
78
+ //#endregion
79
+ export { e as MASK_FNS, t as applyMask, u as penaltyScore };
80
+
81
+ //# sourceMappingURL=_mask.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_mask.js","names":[],"sources":["../src/_mask.ts"],"sourcesContent":["import type { QrGrid } from './_matrix';\n\n/**\n * Data masks and penalty scoring (§7.8.2–7.8.3):\n * eight mask functions XORed onto data modules only, then four penalty rules\n * (N1=3 runs, N2=3 blocks, N3=40 finder-like patterns, N4=10 dark ratio).\n */\n\ntype MaskFn = (x: number, y: number) => boolean;\n\nexport const MASK_FNS: readonly MaskFn[] = [\n (x, y) => (x + y) % 2 === 0,\n (_x, y) => y % 2 === 0,\n (x) => x % 3 === 0,\n (x, y) => (x + y) % 3 === 0,\n (x, y) => (Math.floor(x / 3) + Math.floor(y / 2)) % 2 === 0,\n (x, y) => ((x * y) % 2) + ((x * y) % 3) === 0,\n (x, y) => (((x * y) % 2) + ((x * y) % 3)) % 2 === 0,\n (x, y) => (((x + y) % 2) + ((x * y) % 3)) % 2 === 0,\n];\n\n/** XOR mask `m` onto every non-function module. Idempotent per mask. */\nexport function applyMask(grid: QrGrid, mask: number): void {\n const fn = MASK_FNS[mask];\n for (let y = 0; y < grid.size; y++)\n for (let x = 0; x < grid.size; x++)\n if (!grid.isFunction[y][x] && fn(x, y)) grid.modules[y][x] = !grid.modules[y][x];\n}\n\nconst PENALTY_N1 = 3;\nconst PENALTY_N2 = 3;\nconst PENALTY_N3 = 40;\nconst PENALTY_N4 = 10;\n\n// Runs of ≥5 same-color modules in a row or column: N1 + (run − 5).\nfunction penaltyRuns(grid: QrGrid): number {\n let penalty = 0;\n const line = (same: boolean, run: number): number => {\n if (!same && run >= 5) penalty += PENALTY_N1 + run - 5;\n return same ? run + 1 : 1;\n };\n for (let i = 0; i < grid.size; i++) {\n let runRow = 1;\n let runCol = 1;\n for (let j = 1; j < grid.size; j++) {\n runRow = line(grid.modules[i][j] === grid.modules[i][j - 1], runRow);\n runCol = line(grid.modules[j][i] === grid.modules[j - 1][i], runCol);\n }\n if (runRow >= 5) penalty += PENALTY_N1 + runRow - 5;\n if (runCol >= 5) penalty += PENALTY_N1 + runCol - 5;\n }\n return penalty;\n}\n\n// 2×2 blocks of a single color.\nfunction penaltyBlocks(grid: QrGrid): number {\n let penalty = 0;\n for (let y = 0; y < grid.size - 1; y++)\n for (let x = 0; x < grid.size - 1; x++) {\n const c = grid.modules[y][x];\n if (c === grid.modules[y][x + 1] && c === grid.modules[y + 1][x] && c === grid.modules[y + 1][x + 1])\n penalty += PENALTY_N2;\n }\n return penalty;\n}\n\n// 1:1:3:1:1 finder-like patterns with a 4-module light border on either side.\nfunction penaltyFinderLike(grid: QrGrid): number {\n const size = grid.size;\n let penalty = 0;\n const checkLine = (get: (i: number) => boolean): void => {\n for (let i = 0; i + 11 <= size; i++) {\n const window = Array.from({ length: 11 }, (_, k) => get(i + k));\n const coreA = [false, false, false, false, true, false, true, true, true, false, true];\n const coreB = [true, false, true, true, true, false, true, false, false, false, false];\n if (window.every((v, k) => v === coreA[k]) || window.every((v, k) => v === coreB[k])) penalty += PENALTY_N3;\n }\n };\n for (let y = 0; y < size; y++) checkLine((i) => grid.modules[y][i]);\n for (let x = 0; x < size; x++) checkLine((i) => grid.modules[i][x]);\n return penalty;\n}\n\n// Ratio of dark modules: each 5% step away from 50% costs N4.\nfunction penaltyRatio(grid: QrGrid): number {\n let dark = 0;\n for (const row of grid.modules) for (const m of row) if (m) dark++;\n const total = grid.size * grid.size;\n const k = Math.floor(Math.abs(dark * 20 - total * 10) / total);\n return k * PENALTY_N4;\n}\n\n/** Total penalty score for a fully masked matrix. */\nexport function penaltyScore(grid: QrGrid): number {\n return penaltyRuns(grid) + penaltyBlocks(grid) + penaltyFinderLike(grid) + penaltyRatio(grid);\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ const e=require("./_tables.cjs");function t(e){return{isFunction:Array.from({length:e},()=>Array(e).fill(!1)),modules:Array.from({length:e},()=>Array(e).fill(!1)),size:e}}var n=(e,t,n,r)=>{e.modules[n][t]=r,e.isFunction[n][t]=!0};function r(e,t,r){for(let i=-4;i<=4;i++)for(let a=-4;a<=4;a++){let o=t+3+a,s=r+3+i;if(o<0||s<0||o>=e.size||s>=e.size)continue;let c=Math.max(Math.abs(a),Math.abs(i));n(e,o,s,c!==2&&c!==4)}}function i(e){for(let t=8;t<e.size-8;t++){let r=t%2==0;e.isFunction[6][t]||n(e,t,6,r),e.isFunction[t][6]||n(e,6,t,r)}}function a(e,t,r){for(let i=-2;i<=2;i++)for(let a=-2;a<=2;a++)n(e,t+a,r+i,Math.max(Math.abs(a),Math.abs(i))!==1)}function o(e){let t=e.size;for(let t=0;t<=8;t++)t!==6&&(e.isFunction[8][t]=!0,e.isFunction[t][8]=!0);for(let n=0;n<7;n++)e.isFunction[t-1-n][8]=!0;for(let n=0;n<8;n++)e.isFunction[8][t-1-n]=!0;e.isFunction[t-8][8]=!0}function s(e,t){if(t<7)return;let n=e.size;for(let t=0;t<18;t++){let r=n-11+t%3,i=Math.floor(t/3);e.isFunction[i][r]=!0,e.isFunction[r][i]=!0}}function c(t,n){r(t,0,0),r(t,t.size-7,0),r(t,0,t.size-7),i(t);let c=e.alignmentPatternPositions(n);for(let e of c)for(let n of c)n===6&&e===6||n===6&&e===t.size-7||n===t.size-7&&e===6||a(t,n,e);o(t),s(t,n)}function l(e,t){let n=e.size,r=t.length*8,i=0,a=!0;for(let o=n-1;o>=1;o-=2){o===6&&(o=5);for(let s=0;s<n;s++)for(let c=0;c<2;c++){let l=o-c,u=a?n-1-s:s;e.isFunction[u][l]||(e.modules[u][l]=i<r&&(t[i>>>3]>>>7-(i&7)&1)==1,i++)}a=!a}}exports.createGrid=t,exports.drawFunctionPatterns=c,exports.placeData=l;
2
+ //# sourceMappingURL=_matrix.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_matrix.cjs","names":[],"sources":["../src/_matrix.ts"],"sourcesContent":["import { alignmentPatternPositions } from './_tables';\n\n/**\n * Module placement (§7.7–7.9, Annex E): function patterns are drawn first and\n * recorded in `isFunction`, then the codeword bit stream fills the remaining\n * modules in a two-column zigzag starting bottom-right, skipping column 6.\n */\n\nexport interface QrGrid {\n /** Modules owned by function patterns — skipped by data placement and masks. */\n readonly isFunction: boolean[][];\n /** Final module colors; `true` = dark. Mutable during construction. */\n modules: boolean[][];\n readonly size: number;\n}\n\nexport function createGrid(size: number): QrGrid {\n return {\n isFunction: Array.from({ length: size }, () => new Array<boolean>(size).fill(false)),\n modules: Array.from({ length: size }, () => new Array<boolean>(size).fill(false)),\n size,\n };\n}\n\nconst setFunction = (grid: QrGrid, x: number, y: number, dark: boolean): void => {\n grid.modules[y][x] = dark;\n grid.isFunction[y][x] = true;\n};\n\n/** 7×7 finder pattern plus the one-module separator ring, centered at (x+3, y+3). */\nfunction drawFinder(grid: QrGrid, x: number, y: number): void {\n for (let dy = -4; dy <= 4; dy++)\n for (let dx = -4; dx <= 4; dx++) {\n const xx = x + 3 + dx;\n const yy = y + 3 + dy;\n if (xx < 0 || yy < 0 || xx >= grid.size || yy >= grid.size) continue;\n const dist = Math.max(Math.abs(dx), Math.abs(dy));\n setFunction(grid, xx, yy, dist !== 2 && dist !== 4);\n }\n}\n\n/** Alternating timing pattern along row/col 6, between the finders. */\nfunction drawTiming(grid: QrGrid): void {\n for (let i = 8; i < grid.size - 8; i++) {\n const dark = i % 2 === 0;\n if (!grid.isFunction[6][i]) setFunction(grid, i, 6, dark);\n if (!grid.isFunction[i][6]) setFunction(grid, 6, i, dark);\n }\n}\n\n/** 5×5 alignment pattern centered at (cx, cy). */\nfunction drawAlignment(grid: QrGrid, cx: number, cy: number): void {\n for (let dy = -2; dy <= 2; dy++)\n for (let dx = -2; dx <= 2; dx++) setFunction(grid, cx + dx, cy + dy, Math.max(Math.abs(dx), Math.abs(dy)) !== 1);\n}\n\n/**\n * Reserve the 15 format-info modules around each finder (both copies) and the\n * 6×3 version-info blocks for v≥7 — drawn later by `_format.ts`, but data\n * placement must skip them now.\n */\nfunction reserveFormatAreas(grid: QrGrid): void {\n const size = grid.size;\n // Around the top-left finder.\n for (let i = 0; i <= 8; i++) {\n if (i !== 6) {\n grid.isFunction[8][i] = true;\n grid.isFunction[i][8] = true;\n }\n }\n // Second copy: column 8 rows size-1..size-7 beside the bottom-left finder,\n // row 8 columns size-1..size-8 beside the top-right finder.\n for (let i = 0; i < 7; i++) grid.isFunction[size - 1 - i][8] = true;\n for (let i = 0; i < 8; i++) grid.isFunction[8][size - 1 - i] = true;\n // Always-dark module below the bottom-left format strip.\n grid.isFunction[size - 8][8] = true;\n}\n\nfunction reserveVersionAreas(grid: QrGrid, version: number): void {\n if (version < 7) return;\n const size = grid.size;\n for (let i = 0; i < 18; i++) {\n const a = size - 11 + (i % 3);\n const b = Math.floor(i / 3);\n grid.isFunction[b][a] = true; // top-right block\n grid.isFunction[a][b] = true; // bottom-left block\n }\n}\n\n/** Draw every function pattern and mark reserved areas. */\nexport function drawFunctionPatterns(grid: QrGrid, version: number): void {\n drawFinder(grid, 0, 0);\n drawFinder(grid, grid.size - 7, 0);\n drawFinder(grid, 0, grid.size - 7);\n drawTiming(grid);\n const positions = alignmentPatternPositions(version);\n for (const cy of positions)\n for (const cx of positions) {\n // Skip the three corners covered by finder patterns.\n const isCorner =\n (cx === 6 && cy === 6) || (cx === 6 && cy === grid.size - 7) || (cx === grid.size - 7 && cy === 6);\n if (!isCorner) drawAlignment(grid, cx, cy);\n }\n reserveFormatAreas(grid);\n reserveVersionAreas(grid, version);\n}\n\n/** Place codeword bits into non-function modules via the zigzag scan. */\nexport function placeData(grid: QrGrid, codewords: readonly number[]): void {\n const size = grid.size;\n const totalBits = codewords.length * 8;\n let bitIndex = 0;\n let upward = true;\n for (let right = size - 1; right >= 1; right -= 2) {\n if (right === 6) right = 5; // skip the vertical timing column\n for (let vert = 0; vert < size; vert++) {\n for (let j = 0; j < 2; j++) {\n const x = right - j;\n const y = upward ? size - 1 - vert : vert;\n if (grid.isFunction[y][x]) continue;\n grid.modules[y][x] = bitIndex < totalBits && ((codewords[bitIndex >>> 3] >>> (7 - (bitIndex & 7))) & 1) === 1;\n bitIndex++;\n }\n }\n upward = !upward;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Module placement (§7.7–7.9, Annex E): function patterns are drawn first and
3
+ * recorded in `isFunction`, then the codeword bit stream fills the remaining
4
+ * modules in a two-column zigzag starting bottom-right, skipping column 6.
5
+ */
6
+ export interface QrGrid {
7
+ /** Modules owned by function patterns — skipped by data placement and masks. */
8
+ readonly isFunction: boolean[][];
9
+ /** Final module colors; `true` = dark. Mutable during construction. */
10
+ modules: boolean[][];
11
+ readonly size: number;
12
+ }
13
+ export declare function createGrid(size: number): QrGrid;
14
+ /** Draw every function pattern and mark reserved areas. */
15
+ export declare function drawFunctionPatterns(grid: QrGrid, version: number): void;
16
+ /** Place codeword bits into non-function modules via the zigzag scan. */
17
+ export declare function placeData(grid: QrGrid, codewords: readonly number[]): void;
18
+ //# sourceMappingURL=_matrix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_matrix.d.ts","sourceRoot":"","sources":["../src/_matrix.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,MAAM,WAAW,MAAM;IACrB,gFAAgF;IAChF,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;IACjC,uEAAuE;IACvE,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM/C;AAmED,2DAA2D;AAC3D,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAexE;AAED,yEAAyE;AACzE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAkB1E"}
@@ -0,0 +1,65 @@
1
+ import { alignmentPatternPositions as e } from "./_tables.js";
2
+ //#region src/_matrix.ts
3
+ function t(e) {
4
+ return {
5
+ isFunction: Array.from({ length: e }, () => Array(e).fill(!1)),
6
+ modules: Array.from({ length: e }, () => Array(e).fill(!1)),
7
+ size: e
8
+ };
9
+ }
10
+ var n = (e, t, n, r) => {
11
+ e.modules[n][t] = r, e.isFunction[n][t] = !0;
12
+ };
13
+ function r(e, t, r) {
14
+ for (let i = -4; i <= 4; i++) for (let a = -4; a <= 4; a++) {
15
+ let o = t + 3 + a, s = r + 3 + i;
16
+ if (o < 0 || s < 0 || o >= e.size || s >= e.size) continue;
17
+ let c = Math.max(Math.abs(a), Math.abs(i));
18
+ n(e, o, s, c !== 2 && c !== 4);
19
+ }
20
+ }
21
+ function i(e) {
22
+ for (let t = 8; t < e.size - 8; t++) {
23
+ let r = t % 2 == 0;
24
+ e.isFunction[6][t] || n(e, t, 6, r), e.isFunction[t][6] || n(e, 6, t, r);
25
+ }
26
+ }
27
+ function a(e, t, r) {
28
+ for (let i = -2; i <= 2; i++) for (let a = -2; a <= 2; a++) n(e, t + a, r + i, Math.max(Math.abs(a), Math.abs(i)) !== 1);
29
+ }
30
+ function o(e) {
31
+ let t = e.size;
32
+ for (let t = 0; t <= 8; t++) t !== 6 && (e.isFunction[8][t] = !0, e.isFunction[t][8] = !0);
33
+ for (let n = 0; n < 7; n++) e.isFunction[t - 1 - n][8] = !0;
34
+ for (let n = 0; n < 8; n++) e.isFunction[8][t - 1 - n] = !0;
35
+ e.isFunction[t - 8][8] = !0;
36
+ }
37
+ function s(e, t) {
38
+ if (t < 7) return;
39
+ let n = e.size;
40
+ for (let t = 0; t < 18; t++) {
41
+ let r = n - 11 + t % 3, i = Math.floor(t / 3);
42
+ e.isFunction[i][r] = !0, e.isFunction[r][i] = !0;
43
+ }
44
+ }
45
+ function c(t, n) {
46
+ r(t, 0, 0), r(t, t.size - 7, 0), r(t, 0, t.size - 7), i(t);
47
+ let c = e(n);
48
+ for (let e of c) for (let n of c) n === 6 && e === 6 || n === 6 && e === t.size - 7 || n === t.size - 7 && e === 6 || a(t, n, e);
49
+ o(t), s(t, n);
50
+ }
51
+ function l(e, t) {
52
+ let n = e.size, r = t.length * 8, i = 0, a = !0;
53
+ for (let o = n - 1; o >= 1; o -= 2) {
54
+ o === 6 && (o = 5);
55
+ for (let s = 0; s < n; s++) for (let c = 0; c < 2; c++) {
56
+ let l = o - c, u = a ? n - 1 - s : s;
57
+ e.isFunction[u][l] || (e.modules[u][l] = i < r && (t[i >>> 3] >>> 7 - (i & 7) & 1) == 1, i++);
58
+ }
59
+ a = !a;
60
+ }
61
+ }
62
+ //#endregion
63
+ export { t as createGrid, c as drawFunctionPatterns, l as placeData };
64
+
65
+ //# sourceMappingURL=_matrix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_matrix.js","names":[],"sources":["../src/_matrix.ts"],"sourcesContent":["import { alignmentPatternPositions } from './_tables';\n\n/**\n * Module placement (§7.7–7.9, Annex E): function patterns are drawn first and\n * recorded in `isFunction`, then the codeword bit stream fills the remaining\n * modules in a two-column zigzag starting bottom-right, skipping column 6.\n */\n\nexport interface QrGrid {\n /** Modules owned by function patterns — skipped by data placement and masks. */\n readonly isFunction: boolean[][];\n /** Final module colors; `true` = dark. Mutable during construction. */\n modules: boolean[][];\n readonly size: number;\n}\n\nexport function createGrid(size: number): QrGrid {\n return {\n isFunction: Array.from({ length: size }, () => new Array<boolean>(size).fill(false)),\n modules: Array.from({ length: size }, () => new Array<boolean>(size).fill(false)),\n size,\n };\n}\n\nconst setFunction = (grid: QrGrid, x: number, y: number, dark: boolean): void => {\n grid.modules[y][x] = dark;\n grid.isFunction[y][x] = true;\n};\n\n/** 7×7 finder pattern plus the one-module separator ring, centered at (x+3, y+3). */\nfunction drawFinder(grid: QrGrid, x: number, y: number): void {\n for (let dy = -4; dy <= 4; dy++)\n for (let dx = -4; dx <= 4; dx++) {\n const xx = x + 3 + dx;\n const yy = y + 3 + dy;\n if (xx < 0 || yy < 0 || xx >= grid.size || yy >= grid.size) continue;\n const dist = Math.max(Math.abs(dx), Math.abs(dy));\n setFunction(grid, xx, yy, dist !== 2 && dist !== 4);\n }\n}\n\n/** Alternating timing pattern along row/col 6, between the finders. */\nfunction drawTiming(grid: QrGrid): void {\n for (let i = 8; i < grid.size - 8; i++) {\n const dark = i % 2 === 0;\n if (!grid.isFunction[6][i]) setFunction(grid, i, 6, dark);\n if (!grid.isFunction[i][6]) setFunction(grid, 6, i, dark);\n }\n}\n\n/** 5×5 alignment pattern centered at (cx, cy). */\nfunction drawAlignment(grid: QrGrid, cx: number, cy: number): void {\n for (let dy = -2; dy <= 2; dy++)\n for (let dx = -2; dx <= 2; dx++) setFunction(grid, cx + dx, cy + dy, Math.max(Math.abs(dx), Math.abs(dy)) !== 1);\n}\n\n/**\n * Reserve the 15 format-info modules around each finder (both copies) and the\n * 6×3 version-info blocks for v≥7 — drawn later by `_format.ts`, but data\n * placement must skip them now.\n */\nfunction reserveFormatAreas(grid: QrGrid): void {\n const size = grid.size;\n // Around the top-left finder.\n for (let i = 0; i <= 8; i++) {\n if (i !== 6) {\n grid.isFunction[8][i] = true;\n grid.isFunction[i][8] = true;\n }\n }\n // Second copy: column 8 rows size-1..size-7 beside the bottom-left finder,\n // row 8 columns size-1..size-8 beside the top-right finder.\n for (let i = 0; i < 7; i++) grid.isFunction[size - 1 - i][8] = true;\n for (let i = 0; i < 8; i++) grid.isFunction[8][size - 1 - i] = true;\n // Always-dark module below the bottom-left format strip.\n grid.isFunction[size - 8][8] = true;\n}\n\nfunction reserveVersionAreas(grid: QrGrid, version: number): void {\n if (version < 7) return;\n const size = grid.size;\n for (let i = 0; i < 18; i++) {\n const a = size - 11 + (i % 3);\n const b = Math.floor(i / 3);\n grid.isFunction[b][a] = true; // top-right block\n grid.isFunction[a][b] = true; // bottom-left block\n }\n}\n\n/** Draw every function pattern and mark reserved areas. */\nexport function drawFunctionPatterns(grid: QrGrid, version: number): void {\n drawFinder(grid, 0, 0);\n drawFinder(grid, grid.size - 7, 0);\n drawFinder(grid, 0, grid.size - 7);\n drawTiming(grid);\n const positions = alignmentPatternPositions(version);\n for (const cy of positions)\n for (const cx of positions) {\n // Skip the three corners covered by finder patterns.\n const isCorner =\n (cx === 6 && cy === 6) || (cx === 6 && cy === grid.size - 7) || (cx === grid.size - 7 && cy === 6);\n if (!isCorner) drawAlignment(grid, cx, cy);\n }\n reserveFormatAreas(grid);\n reserveVersionAreas(grid, version);\n}\n\n/** Place codeword bits into non-function modules via the zigzag scan. */\nexport function placeData(grid: QrGrid, codewords: readonly number[]): void {\n const size = grid.size;\n const totalBits = codewords.length * 8;\n let bitIndex = 0;\n let upward = true;\n for (let right = size - 1; right >= 1; right -= 2) {\n if (right === 6) right = 5; // skip the vertical timing column\n for (let vert = 0; vert < size; vert++) {\n for (let j = 0; j < 2; j++) {\n const x = right - j;\n const y = upward ? size - 1 - vert : vert;\n if (grid.isFunction[y][x]) continue;\n grid.modules[y][x] = bitIndex < totalBits && ((codewords[bitIndex >>> 3] >>> (7 - (bitIndex & 7))) & 1) === 1;\n bitIndex++;\n }\n }\n upward = !upward;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ const e=require("./_galois.cjs");var t=new Map;function n(n){let r=t.get(n);if(r)return r;let i=[1];for(let t=0;t<n;t++)i=e.gfPolyMultiply(i,[1,e.gfExp(t)]);return t.set(n,i),i}function r(t,r){let i=n(r),a=Array(r).fill(0);for(let n of t){let t=n^a[0];if(a.copyWithin(0,1),a[r-1]=0,t!==0)for(let n=0;n<r;n++)a[n]^=e.gfMultiply(i[n+1],t)}return a}exports.ecCodewords=r;
2
+ //# sourceMappingURL=_reed-solomon.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_reed-solomon.cjs","names":[],"sources":["../src/_reed-solomon.ts"],"sourcesContent":["import { gfExp, gfMultiply, gfPolyMultiply } from './_galois';\n\n/**\n * Reed–Solomon error-correction codewords over GF(256).\n * The generator polynomial for `degree` EC codewords is ∏ᵢ₌₀..degree₋₁ (x − αⁱ);\n * results are cached per degree (max 30 per ISO Table 9).\n */\n\nconst generatorCache = new Map<number, readonly number[]>();\n\n/** Generator polynomial coefficients (highest-degree first, leading 1 kept). */\nfunction generatorPoly(degree: number): readonly number[] {\n const poly = generatorCache.get(degree);\n if (poly) return poly;\n let g = [1];\n for (let i = 0; i < degree; i++) g = gfPolyMultiply(g, [1, gfExp(i)]);\n generatorCache.set(degree, g);\n return g;\n}\n\n/** EC codewords for one data block: remainder of data·x^degree ÷ generator. */\nexport function ecCodewords(data: readonly number[], degree: number): number[] {\n const gen = generatorPoly(degree); // gen[0] === 1\n const rem = new Array<number>(degree).fill(0);\n for (const b of data) {\n const factor = b ^ rem[0];\n rem.copyWithin(0, 1);\n rem[degree - 1] = 0;\n if (factor !== 0) for (let j = 0; j < degree; j++) rem[j] ^= gfMultiply(gen[j + 1], factor);\n }\n return rem;\n}\n"],"mappings":"iCAQA,IAAM,EAAiB,IAAI,IAG3B,SAAS,EAAc,EAAmC,CACxD,IAAM,EAAO,EAAe,IAAI,CAAM,EACtC,GAAI,EAAM,OAAO,EACjB,IAAI,EAAI,CAAC,CAAC,EACV,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,IAAK,EAAI,EAAA,eAAe,EAAG,CAAC,EAAG,EAAA,MAAM,CAAC,CAAC,CAAC,EAEpE,OADA,EAAe,IAAI,EAAQ,CAAC,EACrB,CACT,CAGA,SAAgB,EAAY,EAAyB,EAA0B,CAC7E,IAAM,EAAM,EAAc,CAAM,EAC1B,EAAU,MAAc,CAAM,CAAC,CAAC,KAAK,CAAC,EAC5C,IAAK,IAAM,KAAK,EAAM,CACpB,IAAM,EAAS,EAAI,EAAI,GAGvB,GAFA,EAAI,WAAW,EAAG,CAAC,EACnB,EAAI,EAAS,GAAK,EACd,IAAW,EAAG,IAAK,IAAI,EAAI,EAAG,EAAI,EAAQ,IAAK,EAAI,IAAM,EAAA,WAAW,EAAI,EAAI,GAAI,CAAM,CAC5F,CACA,OAAO,CACT"}
@@ -0,0 +1,3 @@
1
+ /** EC codewords for one data block: remainder of data·x^degree ÷ generator. */
2
+ export declare function ecCodewords(data: readonly number[], degree: number): number[];
3
+ //# sourceMappingURL=_reed-solomon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_reed-solomon.d.ts","sourceRoot":"","sources":["../src/_reed-solomon.ts"],"names":[],"mappings":"AAoBA,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAU7E"}
@@ -0,0 +1,22 @@
1
+ import { gfExp as e, gfMultiply as t, gfPolyMultiply as n } from "./_galois.js";
2
+ //#region src/_reed-solomon.ts
3
+ var r = /* @__PURE__ */ new Map();
4
+ function i(t) {
5
+ let i = r.get(t);
6
+ if (i) return i;
7
+ let a = [1];
8
+ for (let r = 0; r < t; r++) a = n(a, [1, e(r)]);
9
+ return r.set(t, a), a;
10
+ }
11
+ function a(e, n) {
12
+ let r = i(n), a = Array(n).fill(0);
13
+ for (let i of e) {
14
+ let e = i ^ a[0];
15
+ if (a.copyWithin(0, 1), a[n - 1] = 0, e !== 0) for (let i = 0; i < n; i++) a[i] ^= t(r[i + 1], e);
16
+ }
17
+ return a;
18
+ }
19
+ //#endregion
20
+ export { a as ecCodewords };
21
+
22
+ //# sourceMappingURL=_reed-solomon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_reed-solomon.js","names":[],"sources":["../src/_reed-solomon.ts"],"sourcesContent":["import { gfExp, gfMultiply, gfPolyMultiply } from './_galois';\n\n/**\n * Reed–Solomon error-correction codewords over GF(256).\n * The generator polynomial for `degree` EC codewords is ∏ᵢ₌₀..degree₋₁ (x − αⁱ);\n * results are cached per degree (max 30 per ISO Table 9).\n */\n\nconst generatorCache = new Map<number, readonly number[]>();\n\n/** Generator polynomial coefficients (highest-degree first, leading 1 kept). */\nfunction generatorPoly(degree: number): readonly number[] {\n const poly = generatorCache.get(degree);\n if (poly) return poly;\n let g = [1];\n for (let i = 0; i < degree; i++) g = gfPolyMultiply(g, [1, gfExp(i)]);\n generatorCache.set(degree, g);\n return g;\n}\n\n/** EC codewords for one data block: remainder of data·x^degree ÷ generator. */\nexport function ecCodewords(data: readonly number[], degree: number): number[] {\n const gen = generatorPoly(degree); // gen[0] === 1\n const rem = new Array<number>(degree).fill(0);\n for (const b of data) {\n const factor = b ^ rem[0];\n rem.copyWithin(0, 1);\n rem[degree - 1] = 0;\n if (factor !== 0) for (let j = 0; j < degree; j++) rem[j] ^= gfMultiply(gen[j + 1], factor);\n }\n return rem;\n}\n"],"mappings":";;AAQA,IAAM,oBAAiB,IAAI,IAA+B;AAG1D,SAAS,EAAc,GAAmC;CACxD,IAAM,IAAO,EAAe,IAAI,CAAM;CACtC,IAAI,GAAM,OAAO;CACjB,IAAI,IAAI,CAAC,CAAC;CACV,KAAK,IAAI,IAAI,GAAG,IAAI,GAAQ,KAAK,IAAI,EAAe,GAAG,CAAC,GAAG,EAAM,CAAC,CAAC,CAAC;CAEpE,OADA,EAAe,IAAI,GAAQ,CAAC,GACrB;AACT;AAGA,SAAgB,EAAY,GAAyB,GAA0B;CAC7E,IAAM,IAAM,EAAc,CAAM,GAC1B,IAAU,MAAc,CAAM,CAAC,CAAC,KAAK,CAAC;CAC5C,KAAK,IAAM,KAAK,GAAM;EACpB,IAAM,IAAS,IAAI,EAAI;EAGvB,IAFA,EAAI,WAAW,GAAG,CAAC,GACnB,EAAI,IAAS,KAAK,GACd,MAAW,GAAG,KAAK,IAAI,IAAI,GAAG,IAAI,GAAQ,KAAK,EAAI,MAAM,EAAW,EAAI,IAAI,IAAI,CAAM;CAC5F;CACA,OAAO;AACT"}
@@ -0,0 +1,2 @@
1
+ const e=require("./_tables.cjs");var t=class{bits=[];get length(){return this.bits.length}append(e,t){for(let n=t-1;n>=0;n--)this.bits.push(e>>>n&1)}padToByte(){for(;this.bits.length%8!=0;)this.bits.push(0)}toBytes(){let e=[];for(let t=0;t<this.bits.length;t+=8){let n=0;for(let e=0;e<8;e++)n=n<<1|this.bits[t+e];e.push(n)}return e}};function n(e){if(/^\d+$/.test(e))return`numeric`;for(let t of e)if(!`0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:`.includes(t))return`byte`;return`alphanumeric`}var r=new TextEncoder;function i(e,t){switch(t){case`numeric`:return Math.floor(e.length/3)*10+(e.length%3==1?4:e.length%3==2?7:0);case`alphanumeric`:return Math.floor(e.length/2)*11+e.length%2*6;case`byte`:return r.encode(e).length*8}}function a(t,n,i,a){switch(t.append(e.MODE_BITS[i],4),t.append(o(n,i),e.CHAR_COUNT_BITS[i][e.versionGroup(a)]),i){case`numeric`:for(let e=0;e<n.length;){let r=Math.min(3,n.length-e);t.append(Number.parseInt(n.slice(e,e+r),10),r===3?10:r===2?7:4),e+=r}break;case`alphanumeric`:for(let r=0;r<n.length;)r+1<n.length?(t.append(e.ALPHANUMERIC_CHARSET.indexOf(n[r])*45+e.ALPHANUMERIC_CHARSET.indexOf(n[r+1]),11),r+=2):(t.append(e.ALPHANUMERIC_CHARSET.indexOf(n[r]),6),r+=1);break;case`byte`:for(let e of r.encode(n))t.append(e,8)}}function o(e,t){return t===`byte`?r.encode(e).length:e.length}var s=(t,n)=>e.dataCodewords(t,n)*8;function c(t,n,r){return 4+e.CHAR_COUNT_BITS[n][e.versionGroup(r)]+i(t,n)}function l(n,r,i,o){let c=new t;a(c,n,r,i);let l=s(i,o);c.append(0,Math.min(4,l-c.length)),c.padToByte();let u=c.toBytes(),d=[236,17];for(let t=0;u.length<e.dataCodewords(i,o);t++)u.push(d[t%2]);return u}exports.BitStream=t,exports.appendSegment=a,exports.buildDataCodewords=l,exports.charCount=o,exports.dataBitLength=i,exports.dataCapacityBits=s,exports.detectMode=n,exports.segmentBits=c;
2
+ //# sourceMappingURL=_segments.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_segments.cjs","names":[],"sources":["../src/_segments.ts"],"sourcesContent":["import { ALPHANUMERIC_CHARSET, CHAR_COUNT_BITS, dataCodewords, MODE_BITS, versionGroup } from './_tables';\nimport type { QrErrorCorrection, QrMode } from './types';\n\n/**\n * Data-segment assembly: one segment (single mode) covering the whole input,\n * followed by terminator, byte alignment, and 0xEC/0x11 padding (§7.4–7.5).\n * Kanji and multi-segment optimization are out of scope.\n */\n\n/** Growable bit stream; `bytes` is valid only after `padToByte()`. */\nexport class BitStream {\n private bits: number[] = [];\n\n get length(): number {\n return this.bits.length;\n }\n\n append(value: number, width: number): void {\n for (let i = width - 1; i >= 0; i--) this.bits.push((value >>> i) & 1);\n }\n\n padToByte(): void {\n while (this.bits.length % 8 !== 0) this.bits.push(0);\n }\n\n toBytes(): number[] {\n const out: number[] = [];\n for (let i = 0; i < this.bits.length; i += 8) {\n let b = 0;\n for (let j = 0; j < 8; j++) b = (b << 1) | this.bits[i + j];\n out.push(b);\n }\n return out;\n }\n}\n\n/** Most compact mode able to encode the whole input. */\nexport function detectMode(data: string): QrMode {\n if (/^\\d+$/.test(data)) return 'numeric';\n for (const ch of data) if (!ALPHANUMERIC_CHARSET.includes(ch)) return 'byte';\n return 'alphanumeric';\n}\n\nconst textEncoder = new TextEncoder();\n\n/** Payload bits for the segment body (without mode/count headers). */\nexport function dataBitLength(data: string, mode: QrMode): number {\n switch (mode) {\n case 'numeric':\n return Math.floor(data.length / 3) * 10 + (data.length % 3 === 1 ? 4 : data.length % 3 === 2 ? 7 : 0);\n case 'alphanumeric':\n return Math.floor(data.length / 2) * 11 + (data.length % 2) * 6;\n case 'byte':\n return textEncoder.encode(data).length * 8;\n }\n}\n\n/** Append mode indicator, char count, and payload bits. */\nexport function appendSegment(stream: BitStream, data: string, mode: QrMode, version: number): void {\n stream.append(MODE_BITS[mode], 4);\n stream.append(charCount(data, mode), CHAR_COUNT_BITS[mode][versionGroup(version)]);\n switch (mode) {\n case 'numeric':\n for (let i = 0; i < data.length; ) {\n const n = Math.min(3, data.length - i);\n stream.append(Number.parseInt(data.slice(i, i + n), 10), n === 3 ? 10 : n === 2 ? 7 : 4);\n i += n;\n }\n break;\n case 'alphanumeric':\n for (let i = 0; i < data.length; ) {\n if (i + 1 < data.length) {\n stream.append(ALPHANUMERIC_CHARSET.indexOf(data[i]) * 45 + ALPHANUMERIC_CHARSET.indexOf(data[i + 1]), 11);\n i += 2;\n } else {\n stream.append(ALPHANUMERIC_CHARSET.indexOf(data[i]), 6);\n i += 1;\n }\n }\n break;\n case 'byte':\n for (const b of textEncoder.encode(data)) stream.append(b, 8);\n break;\n }\n}\n\n/** Chars/bytes reported in the count field. Byte mode counts encoded bytes. */\nexport function charCount(data: string, mode: QrMode): number {\n return mode === 'byte' ? textEncoder.encode(data).length : data.length;\n}\n\n/** Capacity in bits for the data area of (version, level). */\nexport const dataCapacityBits = (version: number, level: QrErrorCorrection): number =>\n dataCodewords(version, level) * 8;\n\n/** Bits a segment occupies at `version`: header + payload, before terminator. */\nexport function segmentBits(data: string, mode: QrMode, version: number): number {\n return 4 + CHAR_COUNT_BITS[mode][versionGroup(version)] + dataBitLength(data, mode);\n}\n\n/**\n * Full data-codeword sequence for (version, level): segment + terminator +\n * alignment + pad bytes. Caller guarantees the segment fits.\n */\nexport function buildDataCodewords(data: string, mode: QrMode, version: number, level: QrErrorCorrection): number[] {\n const stream = new BitStream();\n appendSegment(stream, data, mode, version);\n const capacity = dataCapacityBits(version, level);\n stream.append(0, Math.min(4, capacity - stream.length)); // terminator\n stream.padToByte();\n const bytes = stream.toBytes();\n const pad = [0xec, 0x11];\n for (let i = 0; bytes.length < dataCodewords(version, level); i++) bytes.push(pad[i % 2]);\n return bytes;\n}\n"],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { QrErrorCorrection, QrMode } from './types';
2
+ /**
3
+ * Data-segment assembly: one segment (single mode) covering the whole input,
4
+ * followed by terminator, byte alignment, and 0xEC/0x11 padding (§7.4–7.5).
5
+ * Kanji and multi-segment optimization are out of scope.
6
+ */
7
+ /** Growable bit stream; `bytes` is valid only after `padToByte()`. */
8
+ export declare class BitStream {
9
+ private bits;
10
+ get length(): number;
11
+ append(value: number, width: number): void;
12
+ padToByte(): void;
13
+ toBytes(): number[];
14
+ }
15
+ /** Most compact mode able to encode the whole input. */
16
+ export declare function detectMode(data: string): QrMode;
17
+ /** Payload bits for the segment body (without mode/count headers). */
18
+ export declare function dataBitLength(data: string, mode: QrMode): number;
19
+ /** Append mode indicator, char count, and payload bits. */
20
+ export declare function appendSegment(stream: BitStream, data: string, mode: QrMode, version: number): void;
21
+ /** Chars/bytes reported in the count field. Byte mode counts encoded bytes. */
22
+ export declare function charCount(data: string, mode: QrMode): number;
23
+ /** Capacity in bits for the data area of (version, level). */
24
+ export declare const dataCapacityBits: (version: number, level: QrErrorCorrection) => number;
25
+ /** Bits a segment occupies at `version`: header + payload, before terminator. */
26
+ export declare function segmentBits(data: string, mode: QrMode, version: number): number;
27
+ /**
28
+ * Full data-codeword sequence for (version, level): segment + terminator +
29
+ * alignment + pad bytes. Caller guarantees the segment fits.
30
+ */
31
+ export declare function buildDataCodewords(data: string, mode: QrMode, version: number, level: QrErrorCorrection): number[];
32
+ //# sourceMappingURL=_segments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_segments.d.ts","sourceRoot":"","sources":["../src/_segments.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEzD;;;;GAIG;AAEH,sEAAsE;AACtE,qBAAa,SAAS;IACpB,OAAO,CAAC,IAAI,CAAgB;IAE5B,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAI1C,SAAS,IAAI,IAAI;IAIjB,OAAO,IAAI,MAAM,EAAE;CASpB;AAED,wDAAwD;AACxD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI/C;AAID,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAShE;AAED,2DAA2D;AAC3D,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CA0BlG;AAED,+EAA+E;AAC/E,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,8DAA8D;AAC9D,eAAO,MAAM,gBAAgB,GAAI,SAAS,MAAM,EAAE,OAAO,iBAAiB,KAAG,MAC1C,CAAC;AAEpC,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE/E;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,GAAG,MAAM,EAAE,CAUlH"}