fritzkit 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +12 -0
- package/.claude-plugin/plugin.json +13 -0
- package/CHANGELOG.md +8 -0
- package/LICENSE +21 -0
- package/README.md +429 -2
- package/dist/cli/commands/doctor.d.ts +4 -0
- package/dist/cli/commands/doctor.js +7 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/export.d.ts +17 -0
- package/dist/cli/commands/export.js +81 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/kicad.d.ts +10 -0
- package/dist/cli/commands/kicad.js +22 -0
- package/dist/cli/commands/kicad.js.map +1 -0
- package/dist/cli/commands/parts.d.ts +22 -0
- package/dist/cli/commands/parts.js +46 -0
- package/dist/cli/commands/parts.js.map +1 -0
- package/dist/cli/commands/prune.d.ts +14 -0
- package/dist/cli/commands/prune.js +67 -0
- package/dist/cli/commands/prune.js.map +1 -0
- package/dist/cli/commands/render.d.ts +24 -0
- package/dist/cli/commands/render.js +62 -0
- package/dist/cli/commands/render.js.map +1 -0
- package/dist/cli/commands/schema.d.ts +10 -0
- package/dist/cli/commands/schema.js +35 -0
- package/dist/cli/commands/schema.js.map +1 -0
- package/dist/cli/commands/ui.d.ts +14 -0
- package/dist/cli/commands/ui.js +67 -0
- package/dist/cli/commands/ui.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +24 -0
- package/dist/cli/commands/validate.js +91 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/context.d.ts +81 -0
- package/dist/cli/context.js +139 -0
- package/dist/cli/context.js.map +1 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.js +8 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/program.d.ts +21 -0
- package/dist/cli/program.js +158 -0
- package/dist/cli/program.js.map +1 -0
- package/dist/cli/raster.d.ts +4 -0
- package/dist/cli/raster.js +9 -0
- package/dist/cli/raster.js.map +1 -0
- package/dist/core/compile/breadboard-util.d.ts +12 -0
- package/dist/core/compile/breadboard-util.js +107 -0
- package/dist/core/compile/breadboard-util.js.map +1 -0
- package/dist/core/compile/breadboard.d.ts +60 -0
- package/dist/core/compile/breadboard.js +513 -0
- package/dist/core/compile/breadboard.js.map +1 -0
- package/dist/core/compile/fzp.d.ts +12 -0
- package/dist/core/compile/fzp.js +183 -0
- package/dist/core/compile/fzp.js.map +1 -0
- package/dist/core/compile/icon.d.ts +17 -0
- package/dist/core/compile/icon.js +27 -0
- package/dist/core/compile/icon.js.map +1 -0
- package/dist/core/compile/index.d.ts +4 -0
- package/dist/core/compile/index.js +62 -0
- package/dist/core/compile/index.js.map +1 -0
- package/dist/core/compile/pcb.d.ts +39 -0
- package/dist/core/compile/pcb.js +164 -0
- package/dist/core/compile/pcb.js.map +1 -0
- package/dist/core/compile/schematic.d.ts +69 -0
- package/dist/core/compile/schematic.js +240 -0
- package/dist/core/compile/schematic.js.map +1 -0
- package/dist/core/compile/style.d.ts +52 -0
- package/dist/core/compile/style.js +72 -0
- package/dist/core/compile/style.js.map +1 -0
- package/dist/core/compile/types.d.ts +50 -0
- package/dist/core/compile/types.js +15 -0
- package/dist/core/compile/types.js.map +1 -0
- package/dist/core/export/bin.d.ts +61 -0
- package/dist/core/export/bin.js +221 -0
- package/dist/core/export/bin.js.map +1 -0
- package/dist/core/export/fzpz.d.ts +37 -0
- package/dist/core/export/fzpz.js +121 -0
- package/dist/core/export/fzpz.js.map +1 -0
- package/dist/core/export/index.d.ts +5 -0
- package/dist/core/export/index.js +6 -0
- package/dist/core/export/index.js.map +1 -0
- package/dist/core/export/install.d.ts +77 -0
- package/dist/core/export/install.js +183 -0
- package/dist/core/export/install.js.map +1 -0
- package/dist/core/export/prune.d.ts +72 -0
- package/dist/core/export/prune.js +165 -0
- package/dist/core/export/prune.js.map +1 -0
- package/dist/core/fritzing.d.ts +22 -0
- package/dist/core/fritzing.js +77 -0
- package/dist/core/fritzing.js.map +1 -0
- package/dist/core/identity.d.ts +29 -0
- package/dist/core/identity.js +70 -0
- package/dist/core/identity.js.map +1 -0
- package/dist/core/image/bbox.d.ts +27 -0
- package/dist/core/image/bbox.js +24 -0
- package/dist/core/image/bbox.js.map +1 -0
- package/dist/core/image/index.d.ts +8 -0
- package/dist/core/image/index.js +9 -0
- package/dist/core/image/index.js.map +1 -0
- package/dist/core/image/key.d.ts +72 -0
- package/dist/core/image/key.js +317 -0
- package/dist/core/image/key.js.map +1 -0
- package/dist/core/image/prepare.d.ts +31 -0
- package/dist/core/image/prepare.js +98 -0
- package/dist/core/image/prepare.js.map +1 -0
- package/dist/core/image/remover.d.ts +17 -0
- package/dist/core/image/remover.js +51 -0
- package/dist/core/image/remover.js.map +1 -0
- package/dist/core/index.d.ts +16 -0
- package/dist/core/index.js +17 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/kicad/footprint.d.ts +104 -0
- package/dist/core/kicad/footprint.js +317 -0
- package/dist/core/kicad/footprint.js.map +1 -0
- package/dist/core/kicad/index.d.ts +25 -0
- package/dist/core/kicad/index.js +197 -0
- package/dist/core/kicad/index.js.map +1 -0
- package/dist/core/kicad/sexpr.d.ts +35 -0
- package/dist/core/kicad/sexpr.js +163 -0
- package/dist/core/kicad/sexpr.js.map +1 -0
- package/dist/core/resolve.d.ts +113 -0
- package/dist/core/resolve.js +301 -0
- package/dist/core/resolve.js.map +1 -0
- package/dist/core/schema/part.d.ts +995 -0
- package/dist/core/schema/part.js +278 -0
- package/dist/core/schema/part.js.map +1 -0
- package/dist/core/schema/part.schema.json +1122 -0
- package/dist/core/svg.d.ts +20 -0
- package/dist/core/svg.js +56 -0
- package/dist/core/svg.js.map +1 -0
- package/dist/core/units.d.ts +28 -0
- package/dist/core/units.js +42 -0
- package/dist/core/units.js.map +1 -0
- package/dist/core/validate/checker.d.ts +46 -0
- package/dist/core/validate/checker.js +142 -0
- package/dist/core/validate/checker.js.map +1 -0
- package/dist/core/validate/doctor.d.ts +25 -0
- package/dist/core/validate/doctor.js +156 -0
- package/dist/core/validate/doctor.js.map +1 -0
- package/dist/core/validate/explain.d.ts +10 -0
- package/dist/core/validate/explain.js +135 -0
- package/dist/core/validate/explain.js.map +1 -0
- package/dist/core/validate/index.d.ts +21 -0
- package/dist/core/validate/index.js +96 -0
- package/dist/core/validate/index.js.map +1 -0
- package/dist/core/validate/structural.d.ts +74 -0
- package/dist/core/validate/structural.js +664 -0
- package/dist/core/validate/structural.js.map +1 -0
- package/dist/core/workspace.d.ts +69 -0
- package/dist/core/workspace.js +213 -0
- package/dist/core/workspace.js.map +1 -0
- package/dist/mcp/jsonpatch.d.ts +30 -0
- package/dist/mcp/jsonpatch.js +145 -0
- package/dist/mcp/jsonpatch.js.map +1 -0
- package/dist/mcp/main.d.ts +2 -0
- package/dist/mcp/main.js +5 -0
- package/dist/mcp/main.js.map +1 -0
- package/dist/mcp/server.d.ts +28 -0
- package/dist/mcp/server.js +310 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/server/api.d.ts +72 -0
- package/dist/server/api.js +507 -0
- package/dist/server/api.js.map +1 -0
- package/dist/server/events.d.ts +28 -0
- package/dist/server/events.js +134 -0
- package/dist/server/events.js.map +1 -0
- package/dist/server/http.d.ts +36 -0
- package/dist/server/http.js +127 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/index.d.ts +65 -0
- package/dist/server/index.js +193 -0
- package/dist/server/index.js.map +1 -0
- package/dist/ui/assets/index-DLU8opyI.js +63 -0
- package/dist/ui/assets/index-GhUA-T3b.css +1 -0
- package/dist/ui/index.html +14 -0
- package/package.json +89 -4
- package/skills/fritzkit/SKILL.md +690 -0
- package/skills/fritzkit/reference/examples.md +275 -0
- package/skills/fritzkit/reference/part-json.md +333 -0
- package/skills/fritzkit/scripts/measure.py +197 -0
- package/tools/fzp-checker/.python-version +1 -0
- package/tools/fzp-checker/README.md +45 -0
- package/tools/fzp-checker/check_fzp.py +48 -0
- package/tools/fzp-checker/pyproject.toml +26 -0
- package/tools/fzp-checker/uv.lock +266 -0
- package/tools/fzp-checker/vendor/LICENSE.txt +8 -0
- package/tools/fzp-checker/vendor/UPSTREAM.md +25 -0
- package/tools/fzp-checker/vendor/fzp_checker.py +14 -0
- package/tools/fzp-checker/vendor/scripts/checks/__init__.py +26 -0
- package/tools/fzp-checker/vendor/scripts/checks/check_missing_leg_ids.py +44 -0
- package/tools/fzp-checker/vendor/scripts/checks/checkascii.py +27 -0
- package/tools/fzp-checker/vendor/scripts/checks/checkcase.py +156 -0
- package/tools/fzp-checker/vendor/scripts/checks/checkcopies.py +104 -0
- package/tools/fzp-checker/vendor/scripts/checks/connector_numbering.py +79 -0
- package/tools/fzp-checker/vendor/scripts/checks/connectors_misnumbered.py +228 -0
- package/tools/fzp-checker/vendor/scripts/checks/explain_errors.md +95 -0
- package/tools/fzp-checker/vendor/scripts/checks/fzp_checker_runner.py +717 -0
- package/tools/fzp-checker/vendor/scripts/checks/fzp_checkers.py +1069 -0
- package/tools/fzp-checker/vendor/scripts/checks/fzp_svg_checkers.py +62 -0
- package/tools/fzp-checker/vendor/scripts/checks/fzp_utils.py +222 -0
- package/tools/fzp-checker/vendor/scripts/checks/inspector_fc51.png +0 -0
- package/tools/fzp-checker/vendor/scripts/checks/invisibleconnectors.py +118 -0
- package/tools/fzp-checker/vendor/scripts/checks/nolayeridcheck.txt +758 -0
- package/tools/fzp-checker/vendor/scripts/checks/requirements.txt +3 -0
- package/tools/fzp-checker/vendor/scripts/checks/svg_checkers.py +953 -0
- package/tools/fzp-checker/vendor/scripts/checks/svg_utils.py +96 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_checkers.py +839 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/author_missing.fzp.test +3 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/author_present.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/buses_missing_id.fzp.test +8 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/buses_missing_node_members.fzp.test +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/buses_present_valid.fzp.test +8 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_layers_missing_attributes.fzp.test +16 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_layers_present_valid.fzp.test +14 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_numbering_invalid.fzp.test +70 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_numbering_valid.fzp.test +70 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/connector_refs_valid.fzp.test +53 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_mixed.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_silkscreen_nested.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_style_attr.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_white_stroke.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_invalid_wrong_color.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_inherited.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_legacy.fzp.test +12 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_nested_copper.fzp.test +12 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_none.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_standard.fzp.test +12 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/copper_color_valid_uppercase.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/css_connector.fzp.test +100 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/description_missing.fzp.test +3 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/description_present.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/duplicate_ids.fzp.test +27 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/family_property_missing.fzp.test +6 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/family_property_present_valid.fzp.test +6 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/font_size.fzp.test +46 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/fritzing_version_invalid_format.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/fritzing_version_missing.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/fritzing_version_present_valid.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/gorn_absent.fzp.test +15 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/gorn_present.fzp.test +15 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/hybrid_connectors.fzp.test +232 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/invalid_xml.fzp.test +12 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/layer_ids_match.fzp.test +29 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/layer_ids_mismatch.fzp.test +30 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/layer_nesting_invalid.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/layer_nesting_valid.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/matrix_transform.fzp.test +8 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/missing_connector_refs.fzp.test +63 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/missing_leg_ids.fzp.test +34 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_missing.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_non_alnum.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_present.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_special_chars_absent.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_special_chars_present.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/module_id_too_short.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/no_layer_invalid.fzp.test +19 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/no_layer_namedview.fzp.test +19 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/no_layer_valid.fzp.test +19 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/pcb_only.fzp.test +48 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/property_fields_missing_name.fzp.test +6 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/property_fields_missing_value.fzp.test +6 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/property_fields_present.fzp.test +6 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/required_tags_missing.fzp.test +3 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/required_tags_present.fzp.test +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/stroke_test.fzp.test +60 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/template_svgs.fzp.test +35 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/title_missing.fzp.test +3 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/title_present.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/unique_ids.fzp.test +27 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/unique_property_names_duplicates.fzp.test +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/unique_property_names_unique.fzp.test +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/valid_xml.fzp.test +249 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/version_invalid_format.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/version_missing.fzp.test +3 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/version_present_valid.fzp.test +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/views_missing.fzp.test +3 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/core/views_present.fzp.test +8 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/connector_refs_valid_breadboard.svg +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/duplicate_ids_breadboard.svg +13 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/gorn_absent_breadboard.svg +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/gorn_present_breadboard.svg +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/hybrid_connectors_breadboard.svg +102 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/layer_nesting_invalid.svg +13 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/layer_nesting_valid.svg +13 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/matrix_transform.svg +11 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/missing_connector_refs_breadboard.svg +8 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/missing_leg_ids_breadboard.svg +9 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/test_layer_ids_match_breadboard.svg +9 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/test_layer_ids_mismatch_breadboard.svg +9 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/breadboard/unique_ids_breadboard.svg +13 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/hybrid_connectors_icon.svg +78 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/no_layer_invalid.svg +4 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/no_layer_namedview.svg +9 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/no_layer_valid.svg +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/icon/plain_pcb.svg +10 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/connector_refs_valid_pcb.svg +10 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_mixed.svg +8 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_silkscreen_nested.svg +10 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_style_attr.svg +6 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_white_stroke.svg +6 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_invalid_wrong_color.svg +6 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_inherited.svg +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_legacy.svg +10 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_nested_copper.svg +9 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_none.svg +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_standard.svg +10 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/copper_color_valid_uppercase.svg +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/css_connector.svg +25 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/font_size.svg +54 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/hybrid_connectors_pcb.svg +35 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/missing_connector_refs_pcb.svg +14 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/pcb-arduino-shield.svg +25 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/stroke_test.svg +12 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/test_layer_ids_match_pcb.svg +12 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/pcb/test_layer_ids_mismatch_pcb.svg +12 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/connector_refs_valid_schematic.svg +7 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/hybrid_connectors_schematic.svg +59 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/missing_connector_refs_schematic.svg +8 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/test_layer_ids_match_schematic.svg +6 -0
- package/tools/fzp-checker/vendor/scripts/checks/test_data/svg/core/schematic/test_layer_ids_mismatch_schematic.svg +6 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# fritzkit worked examples
|
|
2
|
+
|
|
3
|
+
Each example is a complete, valid `part.json` that compiles to a checker-clean `.fzpz`.
|
|
4
|
+
Field reference: [part-json.md](part-json.md). The XIAO ESP32-C6 example (headers, castellated
|
|
5
|
+
pads, a bus; a portrait board, USB at the top) is in [../SKILL.md](../SKILL.md); the second worked example, a pads-only board
|
|
6
|
+
measured from a listing photo, is "Pads-only board measured from a photo" below.
|
|
7
|
+
|
|
8
|
+
## Brushless ESC with wire leads
|
|
9
|
+
|
|
10
|
+
A board with no pins at all, only flying wires: battery leads on one side, three motor
|
|
11
|
+
phases on the other, a thin servo cable underneath. Each wire is a `leads` entry; the
|
|
12
|
+
connector is the free end, which plugs into a breadboard. The two ground wires (thick
|
|
13
|
+
battery minus and the servo cable's ground) are the same net, so they are one bus. The
|
|
14
|
+
motor phases are NOT bused: they are three separate outputs.
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"slug": "esc-30a-example",
|
|
19
|
+
"title": "30A brushless ESC (wire leads)",
|
|
20
|
+
"description": "Top view. Battery leads leave the left edge, motor phases the right edge, servo cable the bottom edge.",
|
|
21
|
+
"label": "A",
|
|
22
|
+
"outline": { "widthMm": 45, "heightMm": 24, "shape": "rounded", "cornerRadiusMm": 2 },
|
|
23
|
+
"artwork": {
|
|
24
|
+
"boardColor": "#1F4FA0",
|
|
25
|
+
"silkscreen": [{ "kind": "text", "text": "30A ESC", "xMm": 22.5, "yMm": 12, "sizeMm": 2.5 }]
|
|
26
|
+
},
|
|
27
|
+
"leads": [
|
|
28
|
+
{
|
|
29
|
+
"key": "vbat",
|
|
30
|
+
"name": "VBAT",
|
|
31
|
+
"role": "power",
|
|
32
|
+
"color": "#D02020",
|
|
33
|
+
"gaugeMm": 2.2,
|
|
34
|
+
"fromXMm": 0,
|
|
35
|
+
"fromYMm": 6,
|
|
36
|
+
"direction": "left",
|
|
37
|
+
"lengthMm": 40
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"key": "gnd",
|
|
41
|
+
"name": "GND",
|
|
42
|
+
"role": "gnd",
|
|
43
|
+
"color": "#000000",
|
|
44
|
+
"gaugeMm": 2.2,
|
|
45
|
+
"fromXMm": 0,
|
|
46
|
+
"fromYMm": 18,
|
|
47
|
+
"direction": "left",
|
|
48
|
+
"lengthMm": 40
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"key": "ma",
|
|
52
|
+
"name": "A",
|
|
53
|
+
"role": "other",
|
|
54
|
+
"color": "#202020",
|
|
55
|
+
"fromXMm": 45,
|
|
56
|
+
"fromYMm": 5,
|
|
57
|
+
"direction": "right",
|
|
58
|
+
"lengthMm": 30,
|
|
59
|
+
"description": "motor phase A"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"key": "mb",
|
|
63
|
+
"name": "B",
|
|
64
|
+
"role": "other",
|
|
65
|
+
"color": "#202020",
|
|
66
|
+
"fromXMm": 45,
|
|
67
|
+
"fromYMm": 12,
|
|
68
|
+
"direction": "right",
|
|
69
|
+
"lengthMm": 30,
|
|
70
|
+
"description": "motor phase B"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"key": "mc",
|
|
74
|
+
"name": "C",
|
|
75
|
+
"role": "other",
|
|
76
|
+
"color": "#202020",
|
|
77
|
+
"fromXMm": 45,
|
|
78
|
+
"fromYMm": 19,
|
|
79
|
+
"direction": "right",
|
|
80
|
+
"lengthMm": 30,
|
|
81
|
+
"description": "motor phase C"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"key": "sig",
|
|
85
|
+
"name": "SIG",
|
|
86
|
+
"role": "pwm",
|
|
87
|
+
"color": "#F0F0F0",
|
|
88
|
+
"gaugeMm": 0.8,
|
|
89
|
+
"fromXMm": 10,
|
|
90
|
+
"fromYMm": 24,
|
|
91
|
+
"direction": "down",
|
|
92
|
+
"lengthMm": 30,
|
|
93
|
+
"description": "servo PWM input"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"key": "sgnd",
|
|
97
|
+
"name": "SIG GND",
|
|
98
|
+
"label": "-",
|
|
99
|
+
"role": "gnd",
|
|
100
|
+
"color": "#5A3A1A",
|
|
101
|
+
"gaugeMm": 0.8,
|
|
102
|
+
"fromXMm": 12,
|
|
103
|
+
"fromYMm": 24,
|
|
104
|
+
"direction": "down",
|
|
105
|
+
"lengthMm": 30
|
|
106
|
+
}
|
|
107
|
+
],
|
|
108
|
+
"buses": [{ "id": "GND", "pins": ["gnd", "sgnd"] }]
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Notes: if the ESC's servo cable also has a BEC `+5V` wire, add it as a third thin lead with
|
|
113
|
+
`role: "power"`; do not bus it with VBAT (a regulator sits between them).
|
|
114
|
+
|
|
115
|
+
## 1-channel 5 V relay module
|
|
116
|
+
|
|
117
|
+
A 3-pin 0.1 in input header on the left (a `headers` entry, vertical column) and a 3-way
|
|
118
|
+
screw terminal on the right (three `pins` with big holes, `type: "female"`, because the
|
|
119
|
+
terminal pitch is 5 mm and the terminal accepts wires). Mounting holes go in
|
|
120
|
+
`outline.holes`.
|
|
121
|
+
|
|
122
|
+
```json
|
|
123
|
+
{
|
|
124
|
+
"slug": "relay-1ch-5v-example",
|
|
125
|
+
"title": "1-channel 5V relay module",
|
|
126
|
+
"description": "Top view. Input header on the left edge, screw terminal on the right edge.",
|
|
127
|
+
"label": "K",
|
|
128
|
+
"outline": {
|
|
129
|
+
"widthMm": 50,
|
|
130
|
+
"heightMm": 26,
|
|
131
|
+
"shape": "rect",
|
|
132
|
+
"holes": [
|
|
133
|
+
{ "xMm": 3, "yMm": 3, "dMm": 3 },
|
|
134
|
+
{ "xMm": 47, "yMm": 3, "dMm": 3 }
|
|
135
|
+
]
|
|
136
|
+
},
|
|
137
|
+
"artwork": {
|
|
138
|
+
"boardColor": "#1B4F9C",
|
|
139
|
+
"components": [
|
|
140
|
+
{
|
|
141
|
+
"kind": "rect",
|
|
142
|
+
"xMm": 16,
|
|
143
|
+
"yMm": 5,
|
|
144
|
+
"wMm": 19,
|
|
145
|
+
"hMm": 15.5,
|
|
146
|
+
"color": "#2060D0",
|
|
147
|
+
"note": "relay can"
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
},
|
|
151
|
+
"headers": [
|
|
152
|
+
{
|
|
153
|
+
"key": "in",
|
|
154
|
+
"kind": "male",
|
|
155
|
+
"cols": 3,
|
|
156
|
+
"orientation": "vertical",
|
|
157
|
+
"xMm": 2.5,
|
|
158
|
+
"yMm": 10.46,
|
|
159
|
+
"pins": [
|
|
160
|
+
{ "key": "vcc", "name": "VCC", "role": "power" },
|
|
161
|
+
{ "key": "gnd", "name": "GND", "role": "gnd" },
|
|
162
|
+
{ "key": "in1", "name": "IN", "role": "io", "description": "relay driver input" }
|
|
163
|
+
]
|
|
164
|
+
}
|
|
165
|
+
],
|
|
166
|
+
"pins": [
|
|
167
|
+
{
|
|
168
|
+
"key": "no",
|
|
169
|
+
"name": "NO",
|
|
170
|
+
"type": "female",
|
|
171
|
+
"role": "other",
|
|
172
|
+
"xMm": 46,
|
|
173
|
+
"yMm": 8,
|
|
174
|
+
"pad": { "shape": "round", "wMm": 3, "hMm": 3, "holeMm": 1.3 },
|
|
175
|
+
"description": "screw terminal: normally open"
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"key": "com",
|
|
179
|
+
"name": "COM",
|
|
180
|
+
"type": "female",
|
|
181
|
+
"role": "other",
|
|
182
|
+
"xMm": 46,
|
|
183
|
+
"yMm": 13,
|
|
184
|
+
"pad": { "shape": "round", "wMm": 3, "hMm": 3, "holeMm": 1.3 },
|
|
185
|
+
"description": "screw terminal: common"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"key": "nc",
|
|
189
|
+
"name": "NC",
|
|
190
|
+
"type": "female",
|
|
191
|
+
"role": "other",
|
|
192
|
+
"xMm": 46,
|
|
193
|
+
"yMm": 18,
|
|
194
|
+
"pad": { "shape": "round", "wMm": 3, "hMm": 3, "holeMm": 1.3 },
|
|
195
|
+
"description": "screw terminal: normally closed"
|
|
196
|
+
}
|
|
197
|
+
]
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Notes: NO, COM and NC are three different nets; no bus. Modules with an extra `JD-VCC`
|
|
202
|
+
jumper header get those pins as a second header; bus `VCC` with `JD-VCC` only if the jumper
|
|
203
|
+
is a fixed trace, not a removable jumper.
|
|
204
|
+
|
|
205
|
+
## Pads-only board measured from a photo (HW-391 2S 20A balance board)
|
|
206
|
+
|
|
207
|
+
The full spec is [examples/hw391-2s-20a-bms/part.json](../../../examples/hw391-2s-20a-bms/part.json)
|
|
208
|
+
(see its [README](../../../examples/hw391-2s-20a-bms/README.md) for the measured-vs-golden
|
|
209
|
+
table). It was built by a fresh agent from an Amazon listing using only this skill and the
|
|
210
|
+
CLI. What it shows:
|
|
211
|
+
|
|
212
|
+
- No headers, no leads: five through-hole solder pads, each a `pins` entry with
|
|
213
|
+
`type: "female"` and a measured `pad` (`rect`, `wMm`, `hMm`, `holeMm`). Outline 48 x 20 mm
|
|
214
|
+
from the listing's dimension callout; pad centres from the orthographic top photo at a
|
|
215
|
+
known px/mm (the `measure.py` `bbox` and `grid` helpers), good to about 0.3 mm.
|
|
216
|
+
- Conventional names for symbol-only silkscreen: the charger/load pads are printed as a plus
|
|
217
|
+
or minus inside a circle, so `name` is `P+` / `P-` and the `description` says what is
|
|
218
|
+
printed. The cell pads keep their printed text (`0V`, `4.2V`, `8.4V`).
|
|
219
|
+
- An INFERRED bus: `8.4V` and `P+` look like one copper pour on the back photo, so
|
|
220
|
+
`"buses": [{ "id": "BPLUS", "pins": ["bplus", "pplus"] }]`. `0V` and `P-` are NOT bused (the
|
|
221
|
+
MOSFETs sit between them). Inferred nets belong in the report as "check with a meter".
|
|
222
|
+
- Position and size, abridged (all in mm, origin top-left, x right, y down):
|
|
223
|
+
|
|
224
|
+
```json
|
|
225
|
+
{
|
|
226
|
+
"outline": { "widthMm": 48, "heightMm": 20, "shape": "rect" },
|
|
227
|
+
"pins": [
|
|
228
|
+
{
|
|
229
|
+
"key": "pplus",
|
|
230
|
+
"name": "P+",
|
|
231
|
+
"description": "Charge/discharge plus (silkscreen: plus in a circle); same copper as 8.4V",
|
|
232
|
+
"role": "power",
|
|
233
|
+
"type": "female",
|
|
234
|
+
"xMm": 7.55,
|
|
235
|
+
"yMm": 12.6,
|
|
236
|
+
"pad": { "shape": "rect", "wMm": 4.3, "hMm": 3.1, "holeMm": 1.9 }
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
"key": "bplus",
|
|
240
|
+
"name": "8.4V",
|
|
241
|
+
"role": "power",
|
|
242
|
+
"type": "female",
|
|
243
|
+
"xMm": 45.85,
|
|
244
|
+
"yMm": 17.4,
|
|
245
|
+
"pad": { "shape": "rect", "wMm": 4.3, "hMm": 3.1, "holeMm": 1.6 }
|
|
246
|
+
}
|
|
247
|
+
],
|
|
248
|
+
"buses": [{ "id": "BPLUS", "pins": ["bplus", "pplus"] }]
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Lessons: verify the silkscreen model in the photo matches the listing title before
|
|
253
|
+
measuring; use a dimension callout for the outline and the photo only for pad positions;
|
|
254
|
+
the rectangular pads render as solid copper in the PCB preview, the drill is in the SVG
|
|
255
|
+
ring (see "Reading the PCB preview" in [../SKILL.md](../SKILL.md)).
|
|
256
|
+
|
|
257
|
+
## Starting from a KiCad footprint
|
|
258
|
+
|
|
259
|
+
When a `.kicad_mod` exists (manufacturer download, SnapEDA, KiCad library):
|
|
260
|
+
|
|
261
|
+
```
|
|
262
|
+
fritzkit import-kicad path/to/Module.kicad_mod --slug my-module
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
This writes a part with exact pad positions and sizes (through-hole pads -> `type: "female"`
|
|
266
|
+
with `holeMm`; SMD pads -> `type: "pad"`, `smd: true`; non-plated holes -> `outline.holes`;
|
|
267
|
+
pads that share a KiCad number -> tied by a bus). The outline comes from the board edge,
|
|
268
|
+
courtyard, fab layer or the pad bounding box, in that order. Pads on a 2.54 mm grid stay as
|
|
269
|
+
individual pins (exact geometry), they are not converted to headers.
|
|
270
|
+
|
|
271
|
+
What you still do: replace the KiCad pad numbers in `name` with the real signal names from
|
|
272
|
+
the datasheet, set every `role`, add buses for pads that share a net but have different
|
|
273
|
+
KiCad numbers, set `title`, `description`, `sources` and artwork, then validate and render
|
|
274
|
+
as usual. Check the orientation: KiCad footprints are drawn from the top, y down, the same
|
|
275
|
+
frame as fritzkit.
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
<!-- Copy of docs/part-json.md, shipped with the skill so it works when the skill folder is
|
|
2
|
+
copied on its own. Edit docs/part-json.md and copy it here; keep the two identical
|
|
3
|
+
except the relative links in "Worked examples". -->
|
|
4
|
+
|
|
5
|
+
# part.json reference
|
|
6
|
+
|
|
7
|
+
Every fritzkit part is one folder: `part.json` plus an optional `assets/` folder. This page
|
|
8
|
+
documents every field of `part.json`. The source of truth is the zod schema in
|
|
9
|
+
`src/core/schema/part.ts`; the published JSON Schema (`fritzkit schema`, or
|
|
10
|
+
`src/core/schema/part.schema.json`) is generated from it. If this page and the schema ever
|
|
11
|
+
disagree, the schema wins.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
<workspace>/<slug>/part.json the spec (you write this)
|
|
15
|
+
<workspace>/<slug>/assets/... photos, datasheet crops (artwork.photo.src points here)
|
|
16
|
+
<workspace>/<slug>/build/... render output (never read back)
|
|
17
|
+
<workspace>/<slug>/<moduleId>.fzpz export output (never read back)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The workspace defaults to `~/fritzkit/parts`; override it with `--workspace <dir>` or the
|
|
21
|
+
`FRITZKIT_WORKSPACE` environment variable. Only `part.json` and `assets/` feed the
|
|
22
|
+
compiler.
|
|
23
|
+
|
|
24
|
+
## Units and the coordinate frame
|
|
25
|
+
|
|
26
|
+
- **Every length is in millimetres** (fields end in `Mm`). fritzkit converts to mils when it
|
|
27
|
+
writes SVG; you never deal with inches, mils or pixels in the spec.
|
|
28
|
+
- **Origin = the top-left corner of the outline.** x grows to the RIGHT along `widthMm`,
|
|
29
|
+
y grows DOWN along `heightMm`. This is the orientation of a top-down photo of the board on
|
|
30
|
+
screen, so a pixel in an orthographic photo maps straight to mm:
|
|
31
|
+
`xMm = (px - boardLeftPx) / pxPerMm`, `yMm = (py - boardTopPx) / pxPerMm`.
|
|
32
|
+
- **Positions are centres.** A pin's `xMm`/`yMm` is the centre of its pad; a header's
|
|
33
|
+
`xMm`/`yMm` is the centre of its FIRST pin; a hole's `xMm`/`yMm` is its centre. Only
|
|
34
|
+
`rect` silk items use their top-left corner.
|
|
35
|
+
- **Pad sizes are in the part frame and never rotated:** `pad.wMm` is the extent along x,
|
|
36
|
+
`pad.hMm` the extent along y, whatever the header orientation.
|
|
37
|
+
- Pins, leads and overhanging parts may lie OUTSIDE the outline (negative coordinates or
|
|
38
|
+
beyond the outline size). The compiler grows the drawing canvas to fit them.
|
|
39
|
+
- If the part has headers, the compiler shifts the whole drawing so the first header pin
|
|
40
|
+
lands exactly on Fritzing's 0.1 in (100 mil) grid; that is what makes the part seat in a
|
|
41
|
+
breadboard. You do nothing for this; just keep header pins at their true pitch.
|
|
42
|
+
- The drawing shows the TOP (component) side. A pad that exists only on the back is placed
|
|
43
|
+
where it would be seen through the board from the top (same x/y as from the top).
|
|
44
|
+
|
|
45
|
+
## Top level
|
|
46
|
+
|
|
47
|
+
| field | type | default | notes |
|
|
48
|
+
| ------------- | ------------------------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
49
|
+
| `$schema` | string | - | optional; `fritzkit new` writes the published schema URL so editors validate as you type |
|
|
50
|
+
| `slug` | string, 3-60 chars | **required** | lowercase letters, digits and `-`, starting and ending with a letter or digit (`xiao-esp32-c6`). Names the folder and the moduleId |
|
|
51
|
+
| `title` | string, 1-120 | **required** | shown in Fritzing's Inspector and parts bin |
|
|
52
|
+
| `version` | integer >= 1 | `1` | bump by hand when the part changes materially; shown in the variant as `v<version> <hash8>` |
|
|
53
|
+
| `family` | string, 1-60 | the slug | Fritzing swap group: parts in one family can be swapped in the Inspector. Leave unset unless several slugs should swap with each other |
|
|
54
|
+
| `label` | string, 1-4 | `"A"` | reference designator prefix: `A` module/board, `U` IC or MCU board, `J` connector, `K` relay, `M` motor |
|
|
55
|
+
| `author` | string, max 80 | `"fritzkit"` | |
|
|
56
|
+
| `tags` | string[] (each 1-30) | `[]` | search keywords for Fritzing's parts search |
|
|
57
|
+
| `description` | string, max 4000 | `""` | plain text; say what the part is and which side and orientation the drawing shows |
|
|
58
|
+
| `sources` | URL[] | `[]` | listing, wiki and datasheet URLs (must be valid URLs); appended to the description in Fritzing |
|
|
59
|
+
| `properties` | object string -> string | `{}` | extra Inspector properties (`mpn`, `type`, `voltage`, `chip` ...). Keys and values must be non-empty. `family`/`variant` are automatic |
|
|
60
|
+
| `outline` | [Outline](#outline) | **required** | board size and shape |
|
|
61
|
+
| `artwork` | [Artwork](#artwork) | `{}` (vector) | how the breadboard view looks |
|
|
62
|
+
| `pins` | [Pin](#pin)[] | `[]` | free-standing pads or pins at arbitrary positions |
|
|
63
|
+
| `headers` | [Header](#header)[] | `[]` | rows/grids of pins at a fixed pitch (0.1 in headers, castellated edges) |
|
|
64
|
+
| `leads` | [Lead](#lead)[] | `[]` | flying wire leads with a connector at the free end |
|
|
65
|
+
| `pinIds` | object key -> integer >= 0 | `{}` | **managed by fritzkit; never edit by hand.** See [pinIds](#pinids) |
|
|
66
|
+
| `buses` | [Bus](#bus)[] | `[]` | connectors that are the same electrical node (e.g. several GND pads) |
|
|
67
|
+
| `spice` | [Spice](#spice) | - | optional simulator model |
|
|
68
|
+
| `schematic` | [schematic options](#schematic) | `{}` | schematic symbol layout |
|
|
69
|
+
| `pcb` | [pcb options](#pcb) | `{}` | PCB footprint options |
|
|
70
|
+
|
|
71
|
+
Unknown keys are rejected everywhere (every object is strict), so a typo such as
|
|
72
|
+
`"widthmm"` is an error instead of being silently ignored.
|
|
73
|
+
|
|
74
|
+
## Fields shared by pins, header pins and leads
|
|
75
|
+
|
|
76
|
+
| field | type | default | notes |
|
|
77
|
+
| ------------- | --------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
78
|
+
| `key` | string | **required** | stable identifier, unique across the whole part. Letters, digits, `_ . + -`; must not start with `.`, `+` or `-`. Never rename |
|
|
79
|
+
| `name` | string, 1-40 | **required** | the connector name Fritzing shows on hover and in the Inspector. Use the silkscreen text (`GND`, `D7`, `NO`), never `pin1` |
|
|
80
|
+
| `label` | string, max 16 | the name | text drawn next to the pin (breadboard and schematic); `""` hides the breadboard label; the fzp connector name is always `name` |
|
|
81
|
+
| `description` | string, max 400 | the name | function, voltage, alternate functions (`D4 / SDA`) |
|
|
82
|
+
| `role` | enum | `"io"` | `power`, `gnd`, `io`, `analog`, `pwm`, `i2c`, `spi`, `uart`, `usb`, `clock`, `reset`, `enable`, `nc`, `other` |
|
|
83
|
+
|
|
84
|
+
`role` decides where the pin goes on the schematic symbol (see [schematic](#schematic)) and
|
|
85
|
+
its label colour. Use `power` for every supply pin (VCC, 5V, 3V3, VBAT, VIN), `gnd` for every
|
|
86
|
+
ground, `nc` for pins that are not connected, `other` for things like relay contacts and
|
|
87
|
+
motor phases.
|
|
88
|
+
|
|
89
|
+
Symbol-only or non-Latin silkscreen (a plus in a circle, Chinese text): `name` is the
|
|
90
|
+
conventional ASCII function name (`P+`, `P-`, `VCC`); the printed symbol or the translation
|
|
91
|
+
goes in `description`. Names and labels are ASCII only.
|
|
92
|
+
|
|
93
|
+
## Pin
|
|
94
|
+
|
|
95
|
+
A pad or pin at an arbitrary position: solder pads, screw terminals, odd pin spacings, test
|
|
96
|
+
pads, anything not on a regular grid.
|
|
97
|
+
|
|
98
|
+
| field | type | default | notes |
|
|
99
|
+
| ----------------------------------- | ---------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------- |
|
|
100
|
+
| key, name, label, description, role | see above | | |
|
|
101
|
+
| `type` | `female` / `male` / `pad` / `wire` | `"female"` | see below |
|
|
102
|
+
| `xMm` | number | **required** | pad centre, part frame |
|
|
103
|
+
| `yMm` | number | **required** | pad centre, part frame |
|
|
104
|
+
| `pad` | [PadGeometry](#padgeometry) | `{ "shape": "rect", "wMm": 2, "hMm": 2, "holeMm": 1 }` | copper size and drill |
|
|
105
|
+
| `snap` | boolean | - | UI hint only: snap to the 0.1 in grid when dragged in `fritzkit ui` |
|
|
106
|
+
|
|
107
|
+
Connector `type` (what Fritzing lets attach to it):
|
|
108
|
+
|
|
109
|
+
- `female` - a wire or a male pin attaches to it: through-hole solder pads, female header
|
|
110
|
+
sockets, screw terminals. The default, and the right choice for most pads with a hole.
|
|
111
|
+
- `male` - it plugs into a breadboard or socket: header pins.
|
|
112
|
+
- `pad` - a surface pad with no hole: SMD pads, castellated edges, test pads.
|
|
113
|
+
- `wire` - reserved by Fritzing for its own wires; do not use it (leads are emitted as
|
|
114
|
+
`male` automatically).
|
|
115
|
+
|
|
116
|
+
## PadGeometry
|
|
117
|
+
|
|
118
|
+
| field | type | default | notes |
|
|
119
|
+
| -------- | ------------------------- | ------------ | --------------------------------------------------------------- |
|
|
120
|
+
| `shape` | `rect` / `round` / `oval` | `"rect"` | copper shape |
|
|
121
|
+
| `wMm` | number > 0 | **required** | copper extent along x |
|
|
122
|
+
| `hMm` | number > 0 | **required** | copper extent along y |
|
|
123
|
+
| `holeMm` | number >= 0 | - | drill diameter; absent or 0 = no hole (SMD, top copper only) |
|
|
124
|
+
| `smd` | boolean | - | force SMD (no drill, top copper only) even when `holeMm` is set |
|
|
125
|
+
|
|
126
|
+
In the PCB view a pad with a hole becomes a through-hole pad on both copper layers. Fritzing
|
|
127
|
+
needs a minimum hole and annular ring, so very small holes are drawn slightly bigger.
|
|
128
|
+
|
|
129
|
+
The PCB SVG draws the pad as a ring: a `<circle fill="none">` whose stroke is the copper, so
|
|
130
|
+
`drill = 2 * (r - stroke-width / 2)` and `copper = 2 * (r + stroke-width / 2)` (mils). Oblong
|
|
131
|
+
and rectangular pads also get a solid copper rect under the ring, so a preview PNG can look
|
|
132
|
+
like a solid block; the drill is still the ring's empty centre.
|
|
133
|
+
|
|
134
|
+
## Header
|
|
135
|
+
|
|
136
|
+
A row or grid of pins at a fixed pitch, drawn in Fritzing's house style.
|
|
137
|
+
|
|
138
|
+
| field | type | default | notes |
|
|
139
|
+
| ------------- | --------------------------------- | -------------- | -------------------------------------------------------------------------------------------------------- |
|
|
140
|
+
| `key` | string | **required** | identifies the header (not a connector) |
|
|
141
|
+
| `kind` | `male` / `female` / `castellated` | `"male"` | male pins, female sockets, or castellated (half-hole) SMD edge pads |
|
|
142
|
+
| `pitchMm` | number > 0 | `2.54` | centre-to-centre spacing, both directions |
|
|
143
|
+
| `rows` | integer 1-8 | `1` | |
|
|
144
|
+
| `cols` | integer 1-64 | **required** | |
|
|
145
|
+
| `xMm`, `yMm` | number | **required** | centre of the FIRST pin (row 0, col 0) |
|
|
146
|
+
| `orientation` | `horizontal` / `vertical` | `"horizontal"` | horizontal: cols run along +x, rows along +y. vertical: cols run along +y (down), rows along +x (right) |
|
|
147
|
+
| `pins` | (HeaderPin or `null`)[] | **required** | exactly `rows * cols` entries, row-major (row 0 col 0, row 0 col 1, ...). `null` leaves a position empty |
|
|
148
|
+
| `pad` | [PadGeometry](#padgeometry) | see below | copper override |
|
|
149
|
+
|
|
150
|
+
A HeaderPin has only `key`, `name`, `label`, `description` and `role`. Its position comes
|
|
151
|
+
from the grid and its connector type from `kind` (male -> `male`, female -> `female`,
|
|
152
|
+
castellated -> `pad`).
|
|
153
|
+
|
|
154
|
+
Default copper: male/female = round 1.6 mm pad with a 1.0 mm hole (through-hole);
|
|
155
|
+
castellated = rect 1.6 x 2.4 mm SMD (`wMm` along x, `hMm` along y). The castellated default
|
|
156
|
+
suits a HORIZONTAL row along the top or bottom edge. For a VERTICAL column along the left or
|
|
157
|
+
right edge set `"pad": { "shape": "rect", "wMm": 2.4, "hMm": 1.6, "smd": true }` so the long
|
|
158
|
+
side points into the board.
|
|
159
|
+
|
|
160
|
+
Examples: a 1x7 row with pin 1 at the left is
|
|
161
|
+
`{ "key": "j1", "cols": 7, "xMm": <x of pin 1>, "yMm": <y>, "pins": [7 entries] }`; a 2x20
|
|
162
|
+
header is `{ "rows": 2, "cols": 20, ... }` with 40 entries (all of row 0, then all of row 1).
|
|
163
|
+
Two rows that are NOT one pitch apart (the two sides of a DIP-style module) are two separate
|
|
164
|
+
headers.
|
|
165
|
+
|
|
166
|
+
## Lead
|
|
167
|
+
|
|
168
|
+
A flying wire (motor phases, battery leads, a servo cable). Drawn as a bendable leg; the
|
|
169
|
+
connector is the free end, which plugs into a breadboard like a male pin.
|
|
170
|
+
|
|
171
|
+
| field | type | default | notes |
|
|
172
|
+
| ----------------------------------- | -------------------------------- | ------------ | ------------------------------------------------------------- |
|
|
173
|
+
| key, name, label, description, role | see above | | |
|
|
174
|
+
| `fromXMm`, `fromYMm` | number | **required** | where the wire leaves the board (usually on the outline edge) |
|
|
175
|
+
| `direction` | `left` / `right` / `up` / `down` | `"left"` | which way the wire runs from that point |
|
|
176
|
+
| `lengthMm` | number > 0 | `40` | drawn length; the free end is `lengthMm` away in `direction` |
|
|
177
|
+
| `color` | `#RRGGBB` | `"#000000"` | insulation colour |
|
|
178
|
+
| `gaugeMm` | number > 0 | `1.6` | wire outer diameter, for drawing |
|
|
179
|
+
|
|
180
|
+
Leads have no `type` or `pad` field. In the PCB view a lead becomes a through-hole pad
|
|
181
|
+
(unless `pcb.mode` is `smd`).
|
|
182
|
+
|
|
183
|
+
## Outline
|
|
184
|
+
|
|
185
|
+
| field | type | default | notes |
|
|
186
|
+
| ---------------- | ----------------------------- | ------------ | ------------------------------------------------------------------------------ |
|
|
187
|
+
| `widthMm` | number > 0 | **required** | extent along x. Convention: put the LONG edge on x |
|
|
188
|
+
| `heightMm` | number > 0 | **required** | extent along y |
|
|
189
|
+
| `shape` | `rect` / `rounded` / `custom` | `"rounded"` | |
|
|
190
|
+
| `cornerRadiusMm` | number >= 0 | `1` | used by `rounded` |
|
|
191
|
+
| `pathMm` | string | - | for `custom`: an SVG path in mm, part frame, e.g. `"M0 0 H30 V10 L25 15 H0 Z"` |
|
|
192
|
+
| `holes` | `{ xMm, yMm, dMm }`[] | `[]` | mounting holes (centre, diameter); drawn in breadboard and PCB, not connectors |
|
|
193
|
+
|
|
194
|
+
## Artwork
|
|
195
|
+
|
|
196
|
+
How the breadboard view is drawn. The schematic, PCB and icon views are always generated
|
|
197
|
+
from the pins and the outline.
|
|
198
|
+
|
|
199
|
+
| field | type | default | notes |
|
|
200
|
+
| ------------ | ----------------------- | ----------- | ------------------------------------------------------------------------------------ |
|
|
201
|
+
| `style` | `vector` / `photo` | `"vector"` | vector = Fritzing house style; photo = embedded raster with vector pads on top |
|
|
202
|
+
| `boardColor` | `#RRGGBB` | `"#1B7F3B"` | PCB colour (green). Black `#1A1A1A`, blue `#1B4F9C`, red `#B0242A`, purple `#5B2A86` |
|
|
203
|
+
| `silkColor` | `#RRGGBB` | `"#FFFFFF"` | silkscreen colour |
|
|
204
|
+
| `silkscreen` | [SilkItem](#silkitem)[] | `[]` | text and lines printed on the board |
|
|
205
|
+
| `components` | [SilkItem](#silkitem)[] | `[]` | large components drawn as shapes (USB socket, relay can, chip, heatsink) |
|
|
206
|
+
| `photo` | [Photo](#photo) | - | required when `style` is `photo` |
|
|
207
|
+
|
|
208
|
+
Draw only the components that help a user recognise the board and find pin 1 (the USB
|
|
209
|
+
connector, a relay can, a big chip). Do not draw every resistor. fritzkit labels every pin
|
|
210
|
+
already, so do not repeat pin names in `silkscreen`. Component shapes are drawn on top of
|
|
211
|
+
silkscreen text (pads are drawn on top of both), so keep text off component shapes or it is
|
|
212
|
+
hidden. Silkscreen and components are drawn under header bodies, pads and pin labels, so
|
|
213
|
+
put text where pads are not.
|
|
214
|
+
|
|
215
|
+
### SilkItem
|
|
216
|
+
|
|
217
|
+
A union on `kind`. All positions in mm, part frame.
|
|
218
|
+
|
|
219
|
+
| kind | fields (default) |
|
|
220
|
+
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
221
|
+
| `text` | `text` (1-80, required), `xMm`, `yMm`, `sizeMm` (`1.2`), `color` (`#FFFFFF`), `anchor` `start`/`middle`/`end` (`middle`), `rotate` degrees (`0`) |
|
|
222
|
+
| `rect` | `xMm`, `yMm` (TOP-LEFT corner), `wMm`, `hMm`, `color` (`#222222`), `rxMm` corner radius (`0`), `note` (not rendered) |
|
|
223
|
+
| `circle` | `xMm`, `yMm` (centre), `dMm` diameter, `color` (`#222222`), `note` |
|
|
224
|
+
| `line` | `x1Mm`, `y1Mm`, `x2Mm`, `y2Mm`, `widthMm` (`0.2`), `color` (`#FFFFFF`) |
|
|
225
|
+
|
|
226
|
+
### Photo
|
|
227
|
+
|
|
228
|
+
| field | type | default | notes |
|
|
229
|
+
| ------------------ | -------------------------- | ------------ | ------------------------------------------------------------------------------- |
|
|
230
|
+
| `src` | string | **required** | path relative to the part folder, e.g. `"assets/top.jpg"` |
|
|
231
|
+
| `crop` | `[x, y, w, h]` (pixels) | - | crop rectangle in source pixels, applied BEFORE rotation |
|
|
232
|
+
| `rotate` | `0` / `90` / `180` / `270` | `0` | clockwise, applied after the crop, so the board ends up in the spec orientation |
|
|
233
|
+
| `removeBackground` | boolean | `true` | key out a near-white listing background and trim to the board |
|
|
234
|
+
| `opacity` | number 0-1 | `1` | |
|
|
235
|
+
|
|
236
|
+
After crop, rotate and trim the image is stretched over the outline rectangle, so the board
|
|
237
|
+
must fill the processed image edge to edge (that is what `removeBackground` trims to; with
|
|
238
|
+
`removeBackground: false`, crop exactly to the board). The image is downscaled to at most
|
|
239
|
+
1600 px wide. Pads are still drawn as vector shapes on top, at the spec positions.
|
|
240
|
+
|
|
241
|
+
## Bus
|
|
242
|
+
|
|
243
|
+
| field | type | notes |
|
|
244
|
+
| ------ | ----------------------- | ----------------------------------------------------- |
|
|
245
|
+
| `id` | string (`A-Za-z0-9_.-`) | unique, e.g. `GND`, `VBAT` |
|
|
246
|
+
| `pins` | pin key[] (>= 2) | keys of pins, header pins or leads that share one net |
|
|
247
|
+
|
|
248
|
+
A bus tells Fritzing that the connectors are one electrical node, so a wire to one GND pad
|
|
249
|
+
counts as connected to every GND pad (ratsnest, routing checks). A connector can be in at
|
|
250
|
+
most one bus. Bus pins that are really the same copper: several `GND` pads, two `VIN` pads
|
|
251
|
+
tied together, a screw terminal paralleled with a solder pad. Pins that merely have similar
|
|
252
|
+
names (two `+` pads on different nets, `IN1` and `IN2`, `VCC` and `5V` with a regulator
|
|
253
|
+
between them) are NOT a bus unless the copper is visibly shared or the datasheet says so.
|
|
254
|
+
|
|
255
|
+
## pinIds
|
|
256
|
+
|
|
257
|
+
`pinIds` maps every pin key to its Fritzing connector number (`connector0`, `connector1`,
|
|
258
|
+
...). fritzkit fills it in: the first `validate`, `render` or `export` after you add a pin
|
|
259
|
+
gives the new key the next free number and writes it back to `part.json`. Numbers are never
|
|
260
|
+
reused, so when you delete a pin its number stays reserved and every other pin keeps its id.
|
|
261
|
+
That is what lets Fritzing swap a placed copy for a newer version without dropping wires.
|
|
262
|
+
|
|
263
|
+
fritzkit manages `pinIds`: do not hand-edit them for a part that has ever been
|
|
264
|
+
exported/installed (connector ids must stay stable). For a brand-new part you may delete
|
|
265
|
+
the `pinIds` object before the first export to close gaps. Never reuse a key for a
|
|
266
|
+
different physical pin;
|
|
267
|
+
rename a pin by changing `name`, not `key`. A new spec may omit `pinIds` or write `{}`. Gaps
|
|
268
|
+
in the numbering after a pin was removed produce a harmless `connector-numbering` warning
|
|
269
|
+
(only a warning).
|
|
270
|
+
|
|
271
|
+
## Spice
|
|
272
|
+
|
|
273
|
+
| field | type | notes |
|
|
274
|
+
| ------- | -------- | ---------------------------------- |
|
|
275
|
+
| `model` | string | optional `.model` / `.subckt` text |
|
|
276
|
+
| `lines` | string[] | at least one netlist line |
|
|
277
|
+
|
|
278
|
+
Tokens: `{instanceTitle}`, `{net connectorN}` (N from `pinIds`, so add spice AFTER the first
|
|
279
|
+
validate), and `{<property>}` for any entry in `properties`. A battery with internal
|
|
280
|
+
resistance, where connector0 is minus and connector1 is plus:
|
|
281
|
+
|
|
282
|
+
```json
|
|
283
|
+
{
|
|
284
|
+
"properties": { "voltage": "3.7V", "internal resistance": "0.05" },
|
|
285
|
+
"spice": {
|
|
286
|
+
"lines": [
|
|
287
|
+
"V{instanceTitle} {net connector1}_{instanceTitle}_aux {net connector0} DC {voltage}",
|
|
288
|
+
"R{instanceTitle} {net connector1}_{instanceTitle}_aux {net connector1} {internal resistance}"
|
|
289
|
+
]
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Parts without `spice` are greyed out in Fritzing's simulator, which is normal for modules
|
|
295
|
+
and MCU boards.
|
|
296
|
+
|
|
297
|
+
## schematic
|
|
298
|
+
|
|
299
|
+
| field | type | default | notes |
|
|
300
|
+
| -------- | ------------------------------------------ | ----------- | ------------------------------------------ |
|
|
301
|
+
| `layout` | `by-role` | `"by-role"` | an auto-sized rectangle on the 0.1 in grid |
|
|
302
|
+
| `sides` | `{ left?, right?, top?, bottom? }`, role[] | - | override which side each role lands on |
|
|
303
|
+
|
|
304
|
+
Behaviour of `by-role`: one box; pins are grouped by role onto sides, in spec order within
|
|
305
|
+
a role; every bused GND pin still gets its own pin. Default sides: power, usb, enable and
|
|
306
|
+
reset on the left, gnd at the bottom, everything else on the right. An empty `label` is
|
|
307
|
+
drawn as an empty pin label (it does not fall back to `name`). An explicit per-pin ordering
|
|
308
|
+
hint is not available yet.
|
|
309
|
+
Example override:
|
|
310
|
+
`"schematic": { "sides": { "left": ["power", "gnd"], "right": ["io", "i2c", "spi", "uart", "analog", "pwm"] } }`.
|
|
311
|
+
|
|
312
|
+
## pcb
|
|
313
|
+
|
|
314
|
+
| field | type | default | notes |
|
|
315
|
+
| ------------------- | ---------------------- | -------- | ------------------------------------------------------------------- |
|
|
316
|
+
| `mode` | `auto` / `tht` / `smd` | `"auto"` | auto: per pad (a hole means through-hole); tht / smd force all pads |
|
|
317
|
+
| `silkscreenOutline` | boolean | `true` | draw the board outline on the PCB silkscreen |
|
|
318
|
+
|
|
319
|
+
## Identity (computed, not in the spec)
|
|
320
|
+
|
|
321
|
+
- `moduleId = fritzkit-<slug>-<hash8>`; `hash8` hashes part.json (minus `$schema`) and every
|
|
322
|
+
file in `assets/`. Any change gives a new moduleId, because Fritzing refuses to import a
|
|
323
|
+
moduleId it already has.
|
|
324
|
+
- `family = family ?? slug` (stable) and `variant = v<version> <hash8>` (unique per export).
|
|
325
|
+
In Fritzing, select a placed part and pick another variant in the Inspector to swap it.
|
|
326
|
+
|
|
327
|
+
## Worked examples
|
|
328
|
+
|
|
329
|
+
Complete, valid specs live in the skill's
|
|
330
|
+
[examples.md](examples.md): the Seeed XIAO ESP32-C6 (headers and a
|
|
331
|
+
bus), an ESC with wire leads, a relay module, a KiCad import, and the pads-only HW-391
|
|
332
|
+
board measured from a listing photo. The full XIAO spec is also in
|
|
333
|
+
[SKILL.md](../SKILL.md) (a portrait board, USB at the top).
|