feat: ✨ lazily-loaded Gerber viewer demo in the blog, served from R2

Embed KiCad's gerbview WASM in the graphics-to-WebGL blog post as a
click-to-load demo that opens the tiny_tapeout board entirely in-browser.

- GerberDemo.astro: lazy iframe embed + cross-origin-isolation reload guard
  + WebGL2/SharedArrayBuffer feature-detect with a poster fallback
- public/gerber-demo/{index.html,boot.js}: self-contained gerbview boot
  harness (config seed, MEMFS board preload, argv auto-open)
- board/ tiny_tapeout layers + poster.png committed; wasm/ glue JS committed
  (served same-origin — pthread worker can't be cross-origin), while
  gerbview.wasm + kicad-resources.bin are git-ignored and served from
  Cloudflare R2 (assets.pcbjam.com)
- COOP/COEP require-corp scoped to the post + /gerber-demo routes
  (dev: astro.config.mjs + middleware.ts; prod: vercel.json)
- post converted to MDX (@astrojs/mdx) so it can embed the component
- scripts/: sync-demo-wasm.sh, r2-deploy.sh, r2-cors.json

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Viktor Vaczi 2026-06-17 10:28:06 +02:00
commit 57f1f53d26
36 changed files with 242845 additions and 9 deletions

View file

@ -0,0 +1,38 @@
# Gerber viewer blog demo
KiCad's `gerbview` compiled to WebAssembly, embedded (lazily) in the blog post.
Click → it streams the WASM and renders the bundled tiny_tapeout board in-browser.
## Files here (`site/public/gerber-demo/`)
| Path | What it does |
|------|--------------|
| `index.html` | The iframe target — minimal page with the `#main-window` / `#window-container` the WASM needs. |
| `boot.js` | Boot harness: configures Emscripten `Module`, seeds KiCad config, preloads the board into MEMFS, auto-opens it via `Module.arguments`, and injects `wx.js → wx-dom.js → gerbview.js`. Holds `R2_BASE` + the dev/prod asset-base switch. |
| `board/` | The tiny_tapeout Gerber layers (committed) the demo opens. |
| `poster.png` | Static fallback shown to browsers that can't run the live viewer. |
| `wasm/` | `wx.js`/`wx-dom.js`/`gerbview.js` (committed, served same-origin) + `gerbview.wasm`/`kicad-resources.bin` (git-ignored; served from R2 in prod, local in dev). Synced from `/output`. |
## Related pieces (elsewhere in `site/`)
| Path | What it does |
|------|--------------|
| `src/components/GerberDemo.astro` | The embed: lazy click-to-load iframe, cross-origin-isolation reload guard, feature-detect + poster fallback. |
| `src/content/blog/porting-kicad-graphics-to-webgl-with-claude.mdx` | The post that renders `<GerberDemo />`. |
| `astro.config.mjs` + `src/middleware.ts` | Dev cross-origin-isolation headers (COOP/COEP `require-corp`). |
| `vercel.json` | Prod COOP/COEP, scoped to the post + `/gerber-demo/` routes. |
| `scripts/sync-demo-wasm.sh` | Copy fresh WASM from `/output` into `wasm/` (run after a gerbview rebuild). |
| `scripts/r2-deploy.sh` + `scripts/r2-cors.json` | Upload the heavy binaries to Cloudflare R2 (`pcbjam-assets` → `assets.pcbjam.com`) and set CORS. |
## Run / update
```bash
# local dev (serves wasm/ from the local mirror)
scripts/sync-demo-wasm.sh && npm run dev # /blog/porting-kicad-graphics-to-webgl-with-claude
# after a new gerbview build: refresh local mirror, then push binaries to R2
scripts/sync-demo-wasm.sh && scripts/r2-deploy.sh
```
The live viewer needs SharedArrayBuffer + WebGL2 (Chrome/Edge/Firefox, Safari 15.2+);
other browsers get `poster.png`.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,268 @@
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,7.0.9-7.0.9~ubuntu22.04.1*
G04 #@! TF.CreationDate,2023-12-15T15:20:45-05:00*
G04 #@! TF.ProjectId,tinytapeout-demo,74696e79-7461-4706-956f-75742d64656d,0.9.4*
G04 #@! TF.SameCoordinates,PX35e1f20PY8044ea0*
G04 #@! TF.FileFunction,Soldermask,Bot*
G04 #@! TF.FilePolarity,Negative*
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 7.0.9-7.0.9~ubuntu22.04.1) date 2023-12-15 15:20:45*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
%ADD10C,0.900000*%
%ADD11C,6.400000*%
%ADD12O,1.250000X2.400000*%
%ADD13O,1.180000X2.080000*%
%ADD14R,1.700000X1.700000*%
%ADD15O,1.700000X1.700000*%
%ADD16C,1.700000*%
%ADD17R,1.000000X2.510000*%
G04 APERTURE END LIST*
D10*
G04 #@! TO.C,JP7*
X99900000Y16780000D03*
X96900000Y16780000D03*
G04 #@! TD*
G04 #@! TO.C,JP1*
X99900000Y31780000D03*
X96900000Y31780000D03*
G04 #@! TD*
D11*
G04 #@! TO.C,MT3*
X3750000Y77250000D03*
G04 #@! TD*
D12*
G04 #@! TO.C,J15*
X33870000Y79000000D03*
D13*
X22630000Y75000000D03*
X33870000Y75000000D03*
D12*
X22630000Y79000000D03*
G04 #@! TD*
D14*
G04 #@! TO.C,J13*
X4500000Y34440000D03*
D15*
X4500000Y36980000D03*
X4500000Y39520000D03*
X4500000Y42060000D03*
X4500000Y44600000D03*
D16*
X4500000Y47140000D03*
D15*
X1960000Y34440000D03*
X1960000Y36980000D03*
X1960000Y39520000D03*
X1960000Y42060000D03*
X1960000Y44600000D03*
X1960000Y47140000D03*
G04 #@! TD*
D16*
G04 #@! TO.C,J2*
X18810000Y3000000D03*
D15*
X16270000Y3000000D03*
X13730000Y3000000D03*
X11190000Y3000000D03*
G04 #@! TD*
D10*
G04 #@! TO.C,JP3*
X99900000Y26780000D03*
X96900000Y26780000D03*
G04 #@! TD*
G04 #@! TO.C,JP8*
X99900000Y14280000D03*
X96900000Y14280000D03*
G04 #@! TD*
D16*
G04 #@! TO.C,J8*
X64545000Y3000000D03*
D15*
X62005000Y3000000D03*
X59465000Y3000000D03*
G04 #@! TD*
D14*
G04 #@! TO.C,J12*
X4500000Y11580000D03*
D15*
X4500000Y14120000D03*
X4500000Y16660000D03*
X4500000Y19200000D03*
X4500000Y21740000D03*
D16*
X4500000Y24280000D03*
D15*
X1960000Y11580000D03*
X1960000Y14120000D03*
X1960000Y16660000D03*
X1960000Y19200000D03*
X1960000Y21740000D03*
X1960000Y24280000D03*
G04 #@! TD*
D14*
G04 #@! TO.C,J3*
X34045000Y5545000D03*
D15*
X31505000Y5545000D03*
X28965000Y5545000D03*
X26425000Y5545000D03*
X23885000Y5545000D03*
D16*
X21345000Y5545000D03*
D15*
X34045000Y3005000D03*
X31505000Y3005000D03*
X28965000Y3005000D03*
X26425000Y3005000D03*
X23885000Y3005000D03*
X21345000Y3005000D03*
G04 #@! TD*
D11*
G04 #@! TO.C,MT4*
X100750000Y77250000D03*
G04 #@! TD*
G04 #@! TO.C,MT2*
X100750000Y3750000D03*
G04 #@! TD*
D14*
G04 #@! TO.C,J5*
X56905000Y5545000D03*
D15*
X54365000Y5545000D03*
X51825000Y5545000D03*
X49285000Y5545000D03*
X46745000Y5545000D03*
D16*
X44205000Y5545000D03*
D15*
X56905000Y3005000D03*
X54365000Y3005000D03*
X51825000Y3005000D03*
X49285000Y3005000D03*
X46745000Y3005000D03*
X44205000Y3005000D03*
G04 #@! TD*
D10*
G04 #@! TO.C,JP2*
X99900000Y29280000D03*
X96900000Y29280000D03*
G04 #@! TD*
D14*
G04 #@! TO.C,J10*
X1690000Y29260000D03*
D15*
X4230000Y29260000D03*
G04 #@! TD*
D16*
G04 #@! TO.C,J17*
X41700000Y3000000D03*
D15*
X39160000Y3000000D03*
X36620000Y3000000D03*
G04 #@! TD*
D14*
G04 #@! TO.C,J9*
X95000000Y79000000D03*
D15*
X92460000Y79000000D03*
X89920000Y79000000D03*
X87380000Y79000000D03*
X84840000Y79000000D03*
X82300000Y79000000D03*
X79760000Y79000000D03*
X77220000Y79000000D03*
X74680000Y79000000D03*
X72140000Y79000000D03*
X69600000Y79000000D03*
X67060000Y79000000D03*
X64520000Y79000000D03*
X61980000Y79000000D03*
X59440000Y79000000D03*
X56900000Y79000000D03*
X54360000Y79000000D03*
X51820000Y79000000D03*
X49280000Y79000000D03*
X46740000Y79000000D03*
X44200000Y79000000D03*
X41660000Y79000000D03*
X39120000Y79000000D03*
X36580000Y79000000D03*
G04 #@! TD*
D10*
G04 #@! TO.C,JP5*
X99900000Y21780000D03*
X96900000Y21780000D03*
G04 #@! TD*
D14*
G04 #@! TO.C,J14*
X4500000Y57300000D03*
D15*
X4500000Y59840000D03*
X4500000Y62380000D03*
X4500000Y64920000D03*
X4500000Y67460000D03*
D16*
X4500000Y70000000D03*
D15*
X1960000Y57300000D03*
X1960000Y59840000D03*
X1960000Y62380000D03*
X1960000Y64920000D03*
X1960000Y67460000D03*
X1960000Y70000000D03*
G04 #@! TD*
D10*
G04 #@! TO.C,JP6*
X99900000Y19280000D03*
X96900000Y19280000D03*
G04 #@! TD*
D14*
G04 #@! TO.C,J1*
X95000000Y3000000D03*
D15*
X92460000Y3000000D03*
X89920000Y3000000D03*
X87380000Y3000000D03*
X84840000Y3000000D03*
X82300000Y3000000D03*
G04 #@! TD*
D14*
G04 #@! TO.C,J6*
X79765000Y5545000D03*
D15*
X77225000Y5545000D03*
X74685000Y5545000D03*
X72145000Y5545000D03*
X69605000Y5545000D03*
D16*
X67065000Y5545000D03*
D15*
X79765000Y3005000D03*
X77225000Y3005000D03*
X74685000Y3005000D03*
X72145000Y3005000D03*
X69605000Y3005000D03*
X67065000Y3005000D03*
G04 #@! TD*
D10*
G04 #@! TO.C,JP4*
X99900000Y24280000D03*
X96900000Y24280000D03*
G04 #@! TD*
D11*
G04 #@! TO.C,MT1*
X3750000Y3750000D03*
G04 #@! TD*
D17*
G04 #@! TO.C,J11*
X22950000Y30775000D03*
X20410000Y27465000D03*
X17870000Y30775000D03*
X15330000Y27465000D03*
X12790000Y30775000D03*
X10250000Y27465000D03*
G04 #@! TD*
M02*

