unzip -p ${archivePath} ${platedDrillFilename}`.text()\nconst toolDiameters = new Map\u003cstring, number\u003e()\nfor (const match of drillText.matchAll(/^T(\\d+)C([0-9.]+)$/gm)) {\n toolDiameters.set(match[1], Number(match[2]))\n}\n\nlet activeTool = \"\"\nlet viaDrillCount = 0\nfor (const line of drillText.split(/\\r?\\n/)) {\n const toolMatch = line.match(/^T(\\d+)$/)\n if (toolMatch) {\n activeTool = toolMatch[1]\n continue\n }\n if (line.startsWith(\"X\") \u0026\u0026 Math.abs((toolDiameters.get(activeTool) ?? 0) - 0.2) \u003c 1e-6) {\n viaDrillCount += 1\n }\n}\nif (viaDrillCount !== vias.length) {\n throw new Error(\n `Via/drill mismatch: Circuit JSON has ${vias.length} vias but ${platedDrillFilename} has ${viaDrillCount} 0.20 mm drills`,\n )\n}\n\nconst parseDesignators = async (path: string, column: number) =\u003e\n (await Bun.file(path).text())\n .trim()\n .split(/\\r?\\n/)\n .slice(1)\n .map((line) =\u003e line.split(\",\")[column])\n .filter(Boolean)\n .sort()\n\nconst bomDesignators = await parseDesignators(`${outputDir}/jlc_bom.csv`, 1)\nconst cplDesignators = await parseDesignators(`${outputDir}/jlc_cpl.csv`, 0)\nconst manualDesignators = await parseDesignators(`${outputDir}/manual_assembly.csv`, 0)\nconst dnpDesignators = await parseDesignators(`${outputDir}/dnp.csv`, 0)\nif (bomDesignators.join(\"|\") !== cplDesignators.join(\"|\")) {\n throw new Error(\"JLC BOM and CPL designator sets do not match\")\n}\nif (manualDesignators.join(\"|\") !== [\"J1\", \"U3\", \"U3-OPTICS\"].sort().join(\"|\")) {\n throw new Error(`Unexpected manual/consigned set: ${manualDesignators.join(\", \")}`)\n}\nif (dnpDesignators.join(\"|\") !== [\"D0_IND\", \"R0\"].sort().join(\"|\")) {\n throw new Error(`Unexpected DNP set: ${dnpDesignators.join(\", \")}`)\n}\nfor (const excluded of [\"J1\", \"U3\", \"R0\", \"D0_IND\"]) {\n if (bomDesignators.includes(excluded)) {\n throw new Error(`${excluded} must not appear in the JLC SMT BOM/CPL`)\n }\n}\n\nconst bomText = await Bun.file(`${outputDir}/jlc_bom.csv`).text()\nfor (const [designator, footprint, lcsc] of [\n [\"U1\", \"SOT-23-5_LCSC_C53099\", \"C53099\"],\n [\"U2\", \"SOT-23-5_LCSC_C236671\", \"C236671\"],\n] as const) {\n const row = bomText\n .trim()\n .split(/\\r?\\n/)\n .find((line) =\u003e line.split(\",\")[1] === designator)\n if (!row || !row.includes(footprint) || !row.endsWith(`,${lcsc}`)) {\n throw new Error(`${designator} is missing its verified imported footprint/C-number`)\n }\n}\nconst manualText = await Bun.file(`${outputDir}/manual_assembly.csv`).text()\nif (!manualText.includes(\"J1,Manual/rear-side THT\") || !manualText.includes(\"C492426\")) {\n throw new Error(\"J1 must remain a manual rear-side C492426 THT operation\")\n}\nif (!manualText.includes(\"OV7670-VL2A\") || manualText.includes(\"OV07670-VL2A\")) {\n throw new Error(\"U3 must use the exact OV7670-VL2A manual/consigned MPN\")\n}\n\nconsole.log(\n `Production verification passed: ${vias.length}/${viaDrillCount} through vias, ` +\n `${minViaHoleToTraceClearance.toFixed(3)} mm minimum via-hole-to-trace clearance, ` +\n `${bomDesignators.length} matched JLC SMT placements, ${minWireWidth.toFixed(2)}-${maxWireWidth.toFixed(2)} mm routed copper, ` +\n `connected V2V8/GND inner planes, explicit manual/consigned and DNP sets.`,\n)\n","content_mimetype":"text/typescript","created_at":"2026-08-24T13:23:42.504Z"}; window.SSR_PACKAGE_RELEASES = [{"package_release_id":"b165339e-f482-4d8c-9803-33fb4333a2b6","package_id":"664d9097-5b33-4886-9c4c-127597354ec8","version":"1.0.7","github_commit_sha":null,"is_locked":false,"is_latest":true,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-24T13:23:41.618Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-e4247102fc0198eef628891988afe5cd","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b165339e-f482-4d8c-9803-33fb4333a2b6\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"f2715047-0158-4258-88d6-1a58ee4150c6","user_code_job_started_at":"2026-08-24T13:23:44.508Z","user_code_job_completed_at":"2026-08-24T13:25:35.736Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=08a1e392f8de01ebaa77e50228e22d61099362826a7f93bfb39491c8dcafe51a","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"99c5f93b-edfc-4cac-a582-ec8988f59d85","package_id":"664d9097-5b33-4886-9c4c-127597354ec8","version":"1.0.6","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-24T12:16:13.016Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-14b3010608ac46b7c76ddb0bdf1c2769","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=99c5f93b-edfc-4cac-a582-ec8988f59d85\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"15e59836-d9a1-484a-9d3c-027d94bbfaa5","user_code_job_started_at":"2026-08-24T12:16:34.107Z","user_code_job_completed_at":"2026-08-24T12:18:35.336Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=0e62e5ec538c8f68c53b99737a0fafceab877a619b69683629cae5f694cb1912","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"e5912aea-226c-4f88-8c9c-72c31b06fd28","package_id":"664d9097-5b33-4886-9c4c-127597354ec8","version":"1.0.5","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-20T14:13:29.867Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-e28760f00ede8a7b77c3bc349d506a19","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=e5912aea-226c-4f88-8c9c-72c31b06fd28\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"22dc075e-a7b9-4418-b244-6b9a75f6bac4","user_code_job_started_at":"2026-08-20T14:13:43.035Z","user_code_job_completed_at":"2026-08-20T14:15:02.833Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=a19e6bb13decec7243bdae99f42bd560e87b2aa513253d9249ca153e39baa48f","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"adaf2e95-a0ac-4720-936b-6ac03722ca3f","package_id":"664d9097-5b33-4886-9c4c-127597354ec8","version":"1.0.4","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-19T00:39:14.298Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-994de436614f12537d7cfbb1e3cede9d","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=adaf2e95-a0ac-4720-936b-6ac03722ca3f\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=adaf2e95-a0ac-4720-936b-6ac03722ca3f\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=adaf2e95-a0ac-4720-936b-6ac03722ca3f\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"8527b33b-ded7-40db-a351-f683a91f962f","user_code_job_started_at":"2026-08-19T00:39:26.978Z","user_code_job_completed_at":"2026-08-19T00:40:43.859Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=36c294e97efbc02cb1f5a3cee7989e9da70361030f8bc8c35750c656c84ff37c","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"b9d7e5e9-8ccd-4a35-9104-ce01b96a5d06","package_id":"664d9097-5b33-4886-9c4c-127597354ec8","version":"1.0.3","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-19T00:07:28.636Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-cb973d6bca7a6dae029a18bcd1d23d23","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b9d7e5e9-8ccd-4a35-9104-ce01b96a5d06\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b9d7e5e9-8ccd-4a35-9104-ce01b96a5d06\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b9d7e5e9-8ccd-4a35-9104-ce01b96a5d06\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"66d0c808-6000-42b8-8bde-b613951f0119","user_code_job_started_at":"2026-08-19T00:07:46.822Z","user_code_job_completed_at":"2026-08-19T00:09:03.633Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=713a42525c5e9fcb1f6f1d6daad467cac62349b64b1a813eb475df8a30adcf79","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"8abc9cf1-1b18-4c13-8f58-cd906fd74e43","package_id":"664d9097-5b33-4886-9c4c-127597354ec8","version":"1.0.2","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-18T23:57:25.951Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-c99083b1daa2cb4da65a0ac5ae8a0e49","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=8abc9cf1-1b18-4c13-8f58-cd906fd74e43\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=8abc9cf1-1b18-4c13-8f58-cd906fd74e43\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=8abc9cf1-1b18-4c13-8f58-cd906fd74e43\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"7e7daa5e-98ce-4ca2-a6e8-296ea3ca72d0","user_code_job_started_at":"2026-08-18T23:57:38.230Z","user_code_job_completed_at":"2026-08-18T23:58:59.810Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=88340a9e3692f0b54950adaa5c3423906ebfb044b63b3a9745eb8b6196806f4a","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"414c9ebb-9247-40c7-8d8a-ba0e4d698875","package_id":"664d9097-5b33-4886-9c4c-127597354ec8","version":"1.0.1","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-18T22:15:42.595Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-383811e5ffcd7942eb8e70a73c595b41","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=414c9ebb-9247-40c7-8d8a-ba0e4d698875\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=414c9ebb-9247-40c7-8d8a-ba0e4d698875\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=414c9ebb-9247-40c7-8d8a-ba0e4d698875\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"78142397-6ddd-4227-946a-da9bf1d95353","user_code_job_started_at":"2026-08-18T22:15:56.658Z","user_code_job_completed_at":"2026-08-18T22:17:28.314Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=9bd740be2027af3a920052af61972055380555b97d3f0756364fd5e19765d1e0","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"52546987-10f7-466e-b303-d30801ffd712","package_id":"664d9097-5b33-4886-9c4c-127597354ec8","version":"1.0.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-18T20:46:22.846Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-3be1207a47d60b8c8c46639dc473f393","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=52546987-10f7-466e-b303-d30801ffd712\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=52546987-10f7-466e-b303-d30801ffd712\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=52546987-10f7-466e-b303-d30801ffd712\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"cbf46b05-5b90-4dd1-ba13-badef7cc552d","user_code_job_started_at":"2026-08-18T20:46:36.242Z","user_code_job_completed_at":"2026-08-18T20:47:46.933Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=2a2bfa73e897b5fdfc39bf5120e5714f10a7a0db840f2d376111ec710f8b3404","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null}]; window.SSR_PACKAGE_BUILDS = []; window.SSR_RELATED_PACKAGES = [{"package_id":"1ef78ebd-82a5-4c8f-9d50-20d2214060d3","creator_account_id":"8d5e1af7-a381-4aaf-b208-56fa4e9d5a45","latest_package_release_id":"9f04d6d0-fd31-46e9-9b60-a3245f1c282a","last_built_release_id":"9f04d6d0-fd31-46e9-9b60-a3245f1c282a","latest_package_release_fs_sha":"md5-5b46693fb1aca8fd65f3ee614c9a93e6","latest_pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=9f04d6d0-fd31-46e9-9b60-a3245f1c282a\u0026file_path=dist%2Fddr-only%2Fpcb.svg","latest_sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=9f04d6d0-fd31-46e9-9b60-a3245f1c282a\u0026file_path=dist%2Fddr-only%2Fschematic.svg","latest_cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=9f04d6d0-fd31-46e9-9b60-a3245f1c282a\u0026file_path=dist%2Fddr-only%2F3d.png","latest_version":"1.0.16","license":"unset","owner_org_id":"94044d23-fb18-49b3-bcb5-8a702defe7d6","org_owner_tscircuit_handle":"0hmX","owner_github_username":"0hmX","github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"0hmX/simplified-am62l-computer","unscoped_name":"simplified-am62l-computer","star_count":0,"created_at":"2026-08-07T16:09:40.939Z","updated_at":"2026-08-24T13:46:34.470Z","ai_description":"This code defines components and scripts for physically representing and routing high-speed DDR memory signals, power lines, and ground planes on an 8-layer PCB with detailed pin assignments, copper pours, and precise via and trace layouts based on TI EVM reference data.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"same_author","thumbnail_url":"https://api.tscircuit.com/package_files/view?package_release_id=9f04d6d0-fd31-46e9-9b60-a3245f1c282a\u0026file_path=dist%2Fddr-only%2Fpcb.svg"},{"package_id":"ede89d02-7042-4b78-b370-4f9e9ce24568","creator_account_id":"9f398687-69d0-4ef4-a48c-bb6dc990e7df","latest_package_release_id":"0d3197ed-fd8c-4290-8fde-e32ec62ed9c5","last_built_release_id":"0d3197ed-fd8c-4290-8fde-e32ec62ed9c5","latest_package_release_fs_sha":"md5-4e43da8ec34f8f294e7327fc4121c168","latest_pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0d3197ed-fd8c-4290-8fde-e32ec62ed9c5\u0026file_path=dist%2Findex%2Fpcb.svg","latest_sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0d3197ed-fd8c-4290-8fde-e32ec62ed9c5\u0026file_path=dist%2Findex%2Fschematic.svg","latest_cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0d3197ed-fd8c-4290-8fde-e32ec62ed9c5\u0026file_path=dist%2Findex%2F3d.png","latest_version":"1.3.0","license":"unset","owner_org_id":"f154d4e0-ac63-47a3-948e-a13da34df910","org_owner_tscircuit_handle":"seveibar","owner_github_username":"seveibar","github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"seveibar/f1c100s-dev-board","unscoped_name":"f1c100s-dev-board","star_count":0,"created_at":"2026-09-13T23:03:15.223Z","updated_at":"2026-09-13T23:47:36.981Z","ai_description":"This code defines the hardware layout and schematic for a four-layer F1C100S-based module, including footprint placement, pin mappings, power regulation, decoupling capacitors, support components, and routing configurations, enabling automated PCB generation, routing, and verification.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"similar_ai_description","thumbnail_url":"https://api.tscircuit.com/package_files/view?package_release_id=0d3197ed-fd8c-4290-8fde-e32ec62ed9c5\u0026file_path=dist%2Findex%2Fpcb.svg"},{"package_id":"7065b9a6-03de-43a1-ba42-2a0ead33b548","creator_account_id":"1f745cb8-1b99-4215-905f-f8e3dc29bc28","latest_package_release_id":"5746ef1e-d91a-4043-9db3-2cc17f89d777","last_built_release_id":"5746ef1e-d91a-4043-9db3-2cc17f89d777","latest_package_release_fs_sha":"md5-27fc15676f25d1e3a229466d1de0fe7a","latest_pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2Fpcb.svg","latest_sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2Fschematic.svg","latest_cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2F3d.png","latest_version":"1.0.1","license":"unset","owner_org_id":"60917f07-d371-4c51-854f-e2bd7dab9e5a","org_owner_tscircuit_handle":"hrithik18k","owner_github_username":null,"github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"hrithik18k/smart-switch-pcb","unscoped_name":"smart-switch-pcb","star_count":0,"created_at":"2026-09-09T11:12:10.428Z","updated_at":"2026-09-09T11:56:59.112Z","ai_description":"The AO3400A component models a SOT-23 N-channel MOSFET with labeled pins for Gate, Source, and Drain, including 3D CAD models and schematic symbols for electronic circuit design.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"random","thumbnail_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2Fpcb.svg"}]; window.SSR_PACKAGE_ROUTE = {"author":"0hmX","packageName":"robocraze-ov7670-camera-module-clone","packageNameWithScope":"0hmX/robocraze-ov7670-camera-module-clone","version":null,"isLegacyRoute":false,"kind":"file","filePath":"scripts/verify-production.ts"};

0hmX/robocraze-ov7670-camera-module-clone

This code defines and generates a 4-layer PCB hardware layout featuring an OV7670 VGA camera sensor module with fixed component placement, power regulation using ME6211 voltage regulators, a 2x9 header interface, and associated signal routing and mechanical footprints, designed for manufacturing and assembly.

Version
1.0.7
License
MIT
Stars
0

scripts/verify-production.ts

import { checkViaTraceClearance } from "@tscircuit/checks"

type CircuitElement = {
  type: string
  pcb_via_id?: string
  pcb_trace_id?: string
  from_layer?: string
  to_layer?: string
  outer_diameter?: number
  hole_diameter?: number
  layer?: string
  source_net_id?: string
  source_component_id?: string
  source_trace_id?: string
  name?: string
  display_name?: string
  min_trace_thickness?: number
  num_layers?: number
  min_trace_width?: number
  min_via_hole_diameter?: number
  min_via_pad_diameter?: number
  min_trace_to_pad_edge_clearance?: number
  min_via_edge_to_pad_edge_clearance?: number
  min_pad_edge_to_pad_edge_clearance?: number
  min_plated_hole_drill_edge_to_drill_edge_clearance?: number
  min_via_hole_edge_to_via_hole_edge_clearance?: number
  min_board_edge_clearance?: number
  brep_shape?: { outer_ring?: { vertices?: Array<{ x: number; y: number }> } }
  route?: Array<{ route_type: string; layer?: string; width?: number }>
}

const projectDir = new URL("../", import.meta.url).pathname
const outputDir = `${projectDir}dist/index`
const circuitJsonPath = `${outputDir}/circuit.json`
const archivePath = `${outputDir}/robocraze-ov7670-gerbers.zip`

const elements = (await Bun.file(circuitJsonPath).json()) as CircuitElement[]
const diagnostics = elements.filter((element) => /error|warning/.test(element.type))
if (diagnostics.length > 0) {
  throw new Error(`Circuit JSON contains ${diagnostics.length} error/warning records`)
}

const board = elements.find((element) => element.type === "pcb_board")
if (
  board?.num_layers !== 4 ||
  board.min_trace_width !== 0.1 ||
  board.min_via_hole_diameter !== 0.2 ||
  board.min_via_pad_diameter !== 0.45 ||
  board.min_trace_to_pad_edge_clearance !== 0.1 ||
  board.min_via_edge_to_pad_edge_clearance !== 0.1 ||
  board.min_pad_edge_to_pad_edge_clearance !== 0.1 ||
  board.min_via_hole_edge_to_via_hole_edge_clearance !== 0.2 ||
  board.min_plated_hole_drill_edge_to_drill_edge_clearance !== 0.15 ||
  board.min_board_edge_clearance !== 0.3
) {
  throw new Error("PCB fabrication-rule assertions do not match the qualified 4-layer build")
}

const sourceTraces = elements.filter(
  (element) => element.type === "source_trace",
)
const sourceTraceById = new Map(
  sourceTraces.map((trace) => [trace.source_trace_id, trace]),
)
const expectedSourceTraceWidths = new Map<string, number>([
  ["J1_3V3_TO_net_V3V3", 0.3],
  ["J1_GND_TO_net_GND", 0.3],
  ["U1_VOUT_TO_C2_pin1", 0.25],
  ["U2_VOUT_TO_C6_pin1", 0.25],
  ["R1_pin2_TO_C12_pin1", 0.2],
  ["R2_pin2_TO_C9_pin1", 0.2],
  ["C16_pin1_TO_U3_DVDD", 0.2],
])
for (const [name, width] of expectedSourceTraceWidths) {
  const trace = sourceTraces.find((candidate) => candidate.name === name)
  if (trace?.min_trace_thickness !== width) {
    throw new Error(`${name} must request ${width.toFixed(2)} mm copper`)
  }
}

const pcbTraces = elements.filter((element) => element.type === "pcb_trace")
const wireSegments = pcbTraces.flatMap((trace) =>
  (trace.route ?? []).filter(
    (point): point is { route_type: string; layer?: string; width: number } =>
      point.route_type === "wire" && point.width !== undefined,
  ),
)
const minWireWidth = Math.min(...wireSegments.map((segment) => segment.width))
const maxWireWidth = Math.max(...wireSegments.map((segment) => segment.width))
if (minWireWidth < 0.1 || maxWireWidth < 0.3) {
  throw new Error(
    `Unexpected routed width range ${minWireWidth.toFixed(3)}-${maxWireWidth.toFixed(3)} mm`,
  )
}

const allowedMinimumWidthSourceNames = new Set([
  "J1_HREF_TO_U3_HREF",
  "J1_XCLK_TO_U3_XCLK",
  "J1_D6_TO_U3_D6",
  "U3_VREF1_TO_C13_pin1",
  "U3_VREF2_TO_C14_pin1",
])
for (const trace of pcbTraces) {
  const hasMinimumWidth = (trace.route ?? []).some(
    (point) =>
      point.route_type === "wire" &&
      point.width !== undefined &&
      point.width <= 0.1000001,
  )
  if (!hasMinimumWidth) continue
  const sourceName = sourceTraceById.get(trace.source_trace_id)?.name
  if (!sourceName || !allowedMinimumWidthSourceNames.has(sourceName)) {
    throw new Error(
      `${trace.pcb_trace_id ?? trace.source_trace_id} uses 0.10 mm outside an approved CSP escape`,
    )
  }
}

const hrefRoute = pcbTraces.find(
  (trace) => trace.pcb_trace_id === "HREF_CSP_ESCAPE_AND_HEADER_ROUTE",
)
const hrefWidths = new Set(
  (hrefRoute?.route ?? [])
    .filter((point) => point.route_type === "wire")
    .map((point) => point.width),
)
if (!hrefWidths.has(0.1) || !hrefWidths.has(0.15)) {
  throw new Error("HREF must use a 0.10 mm CSP escape and 0.15 mm board route")
}

const vias = elements.filter((element) => element.type === "pcb_via")
const invalidViaSpans = vias.filter(
  (via) => new Set([via.from_layer, via.to_layer]).size !== 2 ||
    ![via.from_layer, via.to_layer].every((layer) => layer === "top" || layer === "bottom"),
)
if (invalidViaSpans.length > 0) {
  throw new Error(`${invalidViaSpans.length} vias are not top-to-bottom through vias`)
}

const viaById = new Map(vias.map((via) => [via.pcb_via_id, via]))
const viaTracePairs = checkViaTraceClearance(elements as never, {
  // A deliberately high threshold returns every foreign via/trace pair so
  // the verifier can compute the actual minimum hole-edge clearance.
  minClearance: 100,
})
const holeEdgeClearances = viaTracePairs.map((error) => {
  const via = viaById.get(error.pcb_via_id)
  if (!via?.outer_diameter || via.hole_diameter === undefined) {
    throw new Error(`Missing via geometry for ${error.pcb_via_id}`)
  }
  if (error.actual_clearance === undefined) {
    throw new Error(`Missing via/trace clearance for ${error.pcb_via_id}`)
  }
  const annularRing = (via.outer_diameter - via.hole_diameter) / 2
  return error.actual_clearance + annularRing
})
const minViaHoleToTraceClearance = Math.min(...holeEdgeClearances)
if (minViaHoleToTraceClearance < 0.2) {
  throw new Error(
    `Via-hole-to-foreign-trace clearance is ${minViaHoleToTraceClearance.toFixed(3)} mm; minimum is 0.200 mm`,
  )
}

const routedWireLayers = new Set(
  pcbTraces
    .flatMap((element) => element.route ?? [])
    .filter((point) => point.route_type === "wire")
    .map((point) => point.layer),
)
if ([...routedWireLayers].some((layer) => layer !== "top" && layer !== "bottom")) {
  throw new Error(`Signal routing uses inner layers: ${[...routedWireLayers].join(", ")}`)
}

const groundNet = elements.find(
  (element) => element.type === "source_net" && element.name === "GND",
)
const v2v8Net = elements.find(
  (element) => element.type === "source_net" && element.name === "V2V8",
)
const innerGroundPours = elements.filter(
  (element) =>
    element.type === "pcb_copper_pour" &&
    element.layer === "inner2" &&
    element.source_net_id === groundNet?.source_net_id,
)
if (
  innerGroundPours.length !== 1 ||
  !innerGroundPours[0].brep_shape?.outer_ring?.vertices?.length
) {
  throw new Error("Expected one connected inner2 GND copper-pour body")
}
const innerPowerPours = elements.filter(
  (element) =>
    element.type === "pcb_copper_pour" &&
    element.layer === "inner1" &&
    element.source_net_id === v2v8Net?.source_net_id,
)
if (
  innerPowerPours.length !== 1 ||
  !innerPowerPours[0].brep_shape?.outer_ring?.vertices?.length
) {
  throw new Error("Expected one connected inner1 V2V8 copper-pour body")
}

const platedDrillFilename = "drill-L1-L4.drl"
const drillText = await Bun.



  

  
  
  
  
  
  
  scripts/verify-production.ts - 0hmX/robocraze-ov7670-camera-module-clone - tscircuit
  
  
  
  
  
  
  
  
  
  
  
  

  
  

  
  
  
  
  
  
  scripts/verify-production.ts - 0hmX/robocraze-ov7670-camera-module-clone - tscircuit
  
  
  
  
  
  
  
  
  
  
  
  

  unzip -p ${archivePath} ${platedDrillFilename}`.text()\nconst toolDiameters = new Map\u003cstring, number\u003e()\nfor (const match of drillText.matchAll(/^T(\\d+)C([0-9.]+)$/gm)) {\n  toolDiameters.set(match[1], Number(match[2]))\n}\n\nlet activeTool = \"\"\nlet viaDrillCount = 0\nfor (const line of drillText.split(/\\r?\\n/)) {\n  const toolMatch = line.match(/^T(\\d+)$/)\n  if (toolMatch) {\n    activeTool = toolMatch[1]\n    continue\n  }\n  if (line.startsWith(\"X\") \u0026\u0026 Math.abs((toolDiameters.get(activeTool) ?? 0) - 0.2) \u003c 1e-6) {\n    viaDrillCount += 1\n  }\n}\nif (viaDrillCount !== vias.length) {\n  throw new Error(\n    `Via/drill mismatch: Circuit JSON has ${vias.length} vias but ${platedDrillFilename} has ${viaDrillCount} 0.20 mm drills`,\n  )\n}\n\nconst parseDesignators = async (path: string, column: number) =\u003e\n  (await Bun.file(path).text())\n    .trim()\n    .split(/\\r?\\n/)\n    .slice(1)\n    .map((line) =\u003e line.split(\",\")[column])\n    .filter(Boolean)\n    .sort()\n\nconst bomDesignators = await parseDesignators(`${outputDir}/jlc_bom.csv`, 1)\nconst cplDesignators = await parseDesignators(`${outputDir}/jlc_cpl.csv`, 0)\nconst manualDesignators = await parseDesignators(`${outputDir}/manual_assembly.csv`, 0)\nconst dnpDesignators = await parseDesignators(`${outputDir}/dnp.csv`, 0)\nif (bomDesignators.join(\"|\") !== cplDesignators.join(\"|\")) {\n  throw new Error(\"JLC BOM and CPL designator sets do not match\")\n}\nif (manualDesignators.join(\"|\") !== [\"J1\", \"U3\", \"U3-OPTICS\"].sort().join(\"|\")) {\n  throw new Error(`Unexpected manual/consigned set: ${manualDesignators.join(\", \")}`)\n}\nif (dnpDesignators.join(\"|\") !== [\"D0_IND\", \"R0\"].sort().join(\"|\")) {\n  throw new Error(`Unexpected DNP set: ${dnpDesignators.join(\", \")}`)\n}\nfor (const excluded of [\"J1\", \"U3\", \"R0\", \"D0_IND\"]) {\n  if (bomDesignators.includes(excluded)) {\n    throw new Error(`${excluded} must not appear in the JLC SMT BOM/CPL`)\n  }\n}\n\nconst bomText = await Bun.file(`${outputDir}/jlc_bom.csv`).text()\nfor (const [designator, footprint, lcsc] of [\n  [\"U1\", \"SOT-23-5_LCSC_C53099\", \"C53099\"],\n  [\"U2\", \"SOT-23-5_LCSC_C236671\", \"C236671\"],\n] as const) {\n  const row = bomText\n    .trim()\n    .split(/\\r?\\n/)\n    .find((line) =\u003e line.split(\",\")[1] === designator)\n  if (!row || !row.includes(footprint) || !row.endsWith(`,${lcsc}`)) {\n    throw new Error(`${designator} is missing its verified imported footprint/C-number`)\n  }\n}\nconst manualText = await Bun.file(`${outputDir}/manual_assembly.csv`).text()\nif (!manualText.includes(\"J1,Manual/rear-side THT\") || !manualText.includes(\"C492426\")) {\n  throw new Error(\"J1 must remain a manual rear-side C492426 THT operation\")\n}\nif (!manualText.includes(\"OV7670-VL2A\") || manualText.includes(\"OV07670-VL2A\")) {\n  throw new Error(\"U3 must use the exact OV7670-VL2A manual/consigned MPN\")\n}\n\nconsole.log(\n  `Production verification passed: ${vias.length}/${viaDrillCount} through vias, ` +\n    `${minViaHoleToTraceClearance.toFixed(3)} mm minimum via-hole-to-trace clearance, ` +\n    `${bomDesignators.length} matched JLC SMT placements, ${minWireWidth.toFixed(2)}-${maxWireWidth.toFixed(2)} mm routed copper, ` +\n    `connected V2V8/GND inner planes, explicit manual/consigned and DNP sets.`,\n)\n","content_mimetype":"text/typescript","created_at":"2026-08-24T13:23:42.504Z"}; window.SSR_PACKAGE_RELEASES = [{"package_release_id":"b165339e-f482-4d8c-9803-33fb4333a2b6","package_id":"664d9097-5b33-4886-9c4c-127597354ec8","version":"1.0.7","github_commit_sha":null,"is_locked":false,"is_latest":true,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-24T13:23:41.618Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":true,"transpilation_display_status":"pending","fs_sha":"md5-e4247102fc0198eef628891988afe5cd","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":true,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":true,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b165339e-f482-4d8c-9803-33fb4333a2b6\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"f2715047-0158-4258-88d6-1a58ee4150c6","user_code_job_started_at":"2026-08-24T13:23:44.508Z","user_code_job_completed_at":"2026-08-24T13:25:35.736Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=08a1e392f8de01ebaa77e50228e22d61099362826a7f93bfb39491c8dcafe51a","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"99c5f93b-edfc-4cac-a582-ec8988f59d85","package_id":"664d9097-5b33-4886-9c4c-127597354ec8","version":"1.0.6","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-24T12:16:13.016Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-14b3010608ac46b7c76ddb0bdf1c2769","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=99c5f93b-edfc-4cac-a582-ec8988f59d85\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"15e59836-d9a1-484a-9d3c-027d94bbfaa5","user_code_job_started_at":"2026-08-24T12:16:34.107Z","user_code_job_completed_at":"2026-08-24T12:18:35.336Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=0e62e5ec538c8f68c53b99737a0fafceab877a619b69683629cae5f694cb1912","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"e5912aea-226c-4f88-8c9c-72c31b06fd28","package_id":"664d9097-5b33-4886-9c4c-127597354ec8","version":"1.0.5","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-20T14:13:29.867Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-e28760f00ede8a7b77c3bc349d506a19","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":null,"sch_preview_image_url":null,"cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=e5912aea-226c-4f88-8c9c-72c31b06fd28\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"22dc075e-a7b9-4418-b244-6b9a75f6bac4","user_code_job_started_at":"2026-08-20T14:13:43.035Z","user_code_job_completed_at":"2026-08-20T14:15:02.833Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=a19e6bb13decec7243bdae99f42bd560e87b2aa513253d9249ca153e39baa48f","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"adaf2e95-a0ac-4720-936b-6ac03722ca3f","package_id":"664d9097-5b33-4886-9c4c-127597354ec8","version":"1.0.4","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-19T00:39:14.298Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-994de436614f12537d7cfbb1e3cede9d","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=adaf2e95-a0ac-4720-936b-6ac03722ca3f\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=adaf2e95-a0ac-4720-936b-6ac03722ca3f\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=adaf2e95-a0ac-4720-936b-6ac03722ca3f\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"8527b33b-ded7-40db-a351-f683a91f962f","user_code_job_started_at":"2026-08-19T00:39:26.978Z","user_code_job_completed_at":"2026-08-19T00:40:43.859Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=36c294e97efbc02cb1f5a3cee7989e9da70361030f8bc8c35750c656c84ff37c","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"b9d7e5e9-8ccd-4a35-9104-ce01b96a5d06","package_id":"664d9097-5b33-4886-9c4c-127597354ec8","version":"1.0.3","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-19T00:07:28.636Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-cb973d6bca7a6dae029a18bcd1d23d23","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b9d7e5e9-8ccd-4a35-9104-ce01b96a5d06\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b9d7e5e9-8ccd-4a35-9104-ce01b96a5d06\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=b9d7e5e9-8ccd-4a35-9104-ce01b96a5d06\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"66d0c808-6000-42b8-8bde-b613951f0119","user_code_job_started_at":"2026-08-19T00:07:46.822Z","user_code_job_completed_at":"2026-08-19T00:09:03.633Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=713a42525c5e9fcb1f6f1d6daad467cac62349b64b1a813eb475df8a30adcf79","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"8abc9cf1-1b18-4c13-8f58-cd906fd74e43","package_id":"664d9097-5b33-4886-9c4c-127597354ec8","version":"1.0.2","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-18T23:57:25.951Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-c99083b1daa2cb4da65a0ac5ae8a0e49","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=8abc9cf1-1b18-4c13-8f58-cd906fd74e43\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=8abc9cf1-1b18-4c13-8f58-cd906fd74e43\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=8abc9cf1-1b18-4c13-8f58-cd906fd74e43\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"7e7daa5e-98ce-4ca2-a6e8-296ea3ca72d0","user_code_job_started_at":"2026-08-18T23:57:38.230Z","user_code_job_completed_at":"2026-08-18T23:58:59.810Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=88340a9e3692f0b54950adaa5c3423906ebfb044b63b3a9745eb8b6196806f4a","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"414c9ebb-9247-40c7-8d8a-ba0e4d698875","package_id":"664d9097-5b33-4886-9c4c-127597354ec8","version":"1.0.1","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-18T22:15:42.595Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-383811e5ffcd7942eb8e70a73c595b41","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=414c9ebb-9247-40c7-8d8a-ba0e4d698875\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=414c9ebb-9247-40c7-8d8a-ba0e4d698875\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=414c9ebb-9247-40c7-8d8a-ba0e4d698875\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"78142397-6ddd-4227-946a-da9bf1d95353","user_code_job_started_at":"2026-08-18T22:15:56.658Z","user_code_job_completed_at":"2026-08-18T22:17:28.314Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=9bd740be2027af3a920052af61972055380555b97d3f0756364fd5e19765d1e0","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null},{"package_release_id":"52546987-10f7-466e-b303-d30801ffd712","package_id":"664d9097-5b33-4886-9c4c-127597354ec8","version":"1.0.0","github_commit_sha":null,"is_locked":false,"is_latest":false,"ready_to_build":true,"is_pr_preview":false,"created_at":"2026-08-18T20:46:22.846Z","circuit_json_build_error":null,"circuit_json_build_error_last_updated_at":null,"has_transpiled":false,"transpilation_error":null,"transpilation_logs":null,"transpilation_in_progress":false,"transpilation_started_at":null,"transpilation_completed_at":null,"transpilation_is_stale":false,"transpilation_display_status":"pending","fs_sha":"md5-3be1207a47d60b8c8c46639dc473f393","circuit_json_build_logs":null,"circuit_json_build_in_progress":false,"circuit_json_build_started_at":null,"circuit_json_build_completed_at":null,"circuit_json_build_is_stale":false,"circuit_json_build_display_status":"pending","image_generation_error":null,"image_generation_error_last_updated_at":null,"image_generation_logs":null,"image_generation_in_progress":false,"image_generation_started_at":null,"image_generation_completed_at":null,"image_generation_is_stale":false,"image_generation_display_status":"pending","pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=52546987-10f7-466e-b303-d30801ffd712\u0026file_path=dist%2Findex%2Fpcb.svg","sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=52546987-10f7-466e-b303-d30801ffd712\u0026file_path=dist%2Findex%2Fschematic.svg","cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=52546987-10f7-466e-b303-d30801ffd712\u0026file_path=dist%2Findex%2F3d.png","package_release_website_url":null,"display_status":"pending","latest_package_build_id":"cbf46b05-5b90-4dd1-ba13-badef7cc552d","user_code_job_started_at":"2026-08-18T20:46:36.242Z","user_code_job_completed_at":"2026-08-18T20:47:46.933Z","user_code_job_error":null,"user_code_job_completed_logs":null,"user_code_job_log_stream_url":"https://usercode.tscircuit.com/user_code_jobs/view_log_stream?user_code_job_id=2a2bfa73e897b5fdfc39bf5120e5714f10a7a0db840f2d376111ec710f8b3404","ai_review_requested":false,"github_pr_number":null,"github_pr_title":null,"github_branch_name":null}]; window.SSR_PACKAGE_BUILDS = []; window.SSR_RELATED_PACKAGES = [{"package_id":"1ef78ebd-82a5-4c8f-9d50-20d2214060d3","creator_account_id":"8d5e1af7-a381-4aaf-b208-56fa4e9d5a45","latest_package_release_id":"9f04d6d0-fd31-46e9-9b60-a3245f1c282a","last_built_release_id":"9f04d6d0-fd31-46e9-9b60-a3245f1c282a","latest_package_release_fs_sha":"md5-5b46693fb1aca8fd65f3ee614c9a93e6","latest_pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=9f04d6d0-fd31-46e9-9b60-a3245f1c282a\u0026file_path=dist%2Fddr-only%2Fpcb.svg","latest_sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=9f04d6d0-fd31-46e9-9b60-a3245f1c282a\u0026file_path=dist%2Fddr-only%2Fschematic.svg","latest_cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=9f04d6d0-fd31-46e9-9b60-a3245f1c282a\u0026file_path=dist%2Fddr-only%2F3d.png","latest_version":"1.0.16","license":"unset","owner_org_id":"94044d23-fb18-49b3-bcb5-8a702defe7d6","org_owner_tscircuit_handle":"0hmX","owner_github_username":"0hmX","github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"0hmX/simplified-am62l-computer","unscoped_name":"simplified-am62l-computer","star_count":0,"created_at":"2026-08-07T16:09:40.939Z","updated_at":"2026-08-24T13:46:34.470Z","ai_description":"This code defines components and scripts for physically representing and routing high-speed DDR memory signals, power lines, and ground planes on an 8-layer PCB with detailed pin assignments, copper pours, and precise via and trace layouts based on TI EVM reference data.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"same_author","thumbnail_url":"https://api.tscircuit.com/package_files/view?package_release_id=9f04d6d0-fd31-46e9-9b60-a3245f1c282a\u0026file_path=dist%2Fddr-only%2Fpcb.svg"},{"package_id":"ede89d02-7042-4b78-b370-4f9e9ce24568","creator_account_id":"9f398687-69d0-4ef4-a48c-bb6dc990e7df","latest_package_release_id":"0d3197ed-fd8c-4290-8fde-e32ec62ed9c5","last_built_release_id":"0d3197ed-fd8c-4290-8fde-e32ec62ed9c5","latest_package_release_fs_sha":"md5-4e43da8ec34f8f294e7327fc4121c168","latest_pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0d3197ed-fd8c-4290-8fde-e32ec62ed9c5\u0026file_path=dist%2Findex%2Fpcb.svg","latest_sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0d3197ed-fd8c-4290-8fde-e32ec62ed9c5\u0026file_path=dist%2Findex%2Fschematic.svg","latest_cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=0d3197ed-fd8c-4290-8fde-e32ec62ed9c5\u0026file_path=dist%2Findex%2F3d.png","latest_version":"1.3.0","license":"unset","owner_org_id":"f154d4e0-ac63-47a3-948e-a13da34df910","org_owner_tscircuit_handle":"seveibar","owner_github_username":"seveibar","github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"seveibar/f1c100s-dev-board","unscoped_name":"f1c100s-dev-board","star_count":0,"created_at":"2026-09-13T23:03:15.223Z","updated_at":"2026-09-13T23:47:36.981Z","ai_description":"This code defines the hardware layout and schematic for a four-layer F1C100S-based module, including footprint placement, pin mappings, power regulation, decoupling capacitors, support components, and routing configurations, enabling automated PCB generation, routing, and verification.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"similar_ai_description","thumbnail_url":"https://api.tscircuit.com/package_files/view?package_release_id=0d3197ed-fd8c-4290-8fde-e32ec62ed9c5\u0026file_path=dist%2Findex%2Fpcb.svg"},{"package_id":"7065b9a6-03de-43a1-ba42-2a0ead33b548","creator_account_id":"1f745cb8-1b99-4215-905f-f8e3dc29bc28","latest_package_release_id":"5746ef1e-d91a-4043-9db3-2cc17f89d777","last_built_release_id":"5746ef1e-d91a-4043-9db3-2cc17f89d777","latest_package_release_fs_sha":"md5-27fc15676f25d1e3a229466d1de0fe7a","latest_pcb_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2Fpcb.svg","latest_sch_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2Fschematic.svg","latest_cad_preview_image_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2F3d.png","latest_version":"1.0.1","license":"unset","owner_org_id":"60917f07-d371-4c51-854f-e2bd7dab9e5a","org_owner_tscircuit_handle":"hrithik18k","owner_github_username":null,"github_repo_full_name":null,"is_source_from_github":false,"description":null,"name":"hrithik18k/smart-switch-pcb","unscoped_name":"smart-switch-pcb","star_count":0,"created_at":"2026-09-09T11:12:10.428Z","updated_at":"2026-09-09T11:56:59.112Z","ai_description":"The AO3400A component models a SOT-23 N-channel MOSFET with labeled pins for Gate, Source, and Drain, including 3D CAD models and schematic symbols for electronic circuit design.","ai_usage_instructions":null,"is_private":false,"is_unlisted":false,"is_public":true,"public_dist_enabled":false,"has_public_dist":true,"starred_at":null,"default_view":"files","website":null,"github_installation_id":null,"allow_pr_previews":false,"related_type":"random","thumbnail_url":"https://api.tscircuit.com/package_files/view?package_release_id=5746ef1e-d91a-4043-9db3-2cc17f89d777\u0026file_path=dist%2Findex%2Fpcb.svg"}]; window.SSR_PACKAGE_ROUTE = {"author":"0hmX","packageName":"robocraze-ov7670-camera-module-clone","packageNameWithScope":"0hmX/robocraze-ov7670-camera-module-clone","version":null,"isLegacyRoute":false,"kind":"file","filePath":"scripts/verify-production.ts"};
  

  

  

  

  
  
  
  



  
unzip -p ${archivePath} ${platedDrillFilename}`.text() const toolDiameters = new Map<string, number>() for (const match of drillText.matchAll(/^T(\d+)C([0-9.]+)$/gm)) { toolDiameters.set(match[1], Number(match[2])) } let activeTool = "" let viaDrillCount = 0 for (const line of drillText.split(/\r?\n/)) { const toolMatch = line.match(/^T(\d+)$/) if (toolMatch) { activeTool = toolMatch[1] continue } if (line.startsWith("X") && Math.abs((toolDiameters.get(activeTool) ?? 0) - 0.2) < 1e-6) { viaDrillCount += 1 } } if (viaDrillCount !== vias.length) { throw new Error( `Via/drill mismatch: Circuit JSON has ${vias.length} vias but ${platedDrillFilename} has ${viaDrillCount} 0.20 mm drills`, ) } const parseDesignators = async (path: string, column: number) => (await Bun.file(path).text()) .trim() .split(/\r?\n/) .slice(1) .map((line) => line.split(",")[column]) .filter(Boolean) .sort() const bomDesignators = await parseDesignators(`${outputDir}/jlc_bom.csv`, 1) const cplDesignators = await parseDesignators(`${outputDir}/jlc_cpl.csv`, 0) const manualDesignators = await parseDesignators(`${outputDir}/manual_assembly.csv`, 0) const dnpDesignators = await parseDesignators(`${outputDir}/dnp.csv`, 0) if (bomDesignators.join("|") !== cplDesignators.join("|")) { throw new Error("JLC BOM and CPL designator sets do not match") } if (manualDesignators.join("|") !== ["J1", "U3", "U3-OPTICS"].sort().join("|")) { throw new Error(`Unexpected manual/consigned set: ${manualDesignators.join(", ")}`) } if (dnpDesignators.join("|") !== ["D0_IND", "R0"].sort().join("|")) { throw new Error(`Unexpected DNP set: ${dnpDesignators.join(", ")}`) } for (const excluded of ["J1", "U3", "R0", "D0_IND"]) { if (bomDesignators.includes(excluded)) { throw new Error(`${excluded} must not appear in the JLC SMT BOM/CPL`) } } const bomText = await Bun.file(`${outputDir}/jlc_bom.csv`).text() for (const [designator, footprint, lcsc] of [ ["U1", "SOT-23-5_LCSC_C53099", "C53099"], ["U2", "SOT-23-5_LCSC_C236671", "C236671"], ] as const) { const row = bomText .trim() .split(/\r?\n/) .find((line) => line.split(",")[1] === designator) if (!row || !row.includes(footprint) || !row.endsWith(`,${lcsc}`)) { throw new Error(`${designator} is missing its verified imported footprint/C-number`) } } const manualText = await Bun.file(`${outputDir}/manual_assembly.csv`).text() if (!manualText.includes("J1,Manual/rear-side THT") || !manualText.includes("C492426")) { throw new Error("J1 must remain a manual rear-side C492426 THT operation") } if (!manualText.includes("OV7670-VL2A") || manualText.includes("OV07670-VL2A")) { throw new Error("U3 must use the exact OV7670-VL2A manual/consigned MPN") } console.log( `Production verification passed: ${vias.length}/${viaDrillCount} through vias, ` + `${minViaHoleToTraceClearance.toFixed(3)} mm minimum via-hole-to-trace clearance, ` + `${bomDesignators.length} matched JLC SMT placements, ${minWireWidth.toFixed(2)}-${maxWireWidth.toFixed(2)} mm routed copper, ` + `connected V2V8/GND inner planes, explicit manual/consigned and DNP sets.`, )