← Commit history

Save native two-sided contact artwork and recorded GLB material correction; qualification remains open

John Lauer ·57e2489a0f ·13d ago ·parent a4a06ac
40 files changed +5572−20
design/silkscreen-review/bottom-candidate-bottom.pngdesign/silkscreen-review/bottom-candidate-top.pngdesign/silkscreen-review/bottom-landed-drc.json+36design/silkscreen-review/bottom-landing-verification.json+1469design/silkscreen-review/front-contacts/front-contact-candidate.pngdesign/silkscreen-review/front-contacts/front-contact-drc.json+36design/silkscreen-review/front-contacts/landing-verification.json+24docs/clips/bottom-silkscreen-native.jpgdocs/clips/bottom-silkscreen-native.mp4docs/clips/opaque-silkscreen.jpgdocs/clips/opaque-silkscreen.mp4docs/silkscreen-review.md+13−1docs/status.md+16−2kicad/adom-custom-electronic-load.kicad_pcb+3326−9tools/alternate_bottom_groups.py+17tools/bottom_artwork_review.py+41tools/bottom_association_targets.py+25tools/bottom_contact_tags.py+19tools/bottom_corner_tags.py+17tools/bottom_identity.py+9tools/bottom_saved_candidate.py+19tools/bottom_silkscreen_candidate.py+7−6tools/bottom_silkscreen_leaders.py+82tools/bottom_silkscreen_native.py+17tools/check_bottom_native_extents.py+17tools/check_bottom_saved_candidate.py+12tools/complete_bottom_candidates.py+29tools/expand_bottom_candidate.py+20tools/front_contact_artwork.py+69tools/land_bottom_artwork.py+34tools/land_front_saved_candidate.py+27tools/opaque_board_material_review.py+16tools/plot_bottom_silkscreen.py+21tools/record_opaque_material_review.py+17tools/refine_bottom_association.py+16tools/render_bottom_candidate.py+7tools/review_front_candidate.py+38tools/verify_bottom_landing.py+40tools/verify_front_landing.py+17videos/inventory.json+19−2
design/silkscreen-review/bottom-candidate-bottom.pngadded
⋯ 1 unchanged line ⋯
design/silkscreen-review/bottom-candidate-top.pngadded
⋯ 1 unchanged line ⋯
design/silkscreen-review/bottom-landed-drc.jsonadded+36
@@ -0,0 +1,36 @@+{
+    "$schema": "https://schemas.kicad.org/drc.v1.json",
+    "coordinate_units": "mm",
+    "date": "2026-10-10T18:29:51",
+    "ignored_checks": [
+        {
+            "description": "Footprint has no courtyard defined",
+            "key": "missing_courtyard"
+        },
+        {
+            "description": "Track endpoint not centered on via",
+            "key": "track_not_centered_on_via"
+        },
+        {
+            "description": "Tuning profile track geometries",
+            "key": "tuning_profile_track_geometries"
+        },
+        {
+            "description": "Footprint doesn't match symbol's footprint filters",
+            "key": "footprint_filters_mismatch"
+        },
+        {
+            "description": "Footprint component type doesn't match footprint pads",
+            "key": "footprint_type_mismatch"
+        }
+    ],
+    "included_severities": [
+        "error",
+        "warning"
+    ],
+    "kicad_version": "10.0.5",
+    "schematic_parity": [],
+    "source": "adom-custom-electronic-load.kicad_pcb",
+    "unconnected_items": [],
+    "violations": []
+}
design/silkscreen-review/bottom-landing-verification.jsonadded+1469
@@ -0,0 +1,1469 @@+{+  "status": "native saved readback matches reviewed artwork",+  "sourceSha256": "82c2fad50b3c2fb93b627df4a984bf7fe85724d73367e33e3d97206e0b752342",+  "savedSha256": "44678abfa0219151ce08165da98ae669f30fca88391411b0f66ecd91adc65189",+  "unchanged": {+    "footprint": true,+    "segment": true,+    "arc": true,+    "via": true,+    "zone": true,+    "net": true,+    "setup": true,+    "layers": true,+    "gr_arc": true,+    "gr_poly": true+  },+  "addedTexts": 193,+  "addedGraphics": 92,+  "nativeTextIds": [+    {+      "id": "db9f2b40-9f5a-4eae-9e45-b35c6ec3624a",+      "text": "U6",+      "reference": "U6",+      "x": 130.2,+      "y": 45.0+    },+    {+      "id": "a0b95823-eb82-4a0b-9403-74eaedab2acf",+      "text": "R33",+      "reference": "R33",+      "x": 142.79999999999998,+      "y": 63.62140000000001+    },+    {+      "id": "dd706367-6633-4fdc-865b-bd26c66d1b98",+      "text": "100k",+      "reference": "R33",+      "x": 142.79999999999998,+      "y": 65.29560000000001+    },+    {+      "id": "2a0f5bc3-3847-4bd6-a95f-7700b25520ee",+      "text": "R11",+      "reference": "R11",+      "x": 132.22140000000002,+      "y": 86.0+    },+    {+      "id": "13ba3fa0-8c5b-4661-a5b8-9ed983d816d2",+      "text": "10k",+      "reference": "R11",+      "x": 133.8956,+      "y": 86.0+    },+    {+      "id": "05dcc37d-7ebc-45f3-bcd9-1350a2445ffd",+      "text": "R21",+      "reference": "R21",+      "x": 122.88571449999999,+      "y": 67.8+    },+    {+      "id": "a294bcb2-8a73-48e1-9fb0-defe4b2d2efa",+      "text": "10k",+      "reference": "R21",+      "x": 119.9676185,+      "y": 67.8+    },+    {+      "id": "dd39f219-dfc6-4e22-84b0-ae4920e17527",+      "text": "MP2",+      "reference": "MP2",+      "x": 160.0,+      "y": 95.72139999999999+    },+    {+      "id": "e0f63387-07bf-4408-93b3-3ed9584b255c",+      "text": "GND",+      "reference": "MP2",+      "x": 160.0,+      "y": 97.3371+    },+    {+      "id": "eb750af0-c7b4-4d07-9d75-1eb5de61614d",+      "text": "J6",+      "reference": "J6",+      "x": 139.4,+      "y": 96.12140000000001+    },+    {+      "id": "33902a4c-53f2-4d22-9329-e4ef7899f337",+      "text": "RX",+      "reference": "J6",+      "x": 139.4,+      "y": 97.79560000000001+    },+    {+      "id": "eb75c64a-b173-4d8d-8c36-10b73faf6949",+      "text": "C15",+      "reference": "C15",+      "x": 141.9,+      "y": 88.62140000000001+    },+    {+      "id": "87772828-59c6-4396-9e83-98d458e847b3",+      "text": "100n",+      "reference": "C15",+      "x": 141.9,+      "y": 90.29560000000001+    },+    {+      "id": "d1474e3e-9c91-484b-8f5b-7e845b892fc5",+      "text": "F1",+      "reference": "F1",+      "x": 106.4,+      "y": 91.4214+    },+    {+      "id": "ab2375ee-98ec-40bf-9a23-761d3879bf98",+      "text": "5 A 32 V fast fuse",+      "reference": "F1",+      "x": 106.4,+      "y": 93.0956+    },+    {+      "id": "545cb0b8-ee7a-4bb0-9da1-aad5ff3712c3",+      "text": "MP3",+      "reference": "MP3",+      "x": 100.0,+      "y": 34.721399999999996+    },+    {+      "id": "47e41a75-2735-46e1-877c-3385ed51bb27",+      "text": "GND",+      "reference": "MP3",+      "x": 100.0,+      "y": 36.3371+    },+    {+      "id": "1ebdc7e7-3d33-47d2-9e7c-4c38b9ae979a",+      "text": "U9",+      "reference": "U9",+      "x": 146.8,+      "y": 65.0+    },+    {+      "id": "22343357-1e07-480a-be59-40e30a46b497",+      "text": "R30",+      "reference": "R30",+      "x": 151.4,+      "y": 37.7214+    },+    {+      "id": "84698045-5a80-46c8-8013-b6f74b39202b",+      "text": "4.7k",+      "reference": "R30",+      "x": 151.4,+      "y": 39.3956+    },+    {+      "id": "9acd2dc9-5b84-47af-8160-0a678b3bb0c4",+      "text": "RSH1",+      "reference": "RSH1",+      "x": 138.4214,+      "y": 85.8+    },+    {+      "id": "ecbc6b14-6233-4ab2-9bd2-1311489e8af2",+      "text": "20m",+      "reference": "RSH1",+      "x": 140.0956,+      "y": 85.8+    },+    {+      "id": "70f82ddf-6b64-420c-82ef-af3114e1f939",+      "text": "U3",+      "reference": "U3",+      "x": 129.3,+      "y": 87.0+    },+    {+      "id": "598c33e6-b434-459d-8db6-3b1dfbc7d6b5",+      "text": "U8",+      "reference": "U8",+      "x": 128.0,+      "y": 52.4+    },+    {+      "id": "ab18f66b-f865-44ad-bdf9-4b721707c288",+      "text": "R20",+      "reference": "R20",+      "x": 116.8,+      "y": 60.2214+    },+    {+      "id": "9f7646bb-d0da-48bd-a593-3121cb992e29",+      "text": "1k",+      "reference": "R20",+      "x": 116.8,+      "y": 61.8956+    },+    {+      "id": "3931fd9f-3704-41b4-ba4d-0820d6fe9c37",+      "text": "MP1",+      "reference": "MP1",+      "x": 100.0,+      "y": 95.72139999999999+    },+    {+      "id": "6b6a112c-7ad9-4fb3-96c3-423c36fa02c6",+      "text": "GND",+      "reference": "MP1",+      "x": 100.0,+      "y": 97.3371+    },+    {+      "id": "65331a26-7f60-44bc-97c7-8fdcdbe6161a",+      "text": "R38",+      "reference": "R38",+      "x": 152.6,+      "y": 63.2214+    },+    {+      "id": "b45bc26e-1a5c-402c-bb1b-a9f219ee973a",+      "text": "10k",+      "reference": "R38",+      "x": 152.6,+      "y": 64.8956+    },+    {+      "id": "e000ee8a-bc52-4c25-b0df-937568a2b053",+      "text": "J10",+      "reference": "J10",+      "x": 101.2,+      "y": 71.8214+    },+    {+      "id": "a554257a-37fc-46ce-823b-d3dcfe0a1dc6",+      "text": "TEMP",+      "reference": "J10",+      "x": 101.2,+      "y": 73.4956+    },+    {+      "id": "bb06c29c-22bc-4d57-9885-d1bfe70ed69a",+      "text": "C16",+      "reference": "C16",+      "x": 126.6,+      "y": 41.5214+    },+    {+      "id": "014186d0-67fc-492d-b83a-43df10ff1f5a",+      "text": "100n",+      "reference": "C16",+      "x": 126.6,+      "y": 43.1956+    },+    {+      "id": "280d5180-eb24-4ccd-9d2c-2ed28f3be8ed",+      "text": "R23",+      "reference": "R23",+      "x": 124.4214,+      "y": 56.11+    },+    {+      "id": "65b9ef64-4ffb-4772-a55a-db671cffcb39",+      "text": "1k",+      "reference": "R23",+      "x": 126.0956,+      "y": 56.11+    },+    {+      "id": "aa306a90-32a6-4d37-ab97-e49e8704d4c3",+      "text": "R24",+      "reference": "R24",+      "x": 146.8,+      "y": 80.8214+    },+    {+      "id": "61d1ace6-730b-4d38-acd6-48afb43cedc1",+      "text": "100k",+      "reference": "R24",+      "x": 146.8,+      "y": 82.4956+    },+    {+      "id": "83be0e35-80b9-4186-aee7-2e5621e98795",+      "text": "J5",+      "reference": "J5",+      "x": 136.0,+      "y": 96.12140000000001+    },+    {+      "id": "21791b50-37e9-4403-adf6-bd587edccd07",+      "text": "TX",+      "reference": "J5",+      "x": 136.0,+      "y": 97.79560000000001+    },+    {+      "id": "fdd29b95-1646-4f17-a50d-1623c71c053d",+      "text": "R34",+      "reference": "R34",+      "x": 149.79999999999998,+      "y": 66.5214+    },+    {+      "id": "2b252ef0-cd76-49a8-9776-e6728edf23b6",+      "text": "100k",+      "reference": "R34",+      "x": 149.79999999999998,+      "y": 68.1956+    },+    {+      "id": "59248331-b32b-4e75-95d2-d536de8b7ed5",+      "text": "R5",+      "reference": "R5",+      "x": 112.8,+      "y": 56.02140000000001+    },+    {+      "id": "91a7eca1-8d77-43c6-b625-be33699ca69f",+      "text": "100k",+      "reference": "R5",+      "x": 112.8,+      "y": 57.695600000000006+    },+    {+      "id": "f607c3a2-82e9-461e-8830-d5955be612d2",+      "text": "D3",+      "reference": "D3",+      "x": 146.3,+      "y": 84.3+    },+    {+      "id": "34083472-66c1-4180-8815-5a9e9440fcd8",+      "text": "J2",+      "reference": "J2",+      "x": 112.0,+      "y": 96.12140000000001+    },+    {+      "id": "bc33141a-7f20-4788-a492-4945700a8049",+      "text": "GND",+      "reference": "J2",+      "x": 112.0,+      "y": 97.79560000000001+    },+    {+      "id": "0b477f6f-88a7-4449-b055-954add10c1d4",+      "text": "U1",+      "reference": "U1",+      "x": 143.8,+      "y": 47.4+    },+    {+      "id": "2f80655c-7583-4774-875d-58a5861692bd",+      "text": "R22",+      "reference": "R22",+      "x": 126.0857145,+      "y": 60.7+    },+    {+      "id": "8f709dbe-d4af-45d8-9311-3c50b85ab99d",+      "text": "33k",+      "reference": "R22",+      "x": 123.1676185,+      "y": 60.7+    },+    {+      "id": "7b4a5f3b-5b5c-4232-a578-57d577d5054e",+      "text": "C1",+      "reference": "C1",+      "x": 114.8,+      "y": 74.42139999999999+    },+    {+      "id": "b751282b-6371-4da4-8592-67b3db890813",+      "text": "100n",+      "reference": "C1",+      "x": 114.8,+      "y": 76.09559999999999+    },+    {+      "id": "0248fd85-e3b8-4727-9d05-1c50daba214d",+      "text": "R31",+      "reference": "R31",+      "x": 147.1714,+      "y": 45.0+    },+    {+      "id": "871efff0-98df-4d53-b3ad-a9566610a642",+      "text": "0",+      "reference": "R31",+      "x": 148.84560000000002,+      "y": 45.0+    },+    {+      "id": "a61cc4dc-8bc4-4ed9-8571-2290d2b40418",+      "text": "R10",+      "reference": "R10",+      "x": 122.39999999999999,+      "y": 78.2414+    },+    {+      "id": "9d72b6bd-1768-47e0-92b2-901c55fc2d36",+      "text": "1k",+      "reference": "R10",+      "x": 122.39999999999999,+      "y": 79.9156+    },+    {+      "id": "435aec3b-d1f4-44f8-b984-bf5cf86d8bdf",+      "text": "J4",+      "reference": "J4",+      "x": 124.0,+      "y": 96.12140000000001+    },+    {+      "id": "495abe46-8dbc-41c6-8f97-640466d18622",+      "text": "GND",+      "reference": "J4",+      "x": 124.0,+      "y": 97.79560000000001+    },+    {+      "id": "b17fe6f2-8c16-42b4-bd10-deb3e88c015d",+      "text": "R26",+      "reference": "R26",+      "x": 153.20000000000002,+      "y": 80.4214+    },+    {+      "id": "c23f1721-6039-4697-a6e3-5c204e6d20ba",+      "text": "10k",+      "reference": "R26",+      "x": 153.20000000000002,+      "y": 82.0956+    },+    {+      "id": "9ffaa3c1-c1e0-4cc7-930a-34b1f0ba116f",+      "text": "TP13",+      "reference": "TP13",+      "x": 105.2,+      "y": 63.2214+    },+    {+      "id": "387466cf-9c7b-47e5-b100-1120f2f3e8d3",+      "text": "SH-",+      "reference": "TP13",+      "x": 105.2,+      "y": 64.8956+    },+    {+      "id": "cfaa1d07-d631-449c-8672-7991a6fc6d0d",+      "text": "J9",+      "reference": "J9",+      "x": 156.6,+      "y": 98.0214+    },+    {+      "id": "e897a738-841e-4620-a802-9c54929c96d2",+      "text": "FAN",+      "reference": "J9",+      "x": 156.6,+      "y": 99.6956+    },+    {+      "id": "a2d77bb4-aaa4-4b6e-9ea9-72dfa0d7a831",+      "text": "R25",+      "reference": "R25",+      "x": 150.0,+      "y": 78.4214+    },+    {+      "id": "57cc7992-8924-49ad-b8a2-05ed7b1126e9",+      "text": "10k",+      "reference": "R25",+      "x": 150.0,+      "y": 80.0956+    },+    {+      "id": "00d84551-bc96-4cb7-a2c7-cd1dd6a9b365",+      "text": "R19",+      "reference": "R19",+      "x": 127.07619050000001,+      "y": 62.51+    },+    {+      "id": "cba4c124-7779-4fe3-bbf6-a9133c45e35e",+      "text": "3.3k",+      "reference": "R19",+      "x": 123.9676185,+      "y": 62.510000000000005+    },+    {+      "id": "dedbe019-f31a-4398-9561-6991acc3f577",+      "text": "R8",+      "reference": "R8",+      "x": 121.2,+      "y": 70.2214+    },+    {+      "id": "12683f29-0a33-4415-93b3-30c8806e4cb1",+      "text": "33k",+      "reference": "R8",+      "x": 121.2,+      "y": 71.8956+    },+    {+      "id": "c4016761-bcd3-442c-960b-e985094faabc",+      "text": "MP4",+      "reference": "MP4",+      "x": 160.0,+      "y": 34.08095249999999+    },+    {+      "id": "fc3e223b-d807-4057-a0cf-34021d05d360",+      "text": "GND",+      "reference": "MP4",+      "x": 160.0,+      "y": 36.3371+    },+    {+      "id": "4c4e83e7-c2fd-4644-819a-8222b8777d10",+      "text": "R37",+      "reference": "R37",+      "x": 148.7,+      "y": 93.6414+    },+    {+      "id": "d5bc570e-7b48-4eb8-a695-ce769a20894b",+      "text": "100k",+      "reference": "R37",+      "x": 148.7,+      "y": 95.3156+    },+    {+      "id": "8b66156b-2be0-4bd6-b0ef-c89e98f0ff99",+      "text": "TP11",+      "reference": "TP11",+      "x": 111.6,+      "y": 85.62140000000001+    },+    {+      "id": "e6420bc7-ee83-4214-b60a-4a721dd20165",+      "text": "GND",+      "reference": "TP11",+      "x": 111.6,+      "y": 87.29560000000001+    },+    {+      "id": "d87c0610-7b7d-48bd-b095-b49a275dfeb1",+      "text": "C5",+      "reference": "C5",+      "x": 144.0,+      "y": 83.8214+    },+    {+      "id": "43c81f9b-9b2b-4a12-9e75-8797eaa0c50e",+      "text": "10n",+      "reference": "C5",+      "x": 144.0,+      "y": 85.4956+    },+    {+      "id": "e91428ac-17e9-4285-8b76-207af82140ae",+      "text": "R13",+      "reference": "R13",+      "x": 141.4,+      "y": 56.821400000000004+    },+    {+      "id": "3bc8dc5e-2099-49e7-bde2-20556e307acb",+      "text": "4.7k",+      "reference": "R13",+      "x": 141.4,+      "y": 58.4956+    },+    {+      "id": "f441aa0c-3ccc-43e0-af9f-aa4227f137ba",+      "text": "C18",+      "reference": "C18",+      "x": 125.6,+      "y": 47.7214+    },+    {+      "id": "b72c1feb-7a75-43cd-9133-c51eecec7c6d",+      "text": "100n",+      "reference": "C18",+      "x": 125.6,+      "y": 49.3956+    },+    {+      "id": "e68530fb-3492-49d6-850b-7f88d58356e0",+      "text": "R16",+      "reference": "R16",+      "x": 153.8,+      "y": 56.0214+    },+    {+      "id": "956bdaaf-e269-4565-9baa-e51397cf9020",+      "text": "10k",+      "reference": "R16",+      "x": 153.8,+      "y": 57.6956+    },+    {+      "id": "b34bc1bc-c30f-48e5-8152-3b9ca8158499",+      "text": "R28",+      "reference": "R28",+      "x": 109.3214,+      "y": 67.01+    },+    {+      "id": "065f6879-5dac-43ac-941c-ae3e05df384e",+      "text": "10k",+      "reference": "R28",+      "x": 110.9956,+      "y": 67.01+    },+    {+      "id": "3e218a30-ab38-45d4-a384-9d186e55a412",+      "text": "R36",+      "reference": "R36",+      "x": 149.2,+      "y": 88.8314+    },+    {+      "id": "141c74f7-7e7a-41fc-a8a1-ad57c38d453d",+      "text": "220k",+      "reference": "R36",+      "x": 149.2,+      "y": 90.5056+    },+    {+      "id": "1ee843a9-78a5-411e-ac66-82f0d7981920",+      "text": "R4",+      "reference": "R4",+      "x": 120.82140000000001,+      "y": 56.6+    },+    {+      "id": "4b9b8fdd-65ca-4340-aebd-d7266b7921e7",+      "text": "10k",+      "reference": "R4",+      "x": 122.49560000000001,+      "y": 56.6+    },+    {+      "id": "80ab2aab-8017-44ca-96b6-6e362e884ce1",+      "text": "U10",+      "reference": "U10",+      "x": 151.9,+      "y": 44.4+    },+    {+      "id": "3c191edf-b972-41d6-b5ef-a3222da71607",+      "text": "U2",+      "reference": "U2",+      "x": 118.4,+      "y": 64.8+    },+    {+      "id": "6c50f5af-b3b2-4eab-bfc6-2364d65d3419",+      "text": "R3",+      "reference": "R3",+      "x": 116.0214,+      "y": 51.0+    },+    {+      "id": "b969188a-114f-40d3-ad3e-3771517b6402",+      "text": "100k",+      "reference": "R3",+      "x": 117.6956,+      "y": 51.0+    },+    {+      "id": "978245b4-a87e-4c96-81b9-f36710786db0",+      "text": "TP6",+      "reference": "TP6",+      "x": 107.6,+      "y": 83.8214+    },+    {+      "id": "e9ce98b8-7869-45cc-b673-f446f272245a",+      "text": "VDRV",+      "reference": "TP6",+      "x": 107.6,+      "y": 85.4956+    },+    {+      "id": "211ba1c3-14b0-41df-b7e9-9ae9072e406b",+      "text": "TP7",+      "reference": "TP7",+      "x": 111.6,+      "y": 82.2214+    },+    {+      "id": "5d39c783-5668-469e-808f-88e4a6932cc6",+      "text": "3V3",+      "reference": "TP7",+      "x": 111.6,+      "y": 83.8956+    },+    {+      "id": "7de030d2-cd54-4df1-8ec6-5f47b1c9470e",+      "text": "Q1",+      "reference": "Q1",+      "x": 130.0,+      "y": 80.0+    },+    {+      "id": "3e537ca3-a7ae-493b-8abd-1f944f41a1b6",+      "text": "Q4",+      "reference": "Q4",+      "x": 118.4,+      "y": 77.0+    },+    {+      "id": "d40ad323-afaf-429a-9c1d-7dcc14643492",+      "text": "TP4",+      "reference": "TP4",+      "x": 99.6214,+      "y": 76.0+    },+    {+      "id": "02c8734a-b884-4e67-bedb-3680562a240e",+      "text": "ISET",+      "reference": "TP4",+      "x": 101.2956,+      "y": 76.0+    },+    {+      "id": "841d8b20-928b-41ea-b9cd-54284735deb6",+      "text": "TP3",+      "reference": "TP3",+      "x": 112.0,+      "y": 78.8214+    },+    {+      "id": "699d7265-173f-4161-bbcb-5fd85b48d450",+      "text": "SH+",+      "reference": "TP3",+      "x": 112.0,+      "y": 80.4956+    },+    {+      "id": "87b209fb-6c4e-4534-9230-0f57f1efcf79",+      "text": "C3",+      "reference": "C3",+      "x": 136.6214,+      "y": 80.2+    },+    {+      "id": "651803be-3de3-4b2f-baec-a21b9e7b0cda",+      "text": "100n",+      "reference": "C3",+      "x": 138.2956,+      "y": 80.2+    },+    {+      "id": "24c2fc72-efa6-402e-a46e-e877690355d9",+      "text": "C6",+      "reference": "C6",+      "x": 157.6214,+      "y": 87.0+    },+    {+      "id": "a57fec9d-91b0-41be-ad39-8d9ec3185481",+      "text": "4.7u 25V",+      "reference": "C6",+      "x": 159.2956,+      "y": 87.0+    },+    {+      "id": "a8690b95-ec9a-4acb-bc14-8e572e0ba8a9",+      "text": "R1",+      "reference": "R1",+      "x": 108.4214,+      "y": 57.4+    },+    {+      "id": "0c065772-9c8f-4fc1-b6a9-6d6529497e7f",+      "text": "10k",+      "reference": "R1",+      "x": 110.0956,+      "y": 57.4+    },+    {+      "id": "c4c4df90-521b-43a3-b4fb-32cf18a2ea86",+      "text": "J3",+      "reference": "J3",+      "x": 120.0,+      "y": 96.12140000000001+    },+    {+      "id": "567828fd-a14f-4953-a443-aa188500372f",+      "text": "5V",+      "reference": "J3",+      "x": 120.0,+      "y": 97.79560000000001+    },+    {+      "id": "30f711e9-c2a7-4666-ba73-969af02d766b",+      "text": "R14",+      "reference": "R14",+      "x": 144.60000000000002,+      "y": 56.821400000000004+    },+    {+      "id": "e75814c0-b150-4171-9f80-e38c9840a4ce",+      "text": "4.7k",+      "reference": "R14",+      "x": 144.60000000000002,+      "y": 58.4956+    },+    {+      "id": "f3f71a89-2997-401a-9e73-cda483f30aa8",+      "text": "R2",+      "reference": "R2",+      "x": 113.2214,+      "y": 53.8+    },+    {+      "id": "69033484-afe8-4efa-ba50-26d496fd284d",+      "text": "100k",+      "reference": "R2",+      "x": 114.8956,+      "y": 53.8+    },+    {+      "id": "51abcd53-641a-412e-a449-f70c8c03186a",+      "text": "C9",+      "reference": "C9",+      "x": 143.4214,+      "y": 67.4+    },+    {+      "id": "b363bc34-6c6a-4a9f-9ac2-daf1e427f9f8",+      "text": "1u",+      "reference": "C9",+      "x": 145.0956,+      "y": 67.4+    },+    {+      "id": "35e5b2db-a472-45a6-b254-833dd355e147",+      "text": "C10",+      "reference": "C10",+      "x": 114.8214,+      "y": 70.89999999999999+    },+    {+      "id": "0ce26751-66a5-46fc-9667-16319b6ca272",+      "text": "1u",+      "reference": "C10",+      "x": 116.4956,+      "y": 70.89999999999999+    },+    {+      "id": "e48c75bb-0ab5-4644-ab2c-7a12f7fa3425",+      "text": "C4",+      "reference": "C4",+      "x": 139.8,+      "y": 60.2214+    },+    {+      "id": "872aae43-0888-4e68-878b-5a3ef3411370",+      "text": "100n",+      "reference": "C4",+      "x": 139.8,+      "y": 61.8956+    },+    {+      "id": "d2d29acf-a034-4700-bc92-9bfce9370311",+      "text": "C17",+      "reference": "C17",+      "x": 105.4,+      "y": 50.52140000000001+    },+    {+      "id": "23842641-22bb-43fc-9735-17d2d53557b3",+      "text": "100n",+      "reference": "C17",+      "x": 105.4,+      "y": 52.195600000000006+    },+    {+      "id": "e84e6605-1e48-437f-ab0e-7f52ea7c6fe7",+      "text": "U5",+      "reference": "U5",+      "x": 145.0,+      "y": 89.0+    },+    {+      "id": "7ef4efc8-2ea0-479e-a812-fad5b6d3a2df",+      "text": "D2",+      "reference": "D2",+      "x": 113.6,+      "y": 59.2+    },+    {+      "id": "9464800d-b47f-471b-b34a-b623588f80a5",+      "text": "R9",+      "reference": "R9",+      "x": 122.8,+      "y": 73.6314+    },+    {+      "id": "ae3983f7-fc55-4231-aeba-b605d17f18ae",+      "text": "5.6k",+      "reference": "R9",+      "x": 122.8,+      "y": 75.3056+    },+    {+      "id": "0f9230cf-6012-483f-bf75-24e51b601cf5",+      "text": "R17",+      "reference": "R17",+      "x": 121.2857145,+      "y": 54.4+    },+    {+      "id": "0b4d6a53-0ad2-4c11-8888-8b667dda4415",+      "text": "10k",+      "reference": "R17",+      "x": 118.3676185,+      "y": 54.4+    },+    {+      "id": "b6a73111-fe5f-442a-b9fb-ff2d7460ecec",+      "text": "C14",+      "reference": "C14",+      "x": 140.4,+      "y": 72.8214+    },+    {+      "id": "ed81dec8-814e-4b00-aff5-00b1068e904a",+      "text": "100n",+      "reference": "C14",+      "x": 140.4,+      "y": 74.4956+    },+    {+      "id": "22eb5ed0-d0ed-4318-a63b-3d3c040895d1",+      "text": "TP2",+      "reference": "TP2",+      "x": 107.6214,+      "y": 80.8+    },+    {+      "id": "ed6ac02a-0756-4661-8c3c-d089335369c7",+      "text": "LOAD+",+      "reference": "TP2",+      "x": 109.2956,+      "y": 80.8+    },+    {+      "id": "3a697338-725f-4624-be1c-4d6af3c92988",+      "text": "C12",+      "reference": "C12",+      "x": 109.39999999999999,+      "y": 62.8214+    },+    {+      "id": "a126ee1a-f086-4e75-88d7-580d41d42319",+      "text": "100n",+      "reference": "C12",+      "x": 109.39999999999999,+      "y": 64.4956+    },+    {+      "id": "36c1813a-9077-46c0-829a-4579b7dd9533",+      "text": "TP1",+      "reference": "TP1",+      "x": 103.2,+      "y": 80.0214+    },+    {+      "id": "e66dc3dc-ff6e-45d2-b3b0-06141cc38ff8",+      "text": "DUT+",+      "reference": "TP1",+      "x": 103.2,+      "y": 81.6956+    },+    {+      "id": "bef0020a-5d9a-4a2c-ae60-47f96ee6453f",+      "text": "R32",+      "reference": "R32",+      "x": 147.57139999999998,+      "y": 48.5+    },+    {+      "id": "2974dff9-0fdb-4fba-b81d-39a454a78904",+      "text": "0",+      "reference": "R32",+      "x": 149.2456,+      "y": 48.5+    },+    {+      "id": "0332fa0e-84df-413a-8195-d9ba305ee77d",+      "text": "U4",+      "reference": "U4",+      "x": 140.2,+      "y": 77.0+    },+    {+      "id": "1c1774ea-ab9e-41b2-b2e3-de4315dd557f",+      "text": "D1",+      "reference": "D1",+      "x": 114.0,+      "y": 91.0+    },+    {+      "id": "675116f4-7fc6-45bf-b350-676aced5db5b",+      "text": "R29",+      "reference": "R29",+      "x": 151.8,+      "y": 34.1214+    },+    {+      "id": "635fa6c3-87d9-4c56-ae6b-fb6857973a5b",+      "text": "4.7k",+      "reference": "R29",+      "x": 151.8,+      "y": 35.7956+    },+    {+      "id": "7027eb85-866d-4820-963c-8576c2097191",+      "text": "J11",+      "reference": "J11",+      "x": 157.4,+      "y": 58.2214+    },+    {+      "id": "af136e0b-2dd7-4bfd-b598-5d6e083deba8",+      "text": "SWD",+      "reference": "J11",+      "x": 157.4,+      "y": 59.8956+    },+    {+      "id": "525f4335-9380-409b-87cd-824c32e140cd",+      "text": "TP9",+      "reference": "TP9",+      "x": 102.0,+      "y": 86.82140000000001+    },+    {+      "id": "bb8178c3-4626-4f66-9619-0e7224bef732",+      "text": "HW_OK",+      "reference": "TP9",+      "x": 102.0,+      "y": 88.49560000000001+    },+    {+      "id": "ba65eddb-4486-4a5f-a93b-bf76f4484247",+      "text": "Q2",+      "reference": "Q2",+      "x": 124.5,+      "y": 85.3+    },+    {+      "id": "e153cfdd-8b29-4076-a243-1aa00cb0f851",+      "text": "C11",+      "reference": "C11",+      "x": 134.8,+      "y": 41.821400000000004+    },+    {+      "id": "ad80a6c3-036c-45ce-a75a-ae6f9ff48027",+      "text": "100n",+      "reference": "C11",+      "x": 134.8,+      "y": 43.4956+    },+    {+      "id": "36b7becd-7638-4bb7-a317-1fe22399af8b",+      "text": "R27",+      "reference": "R27",+      "x": 115.3,+      "y": 65.6214+    },+    {+      "id": "a66715a8-b608-4408-a2fa-9e2c7084794e",+      "text": "1k",+      "reference": "R27",+      "x": 115.3,+      "y": 67.2956+    },+    {+      "id": "e7a9b2d5-15c5-47c6-ac91-28fc3d8c69b1",+      "text": "R15",+      "reference": "R15",+      "x": 149.4,+      "y": 55.6214+    },+    {+      "id": "624193d4-aaf6-409d-a3b3-d6ad5cb5fa8e",+      "text": "10k",+      "reference": "R15",+      "x": 149.4,+      "y": 57.2956+    },+    {+      "id": "fad9bde0-faeb-449b-b7e0-7ee058a1ee3c",+      "text": "C13",+      "reference": "C13",+      "x": 130.4,+      "y": 88.9214+    },+    {+      "id": "8772cbde-61cd-4b8f-9975-f6c40e811c6c",+      "text": "100n",+      "reference": "C13",+      "x": 130.4,+      "y": 90.5956+    },+    {+      "id": "3e21f264-356b-4222-be8d-c96adb536154",+      "text": "D4",+      "reference": "D4",+      "x": 151.5,+      "y": 94.0+    },+    {+      "id": "55ed9ae5-17bd-461e-8b2b-25dccca3db4b",+      "text": "Q3",+      "reference": "Q3",+      "x": 120.30000000000001,+      "y": 81.5+    },+    {+      "id": "cbe74337-6184-429d-9af8-f1e27c5a3b69",+      "text": "R6",+      "reference": "R6",+      "x": 135.1214,+      "y": 83.2+    },+    {+      "id": "ccbb2a50-e74f-4539-9412-aace74222144",+      "text": "100k",+      "reference": "R6",+      "x": 136.7956,+      "y": 83.2+    },+    {+      "id": "a6d9bae0-f618-46cb-b2da-f49eeac5f82a",+      "text": "C2",+      "reference": "C2",+      "x": 132.499999,+      "y": 81.9214+    },+    {+      "id": "f26b8afd-af4c-450d-8958-4cca000284a8",+      "text": "1n",+      "reference": "C2",+      "x": 132.499999,+      "y": 83.5956+    },+    {+      "id": "f6e2fbfe-cd19-4e7a-8583-847fa9b91828",+      "text": "R7",+      "reference": "R7",+      "x": 128.32139999999998,+      "y": 84.4+    },+    {+      "id": "94413533-3792-4a47-a9e6-ac5f8b78a779",+      "text": "1k",+      "reference": "R7",+      "x": 129.9956,+      "y": 84.4+    },+    {+      "id": "eaa070f1-a862-4292-af73-ebca864ff834",+      "text": "J7",+      "reference": "J7",+      "x": 144.0,+      "y": 96.12140000000001+    },+    {+      "id": "c4568312-029e-49ca-9b1d-f3a5ed27309f",+      "text": "GND",+      "reference": "J7",+      "x": 144.0,+      "y": 97.79560000000001+    },+    {+      "id": "b470adc5-c141-4721-abf1-1314e87f65b4",+      "text": "J8",+      "reference": "J8",+      "x": 158.905,+      "y": 42.2214+    },+    {+      "id": "2fc6ba38-4f3f-478c-8ba8-d30b03f5d92c",+      "text": "USB",+      "reference": "J8",+      "x": 158.905,+      "y": 43.8956+    },+    {+      "id": "8703bb3a-bc8f-43ad-8dc0-b2bdb06c89ae",+      "text": "TP5",+      "reference": "TP5",+      "x": 103.6,+      "y": 83.42139999999999+    },+    {+      "id": "9baea1cc-d598-4ebf-8c08-eba1d40d7a31",+      "text": "GATE",+      "reference": "TP5",+      "x": 103.6,+      "y": 85.09559999999999+    },+    {+      "id": "578ecb61-fd8d-45d4-b8d1-a447f7cfc1f8",+      "text": "C7",+      "reference": "C7",+      "x": 151.9214,+      "y": 89.5+    },+    {+      "id": "8d420cde-6846-4853-bcb7-9e6b197f0ba4",+      "text": "4.7u 10V",+      "reference": "C7",+      "x": 153.5956,+      "y": 89.5+    },+    {+      "id": "50c47466-44f4-4d9f-b95c-1077f0358c68",+      "text": "R35",+      "reference": "R35",+      "x": 149.6,+      "y": 85.4214+    },+    {+      "id": "1fe66289-dbba-42d1-93e8-9eb429fbd028",+      "text": "680k",+      "reference": "R35",+      "x": 149.6,+      "y": 87.0956+    },+    {+      "id": "828fdbb1-d543-4229-b8eb-ff804959f411",+      "text": "R18",+      "reference": "R18",+      "x": 124.4857145,+      "y": 58.800000000000004+    },+    {+      "id": "0021bf60-b7bd-4eac-82d7-bee8c7c2f4d6",+      "text": "10k",+      "reference": "R18",+      "x": 121.56761850000001,+      "y": 58.800000000000004+    },+    {+      "id": "4037f427-fe1f-4608-956e-244fdc6ce1fa",+      "text": "TP10",+      "reference": "TP10",+      "x": 105.6214,+      "y": 88.4+    },+    {+      "id": "230aafea-5cf7-433a-99ff-a006a5aaa2c6",+      "text": "LATCH",+      "reference": "TP10",+      "x": 107.2956,+      "y": 88.4+    },+    {+      "id": "c7b13515-bd5f-4051-86bf-866330b0085a",+      "text": "TP8",+      "reference": "TP8",+      "x": 100.0,+      "y": 78.4214+    },+    {+      "id": "865430cf-c774-4990-ad13-504b0e8dd57e",+      "text": "TEMP",+      "reference": "TP8",+      "x": 100.0,+      "y": 80.0956+    },+    {+      "id": "cdb189ae-0894-4a77-b451-8627b858624b",+      "text": "U7",+      "reference": "U7",+      "x": 111.0,+      "y": 49.0+    },+    {+      "id": "abdd61f2-33a2-4ff5-9d97-1ecf86085156",+      "text": "L1",+      "reference": "L1",+      "x": 144.0,+      "y": 92.0214+    },+    {+      "id": "6eb48913-801e-490c-9443-3bcbc23effe3",+      "text": "10uH",+      "reference": "L1",+      "x": 144.0,+      "y": 93.6956+    },+    {+      "id": "2801e5f6-130c-42ee-9325-b6797b9a488a",+      "text": "TP12",+      "reference": "TP12",+      "x": 103.2,+      "y": 66.8214+    },+    {+      "id": "65781e73-da6c-435f-80a7-41f26dc4eb86",+      "text": "TACH",+      "reference": "TP12",+      "x": 103.2,+      "y": 68.4956+    },+    {+      "id": "bdd73698-3ecd-44bc-a4f7-f0ba1aa3beef",+      "text": "C8",+      "reference": "C8",+      "x": 152.6,+      "y": 66.62140000000001+    },+    {+      "id": "b84562eb-3a91-49d3-b6b4-21e0174f768f",+      "text": "1u",+      "reference": "C8",+      "x": 152.6,+      "y": 68.29560000000001+    },+    {+      "id": "614c343b-ad03-4b9c-aebe-bc07f362f8b3",+      "text": "J1",+      "reference": "J1",+      "x": 108.0,+      "y": 96.12140000000001+    },+    {+      "id": "c0c408f3-8cad-47be-8d49-fbfeb20d40e3",+      "text": "DUT+",+      "reference": "J1",+      "x": 108.0,+      "y": 97.79560000000001+    },+    {+      "id": "5346ec91-96ee-458e-8322-c017e9bc106d",+      "text": "ADOM ELECTRONIC LOAD",+      "reference": null,+      "x": 129,+      "y": 33.8+    },+    {+      "id": "de2d7865-1994-44eb-adf4-0d959bc647d1",+      "text": "R0 PROTOTYPE - 2026-10",+      "reference": null,+      "x": 129,+      "y": 36.1+    },+    {+      "id": "6a1a2a94-243d-4bd4-a832-2c9e113c9af8",+      "text": "wiki.adom.inc/adom/adom-custom-electronic-load",+      "reference": null,+      "x": 129,+      "y": 38.1+    }+  ],+  "nativeGraphicIds": [+    "bdbf3801-97af-4485-a0fd-3c6308a7374c",+    "9416a8d1-e0a6-4fbf-b71d-ecd57a132c20",+    "de268751-1bba-4ba5-a032-1639973f922b",+    "88c917a6-969a-46be-a344-c73d1235e424",+    "bfecd1d8-1080-42a8-abb1-e1f4ecb5bc89",+    "91dc10c7-0b57-4d72-993d-3117a66fdd9d",+    "584e494f-b1e6-4fab-bf3a-3009e2c9aeda",+    "e2a214f7-299d-43d4-ab2a-7675a94e6b2e",+    "8d2c27e0-ee70-4711-bcb1-ecfb51ae0127",+    "34f3cce9-4fb0-44ae-a7f3-98436c109e41",+    "608036d8-20c2-4f37-9cf9-15b3881d3ff1",+    "cd6d1654-590b-459f-aaa0-6e063179a656",+    "32f0270e-f5ec-461a-ab87-628521adf7b7",+    "e27de8d9-56a0-49c1-94db-0e79632f79bf",+    "8a2d7ee1-d851-4ff6-af27-e3762e1737f9",+    "e6b2c0cb-f985-4412-9651-632027b79854",+    "4dbeb26a-d53a-4c54-b51d-f41cfa2ac4cd",+    "74d518c8-a523-42e2-ac7f-efa070ec2885",+    "0835d33a-6c98-46fa-b82e-bb4271a55d4c",+    "2605640f-fdfa-4a6c-8450-57147a4e148f",+    "cfff0c57-2aa0-467d-93ac-25d7c18966e1",+    "ae0d5a90-da9c-46ac-b43c-ad36d6c7049f",+    "173e08d3-2d9d-42d0-b370-8cb82962d882",+    "a21a41f2-41e6-4317-9e3a-677157b3ec81",+    "26eebab5-da93-4bfe-86be-7c4a8cbc0cf9",+    "dd1082b0-c63e-4b2f-ac4a-83232abed184",+    "6a4b8fa7-8f01-4e27-b8c8-dbec8e9d9b70",+    "eb3c0b6e-d51e-4faf-9650-045f1dd7b444",+    "e42dab4f-28f6-486a-b46a-4f2df217029a",+    "57f82af6-7fba-4638-bc8d-e676a2a8aeb7",+    "58e96c38-96b6-4bd4-af4d-0703ec661471",+    "ae4a847b-ae14-46d6-ab5f-b0dd62638361",+    "c24efd29-3970-426d-9aa9-98f26ad83fb5",+    "288f5bd9-de2b-4078-a49f-57d26785a70b",+    "597f640a-ce48-4fe4-8e3c-95fe3aa00b18",+    "36792d8f-beaf-4c0e-ad2d-6d5a3c3e0216",+    "9b7fb325-fe8e-4aea-b59c-153026fd8da5",+    "7429b615-3bb9-41cc-9201-f0775140bad6",+    "462e5058-6470-44cc-929a-c30ef3120292",+    "7e10ba5c-ffec-4cda-a9c7-4a82b1e3881f",+    "5cba7977-6891-4513-aa9c-875951f03b2f",+    "8217af64-4f68-400e-b122-16ab54257536",+    "ff165d2b-b9ed-4de0-b1ea-d8fc44b9ae30",+    "e2641d51-ba56-4678-85cd-844f24445f31",+    "ab36d8f5-df50-4c61-99bf-b118ba5f6d0a",+    "f31eba63-90cb-433c-81a2-a3f2820458ba",+    "a9d73bcc-b17f-4f04-acbc-f2b38b4493ba",+    "ac4ce486-efa4-46a5-8f5b-20c6072e371d",+    "7a976432-2d12-48b2-a8b2-b7c4a00ae59f",+    "ac5f8ccf-6fb4-4c56-8578-806afd712e1e",+    "253f1f2e-1f8a-46d8-8804-32487b3e0282",+    "decef083-ed42-411b-873f-31b90ef0edb8",+    "fd655b90-a5b3-4390-b3f0-02ca268b2c81",+    "95dae861-5622-495e-82b1-628fb9bb941a",+    "7e667b7a-839c-4e70-b15f-23483ac0e68f",+    "34aacedb-73fc-4b80-bec0-731a3181b10f",+    "a22e7e72-db01-4459-8f5e-4d6bf41ba85c",+    "6c8a08af-855f-4f41-947b-ff0cd9b5eb94",+    "7e8ee9ca-02c6-496d-8c2b-563582207afc",+    "d024c908-ed27-411c-b6b1-62bf02348d41",+    "f9aa717e-76d5-47fd-888d-e7367dfcd28d",+    "7d378c10-6703-470d-906a-b501c3879096",+    "bd052ee4-ce0a-4b8b-85b2-8cbc843c3042",+    "1f36d8da-c68c-4350-8924-1b9fcdfb52bb",+    "c17eef0d-086f-45f9-b5ef-9541c6f9f8c0",+    "886f4d46-34e7-4e02-8ed9-e785eb9dc816",+    "df26a175-d9b9-4f3f-bacf-92264b261449",+    "07ecf8e9-93ff-40eb-96f1-b4d58cf22ac6",+    "ec3f0685-0e53-47e8-9a25-e20c3292aa5c",+    "111275bf-4e43-42df-8cc7-79b45385d099",+    "d8fe4676-371a-4fd2-a20b-4a267411b53c",+    "97285cb7-a7b8-49e3-84d8-85b07cda101c",+    "21634dde-cefb-47e6-b693-6de9dc078364",+    "548834f2-d061-41b7-88dc-e7ff85338b70",+    "de1fea01-b71b-498e-9242-3bc4bb94d179",+    "a384b36a-de7c-47f6-bd66-3c3d570d17c6",+    "fcb4f13e-fde2-4cea-ab28-0978f534e616",+    "8a63af6c-ad4f-44b2-9427-e22dd07e8341",+    "0c6128d3-39f1-401d-9647-454615aec894",+    "e19a614e-8295-4c3a-a0ec-88aac78720b3",+    "6eb21bb4-94d0-4584-84ed-1e621f67ee05",+    "37ae869c-1cc3-4494-90df-00363b37c2d9",+    "cc475362-2659-4f54-bb96-546919d522a0",+    "02a15cda-9fcc-49fb-a9dc-f5fb354be037",+    "1f614d60-6f72-4c91-a63c-58123facc4c5",+    "a450bce6-79e7-4b53-a298-df15108c39cb",+    "03239249-493b-4662-9316-b683e7699973",+    "2b0ead6f-cafe-42f9-a2ca-5343556fc6d5",+    "4a5d6f5a-2729-4c01-9380-15b07b6fda41",+    "94c4d1f9-3653-4526-b017-605f150789ab",+    "daea8152-d109-41b2-b869-c07c1793ed85",+    "4c08c3cb-cde4-46b0-bf6c-c22421164970"+  ],+  "nativeDRCStillRequired": false,+  "normalizationNote": "Eight pre-existing Reference coordinates below 1e-12 mm serialized to zero; no pad, component placement or copper change",+  "nativeDRC": "bottom-landed-drc.json"+}
design/silkscreen-review/front-contacts/front-contact-candidate.pngadded
⋯ 1 unchanged line ⋯
design/silkscreen-review/front-contacts/front-contact-drc.jsonadded+36
@@ -0,0 +1,36 @@+{
+    "$schema": "https://schemas.kicad.org/drc.v1.json",
+    "coordinate_units": "mm",
+    "date": "2026-10-10T18:42:37",
+    "ignored_checks": [
+        {
+            "description": "Footprint has no courtyard defined",
+            "key": "missing_courtyard"
+        },
+        {
+            "description": "Track endpoint not centered on via",
+            "key": "track_not_centered_on_via"
+        },
+        {
+            "description": "Tuning profile track geometries",
+            "key": "tuning_profile_track_geometries"
+        },
+        {
+            "description": "Footprint doesn't match symbol's footprint filters",
+            "key": "footprint_filters_mismatch"
+        },
+        {
+            "description": "Footprint component type doesn't match footprint pads",
+            "key": "footprint_type_mismatch"
+        }
+    ],
+    "included_severities": [
+        "error",
+        "warning"
+    ],
+    "kicad_version": "10.0.5",
+    "schematic_parity": [],
+    "source": "front-contact-candidate.kicad_pcb",
+    "unconnected_items": [],
+    "violations": []
+}
design/silkscreen-review/front-contacts/landing-verification.jsonadded+24
@@ -0,0 +1,24 @@+{+  "status": "native saved board matches reviewed candidate",+  "savedSha256": "8827e2f804ff0e02766d40287416d814f66fbfa2780483ebdccd983adcb1ed26",+  "sourceSha256": "44678abfa0219151ce08165da98ae669f30fca88391411b0f66ecd91adc65189",+  "candidateSha256": "8827e2f804ff0e02766d40287416d814f66fbfa2780483ebdccd983adcb1ed26",+  "comparison": "Full parsed root content; order-independent root nodes; numeric formatting normalized to 1 nm",+  "addedTexts": 22,+  "addedGraphics": 58,+  "referenceMove": {+    "reference": "J8",+    "before": [+      158.905,+      36.755+    ],+    "after": [+      156.5,+      36.755+    ]+  },+  "circuitAndCopperUnchanged": true,+  "nativeRevision": "8ad5cf23aeb0d12845a382355905c713d28f877ba8c5d1127534893ec4c45fed",+  "nativeDrcPending": false,+  "nativeDrc": "front-contact-drc.json; identical checked and live-saved PCB bytes"+}
docs/clips/bottom-silkscreen-native.jpgadded
⋯ 1 unchanged line ⋯
docs/clips/bottom-silkscreen-native.mp4added
⋯ 1 unchanged line ⋯
docs/clips/opaque-silkscreen.jpgadded
⋯ 1 unchanged line ⋯
docs/clips/opaque-silkscreen.mp4added
⋯ 1 unchanged line ⋯
docs/silkscreen-review.md+13−1
@@ -1,3 +1,15 @@+# Native bottom artwork — board23++Board23 adds 193 bottom text items and 92 graphic segments through the native KiCad API. It includes every component reference, paired passive values, physical contact functions, eleven contact/corner tags, nine association leaders, and the prototype title/date/wiki address. Seven bottom contact tags share the same width; TX/RX are from the load's perspective and 5V identifies the auxiliary supply. Reference/value groups use 1.0/0.8 mm text, with 0.9/0.8 mm corner tags and 0.8 mm IC references. Frame interruptions keep ink off holes, pads and text; retained outlines exceed 70 percent. No other part's pad is enclosed.++The complete candidate and the saved native result both pass project-aware DRC with zero violations and zero open connections. [Saved readback verification](../design/silkscreen-review/bottom-landing-verification.json) checks every added text/line against the plan and preserves all electrical geometry. Eight pre-existing reference coordinates below 1e-12 mm merely serialize to zero. [Native DRC](../design/silkscreen-review/bottom-landed-drc.json) · [Native bottom render](../design/silkscreen-review/bottom-candidate-bottom.png).++[Watch the native labels and frames appear, 2×](clips/bottom-silkscreen-native.mp4). This is an edited native inspection recording, not a smooth hero render. Its raw recorder timing warning is retained in the inventory; it is not wall-clock measurement evidence.++Current PCB SHA-256: `44678abfa0219151ce08165da98ae669f30fca88391411b0f66ecd91adc65189`. Native revision: `25980cc31b2260d0b2fc8398099daf04610124dc10670d4dd0fa0f953b7f4d5c`.++Full silkscreen acceptance remains open while front contact-function labels and fitted-cooling visibility are checked. Thermal and finished-copper dependencies remain open. Historical board22 evidence follows.+ # Native reference-label rework  AIFlow board 22 changes 48 reference-field positions or orientations. All other parsed board data is identical to v85, including pads, components, tracks, vias, zones, nets and rules. The candidate passed desktop KiCad 10.0.5 DRC with zero errors, warnings and open connections. Native top 3D and PCB views were inspected after reopening; R31/R32 clear the MCU pads, the test labels are separated, and R38 is vertical beside its resistor. This is an intermediate silkscreen improvement, not final board acceptance.@@ -12,6 +24,6 @@ Evidence: [byte-preserving candidate comparison](../design/silkscreen-review/sav  Board SHA-256: `82c2fad50b3c2fb93b627df4a984bf7fe85724d73367e33e3d97206e0b752342`. Reopened native revision: `f9a4b7701329a2d162dcc584c0c176d7926b7d24f47dc484fae85319848b1f02`. -Still incomplete: passive values, bottom identity, physical terminal/function labeling, complete artwork/leader audit and visibility with the cooling assembly fitted. A separate mirrored bottom reference/value proposal is being solved at the current project's minimum 0.8 mm text height; it is not on the board. Thermal and finished-copper dependencies remain open. Current/thermal reports are being regenerated for the new exact board file.+Still incomplete: passive values, bottom identity, physical terminal/function labeling, complete artwork/leader audit and visibility with the cooling assembly fitted. A separate mirrored bottom reference/value proposal is being solved at the current project's minimum 0.8 mm text height; it is not on the board. Thermal and finished-copper dependencies remain open. Exact-board22 current screening passes at assumed 35 µm surface / 25 µm barrel copper; thermal screening still fails. Results are in `design/silkscreen-review/fields-board22-0p1/fields.json`.  The short [candidate replay](clips/silkscreen-candidate-replay.mp4) shows recorded solver events from an earlier pass with one unresolved label; it is explicitly labeled REPLAY. The [native review](clips/silkscreen-native-review.mp4) shows the reopened board at 2×, without the cooling assembly. Neither is the final narrated film.
docs/status.md+16−2
@@ -1,8 +1,22 @@-## Latest: checked native reference-label rework+## Current saved board: revision 24++Front contact identities are now present on both faces. Native DRC: zero violations and zero unconnected pads. Saved PCB SHA-256 `8827e2f804ff0e02766d40287416d814f66fbfa2780483ebdccd983adcb1ed26`. Circuit and copper unchanged; J8 reference moved clear of the corner tag. Exact-revision Fields checks and digital-twin refresh are running. Thermal qualification remains open.++Video inventory: 97 raw takes, 40 reviewed excerpts; 35 narrated storyboard drafts await human review. The newest recorded material correction restores opaque physical silkscreen without moving geometry.++## Latest: board23 bottom artwork landed and verified++The native board now includes 193 bottom text items and 92 graphic segments: reference/value groups, contact tags, association lines and the prototype identity/wiki address. Exact saved readback matches the reviewed candidate; native project DRC reports zero violations and zero opens. Tracks, vias, zones, nets, pads and component placements are unchanged. [Evidence and native recording](silkscreen-review.md).++The exact-board23 current screen passes under the assumed 35 µm surface / 25 µm barrel copper. Thermal screening still fails; installed cooling and physical qualification remain open. Front contact-function legends are being checked separately before final silkscreen acceptance. The digital-twin export is being refreshed. Firmware remains locked and unflashed.++Video inventory: 96 raw native takes, 39 reviewed excerpts, 35 storyboard candidates, and two separately labeled solver-event recordings (one reviewed excerpt, one superseded proposal). All 35 storyboard candidates have draft narration; selection, human clip review and final assembly remain unfinished.++## Previous: checked native reference-label rework  AIFlow board 22 contains 48 improved reference labels. Exact non-field board data is preserved; native project DRC is zero errors, warnings and opens. Reopened native PCB and top/bottom 3D views were reviewed. The live field API refused and rolled back; the successful path was an explicitly recorded saved-file replacement. See [silkscreen evidence](silkscreen-review.md). Bottom reference/value groups and full silkscreen acceptance remain unfinished. -Inventory: 95 raw native takes, 38 reviewed excerpts, 34 storyboard candidates and one separately identified solver-event replay. Final narration/assembly remain unfinished. Thermal is still step 13/19; exact-board Fields checks are running. Finished copper, installed cooling and calibrated sensor margin remain unresolved; firmware stays locked.+Inventory: 95 raw native takes, 38 reviewed excerpts, 34 storyboard candidates and one separately identified solver-event replay. All 34 scene candidates have draft narration; human review, final selection and assembly remain unfinished. Thermal is still step 13/19; exact-board current screening passes at assumed 35 µm surface copper; board-only thermal screening fails. Finished copper, installed cooling and calibrated sensor margin remain unresolved; firmware stays locked.  ## Latest: native net review and temperature measurement margin 
kicad/adom-custom-electronic-load.kicad_pcb+3326−9
@@ -6539,7 +6539,7 @@ 		(descr "Resistor SMD 0402 (1005 Metric), square (rectangular) end terminal, IPC-7351 nominal, (Body size source: IPC-SM-782 page 72, https://www.pcb-3d.com/wordpress/wp-content/uploads/ipc-sm-782a_amendment_1_and_2.pdf)")
 		(tags "resistor")
 		(property "Reference" "R31"
-			(at 3.42901104e-16 2.8 0)
+			(at 0 2.8 0)
 			(layer "F.SilkS")
 			(uuid "7547689d-f002-4c97-98bd-6f29e8a04cbc")
 			(effects
@@ -8521,7 +8521,7 @@ 		(descr "Capacitor SMD 0603 (1608 Metric), square (rectangular) end terminal, IPC-7351 nominal, (Body size source: IPC-SM-782 page 76, https://www.pcb-3d.com/wordpress/wp-content/uploads/ipc-sm-782a_amendment_1_and_2.pdf)")
 		(tags "capacitor")
 		(property "Reference" "C5"
-			(at -1.78186109e-16 -1.455 0)
+			(at 0 -1.455 0)
 			(layer "F.SilkS")
 			(uuid "dba04e31-9229-4466-8eb7-9e8a0cab01c6")
 			(effects
@@ -9031,7 +9031,7 @@ 		(descr "Resistor SMD 0402 (1005 Metric), square (rectangular) end terminal, IPC-7351 nominal, (Body size source: IPC-SM-782 page 72, https://www.pcb-3d.com/wordpress/wp-content/uploads/ipc-sm-782a_amendment_1_and_2.pdf)")
 		(tags "resistor")
 		(property "Reference" "R16"
-			(at -2.455 -1.50325395e-16 0)
+			(at -2.455 0 0)
 			(layer "F.SilkS")
 			(uuid "c37e5998-7426-4b8b-b779-2138e4963060")
 			(effects
@@ -13258,7 +13258,7 @@ 		(descr "Capacitor SMD 0603 (1608 Metric), square (rectangular) end terminal, IPC-7351 nominal, (Body size source: IPC-SM-782 page 76, https://www.pcb-3d.com/wordpress/wp-content/uploads/ipc-sm-782a_amendment_1_and_2.pdf)")
 		(tags "capacitor")
 		(property "Reference" "C9"
-			(at -3.005 1.84003182e-16 0)
+			(at -3.005 0 0)
 			(layer "F.SilkS")
 			(uuid "0c9fa42d-e6d5-452a-9edb-bc3abf640fe7")
 			(effects
@@ -13598,7 +13598,7 @@ 		(descr "Capacitor SMD 0603 (1608 Metric), square (rectangular) end terminal, IPC-7351 nominal, (Body size source: IPC-SM-782 page 76, https://www.pcb-3d.com/wordpress/wp-content/uploads/ipc-sm-782a_amendment_1_and_2.pdf)")
 		(tags "capacitor")
 		(property "Reference" "C4"
-			(at -3.00650667e-16 -2.454999 0)
+			(at 0 -2.454999 0)
 			(layer "F.SilkS")
 			(uuid "19129045-73b3-488b-812a-d5095866eb72")
 			(effects
@@ -13938,7 +13938,7 @@ 		(descr "SOT, 5 Pin (JEDEC MO-178 Var AA https://www.jedec.org/document_search?search_api_views_fulltext=MO-178)")
 		(tags "SOT TO_SOT_SMD")
 		(property "Reference" "U5"
-			(at -3.65 4.46996082e-16 0)
+			(at -3.65 0 0)
 			(layer "F.SilkS")
 			(uuid "43d14d2f-8bad-43f5-abd8-5a463b26be8b")
 			(effects
@@ -14344,7 +14344,7 @@ 		(descr "SOD-323")
 		(tags "SOD-323")
 		(property "Reference" "D2"
-			(at 6.21508251e-16 5.075 0)
+			(at 0 5.075 0)
 			(layer "F.SilkS")
 			(uuid "af860ae5-b6eb-4305-8e51-c195525ee135")
 			(effects
@@ -15727,7 +15727,7 @@ 		(at 141 77 180)
 		(descr "TI DGS0010A land pattern 4221984/A 05/2015: pads 1.45 x 0.30, row centers 4.4, pitch 0.5 mm. AI-authored from manufacturer drawing.")
 		(property "Reference" "U4"
-			(at -4.83735486e-16 -3.95 0)
+			(at 0 -3.95 0)
 			(layer "F.SilkS")
 			(uuid "152bf4a5-e958-4c93-a7e3-5d07cfe67710")
 			(effects
@@ -19224,7 +19224,7 @@ 		(descr "USB 2.0 Type C Receptacle, GCT, 16P, top mounted, horizontal, 5A: https://gct.co/files/drawings/usb4105.pdf")
 		(tags "USB C Type-C Receptacle SMD USB 2.0 16P 16C USB4105-15-A USB4105-15-A-060 USB4105-15-A-120 USB4105-GF-A USB4105-GF-A-060 USB4105-GF-A-120")
 		(property "Reference" "J8"
-			(at 6.245 0 0)
+			(at 6.245 -2.405 0)
 			(unlocked yes)
 			(layer "F.SilkS")
 			(uuid "cb64989a-bf4a-42a5-9e22-261b87e2006f")
@@ -21453,6 +21453,926 @@ 			)
 		)
 	)
+	(gr_line
+		(start 98.4 31.4)
+		(end 99.4 30.4)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "bdbf3801-97af-4485-a0fd-3c6308a7374c")
+	)
+	(gr_line
+		(start 98.4 33.954578)
+		(end 98.4 31.4)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "9416a8d1-e0a6-4fbf-b71d-ecd57a132c20")
+	)
+	(gr_line
+		(start 98.4 37.5)
+		(end 98.4 35.488222)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "de268751-1bba-4ba5-a032-1639973f922b")
+	)
+	(gr_line
+		(start 98.4 94.5)
+		(end 98.4 94.954578)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "88c917a6-969a-46be-a344-c73d1235e424")
+	)
+	(gr_line
+		(start 98.4 96.488222)
+		(end 98.4 100.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "bfecd1d8-1080-42a8-abb1-e1f4ecb5bc89")
+	)
+	(gr_line
+		(start 98.4 100.6)
+		(end 99.4 101.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "91dc10c7-0b57-4d72-993d-3117a66fdd9d")
+	)
+	(gr_line
+		(start 99.4 30.4)
+		(end 101.6 30.4)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "584e494f-b1e6-4fab-bf3a-3009e2c9aeda")
+	)
+	(gr_line
+		(start 99.4 101.6)
+		(end 101.6 101.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "e2a214f7-299d-43d4-ab2a-7675a94e6b2e")
+	)
+	(gr_line
+		(start 101.6 30.4)
+		(end 101.6 33.954578)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "8d2c27e0-ee70-4711-bcb1-ecfb51ae0127")
+	)
+	(gr_line
+		(start 101.6 35.488222)
+		(end 101.6 37.5)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "34f3cce9-4fb0-44ae-a7f3-98436c109e41")
+	)
+	(gr_line
+		(start 101.6 37.5)
+		(end 98.4 37.5)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "608036d8-20c2-4f37-9cf9-15b3881d3ff1")
+	)
+	(gr_line
+		(start 101.6 94.5)
+		(end 98.4 94.5)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "cd6d1654-590b-459f-aaa0-6e063179a656")
+	)
+	(gr_line
+		(start 101.6 94.954578)
+		(end 101.6 94.5)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "32f0270e-f5ec-461a-ab87-628521adf7b7")
+	)
+	(gr_line
+		(start 101.6 101.6)
+		(end 101.6 96.488222)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "e27de8d9-56a0-49c1-94db-0e79632f79bf")
+	)
+	(gr_line
+		(start 106.1 94.9)
+		(end 109.9 94.9)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "8a2d7ee1-d851-4ff6-af27-e3762e1737f9")
+	)
+	(gr_line
+		(start 106.1 101.6)
+		(end 106.1 94.9)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "e6b2c0cb-f985-4412-9651-632027b79854")
+	)
+	(gr_line
+		(start 109.9 94.9)
+		(end 109.9 101.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "4dbeb26a-d53a-4c54-b51d-f41cfa2ac4cd")
+	)
+	(gr_line
+		(start 109.9 101.6)
+		(end 106.1 101.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "74d518c8-a523-42e2-ac7f-efa070ec2885")
+	)
+	(gr_line
+		(start 110.1 94.9)
+		(end 113.9 94.9)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "0835d33a-6c98-46fa-b82e-bb4271a55d4c")
+	)
+	(gr_line
+		(start 110.1 101.6)
+		(end 110.1 94.9)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "2605640f-fdfa-4a6c-8450-57147a4e148f")
+	)
+	(gr_line
+		(start 112 66.9)
+		(end 113.9 66.9)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "cfff0c57-2aa0-467d-93ac-25d7c18966e1")
+	)
+	(gr_line
+		(start 113.9 66.9)
+		(end 113.9 67)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "ae0d5a90-da9c-46ac-b43c-ad36d6c7049f")
+	)
+	(gr_line
+		(start 113.9 94.9)
+		(end 113.9 101.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "173e08d3-2d9d-42d0-b370-8cb82962d882")
+	)
+	(gr_line
+		(start 113.9 101.6)
+		(end 110.1 101.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "a21a41f2-41e6-4317-9e3a-677157b3ec81")
+	)
+	(gr_line
+		(start 116.7 52.9)
+		(end 116.7 56.5)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "26eebab5-da93-4bfe-86be-7c4a8cbc0cf9")
+	)
+	(gr_line
+		(start 116.7 56.5)
+		(end 116.8 56.5)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "dd1082b0-c63e-4b2f-ac4a-83232abed184")
+	)
+	(gr_line
+		(start 116.8 56.5)
+		(end 116.8 56.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "6a4b8fa7-8f01-4e27-b8c8-dbec8e9d9b70")
+	)
+	(gr_line
+		(start 116.8 56.6)
+		(end 117.1 56.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "eb3c0b6e-d51e-4faf-9650-045f1dd7b444")
+	)
+	(gr_line
+		(start 116.8 74)
+		(end 117.3 74)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "e42dab4f-28f6-486a-b46a-4f2df217029a")
+	)
+	(gr_line
+		(start 117 53.6)
+		(end 117 55.2)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "57f82af6-7fba-4638-bc8d-e676a2a8aeb7")
+	)
+	(gr_line
+		(start 117 55.2)
+		(end 119 55.2)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "58e96c38-96b6-4bd4-af4d-0703ec661471")
+	)
+	(gr_line
+		(start 117.1 56.6)
+		(end 117.1 56.8)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "ae4a847b-ae14-46d6-ab5f-b0dd62638361")
+	)
+	(gr_line
+		(start 117.4 57.1)
+		(end 117.4 59.1)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "c24efd29-3970-426d-9aa9-98f26ad83fb5")
+	)
+	(gr_line
+		(start 117.5 55.5)
+		(end 117.5 57.1)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "288f5bd9-de2b-4078-a49f-57d26785a70b")
+	)
+	(gr_line
+		(start 117.5 57.1)
+		(end 117.4 57.1)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "597f640a-ce48-4fe4-8e3c-95fe3aa00b18")
+	)
+	(gr_line
+		(start 118 64)
+		(end 118 62.4)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "36792d8f-beaf-4c0e-ad2d-6d5a3c3e0216")
+	)
+	(gr_line
+		(start 118.1 94.9)
+		(end 121.9 94.9)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "9b7fb325-fe8e-4aea-b59c-153026fd8da5")
+	)
+	(gr_line
+		(start 118.1 101.6)
+		(end 118.1 94.9)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "7429b615-3bb9-41cc-9201-f0775140bad6")
+	)
+	(gr_line
+		(start 118.9 53)
+		(end 118.9 53.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "462e5058-6470-44cc-929a-c30ef3120292")
+	)
+	(gr_line
+		(start 118.9 53.6)
+		(end 117 53.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "7e10ba5c-ffec-4cda-a9c7-4a82b1e3881f")
+	)
+	(gr_line
+		(start 119 52.9)
+		(end 119 53)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "5cba7977-6891-4513-aa9c-875951f03b2f")
+	)
+	(gr_line
+		(start 119 53)
+		(end 118.9 53)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "8217af64-4f68-400e-b122-16ab54257536")
+	)
+	(gr_line
+		(start 119 55.2)
+		(end 119 60)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "ff165d2b-b9ed-4de0-b1ea-d8fc44b9ae30")
+	)
+	(gr_line
+		(start 119.5 64)
+		(end 118 64)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "e2641d51-ba56-4678-85cd-844f24445f31")
+	)
+	(gr_line
+		(start 119.5 66.7)
+		(end 119.5 64)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "ab36d8f5-df50-4c61-99bf-b118ba5f6d0a")
+	)
+	(gr_line
+		(start 119.6 52.9)
+		(end 119 52.9)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "f31eba63-90cb-433c-81a2-a3f2820458ba")
+	)
+	(gr_line
+		(start 119.6 53)
+		(end 119.6 52.9)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "a9d73bcc-b17f-4f04-acbc-f2b38b4493ba")
+	)
+	(gr_line
+		(start 119.7 53)
+		(end 119.6 53)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "ac4ce486-efa4-46a5-8f5b-20c6072e371d")
+	)
+	(gr_line
+		(start 119.7 53.4)
+		(end 119.7 53)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "7a976432-2d12-48b2-a8b2-b7c4a00ae59f")
+	)
+	(gr_line
+		(start 120.6 61.5)
+		(end 120.6 61.3)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "ac5f8ccf-6fb4-4c56-8578-806afd712e1e")
+	)
+	(gr_line
+		(start 120.8 77.1)
+		(end 120.8 75.4)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "253f1f2e-1f8a-46d8-8804-32487b3e0282")
+	)
+	(gr_line
+		(start 121.9 94.9)
+		(end 121.9 101.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "decef083-ed42-411b-873f-31b90ef0edb8")
+	)
+	(gr_line
+		(start 121.9 101.6)
+		(end 118.1 101.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "fd655b90-a5b3-4390-b3f0-02ca268b2c81")
+	)
+	(gr_line
+		(start 122.1 94.9)
+		(end 125.9 94.9)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "95dae861-5622-495e-82b1-628fb9bb941a")
+	)
+	(gr_line
+		(start 122.1 101.6)
+		(end 122.1 94.9)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "7e667b7a-839c-4e70-b15f-23483ac0e68f")
+	)
+	(gr_line
+		(start 122.2 61.5)
+		(end 120.6 61.5)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "34aacedb-73fc-4b80-bec0-731a3181b10f")
+	)
+	(gr_line
+		(start 122.9 53.4)
+		(end 119.7 53.4)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "a22e7e72-db01-4459-8f5e-4d6bf41ba85c")
+	)
+	(gr_line
+		(start 122.9 53.5)
+		(end 122.9 53.4)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "6c8a08af-855f-4f41-947b-ff0cd9b5eb94")
+	)
+	(gr_line
+		(start 123 53.5)
+		(end 122.9 53.5)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "7e8ee9ca-02c6-496d-8c2b-563582207afc")
+	)
+	(gr_line
+		(start 123 54.2)
+		(end 123 53.5)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "d024c908-ed27-411c-b6b1-62bf02348d41")
+	)
+	(gr_line
+		(start 123.3 54.2)
+		(end 123 54.2)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "f9aa717e-76d5-47fd-888d-e7367dfcd28d")
+	)
+	(gr_line
+		(start 125.9 94.9)
+		(end 125.9 101.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "7d378c10-6703-470d-906a-b501c3879096")
+	)
+	(gr_line
+		(start 125.9 101.6)
+		(end 122.1 101.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "bd052ee4-ce0a-4b8b-85b2-8cbc843c3042")
+	)
+	(gr_line
+		(start 134.1 94.9)
+		(end 137.9 94.9)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "1f36d8da-c68c-4350-8924-1b9fcdfb52bb")
+	)
+	(gr_line
+		(start 134.1 101.6)
+		(end 134.1 94.9)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "c17eef0d-086f-45f9-b5ef-9541c6f9f8c0")
+	)
+	(gr_line
+		(start 137.9 94.9)
+		(end 137.9 100.479)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "886f4d46-34e7-4e02-8ed9-e785eb9dc816")
+	)
+	(gr_line
+		(start 137.9 101.121)
+		(end 137.9 101.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "df26a175-d9b9-4f3f-bacf-92264b261449")
+	)
+	(gr_line
+		(start 137.9 101.6)
+		(end 134.1 101.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "07ecf8e9-93ff-40eb-96f1-b4d58cf22ac6")
+	)
+	(gr_line
+		(start 138.1 94.9)
+		(end 141.9 94.9)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "ec3f0685-0e53-47e8-9a25-e20c3292aa5c")
+	)
+	(gr_line
+		(start 138.1 100.479)
+		(end 138.1 94.9)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "111275bf-4e43-42df-8cc7-79b45385d099")
+	)
+	(gr_line
+		(start 138.1 101.6)
+		(end 138.1 101.121)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "d8fe4676-371a-4fd2-a20b-4a267411b53c")
+	)
+	(gr_line
+		(start 141.9 94.9)
+		(end 141.9 101.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "97285cb7-a7b8-49e3-84d8-85b07cda101c")
+	)
+	(gr_line
+		(start 141.9 101.6)
+		(end 138.1 101.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "21634dde-cefb-47e6-b693-6de9dc078364")
+	)
+	(gr_line
+		(start 142.1 94.9)
+		(end 145.9 94.9)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "548834f2-d061-41b7-88dc-e7ff85338b70")
+	)
+	(gr_line
+		(start 142.1 101.6)
+		(end 142.1 94.9)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "de1fea01-b71b-498e-9242-3bc4bb94d179")
+	)
+	(gr_line
+		(start 145.9 94.9)
+		(end 145.9 101.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "a384b36a-de7c-47f6-bd66-3c3d570d17c6")
+	)
+	(gr_line
+		(start 145.9 101.6)
+		(end 142.1 101.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "fcb4f13e-fde2-4cea-ab28-0978f534e616")
+	)
+	(gr_line
+		(start 149.1 65.4)
+		(end 149.1 62.7)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "8a63af6c-ad4f-44b2-9427-e22dd07e8341")
+	)
+	(gr_line
+		(start 158.4 30.4)
+		(end 158.4 33.31413)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "0c6128d3-39f1-401d-9647-454615aec894")
+	)
+	(gr_line
+		(start 158.4 34.847774)
+		(end 158.4 37.5)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "e19a614e-8295-4c3a-a0ec-88aac78720b3")
+	)
+	(gr_line
+		(start 158.4 37.5)
+		(end 161.6 37.5)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "6eb21bb4-94d0-4584-84ed-1e621f67ee05")
+	)
+	(gr_line
+		(start 158.4 94.5)
+		(end 161.6 94.5)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "37ae869c-1cc3-4494-90df-00363b37c2d9")
+	)
+	(gr_line
+		(start 158.4 94.954578)
+		(end 158.4 94.5)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "cc475362-2659-4f54-bb96-546919d522a0")
+	)
+	(gr_line
+		(start 158.4 101.6)
+		(end 158.4 96.488222)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "02a15cda-9fcc-49fb-a9dc-f5fb354be037")
+	)
+	(gr_line
+		(start 160.6 30.4)
+		(end 158.4 30.4)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "1f614d60-6f72-4c91-a63c-58123facc4c5")
+	)
+	(gr_line
+		(start 160.6 101.6)
+		(end 158.4 101.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "a450bce6-79e7-4b53-a298-df15108c39cb")
+	)
+	(gr_line
+		(start 161.6 31.4)
+		(end 160.6 30.4)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "03239249-493b-4662-9316-b683e7699973")
+	)
+	(gr_line
+		(start 161.6 33.31413)
+		(end 161.6 31.4)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "2b0ead6f-cafe-42f9-a2ca-5343556fc6d5")
+	)
+	(gr_line
+		(start 161.6 37.5)
+		(end 161.6 34.847774)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "4a5d6f5a-2729-4c01-9380-15b07b6fda41")
+	)
+	(gr_line
+		(start 161.6 94.5)
+		(end 161.6 94.954578)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "94c4d1f9-3653-4526-b017-605f150789ab")
+	)
+	(gr_line
+		(start 161.6 96.488222)
+		(end 161.6 100.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "daea8152-d109-41b2-b869-c07c1793ed85")
+	)
+	(gr_line
+		(start 161.6 100.6)
+		(end 160.6 101.6)
+		(stroke
+			(width 0.12)
+			(type solid)
+		)
+		(layer "B.SilkS")
+		(uuid "4c08c3cb-cde4-46b0-bf6c-c22421164970")
+	)
 	(gr_line
 		(start 98 32)
 		(end 98 100)
@@ -21548,6 +22468,2322 @@ 			)
 		)
 	)
