{"spec_id":"barcode-ean13","library":"muix","language":"javascript","code":"// anyplot.ai\n// barcode-ean13: EAN-13 Barcode\n// Library: muix 7.29.1 | JavaScript 22.23.2\n// Quality: 87/100 | Created: 2026-09-01\nimport { BarChart } from \"@mui/x-charts/BarChart\";\nimport { Box, Typography } from \"@mui/material\";\n\nconst t = window.ANYPLOT_TOKENS;\nconst SIZE = window.ANYPLOT_SIZE;\n\n// --- EAN-13 encoding tables --------------------------------------------------\n// L-code is canonical; the right-hand R-code is its bitwise complement, and the\n// even-parity G-code is the reverse of R (standard EAN-13/UPC-A relationships).\nconst L_CODE = [\n  \"0001101\", \"0011001\", \"0010011\", \"0111101\", \"0100011\",\n  \"0110001\", \"0101111\", \"0111011\", \"0110111\", \"0001011\",\n];\nconst PARITY = [\n  \"LLLLLL\", \"LLGLGG\", \"LLGGLG\", \"LLGGGL\", \"LGLLGG\",\n  \"LGGLLG\", \"LGGGLL\", \"LGLGLG\", \"LGLGGL\", \"LGGLGL\",\n];\nconst complement = (bits) => bits.split(\"\").map((b) => (b === \"1\" ? \"0\" : \"1\")).join(\"\");\nconst reverse = (bits) => bits.split(\"\").reverse().join(\"\");\nconst R_CODE = L_CODE.map(complement);\nconst G_CODE = R_CODE.map(reverse);\n\nconst checkDigit = (twelveDigits) => {\n  const sum = twelveDigits.reduce((acc, d, i) => acc + d * (i % 2 === 0 ? 1 : 3), 0);\n  return (10 - (sum % 10)) % 10;\n};\n\n// --- Data: a 12-digit product code (Polish EAN prefix); check digit computed ---\nconst twelveDigits = \"590123412345\".split(\"\").map(Number);\nconst digits = [...twelveDigits, checkDigit(twelveDigits)];\n\n// --- Encode modules: 9 quiet + 3 start + 42 left + 5 center + 42 right + 3 end + 9 quiet = 113 ---\nconst QUIET_ZONE = 9;\nconst START_GUARD = \"101\";\nconst CENTER_GUARD = \"01010\";\nconst END_GUARD = \"101\";\n\nconst parity = PARITY[digits[0]];\nconst leftBits = digits\n  .slice(1, 7)\n  .map((d, i) => (parity[i] === \"L\" ? L_CODE[d] : G_CODE[d]))\n  .join(\"\");\nconst rightBits = digits\n  .slice(7, 13)\n  .map((d) => R_CODE[d])\n  .join(\"\");\n\nconst bars =\n  \"0\".repeat(QUIET_ZONE) + START_GUARD + leftBits + CENTER_GUARD + rightBits + END_GUARD + \"0\".repeat(QUIET_ZONE);\nconst modules = bars.split(\"\").map(Number);\nconst moduleIndex = modules.map((_, i) => i);\n\n// --- Digit label placement: centered under each digit's 7-module block; the ---\n// --- first digit has no bars of its own and sits centered in the left quiet zone. ---\nconst leftStart = QUIET_ZONE + START_GUARD.length;\nconst rightStart = leftStart + 6 * 7 + CENTER_GUARD.length;\nconst digitCenters = [\n  Math.floor(QUIET_ZONE / 2),\n  ...Array.from({ length: 6 }, (_, i) => leftStart + i * 7 + 3),\n  ...Array.from({ length: 6 }, (_, i) => rightStart + i * 7 + 3),\n];\nconst digitAtCenter = new Map(digitCenters.map((moduleIdx, i) => [moduleIdx, String(digits[i])]));\n\nconst TITLE = \"barcode-ean13 · javascript · muix · anyplot.ai\";\nconst TITLE_HEIGHT = 90;\n\n// Bars render in the theme's ink color rather than the Imprint brand green — a\n// scannable barcode reads as dark-on-light / light-on-dark bars, the same\n// real-world-fidelity exception the style guide grants grass=green or blood=red.\nexport default function Chart() {\n  return (\n    <Box sx={{ width: SIZE.width, height: SIZE.height, display: \"flex\", flexDirection: \"column\" }}>\n      <Typography sx={{ color: t.ink, fontSize: 22, fontWeight: 500, textAlign: \"center\", pt: 2, height: TITLE_HEIGHT }}>\n        {TITLE}\n      </Typography>\n      <BarChart\n        width={SIZE.width}\n        height={SIZE.height - TITLE_HEIGHT}\n        series={[{ data: modules, color: t.ink }]}\n        xAxis={[\n          {\n            scaleType: \"band\",\n            data: moduleIndex,\n            categoryGapRatio: 0,\n            barGapRatio: 0,\n            disableLine: true,\n            disableTicks: true,\n            tickLabelInterval: (value) => digitAtCenter.has(value),\n            valueFormatter: (value) => digitAtCenter.get(value) ?? \"\",\n            tickLabelStyle: { fontSize: 22, fontFamily: \"monospace\", fontWeight: 700 },\n          },\n        ]}\n        leftAxis={null}\n        margin={{ top: 16, right: 24, bottom: 56, left: 24 }}\n        slotProps={{ legend: { hidden: true } }}\n        skipAnimation\n      />\n    </Box>\n  );\n}\n"}