View file

@ -0,0 +1,25 @@
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,7.0.9-7.0.9~ubuntu22.04.1*
G04 #@! TF.CreationDate,2023-12-15T15:20:45-05:00*
G04 #@! TF.ProjectId,tinytapeout-demo,74696e79-7461-4706-956f-75742d64656d,0.9.4*
G04 #@! TF.SameCoordinates,PX35e1f20PY8044ea0*
G04 #@! TF.FileFunction,Paste,Bot*
G04 #@! TF.FilePolarity,Positive*
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 7.0.9-7.0.9~ubuntu22.04.1) date 2023-12-15 15:20:45*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
%ADD10R,1.000000X2.510000*%
G04 APERTURE END LIST*
D10*
G04 #@! TO.C,J11*
X22950000Y30775000D03*
X20410000Y27465000D03*
X17870000Y30775000D03*
X15330000Y27465000D03*
X12790000Y30775000D03*
X10250000Y27465000D03*
G04 #@! TD*
M02*

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,100 @@
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,7.0.9-7.0.9~ubuntu22.04.1*
G04 #@! TF.CreationDate,2023-12-15T15:20:45-05:00*
G04 #@! TF.ProjectId,tinytapeout-demo,74696e79-7461-4706-956f-75742d64656d,0.9.4*
G04 #@! TF.SameCoordinates,PX35e1f20PY8044ea0*
G04 #@! TF.FileFunction,Profile,NP*
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 7.0.9-7.0.9~ubuntu22.04.1) date 2023-12-15 15:20:45*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 #@! TA.AperFunction,Profile*
%ADD10C,0.100000*%
G04 #@! TD*
G04 #@! TA.AperFunction,Profile*
%ADD11C,0.080000*%
G04 #@! TD*
G04 APERTURE END LIST*
D10*
X23630000Y80600000D02*
G75*
G03*
X23230000Y81000000I-400000J0D01*
G01*
X33270000Y81000000D02*
G75*
G03*
X32870000Y80600000I0J-400000D01*
G01*
X104500000Y78000000D02*
G75*
G03*
X101500000Y81000000I-3000000J0D01*
G01*
X33270000Y81000000D02*
X101500000Y81000000D01*
X101500000Y0D02*
X3000000Y0D01*
X104500000Y78000000D02*
X104500000Y3000000D01*
X0Y3000000D02*
G75*
G03*
X3000000Y0I3000000J0D01*
G01*
X23230000Y81000000D02*
X3000000Y81000000D01*
X3000000Y81000000D02*
G75*
G03*
X0Y78000000I0J-3000000D01*
G01*
X0Y3000000D02*
X0Y78000000D01*
X101500000Y0D02*
G75*
G03*
X104500000Y3000000I0J3000000D01*
G01*
D11*
G04 #@! TO.C,J15*
X32870000Y80600000D02*
X32870000Y74400000D01*
X32070000Y74400000D02*
X24430000Y74400000D01*
X23630000Y74400000D02*
X23630000Y80600000D01*
X32545000Y74000001D02*
G75*
G03*
X32869999Y74400000I-37502J362500D01*
G01*
X32220001Y74280000D02*
G75*
G03*
X32545000Y74000001I302498J22499D01*
G01*
X32219999Y74280000D02*
G75*
G03*
X32070001Y74399998I-134999J-15001D01*
G01*
X24430000Y74399998D02*
G75*
G03*
X24280002Y74279999I-15000J-134998D01*
G01*
X23955000Y74000003D02*
G75*
G03*
X24279997Y74279999I22500J302497D01*
G01*
X23630000Y74400000D02*
G75*
G03*
X23955000Y74000000I362500J-37500D01*
G01*
G04 #@! TD*
M02*

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,865 @@
G04 #@! TF.GenerationSoftware,KiCad,Pcbnew,7.0.9-7.0.9~ubuntu22.04.1*
G04 #@! TF.CreationDate,2023-12-15T15:20:44-05:00*
G04 #@! TF.ProjectId,tinytapeout-demo,74696e79-7461-4706-956f-75742d64656d,0.9.4*
G04 #@! TF.SameCoordinates,PX35e1f20PY8044ea0*
G04 #@! TF.FileFunction,Paste,Top*
G04 #@! TF.FilePolarity,Positive*
%FSLAX46Y46*%
G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)*
G04 Created by KiCad (PCBNEW 7.0.9-7.0.9~ubuntu22.04.1) date 2023-12-15 15:20:44*
%MOMM*%
%LPD*%
G01*
G04 APERTURE LIST*
G04 Aperture macros list*
%AMRoundRect*
0 Rectangle with rounded corners*
0 $1 Rounding radius*
0 $2 $3 $4 $5 $6 $7 $8 $9 X,Y pos of 4 corners*
0 Add a 4 corners polygon primitive as box body*
4,1,4,$2,$3,$4,$5,$6,$7,$8,$9,$2,$3,0*
0 Add four circle primitives for the rounded corners*
1,1,$1+$1,$2,$3*
1,1,$1+$1,$4,$5*
1,1,$1+$1,$6,$7*
1,1,$1+$1,$8,$9*
0 Add four rect primitives between the rounded corners*
20,1,$1+$1,$2,$3,$4,$5,0*
20,1,$1+$1,$4,$5,$6,$7,0*
20,1,$1+$1,$6,$7,$8,$9,0*
20,1,$1+$1,$8,$9,$2,$3,0*%
G04 Aperture macros list end*
%ADD10RoundRect,0.225000X0.225000X0.250000X-0.225000X0.250000X-0.225000X-0.250000X0.225000X-0.250000X0*%
%ADD11RoundRect,0.135000X0.185000X-0.135000X0.185000X0.135000X-0.185000X0.135000X-0.185000X-0.135000X0*%
%ADD12RoundRect,0.225000X-0.250000X0.225000X-0.250000X-0.225000X0.250000X-0.225000X0.250000X0.225000X0*%
%ADD13RoundRect,0.140000X-0.140000X-0.170000X0.140000X-0.170000X0.140000X0.170000X-0.140000X0.170000X0*%
%ADD14RoundRect,0.135000X-0.185000X0.135000X-0.185000X-0.135000X0.185000X-0.135000X0.185000X0.135000X0*%
%ADD15RoundRect,0.135000X0.135000X0.185000X-0.135000X0.185000X-0.135000X-0.185000X0.135000X-0.185000X0*%
%ADD16R,0.600000X1.100000*%
%ADD17R,0.300000X1.100000*%
%ADD18RoundRect,0.250000X0.250000X0.475000X-0.250000X0.475000X-0.250000X-0.475000X0.250000X-0.475000X0*%
%ADD19RoundRect,0.135000X-0.135000X-0.185000X0.135000X-0.185000X0.135000X0.185000X-0.135000X0.185000X0*%
%ADD20RoundRect,0.140000X-0.170000X0.140000X-0.170000X-0.140000X0.170000X-0.140000X0.170000X0.140000X0*%
%ADD21RoundRect,0.200000X0.200000X0.275000X-0.200000X0.275000X-0.200000X-0.275000X0.200000X-0.275000X0*%
%ADD22RoundRect,0.140000X0.170000X-0.140000X0.170000X0.140000X-0.170000X0.140000X-0.170000X-0.140000X0*%
%ADD23R,1.400000X1.200000*%
%ADD24RoundRect,0.225000X-0.225000X-0.250000X0.225000X-0.250000X0.225000X0.250000X-0.225000X0.250000X0*%
%ADD25RoundRect,0.140000X0.140000X0.170000X-0.140000X0.170000X-0.140000X-0.170000X0.140000X-0.170000X0*%
%ADD26RoundRect,0.225000X0.250000X-0.225000X0.250000X0.225000X-0.250000X0.225000X-0.250000X-0.225000X0*%
%ADD27R,1.500000X1.400000*%
%ADD28R,1.000000X2.510000*%
%ADD29R,2.200000X1.100000*%
%ADD30RoundRect,0.150000X-0.150000X0.650000X-0.150000X-0.650000X0.150000X-0.650000X0.150000X0.650000X0*%
%ADD31RoundRect,0.200000X0.300000X-0.950000X0.300000X0.950000X-0.300000X0.950000X-0.300000X-0.950000X0*%
%ADD32R,1.000000X2.300000*%
%ADD33RoundRect,0.150000X-0.650000X-0.150000X0.650000X-0.150000X0.650000X0.150000X-0.650000X0.150000X0*%
%ADD34RoundRect,0.249999X-0.395001X-0.395001X0.395001X-0.395001X0.395001X0.395001X-0.395001X0.395001X0*%
%ADD35RoundRect,0.050000X-0.387500X-0.050000X0.387500X-0.050000X0.387500X0.050000X-0.387500X0.050000X0*%
%ADD36RoundRect,0.050000X-0.050000X-0.387500X0.050000X-0.387500X0.050000X0.387500X-0.050000X0.387500X0*%
%ADD37RoundRect,0.243750X0.243750X0.456250X-0.243750X0.456250X-0.243750X-0.456250X0.243750X-0.456250X0*%
%ADD38RoundRect,0.200000X0.200000X0.250000X-0.200000X0.250000X-0.200000X-0.250000X0.200000X-0.250000X0*%
%ADD39RoundRect,0.200000X0.275000X-0.200000X0.275000X0.200000X-0.275000X0.200000X-0.275000X-0.200000X0*%
%ADD40RoundRect,0.100000X0.100000X-0.637500X0.100000X0.637500X-0.100000X0.637500X-0.100000X-0.637500X0*%
%ADD41RoundRect,0.150000X-0.150000X0.512500X-0.150000X-0.512500X0.150000X-0.512500X0.150000X0.512500X0*%
%ADD42R,1.500000X2.000000*%
%ADD43R,3.800000X2.000000*%
%ADD44R,3.150000X1.000000*%
%ADD45RoundRect,0.218750X0.256250X-0.218750X0.256250X0.218750X-0.256250X0.218750X-0.256250X-0.218750X0*%
%ADD46RoundRect,0.250000X-0.250000X-0.475000X0.250000X-0.475000X0.250000X0.475000X-0.250000X0.475000X0*%
%ADD47RoundRect,0.218750X-0.218750X-0.256250X0.218750X-0.256250X0.218750X0.256250X-0.218750X0.256250X0*%
G04 APERTURE END LIST*
D10*
G04 #@! TO.C,C21*
X94775000Y74500000D03*
X93225000Y74500000D03*
G04 #@! TD*
D11*
G04 #@! TO.C,R15*
X99500000Y70790000D03*
X99500000Y71810000D03*
G04 #@! TD*
D12*
G04 #@! TO.C,C32*
X28200000Y27700000D03*
X28200000Y26150000D03*
G04 #@! TD*
D13*
G04 #@! TO.C,C23*
X68195000Y72000000D03*
X69155000Y72000000D03*
G04 #@! TD*
G04 #@! TO.C,C36*
X26920000Y14250000D03*
X27880000Y14250000D03*
G04 #@! TD*
D14*
G04 #@! TO.C,R20*
X26900000Y71710000D03*
X26900000Y70690000D03*
G04 #@! TD*
D15*
G04 #@! TO.C,R38*
X24360000Y31050000D03*
X23340000Y31050000D03*
G04 #@! TD*
D16*
G04 #@! TO.C,J15*
X31450000Y73550000D03*
X30650000Y73550000D03*
D17*
X29500000Y73550000D03*
X28500000Y73550000D03*
X28000000Y73550000D03*
X27000000Y73550000D03*
D16*
X25050000Y73550000D03*
X25850000Y73550000D03*
D17*
X26500000Y73550000D03*
X27500000Y73550000D03*
X29000000Y73550000D03*
X30000000Y73550000D03*
G04 #@! TD*
D18*
G04 #@! TO.C,C6*
X16190000Y67290000D03*
X14290000Y67290000D03*
G04 #@! TD*
D19*
G04 #@! TO.C,R5*
X14390000Y52271429D03*
X15410000Y52271429D03*
G04 #@! TD*
D20*
G04 #@! TO.C,C56*
X8700000Y23880000D03*
X8700000Y22920000D03*
G04 #@! TD*
D18*
G04 #@! TO.C,C7*
X20800000Y79700000D03*
X18900000Y79700000D03*
G04 #@! TD*
D21*
G04 #@! TO.C,R7*
X42325000Y14750000D03*
X40675000Y14750000D03*
G04 #@! TD*
D19*
G04 #@! TO.C,R1*
X14390000Y42100000D03*
X15410000Y42100000D03*
G04 #@! TD*
D22*
G04 #@! TO.C,C29*
X22400000Y10870000D03*
X22400000Y11830000D03*
G04 #@! TD*
D13*
G04 #@! TO.C,C24*
X68195000Y29000000D03*
X69155000Y29000000D03*
G04 #@! TD*
G04 #@! TO.C,C8*
X47595000Y11100000D03*
X48555000Y11100000D03*
G04 #@! TD*
D23*
G04 #@! TO.C,Y1*
X23900000Y10900000D03*
X26100000Y10900000D03*
X26100000Y12600000D03*
X23900000Y12600000D03*
G04 #@! TD*
D11*
G04 #@! TO.C,R18*
X90400000Y70790000D03*
X90400000Y71810000D03*
G04 #@! TD*
D20*
G04 #@! TO.C,C58*
X8500000Y69880000D03*
X8500000Y68920000D03*
G04 #@! TD*
D13*
G04 #@! TO.C,C27*
X11120000Y25400000D03*
X12080000Y25400000D03*
G04 #@! TD*
D19*
G04 #@! TO.C,R11*
X14390000Y59900000D03*
X15410000Y59900000D03*
G04 #@! TD*
D24*
G04 #@! TO.C,C16*
X65400000Y13260000D03*
X66950000Y13260000D03*
G04 #@! TD*
D15*
G04 #@! TO.C,R43*
X93810000Y59500000D03*
X92790000Y59500000D03*
G04 #@! TD*
D22*
G04 #@! TO.C,C4*
X17020000Y6165000D03*
X17020000Y7125000D03*
G04 #@! TD*
D15*
G04 #@! TO.C,R24*
X95765000Y26808572D03*
X94745000Y26808572D03*
G04 #@! TD*
G04 #@! TO.C,R22*
X95765000Y31820000D03*
X94745000Y31820000D03*
G04 #@! TD*
D19*
G04 #@! TO.C,R3*
X14390000Y47185715D03*
X15410000Y47185715D03*
G04 #@! TD*
D13*
G04 #@! TO.C,C2*
X63020000Y14900000D03*
X63980000Y14900000D03*
G04 #@! TD*
D25*
G04 #@! TO.C,C18*
X69155000Y26500000D03*
X68195000Y26500000D03*
G04 #@! TD*
D14*
G04 #@! TO.C,R41*
X39250000Y14547500D03*
X39250000Y13527500D03*
G04 #@! TD*
D26*
G04 #@! TO.C,C42*
X87100000Y70425000D03*
X87100000Y71975000D03*
G04 #@! TD*
D27*
G04 #@! TO.C,SW2*
X67250000Y10000000D03*
X60750000Y10000000D03*
G04 #@! TD*
D11*
G04 #@! TO.C,R8*
X61100000Y12890000D03*
X61100000Y13910000D03*
G04 #@! TD*
D25*
G04 #@! TO.C,C28*
X87680000Y65800000D03*
X86720000Y65800000D03*
G04 #@! TD*
D13*
G04 #@! TO.C,C35*
X32120000Y19200000D03*
X33080000Y19200000D03*
G04 #@! TD*
D28*
G04 #@! TO.C,J7*
X63190000Y21245000D03*
X60650000Y24555000D03*
G04 #@! TD*
D19*
G04 #@! TO.C,R12*
X40990000Y13250000D03*
X42010000Y13250000D03*
G04 #@! TD*
D10*
G04 #@! TO.C,C25*
X94775000Y76040000D03*
X93225000Y76040000D03*
G04 #@! TD*
D12*
G04 #@! TO.C,C5*
X18400000Y7675000D03*
X18400000Y6125000D03*
G04 #@! TD*
D19*
G04 #@! TO.C,R13*
X61090000Y14900000D03*
X62110000Y14900000D03*
G04 #@! TD*
D14*
G04 #@! TO.C,R21*
X30200000Y70910000D03*
X30200000Y69890000D03*
G04 #@! TD*
D19*
G04 #@! TO.C,R42*
X86790000Y73200000D03*
X87810000Y73200000D03*
G04 #@! TD*
G04 #@! TO.C,R2*
X14390000Y44642858D03*
X15410000Y44642858D03*
G04 #@! TD*
D29*
G04 #@! TO.C,SW4*
X17600000Y59890000D03*
X17600000Y57350000D03*
X17600000Y54810000D03*
X17600000Y52270000D03*
X17600000Y49730000D03*
X17600000Y47190000D03*
X17600000Y44650000D03*
X17600000Y42110000D03*
X26400000Y42110000D03*
X26400000Y44650000D03*
X26400000Y47190000D03*
X26400000Y49730000D03*
X26400000Y52270000D03*
X26400000Y54810000D03*
X26400000Y57350000D03*
X26400000Y59890000D03*
G04 #@! TD*
D14*
G04 #@! TO.C,R19*
X95250000Y64010000D03*
X95250000Y62990000D03*
G04 #@! TD*
D30*
G04 #@! TO.C,U7*
X93905000Y57600000D03*
X92635000Y57600000D03*
X91365000Y57600000D03*
X90095000Y57600000D03*
X90095000Y50400000D03*
X91365000Y50400000D03*
X92635000Y50400000D03*
X93905000Y50400000D03*
G04 #@! TD*
D20*
G04 #@! TO.C,C30*
X27700000Y12630000D03*
X27700000Y11670000D03*
G04 #@! TD*
D15*
G04 #@! TO.C,R28*
X95765000Y16785716D03*
X94745000Y16785716D03*
G04 #@! TD*
D25*
G04 #@! TO.C,C39*
X21280000Y24100000D03*
X20320000Y24100000D03*
G04 #@! TD*
D31*
G04 #@! TO.C,U1*
X87050000Y17550000D03*
D32*
X88550000Y17550000D03*
X90050000Y17550000D03*
X91550000Y17550000D03*
X93050000Y17550000D03*
X93050000Y28450000D03*
X91550000Y28450000D03*
X90050000Y28450000D03*
X88550000Y28450000D03*
X87050000Y28450000D03*
G04 #@! TD*
D15*
G04 #@! TO.C,R23*
X95765000Y29314286D03*
X94745000Y29314286D03*
G04 #@! TD*
D25*
G04 #@! TO.C,C38*
X20180000Y19300000D03*
X19220000Y19300000D03*
G04 #@! TD*
D15*
G04 #@! TO.C,R45*
X93810000Y47600000D03*
X92790000Y47600000D03*
G04 #@! TD*
D33*
G04 #@! TO.C,U5*
X14400000Y31905000D03*
X14400000Y30635000D03*
X14400000Y29365000D03*
X14400000Y28095000D03*
X21600000Y28095000D03*
X21600000Y29365000D03*
X21600000Y30635000D03*
X21600000Y31905000D03*
G04 #@! TD*
D26*
G04 #@! TO.C,C37*
X29700000Y26125000D03*
X29700000Y27675000D03*
G04 #@! TD*
D19*
G04 #@! TO.C,R35*
X11740000Y29035000D03*
X12760000Y29035000D03*
G04 #@! TD*
D34*
G04 #@! TO.C,U6*
X25200000Y21300000D03*
X25200000Y19700000D03*
X26800000Y21300000D03*
X26800000Y19700000D03*
D35*
X22562500Y23100000D03*
X22562500Y22700000D03*
X22562500Y22300000D03*
X22562500Y21900000D03*
X22562500Y21500000D03*
X22562500Y21100000D03*
X22562500Y20700000D03*
X22562500Y20300000D03*
X22562500Y19900000D03*
X22562500Y19500000D03*
X22562500Y19100000D03*
X22562500Y18700000D03*
X22562500Y18300000D03*
X22562500Y17900000D03*
D36*
X23400000Y17062500D03*
X23800000Y17062500D03*
X24200000Y17062500D03*
X24600000Y17062500D03*
X25000000Y17062500D03*
X25400000Y17062500D03*
X25800000Y17062500D03*
X26200000Y17062500D03*
X26600000Y17062500D03*
X27000000Y17062500D03*
X27400000Y17062500D03*
X27800000Y17062500D03*
X28200000Y17062500D03*
X28600000Y17062500D03*
D35*
X29437500Y17900000D03*
X29437500Y18300000D03*
X29437500Y18700000D03*
X29437500Y19100000D03*
X29437500Y19500000D03*
X29437500Y19900000D03*
X29437500Y20300000D03*
X29437500Y20700000D03*
X29437500Y21100000D03*
X29437500Y21500000D03*
X29437500Y21900000D03*
X29437500Y22300000D03*
X29437500Y22700000D03*
X29437500Y23100000D03*
D36*
X28600000Y23937500D03*
X28200000Y23937500D03*
X27800000Y23937500D03*
X27400000Y23937500D03*
X27000000Y23937500D03*
X26600000Y23937500D03*
X26200000Y23937500D03*
X25800000Y23937500D03*
X25400000Y23937500D03*
X25000000Y23937500D03*
X24600000Y23937500D03*
X24200000Y23937500D03*
X23800000Y23937500D03*
X23400000Y23937500D03*
G04 #@! TD*
D22*
G04 #@! TO.C,C33*
X31100000Y25920000D03*
X31100000Y26880000D03*
G04 #@! TD*
D15*
G04 #@! TO.C,R27*
X95765000Y19291430D03*
X94745000Y19291430D03*
G04 #@! TD*
D13*
G04 #@! TO.C,C20*
X68195000Y55500000D03*
X69155000Y55500000D03*
G04 #@! TD*
D10*
G04 #@! TO.C,C9*
X49150000Y9900000D03*
X47600000Y9900000D03*
G04 #@! TD*
D37*
G04 #@! TO.C,F1*
X19627500Y67302500D03*
X17752500Y67302500D03*
G04 #@! TD*
D13*
G04 #@! TO.C,C12*
X15020000Y80200000D03*
X15980000Y80200000D03*
G04 #@! TD*
D19*
G04 #@! TO.C,R40*
X11740000Y30335000D03*
X12760000Y30335000D03*
G04 #@! TD*
D11*
G04 #@! TO.C,R37*
X25900000Y13990000D03*
X25900000Y15010000D03*
G04 #@! TD*
D13*
G04 #@! TO.C,C26*
X68195000Y23500000D03*
X69155000Y23500000D03*
G04 #@! TD*
G04 #@! TO.C,C19*
X68195000Y69500000D03*
X69155000Y69500000D03*
G04 #@! TD*
D38*
G04 #@! TO.C,X1*
X88125000Y66975000D03*
X88125000Y68825000D03*
X86675000Y68825000D03*
X86675000Y66975000D03*
G04 #@! TD*
D10*
G04 #@! TO.C,C15*
X71225000Y8900000D03*
X69675000Y8900000D03*
G04 #@! TD*
D27*
G04 #@! TO.C,SW3*
X1650000Y52900000D03*
X8150000Y52900000D03*
G04 #@! TD*
D39*
G04 #@! TO.C,R16*
X37200000Y74875000D03*
X37200000Y76525000D03*
G04 #@! TD*
D24*
G04 #@! TO.C,C17*
X65400000Y14760000D03*
X66950000Y14760000D03*
G04 #@! TD*
D40*
G04 #@! TO.C,U4*
X11725000Y18137500D03*
X12375000Y18137500D03*
X13025000Y18137500D03*
X13675000Y18137500D03*
X14325000Y18137500D03*
X14975000Y18137500D03*
X15625000Y18137500D03*
X16275000Y18137500D03*
X16275000Y23862500D03*
X15625000Y23862500D03*
X14975000Y23862500D03*
X14325000Y23862500D03*
X13675000Y23862500D03*
X13025000Y23862500D03*
X12375000Y23862500D03*
X11725000Y23862500D03*
G04 #@! TD*
D27*
G04 #@! TO.C,SW1*
X44750000Y10000000D03*
X38250000Y10000000D03*
G04 #@! TD*
D26*
G04 #@! TO.C,C3*
X35700000Y74925000D03*
X35700000Y76475000D03*
G04 #@! TD*
D11*
G04 #@! TO.C,R17*
X94550000Y70790000D03*
X94550000Y71810000D03*
G04 #@! TD*
D13*
G04 #@! TO.C,C34*
X31570000Y23900000D03*
X32530000Y23900000D03*
G04 #@! TD*
D15*
G04 #@! TO.C,R31*
X37510000Y64600000D03*
X36490000Y64600000D03*
G04 #@! TD*
D41*
G04 #@! TO.C,U3*
X21050000Y77637500D03*
X20100000Y77637500D03*
X19150000Y77637500D03*
X19150000Y75362500D03*
X21050000Y75362500D03*
G04 #@! TD*
D20*
G04 #@! TO.C,C60*
X8400000Y47030000D03*
X8400000Y46070000D03*
G04 #@! TD*
D42*
G04 #@! TO.C,U2*
X12350000Y69850000D03*
X14650000Y69850000D03*
D43*
X14650000Y76150000D03*
D42*
X16950000Y69850000D03*
G04 #@! TD*
D15*
G04 #@! TO.C,R25*
X95765000Y24302858D03*
X94745000Y24302858D03*
G04 #@! TD*
G04 #@! TO.C,R29*
X95765000Y14280000D03*
X94745000Y14280000D03*
G04 #@! TD*
D26*
G04 #@! TO.C,C61*
X7150000Y45425000D03*
X7150000Y46975000D03*
G04 #@! TD*
D15*
G04 #@! TO.C,R47*
X93810000Y46600000D03*
X92790000Y46600000D03*
G04 #@! TD*
D19*
G04 #@! TO.C,R6*
X14390000Y54814286D03*
X15410000Y54814286D03*
G04 #@! TD*
D10*
G04 #@! TO.C,C11*
X20925000Y73600000D03*
X19375000Y73600000D03*
G04 #@! TD*
D44*
G04 #@! TO.C,J4*
X41395000Y72030000D03*
X46445000Y72030000D03*
X41395000Y69490000D03*
X46445000Y69490000D03*
X41395000Y66950000D03*
X46445000Y66950000D03*
X41395000Y64410000D03*
X46445000Y64410000D03*
X41395000Y61870000D03*
X46445000Y61870000D03*
X41395000Y59330000D03*
X46445000Y59330000D03*
X41395000Y56790000D03*
X46445000Y56790000D03*
X41395000Y54250000D03*
X46445000Y54250000D03*
X41395000Y51710000D03*
X46445000Y51710000D03*
X41395000Y49170000D03*
X46445000Y49170000D03*
X41395000Y46630000D03*
X46445000Y46630000D03*
X41395000Y44090000D03*
X46445000Y44090000D03*
X41395000Y41550000D03*
X46445000Y41550000D03*
X41395000Y39010000D03*
X46445000Y39010000D03*
X41395000Y36470000D03*
X46445000Y36470000D03*
X41395000Y33930000D03*
X46445000Y33930000D03*
X41395000Y31390000D03*
X46445000Y31390000D03*
X41395000Y28850000D03*
X46445000Y28850000D03*
X41395000Y26310000D03*
X46445000Y26310000D03*
X41395000Y23770000D03*
X46445000Y23770000D03*
X77395000Y72030000D03*
X82445000Y72030000D03*
X77395000Y69490000D03*
X82445000Y69490000D03*
X77395000Y66950000D03*
X82445000Y66950000D03*
X77395000Y64410000D03*
X82445000Y64410000D03*
X77395000Y61870000D03*
X82445000Y61870000D03*
X77395000Y59330000D03*
X82445000Y59330000D03*
X77395000Y56790000D03*
X82445000Y56790000D03*
X77395000Y54250000D03*
X82445000Y54250000D03*
X77395000Y51710000D03*
X82445000Y51710000D03*
X77395000Y49170000D03*
X82445000Y49170000D03*
X77395000Y46630000D03*
X82445000Y46630000D03*
X77395000Y44090000D03*
X82445000Y44090000D03*
X77395000Y41550000D03*
X82445000Y41550000D03*
X77395000Y39010000D03*
X82445000Y39010000D03*
X77395000Y36470000D03*
X82445000Y36470000D03*
X77395000Y33930000D03*
X82445000Y33930000D03*
X77395000Y31390000D03*
X82445000Y31390000D03*
X77395000Y28850000D03*
X82445000Y28850000D03*
X77395000Y26310000D03*
X82445000Y26310000D03*
X77395000Y23770000D03*
X82445000Y23770000D03*
G04 #@! TD*
D25*
G04 #@! TO.C,C43*
X95280000Y48800000D03*
X94320000Y48800000D03*
G04 #@! TD*
D19*
G04 #@! TO.C,R10*
X14390000Y57357143D03*
X15410000Y57357143D03*
G04 #@! TD*
D45*
G04 #@! TO.C,D2*
X95800000Y70212500D03*
X95800000Y71787500D03*
G04 #@! TD*
D19*
G04 #@! TO.C,R30*
X36490000Y68900000D03*
X37510000Y68900000D03*
G04 #@! TD*
D15*
G04 #@! TO.C,R44*
X93810000Y60600000D03*
X92790000Y60600000D03*
G04 #@! TD*
G04 #@! TO.C,R26*
X95765000Y21797144D03*
X94745000Y21797144D03*
G04 #@! TD*
D22*
G04 #@! TO.C,C41*
X25800000Y26070000D03*
X25800000Y27030000D03*
G04 #@! TD*
D25*
G04 #@! TO.C,C13*
X21080000Y72100000D03*
X20120000Y72100000D03*
G04 #@! TD*
D15*
G04 #@! TO.C,R48*
X91810000Y47600000D03*
X90790000Y47600000D03*
G04 #@! TD*
D26*
G04 #@! TO.C,C57*
X7200000Y22325000D03*
X7200000Y23875000D03*
G04 #@! TD*
D13*
G04 #@! TO.C,C14*
X69620000Y10200000D03*
X70580000Y10200000D03*
G04 #@! TD*
D45*
G04 #@! TO.C,D3*
X91700000Y70212500D03*
X91700000Y71787500D03*
G04 #@! TD*
D15*
G04 #@! TO.C,R34*
X24410000Y29450000D03*
X23390000Y29450000D03*
G04 #@! TD*
D19*
G04 #@! TO.C,R9*
X6990000Y49500000D03*
X8010000Y49500000D03*
G04 #@! TD*
D15*
G04 #@! TO.C,R46*
X91810000Y46600000D03*
X90790000Y46600000D03*
G04 #@! TD*
D14*
G04 #@! TO.C,R33*
X10500000Y23810000D03*
X10500000Y22790000D03*
G04 #@! TD*
D45*
G04 #@! TO.C,D1*
X100800000Y70212500D03*
X100800000Y71787500D03*
G04 #@! TD*
D15*
G04 #@! TO.C,R39*
X24410000Y27700000D03*
X23390000Y27700000D03*
G04 #@! TD*
D46*
G04 #@! TO.C,C10*
X15000000Y78540000D03*
X16900000Y78540000D03*
G04 #@! TD*
D47*
G04 #@! TO.C,D4*
X91712500Y63500000D03*
X93287500Y63500000D03*
G04 #@! TD*
D19*
G04 #@! TO.C,R32*
X36490000Y63300000D03*
X37510000Y63300000D03*
G04 #@! TD*
G04 #@! TO.C,R4*
X14390000Y49728572D03*
X15410000Y49728572D03*
G04 #@! TD*
D13*
G04 #@! TO.C,C40*
X27170000Y15200000D03*
X28130000Y15200000D03*
G04 #@! TD*
D26*
G04 #@! TO.C,C1*
X44000000Y13125000D03*
X44000000Y14675000D03*
G04 #@! TD*
D11*
G04 #@! TO.C,R36*
X6600000Y27890000D03*
X6600000Y28910000D03*
G04 #@! TD*
D26*
G04 #@! TO.C,C59*
X7200000Y68325000D03*
X7200000Y69875000D03*
G04 #@! TD*
D13*
G04 #@! TO.C,C31*
X21070000Y33400000D03*
X22030000Y33400000D03*
G04 #@! TD*
G04 #@! TO.C,C22*
X68195000Y31540000D03*
X69155000Y31540000D03*
G04 #@! TD*
D19*
G04 #@! TO.C,R14*
X1090000Y49500000D03*
X2110000Y49500000D03*
G04 #@! TD*
M02*

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,13 @@
M48
; DRILL file {KiCad 7.0.9-7.0.9~ubuntu22.04.1} date Fri 15 Dec 2023 03:20:48 PM
; FORMAT={-:-/ absolute / metric / decimal}
; #@! TF.CreationDate,2023-12-15T15:20:48-05:00
; #@! TF.GenerationSoftware,Kicad,Pcbnew,7.0.9-7.0.9~ubuntu22.04.1
; #@! TF.FileFunction,NonPlated,1,4,NPTH
FMAT,2
METRIC
%
G90
G05
T0
M30

