{"spec_id":"qrcode-basic","library":"echarts","language":"javascript","code":"// anyplot.ai\n// qrcode-basic: Basic QR Code Generator\n// Library: echarts 5.5.1 | JavaScript 22.23.0\n// Quality: 87/100 | Created: 2026-06-24\n//# anyplot-orientation: square\n\nconst t = window.ANYPLOT_TOKENS;\n\n// QR code matrix (Version 2, 25×25, EC Level M) encoding \"https://anyplot.ai\"\n// Generated by the qrcode library — standard-compliant, scannable by any QR reader\nconst QR_MATRIX = [\n  [1,1,1,1,1,1,1,0,1,0,0,1,1,0,1,0,0,0,1,1,1,1,1,1,1],\n  [1,0,0,0,0,0,1,0,1,0,1,1,1,1,1,0,1,0,1,0,0,0,0,0,1],\n  [1,0,1,1,1,0,1,0,1,0,1,0,0,1,1,1,1,0,1,0,1,1,1,0,1],\n  [1,0,1,1,1,0,1,0,0,1,0,0,1,0,1,0,1,0,1,0,1,1,1,0,1],\n  [1,0,1,1,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1],\n  [1,0,0,0,0,0,1,0,0,1,1,1,0,1,1,0,1,0,1,0,0,0,0,0,1],\n  [1,1,1,1,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1],\n  [0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0],\n  [1,0,0,1,1,1,1,1,1,1,0,1,1,1,1,0,1,1,0,0,1,0,1,1,1],\n  [0,0,1,0,1,0,0,1,0,0,1,0,0,0,1,1,1,0,0,1,1,1,1,1,0],\n  [1,0,0,0,0,1,1,1,1,0,1,1,0,0,1,1,0,0,0,1,1,1,0,0,1],\n  [0,1,1,1,1,1,0,1,0,1,0,1,0,0,1,0,0,1,0,0,0,1,1,1,1],\n  [1,0,1,1,1,0,1,0,1,1,1,1,0,1,1,1,0,0,1,1,0,0,0,0,1],\n  [1,0,0,0,1,0,0,0,0,0,1,0,1,0,0,1,1,1,0,0,1,0,0,1,0],\n  [1,1,0,0,0,0,1,1,1,1,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1],\n  [1,0,0,1,0,1,0,0,1,0,0,0,1,1,1,1,0,1,1,1,0,1,1,0,1],\n  [1,0,1,1,1,0,1,0,1,0,1,1,1,0,0,0,1,1,1,1,1,0,1,1,0],\n  [0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,1,0,0,0,1,0,1,1,0],\n  [1,1,1,1,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,0,0,1],\n  [1,0,0,0,0,0,1,0,1,0,1,1,0,1,0,1,1,0,0,0,1,0,0,0,0],\n  [1,0,1,1,1,0,1,0,1,0,1,1,0,1,0,1,1,1,1,1,1,0,0,0,1],\n  [1,0,1,1,1,0,1,0,1,1,1,0,1,1,0,0,1,1,1,0,0,0,0,1,1],\n  [1,0,1,1,1,0,1,0,0,0,0,1,0,1,0,0,1,0,0,0,1,1,1,1,1],\n  [1,0,0,0,0,0,1,0,0,1,0,1,1,1,0,0,0,1,1,1,1,0,1,1,1],\n  [1,1,1,1,1,1,1,0,1,1,0,1,1,1,0,0,1,1,1,0,0,1,0,0,1],\n];\nconst QR_SIZE = 25;\n\n// Add 4-module quiet zone around QR code (required for reliable scanning)\nconst QUIET = 4;\nconst TOTAL = QR_SIZE + 2 * QUIET; // 33\n\nconst data = [];\nfor (let r = 0; r < TOTAL; r++) {\n  for (let c = 0; c < TOTAL; c++) {\n    const inQR = r >= QUIET && r < QUIET + QR_SIZE && c >= QUIET && c < QUIET + QR_SIZE;\n    const value = inQR ? QR_MATRIX[r - QUIET][c - QUIET] : 0;\n    data.push([c, r, value]);\n  }\n}\n\nconst chart = echarts.init(document.getElementById(\"container\"));\n\n// QR module colors: high-contrast ink on page background\n// Light theme: near-black on cream; dark theme: near-white on near-black\nconst MODULE_DARK = t.ink;\nconst MODULE_LIGHT = t.pageBg;\n\n// Grid: 930×930 CSS px centered in 1200×1200 mount\n// Equal left/right margins (135 px) + increased bottom (140 px) center the QR vertically\nconst GRID_SIZE = 930;\nconst MARGIN = (1200 - GRID_SIZE) / 2; // 135 CSS px\nconst GRID_TOP = 130;\nconst GRID_BOTTOM = 140;\n\n// Cell size for computing annotation positions\nconst cellW = GRID_SIZE / TOTAL; // ≈ 28.18 px\n\n// Finder-pattern pixel anchors (top-left corner of each 7×7 FP block, in canvas coords)\nconst fp_tl_x = MARGIN + QUIET * cellW;          // top-left FP left edge\nconst fp_tl_y = GRID_TOP + QUIET * cellW;         // top FPs top edge\nconst fp_tr_x = MARGIN + (QUIET + 18) * cellW;   // top-right FP left edge\nconst fp_bl_y = GRID_TOP + (QUIET + 18) * cellW; // bottom-left FP top edge\nconst fp_w = 7 * cellW;                           // finder-pattern width/height\nconst fp_cx_l = fp_tl_x + fp_w / 2;              // left FP center x\nconst fp_cx_r = fp_tr_x + fp_w / 2;              // right FP center x\nconst qrBottom = 1200 - GRID_BOTTOM;              // grid bottom edge in canvas px\n\nchart.setOption({\n  animation: false,\n  backgroundColor: t.pageBg,\n  title: {\n    text: \"qrcode-basic · javascript · echarts · anyplot.ai\",\n    subtext: \"Scan to visit: https://anyplot.ai  ·  QR Version 2  ·  Error Correction Level M\",\n    left: \"center\",\n    top: 28,\n    textStyle: { color: t.ink, fontSize: 22, fontWeight: \"bold\" },\n    subtextStyle: { color: t.inkSoft, fontSize: 14 },\n  },\n  graphic: [\n    // Thin themed frame around the full QR (including quiet zone) — design framing\n    {\n      type: \"rect\",\n      bounding: \"raw\",\n      shape: { x: MARGIN - 2, y: GRID_TOP - 2, width: GRID_SIZE + 4, height: GRID_SIZE + 4 },\n      style: { fill: \"transparent\", stroke: t.inkSoft, lineWidth: 1.5, opacity: 0.35 },\n      z: 50,\n    },\n    // \"FP\" callout above the top-left finder pattern (in the quiet zone)\n    {\n      type: \"text\",\n      bounding: \"raw\",\n      x: fp_cx_l,\n      y: fp_tl_y - 20,\n      style: { text: \"FP\", fill: t.inkSoft, fontSize: 10, fontWeight: \"bold\", textAlign: \"center\" },\n      z: 60,\n    },\n    // \"FP\" callout above the top-right finder pattern (in the quiet zone)\n    {\n      type: \"text\",\n      bounding: \"raw\",\n      x: fp_cx_r,\n      y: fp_tl_y - 20,\n      style: { text: \"FP\", fill: t.inkSoft, fontSize: 10, fontWeight: \"bold\", textAlign: \"center\" },\n      z: 60,\n    },\n    // \"FP\" callout below the bottom-left finder pattern (in the quiet zone)\n    {\n      type: \"text\",\n      bounding: \"raw\",\n      x: fp_cx_l,\n      y: fp_bl_y + fp_w + 6,\n      style: { text: \"FP\", fill: t.inkSoft, fontSize: 10, fontWeight: \"bold\", textAlign: \"center\" },\n      z: 60,\n    },\n    // Footer annotation explaining QR structural components\n    {\n      type: \"text\",\n      bounding: \"raw\",\n      x: 600,\n      y: qrBottom + 38,\n      style: {\n        text: \"FP = Finder Pattern (3 corners)  ·  Timing Patterns  ·  Quiet Zone (border)\",\n        fill: t.inkSoft,\n        fontSize: 12,\n        textAlign: \"center\",\n      },\n      z: 50,\n    },\n  ],\n  grid: {\n    left: MARGIN,\n    right: MARGIN,\n    top: GRID_TOP,\n    bottom: GRID_BOTTOM,\n    containLabel: false,\n  },\n  xAxis: {\n    type: \"category\",\n    data: Array.from({ length: TOTAL }, (_, i) => i),\n    show: false,\n    splitLine: { show: false },\n    axisTick: { show: false },\n    axisLine: { show: false },\n  },\n  yAxis: {\n    type: \"category\",\n    data: Array.from({ length: TOTAL }, (_, i) => i),\n    inverse: true,\n    show: false,\n    splitLine: { show: false },\n    axisTick: { show: false },\n    axisLine: { show: false },\n  },\n  visualMap: {\n    type: \"piecewise\",\n    show: false,\n    pieces: [\n      { value: 0, color: MODULE_LIGHT },\n      { value: 1, color: MODULE_DARK },\n    ],\n  },\n  series: [\n    {\n      type: \"heatmap\",\n      data: data,\n      itemStyle: { borderWidth: 0 },\n    },\n  ],\n});\n"}