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,140 @@
|
|
|
1
|
+
import { SxClass } from "../../base-classes/SxClass"
|
|
2
|
+
import type { PrimitiveSExpr } from "../../parseToPrimitiveSExpr"
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
StackupCastellatedPads,
|
|
6
|
+
StackupCopperFinish,
|
|
7
|
+
StackupDielectricConstraints,
|
|
8
|
+
StackupEdgeConnector,
|
|
9
|
+
StackupEdgePlating,
|
|
10
|
+
} from "./StackupProperties"
|
|
11
|
+
import { StackupLayer } from "./StackupLayer"
|
|
12
|
+
|
|
13
|
+
export class Stackup extends SxClass {
|
|
14
|
+
static override token = "stackup"
|
|
15
|
+
static override parentToken = "setup"
|
|
16
|
+
token = "stackup"
|
|
17
|
+
|
|
18
|
+
private _layers: StackupLayer[] = []
|
|
19
|
+
private _sxCopperFinish?: StackupCopperFinish
|
|
20
|
+
private _sxDielectricConstraints?: StackupDielectricConstraints
|
|
21
|
+
private _sxEdgeConnector?: StackupEdgeConnector
|
|
22
|
+
private _sxCastellatedPads?: StackupCastellatedPads
|
|
23
|
+
private _sxEdgePlating?: StackupEdgePlating
|
|
24
|
+
|
|
25
|
+
constructor(opts: {
|
|
26
|
+
layers?: StackupLayer[]
|
|
27
|
+
copperFinish?: StackupCopperFinish
|
|
28
|
+
dielectricConstraints?: StackupDielectricConstraints
|
|
29
|
+
edgeConnector?: StackupEdgeConnector
|
|
30
|
+
castellatedPads?: StackupCastellatedPads
|
|
31
|
+
edgePlating?: StackupEdgePlating
|
|
32
|
+
} = {}) {
|
|
33
|
+
super()
|
|
34
|
+
this.layers = opts.layers ?? []
|
|
35
|
+
this._sxCopperFinish = opts.copperFinish
|
|
36
|
+
this._sxDielectricConstraints = opts.dielectricConstraints
|
|
37
|
+
this._sxEdgeConnector = opts.edgeConnector
|
|
38
|
+
this._sxCastellatedPads = opts.castellatedPads
|
|
39
|
+
this._sxEdgePlating = opts.edgePlating
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static override fromSexprPrimitives(
|
|
43
|
+
primitiveSexprs: PrimitiveSExpr[],
|
|
44
|
+
): Stackup {
|
|
45
|
+
const { propertyMap, arrayPropertyMap } =
|
|
46
|
+
SxClass.parsePrimitivesToClassProperties(primitiveSexprs, this.token)
|
|
47
|
+
|
|
48
|
+
return new Stackup({
|
|
49
|
+
layers: (arrayPropertyMap.layer as StackupLayer[] | undefined) ?? [],
|
|
50
|
+
copperFinish: propertyMap.copper_finish as StackupCopperFinish,
|
|
51
|
+
dielectricConstraints:
|
|
52
|
+
propertyMap.dielectric_constraints as StackupDielectricConstraints,
|
|
53
|
+
edgeConnector: propertyMap.edge_connector as StackupEdgeConnector,
|
|
54
|
+
castellatedPads:
|
|
55
|
+
propertyMap.castellated_pads as StackupCastellatedPads,
|
|
56
|
+
edgePlating: propertyMap.edge_plating as StackupEdgePlating,
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
get layers(): StackupLayer[] {
|
|
61
|
+
return [...this._layers]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
set layers(layers: StackupLayer[]) {
|
|
65
|
+
this._layers = layers.map((layer) => {
|
|
66
|
+
if (!(layer instanceof StackupLayer)) {
|
|
67
|
+
throw new Error("Stackup layers must be StackupLayer instances")
|
|
68
|
+
}
|
|
69
|
+
return layer
|
|
70
|
+
})
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
get copperFinish(): string | undefined {
|
|
74
|
+
return this._sxCopperFinish?.value
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
set copperFinish(value: string | undefined) {
|
|
78
|
+
this._sxCopperFinish = value
|
|
79
|
+
? new StackupCopperFinish(value)
|
|
80
|
+
: undefined
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
get dielectricConstraints(): string | undefined {
|
|
84
|
+
return this._sxDielectricConstraints?.value
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
set dielectricConstraints(value: string | undefined) {
|
|
88
|
+
this._sxDielectricConstraints = value
|
|
89
|
+
? new StackupDielectricConstraints(value)
|
|
90
|
+
: undefined
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
get edgeConnector(): string | undefined {
|
|
94
|
+
return this._sxEdgeConnector?.value
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
set edgeConnector(value: string | undefined) {
|
|
98
|
+
this._sxEdgeConnector = value
|
|
99
|
+
? new StackupEdgeConnector(value)
|
|
100
|
+
: undefined
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
get castellatedPads(): string | undefined {
|
|
104
|
+
return this._sxCastellatedPads?.value
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
set castellatedPads(value: string | undefined) {
|
|
108
|
+
this._sxCastellatedPads = value
|
|
109
|
+
? new StackupCastellatedPads(value)
|
|
110
|
+
: undefined
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
get edgePlating(): string | undefined {
|
|
114
|
+
return this._sxEdgePlating?.value
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
set edgePlating(value: string | undefined) {
|
|
118
|
+
this._sxEdgePlating = value
|
|
119
|
+
? new StackupEdgePlating(value)
|
|
120
|
+
: undefined
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
override getChildren(): SxClass[] {
|
|
124
|
+
const children: SxClass[] = [...this._layers]
|
|
125
|
+
const optionalChildren = [
|
|
126
|
+
this._sxCopperFinish,
|
|
127
|
+
this._sxDielectricConstraints,
|
|
128
|
+
this._sxEdgeConnector,
|
|
129
|
+
this._sxCastellatedPads,
|
|
130
|
+
this._sxEdgePlating,
|
|
131
|
+
]
|
|
132
|
+
for (const child of optionalChildren) {
|
|
133
|
+
if (child) {
|
|
134
|
+
children.push(child)
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return children
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
SxClass.register(Stackup)
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { SxClass } from "../../base-classes/SxClass"
|
|
2
|
+
import type { PrimitiveSExpr } from "../../parseToPrimitiveSExpr"
|
|
3
|
+
import { quoteSExprString } from "../../utils/quoteSExprString"
|
|
4
|
+
import { toNumberValue } from "../../utils/toNumberValue"
|
|
5
|
+
import { toStringValue } from "../../utils/toStringValue"
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
StackupLayerColor,
|
|
9
|
+
StackupLayerEpsilonR,
|
|
10
|
+
StackupLayerLossTangent,
|
|
11
|
+
StackupLayerMaterial,
|
|
12
|
+
StackupLayerThickness,
|
|
13
|
+
StackupLayerType,
|
|
14
|
+
} from "./StackupLayerProperties"
|
|
15
|
+
|
|
16
|
+
export class StackupLayer extends SxClass {
|
|
17
|
+
static override token = "layer"
|
|
18
|
+
static override parentToken = "stackup"
|
|
19
|
+
token = "layer"
|
|
20
|
+
|
|
21
|
+
private _name: string
|
|
22
|
+
private _number?: number
|
|
23
|
+
|
|
24
|
+
private _sxType?: StackupLayerType
|
|
25
|
+
private _sxColor?: StackupLayerColor
|
|
26
|
+
private _sxThickness?: StackupLayerThickness
|
|
27
|
+
private _sxMaterial?: StackupLayerMaterial
|
|
28
|
+
private _sxEpsilonR?: StackupLayerEpsilonR
|
|
29
|
+
private _sxLossTangent?: StackupLayerLossTangent
|
|
30
|
+
|
|
31
|
+
constructor(
|
|
32
|
+
name: string,
|
|
33
|
+
opts: {
|
|
34
|
+
number?: number
|
|
35
|
+
type?: StackupLayerType
|
|
36
|
+
color?: StackupLayerColor
|
|
37
|
+
thickness?: StackupLayerThickness
|
|
38
|
+
material?: StackupLayerMaterial
|
|
39
|
+
epsilonR?: StackupLayerEpsilonR
|
|
40
|
+
lossTangent?: StackupLayerLossTangent
|
|
41
|
+
} = {},
|
|
42
|
+
) {
|
|
43
|
+
super()
|
|
44
|
+
this._name = name
|
|
45
|
+
this._number = opts.number
|
|
46
|
+
this._sxType = opts.type
|
|
47
|
+
this._sxColor = opts.color
|
|
48
|
+
this._sxThickness = opts.thickness
|
|
49
|
+
this._sxMaterial = opts.material
|
|
50
|
+
this._sxEpsilonR = opts.epsilonR
|
|
51
|
+
this._sxLossTangent = opts.lossTangent
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static override fromSexprPrimitives(
|
|
55
|
+
primitiveSexprs: PrimitiveSExpr[],
|
|
56
|
+
): StackupLayer {
|
|
57
|
+
if (primitiveSexprs.length === 0) {
|
|
58
|
+
throw new Error("Stackup layer requires at least a name")
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const name = toStringValue(primitiveSexprs[0])
|
|
62
|
+
if (name === undefined) {
|
|
63
|
+
throw new Error("Stackup layer name must be a string")
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let propertyIndex = 1
|
|
67
|
+
let number: number | undefined
|
|
68
|
+
const maybeNumber = primitiveSexprs[propertyIndex]
|
|
69
|
+
const numericLayerNumber = toNumberValue(maybeNumber)
|
|
70
|
+
if (numericLayerNumber !== undefined) {
|
|
71
|
+
number = numericLayerNumber
|
|
72
|
+
propertyIndex += 1
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const propertyPrimitives = primitiveSexprs.slice(propertyIndex)
|
|
76
|
+
const { propertyMap } = SxClass.parsePrimitivesToClassProperties(
|
|
77
|
+
propertyPrimitives,
|
|
78
|
+
this.token,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
return new StackupLayer(name, {
|
|
82
|
+
number,
|
|
83
|
+
type: propertyMap.type as StackupLayerType,
|
|
84
|
+
color: propertyMap.color as StackupLayerColor,
|
|
85
|
+
thickness: propertyMap.thickness as StackupLayerThickness,
|
|
86
|
+
material: propertyMap.material as StackupLayerMaterial,
|
|
87
|
+
epsilonR: propertyMap.epsilon_r as StackupLayerEpsilonR,
|
|
88
|
+
lossTangent: propertyMap.loss_tangent as StackupLayerLossTangent,
|
|
89
|
+
})
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
get name(): string {
|
|
93
|
+
return this._name
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
set name(value: string) {
|
|
97
|
+
const parsed = toStringValue(value)
|
|
98
|
+
if (parsed === undefined) {
|
|
99
|
+
throw new Error("Stackup layer name must be a string")
|
|
100
|
+
}
|
|
101
|
+
this._name = parsed
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
get number(): number | undefined {
|
|
105
|
+
return this._number
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
set number(value: number | undefined) {
|
|
109
|
+
if (value === undefined) {
|
|
110
|
+
this._number = undefined
|
|
111
|
+
return
|
|
112
|
+
}
|
|
113
|
+
const parsed = toNumberValue(value)
|
|
114
|
+
if (parsed === undefined) {
|
|
115
|
+
throw new Error("Stackup layer number must be numeric")
|
|
116
|
+
}
|
|
117
|
+
this._number = parsed
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
get type(): string | undefined {
|
|
121
|
+
return this._sxType?.value
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
set type(value: string | StackupLayerType | undefined) {
|
|
125
|
+
if (value === undefined) {
|
|
126
|
+
this._sxType = undefined
|
|
127
|
+
return
|
|
128
|
+
}
|
|
129
|
+
this._sxType =
|
|
130
|
+
value instanceof StackupLayerType ? value : new StackupLayerType(value)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
get color(): string | undefined {
|
|
134
|
+
return this._sxColor?.value
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
set color(value: string | StackupLayerColor | undefined) {
|
|
138
|
+
if (value === undefined) {
|
|
139
|
+
this._sxColor = undefined
|
|
140
|
+
return
|
|
141
|
+
}
|
|
142
|
+
this._sxColor =
|
|
143
|
+
value instanceof StackupLayerColor ? value : new StackupLayerColor(value)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
get thickness(): number | undefined {
|
|
147
|
+
return this._sxThickness?.value
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
set thickness(value: number | StackupLayerThickness | undefined) {
|
|
151
|
+
if (value === undefined) {
|
|
152
|
+
this._sxThickness = undefined
|
|
153
|
+
return
|
|
154
|
+
}
|
|
155
|
+
this._sxThickness =
|
|
156
|
+
value instanceof StackupLayerThickness
|
|
157
|
+
? value
|
|
158
|
+
: new StackupLayerThickness(value)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
get material(): string | undefined {
|
|
162
|
+
return this._sxMaterial?.value
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
set material(value: string | StackupLayerMaterial | undefined) {
|
|
166
|
+
if (value === undefined) {
|
|
167
|
+
this._sxMaterial = undefined
|
|
168
|
+
return
|
|
169
|
+
}
|
|
170
|
+
this._sxMaterial =
|
|
171
|
+
value instanceof StackupLayerMaterial
|
|
172
|
+
? value
|
|
173
|
+
: new StackupLayerMaterial(value)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
get epsilonR(): number | undefined {
|
|
177
|
+
return this._sxEpsilonR?.value
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
set epsilonR(value: number | StackupLayerEpsilonR | undefined) {
|
|
181
|
+
if (value === undefined) {
|
|
182
|
+
this._sxEpsilonR = undefined
|
|
183
|
+
return
|
|
184
|
+
}
|
|
185
|
+
this._sxEpsilonR =
|
|
186
|
+
value instanceof StackupLayerEpsilonR
|
|
187
|
+
? value
|
|
188
|
+
: new StackupLayerEpsilonR(value)
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
get lossTangent(): number | undefined {
|
|
192
|
+
return this._sxLossTangent?.value
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
set lossTangent(value: number | StackupLayerLossTangent | undefined) {
|
|
196
|
+
if (value === undefined) {
|
|
197
|
+
this._sxLossTangent = undefined
|
|
198
|
+
return
|
|
199
|
+
}
|
|
200
|
+
this._sxLossTangent =
|
|
201
|
+
value instanceof StackupLayerLossTangent
|
|
202
|
+
? value
|
|
203
|
+
: new StackupLayerLossTangent(value)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
override getChildren(): SxClass[] {
|
|
207
|
+
const children: SxClass[] = []
|
|
208
|
+
if (this._sxType) children.push(this._sxType)
|
|
209
|
+
if (this._sxColor) children.push(this._sxColor)
|
|
210
|
+
if (this._sxThickness) children.push(this._sxThickness)
|
|
211
|
+
if (this._sxMaterial) children.push(this._sxMaterial)
|
|
212
|
+
if (this._sxEpsilonR) children.push(this._sxEpsilonR)
|
|
213
|
+
if (this._sxLossTangent) children.push(this._sxLossTangent)
|
|
214
|
+
return children
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
override getString(): string {
|
|
218
|
+
const header = `(layer ${quoteSExprString(this._name)}${
|
|
219
|
+
this._number !== undefined ? ` ${this._number}` : ""
|
|
220
|
+
}`
|
|
221
|
+
const children = this.getChildren()
|
|
222
|
+
if (children.length === 0) {
|
|
223
|
+
return `${header})`
|
|
224
|
+
}
|
|
225
|
+
const lines: string[] = [header]
|
|
226
|
+
for (const child of children) {
|
|
227
|
+
lines.push(child.getStringIndented())
|
|
228
|
+
}
|
|
229
|
+
lines.push(")")
|
|
230
|
+
return lines.join("\n")
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
SxClass.register(StackupLayer)
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { SxClass } from "../../base-classes/SxClass"
|
|
2
|
+
import type { PrimitiveSExpr } from "../../parseToPrimitiveSExpr"
|
|
3
|
+
import { toNumberValue } from "../../utils/toNumberValue"
|
|
4
|
+
|
|
5
|
+
import { SingleValueProperty } from "./base"
|
|
6
|
+
|
|
7
|
+
abstract class StackupLayerProperty<T extends string | number> extends SingleValueProperty<T> {
|
|
8
|
+
static override parentToken = "layer"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class StackupLayerType extends StackupLayerProperty<string> {
|
|
12
|
+
static override token = "type"
|
|
13
|
+
token = "type"
|
|
14
|
+
protected override quoteStringValue = true
|
|
15
|
+
}
|
|
16
|
+
SxClass.register(StackupLayerType)
|
|
17
|
+
|
|
18
|
+
export class StackupLayerColor extends StackupLayerProperty<string> {
|
|
19
|
+
static override token = "color"
|
|
20
|
+
token = "color"
|
|
21
|
+
protected override quoteStringValue = true
|
|
22
|
+
}
|
|
23
|
+
SxClass.register(StackupLayerColor)
|
|
24
|
+
|
|
25
|
+
export class StackupLayerThickness extends StackupLayerProperty<number> {
|
|
26
|
+
static override token = "thickness"
|
|
27
|
+
token = "thickness"
|
|
28
|
+
|
|
29
|
+
protected static override parsePrimitiveValue(
|
|
30
|
+
value: PrimitiveSExpr | undefined,
|
|
31
|
+
): number {
|
|
32
|
+
const parsed = toNumberValue(value)
|
|
33
|
+
if (parsed === undefined) {
|
|
34
|
+
throw new Error("Stackup layer thickness expects a numeric value")
|
|
35
|
+
}
|
|
36
|
+
return parsed
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
SxClass.register(StackupLayerThickness)
|
|
40
|
+
|
|
41
|
+
export class StackupLayerMaterial extends StackupLayerProperty<string> {
|
|
42
|
+
static override token = "material"
|
|
43
|
+
token = "material"
|
|
44
|
+
protected override quoteStringValue = true
|
|
45
|
+
}
|
|
46
|
+
SxClass.register(StackupLayerMaterial)
|
|
47
|
+
|
|
48
|
+
export class StackupLayerEpsilonR extends StackupLayerProperty<number> {
|
|
49
|
+
static override token = "epsilon_r"
|
|
50
|
+
token = "epsilon_r"
|
|
51
|
+
|
|
52
|
+
protected static override parsePrimitiveValue(
|
|
53
|
+
value: PrimitiveSExpr | undefined,
|
|
54
|
+
): number {
|
|
55
|
+
const parsed = toNumberValue(value)
|
|
56
|
+
if (parsed === undefined) {
|
|
57
|
+
throw new Error("Stackup layer epsilon_r expects a numeric value")
|
|
58
|
+
}
|
|
59
|
+
return parsed
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
SxClass.register(StackupLayerEpsilonR)
|
|
63
|
+
|
|
64
|
+
export class StackupLayerLossTangent extends StackupLayerProperty<number> {
|
|
65
|
+
static override token = "loss_tangent"
|
|
66
|
+
token = "loss_tangent"
|
|
67
|
+
|
|
68
|
+
protected static override parsePrimitiveValue(
|
|
69
|
+
value: PrimitiveSExpr | undefined,
|
|
70
|
+
): number {
|
|
71
|
+
const parsed = toNumberValue(value)
|
|
72
|
+
if (parsed === undefined) {
|
|
73
|
+
throw new Error("Stackup layer loss_tangent expects a numeric value")
|
|
74
|
+
}
|
|
75
|
+
return parsed
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
SxClass.register(StackupLayerLossTangent)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { SxClass } from "../../base-classes/SxClass"
|
|
2
|
+
|
|
3
|
+
import { SingleValueProperty } from "./base"
|
|
4
|
+
|
|
5
|
+
abstract class StackupSingleValueProperty<
|
|
6
|
+
T extends string | number,
|
|
7
|
+
> extends SingleValueProperty<T> {
|
|
8
|
+
static override parentToken = "stackup"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class StackupCopperFinish extends StackupSingleValueProperty<string> {
|
|
12
|
+
static override token = "copper_finish"
|
|
13
|
+
token = "copper_finish"
|
|
14
|
+
protected override quoteStringValue = true
|
|
15
|
+
}
|
|
16
|
+
SxClass.register(StackupCopperFinish)
|
|
17
|
+
|
|
18
|
+
export class StackupDielectricConstraints extends StackupSingleValueProperty<string> {
|
|
19
|
+
static override token = "dielectric_constraints"
|
|
20
|
+
token = "dielectric_constraints"
|
|
21
|
+
}
|
|
22
|
+
SxClass.register(StackupDielectricConstraints)
|
|
23
|
+
|
|
24
|
+
export class StackupEdgeConnector extends StackupSingleValueProperty<string> {
|
|
25
|
+
static override token = "edge_connector"
|
|
26
|
+
token = "edge_connector"
|
|
27
|
+
}
|
|
28
|
+
SxClass.register(StackupEdgeConnector)
|
|
29
|
+
|
|
30
|
+
export class StackupCastellatedPads extends StackupSingleValueProperty<string> {
|
|
31
|
+
static override token = "castellated_pads"
|
|
32
|
+
token = "castellated_pads"
|
|
33
|
+
}
|
|
34
|
+
SxClass.register(StackupCastellatedPads)
|
|
35
|
+
|
|
36
|
+
export class StackupEdgePlating extends StackupSingleValueProperty<string> {
|
|
37
|
+
static override token = "edge_plating"
|
|
38
|
+
token = "edge_plating"
|
|
39
|
+
}
|
|
40
|
+
SxClass.register(StackupEdgePlating)
|
|
41
|
+
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { SxClass } from "../../base-classes/SxClass"
|
|
2
|
+
import { quoteSExprString } from "../../utils/quoteSExprString"
|
|
3
|
+
import { toNumberValue } from "../../utils/toNumberValue"
|
|
4
|
+
import { toStringValue } from "../../utils/toStringValue"
|
|
5
|
+
import type { PrimitiveSExpr } from "../../parseToPrimitiveSExpr"
|
|
6
|
+
|
|
7
|
+
type SingleValuePropertyConstructor<T extends string | number> = new (
|
|
8
|
+
value: T,
|
|
9
|
+
) => SingleValueProperty<T>
|
|
10
|
+
|
|
11
|
+
export abstract class SingleValueProperty<
|
|
12
|
+
T extends string | number,
|
|
13
|
+
> extends SxClass {
|
|
14
|
+
protected _value: T
|
|
15
|
+
protected quoteStringValue = false
|
|
16
|
+
|
|
17
|
+
constructor(value: T) {
|
|
18
|
+
super()
|
|
19
|
+
this._value = value
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static override fromSexprPrimitives(
|
|
23
|
+
primitiveSexprs: PrimitiveSExpr[],
|
|
24
|
+
): SingleValueProperty<string | number> {
|
|
25
|
+
const [valuePrimitive] = primitiveSexprs
|
|
26
|
+
const value = (this as typeof SingleValueProperty).parsePrimitiveValue(
|
|
27
|
+
valuePrimitive,
|
|
28
|
+
)
|
|
29
|
+
const Constructor = this as unknown as SingleValuePropertyConstructor<
|
|
30
|
+
string | number
|
|
31
|
+
>
|
|
32
|
+
return new Constructor(value)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
protected static parsePrimitiveValue(
|
|
36
|
+
value: PrimitiveSExpr | undefined,
|
|
37
|
+
): string | number {
|
|
38
|
+
const stringValue = toStringValue(value)
|
|
39
|
+
if (stringValue === undefined) {
|
|
40
|
+
throw new Error(`${this.name} expects a primitive value`)
|
|
41
|
+
}
|
|
42
|
+
return stringValue
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
get value(): T {
|
|
46
|
+
return this._value
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
set value(value: T) {
|
|
50
|
+
this._value = value
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
override getChildren(): SxClass[] {
|
|
54
|
+
return []
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
protected formatValue(): string {
|
|
58
|
+
if (typeof this._value === "string") {
|
|
59
|
+
return this.quoteStringValue
|
|
60
|
+
? quoteSExprString(this._value)
|
|
61
|
+
: this._value
|
|
62
|
+
}
|
|
63
|
+
return `${this._value}`
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
override getString(): string {
|
|
67
|
+
return `(${this.token} ${this.formatValue()})`
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
type NumericListPropertyConstructor = new (
|
|
72
|
+
values: number[],
|
|
73
|
+
) => NumericListProperty
|
|
74
|
+
|
|
75
|
+
export abstract class NumericListProperty extends SxClass {
|
|
76
|
+
protected _values: number[]
|
|
77
|
+
|
|
78
|
+
constructor(values: number[]) {
|
|
79
|
+
super()
|
|
80
|
+
this._values = values
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
static override fromSexprPrimitives(
|
|
84
|
+
primitiveSexprs: PrimitiveSExpr[],
|
|
85
|
+
): NumericListProperty {
|
|
86
|
+
const values = primitiveSexprs.map((primitive) => {
|
|
87
|
+
const value = toNumberValue(primitive)
|
|
88
|
+
if (value === undefined) {
|
|
89
|
+
throw new Error(
|
|
90
|
+
`${this.name} expects numeric primitives but received ${primitive}`,
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
return value
|
|
94
|
+
})
|
|
95
|
+
const Constructor = this as unknown as NumericListPropertyConstructor
|
|
96
|
+
return new Constructor(values)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
get values(): number[] {
|
|
100
|
+
return [...this._values]
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
set values(values: number[]) {
|
|
104
|
+
this._values = [...values]
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
override getChildren(): SxClass[] {
|
|
108
|
+
return []
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
override getString(): string {
|
|
112
|
+
return `(${this.token} ${this._values.join(" ")})`
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
type CoordinatePropertyConstructor = new (
|
|
117
|
+
x: number,
|
|
118
|
+
y: number,
|
|
119
|
+
) => CoordinateProperty
|
|
120
|
+
|
|
121
|
+
export abstract class CoordinateProperty extends SxClass {
|
|
122
|
+
protected _x: number
|
|
123
|
+
protected _y: number
|
|
124
|
+
|
|
125
|
+
constructor(x: number, y: number) {
|
|
126
|
+
super()
|
|
127
|
+
this._x = x
|
|
128
|
+
this._y = y
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
static override fromSexprPrimitives(
|
|
132
|
+
primitiveSexprs: PrimitiveSExpr[],
|
|
133
|
+
): CoordinateProperty {
|
|
134
|
+
const [xPrimitive, yPrimitive] = primitiveSexprs
|
|
135
|
+
const x = toNumberValue(xPrimitive)
|
|
136
|
+
const y = toNumberValue(yPrimitive)
|
|
137
|
+
if (x === undefined || y === undefined) {
|
|
138
|
+
throw new Error(`${this.name} expects two numeric values`)
|
|
139
|
+
}
|
|
140
|
+
const Constructor = this as unknown as CoordinatePropertyConstructor
|
|
141
|
+
return new Constructor(x, y)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
get x(): number {
|
|
145
|
+
return this._x
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
set x(value: number) {
|
|
149
|
+
this._x = value
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
get y(): number {
|
|
153
|
+
return this._y
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
set y(value: number) {
|
|
157
|
+
this._y = value
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
override getChildren(): SxClass[] {
|
|
161
|
+
return []
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
override getString(): string {
|
|
165
|
+
return `(${this.token} ${this._x} ${this._y})`
|
|
166
|
+
}
|
|
167
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export * from "./Setup"
|
|
2
|
+
export * from "./Stackup"
|
|
3
|
+
export * from "./StackupLayer"
|
|
4
|
+
export * from "./StackupProperties"
|
|
5
|
+
export * from "./StackupLayerProperties"
|
|
6
|
+
export * from "./PcbPlotParams"
|
|
7
|
+
export * from "./PcbPlotParamsBase"
|
|
8
|
+
export * from "./PcbPlotParamsNumericProperties"
|
|
9
|
+
export * from "./PcbPlotParamsStringPropertiesA"
|
|
10
|
+
export * from "./PcbPlotParamsStringPropertiesB"
|
|
11
|
+
export * from "./setupNumericProperties"
|
|
12
|
+
export * from "./setupMultiValueProperties"
|
|
13
|
+
export * from "./setupStringProperties"
|
|
14
|
+
export * from "./SetupPropertyTypes"
|