View file

@ -0,0 +1,740 @@
M48
; DRILL file {KiCad 7.0.9-7.0.9~ubuntu22.04.1} date Fri 15 Dec 2023 03:20:48 PM
; FORMAT={-:-/ absolute / metric / decimal}
; #@! TF.CreationDate,2023-12-15T15:20:48-05:00
; #@! TF.GenerationSoftware,Kicad,Pcbnew,7.0.9-7.0.9~ubuntu22.04.1
; #@! TF.FileFunction,Plated,1,4,PTH
FMAT,2
METRIC
; #@! TA.AperFunction,Plated,PTH,ViaDrill
T1C0.300
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T2C0.300
; #@! TA.AperFunction,Plated,PTH,ViaDrill
T3C0.400
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T4C0.600
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T5C1.000
; #@! TA.AperFunction,Plated,PTH,ComponentDrill
T6C3.200
%
G90
G05
T1
X4.9Y33.08
X5.724Y14.712
X5.998Y61.12
X6.433Y15.702
X6.525Y31.2
X6.543Y27.545
X6.632Y33.758
X6.677Y35.792
X7.055Y30.205
X7.067Y37.015
X7.2Y74.5
X7.2Y70.9
X7.3Y8.5
X7.382Y60.53
X7.8Y75.1
X8.2Y60.015
X8.3Y20.2
X8.62Y50.5
X8.65Y45.3
X8.674Y34.7
X9.1Y21.5
X9.109Y27.286
X9.252Y51.2
X9.4Y57.1
X9.507Y36.529
X9.6Y62.6
X9.6Y55.495
X9.6Y37.6
X9.65Y25.85
X9.9Y22.6
X10.025Y42.765
X10.152Y18.5
X10.154Y35.758
X10.4Y58.267
X10.47Y47.994
X10.47Y41.061
X10.8Y10.9
X11.102Y53.002
X11.903Y64.183
X12.18Y25.177
X12.2Y19.4
X12.5Y37.3
X12.58Y26.638
X12.626Y60.63
X12.8Y31.3
X13.029Y19.296
X13.45Y41.078
X13.5Y57.2
X13.5Y54.8
X13.5Y52.3
X13.5Y49.7
X13.5Y47.186
X13.5Y44.6
X13.506Y59.594
X13.709Y37.14
X13.9Y16.2
X14.157Y26.345
X14.232Y20.995
X14.291Y45.691
X14.322Y19.3
X14.325Y24.9
X14.5Y48.71
X14.942Y22.0
X14.989Y32.433
X15.25Y30.9
X15.558Y19.175
X15.639Y25.176
X15.665Y28.665
X16.1Y14.0
X16.2Y7.15
X16.287Y20.594
X16.555Y35.375
X16.602Y25.175
X16.9Y16.7
X16.924Y66.013
X17.1Y80.2
X17.1Y7.8
X17.346Y17.7
X17.6Y18.7
X17.648Y27.821
X17.68Y23.7
X17.85Y80.15
X18.0Y78.2
X18.0Y25.8
X18.175Y29.2
X18.221Y33.068
X18.807Y23.02
X18.9Y17.95
X19.0Y19.8
X19.2Y72.2
X19.25Y52.6
X19.476Y24.326
X19.5Y25.3
X19.762Y34.011
X19.77Y40.372
X19.964Y19.794
X20.1Y76.3
X20.194Y71.302
X20.3Y32.5
X20.436Y7.086
X20.476Y33.496
X20.527Y50.527
X21.057Y42.373
X21.2Y43.7
X21.3Y56.8
X21.3Y25.738
X21.3Y8.8
X21.5Y17.712
X21.922Y12.6
X22.4Y46.5
X22.521Y35.879
X22.637Y17.062
X22.7Y4.342
X22.8Y63.052
X22.912Y30.238
X23.1Y52.2
X23.1Y33.3
X23.7Y9.474
X23.73Y28.529
X23.9Y44.5
X23.981Y38.78
X24.026Y56.332
X24.1Y47.2
X24.159Y22.895
X24.65Y15.75
X24.738Y26.064
X24.898Y17.987
X25.099Y8.351
X25.312Y65.093
X25.442Y43.219
X25.675Y25.261
X25.8Y22.7
X26.2Y31.7
X26.407Y18.197
X26.473Y7.48
X26.506Y26.871
X26.924Y25.616
X27.1Y27.7
X27.247Y18.064
X27.4Y72.5
X27.55Y10.9
X27.615Y25.134
X28.162Y10.288
X28.527Y18.118
X28.671Y71.51
X28.8Y72.3
X28.85Y15.195
X28.85Y14.3
X29.444Y47.837
X29.5Y16.95
X29.6Y12.3
X30.11Y47.19
X30.3Y0.7
X30.35Y28.9
X30.35Y16.988
X31.027Y28.166
X31.1Y8.838
X31.6Y53.9
X31.6Y46.1
X32.0Y13.6
X32.0Y10.6
X32.0Y7.877
X32.004Y27.007
X32.371Y26.106
X32.39Y18.578
X32.4Y24.8
X32.5Y64.6
X32.688Y36.627
X32.752Y1.195
X32.889Y50.725
X32.95Y12.25
X33.0Y44.3
X33.264Y24.631
X33.371Y18.578
X33.7Y49.1
X34.167Y31.3
X34.556Y59.572
X34.88Y52.938
X35.05Y1.7
X35.114Y34.5
X35.2Y9.6
X35.22Y68.56
X35.4Y14.4
X35.85Y8.15
X35.97Y51.3
X35.986Y55.098
X35.995Y64.747
X36.0Y62.9
X36.234Y24.6
X36.234Y17.456
X36.5Y41.6
X36.8Y73.9
X36.8Y13.0
X37.9Y33.9
X38.507Y15.088
X38.6Y23.5
X38.8Y72.97
X39.1Y8.185
X39.172Y64.887
X39.176Y54.413
X39.3Y32.7
X39.572Y72.174
X40.25Y0.85
X41.8Y32.7
X43.098Y12.473
X43.1Y14.6
X43.25Y10.0
X44.046Y68.625
X44.05Y12.3
X44.1Y74.3
X44.67Y41.735
X45.896Y11.603
X45.9Y17.0
X46.3Y25.5
X46.6Y11.1
X46.65Y12.35
X46.8Y73.4
X48.6Y23.2
X48.741Y58.685
X49.247Y61.197
X49.285Y20.7
X50.0Y10.7
X50.1Y11.55
X50.2Y26.1
X50.267Y42.867
X50.444Y66.3
X51.042Y58.24
X51.042Y22.5
X51.6Y69.4
X51.755Y56.2
X51.8Y61.7
X51.835Y20.133
X51.867Y65.88
X52.427Y30.5
X52.468Y9.3
X53.1Y62.7
X53.1Y50.6
X53.14Y22.1
X53.9Y19.7
X54.4Y70.985
X54.4Y58.705
X54.4Y55.9
X54.967Y45.7
X54.967Y18.184
X55.152Y48.545
X55.7Y20.8
X55.999Y63.785
X56.9Y67.2
X57.35Y17.95
X58.0Y53.05
X58.037Y28.0
X58.2Y7.7
X58.7Y14.1
X58.8Y38.9
X59.6Y15.7
X59.8Y23.0
X60.9Y65.8
X60.9Y1.3
X61.51Y12.543
X61.8Y13.9
X61.847Y10.1
X61.9Y7.0
X61.9Y70.312
X63.19Y21.245
X63.2Y16.4
X64.25Y67.75
X64.3Y8.4
X64.331Y14.066
X64.55Y5.6
X65.4Y15.8
X65.9Y12.5
X66.22Y64.9
X66.7Y38.7
X67.0Y11.79
X67.55Y74.2
X68.2Y46.5
X69.0Y12.4
X69.0Y9.8
X69.0Y8.4
X70.0Y59.6
X70.5Y70.9
X70.807Y13.207
X72.1Y39.832
X72.14Y46.8
X73.256Y12.575
X74.7Y49.2
X74.7Y37.322
X75.7Y43.915
X75.9Y11.867
X76.4Y45.4
X77.2Y36.6
X78.397Y40.097
X78.397Y11.167
X79.2Y60.4
X79.825Y43.7
X82.3Y10.5
X82.4Y68.435
X84.8Y74.0
X84.8Y45.7
X84.8Y9.7
X84.9Y13.207
X86.2Y57.9
X86.2Y51.9
X87.1Y30.0
X87.15Y16.2
X87.2Y25.2
X87.4Y63.2
X87.4Y50.0
X87.45Y8.95
X87.82Y68.14
X88.05Y20.6
X88.15Y26.2
X88.4Y76.7
X88.65Y19.8
X88.669Y70.061
X88.775Y24.298
X89.92Y7.4
X90.0Y54.2
X90.0Y49.1
X90.05Y25.9
X90.05Y19.9
X90.1Y73.5
X90.531Y69.425
X91.45Y26.0
X91.45Y19.9
X92.0Y76.7
X92.5Y52.7
X92.65Y45.98
X92.703Y56.625
X93.8Y70.2
X94.35Y25.2
X94.35Y17.7
X94.4Y73.2
X94.4Y65.0
X94.4Y60.7
X94.5Y48.1
X95.7Y69.6
X98.6Y69.9
X99.1Y41.4
X99.7Y11.8
X100.0Y10.5
X100.529Y8.941
X100.553Y13.147
X100.679Y11.735
X101.174Y10.441
X101.551Y9.0
T2
X0.7Y63.6
X0.7Y58.6
X0.7Y12.9
X0.9Y72.3
X3.4Y49.5
X3.7Y9.0
X7.2Y34.8
X8.1Y73.6
X8.1Y62.9
X8.45Y67.55
X8.5Y19.1
X8.5Y13.1
X8.6Y58.2
X8.6Y54.8
X8.7Y41.9
X10.3Y39.0
X10.3Y29.3
X11.2Y54.7
X11.25Y80.2
X12.3Y21.3
X12.4Y71.8
X12.5Y49.7
X12.5Y45.7
X12.5Y41.9
X12.5Y13.1
X12.5Y5.2
X12.5Y0.7
X17.6Y13.9
X19.7Y5.2
X20.0Y48.8
X20.2Y57.3
X23.0Y43.3
X23.6Y8.1
X23.75Y71.0
X24.0Y73.3
X24.2Y33.3
X24.4Y18.9
X24.5Y22.1
X26.0Y63.0
X26.0Y20.5
X27.0Y68.2
X27.7Y22.0
X27.7Y18.8
X29.0Y70.4
X31.2Y56.8
X31.4Y44.5
X31.9Y67.2
X32.8Y73.3
X34.4Y10.3
X34.5Y14.8
X35.2Y72.2
X35.5Y26.4
X35.5Y19.0
X35.7Y32.9
X35.7Y5.6
X37.8Y41.5
X39.9Y9.7
X40.2Y19.1
X40.4Y5.6
X42.9Y0.8
X43.6Y41.3
X43.9Y36.4
X43.9Y31.5
X47.98Y0.8
X48.1Y75.6
X48.8Y66.0
X50.1Y17.2
X52.0Y62.8
X53.0Y69.5
X53.06Y0.8
X53.1Y75.6
X54.9Y50.1
X55.7Y75.6
X56.5Y30.3
X56.5Y9.2
X56.6Y55.5
X56.7Y19.1
X58.14Y0.8
X58.7Y13.2
X62.2Y65.3
X62.2Y55.6
X62.2Y50.3
X62.2Y45.3
X62.2Y41.1
X62.2Y34.0
X62.2Y27.1
X62.2Y19.1
X63.2Y6.3
X63.22Y0.8
X63.3Y75.6
X66.6Y31.6
X66.6Y29.0
X66.6Y26.5
X66.6Y23.5
X67.4Y75.6
X68.3Y0.8
X70.9Y75.6
X71.2Y65.2
X71.2Y59.4
X71.2Y50.9
X71.3Y46.3
X71.3Y38.8
X71.3Y32.6
X71.3Y27.4
X71.3Y22.1
X71.6Y12.0
X73.38Y0.8
X73.6Y75.6
X74.4Y73.5
X78.46Y0.8
X78.9Y73.5
X80.7Y14.2
X81.1Y75.6
X83.5Y6.8
X83.54Y0.8
X83.6Y75.6
X86.0Y43.1
X86.0Y37.5
X86.0Y31.4
X86.2Y75.6
X86.85Y14.2
X87.1Y23.0
X88.62Y0.8
X88.7Y49.4
X88.8Y6.8
X90.05Y23.0
X90.1Y59.2
X91.8Y75.6
X92.9Y23.0
X93.4Y55.1
X95.3Y73.6
X95.8Y25.6
X95.8Y18.0
X95.9Y59.4
X96.2Y43.1
X96.2Y37.5
X97.7Y71.7
X101.4Y26.6
X101.4Y24.1
X101.4Y21.5
X103.7Y69.1
X103.7Y64.1
X103.7Y59.1
X103.7Y54.1
X103.7Y49.1
X103.7Y44.1
X103.7Y39.1
X103.7Y34.1
X103.7Y29.1
T3
X11.2Y69.8
X12.7Y68.2
X13.1Y67.3
X21.1Y69.5
X21.7Y72.8
X23.1Y41.6
X24.701Y72.305
X25.75Y72.252
X26.2Y67.3
X30.6Y72.4
X30.7Y67.3
X31.7Y72.4
X36.435Y49.27
X38.027Y66.715
X39.2Y61.6
X41.5Y76.0
X41.5Y70.62
X41.5Y65.3
X43.4Y53.9
X43.6Y49.1
X44.0Y24.8
X46.5Y62.8
X48.3Y24.6
X48.7Y72.0
X67.6Y73.0
X67.6Y70.5
X67.6Y54.9
X69.0Y27.5
X69.0Y24.5
X69.25Y77.386
X69.25Y53.915
X69.25Y51.389
X69.47Y70.538
X69.56Y73.066
X70.0Y55.105
X70.0Y31.5
X70.0Y29.0
X75.1Y41.7
X75.4Y56.8
X79.0Y48.3
X79.4Y33.9
X80.1Y28.8
X80.2Y31.4
X80.2Y26.3
X80.2Y23.8
X80.6Y72.0
X80.7Y50.9
X82.5Y60.4
X82.6Y43.1
X83.5Y68.6
X84.7Y49.1
X87.15Y21.8
X88.5Y54.5
X88.669Y56.69
X96.5Y4.4
X96.9Y79.4
X96.9Y78.5
X96.9Y70.7
X97.1Y5.3
T4
X96.9Y31.78
X96.9Y29.28
X96.9Y26.78
X96.9Y24.28
X96.9Y21.78
X96.9Y19.28
X96.9Y16.78
X96.9Y14.28
X99.9Y31.78
X99.9Y29.28
X99.9Y26.78
X99.9Y24.28
X99.9Y21.78
X99.9Y19.28
X99.9Y16.78
X99.9Y14.28
T5
X1.69Y29.26
X1.96Y70.0
X1.96Y67.46
X1.96Y64.92
X1.96Y62.38
X1.96Y59.84
X1.96Y57.3
X1.96Y47.14
X1.96Y44.6
X1.96Y42.06
X1.96Y39.52
X1.96Y36.98
X1.96Y34.44
X1.96Y24.28
X1.96Y21.74
X1.96Y19.2
X1.96Y16.66
X1.96Y14.12
X1.96Y11.58
X4.23Y29.26
X4.5Y70.0
X4.5Y67.46
X4.5Y64.92
X4.5Y62.38
X4.5Y59.84
X4.5Y57.3
X4.5Y47.14
X4.5Y44.6
X4.5Y42.06
X4.5Y39.52
X4.5Y36.98
X4.5Y34.44
X4.5Y24.28
X4.5Y21.74
X4.5Y19.2
X4.5Y16.66
X4.5Y14.12
X4.5Y11.58
X11.19Y3.0
X13.73Y3.0
X16.27Y3.0
X18.81Y3.0
X21.345Y5.545
X21.345Y3.005
X23.885Y5.545
X23.885Y3.005
X26.425Y5.545
X26.425Y3.005
X28.965Y5.545
X28.965Y3.005
X31.505Y5.545
X31.505Y3.005
X34.045Y5.545
X34.045Y3.005
X36.58Y79.0
X36.62Y3.0
X39.12Y79.0
X39.16Y3.0
X41.66Y79.0
X41.7Y3.0
X44.2Y79.0
X44.205Y5.545
X44.205Y3.005
X46.74Y79.0
X46.745Y5.545
X46.745Y3.005
X49.28Y79.0
X49.285Y5.545
X49.285Y3.005
X51.82Y79.0
X51.825Y5.545
X51.825Y3.005
X54.36Y79.0
X54.365Y5.545
X54.365Y3.005
X56.9Y79.0
X56.905Y5.545
X56.905Y3.005
X59.44Y79.0
X59.465Y3.0
X61.98Y79.0
X62.005Y3.0
X64.52Y79.0
X64.545Y3.0
X67.06Y79.0
X67.065Y5.545
X67.065Y3.005
X69.6Y79.0
X69.605Y5.545
X69.605Y3.005
X72.14Y79.0
X72.145Y5.545
X72.145Y3.005
X74.68Y79.0
X74.685Y5.545
X74.685Y3.005
X77.22Y79.0
X77.225Y5.545
X77.225Y3.005
X79.76Y79.0
X79.765Y5.545
X79.765Y3.005
X82.3Y79.0
X82.3Y3.0
X84.84Y79.0
X84.84Y3.0
X87.38Y79.0
X87.38Y3.0
X89.92Y79.0
X89.92Y3.0
X92.46Y79.0
X92.46Y3.0
X95.0Y79.0
X95.0Y3.0
T6
X3.75Y77.25
X3.75Y3.75
X100.75Y77.25
X100.75Y3.75
T4
G00X22.63Y78.4
M15
G01X22.63Y79.6
M16
G05
G00X22.63Y74.6
M15
G01X22.63Y75.4
M16
G05
G00X33.87Y78.4
M15
G01X33.87Y79.6
M16
G05
G00X33.87Y74.6
M15
G01X33.87Y75.4
M16
G05
T0
M30

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,209 @@
{
"Header": {
"GenerationSoftware": {
"Vendor": "KiCad",
"Application": "Pcbnew",
"Version": "7.0.9-7.0.9~ubuntu22.04.1"
},
"CreationDate": "2023-12-15T15:20:45-05:00"
},
"GeneralSpecs": {
"ProjectId": {
"Name": "tinytapeout-demo",
"GUID": "74696e79-7461-4706-956f-75742d64656d",
"Revision": "0.9.4"
},
"Size": {
"X": 104.6,
"Y": 81.1
},
"LayerNumber": 4,
"BoardThickness": 1.5625,
"Finish": "None",
"ImpedanceControlled": true
},
"DesignRules": [
{
"Layers": "Outer",
"PadToPad": 0.18,
"PadToTrack": 0.18,
"TrackToTrack": 0.2,
"MinLineWidth": 0.16,
"TrackToRegion": 0.25,
"RegionToRegion": 0.25
},
{
"Layers": "Inner",
"PadToPad": 0.18,
"PadToTrack": 0.18,
"TrackToTrack": 0.2,
"MinLineWidth": 0.23,
"TrackToRegion": 0.25,
"RegionToRegion": 0.25
}
],
"FilesAttributes": [
{
"Path": "tinytapeout-demo-F_Cu.gbr",
"FileFunction": "Copper,L1,Top",
"FilePolarity": "Positive"
},
{
"Path": "tinytapeout-demo-In1_Cu.gbr",
"FileFunction": "Copper,L2,Inr",
"FilePolarity": "Positive"
},
{
"Path": "tinytapeout-demo-In2_Cu.gbr",
"FileFunction": "Copper,L3,Inr",
"FilePolarity": "Positive"
},
{
"Path": "tinytapeout-demo-B_Cu.gbr",
"FileFunction": "Copper,L4,Bot",
"FilePolarity": "Positive"
},
{
"Path": "tinytapeout-demo-F_Paste.gbr",
"FileFunction": "SolderPaste,Top",
"FilePolarity": "Positive"
},
{
"Path": "tinytapeout-demo-B_Paste.gbr",
"FileFunction": "SolderPaste,Bot",
"FilePolarity": "Positive"
},
{
"Path": "tinytapeout-demo-F_Silkscreen.gbr",
"FileFunction": "Legend,Top",
"FilePolarity": "Positive"
},
{
"Path": "tinytapeout-demo-B_Silkscreen.gbr",
"FileFunction": "Legend,Bot",
"FilePolarity": "Positive"
},
{
"Path": "tinytapeout-demo-F_Mask.gbr",
"FileFunction": "SolderMask,Top",
"FilePolarity": "Negative"
},
{
"Path": "tinytapeout-demo-B_Mask.gbr",
"FileFunction": "SolderMask,Bot",
"FilePolarity": "Negative"
},
{
"Path": "tinytapeout-demo-Edge_Cuts.gbr",
"FileFunction": "Profile",
"FilePolarity": "Positive"
},
{
"Path": "tinytapeout-demo-User_2.gbr",
"FileFunction": "Other,User",
"FilePolarity": "Positive"
}
],
"MaterialStackup": [
{
"Type": "Legend",
"Color": "White",
"Name": "Top Silk Screen"
},
{
"Type": "SolderPaste",
"Name": "Top Solder Paste"
},
{
"Type": "SolderMask",
"Color": "Green",
"Thickness": 0.01,
"Name": "Top Solder Mask"
},
{
"Type": "Copper",
"Thickness": 0.035,
"Name": "F.Cu"
},
{
"Type": "Dielectric",
"Color": "R109G116B75",
"Thickness": 0.0681,
"Material": "R-1551(W)",
"DielectricConstant": "4.3",
"LossTangent": "0.02",
"Name": "F.Cu/In1.Cu (1/2)",
"Notes": "Type: dielectric layer 1 - 1/2 (from F.Cu to In1.Cu)"
},
{
"Type": "Dielectric",
"Color": "R109G116B75",
"Thickness": 0.0681,
"Material": "R-1551(W)",
"DielectricConstant": "4.3",
"LossTangent": "0.02",
"Name": "F.Cu/In1.Cu (2/2)",
"Notes": "Type: dielectric layer 1 - 2/2 (from F.Cu to In1.Cu)"
},
{
"Type": "Copper",
"Thickness": 0.035,
"Name": "In1.Cu"
},
{
"Type": "Dielectric",
"Color": "R109G116B75",
"Thickness": 1.13,
"Material": "R-1566(W)",
"DielectricConstant": "4.6",
"LossTangent": "0.02",
"Name": "In1.Cu/In2.Cu",
"Notes": "Type: dielectric layer 2 (from In1.Cu to In2.Cu)"
},
{
"Type": "Copper",
"Thickness": 0.035,
"Name": "In2.Cu"
},
{
"Type": "Dielectric",
"Color": "R109G116B75",
"Thickness": 0.0681,
"Material": "R-1551(W)",
"DielectricConstant": "4.3",
"LossTangent": "0.02",
"Name": "In2.Cu/B.Cu (1/2)",
"Notes": "Type: dielectric layer 3 - 1/2 (from In2.Cu to B.Cu)"
},
{
"Type": "Dielectric",
"Color": "R109G116B75",
"Thickness": 0.0681,
"Material": "R-1551(W)",
"DielectricConstant": "4.3",
"LossTangent": "0.02",
"Name": "In2.Cu/B.Cu (2/2)",
"Notes": "Type: dielectric layer 3 - 2/2 (from In2.Cu to B.Cu)"
},
{
"Type": "Copper",
"Thickness": 0.035,
"Name": "B.Cu"
},
{
"Type": "SolderMask",
"Color": "Green",
"Thickness": 0.01,
"Name": "Bottom Solder Mask"
},
{
"Type": "SolderPaste",
"Name": "Bottom Solder Paste"
},
{
"Type": "Legend",
"Color": "White",
"Name": "Bottom Silk Screen"
}
]
}