+	(gr_text "GND"
+		(at 100 36.3371 0)
+		(layer "B.SilkS")
+		(uuid "47e41a75-2735-46e1-877c-3385ed51bb27")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "TEMP"
+		(at 100 80.0956 0)
+		(layer "B.SilkS")
+		(uuid "865430cf-c774-4990-ad13-504b0e8dd57e")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "GND"
+		(at 100 97.3371 0)
+		(layer "B.SilkS")
+		(uuid "6b6a112c-7ad9-4fb3-96c3-423c36fa02c6")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "TEMP"
+		(at 101.2 73.4956 0)
+		(layer "B.SilkS")
+		(uuid "a554257a-37fc-46ce-823b-d3dcfe0a1dc6")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "HW_OK"
+		(at 102 88.4956 0)
+		(layer "B.SilkS")
+		(uuid "bb8178c3-4626-4f66-9619-0e7224bef732")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "TACH"
+		(at 103.2 68.4956 0)
+		(layer "B.SilkS")
+		(uuid "65781e73-da6c-435f-80a7-41f26dc4eb86")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "DUT+"
+		(at 103.2 81.6956 0)
+		(layer "B.SilkS")
+		(uuid "e66dc3dc-ff6e-45d2-b3b0-06141cc38ff8")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "GATE"
+		(at 103.6 85.0956 0)
+		(layer "B.SilkS")
+		(uuid "9baea1cc-d598-4ebf-8c08-eba1d40d7a31")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "SH-"
+		(at 105.2 64.8956 0)
+		(layer "B.SilkS")
+		(uuid "387466cf-9c7b-47e5-b100-1120f2f3e8d3")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "100n"
+		(at 105.4 52.1956 0)
+		(layer "B.SilkS")
+		(uuid "23842641-22bb-43fc-9735-17d2d53557b3")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "5 A 32 V fast fuse"
+		(at 106.4 93.0956 0)
+		(layer "B.SilkS")
+		(uuid "ab2375ee-98ec-40bf-9a23-761d3879bf98")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "VDRV"
+		(at 107.6 85.4956 0)
+		(layer "B.SilkS")
+		(uuid "e9ce98b8-7869-45cc-b673-f446f272245a")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "DUT+"
+		(at 108 97.7956 0)
+		(layer "B.SilkS")
+		(uuid "c0c408f3-8cad-47be-8d49-fbfeb20d40e3")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "100n"
+		(at 109.4 64.4956 0)
+		(layer "B.SilkS")
+		(uuid "a126ee1a-f086-4e75-88d7-580d41d42319")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "U7"
+		(at 111 49 0)
+		(layer "B.SilkS")
+		(uuid "cdb189ae-0894-4a77-b451-8627b858624b")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "3V3"
+		(at 111.6 83.8956 0)
+		(layer "B.SilkS")
+		(uuid "5d39c783-5668-469e-808f-88e4a6932cc6")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "GND"
+		(at 111.6 87.2956 0)
+		(layer "B.SilkS")
+		(uuid "e6420bc7-ee83-4214-b60a-4a721dd20165")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "SH+"
+		(at 112 80.4956 0)
+		(layer "B.SilkS")
+		(uuid "699d7265-173f-4161-bbcb-5fd85b48d450")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "GND"
+		(at 112 97.7956 0)
+		(layer "B.SilkS")
+		(uuid "bc33141a-7f20-4788-a492-4945700a8049")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "100k"
+		(at 112.8 57.6956 0)
+		(layer "B.SilkS")
+		(uuid "91a7eca1-8d77-43c6-b625-be33699ca69f")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "D2"
+		(at 113.6 59.2 0)
+		(layer "B.SilkS")
+		(uuid "7ef4efc8-2ea0-479e-a812-fad5b6d3a2df")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "D1"
+		(at 114 91 0)
+		(layer "B.SilkS")
+		(uuid "1c1774ea-ab9e-41b2-b2e3-de4315dd557f")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "100n"
+		(at 114.8 76.0956 0)
+		(layer "B.SilkS")
+		(uuid "b751282b-6371-4da4-8592-67b3db890813")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "1k"
+		(at 115.3 67.2956 0)
+		(layer "B.SilkS")
+		(uuid "a66715a8-b608-4408-a2fa-9e2c7084794e")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "1k"
+		(at 116.8 61.8956 0)
+		(layer "B.SilkS")
+		(uuid "9f7646bb-d0da-48bd-a593-3121cb992e29")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "10k"
+		(at 118.367619 54.4 0)
+		(layer "B.SilkS")
+		(uuid "0b4d6a53-0ad2-4c11-8888-8b667dda4415")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "U2"
+		(at 118.4 64.8 0)
+		(layer "B.SilkS")
+		(uuid "3c191edf-b972-41d6-b5ef-a3222da71607")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "Q4"
+		(at 118.4 77 0)
+		(layer "B.SilkS")
+		(uuid "3e537ca3-a7ae-493b-8abd-1f944f41a1b6")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "10k"
+		(at 119.967619 67.8 0)
+		(layer "B.SilkS")
+		(uuid "a294bcb2-8a73-48e1-9fb0-defe4b2d2efa")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "5V"
+		(at 120 97.7956 0)
+		(layer "B.SilkS")
+		(uuid "567828fd-a14f-4953-a443-aa188500372f")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "33k"
+		(at 121.2 71.8956 0)
+		(layer "B.SilkS")
+		(uuid "12683f29-0a33-4415-93b3-30c8806e4cb1")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "10k"
+		(at 121.567619 58.8 0)
+		(layer "B.SilkS")
+		(uuid "0021bf60-b7bd-4eac-82d7-bee8c7c2f4d6")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "1k"
+		(at 122.4 79.9156 0)
+		(layer "B.SilkS")
+		(uuid "9d72b6bd-1768-47e0-92b2-901c55fc2d36")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "5.6k"
+		(at 122.8 75.3056 0)
+		(layer "B.SilkS")
+		(uuid "ae3983f7-fc55-4231-aeba-b605d17f18ae")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "33k"
+		(at 123.167619 60.7 0)
+		(layer "B.SilkS")
+		(uuid "8f709dbe-d4af-45d8-9311-3c50b85ab99d")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "3.3k"
+		(at 123.967619 62.51 0)
+		(layer "B.SilkS")
+		(uuid "cba4c124-7779-4fe3-bbf6-a9133c45e35e")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "GND"
+		(at 124 97.7956 0)
+		(layer "B.SilkS")
+		(uuid "495abe46-8dbc-41c6-8f97-640466d18622")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "Q2"
+		(at 124.5 85.3 0)
+		(layer "B.SilkS")
+		(uuid "ba65eddb-4486-4a5f-a93b-bf76f4484247")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "100n"
+		(at 125.6 49.3956 0)
+		(layer "B.SilkS")
+		(uuid "b72c1feb-7a75-43cd-9133-c51eecec7c6d")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "100n"
+		(at 126.6 43.1956 0)
+		(layer "B.SilkS")
+		(uuid "014186d0-67fc-492d-b83a-43df10ff1f5a")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "U8"
+		(at 128 52.4 0)
+		(layer "B.SilkS")
+		(uuid "598c33e6-b434-459d-8db6-3b1dfbc7d6b5")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R0 PROTOTYPE - 2026-10"
+		(at 129 36.1 0)
+		(layer "B.SilkS")
+		(uuid "de2d7865-1994-44eb-adf4-0d959bc647d1")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "wiki.adom.inc/adom/adom-custom-electronic-load"
+		(at 129 38.1 0)
+		(layer "B.SilkS")
+		(uuid "6a1a2a94-243d-4bd4-a832-2c9e113c9af8")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "Q1"
+		(at 130 80 0)
+		(layer "B.SilkS")
+		(uuid "7de030d2-cd54-4df1-8ec6-5f47b1c9470e")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "100n"
+		(at 130.4 90.5956 0)
+		(layer "B.SilkS")
+		(uuid "8772cbde-61cd-4b8f-9975-f6c40e811c6c")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "1n"
+		(at 132.499999 83.5956 0)
+		(layer "B.SilkS")
+		(uuid "f26b8afd-af4c-450d-8958-4cca000284a8")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "100n"
+		(at 134.8 43.4956 0)
+		(layer "B.SilkS")
+		(uuid "ad80a6c3-036c-45ce-a75a-ae6f9ff48027")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "TX"
+		(at 136 97.7956 0)
+		(layer "B.SilkS")
+		(uuid "21791b50-37e9-4403-adf6-bd587edccd07")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "RX"
+		(at 139.4 97.7956 0)
+		(layer "B.SilkS")
+		(uuid "33902a4c-53f2-4d22-9329-e4ef7899f337")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "100n"
+		(at 139.8 61.8956 0)
+		(layer "B.SilkS")
+		(uuid "872aae43-0888-4e68-878b-5a3ef3411370")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "100n"
+		(at 140.4 74.4956 0)
+		(layer "B.SilkS")
+		(uuid "ed81dec8-814e-4b00-aff5-00b1068e904a")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "4.7k"
+		(at 141.4 58.4956 0)
+		(layer "B.SilkS")
+		(uuid "3bc8dc5e-2099-49e7-bde2-20556e307acb")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "100n"
+		(at 141.9 90.2956 0)
+		(layer "B.SilkS")
+		(uuid "87772828-59c6-4396-9e83-98d458e847b3")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "100k"
+		(at 142.8 65.2956 0)
+		(layer "B.SilkS")
+		(uuid "dd706367-6633-4fdc-865b-bd26c66d1b98")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "U1"
+		(at 143.8 47.4 0)
+		(layer "B.SilkS")
+		(uuid "0b477f6f-88a7-4449-b055-954add10c1d4")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "10n"
+		(at 144 85.4956 0)
+		(layer "B.SilkS")
+		(uuid "43c81f9b-9b2b-4a12-9e75-8797eaa0c50e")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "10uH"
+		(at 144 93.6956 0)
+		(layer "B.SilkS")
+		(uuid "6eb48913-801e-490c-9443-3bcbc23effe3")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "GND"
+		(at 144 97.7956 0)
+		(layer "B.SilkS")
+		(uuid "c4568312-029e-49ca-9b1d-f3a5ed27309f")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "4.7k"
+		(at 144.6 58.4956 0)
+		(layer "B.SilkS")
+		(uuid "e75814c0-b150-4171-9f80-e38c9840a4ce")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "U5"
+		(at 145 89 0)
+		(layer "B.SilkS")
+		(uuid "e84e6605-1e48-437f-ab0e-7f52ea7c6fe7")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "D3"
+		(at 146.3 84.3 0)
+		(layer "B.SilkS")
+		(uuid "f607c3a2-82e9-461e-8830-d5955be612d2")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "100k"
+		(at 146.8 82.4956 0)
+		(layer "B.SilkS")
+		(uuid "61d1ace6-730b-4d38-acd6-48afb43cedc1")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "100k"
+		(at 148.7 95.3156 0)
+		(layer "B.SilkS")
+		(uuid "d5bc570e-7b48-4eb8-a695-ce769a20894b")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "220k"
+		(at 149.2 90.5056 0)
+		(layer "B.SilkS")
+		(uuid "141c74f7-7e7a-41fc-a8a1-ad57c38d453d")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "10k"
+		(at 149.4 57.2956 0)
+		(layer "B.SilkS")
+		(uuid "624193d4-aaf6-409d-a3b3-d6ad5cb5fa8e")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "680k"
+		(at 149.6 87.0956 0)
+		(layer "B.SilkS")
+		(uuid "1fe66289-dbba-42d1-93e8-9eb429fbd028")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "100k"
+		(at 149.8 68.1956 0)
+		(layer "B.SilkS")
+		(uuid "2b252ef0-cd76-49a8-9776-e6728edf23b6")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "10k"
+		(at 150 80.0956 0)
+		(layer "B.SilkS")
+		(uuid "57cc7992-8924-49ad-b8a2-05ed7b1126e9")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "4.7k"
+		(at 151.4 39.3956 0)
+		(layer "B.SilkS")
+		(uuid "84698045-5a80-46c8-8013-b6f74b39202b")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "D4"
+		(at 151.5 94 0)
+		(layer "B.SilkS")
+		(uuid "3e21f264-356b-4222-be8d-c96adb536154")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "4.7k"
+		(at 151.8 35.7956 0)
+		(layer "B.SilkS")
+		(uuid "635fa6c3-87d9-4c56-ae6b-fb6857973a5b")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "U10"
+		(at 151.9 44.4 0)
+		(layer "B.SilkS")
+		(uuid "80ab2aab-8017-44ca-96b6-6e362e884ce1")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "10k"
+		(at 152.6 64.8956 0)
+		(layer "B.SilkS")
+		(uuid "b45bc26e-1a5c-402c-bb1b-a9f219ee973a")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "1u"
+		(at 152.6 68.2956 0)
+		(layer "B.SilkS")
+		(uuid "b84562eb-3a91-49d3-b6b4-21e0174f768f")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "10k"
+		(at 153.2 82.0956 0)
+		(layer "B.SilkS")
+		(uuid "c23f1721-6039-4697-a6e3-5c204e6d20ba")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "10k"
+		(at 153.8 57.6956 0)
+		(layer "B.SilkS")
+		(uuid "956bdaaf-e269-4565-9baa-e51397cf9020")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "FAN"
+		(at 156.6 99.6956 0)
+		(layer "B.SilkS")
+		(uuid "e897a738-841e-4620-a802-9c54929c96d2")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "SWD"
+		(at 157.4 59.8956 0)
+		(layer "B.SilkS")
+		(uuid "af136e0b-2dd7-4bfd-b598-5d6e083deba8")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "USB"
+		(at 158.905 43.8956 0)
+		(layer "B.SilkS")
+		(uuid "2fc6ba38-4f3f-478c-8ba8-d30b03f5d92c")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "GND"
+		(at 160 36.3371 0)
+		(layer "B.SilkS")
+		(uuid "fc3e223b-d807-4057-a0cf-34021d05d360")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "GND"
+		(at 160 97.3371 0)
+		(layer "B.SilkS")
+		(uuid "e0f63387-07bf-4408-93b3-3ed9584b255c")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "ISET"
+		(at 101.2956 76 90)
+		(layer "B.SilkS")
+		(uuid "02c8734a-b884-4e67-bedb-3680562a240e")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "LATCH"
+		(at 107.2956 88.4 90)
+		(layer "B.SilkS")
+		(uuid "230aafea-5cf7-433a-99ff-a006a5aaa2c6")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "LOAD+"
+		(at 109.2956 80.8 90)
+		(layer "B.SilkS")
+		(uuid "ed6ac02a-0756-4661-8c3c-d089335369c7")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "10k"
+		(at 110.0956 57.4 90)
+		(layer "B.SilkS")
+		(uuid "0c065772-9c8f-4fc1-b6a9-6d6529497e7f")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "10k"
+		(at 110.9956 67.01 90)
+		(layer "B.SilkS")
+		(uuid "065f6879-5dac-43ac-941c-ae3e05df384e")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "100k"
+		(at 114.8956 53.8 90)
+		(layer "B.SilkS")
+		(uuid "69033484-afe8-4efa-ba50-26d496fd284d")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "1u"
+		(at 116.4956 70.9 90)
+		(layer "B.SilkS")
+		(uuid "0ce26751-66a5-46fc-9667-16319b6ca272")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "100k"
+		(at 117.6956 51 90)
+		(layer "B.SilkS")
+		(uuid "b969188a-114f-40d3-ad3e-3771517b6402")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "Q3"
+		(at 120.3 81.5 90)
+		(layer "B.SilkS")
+		(uuid "55ed9ae5-17bd-461e-8b2b-25dccca3db4b")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "10k"
+		(at 122.4956 56.6 90)
+		(layer "B.SilkS")
+		(uuid "4b9b8fdd-65ca-4340-aebd-d7266b7921e7")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "1k"
+		(at 126.0956 56.11 90)
+		(layer "B.SilkS")
+		(uuid "65b9ef64-4ffb-4772-a55a-db671cffcb39")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "U3"
+		(at 129.3 87 90)
+		(layer "B.SilkS")
+		(uuid "70f82ddf-6b64-420c-82ef-af3114e1f939")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "1k"
+		(at 129.9956 84.4 90)
+		(layer "B.SilkS")
+		(uuid "94413533-3792-4a47-a9e6-ac5f8b78a779")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "U6"
+		(at 130.2 45 90)
+		(layer "B.SilkS")
+		(uuid "db9f2b40-9f5a-4eae-9e45-b35c6ec3624a")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "10k"
+		(at 133.8956 86 90)
+		(layer "B.SilkS")
+		(uuid "13ba3fa0-8c5b-4661-a5b8-9ed983d816d2")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "100k"
+		(at 136.7956 83.2 90)
+		(layer "B.SilkS")
+		(uuid "ccbb2a50-e74f-4539-9412-aace74222144")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "100n"
+		(at 138.2956 80.2 90)
+		(layer "B.SilkS")
+		(uuid "651803be-3de3-4b2f-baec-a21b9e7b0cda")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "20m"
+		(at 140.0956 85.8 90)
+		(layer "B.SilkS")
+		(uuid "ecbc6b14-6233-4ab2-9bd2-1311489e8af2")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "U4"
+		(at 140.2 77 90)
+		(layer "B.SilkS")
+		(uuid "0332fa0e-84df-413a-8195-d9ba305ee77d")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "1u"
+		(at 145.0956 67.4 90)
+		(layer "B.SilkS")
+		(uuid "b363bc34-6c6a-4a9f-9ac2-daf1e427f9f8")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "U9"
+		(at 146.8 65 90)
+		(layer "B.SilkS")
+		(uuid "1ebdc7e7-3d33-47d2-9e7c-4c38b9ae979a")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "0"
+		(at 148.8456 45 90)
+		(layer "B.SilkS")
+		(uuid "871efff0-98df-4d53-b3ad-a9566610a642")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "0"
+		(at 149.2456 48.5 90)
+		(layer "B.SilkS")
+		(uuid "2974dff9-0fdb-4fba-b81d-39a454a78904")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "4.7u 10V"
+		(at 153.5956 89.5 90)
+		(layer "B.SilkS")
+		(uuid "8d420cde-6846-4853-bcb7-9e6b197f0ba4")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "4.7u 25V"
+		(at 159.2956 87 90)
+		(layer "B.SilkS")
+		(uuid "a57fec9d-91b0-41be-ad39-8d9ec3185481")
+		(effects
+			(font
+				(size 0.8 0.8)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "MP3"
+		(at 100 34.7214 0)
+		(layer "B.SilkS")
+		(uuid "545cb0b8-ee7a-4bb0-9da1-aad5ff3712c3")
+		(effects
+			(font
+				(size 0.9 0.9)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "MP1"
+		(at 100 95.7214 0)
+		(layer "B.SilkS")
+		(uuid "3931fd9f-3704-41b4-ba4d-0820d6fe9c37")
+		(effects
+			(font
+				(size 0.9 0.9)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "MP4"
+		(at 160 34.080952 0)
+		(layer "B.SilkS")
+		(uuid "c4016761-bcd3-442c-960b-e985094faabc")
+		(effects
+			(font
+				(size 0.9 0.9)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "MP2"
+		(at 160 95.7214 0)
+		(layer "B.SilkS")
+		(uuid "dd39f219-dfc6-4e22-84b0-ae4920e17527")
+		(effects
+			(font
+				(size 0.9 0.9)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "TP8"
+		(at 100 78.4214 0)
+		(layer "B.SilkS")
+		(uuid "c7b13515-bd5f-4051-86bf-866330b0085a")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "J10"
+		(at 101.2 71.8214 0)
+		(layer "B.SilkS")
+		(uuid "e000ee8a-bc52-4c25-b0df-937568a2b053")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "TP9"
+		(at 102 86.8214 0)
+		(layer "B.SilkS")
+		(uuid "525f4335-9380-409b-87cd-824c32e140cd")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "TP12"
+		(at 103.2 66.8214 0)
+		(layer "B.SilkS")
+		(uuid "2801e5f6-130c-42ee-9325-b6797b9a488a")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "TP1"
+		(at 103.2 80.0214 0)
+		(layer "B.SilkS")
+		(uuid "36c1813a-9077-46c0-829a-4579b7dd9533")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "TP5"
+		(at 103.6 83.4214 0)
+		(layer "B.SilkS")
+		(uuid "8703bb3a-bc8f-43ad-8dc0-b2bdb06c89ae")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "TP13"
+		(at 105.2 63.2214 0)
+		(layer "B.SilkS")
+		(uuid "9ffaa3c1-c1e0-4cc7-930a-34b1f0ba116f")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "C17"
+		(at 105.4 50.5214 0)
+		(layer "B.SilkS")
+		(uuid "d2d29acf-a034-4700-bc92-9bfce9370311")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "F1"
+		(at 106.4 91.4214 0)
+		(layer "B.SilkS")
+		(uuid "d1474e3e-9c91-484b-8f5b-7e845b892fc5")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "TP6"
+		(at 107.6 83.8214 0)
+		(layer "B.SilkS")
+		(uuid "978245b4-a87e-4c96-81b9-f36710786db0")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "J1"
+		(at 108 96.1214 0)
+		(layer "B.SilkS")
+		(uuid "614c343b-ad03-4b9c-aebe-bc07f362f8b3")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "C12"
+		(at 109.4 62.8214 0)
+		(layer "B.SilkS")
+		(uuid "3a697338-725f-4624-be1c-4d6af3c92988")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "TP7"
+		(at 111.6 82.2214 0)
+		(layer "B.SilkS")
+		(uuid "211ba1c3-14b0-41df-b7e9-9ae9072e406b")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "TP11"
+		(at 111.6 85.6214 0)
+		(layer "B.SilkS")
+		(uuid "8b66156b-2be0-4bd6-b0ef-c89e98f0ff99")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "TP3"
+		(at 112 78.8214 0)
+		(layer "B.SilkS")
+		(uuid "841d8b20-928b-41ea-b9cd-54284735deb6")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "J2"
+		(at 112 96.1214 0)
+		(layer "B.SilkS")
+		(uuid "34083472-66c1-4180-8815-5a9e9440fcd8")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R5"
+		(at 112.8 56.0214 0)
+		(layer "B.SilkS")
+		(uuid "59248331-b32b-4e75-95d2-d536de8b7ed5")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "C1"
+		(at 114.8 74.4214 0)
+		(layer "B.SilkS")
+		(uuid "7b4a5f3b-5b5c-4232-a578-57d577d5054e")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R27"
+		(at 115.3 65.6214 0)
+		(layer "B.SilkS")
+		(uuid "36b7becd-7638-4bb7-a317-1fe22399af8b")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R20"
+		(at 116.8 60.2214 0)
+		(layer "B.SilkS")
+		(uuid "ab18f66b-f865-44ad-bdf9-4b721707c288")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "J3"
+		(at 120 96.1214 0)
+		(layer "B.SilkS")
+		(uuid "c4c4df90-521b-43a3-b4fb-32cf18a2ea86")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R8"
+		(at 121.2 70.2214 0)
+		(layer "B.SilkS")
+		(uuid "dedbe019-f31a-4398-9561-6991acc3f577")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R17"
+		(at 121.285715 54.4 0)
+		(layer "B.SilkS")
+		(uuid "0f9230cf-6012-483f-bf75-24e51b601cf5")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R10"
+		(at 122.4 78.2414 0)
+		(layer "B.SilkS")
+		(uuid "a61cc4dc-8bc4-4ed9-8571-2290d2b40418")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R9"
+		(at 122.8 73.6314 0)
+		(layer "B.SilkS")
+		(uuid "9464800d-b47f-471b-b34a-b623588f80a5")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R21"
+		(at 122.885715 67.8 0)
+		(layer "B.SilkS")
+		(uuid "05dcc37d-7ebc-45f3-bcd9-1350a2445ffd")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "J4"
+		(at 124 96.1214 0)
+		(layer "B.SilkS")
+		(uuid "435aec3b-d1f4-44f8-b984-bf5cf86d8bdf")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R18"
+		(at 124.485715 58.8 0)
+		(layer "B.SilkS")
+		(uuid "828fdbb1-d543-4229-b8eb-ff804959f411")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "C18"
+		(at 125.6 47.7214 0)
+		(layer "B.SilkS")
+		(uuid "f441aa0c-3ccc-43e0-af9f-aa4227f137ba")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R22"
+		(at 126.085715 60.7 0)
+		(layer "B.SilkS")
+		(uuid "2f80655c-7583-4774-875d-58a5861692bd")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "C16"
+		(at 126.6 41.5214 0)
+		(layer "B.SilkS")
+		(uuid "bb06c29c-22bc-4d57-9885-d1bfe70ed69a")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R19"
+		(at 127.076191 62.51 0)
+		(layer "B.SilkS")
+		(uuid "00d84551-bc96-4cb7-a2c7-cd1dd6a9b365")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "C13"
+		(at 130.4 88.9214 0)
+		(layer "B.SilkS")
+		(uuid "fad9bde0-faeb-449b-b7e0-7ee058a1ee3c")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "C2"
+		(at 132.499999 81.9214 0)
+		(layer "B.SilkS")
+		(uuid "a6d9bae0-f618-46cb-b2da-f49eeac5f82a")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "C11"
+		(at 134.8 41.8214 0)
+		(layer "B.SilkS")
+		(uuid "e153cfdd-8b29-4076-a243-1aa00cb0f851")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "J5"
+		(at 136 96.1214 0)
+		(layer "B.SilkS")
+		(uuid "83be0e35-80b9-4186-aee7-2e5621e98795")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "J6"
+		(at 139.4 96.1214 0)
+		(layer "B.SilkS")
+		(uuid "eb750af0-c7b4-4d07-9d75-1eb5de61614d")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "C4"
+		(at 139.8 60.2214 0)
+		(layer "B.SilkS")
+		(uuid "e48c75bb-0ab5-4644-ab2c-7a12f7fa3425")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "C14"
+		(at 140.4 72.8214 0)
+		(layer "B.SilkS")
+		(uuid "b6a73111-fe5f-442a-b9fb-ff2d7460ecec")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R13"
+		(at 141.4 56.8214 0)
+		(layer "B.SilkS")
+		(uuid "e91428ac-17e9-4285-8b76-207af82140ae")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "C15"
+		(at 141.9 88.6214 0)
+		(layer "B.SilkS")
+		(uuid "eb75c64a-b173-4d8d-8c36-10b73faf6949")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R33"
+		(at 142.8 63.6214 0)
+		(layer "B.SilkS")
+		(uuid "a0b95823-eb82-4a0b-9403-74eaedab2acf")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "C5"
+		(at 144 83.8214 0)
+		(layer "B.SilkS")
+		(uuid "d87c0610-7b7d-48bd-b095-b49a275dfeb1")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "L1"
+		(at 144 92.0214 0)
+		(layer "B.SilkS")
+		(uuid "abdd61f2-33a2-4ff5-9d97-1ecf86085156")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "J7"
+		(at 144 96.1214 0)
+		(layer "B.SilkS")
+		(uuid "eaa070f1-a862-4292-af73-ebca864ff834")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R14"
+		(at 144.6 56.8214 0)
+		(layer "B.SilkS")
+		(uuid "30f711e9-c2a7-4666-ba73-969af02d766b")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R24"
+		(at 146.8 80.8214 0)
+		(layer "B.SilkS")
+		(uuid "aa306a90-32a6-4d37-ab97-e49e8704d4c3")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R37"
+		(at 148.7 93.6414 0)
+		(layer "B.SilkS")
+		(uuid "4c4e83e7-c2fd-4644-819a-8222b8777d10")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R36"
+		(at 149.2 88.8314 0)
+		(layer "B.SilkS")
+		(uuid "3e218a30-ab38-45d4-a384-9d186e55a412")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R15"
+		(at 149.4 55.6214 0)
+		(layer "B.SilkS")
+		(uuid "e7a9b2d5-15c5-47c6-ac91-28fc3d8c69b1")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R35"
+		(at 149.6 85.4214 0)
+		(layer "B.SilkS")
+		(uuid "50c47466-44f4-4d9f-b95c-1077f0358c68")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R34"
+		(at 149.8 66.5214 0)
+		(layer "B.SilkS")
+		(uuid "fdd29b95-1646-4f17-a50d-1623c71c053d")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R25"
+		(at 150 78.4214 0)
+		(layer "B.SilkS")
+		(uuid "a2d77bb4-aaa4-4b6e-9ea9-72dfa0d7a831")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R30"
+		(at 151.4 37.7214 0)
+		(layer "B.SilkS")
+		(uuid "22343357-1e07-480a-be59-40e30a46b497")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R29"
+		(at 151.8 34.1214 0)
+		(layer "B.SilkS")
+		(uuid "675116f4-7fc6-45bf-b350-676aced5db5b")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R38"
+		(at 152.6 63.2214 0)
+		(layer "B.SilkS")
+		(uuid "65331a26-7f60-44bc-97c7-8fdcdbe6161a")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "C8"
+		(at 152.6 66.6214 0)
+		(layer "B.SilkS")
+		(uuid "bdd73698-3ecd-44bc-a4f7-f0ba1aa3beef")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R26"
+		(at 153.2 80.4214 0)
+		(layer "B.SilkS")
+		(uuid "b17fe6f2-8c16-42b4-bd10-deb3e88c015d")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R16"
+		(at 153.8 56.0214 0)
+		(layer "B.SilkS")
+		(uuid "e68530fb-3492-49d6-850b-7f88d58356e0")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "J9"
+		(at 156.6 98.0214 0)
+		(layer "B.SilkS")
+		(uuid "cfaa1d07-d631-449c-8672-7991a6fc6d0d")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "J11"
+		(at 157.4 58.2214 0)
+		(layer "B.SilkS")
+		(uuid "7027eb85-866d-4820-963c-8576c2097191")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "J8"
+		(at 158.905 42.2214 0)
+		(layer "B.SilkS")
+		(uuid "b470adc5-c141-4721-abf1-1314e87f65b4")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "TP4"
+		(at 99.6214 76 90)
+		(layer "B.SilkS")
+		(uuid "d40ad323-afaf-429a-9c1d-7dcc14643492")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "TP10"
+		(at 105.6214 88.4 90)
+		(layer "B.SilkS")
+		(uuid "4037f427-fe1f-4608-956e-244fdc6ce1fa")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "TP2"
+		(at 107.6214 80.8 90)
+		(layer "B.SilkS")
+		(uuid "22eb5ed0-d0ed-4318-a63b-3d3c040895d1")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R1"
+		(at 108.4214 57.4 90)
+		(layer "B.SilkS")
+		(uuid "a8690b95-ec9a-4acb-bc14-8e572e0ba8a9")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R28"
+		(at 109.3214 67.01 90)
+		(layer "B.SilkS")
+		(uuid "b34bc1bc-c30f-48e5-8152-3b9ca8158499")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R2"
+		(at 113.2214 53.8 90)
+		(layer "B.SilkS")
+		(uuid "f3f71a89-2997-401a-9e73-cda483f30aa8")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "C10"
+		(at 114.8214 70.9 90)
+		(layer "B.SilkS")
+		(uuid "35e5b2db-a472-45a6-b254-833dd355e147")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R3"
+		(at 116.0214 51 90)
+		(layer "B.SilkS")
+		(uuid "6c50f5af-b3b2-4eab-bfc6-2364d65d3419")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R4"
+		(at 120.8214 56.6 90)
+		(layer "B.SilkS")
+		(uuid "1ee843a9-78a5-411e-ac66-82f0d7981920")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R23"
+		(at 124.4214 56.11 90)
+		(layer "B.SilkS")
+		(uuid "280d5180-eb24-4ccd-9d2c-2ed28f3be8ed")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R7"
+		(at 128.3214 84.4 90)
+		(layer "B.SilkS")
+		(uuid "f6e2fbfe-cd19-4e7a-8583-847fa9b91828")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R11"
+		(at 132.2214 86 90)
+		(layer "B.SilkS")
+		(uuid "2a0f5bc3-3847-4bd6-a95f-7700b25520ee")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R6"
+		(at 135.1214 83.2 90)
+		(layer "B.SilkS")
+		(uuid "cbe74337-6184-429d-9af8-f1e27c5a3b69")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "C3"
+		(at 136.6214 80.2 90)
+		(layer "B.SilkS")
+		(uuid "87b209fb-6c4e-4534-9230-0f57f1efcf79")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "RSH1"
+		(at 138.4214 85.8 90)
+		(layer "B.SilkS")
+		(uuid "9acd2dc9-5b84-47af-8160-0a678b3bb0c4")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "C9"
+		(at 143.4214 67.4 90)
+		(layer "B.SilkS")
+		(uuid "51abcd53-641a-412e-a449-f70c8c03186a")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R31"
+		(at 147.1714 45 90)
+		(layer "B.SilkS")
+		(uuid "0248fd85-e3b8-4727-9d05-1c50daba214d")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "R32"
+		(at 147.5714 48.5 90)
+		(layer "B.SilkS")
+		(uuid "bef0020a-5d9a-4a2c-ae60-47f96ee6453f")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "C7"
+		(at 151.9214 89.5 90)
+		(layer "B.SilkS")
+		(uuid "578ecb61-fd8d-45d4-b8d1-a447f7cfc1f8")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "C6"
+		(at 157.6214 87 90)
+		(layer "B.SilkS")
+		(uuid "24c2fc72-efa6-402e-a46e-e877690355d9")
+		(effects
+			(font
+				(size 1 1)
+				(thickness 0.12)
+			)
+			(justify mirror)
+		)
+	)
+	(gr_text "ADOM ELECTRONIC LOAD"
+		(at 129 33.8 0)
+		(layer "B.SilkS")
+		(uuid "5346ec91-96ee-458e-8322-c017e9bc106d")
+		(effects
+			(font
+				(size 1.2 1.2)
+				(thickness 0.15)
+			)
+			(justify mirror)
+		)
+	)
 	(segment
 		(start 104.5 85.2)
 		(end 104.3 85)
@@ -43931,4 +47167,85 @@ 		)
 	)
 	(embedded_fonts no)
++(gr_text "MP2" (at 160.000000000 95.721400000 0) (layer "F.SilkS") (uuid "ab430cb3-c333-4c96-8a48-7ec181f49008") (effects (font (size 0.9 0.9) (thickness 0.12))))+(gr_text "GND" (at 160.000000000 97.337100000 0) (layer "F.SilkS") (uuid "3724be76-b732-4f34-b87c-d8d3e1ace19c") (effects (font (size 0.8 0.8) (thickness 0.12))))+(gr_text "J6" (at 139.400000000 96.121400000 0) (layer "F.SilkS") (uuid "401f566b-c18d-46f5-a606-5124ddcb86c2") (effects (font (size 1.0 1.0) (thickness 0.12))))+(gr_text "RX" (at 139.400000000 97.795600000 0) (layer "F.SilkS") (uuid "108f5f6f-ddf0-496a-a9c9-19edf7f8f891") (effects (font (size 0.8 0.8) (thickness 0.12))))+(gr_text "MP3" (at 100.000000000 34.721400000 0) (layer "F.SilkS") (uuid "294c1856-e3f9-48aa-80e0-25077e6c0c80") (effects (font (size 0.9 0.9) (thickness 0.12))))+(gr_text "GND" (at 100.000000000 36.337100000 0) (layer "F.SilkS") (uuid "e51702a3-f069-4508-8e66-aafa7fee0448") (effects (font (size 0.8 0.8) (thickness 0.12))))+(gr_text "MP1" (at 100.000000000 95.721400000 0) (layer "F.SilkS") (uuid "997cc14e-dab6-4561-9163-800928a7526a") (effects (font (size 0.9 0.9) (thickness 0.12))))+(gr_text "GND" (at 100.000000000 97.337100000 0) (layer "F.SilkS") (uuid "65043afa-7f98-4dda-a97a-4b85b2cfb647") (effects (font (size 0.8 0.8) (thickness 0.12))))+(gr_text "J5" (at 136.000000000 96.121400000 0) (layer "F.SilkS") (uuid "76645fb7-d1d4-4d9d-abb5-ae0ebe52e962") (effects (font (size 1.0 1.0) (thickness 0.12))))+(gr_text "TX" (at 136.000000000 97.795600000 0) (layer "F.SilkS") (uuid "396791e7-5f02-4210-89c1-51e529879518") (effects (font (size 0.8 0.8) (thickness 0.12))))+(gr_text "J2" (at 112.000000000 96.121400000 0) (layer "F.SilkS") (uuid "345ac02e-74be-4438-898b-08cec9cebd53") (effects (font (size 1.0 1.0) (thickness 0.12))))+(gr_text "GND" (at 112.000000000 97.795600000 0) (layer "F.SilkS") (uuid "53875b07-002c-410d-9c4b-7f0fcf51d8ec") (effects (font (size 0.8 0.8) (thickness 0.12))))+(gr_text "J4" (at 124.000000000 96.121400000 0) (layer "F.SilkS") (uuid "3b62f36a-021e-42fc-9713-c13cf2e2bd7a") (effects (font (size 1.0 1.0) (thickness 0.12))))+(gr_text "GND" (at 124.000000000 97.795600000 0) (layer "F.SilkS") (uuid "d9654136-0bce-4474-9603-576094a934e2") (effects (font (size 0.8 0.8) (thickness 0.12))))+(gr_text "MP4" (at 160.000000000 34.721400000 0) (layer "F.SilkS") (uuid "6e046cfb-e0cd-4ed2-b1d8-8522cb2daecc") (effects (font (size 0.9 0.9) (thickness 0.12))))+(gr_text "GND" (at 160.000000000 36.337100000 0) (layer "F.SilkS") (uuid "50baca8e-9764-4713-a111-3453f25f2abd") (effects (font (size 0.8 0.8) (thickness 0.12))))+(gr_text "J3" (at 120.000000000 96.121400000 0) (layer "F.SilkS") (uuid "e43660ac-d9a9-425c-a454-f9002e336803") (effects (font (size 1.0 1.0) (thickness 0.12))))+(gr_text "5V" (at 120.000000000 97.795600000 0) (layer "F.SilkS") (uuid "1903920f-f9c8-4965-9ab8-8697b3a58559") (effects (font (size 0.8 0.8) (thickness 0.12))))+(gr_text "J7" (at 145.650000000 100.800000000 0) (layer "F.SilkS") (uuid "6239f1fd-2352-4484-86a1-bcf3000f3ff5") (effects (font (size 0.8 0.8) (thickness 0.12))))+(gr_text "GND" (at 148.000000000 100.800000000 0) (layer "F.SilkS") (uuid "48c158df-443f-48db-8292-0879f0f6520d") (effects (font (size 0.8 0.8) (thickness 0.12))))+(gr_text "J1" (at 108.000000000 96.121400000 0) (layer "F.SilkS") (uuid "ef8c3475-6178-4b87-a66f-2d9ac19163e0") (effects (font (size 1.0 1.0) (thickness 0.12))))+(gr_text "DUT+" (at 108.000000000 97.795600000 0) (layer "F.SilkS") (uuid "9e7a7f6b-e425-4671-b171-7d526068e02d") (effects (font (size 0.8 0.8) (thickness 0.12))))+(gr_line (start 138.100000000 98.800000000) (end 141.900000000 98.800000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "9b13cfe9-a368-4993-8a08-13c1dc0d107d"))+(gr_line (start 141.900000000 98.800000000) (end 141.900000000 101.600000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "553a07ae-19fd-49cd-9e98-49c1d2febc5b"))+(gr_line (start 141.900000000 101.600000000) (end 138.100000000 101.600000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "7c73440d-265c-479d-85f0-9292370dc1db"))+(gr_line (start 138.100000000 101.600000000) (end 138.100000000 101.121000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "c4f76776-cc74-4dc0-8dae-476f9c538abb"))+(gr_line (start 138.100000000 100.479000000) (end 138.100000000 98.800000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "c95d51e7-e12d-4871-96da-9650d0ed8e0b"))+(gr_line (start 134.100000000 98.800000000) (end 137.900000000 98.800000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "7c543a2a-1ec7-49b9-9d51-f27e9c056c48"))+(gr_line (start 137.900000000 98.800000000) (end 137.900000000 100.479000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "9eb71929-83f2-47e5-8133-25c01e4b4da3"))+(gr_line (start 137.900000000 101.121000000) (end 137.900000000 101.600000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "299be50b-1193-4056-9596-cf2ab57b215a"))+(gr_line (start 137.900000000 101.600000000) (end 134.100000000 101.600000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "a96f1fa1-bae2-4539-8a4c-23ba5844cff1"))+(gr_line (start 134.100000000 101.600000000) (end 134.100000000 98.800000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "a64829e1-1c50-42b0-b9af-c2d3bd26be1f"))+(gr_line (start 110.100000000 98.800000000) (end 113.900000000 98.800000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "29a5f471-a741-4048-ae61-aeb703ecd3cc"))+(gr_line (start 113.900000000 98.800000000) (end 113.900000000 101.600000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "07962236-46c9-4968-8e3c-b110a67efd22"))+(gr_line (start 113.900000000 101.600000000) (end 110.100000000 101.600000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "0aed9386-95a0-43fd-9e35-7b6637624504"))+(gr_line (start 110.100000000 101.600000000) (end 110.100000000 98.800000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "22bc6bf0-d024-4856-a34d-3127a1994b34"))+(gr_line (start 122.100000000 98.800000000) (end 125.900000000 98.800000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "de974377-ebd7-44f4-ad1a-1cb97c76791c"))+(gr_line (start 125.900000000 98.800000000) (end 125.900000000 101.600000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "a7064868-2eed-4853-ad43-b36dfcaf6893"))+(gr_line (start 125.900000000 101.600000000) (end 122.100000000 101.600000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "4653fabc-e5e5-4e0b-8072-792196febfa4"))+(gr_line (start 122.100000000 101.600000000) (end 122.100000000 98.800000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "f9498df9-400d-4621-8091-8b65f879ed33"))+(gr_line (start 118.100000000 98.800000000) (end 121.900000000 98.800000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "83711693-5fe0-477e-a2ca-34c594be5c88"))+(gr_line (start 121.900000000 98.800000000) (end 121.900000000 101.600000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "efdb6977-b811-4ea0-8137-711cc4372b7a"))+(gr_line (start 121.900000000 101.600000000) (end 118.100000000 101.600000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "a0c6bb6c-88cc-499d-9cbf-21d44709541b"))+(gr_line (start 118.100000000 101.600000000) (end 118.100000000 98.800000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "91626f82-89b3-4787-b3ec-80fef099edc3"))+(gr_line (start 142.100000000 98.800000000) (end 145.900000000 98.800000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "d30160a0-5223-495a-8b9d-9541e59c3f90"))+(gr_line (start 145.900000000 98.800000000) (end 145.900000000 100.000400000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "f1ff289c-4342-4101-ac12-cda470864076"))+(gr_line (start 145.900000000 101.600000000) (end 142.100000000 101.600000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "123c4652-1bf7-43cd-b054-7abac8bcd860"))+(gr_line (start 142.100000000 101.600000000) (end 142.100000000 98.800000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "b4fd5d68-d537-4d4c-830e-961ac377949a"))+(gr_line (start 106.100000000 98.800000000) (end 109.900000000 98.800000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "326663bd-9066-4474-9316-c98810fe4af0"))+(gr_line (start 109.900000000 98.800000000) (end 109.900000000 101.600000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "b4bf6e99-f331-4e84-9882-23eb69d746c9"))+(gr_line (start 109.900000000 101.600000000) (end 106.100000000 101.600000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "c89c2a5b-2a0c-474a-9a00-f0b0ba601a21"))+(gr_line (start 106.100000000 101.600000000) (end 106.100000000 98.800000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "ad1e275a-c64c-4670-8847-9ee2a8557aac"))+(gr_line (start 160.600000000 101.600000000) (end 158.400000000 101.600000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "8b771b75-b534-475d-b9b6-9f1ea29fb55e"))+(gr_line (start 158.400000000 101.600000000) (end 158.400000000 96.488222091) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "95082a2e-ae68-461f-9907-b5b7e704d42a"))+(gr_line (start 158.400000000 94.954577909) (end 158.400000000 94.500000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "24108f0b-487d-4a0c-8222-980742bacdc2"))+(gr_line (start 158.400000000 94.500000000) (end 161.600000000 94.500000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "d0e242f3-cb8c-4f4a-81b9-1917efe8b6b0"))+(gr_line (start 161.600000000 94.500000000) (end 161.600000000 94.954577909) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "54259e83-1a74-49d3-ae67-08163cd124ad"))+(gr_line (start 161.600000000 96.488222091) (end 161.600000000 100.600000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "c35f0916-ea79-438e-bdfe-af8d094b95b7"))+(gr_line (start 161.600000000 100.600000000) (end 160.600000000 101.600000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "15c9977e-9a93-4abf-9659-2f6a28c641d5"))+(gr_line (start 99.400000000 30.400000000) (end 101.600000000 30.400000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "2453e4cd-f6df-4c52-bd6c-3b5dafcae132"))+(gr_line (start 101.600000000 30.400000000) (end 101.600000000 33.954577909) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "094ebd64-580b-4a2a-b317-da807d79b734"))+(gr_line (start 101.600000000 35.488222091) (end 101.600000000 37.500000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "517c4e0b-13c3-4720-bcb6-58159b45d74b"))+(gr_line (start 101.600000000 37.500000000) (end 98.400000000 37.500000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "7c017829-cd17-4a03-ab1f-ad4b1cd3f333"))+(gr_line (start 98.400000000 37.500000000) (end 98.400000000 35.488222091) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "0ca78bb3-1581-4513-bc8c-1f75cb440530"))+(gr_line (start 98.400000000 33.954577909) (end 98.400000000 31.400000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "c0431388-afd2-4701-9de5-7f5c260b0dad"))+(gr_line (start 98.400000000 31.400000000) (end 99.400000000 30.400000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "45ce6422-7eda-445f-af08-c9e11d49074d"))+(gr_line (start 99.400000000 101.600000000) (end 101.600000000 101.600000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "2a40842b-eea6-4616-b2da-31c2aa022394"))+(gr_line (start 101.600000000 101.600000000) (end 101.600000000 96.488222091) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "ebdb87f8-43be-4120-b7dd-bd3472da7107"))+(gr_line (start 101.600000000 94.954577909) (end 101.600000000 94.500000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "8c0638a3-af00-456b-ab46-70fd1c05ebdf"))+(gr_line (start 101.600000000 94.500000000) (end 98.400000000 94.500000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "13c03639-f185-487f-bc61-58c28b1cc9c8"))+(gr_line (start 98.400000000 94.500000000) (end 98.400000000 94.954577909) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "eccfc018-9663-4ee6-ba4a-adaa802c4411"))+(gr_line (start 98.400000000 96.488222091) (end 98.400000000 100.600000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "c0c812bd-985a-4fb3-9144-1dce8a31781e"))+(gr_line (start 98.400000000 100.600000000) (end 99.400000000 101.600000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "780cb91d-dd1a-4096-a5b6-b0d00b48ffdc"))+(gr_line (start 160.600000000 30.400000000) (end 158.400000000 30.400000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "6f84a44d-48f1-41b3-8364-3b411667b73c"))+(gr_line (start 158.400000000 30.400000000) (end 158.400000000 33.954577909) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "2caca4d7-b723-4085-a40b-a0a3447c9715"))+(gr_line (start 158.400000000 35.488222091) (end 158.400000000 37.500000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "20bb8fe1-2165-47a6-856a-73fb8a49e772"))+(gr_line (start 158.400000000 37.500000000) (end 161.600000000 37.500000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "6ebca35b-d482-4848-ae35-b7cc8c48c00f"))+(gr_line (start 161.600000000 37.500000000) (end 161.600000000 35.488222091) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "d42ee504-9358-4cc0-8bd6-05cb2d62a948"))+(gr_line (start 161.600000000 33.954577909) (end 161.600000000 31.400000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "9f0e4f5e-c185-489a-96e8-fa770ebf2e69"))+(gr_line (start 161.600000000 31.400000000) (end 160.600000000 30.400000000) (stroke (width 0.12) (type solid)) (layer "F.SilkS") (uuid "867865ab-599e-420e-a574-24e43b06c3a5")) )
tools/alternate_bottom_groups.pyadded+17
@@ -0,0 +1,17 @@+#!/usr/bin/env python3+"""Add compact side-by-side alternatives from the same native glyph extents."""+import json,copy+from pathlib import Path+p=Path(__file__).resolve().parents[1]/'design/silkscreen-review/bottom-candidates.json';s=json.loads(p.read_text());count=0+for g in s['labels']:+ if g['id'] not in ['R'+str(n) for n in range(17,24)]:continue+ original=[c for c in g['candidates'] if c['children'][0].get('angle',0)==0 and not c.get('inline')]+ for t in original:+  if len(t['children'])!=2:continue+  c=copy.deepcopy(t);x,y=c['position'];widths=[z['box'][2]-z['box'][0] for z in c['children']];total=sum(widths)+.2+  # From below, larger X is to the left: reference precedes value.+  centers=[x+total/2-widths[0]/2,x-total/2+widths[1]/2]+  for child,cx in zip(c['children'],centers):+   b=child['box'];dx=cx-(b[0]+b[2])/2;dy=y-(b[1]+b[3])/2;child['x']+=dx;child['y']+=dy;child['box']=[b[0]+dx,b[1]+dy,b[2]+dx,b[3]+dy]+  c['boxes']=[z['box'] for z in c['children']];b=c['boxes'];c['box']=[min(z[0] for z in b),min(z[1] for z in b),max(z[2] for z in b),max(z[3] for z in b)];c['inline']=True;c['qualityPenalty']=.05;g['candidates'].append(c);count+=1+s['candidatesPerLabel']=5000;s['milpPerFont']=256;p.write_text(json.dumps(s)+'\n');print('Added',count,'native-metric inline alternatives')
tools/bottom_artwork_review.pyadded+41
@@ -0,0 +1,41 @@+#!/usr/bin/env python3+"""Build and independently check complete bottom text, tags and association lines."""+import json,hashlib,math+from pathlib import Path+from shapely.geometry import box,LineString,Point+from shapely.ops import unary_union+P=Path(__file__).resolve().parents[1]/'design/silkscreen-review'+s=json.loads((P/'bottom-candidates.json').read_text());l=json.loads((P/'bottom-layout.json').read_text());assert not l['unresolved']+texts=[c for g in l['placements'] for c in g['children']]+json.loads((P/'bottom-identity.json').read_text())['texts']+physical=[(o['id'],box(*o['box'])) for o in s['obstacles'] if o['kind'] not in ['association-target','contact-frame']]+textshapes=[box(*t['box']) for t in texts];findings=[]+for i,(t,b) in enumerate(zip(texts,textshapes)):+ if not box(*s['bounds']).covers(b):findings.append(dict(kind='text-outside',text=t['text']))+ for name,o in physical:+  if b.distance(o)<.119:findings.append(dict(kind='text-physical',text=t['text'],obstacle=name,distance=b.distance(o)))+ for j in range(i):+  if b.distance(textshapes[j])<.119:findings.append(dict(kind='text-pair',texts=[t['text'],texts[j]['text']],distance=b.distance(textshapes[j])))+obstacles=unary_union([p for _,p in physical]+textshapes);graphics=[];framechecks=[]+for f in json.loads((P/'bottom-contact-tags.json').read_text())['frames']+json.loads((P/'bottom-corner-tags.json').read_text())['frames']:+ if f['kind']=='rect':+  (x,y),(X,Y)=f['points'];pts=[[x,y],[X,y],[X,Y],[x,Y],[x,y]]+ else:pts=f['points']+ original=LineString(pts);clipped=original.difference(obstacles.buffer(.121));lines=list(clipped.geoms) if hasattr(clipped,'geoms') else [clipped];kept=sum(a.length for a in lines);ratio=kept/original.length+ framechecks.append(dict(reference=f['reference'],retainedFraction=ratio,originalLengthMm=original.length))+ if ratio<.7:findings.append(dict(kind='frame-too-broken',reference=f['reference'],retainedFraction=ratio))+ area=__import__('shapely.geometry',fromlist=['Polygon']).Polygon(pts)+ for o in s['obstacles']:+  if o['kind']=='pad-mask-or-hole' and o.get('reference')!=f['reference'] and area.contains(box(*o['box']).representative_point()):findings.append(dict(kind='frame-encloses-other-pad',reference=f['reference'],obstacle=o['id']))+ for line in lines:+  coords=list(line.coords)+  for a,b in zip(coords,coords[1:]):+   if math.dist(a,b)>.02:graphics.append(dict(kind='line',layer='B.SilkS',points=[list(a),list(b)],stroke=.12,reference=f['reference'],role='frame'))+leaders=json.loads((P/'bottom-leaders.json').read_text());assert not leaders['unresolved'];assert leaders['layoutSha256']==hashlib.sha256((P/'bottom-layout.json').read_bytes()).hexdigest()+for lead in leaders['leaders']:+ # Preserve the audited orthogonal paths here. Rounded alternatives are a separate refinement.+ for a,b in zip(lead['points'],lead['points'][1:]):graphics.append(dict(kind='line',layer='B.SilkS',points=[a,b],stroke=.12,reference=lead['reference'],role='leader'))+for g in graphics:+ line=LineString(g['points']);distance=line.distance(obstacles)+ if distance<.119:findings.append(dict(kind='graphic-obstacle',reference=g['reference'],distance=distance))+result=dict(status='candidate-only',boardSha256=s['boardSha256'],nativeRevision=s['nativeRevision'],texts=texts,graphics=graphics,frameChecks=framechecks,findings=findings,limits=['Native DRC and render review still required.','Association leaders point to projections of front-side components, not exposed bottom pads.'])+(P/'bottom-artwork.json').write_text(json.dumps(result,indent=2)+'\n');print(json.dumps(dict(texts=len(texts),graphics=len(graphics),findings=findings,frames=framechecks),indent=2));raise SystemExit(2 if findings else 0)
tools/bottom_association_targets.pyadded+25
@@ -0,0 +1,25 @@+#!/usr/bin/env python3+"""Reserve explicit projected-body endpoints before solving bottom labels."""+import json,math+from pathlib import Path+import numpy as np+from shapely.geometry import Point,box+from shapely.ops import unary_union+ROOT=Path(__file__).resolve().parents[1];P=ROOT/'design/silkscreen-review'+spec=json.loads((P/'bottom-candidates.json').read_text());layout=json.loads((P/'bottom-layout.json').read_text())+bodies={r['ref']:r['boundsMm'] for r in json.loads((ROOT/'mechanical/cooling-680-body-audit.json').read_text())['rows']}+anchors={g['id']:g['anchor'] for g in spec['labels']};physical=unary_union([box(*o['box']) for o in spec['obstacles'] if o['kind']!='association-target'])+targets=[]+for g in layout['placements']:+    if math.dist(g['position'],anchors[g['id']])<=3.5:continue+    b=bodies[g['id']];q=[b[0],b[1],b[3],b[4]];candidates=[]+    for x in np.arange(math.ceil((q[0]-98.3)*10),math.floor((q[2]-98.3)*10)+1):+        for y in np.arange(math.ceil((q[1]-30.3)*10),math.floor((q[3]-30.3)*10)+1):+            p=[float(98.3+x*.1),float(30.3+y*.1)];clear=physical.distance(Point(p))+            if clear>=.24:candidates.append((math.dist(p,g['position']),-clear,p))+    if not candidates:raise RuntimeError('No physical-clearance endpoint for '+g['id'])+    _,negative_clear,p=min(candidates);targets.append(dict(reference=g['id'],point=p,bodyProjection=q,physicalClearanceMm=-negative_clear))+spec['obstacles']=[o for o in spec['obstacles'] if o['kind']!='association-target']+for t in targets:+    x,y=t['point'];spec['obstacles'].append(dict(id='target:'+t['reference'],reference=t['reference'],kind='association-target',layer='B.SilkS',box=[x-.2,y-.2,x+.2,y+.2]))+(P/'bottom-association-targets.json').write_text(json.dumps(targets,indent=2)+'\n');(P/'bottom-candidates.json').write_text(json.dumps(spec)+'\n');print('Reserved',len(targets),'projected-body endpoints against text placement')
tools/bottom_contact_tags.pyadded+19
@@ -0,0 +1,19 @@+#!/usr/bin/env python3+"""Pin bottom machine-contact tags to their physical pads, with equal frames."""+import copy,json,subprocess+from pathlib import Path+R=Path(__file__).resolve().parents[1];P=R/'design/silkscreen-review';p=P/'bottom-candidates.json';s=json.loads(p.read_text())+texts=[dict(id=k,text=v,x=0,y=0,height=.8,width=.8,stroke=.12,mirrored=True,rotation=0) for k,v in [('J3','5V'),('J5','TX'),('J6','RX')]]+r=json.loads(subprocess.check_output(['adom-bridge','--target','AdomLapper','--ai-thread','adom-custom-load','kicad_text_bounds',json.dumps(dict(filePath='C:/Users/john/adom-projects/adom-custom-electronic-load/kicad/adom-custom-electronic-load.kicad_pcb',expectedRevision=s['nativeRevision'],texts=texts))],text=True));assert r['success'];metrics={t['id']:t['box'] for t in r['texts']};aliases={t['id']:t['text'] for t in texts};frames=[]+for g in s['labels']:+ if g['id'] not in ['J'+str(i) for i in range(1,8)]:continue+ c=copy.deepcopy(next(c for c in g['candidates'] if c['children'][0].get('angle',0)==0));x=g['anchor'][0];y=96.9;dx=x-c['position'][0];dy=y-c['position'][1]+ for child in c['children']:+  child['x']+=dx;child['y']+=dy;b=child['box'];child['box']=[b[0]+dx,b[1]+dy,b[2]+dx,b[3]+dy]+  if child['role']=='value' and g['id'] in aliases:+   child['text']=aliases[g['id']];b=metrics[g['id']];child['box']=[b[0]+child['x'],b[1]+child['y'],b[2]+child['x'],b[3]+child['y']]+ c['boxes']=[a['box'] for a in c['children']];b=c['boxes'];c['box']=[min(q[0] for q in b),min(q[1] for q in b),max(q[2] for q in b),max(q[3] for q in b)];c['position']=[x,y];g['candidates']=[c];g['maxDistance']=4+ frame=dict(reference=g['id'],kind='rect',layer='B.SilkS',points=[[x-1.9,94.9],[x+1.9,101.6]],stroke=.12);frames.append(frame)+ # Reserve each physical stroke, not the interior containing its own text and pad.+ for n,b in enumerate([[x-1.96,94.84,x+1.96,94.96],[x-1.96,101.54,x+1.96,101.66],[x-1.96,94.84,x-1.84,101.66],[x+1.84,94.84,x+1.96,101.66]]):s['obstacles'].append(dict(id=f'tag:{g["id"]}:{n}',kind='contact-frame',reference=g['id'],layer='B.SilkS',box=b))+p.write_text(json.dumps(s)+'\n');(P/'bottom-contact-tags.json').write_text(json.dumps(dict(frames=frames,aliases=aliases,metrics=r),indent=2)+'\n');print('Seven equal-width contact tags tied to pad X coordinates; UART TX/RX and auxiliary 5V aliases')
tools/bottom_corner_tags.pyadded+17
@@ -0,0 +1,17 @@+#!/usr/bin/env python3+"""Four equal corner tags; mirror their outlines into the board corners."""+import json,subprocess+from pathlib import Path+P=Path(__file__).resolve().parents[1]/'design/silkscreen-review';s=json.loads((P/'bottom-candidates.json').read_text());l=json.loads((P/'bottom-layout.json').read_text())+t=[dict(id='MP'+str(n),text='MP'+str(n),x=0,y=0,height=.9,width=.9,stroke=.12,mirrored=True,rotation=0) for n in range(1,5)]+r=json.loads(subprocess.check_output(['adom-bridge','--target','AdomLapper','--ai-thread','adom-custom-load','kicad_text_bounds',json.dumps(dict(filePath='C:/Users/john/adom-projects/adom-custom-electronic-load/kicad/adom-custom-electronic-load.kicad_pcb',expectedRevision=s['nativeRevision'],texts=t))],text=True));assert r['success'];metrics={z['id']:z['box'] for z in r['texts']};frames=[]+for g in s['labels']:+ if not g['id'].startswith('MP'):continue+ x,y=g['anchor'];upper=y<60;ref=g['id'];old=next(c for c in l['placements'] if c['id']==ref);value=old['children'][1];b=value['box'];vw,vh=b[2]-b[0],b[3]-b[1];rb=metrics[ref];rh=rb[3]-rb[1];cy=35.5 if upper else 96.5;total=rh+.2+vh;ry=cy-total/2+rh/2;vy=cy+total/2-vh/2+ children=[dict(text=ref,reference=ref,role='reference',x=x,y=ry,size=.9,stroke=.12,layer='B.SilkS',mirrored=True,box=[rb[0]+x,rb[1]+ry,rb[2]+x,rb[3]+ry]),dict(text='GND',reference=ref,role='value',x=x,y=vy,size=.8,stroke=.12,layer='B.SilkS',mirrored=True,box=[x-vw/2,vy-vh/2,x+vw/2,vy+vh/2])]+ boxes=[c['box'] for c in children];new=dict(id=ref,position=[x,cy],font=.9,boxes=boxes,box=[min(q[0] for q in boxes),min(q[1] for q in boxes),max(q[2] for q in boxes),max(q[3] for q in boxes)],children=children,layer='B.SilkS');l['placements']=[new if c['id']==ref else c for c in l['placements']]+ # Common local outline, chamfer on the board's outer corner; reflect X/Y.+ sx=1 if x<130 else -1;sy=1 if upper else -1+ points=[[x+sx*a,y+sy*b] for a,b in [(-.6,-1.6),(1.6,-1.6),(1.6,5.5),(-1.6,5.5),(-1.6,-.6),(-.6,-1.6)]]+ frames.append(dict(reference=ref,kind='polyline',layer='B.SilkS',points=points,stroke=.12))+(P/'bottom-layout.json').write_text(json.dumps(l,indent=2)+'\n');(P/'bottom-corner-tags.json').write_text(json.dumps(dict(frames=frames,metrics=r,referenceHeightMm=.9,valueHeightMm=.8),indent=2)+'\n');print('Four mirrored equal-size corner tags; 0.9 mm reference, 0.8 mm net')
tools/bottom_identity.pyadded+9
@@ -0,0 +1,9 @@+#!/usr/bin/env python3+"""Measure a restrained prototype identity block with the native font."""+import json,subprocess+from pathlib import Path+R=Path(__file__).resolve().parents[1];P=R/'design/silkscreen-review';s=json.loads((P/'bottom-candidates.json').read_text())+texts=[dict(id='identity-title',text='ADOM ELECTRONIC LOAD',x=129,y=33.8,height=1.2,width=1.2,stroke=.15,mirrored=True,rotation=0),dict(id='identity-revision',text='R0 PROTOTYPE - 2026-10',x=129,y=36.1,height=.8,width=.8,stroke=.12,mirrored=True,rotation=0),dict(id='identity-source',text='wiki.adom.inc/adom/adom-custom-electronic-load',x=129,y=38.1,height=.8,width=.8,stroke=.12,mirrored=True,rotation=0)]+r=json.loads(subprocess.check_output(['adom-bridge','--target','AdomLapper','--ai-thread','adom-custom-load','kicad_text_bounds',json.dumps(dict(filePath='C:/Users/john/adom-projects/adom-custom-electronic-load/kicad/adom-custom-electronic-load.kicad_pcb',expectedRevision=s['nativeRevision'],texts=texts))],text=True));assert r['success'];bounds={t['id']:t['box'] for t in r['texts']}+for t in texts:t.update(layer='B.SilkS',box=bounds[t['id']])+(P/'bottom-identity.json').write_text(json.dumps(dict(texts=texts,metrics=r),indent=2)+'\n');print(json.dumps(texts,indent=2))
tools/bottom_saved_candidate.pyadded+19
@@ -0,0 +1,19 @@+#!/usr/bin/env python3+"""Isolated bottom artwork candidate; the live board is never changed here."""+import json,hashlib,uuid,shutil+from pathlib import Path+from sexp import parse+R=Path(__file__).resolve().parents[1];P=R/'design/silkscreen-review';a=json.loads((P/'bottom-artwork.json').read_text());assert not a['findings']+source=R/'kicad/adom-custom-electronic-load.kicad_pcb';raw=source.read_bytes().decode();assert hashlib.sha256(raw.encode()).hexdigest()==a['boardSha256'];nodes=[];ids=[]+for t in a['texts']:+ ident=str(uuid.uuid4());ids.append(ident);size=t.get('size',t.get('height'));width=t.get('width',size);rotation=t.get('angle',t.get('rotation',0))+ nodes.append(f'(gr_text {json.dumps(t["text"])} (at {t["x"]:.9f} {t["y"]:.9f} {rotation}) (layer "B.SilkS") (uuid "{ident}") (effects (font (size {size} {width}) (thickness {t["stroke"]})) (justify mirror)))')+for g in a['graphics']:+ ident=str(uuid.uuid4());ids.append(ident);(x,y),(X,Y)=g['points'];nodes.append(f'(gr_line (start {x:.9f} {y:.9f}) (end {X:.9f} {Y:.9f}) (stroke (width {g["stroke"]}) (type solid)) (layer "B.SilkS") (uuid "{ident}"))')+pos=raw.rfind(')');new=raw[:pos]+'\n'+'\n'.join(nodes)+'\n'+raw[pos:];parsed=parse(new)+# Remove only the newly appended root nodes, then compare the entire parsed original.+assert parsed[:-len(nodes)]==parse(raw),'Unrelated board data changed'+out=R/'kicad/bottom-artwork-candidate.kicad_pcb';out.write_text(new)+for suffix in ['.kicad_pro','.kicad_dru']:shutil.copyfile(source.with_suffix(suffix),out.with_suffix(suffix))+report=dict(status='isolated candidate; live board unchanged',sourceSha256=a['boardSha256'],candidateSha256=hashlib.sha256(new.encode()).hexdigest(),textCount=len(a['texts']),graphicCount=len(a['graphics']),onlyStandaloneBottomSilkscreenAdded=True,addedIds=ids)+(P/'bottom-saved-candidate-review.json').write_text(json.dumps(report,indent=2)+'\n');print(json.dumps({k:v for k,v in report.items() if k!='addedIds'}))
tools/bottom_silkscreen_candidate.py+7−6
@@ -12,7 +12,7 @@ aliases={'DUT_POS':'DUT+','LOAD_POS':'LOAD+','SHUNT_P_SENSE':'SH+','SHUNT_N_SENS for f in find(board,'footprint'):     props={p[1]:p[2] for p in find(f,'property')};ref=props['Reference'];at=first(f,'at');anchor=list(map(float,at[1:3]))     value=None-    if ref.startswith(('R','C','L','F')):value=props['Value']+    if ref.startswith(('R','C','L','F')):value='20m' if ref=='RSH1' else props['Value']     elif ref.startswith(('TP','MP')) or ref in ['J'+str(i) for i in range(1,8)]:         nets={first(p,'net')[-1] for p in find(f,'pad') if first(p,'net')}         assert len(nets)==1,(ref,nets)@@ -35,10 +35,11 @@ for g in groups:     offsets=[]     for h in heights:offsets.append(base+h/2);base+=h+.2     cs=[]-    for i in range(-10,11):-        for j in range(-10,11):+    radius=8 if g['id'] in ('R21','R3') else 6 if g['id'] in ('R17','R19','R20','R34') else 4+    for i in range(-int(radius/.4),int(radius/.4)+1):+        for j in range(-int(radius/.4),int(radius/.4)+1):             dx,dy=i*.4,j*.4-            if math.hypot(dx,dy)>4:continue+            if math.hypot(dx,dy)>radius:continue             x,y=g['anchor'][0]+dx,g['anchor'][1]+dy;children=[]             for k,c in enumerate(g['children']):                 q=bounds[c['id']];yy=y+offsets[k]@@ -54,7 +55,7 @@ for g in groups:                 rotated.append(dict(c,x=x+(c['y']-y),y=y-(c['x']-x),angle=90,box=[min(a for a,b in corners),min(b for a,b in corners),max(a for a,b in corners),max(b for a,b in corners)]))             rb=[c['box'] for c in rotated];envelope=[min(q[0] for q in rb),min(q[1] for q in rb),max(q[2] for q in rb),max(q[3] for q in rb)]             cs.append(dict(position=[x,y],font=g['children'][0]['height'],box=envelope,boxes=rb,children=rotated,layer='B.SilkS',qualityPenalty=.1))-    labels.append(dict(id=g['id'],anchor=g['anchor'],maxDistance=4,candidates=cs,requiredRoles=['reference','value'] if g['value'] else ['reference'],maxValueRatio=.8))-data=dict(bounds=[98.3,30.3,161.7,101.7],labels=labels,obstacles=[o for o in source['obstacles'] if o['layer']=='B.SilkS'],clearance=.12,solver='milp',solverSeconds=45,milpPerFont=48,candidatesPerLabel=2000,boundsSource='Native mirrored glyph metrics; exact electrical geometry retained from v85; rounded-corner and native DRC review pending',boardSha256=hashlib.sha256(board_path.read_bytes()).hexdigest(),nativeRevision=state['revision'])+    labels.append(dict(id=g['id'],anchor=g['anchor'],maxDistance=radius,candidates=cs,requiredRoles=['reference','value'] if g['value'] else ['reference'],maxValueRatio=.8))+data=dict(bounds=[98.3,30.3,161.7,101.7],labels=labels,obstacles=[o for o in source['obstacles'] if o['layer']=='B.SilkS'],clearance=.12,solver='milp',solverSeconds=90,milpPerFont=192,candidatesPerLabel=2000,boundsSource='Native mirrored glyph metrics; exact electrical geometry retained from v85; rounded-corner, label association/leader and native DRC review pending',boardSha256=hashlib.sha256(board_path.read_bytes()).hexdigest(),nativeRevision=state['revision']) (OUT/'bottom-candidates.json').write_text(json.dumps(data)+'\n') print(f'{len(groups)} complete reference/value groups, {len(texts)} native text extents; minimum 0.8 mm matches current project rules')
tools/bottom_silkscreen_leaders.pyadded+82
@@ -0,0 +1,82 @@+#!/usr/bin/env python3+"""Route explicit bottom-side association leaders for distant text groups.++Targets are the mirrored projections of front-side component bodies, not exposed+electrical pads. This remains a proposal until native DRC and visual review.+"""+import heapq,itertools,json,math+from pathlib import Path+import numpy as np+from shapely import contains_xy+from shapely.geometry import box,LineString,Point+from shapely.ops import unary_union+from sexp import parse,find,first++ROOT=Path(__file__).resolve().parents[1];P=ROOT/'design/silkscreen-review'+spec=json.loads((P/'bottom-candidates.json').read_text());layout=json.loads((P/'bottom-layout.json').read_text());assert not layout['unresolved']+anchors={g['id']:g['anchor'] for g in spec['labels']}+bodies={r['ref']:r['boundsMm'] for r in json.loads((ROOT/'mechanical/cooling-680-body-audit.json').read_text())['rows']}+pad_targets={}+for footprint in find(parse((ROOT/'kicad/adom-custom-electronic-load.kicad_pcb').read_text()),'footprint'):+    ref=next(p[2] for p in find(footprint,'property') if p[1]=='Reference');at=first(footprint,'at');theta=math.radians(-float(at[3])) if len(at)>3 else 0+    pad_targets[ref]=[]+    for p in find(footprint,'pad'):+        local=first(p,'at');x,y=map(float,local[1:3]);pad_targets[ref].append([float(at[1])+x*math.cos(theta)-y*math.sin(theta),float(at[2])+x*math.sin(theta)+y*math.cos(theta)])+targets={t['reference']:t for t in json.loads((P/'bottom-association-targets.json').read_text())}+obstacles=[box(*o['box']) for o in spec['obstacles'] if o['kind']!='association-target']+obstacles += [box(*b) for g in layout['placements'] for b in g['boxes']]+pitch=.1;x0,y0,x1,y1=spec['bounds'];nx=int((x1-x0)/pitch)+1;ny=int((y1-y0)/pitch)+1+xs=x0+np.arange(nx)*pitch;ys=y0+np.arange(ny)*pitch;xx,yy=np.meshgrid(xs,ys)+def cell(p):return (round((p[0]-x0)/pitch),round((p[1]-y0)/pitch))+def point(c):return [float(xs[c[0]]),float(ys[c[1]])]+leaders=[];failed=[]+groups=sorted((g for g in layout['placements'] if math.dist(g['position'],anchors[g['id']])>3.5),key=lambda g:-math.dist(g['position'],anchors[g['id']]))+for g in groups:+    ref=g['id'];b=g['box'];a=anchors[ref];body=bodies.get(ref)+    if not body:failed.append(dict(reference=ref,reason='No fitted-body projection'));continue+    # 0.12 mm line: 0.06 mm half-stroke plus 0.06 mm edge separation.+    # This is distinct from the larger text-box reservation. No hole is crossed.+    local_obstacles=obstacles+[box(*o['box']) for o in spec['obstacles'] if o['kind']=='association-target' and o['reference']!=ref]+    occupied=unary_union(local_obstacles).buffer(.12)+    blocked=contains_xy(occupied,xx,yy)+    # Candidate starts around text enclosure; targets on the part-body projection.+    def perimeter(q,gap=0):+        x,y,X,Y=q;out=[]+        for t in np.linspace(0,1,max(8,int(2*((X-x)+(Y-y))/pitch))):+            out.extend([[x-gap+(X-x+2*gap)*t,y-gap],[x-gap+(X-x+2*gap)*t,Y+gap],[x-gap,y-gap+(Y-y+2*gap)*t],[X+gap,y-gap+(Y-y+2*gap)*t]])+        return {cell(p) for p in out}+    def free(c):return 0<=c[0]<nx and 0<=c[1]<ny and not blocked[c[1],c[0]]+    starts={c for c in perimeter(b,.35) if free(c)}+    targetbox=[body[0],body[1],body[3],body[4]]+    if ref in targets:+        goals={cell(targets[ref]['point'])} if free(cell(targets[ref]['point'])) else set()+    else:+        goals={cell([x,y]) for x in np.arange(targetbox[0],targetbox[2]+.001,.1) for y in np.arange(targetbox[1],targetbox[3]+.001,.1) if free(cell([x,y]))}+    if not starts or not goals:failed.append(dict(reference=ref,reason='No clear label rim or projected-body target',startCount=len(starts),targetCount=len(goals)));continue+    goal_array=list(goals)+    def heuristic(c):return min(abs(c[0]-t[0])+abs(c[1]-t[1]) for t in goal_array)+    heap=[];distance={};parents={};counter=itertools.count()+    for c in starts:distance[c]=0;heapq.heappush(heap,(heuristic(c),next(counter),c))+    end=None+    while heap:+        _,_,c=heapq.heappop(heap)+        if c in goals:end=c;break+        for dx,dy in [(1,0),(-1,0),(0,1),(0,-1)]:+            n=(c[0]+dx,c[1]+dy)+            if not free(n):continue+            cost=distance[c]+1+            if cost<distance.get(n,math.inf):distance[n]=cost;parents[n]=c;heapq.heappush(heap,(cost+heuristic(n),next(counter),n))+    if end is None:failed.append(dict(reference=ref,reason='No collision-free grid path'));continue+    path=[end]+    while path[-1] in parents:path.append(parents[path[-1]])+    path=list(reversed(path));line=LineString([point(c) for c in path]).simplify(.001)+    # Independent continuous-distance check; reject cell-sampling shortcuts.+    clearance=min(line.distance(o) for o in local_obstacles)+    if clearance<.119:failed.append(dict(reference=ref,reason='Continuous clearance failed',clearance=clearance));continue+    points=[list(p) for p in line.coords]+    leaders.append(dict(reference=ref,layer='B.SilkS',stroke=.12,points=points,targetProjection=targetbox,allowedPadProjections=pad_targets.get(ref,[]),minimumObstacleDistanceMm=clearance,labelOffsetMm=math.dist(g['position'],a)))+    obstacles.append(line.buffer(.06))+result=dict(status='proposal-not-native-accepted',boardSha256=spec['boardSha256'],layoutSha256=__import__('hashlib').sha256((P/'bottom-layout.json').read_bytes()).hexdigest(),leaders=leaders,unresolved=failed,limits=['Leaders indicate projected front-side body locations on the bottom; not exposed pad identities.','Orthogonal lines are a routing proposal; rounded corners and final artwork/association review remain pending.','Native DRC is still required for text plus leaders together.'])+(P/'bottom-leaders.json').write_text(json.dumps(result,indent=2)+'\n')+print(json.dumps(dict(routed=len(leaders),unresolved=failed),indent=2))+raise SystemExit(2 if failed else 0)
tools/bottom_silkscreen_native.pyadded+17
@@ -0,0 +1,17 @@+#!/usr/bin/env python3+"""Dry-run only: native check of the complete bottom text proposal."""+import json, subprocess+from pathlib import Path+ROOT=Path(__file__).resolve().parents[1];P=ROOT/'design/silkscreen-review'+layout=json.loads((P/'bottom-layout.json').read_text());inputs=json.loads((P/'bottom-candidates.json').read_text())+assert not layout['unresolved'] and len(layout['placements'])==104+texts=[]+for group in layout['placements']:+    for c in group['children']:+        texts.append(dict(text=c['text'],x=c['x'],y=c['y'],height=c['size'],width=c['size'],stroke=c['stroke'],rotation=c.get('angle',0),layer='B.SilkS',mirrored=True,align='center'))+payload=dict(filePath='C:/Users/john/adom-projects/adom-custom-electronic-load/kicad/adom-custom-electronic-load.kicad_pcb',expectedRevision=inputs['nativeRevision'],create=texts,dryRun=True,save=False)+(P/'bottom-native-proposal.json').write_text(json.dumps(payload,indent=2)+'\n')+raw=subprocess.check_output(['adom-bridge','--target','AdomLapper','--ai-thread','adom-custom-load','kicad_silk_text_batch',json.dumps(payload)],text=True)+(P/'bottom-native-dryrun.json').write_text(raw);r=json.loads(raw)+print(json.dumps({k:v for k,v in r.items() if k in ('success','mutated','error','errorCode','violations','revision')},indent=2))+raise SystemExit(0 if r.get('success') else 2)
tools/check_bottom_native_extents.pyadded+17
@@ -0,0 +1,17 @@+#!/usr/bin/env python3+"""Refresh all final candidate extents from KiCad, including rotated groups."""+import json,subprocess+from pathlib import Path+P=Path(__file__).resolve().parents[1]/'design/silkscreen-review';s=json.loads((P/'bottom-candidates.json').read_text());l=json.loads((P/'bottom-layout.json').read_text());identity=json.loads((P/'bottom-identity.json').read_text());alltext=[c for g in l['placements'] for c in g['children']]+identity['texts'];defs=[]+for i,c in enumerate(alltext):+ size=c.get('size',c.get('height'));defs.append(dict(id=str(i),text=c['text'],x=c['x'],y=c['y'],height=size,width=c.get('width',size),stroke=c['stroke'],mirrored=True,rotation=c.get('angle',c.get('rotation',0))))+changes=[]+for start in range(0,len(defs),40):+ r=json.loads(subprocess.check_output(['adom-bridge','--target','AdomLapper','--ai-thread','adom-custom-load','kicad_text_bounds',json.dumps(dict(filePath='C:/Users/john/adom-projects/adom-custom-electronic-load/kicad/adom-custom-electronic-load.kicad_pcb',expectedRevision=s['nativeRevision'],texts=defs[start:start+40]))],text=True));assert r['success'];(P/f'final-native-extents-{start:03}.json').write_text(json.dumps(r,indent=2)+'\n')+ for t in r['texts']:+  c=alltext[int(t['id'])];err=max(abs(a-b) for a,b in zip(c['box'],t['box']))+  if err>1e-5:changes.append(dict(text=c['text'],reference=c.get('reference'),maximumBoundDifferenceMm=err,before=c['box'],after=t['box']))+  c['box']=t['box']+for g in l['placements']:+ b=[c['box'] for c in g['children']];g['boxes']=b;g['box']=[min(q[0] for q in b),min(q[1] for q in b),max(q[2] for q in b),max(q[3] for q in b)]+(P/'bottom-layout.json').write_text(json.dumps(l,indent=2)+'\n');(P/'bottom-identity.json').write_text(json.dumps(identity,indent=2)+'\n');(P/'bottom-extents-corrections.json').write_text(json.dumps(changes,indent=2)+'\n');print(json.dumps(changes,indent=2))
tools/check_bottom_saved_candidate.pyadded+12
@@ -0,0 +1,12 @@+#!/usr/bin/env python3+"""Native desktop DRC of the isolated candidate, with its real project context."""+import json,subprocess+from pathlib import Path+R=Path(__file__).resolve().parents[1];P=R/'design/silkscreen-review';host='C:/Users/john/adom-projects/adom-custom-electronic-load/kicad'+def call(verb,payload):+ r=json.loads(subprocess.check_output(['adom-bridge','--target','AdomLapper','--ai-thread','adom-custom-load',verb,json.dumps(payload)],text=True));(P/('bottom-'+verb+'.json')).write_text(json.dumps(r,indent=2)+'\n');assert r.get('success',r.get('ok')) and r.get('exitCode',0)==0,r;return r+call('send_files',dict(filePaths=[str(R/'kicad'/('bottom-artwork-candidate'+x)) for x in ['.kicad_pcb','.kicad_pro','.kicad_dru']],dest=host,reason='Check isolated bottom artwork with the real project rules; preserve the live board'))+cli='C:/Users/john/AppData/Local/Programs/KiCad/10.0/bin/kicad-cli.exe'+r=call('shell_execute',dict(command=f'"{cli}" pcb drc --format json --output "{host}/bottom-artwork-candidate-drc.json" "{host}/bottom-artwork-candidate.kicad_pcb"',timeoutSeconds=120,reason='Native project-aware DRC for the complete bottom text and graphics candidate'));print(r['stdout'])+call('pull_file',dict(filePaths=[host+'/bottom-artwork-candidate-drc.json'],saveTo=str(P)))+r=json.loads((P/'bottom-artwork-candidate-drc.json').read_text());print('violations',len(r['violations']),'opens',len(r['unconnected_items']));assert not r['violations'] and not r['unconnected_items']
tools/complete_bottom_candidates.pyadded+29
@@ -0,0 +1,29 @@+import json,math+s=json.load(open('design/silkscreen-review/bottom-candidates.json'));l=json.load(open('design/silkscreen-review/bottom-layout.json'));gap=s['clearance']+def overlap(a,b):return not(a[2]+gap<=b[0] or b[2]+gap<=a[0] or a[3]+gap<=b[1] or b[3]+gap<=a[1])+for g in s['labels']:+ if g['id'] not in l['unresolved']:continue+ feasible=[];physical=[]+ if g['id']=='J6':+  import copy+  c=copy.deepcopy(g['candidates'][0]);c['position'][0]-=.6;c['box'][0]-=.6;c['box'][2]-=.6+  for b in c['boxes']:b[0]-=.6;b[2]-=.6+  for child in c['children']:child['x']-=.6;child['box'][0]-=.6;child['box'][2]-=.6+  g['candidates'].append(c)+ for c in g['candidates']:+  hits=[o['id'] for o in s['obstacles'] if any(overlap(b,o['box']) for b in c['boxes'])]+  if hits:+   if len(g['candidates'])==1:print(g['id'],'physicalhits',hits)+   continue+  physical.append(c)+  hits=[h['id'] for h in l['placements'] if not h.get('unresolved') and any(overlap(b,z) for b in c['boxes'] for z in h['boxes'])]+  if not hits:feasible.append(c)+ feasible.sort(key=lambda c:math.dist(c['position'],g['anchor']))+ print(g['id'],'physicalclear',len(physical),'fullclear',len(feasible),'best',feasible[0]['position'] if feasible else None)+ if feasible:+  row=dict(feasible[0],id=g['id']);l['placements']=[row if c['id']==g['id'] else c for c in l['placements']];l['unresolved'].remove(g['id'])+json.dump(l,open('design/silkscreen-review/bottom-layout-completion-candidate.json','w'),indent=2)++assert not l['unresolved'],l['unresolved']+l['method']+='; complete-set collision-checked insertion of candidates omitted by the bounded MILP subset'+json.dump(l,open('design/silkscreen-review/bottom-layout.json','w'),indent=2)
tools/expand_bottom_candidate.pyadded+20
@@ -0,0 +1,20 @@+#!/usr/bin/env python3+"""Extend one label search using already measured native glyph geometry."""+import copy,json,math,argparse+from pathlib import Path+p=argparse.ArgumentParser();p.add_argument('reference');p.add_argument('radius',type=float);a=p.parse_args()+root=Path(__file__).resolve().parents[1];path=root/'design/silkscreen-review/bottom-candidates.json';spec=json.loads(path.read_text());g=next(g for g in spec['labels'] if g['id']==a.reference)+templates={}+for c in g['candidates']:templates.setdefault(c['children'][0].get('angle',0),c)+g['candidates']=[];g['maxDistance']=a.radius+for i in range(-int(a.radius/.4),int(a.radius/.4)+1):+ for j in range(-int(a.radius/.4),int(a.radius/.4)+1):+  if math.hypot(i*.4,j*.4)>a.radius:continue+  x,y=g['anchor'][0]+i*.4,g['anchor'][1]+j*.4+  for t in templates.values():+   c=copy.deepcopy(t);dx,dy=x-t['position'][0],y-t['position'][1]+   def shift(b):return [b[0]+dx,b[1]+dy,b[2]+dx,b[3]+dy]+   c['position']=[x,y];c['box']=shift(c['box']);c['boxes']=[shift(b) for b in c['boxes']]+   for child in c['children']:child['x']+=dx;child['y']+=dy;child['box']=shift(child['box'])+   g['candidates'].append(c)+path.write_text(json.dumps(spec)+'\n');print(a.reference,len(g['candidates']))
tools/front_contact_artwork.pyadded+69
@@ -0,0 +1,69 @@+#!/usr/bin/env python3+"""Plan front contact legends using native metrics and fitted-body exclusions."""+import json,subprocess,hashlib,math,copy+from pathlib import Path+from shapely.geometry import box,LineString,Polygon+from shapely.ops import unary_union+from sexp import parse,find,first+R=Path(__file__).resolve().parents[1];P=R/'design/silkscreen-review';O=P/'front-contacts';O.mkdir(exist_ok=True)+boardpath=R/'kicad/adom-custom-electronic-load.kicad_pcb';board=parse(boardpath.read_text());oldgeom=json.loads((P/'geometry.json').read_text());bottom=json.loads((P/'bottom-layout.json').read_text());groups=[copy.deepcopy(g) for g in bottom['placements'] if g['id'] in ['J'+str(i) for i in range(1,8)]+['MP'+str(i) for i in range(1,5)]]+newtexts=[]+corner_y={c['role']:c['y'] for g in groups if g['id']=='MP3' for c in g['children']}+for g in groups:+ for c in g['children']:+  c['layer']='F.SilkS';c['mirrored']=False+  if g['id']=='J7':+   # The fitted inductor ends at Y=98.2: there is no legal two-line+   # legend above this contact. Put its paired legend beside its rim.+   c['x']=145.65 if c['role']=='reference' else 148.0;c['y']=100.8;c['size']=.8;c['angle']=0+  if g['id']=='MP4':c['y']=corner_y[c['role']]+  newtexts.append(c)+existing=[]+for fp in find(board,'footprint'):+ at=first(fp,'at');angle=-math.radians(float(at[3]) if len(at)>3 else 0)+ for p in find(fp,'property'):+  if first(p,'layer')[1]!='F.SilkS' or first(p,'hide')==['hide','yes']:continue+  e=first(p,'effects');font=first(e,'font');sz=first(font,'size');a=first(p,'at');x,y=map(float,a[1:3]);just=first(e,'justify') or []+  existing.append(dict(text=p[2],x=float(at[1])+x*math.cos(angle)-y*math.sin(angle),y=float(at[2])+x*math.sin(angle)+y*math.cos(angle),height=float(sz[1]),width=float(sz[2]),stroke=float(first(font,'thickness')[1]),rotation=float(a[3]) if len(a)>3 else 0,mirrored='mirror' in just,align='center'))+for p in find(board,'gr_text'):+ if first(p,'layer')[1]!='F.SilkS':continue+ a=first(p,'at');e=first(p,'effects');f=first(e,'font');sz=first(f,'size');existing.append(dict(text=p[1],x=float(a[1]),y=float(a[2]),height=float(sz[1]),width=float(sz[2]),stroke=float(first(f,'thickness')[1]),rotation=float(a[3]) if len(a)>3 else 0,mirrored=False,align='center'))+field_moves=[]+for e in existing:+ if e['text']=='J8':+  field_moves.append(dict(reference='J8',before=[e['x'],e['y']],after=[156.5,e['y']]))+  e['x']=156.5+assert len(field_moves)==1+state=json.loads(subprocess.check_output(['adom-bridge','--target','AdomLapper','--ai-thread','adom-custom-load','kicad_routing_state',json.dumps(dict(filePath='C:/Users/john/adom-projects/adom-custom-electronic-load/kicad/adom-custom-electronic-load.kicad_pcb'))],text=True));assert state['success']+all_defs=[dict(text=c['text'],x=c['x'],y=c['y'],height=c['size'],width=c['size'],stroke=c['stroke'],rotation=c.get('angle',0),mirrored=False,align='center') for c in newtexts]+existing+bounds={}+for start in range(0,len(all_defs),40):+ defs=[dict(v,id=str(i)) for i,v in enumerate(all_defs) if start<=i<start+40]+ r=json.loads(subprocess.check_output(['adom-bridge','--target','AdomLapper','--ai-thread','adom-custom-load','kicad_text_bounds',json.dumps(dict(filePath=state['boardPath'],expectedRevision=state['revision'],texts=defs))],text=True));assert r['success'];bounds.update({int(t['id']):t['box'] for t in r['texts']});(O/f'metrics-{start:03}.json').write_text(json.dumps(r,indent=2)+'\n')+for i,c in enumerate(newtexts):c['box']=bounds[i]+# Original v85 pads/bodies remain valid through the independently checked chain+# of silk-only revisions. Bind that fact instead of rewriting the historic audit.+proof=json.loads((P/'bottom-landing-verification.json').read_text());assert all(proof['unchanged'].values());assert proof['savedSha256']==hashlib.sha256(boardpath.read_bytes()).hexdigest()+physical=[o for o in oldgeom['obstacles'] if o['layer']=='F.SilkS'];obstacles=[(o['id'],box(*o['box'])) for o in physical]+[('existing:'+str(i),box(*bounds[i])) for i in range(len(newtexts),len(all_defs))];findings=[]+for i,c in enumerate(newtexts):+ b=box(*c['box'])+ for name,o in obstacles:+  if b.distance(o)<.119:findings.append(dict(kind='text-obstacle',text=c['text'],reference=c['reference'],obstacle=name,distance=b.distance(o)))+ for d in newtexts[:i]:+  if b.distance(box(*d['box']))<.119:findings.append(dict(kind='text-pair',texts=[c['text'],d['text']]))+all_obstacles=unary_union([o for _,o in obstacles]+[box(*c['box']) for c in newtexts]);graphics=[];framechecks=[]+frames=json.loads((P/'bottom-contact-tags.json').read_text())['frames']+json.loads((P/'bottom-corner-tags.json').read_text())['frames']+for f in frames:+ if f['kind']=='rect':+  (x,y),(X,Y)=f['points'];y=98.8;pts=[[x,y],[X,y],[X,Y],[x,Y],[x,y]]+ else:pts=f['points']+ line=LineString(pts);clipped=line.difference(all_obstacles.buffer(.121));parts=list(clipped.geoms) if hasattr(clipped,'geoms') else [clipped];ratio=sum(p.length for p in parts)/line.length;framechecks.append(dict(reference=f['reference'],retainedFraction=ratio))+ if ratio<.7:findings.append(dict(kind='frame-too-broken',reference=f['reference'],retainedFraction=ratio))+ area=Polygon(pts)+ for o in physical:+  if o['kind']=='pad-mask-or-hole' and o.get('reference')!=f['reference'] and area.contains(box(*o['box']).representative_point()):findings.append(dict(kind='frame-encloses-other-pad',reference=f['reference'],obstacle=o['id']))+ for p in parts:+  xy=list(p.coords)+  for a,b in zip(xy,xy[1:]):+   if math.dist(a,b)>.02:graphics.append(dict(kind='line',layer='F.SilkS',points=[list(a),list(b)],stroke=.12,reference=f['reference']))+result=dict(status='candidate only',boardSha256=proof['savedSha256'],nativeRevision=state['revision'],texts=newtexts,fieldMoves=field_moves,graphics=graphics,frameChecks=framechecks,findings=findings,sourceBodyAudit='mechanical/cooling-680-body-audit.json',equivalenceEvidence='design/silkscreen-review/bottom-landing-verification.json');(O/'artwork.json').write_text(json.dumps(result,indent=2)+'\n');print(json.dumps(dict(texts=len(newtexts),graphics=len(graphics),findings=findings,frames=framechecks),indent=2));raise SystemExit(2 if findings else 0)
tools/land_bottom_artwork.pyadded+34
@@ -0,0 +1,34 @@+#!/usr/bin/env python3+"""Apply the fully checked text and graphics through two native transactions.++Stops on every semantic failure and retains receipts; never automatically replays+an uncertain mutation. Records the exact linked native 3D viewer during landing.+"""+import json,subprocess,hashlib,time+from pathlib import Path+R=Path(__file__).resolve().parents[1];P=R/'design/silkscreen-review';a=json.loads((P/'bottom-artwork.json').read_text());assert not a['findings'];drc=json.loads((P/'bottom-artwork-candidate-drc.json').read_text());assert not drc['violations'] and not drc['unconnected_items']+board='C:/Users/john/adom-projects/adom-custom-electronic-load/kicad/adom-custom-electronic-load.kicad_pcb';pcb=41886014;viewer=1124570+assert hashlib.sha256((R/'kicad/adom-custom-electronic-load.kicad_pcb').read_bytes()).hexdigest()==a['boardSha256']+def call(name,data,label):+ raw=subprocess.check_output(['adom-bridge','--target','AdomLapper','--ai-thread','adom-custom-load',name,json.dumps(data)],text=True);(P/f'land-bottom-{label}.json').write_text(raw);r=json.loads(raw)+ if not r.get('success',r.get('ok')) or r.get('postCommitError'):raise RuntimeError(f'{label}: inspect receipt before any retry: '+str(r.get('error',r.get('postCommitError'))))+ return r+state=call('kicad_routing_state',dict(filePath=board),'before');assert state['revision']==a['nativeRevision']+call('kicad_3d_view',dict(hwnd=viewer,action='view_bottom'),'view-before')+record=call('desktop_record_start',dict(hwnd=viewer,fps=30,cursor=False,audio=False,maxDurationMs=300000,reason='Record native bottom labels and contact frames appearing on the electronic-load PCB'),'record-start');rid=record['recordingId']+try:+ texts=[]+ for t in a['texts']:+  size=t.get('size',t.get('height'));texts.append(dict(text=t['text'],x=t['x'],y=t['y'],height=size,width=t.get('width',size),stroke=t['stroke'],rotation=t.get('angle',t.get('rotation',0)),layer='B.SilkS',mirrored=True,align='center'))+ r=call('kicad_silk_text_batch',dict(filePath=board,expectedRevision=state['revision'],create=texts,dryRun=False,save=False),'texts');print('Native text transaction committed',flush=True)+ call('kicad_refresh_board_views',dict(pcbHwnd=pcb),'refresh-texts')+ state=call('kicad_routing_state',dict(filePath=board),'after-texts')+ graphics=[{k:g[k] for k in ['kind','layer','points','stroke']} for g in a['graphics']]+ r=call('kicad_silk_graphics_batch',dict(filePath=board,expectedRevision=state['revision'],create=graphics,dryRun=False,save=True),'graphics');print('Native graphics transaction committed',flush=True)+ call('kicad_refresh_board_views',dict(pcbHwnd=pcb),'refresh-all')+ call('kicad_3d_view',dict(hwnd=viewer,action='tour',steps=[['view_bottom',1],['zoom_in',1],['zoom_out',1]],pauseMs=1000),'review-tour')+ call('kicad_routing_state',dict(filePath=board),'after')+finally:+ stop=call('desktop_record_stop',dict(recordingId=rid),'record-stop')+ path=stop.get('path',record['path']);call('pull_file',dict(filePaths=[path],saveTo=str(R/'videos/raw')),'record-pull')+print('Native landing complete; saved-file readback and DRC still required',flush=True)
tools/land_front_saved_candidate.pyadded+27
@@ -0,0 +1,27 @@+#!/usr/bin/env python3+"""Land checked front art with one required footprint-field file edit.++KiCad 10's tested field API cannot update J8's Reference property. Save and close+only this board, preserve its exact source, then reopen the checked candidate.+"""+import json,subprocess,hashlib,shutil,time+from pathlib import Path+R=Path(__file__).resolve().parents[1];O=R/'design/silkscreen-review/front-contacts';a=json.loads((O/'artwork.json').read_text());report=json.loads((O/'candidate-review.json').read_text());d=json.loads((O/'front-contact-drc.json').read_text());assert not a['findings'] and not d['violations'] and not d['unconnected_items'];candidate=R/'kicad/front-contact-candidate.kicad_pcb';assert hashlib.sha256(candidate.read_bytes()).hexdigest()==report['candidateSha256']+remote='C:/Users/john/adom-projects/adom-custom-electronic-load/kicad/adom-custom-electronic-load.kicad_pcb';pcb=41886014++def call(v,p,label):+ raw=subprocess.check_output(['adom-bridge','--target','AdomLapper','--ai-thread','adom-custom-load',v,json.dumps(p)],text=True);(O/('land-'+label+'.json')).write_text(raw);r=json.loads(raw);assert r.get('success',r.get('ok')),r;return r+state=call('kicad_routing_state',dict(filePath=remote),'before');assert state['revision']==a['nativeRevision']+call('kicad_send_key',dict(hwnd=pcb,menu='Save'),'save-before')+call('pull_file',dict(filePaths=[remote],saveTo=str(O/'before')),'backup');assert hashlib.sha256((O/'before/adom-custom-electronic-load.kicad_pcb').read_bytes()).hexdigest()==a['boardSha256']+call('desktop_close_window',dict(hwnd=pcb),'close')+for i in range(5):+ r=call('desktop_list_windows',{},f'windows-{i}');w=json.loads(r['output'])['data']['windows']+ if not any(x['hwnd']==pcb for x in w):break+ time.sleep(1)+else:raise RuntimeError('Task editor did not close; inspect dialogs without discarding work')+shutil.copy2(candidate,R/'kicad/adom-custom-electronic-load.kicad_pcb')+call('send_files',dict(filePaths=[str(R/'kicad/adom-custom-electronic-load.kicad_pcb')],dest=remote.rsplit('/',1)[0],reason='Adopt DRC-clean front legends and move J8 reference out of corner tag; copper unchanged'),'send')+call('kicad_open_board',dict(filePath=remote,foreground=False,waitSeconds=15),'open')+state=call('kicad_routing_state',dict(filePath=remote),'after');print(json.dumps(dict(revision=state['revision'],boardPath=state['boardPath'],netsRemaining=state.get('netsRemaining'))),flush=True)+call('kicad_open_editors',{},'editors')
tools/opaque_board_material_review.pyadded+16
@@ -0,0 +1,16 @@+#!/usr/bin/env python3+"""Isolate opaque ink/substrate materials without changing any mesh bytes."""+import copy,json,re,hashlib+from pathlib import Path+from glb_shape_helpers import read_glb,write_glb+R=Path(__file__).resolve().parents[1];O=R/'mechanical/board23-review';source=O/'board23.glb';g,b=read_glb(source);before=copy.deepcopy(g);changes=[]+for mesh in g['meshes']:+ role=(mesh.get('extras') or {}).get('adomBoardLayer')+ if not role:+  m=re.search(r'_(PCB|silkscreen)(?:[-_.]\d+)?$',mesh.get('name',''),re.I);role=m.group(1).lower() if m else None+ if role not in ['pcb','silkscreen']:continue+ for prim in mesh['primitives']:+  old=prim['material'];mat=copy.deepcopy(g['materials'][old]);mat['name']='OpaqueReview_'+role;mat.setdefault('pbrMetallicRoughness',{}).setdefault('baseColorFactor',[1,1,1,1])[3]=1;mat['alphaMode']='OPAQUE';prim['material']=len(g['materials']);g['materials'].append(mat);changes.append(dict(role=role,mesh=mesh.get('name'),oldMaterial=old,newMaterial=prim['material']))+assert {c['role'] for c in changes}=={'pcb','silkscreen'}+out=O/'board23-opaque-review.glb';write_glb(out,g,b)+report=dict(sourceSha256=hashlib.sha256(source.read_bytes()).hexdigest(),outputSha256=hashlib.sha256(out.read_bytes()).hexdigest(),binaryBufferUnchanged=True,nodesUnchanged=g['nodes']==before['nodes'],accessorsUnchanged=g['accessors']==before['accessors'],changes=changes,status='visual experiment, not source release');(O/'opaque-material-review.json').write_text(json.dumps(report,indent=2)+'\n');print(json.dumps(report,indent=2))
tools/plot_bottom_silkscreen.pyadded+21
@@ -0,0 +1,21 @@+#!/usr/bin/env python3+"""Engineering plan view; text boxes are native glyph envelopes, not rendered ink."""+import json+from pathlib import Path+import matplotlib;matplotlib.use('Agg')+import matplotlib.pyplot as plt+from matplotlib.patches import Rectangle+ROOT=Path(__file__).resolve().parents[1];P=ROOT/'design/silkscreen-review'+s=json.loads((P/'bottom-candidates.json').read_text());l=json.loads((P/'bottom-layout.json').read_text())+fig,ax=plt.subplots(figsize=(10,11));ax.set_facecolor('#13282b')+for o in s['obstacles']:+ b=o['box'];ax.add_patch(Rectangle((b[0],b[1]),b[2]-b[0],b[3]-b[1],color='#ff765e' if o['kind']=='association-target' else '#748787',alpha=.7))+for g in l['placements']:+ if g.get('unresolved'):continue+ for c in g['children']:+  b=c['box'];ax.add_patch(Rectangle((b[0],b[1]),b[2]-b[0],b[3]-b[1],edgecolor='#6acaca',facecolor='none',lw=.4));ax.text(c['x'],c['y'],c['text'],ha='center',va='center',fontsize=5,rotation=-c.get('angle',0),color='white')+if (P/'bottom-leaders.json').exists():+ for g in json.loads((P/'bottom-leaders.json').read_text())['leaders']:+  x,y=zip(*g['points']);ax.plot(x,y,color='#ffcb64',lw=.8)+x,y,X,Y=s['bounds'];ax.set_xlim(X+1,x-1);ax.set_ylim(Y+1,y-1);ax.set_aspect('equal');ax.set_title('Bottom inspection • proposed labels, native glyph envelopes\nMirrored viewing coordinates; not native artwork acceptance')+fig.savefig(P/'bottom-plan.png',dpi=180,bbox_inches='tight');print(P/'bottom-plan.png')
tools/record_opaque_material_review.pyadded+17
@@ -0,0 +1,17 @@+#!/usr/bin/env python3+import json,subprocess,shutil,time+from pathlib import Path+R=Path(__file__).resolve().parents[1];O=R/'mechanical/board23-review';shutil.copy2(O/'board23-opaque-review.glb',R/'checkpoints/board-review-v85/board23-opaque-review.glb');session='adom-custom-load-current-milestone'+def call(v,a,label):+ r=json.loads(subprocess.check_output(['adom-bridge','--target','AdomLapper','--ai-thread','adom-custom-load',v,json.dumps(a)],text=True));(O/f'material-{label}.json').write_text(json.dumps(r,indent=2)+'\n');assert r.get('success',r.get('ok')),r;return r+call('pup_evaluate',dict(sessionId=session,expression='(()=>{const c=boardReview.viewer.getCamera();c.alpha=-Math.PI/2;c.beta=Math.PI-.01;c.radius=.105;return {ready:boardReview.ready}})()'),'camera-before')+r=call('desktop_record_start',dict(hwnd=10291968,cursor=False,audio=False,fps=30,maxDurationMs=60000,reason='Record actual opaque silkscreen/substrate visual correction; mesh geometry unchanged'),'record-start')+try:+ time.sleep(1.5)+ call('pup_evaluate',dict(sessionId=session,expression='(async()=>{await boardReview.viewer.loadModel("board23-opaque-review.glb");const c=boardReview.viewer.getCamera();c.alpha=-Math.PI/2;c.beta=Math.PI-.01;c.radius=.105;boardReview.camera=c;document.querySelector("#status").textContent="Opaque ink/substrate experiment — geometry unchanged";return {ready:true}})()'),'load-opaque')+ time.sleep(2)+ call('pup_evaluate',dict(sessionId=session,expression='(()=>{boardReview.camera.beta=2.8;return {beta:boardReview.camera.beta}})()'),'tilt')+ time.sleep(1.5)+finally:+ stop=call('desktop_record_stop',dict(recordingId=r['recordingId']),'record-stop');call('pull_file',dict(filePaths=[stop.get('path',r['path'])],saveTo=str(R/'videos/raw')),'record-pull')+print('Material comparison take complete; visual review still required')
tools/refine_bottom_association.pyadded+16
@@ -0,0 +1,16 @@+#!/usr/bin/env python3+"""Resolve one known cross-component association against the full proposal."""+import json,math,hashlib+from pathlib import Path+P=Path(__file__).resolve().parents[1]/'design/silkscreen-review';s=json.loads((P/'bottom-candidates.json').read_text());l=json.loads((P/'bottom-layout.json').read_text());gap=s['clearance']+def overlap(a,b):return not(a[2]+gap<=b[0] or b[2]+gap<=a[0] or a[3]+gap<=b[1] or b[3]+gap<=a[1])+g=next(g for g in s['labels'] if g['id']=='R9');target=[120.6,75.2,121,75.6];options=[]+for c in g['candidates']:+ if any(overlap(b,o['box']) for b in c['boxes'] for o in s['obstacles']):continue+ if any(overlap(b,target) for b in c['boxes']):continue+ if any(overlap(b,z) for b in c['boxes'] for h in l['placements'] if h['id']!='R9' for z in h['boxes']):continue+ options.append(c)+print('R9 alternatives preserving R10 endpoint:',len(options))+assert options,'Expand local association candidates before changing the board'+c=min(options,key=lambda c:math.dist(c['position'],g['anchor']));l['placements']=[dict(c,id='R9') if h['id']=='R9' else h for h in l['placements']];(P/'bottom-layout.json').write_text(json.dumps(l,indent=2)+'\n')+t=json.loads((P/'bottom-association-targets.json').read_text());t.append(dict(reference='R10',point=[120.8,75.4],bodyProjection=[120.55,74.92,121.05,75.92],reason='Keep R9 text clear of R10 projected body'));(P/'bottom-association-targets.json').write_text(json.dumps(t,indent=2)+'\n');s['obstacles'].append(dict(id='target:R10',reference='R10',kind='association-target',layer='B.SilkS',box=target));(P/'bottom-candidates.json').write_text(json.dumps(s)+'\n');print('R9 moved to',c['position'])
tools/render_bottom_candidate.pyadded+7
@@ -0,0 +1,7 @@+#!/usr/bin/env python3+import json,subprocess+from pathlib import Path+R=Path(__file__).resolve().parents[1];P=R/'design/silkscreen-review';host='C:/Users/john/adom-projects/adom-custom-electronic-load/kicad';cli='C:/Users/john/AppData/Local/Programs/KiCad/10.0/bin/kicad-cli.exe'+for side in ['bottom','top']:+ r=json.loads(subprocess.check_output(['adom-bridge','--target','AdomLapper','--ai-thread','adom-custom-load','shell_execute',json.dumps(dict(command=f'"{cli}" pcb render --side {side} --width 1800 --height 2000 --quality high --output "{host}/bottom-candidate-{side}.png" "{host}/bottom-artwork-candidate.kicad_pcb"',timeoutSeconds=120,reason='Native isolated artwork render; keep the live editor unchanged'))],text=True));(P/f'bottom-render-{side}.json').write_text(json.dumps(r,indent=2));assert r.get('success') and r.get('exitCode')==0,r+r=json.loads(subprocess.check_output(['adom-bridge','--target','AdomLapper','--ai-thread','adom-custom-load','pull_file',json.dumps(dict(filePaths=[host+'/bottom-candidate-'+s+'.png' for s in ['bottom','top']],saveTo=str(P)))],text=True));assert r.get('success',r.get('ok'));print('Native candidate top and bottom renders pulled')
tools/review_front_candidate.pyadded+38
@@ -0,0 +1,38 @@+#!/usr/bin/env python3+"""Create/check/render isolated front legends; keep the live board unchanged."""+import json,hashlib,uuid,shutil,subprocess,re,math,copy+from pathlib import Path+from sexp import parse,find,first+R=Path(__file__).resolve().parents[1];O=R/'design/silkscreen-review/front-contacts';a=json.loads((O/'artwork.json').read_text());assert not a['findings'];source=R/'kicad/adom-custom-electronic-load.kicad_pcb';raw=source.read_bytes();assert hashlib.sha256(raw).hexdigest()==a['boardSha256'];text=raw.decode();original=parse(text);nodes=[]+move=a['fieldMoves'][0];fp=next(f for f in find(original,'footprint') if any(p[1:3]==['Reference','J8'] for p in find(f,'property')));prop=next(p for p in find(fp,'property') if p[1]=='Reference');field_id=first(prop,'uuid')[1];at=first(fp,'at');theta=math.radians(float(at[3]) if len(at)>3 else 0);dx=move['after'][0]-float(at[1]);dy=move['after'][1]-float(at[2]);lx=dx*math.cos(theta)-dy*math.sin(theta);ly=dx*math.sin(theta)+dy*math.cos(theta);rotation=first(prop,'at')[3]+stack=[];matched=0+for m in re.finditer(r'"(?:\\.|[^"\\])*"|[()]',text):+ if m.group()=='(':stack.append(m.start())+ elif m.group()==')':+  start=stack.pop()+  if text.startswith('(property ',start) and field_id in text[start:m.end()]:+   fragment=text[start:m.end()];fragment,n=re.subn(r'\(at\s+[^()]+\)',f'(at {lx:.9g} {ly:.9g} {rotation})',fragment,count=1);assert n==1;text=text[:start]+fragment+text[m.end():];matched+=1;break+assert matched==1+for t in a['texts']:+ size=t['size'];nodes.append(f'(gr_text {json.dumps(t["text"])} (at {t["x"]:.9f} {t["y"]:.9f} {t.get("angle",0)}) (layer "F.SilkS") (uuid "{uuid.uuid4()}") (effects (font (size {size} {size}) (thickness {t["stroke"]}))))')+for g in a['graphics']:+ (x,y),(X,Y)=g['points'];nodes.append(f'(gr_line (start {x:.9f} {y:.9f}) (end {X:.9f} {Y:.9f}) (stroke (width {g["stroke"]}) (type solid)) (layer "F.SilkS") (uuid "{uuid.uuid4()}"))')+pos=text.rfind(')');new=text[:pos]+'\n'+'\n'.join(nodes)+'\n'+text[pos:];assert parse(new)[:-len(nodes)]==parse(text)+def neutralize(v):+ v=copy.deepcopy(v)+ for f in find(v,'footprint'):+  for p in find(f,'property'):+   if first(p,'uuid')==['uuid',field_id]:p[:]=['reviewed-reference',field_id]+ return v+assert neutralize(parse(text))==neutralize(original),'Unrelated data changed'+candidate=R/'kicad/front-contact-candidate.kicad_pcb';candidate.write_bytes(new.encode())+for ext in ['.kicad_pro','.kicad_dru']:shutil.copyfile(source.with_suffix(ext),candidate.with_suffix(ext))+report=dict(status='isolated candidate',sourceSha256=a['boardSha256'],candidateSha256=hashlib.sha256(new.encode()).hexdigest(),texts=len(a['texts']),graphics=len(a['graphics']),allPreviousParsedBoardDataUnchangedExceptJ8Reference=True,referenceMove=move,referenceFieldId=field_id);(O/'candidate-review.json').write_text(json.dumps(report,indent=2)+'\n')+host='C:/Users/john/adom-projects/adom-custom-electronic-load/kicad';cli='C:/Users/john/AppData/Local/Programs/KiCad/10.0/bin/kicad-cli.exe'+def call(v,p,label):+ r=json.loads(subprocess.check_output(['adom-bridge','--target','AdomLapper','--ai-thread','adom-custom-load',v,json.dumps(p)],text=True));(O/(label+'.json')).write_text(json.dumps(r,indent=2)+'\n');assert r.get('success',r.get('ok')) and r.get('exitCode',0)==0,r;return r+call('send_files',dict(filePaths=[str(candidate.with_suffix(e)) for e in ['.kicad_pcb','.kicad_pro','.kicad_dru']],dest=host,reason='Check isolated front contact legends without changing the live board'),'send')+r=call('shell_execute',dict(command=f'"{cli}" pcb drc --format json --output "{host}/front-contact-drc.json" "{host}/front-contact-candidate.kicad_pcb"',timeoutSeconds=120,reason='Native project-aware DRC for front contact legends'),'drc-command');print(r['stdout'],flush=True)+call('pull_file',dict(filePaths=[host+'/front-contact-drc.json'],saveTo=str(O)),'drc-pull');d=json.loads((O/'front-contact-drc.json').read_text());assert not d['violations'] and not d['unconnected_items']+call('shell_execute',dict(command=f'"{cli}" pcb render --side top --width 1800 --height 2000 --quality high --output "{host}/front-contact-candidate.png" "{host}/front-contact-candidate.kicad_pcb"',timeoutSeconds=120,reason='Inspect front legends against the fitted components in native KiCad'),'render-command')+call('pull_file',dict(filePaths=[host+'/front-contact-candidate.png'],saveTo=str(O)),'render-pull');print('Front candidate DRC clean and native render ready',flush=True)
tools/verify_bottom_landing.pyadded+40
@@ -0,0 +1,40 @@+#!/usr/bin/env python3+"""Compare native saved readback with the original and the reviewed artwork."""+import json,hashlib,collections,math+from pathlib import Path+from sexp import parse,find,first+R=Path(__file__).resolve().parents[1];P=R/'design/silkscreen-review';old=R/'kicad/adom-custom-electronic-load.kicad_pcb';new=P/'landed/adom-custom-electronic-load.kicad_pcb';a=json.loads((P/'bottom-artwork.json').read_text());before=parse(old.read_text());after=parse(new.read_text());assert hashlib.sha256(old.read_bytes()).hexdigest()==a['boardSha256']+def stable(nodes):return sorted(json.dumps(n,sort_keys=True) for n in nodes)+physical=['footprint','segment','arc','via','zone','net','setup','layers','gr_arc','gr_poly']+checks={kind:stable(find(before,kind))==stable(find(after,kind)) for kind in physical}+# KiCad serializes near-zero reference coordinates as literal zero. Restrict+# normalization to that exact harmless save behavior, never pads or copper.+import copy+def normalized_footprints(board):+ rows=copy.deepcopy(find(board,'footprint'))+ for f in rows:+  for p in find(f,'property'):+   if p[1]!='Reference':continue+   at=first(p,'at')+   for i in [1,2]:+    if abs(float(at[i]))<1e-12:at[i]='0'+ return rows+checks['footprint']=stable(normalized_footprints(before))==stable(normalized_footprints(after))+assert all(checks.values()),checks+oldtexts=find(before,'gr_text');newtexts=find(after,'gr_text');oldlines=find(before,'gr_line');newlines=find(after,'gr_line')+def key(n):return first(n,'uuid')[1]+oldmap={key(n):n for n in oldtexts+oldlines};newmap={key(n):n for n in newtexts+newlines};assert all(newmap.get(k)==n for k,n in oldmap.items()),'Existing standalone artwork changed'+texts=[n for n in newtexts if key(n) not in oldmap];lines=[n for n in newlines if key(n) not in oldmap];assert len(texts)==len(a['texts']) and len(lines)==len(a['graphics'])+remaining=texts.copy();mapping=[]+for t in a['texts']:+ size=t.get('size',t.get('height'));rot=t.get('angle',t.get('rotation',0));matches=[]+ for n in remaining:+  at=first(n,'at');effects=first(n,'effects');font=first(effects,'font');sz=first(font,'size');stroke=first(font,'thickness');justify=first(effects,'justify')+  if n[1]==t['text'] and first(n,'layer')[1]=='B.SilkS' and math.dist(list(map(float,at[1:3])),[t['x'],t['y']])<1e-5 and abs(float(at[3] if len(at)>3 else 0)-rot)<1e-5 and abs(float(sz[1])-size)<1e-6 and abs(float(sz[2])-t.get('width',size))<1e-6 and abs(float(stroke[1])-t['stroke'])<1e-6 and justify and 'mirror' in justify:matches.append(n)+ assert len(matches)==1,(t['text'],len(matches));n=matches[0];remaining.remove(n);mapping.append(dict(id=key(n),text=t['text'],reference=t.get('reference'),x=t['x'],y=t['y']))+remaining=lines.copy()+for g in a['graphics']:+ matches=[n for n in remaining if first(n,'layer')[1]=='B.SilkS' and math.dist(list(map(float,first(n,'start')[1:3])),g['points'][0])<1e-5 and math.dist(list(map(float,first(n,'end')[1:3])),g['points'][1])<1e-5 and abs(float(first(first(n,'stroke'),'width')[1])-g['stroke'])<1e-6]+ assert len(matches)==1,(g,len(matches));remaining.remove(matches[0])+report=dict(status='native saved readback matches reviewed artwork',sourceSha256=a['boardSha256'],savedSha256=hashlib.sha256(new.read_bytes()).hexdigest(),unchanged=checks,addedTexts=len(texts),addedGraphics=len(lines),nativeTextIds=mapping,nativeGraphicIds=[key(n) for n in lines],nativeDRCStillRequired=True,normalizationNote='Eight pre-existing Reference coordinates below 1e-12 mm serialized to zero; no pad, component placement or copper change')+(P/'bottom-landing-verification.json').write_text(json.dumps(report,indent=2)+'\n');print(json.dumps({k:v for k,v in report.items() if k not in ['nativeTextIds','nativeGraphicIds']}))
tools/verify_front_landing.pyadded+17
@@ -0,0 +1,17 @@+#!/usr/bin/env python3+"""Require exact reviewed board content, allowing only native number formatting."""+import json,hashlib,decimal+from pathlib import Path+from sexp import parse+R=Path(__file__).resolve().parents[1];O=R/'design/silkscreen-review/front-contacts';candidate=R/'kicad/front-contact-candidate.kicad_pcb';saved=O/'landed/adom-custom-electronic-load.kicad_pcb';review=json.loads((O/'candidate-review.json').read_text());assert hashlib.sha256(candidate.read_bytes()).hexdigest()==review['candidateSha256']+def norm(v):+ if isinstance(v,list):return [norm(x) for x in v]+ try:+  n=decimal.Decimal(v)+  if not n.is_finite():return v+  return str(n.quantize(decimal.Decimal('0.000001')).normalize())+ except (decimal.InvalidOperation,ValueError,TypeError):return v+before=norm(parse(candidate.read_text()));after=norm(parse(saved.read_text()));assert before[0]==after[0]+a=sorted(json.dumps(x) for x in before[1:]);b=sorted(json.dumps(x) for x in after[1:]);assert a==b,'Saved board differs from candidate beyond native 1 nm formatting'+report=dict(status='native saved board matches reviewed candidate',savedSha256=hashlib.sha256(saved.read_bytes()).hexdigest(),sourceSha256=review['sourceSha256'],candidateSha256=review['candidateSha256'],comparison='Full parsed root content; order-independent root nodes; numeric formatting normalized to 1 nm',addedTexts=review['texts'],addedGraphics=review['graphics'],referenceMove=review['referenceMove'],circuitAndCopperUnchanged=True,nativeRevision='8ad5cf23aeb0d12845a382355905c713d28f877ba8c5d1127534893ec4c45fed',nativeDrcPending=True)+(O/'landing-verification.json').write_text(json.dumps(report,indent=2)+'\n');print(json.dumps(report,indent=2))
videos/inventory.json+19−2
@@ -1,6 +1,6 @@ {-  "rawTakeCount": 95,-  "reviewedExcerptCount": 38,+  "rawTakeCount": 97,+  "reviewedExcerptCount": 40,   "countingRule": "Unique raw window recording filenames in this project; excludes derivative action/speed exports and reference projects. Raw count includes rejected takes.",   "takes": [     {@@ -572,6 +572,18 @@       "durationSeconds": 18.433333,       "topic": "Native 3D reference-label review after saved-file rework",       "review": "Raw/contact sheet and edited contact sheet reviewed; excerpt fully decoded. 4.5-second 2x crop. Bare PCB only, no thermal qualification. Recorder elapsed17.944s versus encoded18.433s; timeline repair warning retained, not timing evidence."+    },+    {+      "file": "videos/raw/window-1124570-20261010-232726.mp4",+      "durationSeconds": 33.633333,+      "topic": "Native bottom text and contact frames appear on board23",+      "review": "Raw contact sheets and edited poster reviewed; full edited decode passed. 6.8-second 2x cut removes idle time. Native 3D review, not a smooth hero render. Recorder timeline repair warning retained: 33.019s elapsed versus 33.633s encoded; not timing evidence."+    },+    {+      "file": "videos/raw/window-10291968-20261010-234532.mp4",+      "durationSeconds": 5.466667,+      "topic": "Actual GLB substrate and silkscreen material correction",+      "review": "Contact sheet reviewed: faint ink becomes readable without geometry change. Full excerpt decode passed. Recorder timing warning retained; not a timing benchmark."     }   ],   "replays": [@@ -580,6 +592,11 @@       "kind": "recorded-event replay, not raw native process footage",       "excerpt": "docs/clips/silkscreen-candidate-replay.mp4",       "review": "Contact sheet reviewed, full excerpt decode passed. Earlier 93/94 proposal, no native edits claimed."+    },+    {+      "file": "aiflow/run/silkscreen-dashboard/recordings/replay-1791673332110200643.webm",+      "kind": "recorded-event replay, not raw native process footage",+      "review": "Earlier 104-group bottom proposal, superseded by later association and contact-tag rework. Not promoted to reviewed excerpt."     }   ] }