kicadts 0.0.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/.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc +111 -0
- package/.vscode/settings.json +16 -0
- package/AGENTS.md +30 -0
- package/README.md +206 -0
- package/biome.json +93 -0
- package/bun.lock +48 -0
- package/bunfig.toml +5 -0
- package/lib/index.ts +1 -0
- package/lib/sexpr/base-classes/SxClass.ts +164 -0
- package/lib/sexpr/base-classes/SxPrimitiveBoolean.ts +35 -0
- package/lib/sexpr/base-classes/SxPrimitiveNumber.ts +26 -0
- package/lib/sexpr/base-classes/SxPrimitiveString.ts +26 -0
- package/lib/sexpr/classes/At.ts +38 -0
- package/lib/sexpr/classes/Bus.ts +83 -0
- package/lib/sexpr/classes/BusEntry.ts +142 -0
- package/lib/sexpr/classes/Color.ts +29 -0
- package/lib/sexpr/classes/Dnp.ts +8 -0
- package/lib/sexpr/classes/EmbeddedFonts.ts +70 -0
- package/lib/sexpr/classes/ExcludeFromSim.ts +8 -0
- package/lib/sexpr/classes/FieldsAutoplaced.ts +8 -0
- package/lib/sexpr/classes/Footprint.ts +719 -0
- package/lib/sexpr/classes/FootprintAttr.ts +102 -0
- package/lib/sexpr/classes/FootprintAutoplaceCost180.ts +9 -0
- package/lib/sexpr/classes/FootprintAutoplaceCost90.ts +9 -0
- package/lib/sexpr/classes/FootprintClearance.ts +9 -0
- package/lib/sexpr/classes/FootprintDescr.ts +44 -0
- package/lib/sexpr/classes/FootprintLocked.ts +32 -0
- package/lib/sexpr/classes/FootprintModel.ts +145 -0
- package/lib/sexpr/classes/FootprintNetTiePadGroups.ts +50 -0
- package/lib/sexpr/classes/FootprintPad.ts +705 -0
- package/lib/sexpr/classes/FootprintPath.ts +44 -0
- package/lib/sexpr/classes/FootprintPlaced.ts +32 -0
- package/lib/sexpr/classes/FootprintPrivateLayers.ts +56 -0
- package/lib/sexpr/classes/FootprintSheetfile.ts +44 -0
- package/lib/sexpr/classes/FootprintSheetname.ts +44 -0
- package/lib/sexpr/classes/FootprintSolderMaskMargin.ts +9 -0
- package/lib/sexpr/classes/FootprintSolderPasteMargin.ts +9 -0
- package/lib/sexpr/classes/FootprintSolderPasteRatio.ts +9 -0
- package/lib/sexpr/classes/FootprintTags.ts +44 -0
- package/lib/sexpr/classes/FootprintTedit.ts +21 -0
- package/lib/sexpr/classes/FootprintThermalGap.ts +9 -0
- package/lib/sexpr/classes/FootprintThermalWidth.ts +9 -0
- package/lib/sexpr/classes/FootprintZoneConnect.ts +9 -0
- package/lib/sexpr/classes/FpArc.ts +289 -0
- package/lib/sexpr/classes/FpCircle.ts +293 -0
- package/lib/sexpr/classes/FpLine.ts +288 -0
- package/lib/sexpr/classes/FpPoly.ts +266 -0
- package/lib/sexpr/classes/FpPolyFill.ts +48 -0
- package/lib/sexpr/classes/FpPolyLocked.ts +40 -0
- package/lib/sexpr/classes/FpRect.ts +293 -0
- package/lib/sexpr/classes/FpText.ts +341 -0
- package/lib/sexpr/classes/FpTextBox.ts +412 -0
- package/lib/sexpr/classes/GrLine.ts +245 -0
- package/lib/sexpr/classes/GrLineAngle.ts +32 -0
- package/lib/sexpr/classes/GrLineEnd.ts +61 -0
- package/lib/sexpr/classes/GrLineLocked.ts +40 -0
- package/lib/sexpr/classes/GrLineStart.ts +61 -0
- package/lib/sexpr/classes/GrText.ts +202 -0
- package/lib/sexpr/classes/Image.ts +256 -0
- package/lib/sexpr/classes/InBom.ts +8 -0
- package/lib/sexpr/classes/Junction.ts +134 -0
- package/lib/sexpr/classes/KicadPcb.ts +313 -0
- package/lib/sexpr/classes/KicadSch.ts +303 -0
- package/lib/sexpr/classes/KicadSchGenerator.ts +32 -0
- package/lib/sexpr/classes/KicadSchGeneratorVersion.ts +30 -0
- package/lib/sexpr/classes/KicadSchVersion.ts +22 -0
- package/lib/sexpr/classes/Label.ts +136 -0
- package/lib/sexpr/classes/Layer.ts +51 -0
- package/lib/sexpr/classes/Layers.ts +47 -0
- package/lib/sexpr/classes/LibSymbols.ts +61 -0
- package/lib/sexpr/classes/NoConnect.ts +73 -0
- package/lib/sexpr/classes/OnBoard.ts +8 -0
- package/lib/sexpr/classes/PadChamfer.ts +50 -0
- package/lib/sexpr/classes/PadChamferRatio.ts +9 -0
- package/lib/sexpr/classes/PadClearance.ts +9 -0
- package/lib/sexpr/classes/PadDieLength.ts +9 -0
- package/lib/sexpr/classes/PadDrill.ts +145 -0
- package/lib/sexpr/classes/PadDrillOffset.ts +54 -0
- package/lib/sexpr/classes/PadLayers.ts +59 -0
- package/lib/sexpr/classes/PadNet.ts +56 -0
- package/lib/sexpr/classes/PadOptions.ts +182 -0
- package/lib/sexpr/classes/PadPinFunction.ts +9 -0
- package/lib/sexpr/classes/PadPinType.ts +9 -0
- package/lib/sexpr/classes/PadPrimitiveGrArc.ts +254 -0
- package/lib/sexpr/classes/PadPrimitiveGrCircle.ts +279 -0
- package/lib/sexpr/classes/PadPrimitiveGrLine.ts +126 -0
- package/lib/sexpr/classes/PadPrimitives.ts +289 -0
- package/lib/sexpr/classes/PadRectDelta.ts +57 -0
- package/lib/sexpr/classes/PadRoundrectRratio.ts +9 -0
- package/lib/sexpr/classes/PadSize.ts +54 -0
- package/lib/sexpr/classes/PadSolderMaskMargin.ts +9 -0
- package/lib/sexpr/classes/PadSolderPasteMargin.ts +9 -0
- package/lib/sexpr/classes/PadSolderPasteMarginRatio.ts +9 -0
- package/lib/sexpr/classes/PadTeardrops.ts +208 -0
- package/lib/sexpr/classes/PadThermalBridgeAngle.ts +9 -0
- package/lib/sexpr/classes/PadThermalGap.ts +9 -0
- package/lib/sexpr/classes/PadThermalWidth.ts +9 -0
- package/lib/sexpr/classes/PadZoneConnect.ts +9 -0
- package/lib/sexpr/classes/Paper.ts +119 -0
- package/lib/sexpr/classes/PcbGeneral.ts +75 -0
- package/lib/sexpr/classes/PcbGeneralLegacyTeardrops.ts +44 -0
- package/lib/sexpr/classes/PcbGeneralThickness.ts +9 -0
- package/lib/sexpr/classes/PcbGenerator.ts +16 -0
- package/lib/sexpr/classes/PcbGeneratorVersion.ts +16 -0
- package/lib/sexpr/classes/PcbLayerDefinition.ts +102 -0
- package/lib/sexpr/classes/PcbLayers.ts +34 -0
- package/lib/sexpr/classes/PcbNet.ts +56 -0
- package/lib/sexpr/classes/PcbVersion.ts +9 -0
- package/lib/sexpr/classes/Property.ts +246 -0
- package/lib/sexpr/classes/PropertyHide.ts +9 -0
- package/lib/sexpr/classes/PropertyUnlocked.ts +9 -0
- package/lib/sexpr/classes/Pts.ts +65 -0
- package/lib/sexpr/classes/RenderCache.ts +221 -0
- package/lib/sexpr/classes/SchematicText.ts +141 -0
- package/lib/sexpr/classes/Segment.ts +222 -0
- package/lib/sexpr/classes/SegmentEnd.ts +59 -0
- package/lib/sexpr/classes/SegmentLocked.ts +33 -0
- package/lib/sexpr/classes/SegmentNet.ts +62 -0
- package/lib/sexpr/classes/SegmentStart.ts +59 -0
- package/lib/sexpr/classes/Setup/PcbPlotParams.ts +729 -0
- package/lib/sexpr/classes/Setup/PcbPlotParamsBase.ts +9 -0
- package/lib/sexpr/classes/Setup/PcbPlotParamsNumericProperties.ts +105 -0
- package/lib/sexpr/classes/Setup/PcbPlotParamsStringPropertiesA.ts +104 -0
- package/lib/sexpr/classes/Setup/PcbPlotParamsStringPropertiesB.ts +105 -0
- package/lib/sexpr/classes/Setup/Setup.ts +573 -0
- package/lib/sexpr/classes/Setup/SetupPropertyTypes.ts +119 -0
- package/lib/sexpr/classes/Setup/Stackup.ts +140 -0
- package/lib/sexpr/classes/Setup/StackupLayer.ts +233 -0
- package/lib/sexpr/classes/Setup/StackupLayerProperties.ts +78 -0
- package/lib/sexpr/classes/Setup/StackupProperties.ts +41 -0
- package/lib/sexpr/classes/Setup/base.ts +167 -0
- package/lib/sexpr/classes/Setup/index.ts +14 -0
- package/lib/sexpr/classes/Setup/setupMultiValueProperties.ts +54 -0
- package/lib/sexpr/classes/Setup/setupNumericProperties.ts +151 -0
- package/lib/sexpr/classes/Setup/setupPropertyHandlers.ts +90 -0
- package/lib/sexpr/classes/Setup/setupStringProperties.ts +75 -0
- package/lib/sexpr/classes/Sheet.ts +205 -0
- package/lib/sexpr/classes/SheetFill.ts +44 -0
- package/lib/sexpr/classes/SheetInstances.ts +168 -0
- package/lib/sexpr/classes/SheetInstancesRoot.ts +165 -0
- package/lib/sexpr/classes/SheetPin.ts +122 -0
- package/lib/sexpr/classes/SheetProperty.ts +115 -0
- package/lib/sexpr/classes/SheetSize.ts +44 -0
- package/lib/sexpr/classes/Stroke.ts +58 -0
- package/lib/sexpr/classes/StrokeType.ts +34 -0
- package/lib/sexpr/classes/Symbol.ts +1541 -0
- package/lib/sexpr/classes/TextEffects.ts +444 -0
- package/lib/sexpr/classes/TitleBlock.ts +352 -0
- package/lib/sexpr/classes/Unit.ts +28 -0
- package/lib/sexpr/classes/Uuid.ts +8 -0
- package/lib/sexpr/classes/Via.ts +328 -0
- package/lib/sexpr/classes/ViaNet.ts +59 -0
- package/lib/sexpr/classes/Width.ts +8 -0
- package/lib/sexpr/classes/Wire.ts +91 -0
- package/lib/sexpr/classes/Xy.ts +35 -0
- package/lib/sexpr/classes/Zone.ts +41 -0
- package/lib/sexpr/index.ts +130 -0
- package/lib/sexpr/parseKicadSexpr.ts +5 -0
- package/lib/sexpr/parseToPrimitiveSExpr.ts +240 -0
- package/lib/sexpr/utils/indentLines.ts +3 -0
- package/lib/sexpr/utils/parseYesNo.ts +12 -0
- package/lib/sexpr/utils/quoteSExprString.ts +8 -0
- package/lib/sexpr/utils/strokeFromArgs.ts +19 -0
- package/lib/sexpr/utils/toNumberValue.ts +13 -0
- package/lib/sexpr/utils/toStringValue.ts +10 -0
- package/package.json +26 -0
- package/scripts/download-references.ts +66 -0
- package/tests/fixtures/expectEqualPrimitiveSExpr.ts +200 -0
- package/tests/sexpr/KicadPcbDemos.test.ts +48 -0
- package/tests/sexpr/KicadSchDemos.test.ts +49 -0
- package/tests/sexpr/classes/Footprint.test.ts +277 -0
- package/tests/sexpr/classes/FootprintPad.test.ts +71 -0
- package/tests/sexpr/classes/FpArc.test.ts +45 -0
- package/tests/sexpr/classes/FpCircle.test.ts +39 -0
- package/tests/sexpr/classes/FpPoly.test.ts +43 -0
- package/tests/sexpr/classes/FpRect.test.ts +40 -0
- package/tests/sexpr/classes/FpTextBox.test.ts +84 -0
- package/tests/sexpr/classes/Image.test.ts +50 -0
- package/tests/sexpr/classes/KicadSch.test.ts +97 -0
- package/tests/sexpr/classes/Paper.test.ts +30 -0
- package/tests/sexpr/classes/Property.test.ts +48 -0
- package/tests/sexpr/classes/Setup.test.ts +189 -0
- package/tests/sexpr/classes/Sheet.test.ts +107 -0
- package/tests/sexpr/classes/Stroke.test.ts +15 -0
- package/tests/sexpr/classes/Symbol.test.ts +96 -0
- package/tests/sexpr/classes/TextEffects.test.ts +56 -0
- package/tests/sexpr/classes/TitleBlock.test.ts +40 -0
- package/tsconfig.json +35 -0
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { SxClass } from "../base-classes/SxClass"
|
|
2
|
+
import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
|
|
3
|
+
import { Layer } from "./Layer"
|
|
4
|
+
import { Stroke } from "./Stroke"
|
|
5
|
+
import { Uuid } from "./Uuid"
|
|
6
|
+
import { Width } from "./Width"
|
|
7
|
+
import { toNumberValue } from "../utils/toNumberValue"
|
|
8
|
+
import { toStringValue } from "../utils/toStringValue"
|
|
9
|
+
|
|
10
|
+
export class FpCircle extends SxClass {
|
|
11
|
+
static override token = "fp_circle"
|
|
12
|
+
token = "fp_circle"
|
|
13
|
+
|
|
14
|
+
private _sxCenter?: FpCircleCenter
|
|
15
|
+
private _sxEnd?: FpCircleEnd
|
|
16
|
+
private _sxLayer?: Layer
|
|
17
|
+
private _sxWidth?: Width
|
|
18
|
+
private _sxStroke?: Stroke
|
|
19
|
+
private _sxFill?: FpCircleFill
|
|
20
|
+
private _sxUuid?: Uuid
|
|
21
|
+
private _locked = false
|
|
22
|
+
|
|
23
|
+
static override fromSexprPrimitives(
|
|
24
|
+
primitiveSexprs: PrimitiveSExpr[],
|
|
25
|
+
): FpCircle {
|
|
26
|
+
const circle = new FpCircle()
|
|
27
|
+
|
|
28
|
+
const { propertyMap } = SxClass.parsePrimitivesToClassProperties(
|
|
29
|
+
primitiveSexprs,
|
|
30
|
+
this.token,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
circle._sxCenter = propertyMap.center as FpCircleCenter | undefined
|
|
34
|
+
circle._sxEnd = propertyMap.end as FpCircleEnd | undefined
|
|
35
|
+
circle._sxLayer = propertyMap.layer as Layer | undefined
|
|
36
|
+
circle._sxWidth = propertyMap.width as Width | undefined
|
|
37
|
+
circle._sxStroke = propertyMap.stroke as Stroke | undefined
|
|
38
|
+
circle._sxFill = propertyMap.fill as FpCircleFill | undefined
|
|
39
|
+
circle._sxUuid = propertyMap.uuid as Uuid | undefined
|
|
40
|
+
|
|
41
|
+
for (const primitive of primitiveSexprs) {
|
|
42
|
+
if (primitive === "locked") {
|
|
43
|
+
circle._locked = true
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return circle
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
get center(): FpCircleCenter | undefined {
|
|
51
|
+
return this._sxCenter
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
set center(
|
|
55
|
+
value: FpCircleCenter | { x: number; y: number } | undefined,
|
|
56
|
+
) {
|
|
57
|
+
if (value === undefined) {
|
|
58
|
+
this._sxCenter = undefined
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
if (value instanceof FpCircleCenter) {
|
|
62
|
+
this._sxCenter = value
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
this._sxCenter = new FpCircleCenter(value.x, value.y)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
get end(): FpCircleEnd | undefined {
|
|
69
|
+
return this._sxEnd
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
set end(value: FpCircleEnd | { x: number; y: number } | undefined) {
|
|
73
|
+
if (value === undefined) {
|
|
74
|
+
this._sxEnd = undefined
|
|
75
|
+
return
|
|
76
|
+
}
|
|
77
|
+
if (value instanceof FpCircleEnd) {
|
|
78
|
+
this._sxEnd = value
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
this._sxEnd = new FpCircleEnd(value.x, value.y)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
get layer(): Layer | undefined {
|
|
85
|
+
return this._sxLayer
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
set layer(value: Layer | string | string[] | undefined) {
|
|
89
|
+
if (value === undefined) {
|
|
90
|
+
this._sxLayer = undefined
|
|
91
|
+
return
|
|
92
|
+
}
|
|
93
|
+
if (value instanceof Layer) {
|
|
94
|
+
this._sxLayer = value
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
const names = Array.isArray(value) ? value : [value]
|
|
98
|
+
this._sxLayer = new Layer(names)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
get width(): number | undefined {
|
|
102
|
+
return this._sxWidth?.value
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
set width(value: number | Width | undefined) {
|
|
106
|
+
if (value === undefined) {
|
|
107
|
+
this._sxWidth = undefined
|
|
108
|
+
return
|
|
109
|
+
}
|
|
110
|
+
if (value instanceof Width) {
|
|
111
|
+
this._sxWidth = value
|
|
112
|
+
return
|
|
113
|
+
}
|
|
114
|
+
this._sxWidth = new Width(value)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
get widthClass(): Width | undefined {
|
|
118
|
+
return this._sxWidth
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
get stroke(): Stroke | undefined {
|
|
122
|
+
return this._sxStroke
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
set stroke(value: Stroke | undefined) {
|
|
126
|
+
this._sxStroke = value
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
get fill(): boolean | undefined {
|
|
130
|
+
return this._sxFill?.filled
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
set fill(value: boolean | FpCircleFill | undefined) {
|
|
134
|
+
if (value === undefined) {
|
|
135
|
+
this._sxFill = undefined
|
|
136
|
+
return
|
|
137
|
+
}
|
|
138
|
+
if (value instanceof FpCircleFill) {
|
|
139
|
+
this._sxFill = value
|
|
140
|
+
return
|
|
141
|
+
}
|
|
142
|
+
this._sxFill = new FpCircleFill(value)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
get fillClass(): FpCircleFill | undefined {
|
|
146
|
+
return this._sxFill
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
get uuid(): string | undefined {
|
|
150
|
+
return this._sxUuid?.value
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
set uuid(value: string | Uuid | undefined) {
|
|
154
|
+
if (value === undefined) {
|
|
155
|
+
this._sxUuid = undefined
|
|
156
|
+
return
|
|
157
|
+
}
|
|
158
|
+
if (value instanceof Uuid) {
|
|
159
|
+
this._sxUuid = value
|
|
160
|
+
return
|
|
161
|
+
}
|
|
162
|
+
this._sxUuid = new Uuid(value)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
get uuidClass(): Uuid | undefined {
|
|
166
|
+
return this._sxUuid
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
get locked(): boolean {
|
|
170
|
+
return this._locked
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
set locked(value: boolean) {
|
|
174
|
+
this._locked = value
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
override getChildren(): SxClass[] {
|
|
178
|
+
const children: SxClass[] = []
|
|
179
|
+
if (this._sxCenter) children.push(this._sxCenter)
|
|
180
|
+
if (this._sxEnd) children.push(this._sxEnd)
|
|
181
|
+
if (this._sxLayer) children.push(this._sxLayer)
|
|
182
|
+
if (this._sxWidth) children.push(this._sxWidth)
|
|
183
|
+
if (this._sxStroke) children.push(this._sxStroke)
|
|
184
|
+
if (this._sxFill) children.push(this._sxFill)
|
|
185
|
+
if (this._sxUuid) children.push(this._sxUuid)
|
|
186
|
+
return children
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
override getString(): string {
|
|
190
|
+
const lines = ["(fp_circle"]
|
|
191
|
+
const push = (value?: SxClass) => {
|
|
192
|
+
if (!value) return
|
|
193
|
+
lines.push(value.getStringIndented())
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
push(this._sxCenter)
|
|
197
|
+
push(this._sxEnd)
|
|
198
|
+
push(this._sxLayer)
|
|
199
|
+
push(this._sxWidth)
|
|
200
|
+
push(this._sxStroke)
|
|
201
|
+
push(this._sxFill)
|
|
202
|
+
push(this._sxUuid)
|
|
203
|
+
|
|
204
|
+
if (this._locked) {
|
|
205
|
+
lines.push(" locked")
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
lines.push(")")
|
|
209
|
+
return lines.join("\n")
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
SxClass.register(FpCircle)
|
|
213
|
+
|
|
214
|
+
export class FpCircleCenter extends SxClass {
|
|
215
|
+
static override token = "center"
|
|
216
|
+
static override parentToken = "fp_circle"
|
|
217
|
+
token = "center"
|
|
218
|
+
|
|
219
|
+
x: number
|
|
220
|
+
y: number
|
|
221
|
+
|
|
222
|
+
constructor(x: number, y: number) {
|
|
223
|
+
super()
|
|
224
|
+
this.x = x
|
|
225
|
+
this.y = y
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
static override fromSexprPrimitives(
|
|
229
|
+
primitiveSexprs: PrimitiveSExpr[],
|
|
230
|
+
): FpCircleCenter {
|
|
231
|
+
const x = toNumberValue(primitiveSexprs[0]) ?? 0
|
|
232
|
+
const y = toNumberValue(primitiveSexprs[1]) ?? 0
|
|
233
|
+
return new FpCircleCenter(x, y)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
override getString(): string {
|
|
237
|
+
return `(center ${this.x} ${this.y})`
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
SxClass.register(FpCircleCenter)
|
|
241
|
+
|
|
242
|
+
export class FpCircleEnd extends SxClass {
|
|
243
|
+
static override token = "end"
|
|
244
|
+
static override parentToken = "fp_circle"
|
|
245
|
+
token = "end"
|
|
246
|
+
|
|
247
|
+
x: number
|
|
248
|
+
y: number
|
|
249
|
+
|
|
250
|
+
constructor(x: number, y: number) {
|
|
251
|
+
super()
|
|
252
|
+
this.x = x
|
|
253
|
+
this.y = y
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
static override fromSexprPrimitives(
|
|
257
|
+
primitiveSexprs: PrimitiveSExpr[],
|
|
258
|
+
): FpCircleEnd {
|
|
259
|
+
const x = toNumberValue(primitiveSexprs[0]) ?? 0
|
|
260
|
+
const y = toNumberValue(primitiveSexprs[1]) ?? 0
|
|
261
|
+
return new FpCircleEnd(x, y)
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
override getString(): string {
|
|
265
|
+
return `(end ${this.x} ${this.y})`
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
SxClass.register(FpCircleEnd)
|
|
269
|
+
|
|
270
|
+
export class FpCircleFill extends SxClass {
|
|
271
|
+
static override token = "fill"
|
|
272
|
+
static override parentToken = "fp_circle"
|
|
273
|
+
token = "fill"
|
|
274
|
+
|
|
275
|
+
filled: boolean
|
|
276
|
+
|
|
277
|
+
constructor(filled: boolean) {
|
|
278
|
+
super()
|
|
279
|
+
this.filled = filled
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
static override fromSexprPrimitives(
|
|
283
|
+
primitiveSexprs: PrimitiveSExpr[],
|
|
284
|
+
): FpCircleFill {
|
|
285
|
+
const state = toStringValue(primitiveSexprs[0])
|
|
286
|
+
return new FpCircleFill(state === "yes")
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
override getString(): string {
|
|
290
|
+
return `(fill ${this.filled ? "yes" : "no"})`
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
SxClass.register(FpCircleFill)
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { SxClass } from "../base-classes/SxClass"
|
|
2
|
+
import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
|
|
3
|
+
import { Layer } from "./Layer"
|
|
4
|
+
import { Stroke } from "./Stroke"
|
|
5
|
+
import { Uuid } from "./Uuid"
|
|
6
|
+
import { Width } from "./Width"
|
|
7
|
+
|
|
8
|
+
const SUPPORTED_SINGLE_TOKENS = new Set([
|
|
9
|
+
"start",
|
|
10
|
+
"end",
|
|
11
|
+
"layer",
|
|
12
|
+
"width",
|
|
13
|
+
"stroke",
|
|
14
|
+
"uuid",
|
|
15
|
+
])
|
|
16
|
+
|
|
17
|
+
export class FpLine extends SxClass {
|
|
18
|
+
static override token = "fp_line"
|
|
19
|
+
static override parentToken = "footprint"
|
|
20
|
+
override token = "fp_line"
|
|
21
|
+
|
|
22
|
+
private _sxStart?: FpLineStart
|
|
23
|
+
private _sxEnd?: FpLineEnd
|
|
24
|
+
private _sxLayer?: Layer
|
|
25
|
+
private _sxWidth?: Width
|
|
26
|
+
private _sxStroke?: Stroke
|
|
27
|
+
private _sxUuid?: Uuid
|
|
28
|
+
private _locked = false
|
|
29
|
+
|
|
30
|
+
static override fromSexprPrimitives(
|
|
31
|
+
primitiveSexprs: PrimitiveSExpr[],
|
|
32
|
+
): FpLine {
|
|
33
|
+
const fpLine = new FpLine()
|
|
34
|
+
|
|
35
|
+
const structuredPrimitives: PrimitiveSExpr[] = []
|
|
36
|
+
|
|
37
|
+
for (const primitive of primitiveSexprs) {
|
|
38
|
+
if (typeof primitive === "string") {
|
|
39
|
+
if (primitive === "locked") {
|
|
40
|
+
if (fpLine._locked) {
|
|
41
|
+
throw new Error("fp_line encountered duplicate locked flags")
|
|
42
|
+
}
|
|
43
|
+
fpLine._locked = true
|
|
44
|
+
continue
|
|
45
|
+
}
|
|
46
|
+
throw new Error(`fp_line encountered unsupported flag "${primitive}"`)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (!Array.isArray(primitive) || primitive.length === 0) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
`fp_line encountered invalid child expression: ${JSON.stringify(primitive)}`,
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
structuredPrimitives.push(primitive)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const { propertyMap, arrayPropertyMap } =
|
|
59
|
+
SxClass.parsePrimitivesToClassProperties(structuredPrimitives, this.token)
|
|
60
|
+
|
|
61
|
+
for (const token of Object.keys(propertyMap)) {
|
|
62
|
+
if (!SUPPORTED_SINGLE_TOKENS.has(token)) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`fp_line encountered unsupported child token "${token}"`,
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
for (const [token, entries] of Object.entries(arrayPropertyMap)) {
|
|
70
|
+
if (!SUPPORTED_SINGLE_TOKENS.has(token)) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
`fp_line encountered unsupported child token "${token}"`,
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
if (entries.length > 1) {
|
|
76
|
+
throw new Error(
|
|
77
|
+
`fp_line does not support repeated child token "${token}"`,
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
fpLine._sxStart =
|
|
83
|
+
(arrayPropertyMap.start?.[0] as FpLineStart | undefined) ??
|
|
84
|
+
(propertyMap.start as FpLineStart | undefined)
|
|
85
|
+
fpLine._sxEnd =
|
|
86
|
+
(arrayPropertyMap.end?.[0] as FpLineEnd | undefined) ??
|
|
87
|
+
(propertyMap.end as FpLineEnd | undefined)
|
|
88
|
+
fpLine._sxLayer =
|
|
89
|
+
(arrayPropertyMap.layer?.[0] as Layer | undefined) ??
|
|
90
|
+
(propertyMap.layer as Layer | undefined)
|
|
91
|
+
fpLine._sxWidth =
|
|
92
|
+
(arrayPropertyMap.width?.[0] as Width | undefined) ??
|
|
93
|
+
(propertyMap.width as Width | undefined)
|
|
94
|
+
fpLine._sxStroke =
|
|
95
|
+
(arrayPropertyMap.stroke?.[0] as Stroke | undefined) ??
|
|
96
|
+
(propertyMap.stroke as Stroke | undefined)
|
|
97
|
+
fpLine._sxUuid =
|
|
98
|
+
(arrayPropertyMap.uuid?.[0] as Uuid | undefined) ??
|
|
99
|
+
(propertyMap.uuid as Uuid | undefined)
|
|
100
|
+
|
|
101
|
+
if (!fpLine._sxStart) {
|
|
102
|
+
throw new Error("fp_line requires a start child token")
|
|
103
|
+
}
|
|
104
|
+
if (!fpLine._sxEnd) {
|
|
105
|
+
throw new Error("fp_line requires an end child token")
|
|
106
|
+
}
|
|
107
|
+
if (!fpLine._sxLayer) {
|
|
108
|
+
throw new Error("fp_line requires a layer child token")
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return fpLine
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
get start(): FpLineStart | undefined {
|
|
115
|
+
return this._sxStart
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
set start(value: FpLineStart | { x: number; y: number } | undefined) {
|
|
119
|
+
if (value === undefined) {
|
|
120
|
+
this._sxStart = undefined
|
|
121
|
+
return
|
|
122
|
+
}
|
|
123
|
+
this._sxStart =
|
|
124
|
+
value instanceof FpLineStart ? value : new FpLineStart(value.x, value.y)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
get end(): FpLineEnd | undefined {
|
|
128
|
+
return this._sxEnd
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
set end(value: FpLineEnd | { x: number; y: number } | undefined) {
|
|
132
|
+
if (value === undefined) {
|
|
133
|
+
this._sxEnd = undefined
|
|
134
|
+
return
|
|
135
|
+
}
|
|
136
|
+
this._sxEnd = value instanceof FpLineEnd ? value : new FpLineEnd(value.x, value.y)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
get layer(): Layer | undefined {
|
|
140
|
+
return this._sxLayer
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
set layer(value: Layer | string | Array<string | number> | undefined) {
|
|
144
|
+
if (value === undefined) {
|
|
145
|
+
this._sxLayer = undefined
|
|
146
|
+
return
|
|
147
|
+
}
|
|
148
|
+
if (value instanceof Layer) {
|
|
149
|
+
this._sxLayer = value
|
|
150
|
+
return
|
|
151
|
+
}
|
|
152
|
+
const names = Array.isArray(value) ? value : [value]
|
|
153
|
+
this._sxLayer = new Layer(names)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
get width(): number | undefined {
|
|
157
|
+
return this._sxWidth?.value
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
set width(value: number | undefined) {
|
|
161
|
+
this._sxWidth = value === undefined ? undefined : new Width(value)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
get stroke(): Stroke | undefined {
|
|
165
|
+
return this._sxStroke
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
set stroke(value: Stroke | undefined) {
|
|
169
|
+
this._sxStroke = value
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
get uuid(): Uuid | undefined {
|
|
173
|
+
return this._sxUuid
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
set uuid(value: Uuid | string | undefined) {
|
|
177
|
+
if (value === undefined) {
|
|
178
|
+
this._sxUuid = undefined
|
|
179
|
+
return
|
|
180
|
+
}
|
|
181
|
+
this._sxUuid = value instanceof Uuid ? value : new Uuid(value)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
get locked(): boolean {
|
|
185
|
+
return this._locked
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
set locked(value: boolean) {
|
|
189
|
+
this._locked = value
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
override getChildren(): SxClass[] {
|
|
193
|
+
const children: SxClass[] = []
|
|
194
|
+
if (this._sxStart) children.push(this._sxStart)
|
|
195
|
+
if (this._sxEnd) children.push(this._sxEnd)
|
|
196
|
+
if (this._sxStroke) {
|
|
197
|
+
children.push(this._sxStroke)
|
|
198
|
+
} else if (this._sxWidth) {
|
|
199
|
+
children.push(this._sxWidth)
|
|
200
|
+
}
|
|
201
|
+
if (this._sxLayer) children.push(this._sxLayer)
|
|
202
|
+
if (this._sxUuid) children.push(this._sxUuid)
|
|
203
|
+
if (this._locked) children.push(new FpLineLocked())
|
|
204
|
+
return children
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
SxClass.register(FpLine)
|
|
208
|
+
|
|
209
|
+
export class FpLineStart extends SxClass {
|
|
210
|
+
static override token = "start"
|
|
211
|
+
static override parentToken = "fp_line"
|
|
212
|
+
override token = "start"
|
|
213
|
+
|
|
214
|
+
constructor(public x: number, public y: number) {
|
|
215
|
+
super()
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
static override fromSexprPrimitives(
|
|
219
|
+
primitiveSexprs: PrimitiveSExpr[],
|
|
220
|
+
): FpLineStart {
|
|
221
|
+
const [rawX, rawY] = primitiveSexprs
|
|
222
|
+
const x = Number(rawX)
|
|
223
|
+
const y = Number(rawY)
|
|
224
|
+
if (!Number.isFinite(x) || !Number.isFinite(y)) {
|
|
225
|
+
throw new Error("fp_line start expects numeric coordinates")
|
|
226
|
+
}
|
|
227
|
+
return new FpLineStart(x, y)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
override getChildren(): SxClass[] {
|
|
231
|
+
return []
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
override getString(): string {
|
|
235
|
+
return `(start ${this.x} ${this.y})`
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
SxClass.register(FpLineStart)
|
|
239
|
+
|
|
240
|
+
export class FpLineEnd extends SxClass {
|
|
241
|
+
static override token = "end"
|
|
242
|
+
static override parentToken = "fp_line"
|
|
243
|
+
override token = "end"
|
|
244
|
+
|
|
245
|
+
constructor(public x: number, public y: number) {
|
|
246
|
+
super()
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
static override fromSexprPrimitives(
|
|
250
|
+
primitiveSexprs: PrimitiveSExpr[],
|
|
251
|
+
): FpLineEnd {
|
|
252
|
+
const [rawX, rawY] = primitiveSexprs
|
|
253
|
+
const x = Number(rawX)
|
|
254
|
+
const y = Number(rawY)
|
|
255
|
+
if (!Number.isFinite(x) || !Number.isFinite(y)) {
|
|
256
|
+
throw new Error("fp_line end expects numeric coordinates")
|
|
257
|
+
}
|
|
258
|
+
return new FpLineEnd(x, y)
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
override getChildren(): SxClass[] {
|
|
262
|
+
return []
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
override getString(): string {
|
|
266
|
+
return `(end ${this.x} ${this.y})`
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
SxClass.register(FpLineEnd)
|
|
270
|
+
|
|
271
|
+
class FpLineLocked extends SxClass {
|
|
272
|
+
static override token = "locked"
|
|
273
|
+
static override parentToken = "fp_line"
|
|
274
|
+
override token = "locked"
|
|
275
|
+
|
|
276
|
+
static override fromSexprPrimitives(): FpLineLocked {
|
|
277
|
+
return new FpLineLocked()
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
override getChildren(): SxClass[] {
|
|
281
|
+
return []
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
override getString(): string {
|
|
285
|
+
return "locked"
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
SxClass.register(FpLineLocked)
|