View file

@ -0,0 +1,314 @@
/*
* Self-contained boot harness for the KiCad Gerber viewer (gerbview) WASM,
* embedded in the blog post via an <iframe>. Adapted from the proven test
* harness (tests/apps/kicad/gerbview.html) and the React port
* (web/standalone/src/wasm/boot.ts) — same global `Module`, same preRun steps,
* same wx.js -> wx-dom.js -> gerbview.js injection order.
*
* Classic script (NOT a module): the non-modularized WASM glue reads a GLOBAL
* `var Module` and a GLOBAL `mainWindow`, and publishes `FS` onto the global
* scope. Top-level `var`/`const` here share that global scope.
*
* Asset layout, split because the pthread worker script MUST be same-origin
* (a Worker can't be created from a cross-origin URL). So the small glue stays
* on the site origin and only the big binaries move to Cloudflare R2:
* GLUE_BASE : wx.js, wx-dom.js, gerbview.js, mainScriptUrlOrBlob (same-origin)
* BINARY_BASE : gerbview.wasm, kicad-resources.bin (R2 in prod, local in dev)
*
* BINARY_BASE auto-switches by hostname: localhost → the local mirror (./wasm),
* any other host → R2_BASE below. Override either base with ?glue=/?bin=.
* To point at R2, set R2_BASE to your bucket's public URL — either a custom
* domain (https://assets.pcbjam.com) or the managed https://<id>.r2.dev URL.
*/
(function () {
"use strict";
// R2 bucket public URL (no trailing slash). Custom domain for the
// pcbjam-assets bucket (the managed URL https://pub-cecc0239e6f74d99ba7d06630bd87c64.r2.dev
// also still works).
var R2_BASE = "https://assets.pcbjam.com";
var params = new URLSearchParams(location.search);
var isLocal = /^(localhost|127\.0\.0\.1|\[?::1\]?)$/.test(location.hostname);
var GLUE_BASE = (params.get("glue") || "./wasm").replace(/\/+$/, "");
var BINARY_BASE = (params.get("bin") || (isLocal ? "./wasm" : R2_BASE)).replace(
/\/+$/,
""
);
// KiCad paths baked into the WASM build (see web/standalone/src/wasm/constants.ts).
var KICAD_VERSION_DIR = "9.99";
var KICAD_CONFIG_DIR =
"/home/kicad/.config/kicad/kicad/" + KICAD_VERSION_DIR;
var RESOURCE_PATH =
"/workspace/build-wasm/sysroot/share/kicad/resources";
// The board to auto-open: all tiny_tapeout layers (bottom→top for a sensible
// draw order). The .gbrjob is preloaded too but we open the individual layer
// files (gerbview opens gerber/drill files from argv deterministically).
var BOARD_DIR = "/home/kicad/demo";
var BOARD_FILES = [
"tinytapeout-demo-Edge_Cuts.gbr",
"tinytapeout-demo-B_Cu.gbr",
"tinytapeout-demo-In2_Cu.gbr",
"tinytapeout-demo-In1_Cu.gbr",
"tinytapeout-demo-F_Cu.gbr",
"tinytapeout-demo-B_Mask.gbr",
"tinytapeout-demo-F_Mask.gbr",
"tinytapeout-demo-B_Paste.gbr",
"tinytapeout-demo-F_Paste.gbr",
"tinytapeout-demo-B_Silkscreen.gbr",
"tinytapeout-demo-F_Silkscreen.gbr",
"tinytapeout-demo-User_2.gbr",
"tinytapeout-demo-PTH.drl",
"tinytapeout-demo-NPTH.drl",
"tinytapeout-demo-job.gbrjob",
];
var OPEN_FILES = BOARD_FILES.filter(function (f) {
return /\.(gbr|drl)$/.test(f);
});
var OPEN_ARGS = OPEN_FILES.map(function (f) {
return BOARD_DIR + "/" + f;
});
// ── Status UI ──────────────────────────────────────────────────────────────
var statusText = document.getElementById("status-text");
var progressBar = document.getElementById("progress-bar");
function setStatusUI(text) {
if (statusText) statusText.textContent = text;
var m = /(\d+)\/(\d+)/.exec(text || "");
if (m && progressBar) {
progressBar.style.width =
(parseInt(m[1], 10) / parseInt(m[2], 10)) * 100 + "%";
}
}
function hideStatus() {
var s = document.getElementById("status");
if (s) s.style.display = "none";
}
function showError(msg) {
console.error("[KICAD_ERROR] " + msg);
if (statusText) {
statusText.textContent = "Error: " + msg;
statusText.style.color = "#ff6b6b";
}
}
// The WASM reads the top frame geometry from a GLOBAL `mainWindow` element.
var mainWindow = document.getElementById("main-window");
window.mainWindow = mainWindow;
// ── Prefetch the heavy, non-wasm assets in parallel with the wasm download ──
// images.tar.gz (compiled-in KiCad resources) and the board layers. Both are
// ~10x smaller than gerbview.wasm, so they land before preRun runs; a run
// dependency guards the rare case where the wasm wins the race.
var resourceData = null;
// Served without a .gz extension on purpose (see sync-demo-wasm.sh) so no
// server adds Content-Encoding: gzip. Written into MEMFS as images.tar.gz.
fetch(BINARY_BASE + "/kicad-resources.bin")
.then(function (r) {
if (!r.ok) throw new Error("HTTP " + r.status);
return r.arrayBuffer();
})
.then(function (buf) {
resourceData = new Uint8Array(buf);
console.log("[KICAD] prefetched images.tar.gz (" + resourceData.length + " bytes)");
})
.catch(function (err) {
console.warn("[KICAD] images.tar.gz prefetch failed:", err.message);
});
var boardData = null; // { name: Uint8Array }
var boardPromise = Promise.all(
BOARD_FILES.map(function (name) {
return fetch("./board/" + name)
.then(function (r) {
if (!r.ok) throw new Error("HTTP " + r.status + " for " + name);
return r.arrayBuffer();
})
.then(function (buf) {
return [name, new Uint8Array(buf)];
});
})
)
.then(function (pairs) {
boardData = {};
pairs.forEach(function (p) {
boardData[p[0]] = p[1];
});
console.log("[KICAD] prefetched " + pairs.length + " board files");
})
.catch(function (err) {
console.error("[KICAD] board prefetch failed:", err.message);
});
// ── preRun steps ────────────────────────────────────────────────────────────
function createCanvas() {
var canvas = document.createElement("canvas");
canvas.id = "canvas";
canvas.style.display = "none";
canvas.style.width = window.innerWidth + "px";
canvas.style.height = window.innerHeight + "px";
canvas.oncontextmenu = function (e) {
e.preventDefault();
};
canvas.addEventListener(
"webglcontextlost",
function (e) {
showError("WebGL context lost — reload to retry.");
e.preventDefault();
},
false
);
mainWindow.appendChild(canvas);
Module.canvas = canvas;
console.log("[KICAD] canvas " + window.innerWidth + "x" + window.innerHeight);
}
function writeResources() {
FS.mkdirTree(RESOURCE_PATH);
if (resourceData) {
FS.writeFile(RESOURCE_PATH + "/images.tar.gz", resourceData);
console.log("[KICAD] wrote images.tar.gz");
} else {
console.warn("[KICAD] images.tar.gz not ready at preRun");
}
}
// Suppress the first-run setup wizard (its modal loop crashes Asyncify on our
// ephemeral MEMFS): make every settings provider report NeedsUserInput()==false.
function seedKicadConfig() {
FS.mkdirTree(KICAD_CONFIG_DIR);
var seed = function (path, contents) {
if (FS.analyzePath(path).exists) return;
FS.writeFile(path, contents);
};
seed(
KICAD_CONFIG_DIR + "/kicad_common.json",
JSON.stringify(
{
do_not_show_again: {
update_check_prompt: true,
data_collection_prompt: true,
},
},
null,
2
)
);
seed(KICAD_CONFIG_DIR + "/sym-lib-table", "(sym_lib_table\n (version 7)\n)\n");
seed(KICAD_CONFIG_DIR + "/fp-lib-table", "(fp_lib_table\n (version 7)\n)\n");
seed(
KICAD_CONFIG_DIR + "/design-block-lib-table",
"(design_block_lib_table\n (version 7)\n)\n"
);
console.log("[KICAD] seeded config (wizard suppressed)");
}
// Write the board into MEMFS and point argv at it so gerbview auto-opens it.
// argv must be set before main(); a run dependency keeps main() waiting if the
// board fetch hasn't landed yet.
function preloadBoard() {
Module.arguments = OPEN_ARGS;
var writeBoard = function () {
if (!boardData) return;
FS.mkdirTree(BOARD_DIR);
Object.keys(boardData).forEach(function (name) {
FS.writeFile(BOARD_DIR + "/" + name, boardData[name]);
});
console.log("[KICAD] wrote board into " + BOARD_DIR + "; argv=" + OPEN_ARGS.length + " files");
};
if (boardData) {
writeBoard();
return;
}
var add = window.addRunDependency;
var rm = window.removeRunDependency;
if (typeof add === "function" && typeof rm === "function") {
add("board-files");
boardPromise.then(function () {
writeBoard();
rm("board-files");
});
} else {
// Best-effort fallback (board << wasm, so this path is unlikely to lose).
boardPromise.then(writeBoard);
}
}
// ── Module config (global) ───────────────────────────────────────────────────
var Module = {
thisProgram: "/usr/bin/gerbview", // argv[0] for KiCad's DEBUG check
arguments: OPEN_ARGS,
preRun: [createCanvas, writeResources, seedKicadConfig, preloadBoard],
postRun: [],
print: function () {
console.log("[KICAD_OUT] " + Array.prototype.join.call(arguments, " "));
},
printErr: function () {
console.error("[KICAD_ERR] " + Array.prototype.join.call(arguments, " "));
},
setStatus: function (text) {
if (text) console.log("[KICAD_STATUS] " + text);
setStatusUI(text);
},
totalDependencies: 0,
monitorRunDependencies: function (left) {
this.totalDependencies = Math.max(this.totalDependencies, left);
Module.setStatus(
left
? "Preparing… (" + (this.totalDependencies - left) + "/" + this.totalDependencies + ")"
: "All downloads complete."
);
},
onRuntimeInitialized: function () {
console.log("[KICAD] runtime initialized");
if (Module.canvas) Module.canvas.style.display = "block";
hideStatus();
},
onAbort: function (what) {
showError("aborted: " + (what === undefined ? "" : String(what)));
},
// Route the .wasm to BINARY_BASE; everything else (the pthread worker) to GLUE_BASE.
locateFile: function (path) {
return (/\.wasm$/.test(path) ? BINARY_BASE : GLUE_BASE) + "/" + path;
},
// Pin the pthread worker to the same-origin glue (workers cannot be cross-origin).
mainScriptUrlOrBlob: GLUE_BASE + "/gerbview.js",
};
window.Module = Module;
Module.setStatus("Downloading…");
window.onerror = function (msg, url, line) {
showError(msg + " @ " + url + ":" + line);
return false;
};
// ── Inject glue scripts in the required order ────────────────────────────────
function loadScript(src) {
return new Promise(function (resolve, reject) {
var s = document.createElement("script");
s.src = src;
s.onload = resolve;
s.onerror = function () {
reject(new Error("failed to load " + src));
};
document.body.appendChild(s);
});
}
loadScript(GLUE_BASE + "/wx.js")
.then(function () {
return loadScript(GLUE_BASE + "/wx-dom.js");
})
.then(function () {
return loadScript(GLUE_BASE + "/gerbview.js");
})
.then(function () {
console.log("[KICAD] injected wx.js + wx-dom.js + gerbview.js (glue=" + GLUE_BASE + ", bin=" + BINARY_BASE + ")");
})
.catch(function (err) {
showError(err.message);
});
})();

