{"spec_id":"barcode-ean13","library":"plotly","language":"python","code":"\"\"\" anyplot.ai\nbarcode-ean13: EAN-13 Barcode\nLibrary: plotly 6.7.0 | Python 3.13.13\nQuality: 85/100 | Updated: 2026-05-21\n\"\"\"\n\nimport os\nimport sys\n\n\n# Prevent this file (plotly.py) from shadowing the installed plotly package\nsys.path = [p for p in sys.path if p not in (\"\", os.path.dirname(os.path.abspath(__file__)))]\n\nimport plotly.graph_objects as go\n\n\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\n\nBAR_COLOR = INK\n\n# EAN-13 encoding patterns\nL_CODES = {\n    \"0\": \"0001101\",\n    \"1\": \"0011001\",\n    \"2\": \"0010011\",\n    \"3\": \"0111101\",\n    \"4\": \"0100011\",\n    \"5\": \"0110001\",\n    \"6\": \"0101111\",\n    \"7\": \"0111011\",\n    \"8\": \"0110111\",\n    \"9\": \"0001011\",\n}\n\nG_CODES = {\n    \"0\": \"0100111\",\n    \"1\": \"0110011\",\n    \"2\": \"0011011\",\n    \"3\": \"0100001\",\n    \"4\": \"0011101\",\n    \"5\": \"0111001\",\n    \"6\": \"0000101\",\n    \"7\": \"0010001\",\n    \"8\": \"0001001\",\n    \"9\": \"0010111\",\n}\n\nR_CODES = {\n    \"0\": \"1110010\",\n    \"1\": \"1100110\",\n    \"2\": \"1101100\",\n    \"3\": \"1000010\",\n    \"4\": \"1011100\",\n    \"5\": \"1001110\",\n    \"6\": \"1010000\",\n    \"7\": \"1000100\",\n    \"8\": \"1001000\",\n    \"9\": \"1110100\",\n}\n\n# First digit determines L/G parity pattern for left side\nFIRST_DIGIT_PATTERNS = {\n    \"0\": \"LLLLLL\",\n    \"1\": \"LLGLGG\",\n    \"2\": \"LLGGLG\",\n    \"3\": \"LLGGGL\",\n    \"4\": \"LGLLGG\",\n    \"5\": \"LGGLLG\",\n    \"6\": \"LGGGLL\",\n    \"7\": \"LGLGLG\",\n    \"8\": \"LGLGGL\",\n    \"9\": \"LGGLGL\",\n}\n\n# German product EAN-13\nean_code = \"4006381333931\"\n\ncode = ean_code\nif len(code) == 12:\n    total = sum(int(d) * (1 if i % 2 == 0 else 3) for i, d in enumerate(code))\n    code = code + str((10 - (total % 10)) % 10)\n\nfirst_digit = code[0]\nleft_digits = code[1:7]\nright_digits = code[7:13]\n\n# Encode to binary\nbinary_pattern = \"101\"\n\nlg_pattern = FIRST_DIGIT_PATTERNS[first_digit]\nfor i, digit in enumerate(left_digits):\n    if lg_pattern[i] == \"L\":\n        binary_pattern += L_CODES[digit]\n    else:\n        binary_pattern += G_CODES[digit]\n\nbinary_pattern += \"01010\"\n\nfor digit in right_digits:\n    binary_pattern += R_CODES[digit]\n\nbinary_pattern += \"101\"\n\n# Bar dimensions (in plot units)\nmodule_width = 3\nbar_height = 200\nguard_height = 220\nquiet_zone = 9 * module_width\n\n# Guard bar positions: start (0-2), center (45-49), end (92-94)\nguard_positions = set(range(0, 3)) | set(range(45, 50)) | set(range(92, 95))\n\nfig = go.Figure()\n\nx_pos = quiet_zone\nfor i, bit in enumerate(binary_pattern):\n    if bit == \"1\":\n        height = guard_height if i in guard_positions else bar_height\n        fig.add_shape(\n            type=\"rect\", x0=x_pos, y0=0, x1=x_pos + module_width, y1=height, fillcolor=BAR_COLOR, line={\"width\": 0}\n        )\n    x_pos += module_width\n\ntotal_width = quiet_zone * 2 + len(binary_pattern) * module_width\n\n# Human-readable digits\ndigit_y = -35\nfont_size = 18\n\n# First digit (outside left guard)\nfig.add_annotation(\n    x=quiet_zone - module_width * 4,\n    y=digit_y,\n    text=code[0],\n    showarrow=False,\n    font={\"size\": font_size, \"family\": \"monospace\", \"color\": INK},\n)\n\n# Left group: digits 2–7 under left bars\nleft_start = quiet_zone + 3 * module_width\nfor i, digit in enumerate(code[1:7]):\n    x = left_start + (i + 0.5) * 7 * module_width\n    fig.add_annotation(\n        x=x, y=digit_y, text=digit, showarrow=False, font={\"size\": font_size, \"family\": \"monospace\", \"color\": INK}\n    )\n\n# Right group: digits 8–13 under right bars\nright_start = quiet_zone + 3 * module_width + 42 * module_width + 5 * module_width\nfor i, digit in enumerate(code[7:13]):\n    x = right_start + (i + 0.5) * 7 * module_width\n    fig.add_annotation(\n        x=x, y=digit_y, text=digit, showarrow=False, font={\"size\": font_size, \"family\": \"monospace\", \"color\": INK}\n    )\n\n# Segment labels: Country (GS1 prefix), Manufacturer, Product, Check\nsegment_y = -65\nx_first = quiet_zone - module_width * 4\nx_country = (x_first + left_start + 0.5 * 7 * module_width + left_start + 1.5 * 7 * module_width) / 3\nx_manuf = left_start + 4.0 * 7 * module_width\nx_product = right_start + 2.5 * 7 * module_width\nx_check = right_start + 5.5 * 7 * module_width\nfor x, label in [(x_country, \"Country\"), (x_manuf, \"Manufacturer\"), (x_product, \"Product\"), (x_check, \"Check\")]:\n    fig.add_annotation(x=x, y=segment_y, text=label, showarrow=False, font={\"size\": 9, \"color\": INK_SOFT})\n\nfig.update_layout(\n    autosize=False,\n    title={\n        \"text\": \"barcode-ean13 · python · plotly · anyplot.ai\",\n        \"font\": {\"size\": 16, \"color\": INK},\n        \"x\": 0.5,\n        \"xanchor\": \"center\",\n    },\n    xaxis={\"visible\": False, \"range\": [-20, total_width + 20]},\n    yaxis={\"visible\": False, \"range\": [-100, guard_height + 20]},\n    plot_bgcolor=PAGE_BG,\n    paper_bgcolor=PAGE_BG,\n    margin={\"l\": 80, \"r\": 40, \"t\": 80, \"b\": 60},\n    width=800,\n    height=450,\n)\n\nfig.write_image(f\"plot-{THEME}.png\", width=800, height=450, scale=4)\nfig.write_html(f\"plot-{THEME}.html\", include_plotlyjs=\"cdn\")\n"}