gitcad-core 0.7.7__py3-none-any.whl

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.
gitcad/seams.py ADDED
@@ -0,0 +1,249 @@
1
+ """The six seams — the only load-bearing interfaces in gitcad.
2
+
3
+ Rule (see ADR-0002): everything swappable lives behind one of these Protocols.
4
+ Agents work *inside* a seam, never across one. A "major architecture change"
5
+ should mean writing a new backend for one seam, not a rewrite. Keeping the seam
6
+ count small and the interfaces narrow is what preserves that property, so adding
7
+ a seam or widening one is a human-sign-off change (see ``CODEOWNERS``).
8
+
9
+ These are :class:`typing.Protocol` classes: backends satisfy them structurally,
10
+ so a backend package need not import gitcad-core to implement one.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from typing import Any, Protocol, runtime_checkable
16
+
17
+ from gitcad.errors import ValidationReport
18
+
19
+ # A Shape is an opaque, backend-owned handle to geometry. Core code never
20
+ # inspects its internals — it only passes it back to the same Kernel. This is
21
+ # what lets OCCT, a mesh kernel, or a future Rust kernel all satisfy `Kernel`.
22
+ Shape = Any
23
+
24
+
25
+ @runtime_checkable
26
+ class Kernel(Protocol):
27
+ """Geometry backend. The one seam that talks b-rep math.
28
+
29
+ Intent-level, not control-point level: callers express *what must be true*
30
+ (through these points, tangent to that face, curvature-continuous) and the
31
+ kernel solves the geometry. See ADR-0002 for why the API is intent-based.
32
+ """
33
+
34
+ name: str
35
+ """Backend identity for fingerprints, e.g. ``"occt-7.8.1"`` or ``"null"``."""
36
+
37
+ def box(self, dx: float, dy: float, dz: float) -> Shape: ...
38
+
39
+ def cylinder(self, radius: float, height: float) -> Shape: ...
40
+
41
+ def sphere(self, radius: float) -> Shape: ...
42
+
43
+ def cone(self, r1: float, r2: float, height: float) -> Shape: ...
44
+
45
+ def boolean(self, op: str, a: Shape, b: Shape) -> Shape:
46
+ """``op`` in {"union", "cut", "intersect"}."""
47
+ ...
48
+
49
+ def extrude(self, profile: dict, height: float) -> Shape:
50
+ """Linear sweep of a closed XY profile (gitcad.sketch form) along +Z."""
51
+ ...
52
+
53
+ def revolve(self, profile: dict, angle_deg: float = 360.0) -> Shape:
54
+ """Revolve a closed XY profile about the Y axis."""
55
+ ...
56
+
57
+ def loft(self, sections: list[tuple[dict, float]], *, ruled: bool = False) -> Shape:
58
+ """Solid through closed XY profiles stacked at their z heights."""
59
+ ...
60
+
61
+ def sweep(self, profile: dict, path: list[tuple[float, float, float]]) -> Shape:
62
+ """Sweep a closed XY profile along a 3D polyline path from (0,0,0)."""
63
+ ...
64
+
65
+ def mirror(self, shape: Shape, plane: str) -> Shape:
66
+ """Mirrored copy across a principal plane ("xy"|"yz"|"zx") at origin."""
67
+ ...
68
+
69
+ def mass_props(self, shape: Shape) -> dict[str, float]:
70
+ """Unit-density volume, center of mass, inertia tensor about the COM."""
71
+ ...
72
+
73
+ def chamfer(self, shape: Shape, edges: list[int] | None, distance: float) -> Shape:
74
+ """Chamfer by edge enumeration index (same contract as fillet)."""
75
+ ...
76
+
77
+ def shell(self, shape: Shape, remove_faces: list[int], thickness: float) -> Shape:
78
+ """Hollow to a wall thickness, removing listed faces as openings."""
79
+ ...
80
+
81
+ def fillet(self, shape: Shape, edges: list[int] | None, radius: float) -> Shape:
82
+ """Fillet by enumeration index into ``entities(shape, "edge")`` order
83
+ (``None`` = all edges). Index resolution from stable entity ids happens
84
+ one level up, in the document build (ADR-0003) — the kernel never sees
85
+ identity, only concrete indices valid for this exact shape."""
86
+ ...
87
+
88
+ def entities(self, shape: Shape, kind: str) -> list[dict[str, Any]]:
89
+ """Enumerate topological entities (``kind`` in {"face","edge","vertex"})
90
+ with a stable, order-independent semantic descriptor each. This is the
91
+ raw material the :class:`IdentityService` turns into durable IDs."""
92
+ ...
93
+
94
+ def transform(self, shape: Shape, *, translate: tuple[float, float, float] = (0, 0, 0),
95
+ rotate_axis: tuple[float, float, float] = (0, 0, 1), rotate_deg: float = 0.0) -> Shape:
96
+ """Rigid placement: rotate about an axis through the origin, then
97
+ translate. The primitive every positioned feature builds on."""
98
+ ...
99
+
100
+ def scale(self, shape: Shape, fx: float, fy: float | None = None,
101
+ fz: float | None = None) -> Shape:
102
+ """Uniform (one factor) or anisotropic (three) scale about the origin."""
103
+ ...
104
+
105
+ def draft(self, shape: Shape, faces: list[int], angle_deg: float,
106
+ pull: tuple[float, float, float] = (0, 0, 1),
107
+ neutral_z: float = 0.0) -> Shape:
108
+ """Molding draft: tilt the listed faces (empty = all faces normal to
109
+ pull) by ``angle_deg`` about the neutral plane z=``neutral_z``."""
110
+ ...
111
+
112
+ def helix(self, radius: float, pitch: float, turns: float,
113
+ ccw: bool = True) -> Shape:
114
+ """A 3D helical wire about +z — the spine of springs and threads."""
115
+ ...
116
+
117
+ def pipe(self, spine: Shape, profile_diameter: float) -> Shape:
118
+ """Sweep a circular section along a wire spine (springs, wire runs)."""
119
+ ...
120
+
121
+ def validate(self, shape: Shape) -> ValidationReport:
122
+ """Machine-readable geometric checks (watertight, self-intersection,
123
+ continuity). The core of the agent verification loop."""
124
+ ...
125
+
126
+ def measure(self, shape: Shape) -> dict[str, float]:
127
+ """Mass properties: volume, area, centroid — deterministic oracle used
128
+ by golden tests and by geometric-diff in PRs."""
129
+ ...
130
+
131
+ def bbox(self, shape: Shape) -> tuple[tuple[float, float, float], tuple[float, float, float]]:
132
+ """Axis-aligned bounding box ((minx,miny,minz),(maxx,maxy,maxz)) —
133
+ the source of a derived part envelope (ADR-0008)."""
134
+ ...
135
+
136
+ def export_step(self, shape: Shape, path: str) -> None:
137
+ """Write ISO 10303-21 STEP — the mechanical interchange deliverable."""
138
+ ...
139
+
140
+ def export_stl(self, shape: Shape, path: str, *, deflection: float = 0.1) -> None:
141
+ """Tessellate and write STL for 3D printing."""
142
+ ...
143
+
144
+ def import_step(self, path: str) -> Shape:
145
+ """Read STEP — the onboarding path for existing mechanical work."""
146
+ ...
147
+
148
+ def import_brep(self, path: str) -> Shape:
149
+ """Read OCCT-native .brep (what .FCStd embeds per object)."""
150
+ ...
151
+
152
+ def export_brep(self, shape: Shape, path: str) -> None:
153
+ """Write OCCT-native .brep — the content-addressed import artifact."""
154
+ ...
155
+
156
+ def compound(self, shapes: list[Shape]) -> Shape:
157
+ """Combine shapes into one compound (multi-body import container)."""
158
+ ...
159
+
160
+ def hlr_project(self, shape: Shape, direction: tuple[float, float, float],
161
+ xdir: tuple[float, float, float], *,
162
+ deflection: float = 0.05) -> dict[str, list[list[tuple[float, float]]]]:
163
+ """Hidden-line-removal projection to 2D polylines (visible/hidden) —
164
+ the geometry backend of the DrawingEngine (ADR-0002)."""
165
+ ...
166
+
167
+ def tessellate(self, shape: Shape, *, deflection: float = 0.2) -> dict[str, list]:
168
+ """Triangulate for display: {"positions": [x,y,z,...], "indices":
169
+ [a,b,c,...]} — the viewer/Renderer geometry source."""
170
+ ...
171
+
172
+
173
+ @runtime_checkable
174
+ class IdentityService(Protocol):
175
+ """Assigns stable IDs to topological entities (the topological-naming fix).
176
+
177
+ An ID must survive upstream edits, reordering, and rebuilds. Identity is
178
+ derived from *construction lineage + geometric fingerprint*, never from an
179
+ ordinal index. See ADR-0003 — this is the decision that makes git workflows
180
+ (merge, rebase) survivable for CAD.
181
+ """
182
+
183
+ def assign(self, descriptor: dict[str, Any], lineage: tuple[str, ...]) -> str: ...
184
+
185
+ def resolve(self, entity_id: str, candidates: list[dict[str, Any]]) -> dict[str, Any] | None:
186
+ """Re-bind a stored ID to the best-matching current entity after a
187
+ rebuild, or ``None`` if it genuinely no longer exists."""
188
+ ...
189
+
190
+
191
+ @runtime_checkable
192
+ class DocumentModel(Protocol):
193
+ """The feature tree and its canonical text (de)serialization.
194
+
195
+ Source of truth is text (ADR-0004): this seam owns the mapping between the
196
+ editable, git-diffable text form and the in-memory feature graph.
197
+ """
198
+
199
+ def dumps(self) -> str: ...
200
+
201
+ @classmethod
202
+ def loads(cls, text: str) -> "DocumentModel": ...
203
+
204
+ def content_hash(self) -> str: ...
205
+
206
+
207
+ @runtime_checkable
208
+ class Renderer(Protocol):
209
+ """Headless tessellation → images / glTF. The agent's eyes (stub for now)."""
210
+
211
+ def render(self, shape: Shape, *, views: list[str], overlay: str | None = None) -> dict[str, bytes]: ...
212
+
213
+ def to_gltf(self, shape: Shape) -> bytes: ...
214
+
215
+
216
+ @runtime_checkable
217
+ class DrawingEngine(Protocol):
218
+ """3D → 2D drafting: HLR projection, associative dimensions, GD&T, sheets.
219
+
220
+ The mechanical-engineering deliverable. Projection is delegated to the
221
+ Kernel's HLR; this seam owns the 2D document model on top. Stub for now.
222
+ """
223
+
224
+ def project(self, shape: Shape, direction: str) -> dict[str, Any]:
225
+ """Return 2D edges tagged visible/hidden for one orthographic view."""
226
+ ...
227
+
228
+ def export(self, sheet: dict[str, Any], fmt: str) -> bytes:
229
+ """``fmt`` in {"svg", "pdf", "dxf"}."""
230
+ ...
231
+
232
+
233
+ @runtime_checkable
234
+ class Storage(Protocol):
235
+ """Git-backed store: text models are source, geometry is a build artifact.
236
+
237
+ ADR-0004. Models are committed as text; ``.brep``/STEP/PDF are generated,
238
+ content-addressed artifacts — never source. Stub for now.
239
+ """
240
+
241
+ def read_model(self, ref: str, path: str) -> str: ...
242
+
243
+ def write_model(self, path: str, text: str, message: str) -> str:
244
+ """Commit a model revision; return the commit id."""
245
+ ...
246
+
247
+ def put_artifact(self, data: bytes) -> str:
248
+ """Store a build artifact content-addressed; return its digest."""
249
+ ...
gitcad/strokefont.py ADDED
@@ -0,0 +1,84 @@
1
+ """A minimal single-stroke vector font for fab outputs (KiCad-map P3).
2
+
3
+ Gerber legend layers carry strokes, not text — every silkscreen ref is
4
+ drawn. Glyphs live in a unit cell (x 0..0.6, y 0..1, y-up), each a list
5
+ of polylines; ``text_strokes`` scales and places them. Deliberately
6
+ spartan: uppercase + digits + the punctuation that appears in refs and
7
+ values (text is uppercased on the way in — silkscreen is not typography).
8
+ Unknown characters render as a hollow box, visibly wrong rather than
9
+ silently absent.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ W = 0.6 # glyph width in cell units (height is 1.0)
15
+ ADVANCE = 0.85 # horizontal advance per character
16
+
17
+ _G: dict[str, list[list[tuple[float, float]]]] = {
18
+ "0": [[(0, 0), (0.6, 0), (0.6, 1), (0, 1), (0, 0)], [(0, 0.15), (0.6, 0.85)]],
19
+ "1": [[(0.15, 0.8), (0.35, 1), (0.35, 0)], [(0.15, 0), (0.55, 0)]],
20
+ "2": [[(0, 0.85), (0.15, 1), (0.45, 1), (0.6, 0.85), (0.6, 0.6), (0, 0), (0.6, 0)]],
21
+ "3": [[(0, 1), (0.6, 1), (0.3, 0.6), (0.6, 0.35), (0.6, 0.15), (0.45, 0), (0.1, 0), (0, 0.1)]],
22
+ "4": [[(0.45, 0), (0.45, 1), (0, 0.35), (0.6, 0.35)]],
23
+ "5": [[(0.6, 1), (0, 1), (0, 0.55), (0.45, 0.55), (0.6, 0.4), (0.6, 0.15), (0.45, 0), (0, 0)]],
24
+ "6": [[(0.5, 1), (0.1, 1), (0, 0.85), (0, 0.15), (0.15, 0), (0.45, 0), (0.6, 0.15), (0.6, 0.4), (0.45, 0.5), (0, 0.5)]],
25
+ "7": [[(0, 1), (0.6, 1), (0.2, 0)]],
26
+ "8": [[(0.1, 0.55), (0, 0.7), (0, 0.85), (0.15, 1), (0.45, 1), (0.6, 0.85), (0.6, 0.7), (0.5, 0.55), (0.1, 0.55), (0, 0.4), (0, 0.15), (0.15, 0), (0.45, 0), (0.6, 0.15), (0.6, 0.4), (0.5, 0.55)]],
27
+ "9": [[(0.6, 0.5), (0.15, 0.5), (0, 0.6), (0, 0.85), (0.15, 1), (0.45, 1), (0.6, 0.85), (0.6, 0.15), (0.5, 0), (0.1, 0)]],
28
+ "A": [[(0, 0), (0.3, 1), (0.6, 0)], [(0.12, 0.4), (0.48, 0.4)]],
29
+ "B": [[(0, 0), (0, 1), (0.45, 1), (0.6, 0.85), (0.6, 0.65), (0.45, 0.55), (0, 0.55)], [(0.45, 0.55), (0.6, 0.4), (0.6, 0.15), (0.45, 0), (0, 0)]],
30
+ "C": [[(0.6, 0.85), (0.45, 1), (0.15, 1), (0, 0.85), (0, 0.15), (0.15, 0), (0.45, 0), (0.6, 0.15)]],
31
+ "D": [[(0, 0), (0, 1), (0.4, 1), (0.6, 0.8), (0.6, 0.2), (0.4, 0), (0, 0)]],
32
+ "E": [[(0.6, 1), (0, 1), (0, 0), (0.6, 0)], [(0, 0.55), (0.45, 0.55)]],
33
+ "F": [[(0.6, 1), (0, 1), (0, 0)], [(0, 0.55), (0.45, 0.55)]],
34
+ "G": [[(0.6, 0.85), (0.45, 1), (0.15, 1), (0, 0.85), (0, 0.15), (0.15, 0), (0.45, 0), (0.6, 0.15), (0.6, 0.45), (0.35, 0.45)]],
35
+ "H": [[(0, 0), (0, 1)], [(0.6, 0), (0.6, 1)], [(0, 0.55), (0.6, 0.55)]],
36
+ "I": [[(0.1, 0), (0.5, 0)], [(0.3, 0), (0.3, 1)], [(0.1, 1), (0.5, 1)]],
37
+ "J": [[(0.6, 1), (0.6, 0.15), (0.45, 0), (0.15, 0), (0, 0.15)]],
38
+ "K": [[(0, 0), (0, 1)], [(0.6, 1), (0, 0.5), (0.6, 0)]],
39
+ "L": [[(0, 1), (0, 0), (0.6, 0)]],
40
+ "M": [[(0, 0), (0, 1), (0.3, 0.5), (0.6, 1), (0.6, 0)]],
41
+ "N": [[(0, 0), (0, 1), (0.6, 0), (0.6, 1)]],
42
+ "O": [[(0.15, 0), (0.45, 0), (0.6, 0.15), (0.6, 0.85), (0.45, 1), (0.15, 1), (0, 0.85), (0, 0.15), (0.15, 0)]],
43
+ "P": [[(0, 0), (0, 1), (0.45, 1), (0.6, 0.85), (0.6, 0.6), (0.45, 0.5), (0, 0.5)]],
44
+ "Q": [[(0.15, 0), (0.45, 0), (0.6, 0.15), (0.6, 0.85), (0.45, 1), (0.15, 1), (0, 0.85), (0, 0.15), (0.15, 0)], [(0.35, 0.25), (0.6, 0)]],
45
+ "R": [[(0, 0), (0, 1), (0.45, 1), (0.6, 0.85), (0.6, 0.6), (0.45, 0.5), (0, 0.5)], [(0.3, 0.5), (0.6, 0)]],
46
+ "S": [[(0.6, 0.85), (0.45, 1), (0.15, 1), (0, 0.85), (0, 0.65), (0.6, 0.35), (0.6, 0.15), (0.45, 0), (0.15, 0), (0, 0.15)]],
47
+ "T": [[(0, 1), (0.6, 1)], [(0.3, 1), (0.3, 0)]],
48
+ "U": [[(0, 1), (0, 0.15), (0.15, 0), (0.45, 0), (0.6, 0.15), (0.6, 1)]],
49
+ "V": [[(0, 1), (0.3, 0), (0.6, 1)]],
50
+ "W": [[(0, 1), (0.15, 0), (0.3, 0.5), (0.45, 0), (0.6, 1)]],
51
+ "X": [[(0, 0), (0.6, 1)], [(0, 1), (0.6, 0)]],
52
+ "Y": [[(0, 1), (0.3, 0.5), (0.6, 1)], [(0.3, 0.5), (0.3, 0)]],
53
+ "Z": [[(0, 1), (0.6, 1), (0, 0), (0.6, 0)]],
54
+ "-": [[(0.1, 0.5), (0.5, 0.5)]],
55
+ "+": [[(0.1, 0.5), (0.5, 0.5)], [(0.3, 0.3), (0.3, 0.7)]],
56
+ ".": [[(0.25, 0), (0.35, 0), (0.35, 0.1), (0.25, 0.1), (0.25, 0)]],
57
+ "_": [[(0, 0), (0.6, 0)]],
58
+ "/": [[(0, 0), (0.6, 1)]],
59
+ "%": [[(0, 0), (0.6, 1)], [(0.05, 0.8), (0.15, 0.9)], [(0.45, 0.1), (0.55, 0.2)]],
60
+ }
61
+
62
+ _UNKNOWN = [[(0, 0), (0.6, 0), (0.6, 1), (0, 1), (0, 0)]] # hollow box
63
+
64
+
65
+ def text_strokes(text: str, x: float, y: float, height: float,
66
+ ) -> list[tuple[float, float, float, float]]:
67
+ """Stroke segments for ``text`` with its lower-left corner at (x, y),
68
+ y-up, glyph height ``height`` mm. Returns (x1, y1, x2, y2) segments."""
69
+ segs: list[tuple[float, float, float, float]] = []
70
+ cx = x
71
+ for ch in text.upper():
72
+ if ch == " ":
73
+ cx += ADVANCE * height
74
+ continue
75
+ for poly in _G.get(ch, _UNKNOWN):
76
+ for (ax, ay), (bx, by) in zip(poly, poly[1:]):
77
+ segs.append((cx + ax * height, y + ay * height,
78
+ cx + bx * height, y + by * height))
79
+ cx += ADVANCE * height
80
+ return segs
81
+
82
+
83
+ def text_width(text: str, height: float) -> float:
84
+ return len(text) * ADVANCE * height
gitcad/waivers.py ADDED
@@ -0,0 +1,59 @@
1
+ """Check waivers — a silenced check must leave a trace (KiCad-map tier 2).
2
+
3
+ KiCad has per-violation exclusions buried in project files; here a waiver
4
+ is reviewable canonical text next to the design:
5
+
6
+ {"schema": "gitcad/waivers@1", "waivers": [
7
+ {"match": "erc:net-single-pin:TP*", "reason": "test points", "author": "dan"}]}
8
+
9
+ Rules with teeth:
10
+ - every waiver REQUIRES a reason — suppression without rationale refused;
11
+ - ``match`` is an fnmatch glob over the violation string, so one waiver
12
+ can cover a family without hiding unrelated failures;
13
+ - waived violations stay VISIBLE (moved to ``waived``, never deleted);
14
+ - a waiver that matches nothing is reported ``unused`` — stale
15
+ suppressions are debt, and debt shows.
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ import json
21
+ from fnmatch import fnmatchcase
22
+
23
+ from gitcad.errors import GitcadError
24
+
25
+ SCHEMA = "gitcad/waivers@1"
26
+
27
+
28
+ def load_waivers(text: str) -> list[dict]:
29
+ doc = json.loads(text)
30
+ if doc.get("schema") != SCHEMA:
31
+ raise GitcadError(f"unsupported waivers schema {doc.get('schema')!r}")
32
+ waivers = doc.get("waivers", [])
33
+ for w in waivers:
34
+ if not w.get("match"):
35
+ raise GitcadError("every waiver needs a match pattern")
36
+ if not (w.get("reason") or "").strip():
37
+ raise GitcadError(
38
+ f"waiver {w['match']!r} has no reason — suppression without "
39
+ "rationale is refused")
40
+ return waivers
41
+
42
+
43
+ def waive(violations: list[str], waivers: list[dict]
44
+ ) -> tuple[list[str], list[dict], list[str]]:
45
+ """(kept, waived [{violation, match, reason}], unused_matches)."""
46
+ kept: list[str] = []
47
+ waived: list[dict] = []
48
+ hits = {w["match"]: 0 for w in waivers}
49
+ for v in violations:
50
+ for w in waivers:
51
+ if fnmatchcase(v, w["match"]):
52
+ hits[w["match"]] += 1
53
+ waived.append({"violation": v, "match": w["match"],
54
+ "reason": w["reason"]})
55
+ break
56
+ else:
57
+ kept.append(v)
58
+ unused = [m for m, n in hits.items() if n == 0]
59
+ return kept, waived, unused
@@ -0,0 +1,40 @@
1
+ Metadata-Version: 2.4
2
+ Name: gitcad-core
3
+ Version: 0.7.7
4
+ Summary: gitcad core: canonical text, stable identity, the Part standard, report pipeline
5
+ Project-URL: Homepage, https://gitcad.xyz
6
+ Project-URL: Repository, https://github.com/gitcad-xyz/gitcad
7
+ Project-URL: Issues, https://github.com/gitcad-xyz/gitcad/issues
8
+ Author-email: Dan Willis <danielcwillis@gmail.com>
9
+ License-Expression: Apache-2.0
10
+ Keywords: agent,brep,cad,git,headless,identity,part
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Manufacturing
14
+ Classifier: License :: OSI Approved :: Apache Software License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Topic :: Multimedia :: Graphics :: 3D Modeling
18
+ Classifier: Topic :: Scientific/Engineering
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+
22
+ # gitcad-core
23
+
24
+ Core of [**gitcad**](https://gitcad.xyz) — the agent-first, headless, git-native
25
+ CAD substrate. This package is the dependency-free foundation the mechanical and
26
+ electrical domains build on:
27
+
28
+ - **Canonical text** — every model serializes to byte-stable, diff-friendly
29
+ source; geometry is a build artifact, never committed.
30
+ - **Stable identity** — entity and feature ids derive from construction lineage
31
+ and geometric fingerprint, never from ordinal position.
32
+ - **The Part standard** — one manifest/interface/semver/lockfile model that lets
33
+ mechanical parts, boards, and assemblies compose across domains.
34
+ - **Report pipeline** — the verification/render loop that turns a build into a
35
+ reviewable artifact.
36
+
37
+ Pure Python, no third-party runtime dependencies. Install the full system with
38
+ `pip install gitcad`.
39
+
40
+ Apache-2.0 · https://github.com/gitcad-xyz/gitcad
@@ -0,0 +1,26 @@
1
+ gitcad/_version.py,sha256=wu65dmVM9fKR1rBHH263ls8Ca2FZzb0ejYcrP_Ld0iY,22
2
+ gitcad/canonical.py,sha256=K3QStnwcn6nAAWBbmllDMHaaKzFsgB_5ihCvrthvDb8,2352
3
+ gitcad/errors.py,sha256=SAbWf0tJUDlFKgmmiBz-mmSdZn08zBV8hMWqcB6BT9g,2999
4
+ gitcad/expr.py,sha256=AwJ8WKz2BRGGd8ijibwGPiqHmzRPc9w8SA-iq2dWbpA,5511
5
+ gitcad/identity.py,sha256=xSVyXq1mDLcHqwhiJoTNflbauudRfR0JCTD_5QJn2hU,5355
6
+ gitcad/seams.py,sha256=ZwR-ah2YG-Y_3hRq_RpxI4Vw78XaH8rEMIGn7asVIjo,9981
7
+ gitcad/strokefont.py,sha256=Z9Zg3I1EvL5Eb-duhzReXT_RHe7CtyX5e1CSIZn1-5E,5041
8
+ gitcad/waivers.py,sha256=PeM_30KVEPj38vRTrJx6JG4a5A72VH0l7se0f0_65oU,2133
9
+ gitcad/importers/report.py,sha256=Lshscg6IedTaO5IBF5-g-KUgocxBJ9CSVYTUchcwItE,1166
10
+ gitcad/part/__init__.py,sha256=JTR_NbKFYTTgs5X9AZlJ-HDL4GlWTI52f-2qUgNHAh8,1361
11
+ gitcad/part/assembly.py,sha256=A6aX8nnnz4pd6AaAJlR8iRBnNtbfRbLivzhMbuCurL0,10451
12
+ gitcad/part/bought.py,sha256=-PO9gk81mmjIhYClH1nk4KaMMtzt5dciUXYXGh5dSAQ,2807
13
+ gitcad/part/exploded.py,sha256=F44BzbJmoeHUchoIv9YXOU6BhzdiioUHSWDr7IbRaDk,4321
14
+ gitcad/part/interface.py,sha256=m8ugdgZt9tHLrHWHnKBYEpaEj2aPSHho985yp-LxOZY,7493
15
+ gitcad/part/interference.py,sha256=CIHKnzpACLrXdoItajDe89vSCIuarxQkkX0dmA1QU4A,2891
16
+ gitcad/part/lockfile.py,sha256=rdId_HGZf6A4jOOEGdBaf2Fk11Zfj-j92IylApgrtfM,5588
17
+ gitcad/part/manifest.py,sha256=p-zT_zWoczj9P02ZimCG8KSkerZ_63FKDS0j6QX_BMs,2622
18
+ gitcad/part/matesolve.py,sha256=zSvQ-11FMpZ4_I_43wycsk2jYLEUW0kdhZN7Z-v8qko,3489
19
+ gitcad/part/semver.py,sha256=w6svOd3DszrCLRJlsXEk1Anwp-ebd_YsFJnGT691GRs,2815
20
+ gitcad/report/__init__.py,sha256=R31rqGmbO2qT5jHx_CO8mc34jHPmg8MHIsoqfVr1C3k,918
21
+ gitcad/report/fingerprint.py,sha256=L_b6POelyW5UwYhOnyvpM_p6EE-vXfFHLaF7AdPOxBw,835
22
+ gitcad/report/reduce.py,sha256=1gBuPxYBRrcUQzLlOOlxLRLoPM6l2MeotPhad7gprYM,3243
23
+ gitcad/report/scrub.py,sha256=N6sZGdsddDqlXVbBQhKlMVYPfaMiFwn496Hf5HI05_o,5167
24
+ gitcad_core-0.7.7.dist-info/METADATA,sha256=jg1ztfH0bcyQNl-OvwC64uh2ElUWN2hi8rwZKj8y4mU,1800
25
+ gitcad_core-0.7.7.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
26
+ gitcad_core-0.7.7.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.31.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any