View file

@ -0,0 +1,89 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>PCBJam — Gerber viewer demo</title>
<style>
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
background: #0b1020;
}
/* The canvas must have no border/padding or mouse coords go wrong. */
.emscripten {
padding-right: 0;
margin-left: auto;
margin-right: auto;
display: block;
}
div.emscripten {
text-align: center;
}
canvas.emscripten {
border: 0px none;
}
/* wxWidgets-DOM per-window overlays (created by wx.js, appended to
#window-container). Mirror the proven harness exactly. */
.window {
position: absolute;
pointer-events: none;
z-index: 10;
background-color: black;
overflow: hidden;
width: 0;
height: 0;
}
.window-canvas {
position: absolute;
top: 0;
left: 0;
pointer-events: none;
}
#status {
position: fixed;
left: 12px;
bottom: 12px;
z-index: 1000;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-size: 12px;
color: #e7ecf5;
background: rgba(11, 16, 32, 0.85);
border: 1px solid #233052;
padding: 8px 10px;
border-radius: 8px;
}
#progress {
width: 240px;
height: 6px;
margin-top: 6px;
background: #233052;
border-radius: 3px;
overflow: hidden;
}
#progress-bar {
height: 100%;
width: 0%;
background: #4f7cff;
transition: width 0.25s;
}
</style>
</head>
<body>
<div
id="main-window"
style="width: 100vw; height: 100vh; position: absolute; top: 0; left: 0"
></div>
<div id="window-container"></div>
<div id="status">
<div id="status-text">Initializing…</div>
<div id="progress"><div id="progress-bar"></div></div>
</div>
<!-- Classic script (not a module): the WASM glue needs global Module / mainWindow / FS. -->
<script src="./boot.js"></script>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff