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.
Files changed (188) hide show
  1. package/.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc +111 -0
  2. package/.vscode/settings.json +16 -0
  3. package/AGENTS.md +30 -0
  4. package/README.md +206 -0
  5. package/biome.json +93 -0
  6. package/bun.lock +48 -0
  7. package/bunfig.toml +5 -0
  8. package/lib/index.ts +1 -0
  9. package/lib/sexpr/base-classes/SxClass.ts +164 -0
  10. package/lib/sexpr/base-classes/SxPrimitiveBoolean.ts +35 -0
  11. package/lib/sexpr/base-classes/SxPrimitiveNumber.ts +26 -0
  12. package/lib/sexpr/base-classes/SxPrimitiveString.ts +26 -0
  13. package/lib/sexpr/classes/At.ts +38 -0
  14. package/lib/sexpr/classes/Bus.ts +83 -0
  15. package/lib/sexpr/classes/BusEntry.ts +142 -0
  16. package/lib/sexpr/classes/Color.ts +29 -0
  17. package/lib/sexpr/classes/Dnp.ts +8 -0
  18. package/lib/sexpr/classes/EmbeddedFonts.ts +70 -0
  19. package/lib/sexpr/classes/ExcludeFromSim.ts +8 -0
  20. package/lib/sexpr/classes/FieldsAutoplaced.ts +8 -0
  21. package/lib/sexpr/classes/Footprint.ts +719 -0
  22. package/lib/sexpr/classes/FootprintAttr.ts +102 -0
  23. package/lib/sexpr/classes/FootprintAutoplaceCost180.ts +9 -0
  24. package/lib/sexpr/classes/FootprintAutoplaceCost90.ts +9 -0
  25. package/lib/sexpr/classes/FootprintClearance.ts +9 -0
  26. package/lib/sexpr/classes/FootprintDescr.ts +44 -0
  27. package/lib/sexpr/classes/FootprintLocked.ts +32 -0
  28. package/lib/sexpr/classes/FootprintModel.ts +145 -0
  29. package/lib/sexpr/classes/FootprintNetTiePadGroups.ts +50 -0
  30. package/lib/sexpr/classes/FootprintPad.ts +705 -0
  31. package/lib/sexpr/classes/FootprintPath.ts +44 -0
  32. package/lib/sexpr/classes/FootprintPlaced.ts +32 -0
  33. package/lib/sexpr/classes/FootprintPrivateLayers.ts +56 -0
  34. package/lib/sexpr/classes/FootprintSheetfile.ts +44 -0
  35. package/lib/sexpr/classes/FootprintSheetname.ts +44 -0
  36. package/lib/sexpr/classes/FootprintSolderMaskMargin.ts +9 -0
  37. package/lib/sexpr/classes/FootprintSolderPasteMargin.ts +9 -0
  38. package/lib/sexpr/classes/FootprintSolderPasteRatio.ts +9 -0
  39. package/lib/sexpr/classes/FootprintTags.ts +44 -0
  40. package/lib/sexpr/classes/FootprintTedit.ts +21 -0
  41. package/lib/sexpr/classes/FootprintThermalGap.ts +9 -0
  42. package/lib/sexpr/classes/FootprintThermalWidth.ts +9 -0
  43. package/lib/sexpr/classes/FootprintZoneConnect.ts +9 -0
  44. package/lib/sexpr/classes/FpArc.ts +289 -0
  45. package/lib/sexpr/classes/FpCircle.ts +293 -0
  46. package/lib/sexpr/classes/FpLine.ts +288 -0
  47. package/lib/sexpr/classes/FpPoly.ts +266 -0
  48. package/lib/sexpr/classes/FpPolyFill.ts +48 -0
  49. package/lib/sexpr/classes/FpPolyLocked.ts +40 -0
  50. package/lib/sexpr/classes/FpRect.ts +293 -0
  51. package/lib/sexpr/classes/FpText.ts +341 -0
  52. package/lib/sexpr/classes/FpTextBox.ts +412 -0
  53. package/lib/sexpr/classes/GrLine.ts +245 -0
  54. package/lib/sexpr/classes/GrLineAngle.ts +32 -0
  55. package/lib/sexpr/classes/GrLineEnd.ts +61 -0
  56. package/lib/sexpr/classes/GrLineLocked.ts +40 -0
  57. package/lib/sexpr/classes/GrLineStart.ts +61 -0
  58. package/lib/sexpr/classes/GrText.ts +202 -0
  59. package/lib/sexpr/classes/Image.ts +256 -0
  60. package/lib/sexpr/classes/InBom.ts +8 -0
  61. package/lib/sexpr/classes/Junction.ts +134 -0
  62. package/lib/sexpr/classes/KicadPcb.ts +313 -0
  63. package/lib/sexpr/classes/KicadSch.ts +303 -0
  64. package/lib/sexpr/classes/KicadSchGenerator.ts +32 -0
  65. package/lib/sexpr/classes/KicadSchGeneratorVersion.ts +30 -0
  66. package/lib/sexpr/classes/KicadSchVersion.ts +22 -0
  67. package/lib/sexpr/classes/Label.ts +136 -0
  68. package/lib/sexpr/classes/Layer.ts +51 -0
  69. package/lib/sexpr/classes/Layers.ts +47 -0
  70. package/lib/sexpr/classes/LibSymbols.ts +61 -0
  71. package/lib/sexpr/classes/NoConnect.ts +73 -0
  72. package/lib/sexpr/classes/OnBoard.ts +8 -0
  73. package/lib/sexpr/classes/PadChamfer.ts +50 -0
  74. package/lib/sexpr/classes/PadChamferRatio.ts +9 -0
  75. package/lib/sexpr/classes/PadClearance.ts +9 -0
  76. package/lib/sexpr/classes/PadDieLength.ts +9 -0
  77. package/lib/sexpr/classes/PadDrill.ts +145 -0
  78. package/lib/sexpr/classes/PadDrillOffset.ts +54 -0
  79. package/lib/sexpr/classes/PadLayers.ts +59 -0
  80. package/lib/sexpr/classes/PadNet.ts +56 -0
  81. package/lib/sexpr/classes/PadOptions.ts +182 -0
  82. package/lib/sexpr/classes/PadPinFunction.ts +9 -0
  83. package/lib/sexpr/classes/PadPinType.ts +9 -0
  84. package/lib/sexpr/classes/PadPrimitiveGrArc.ts +254 -0
  85. package/lib/sexpr/classes/PadPrimitiveGrCircle.ts +279 -0
  86. package/lib/sexpr/classes/PadPrimitiveGrLine.ts +126 -0
  87. package/lib/sexpr/classes/PadPrimitives.ts +289 -0
  88. package/lib/sexpr/classes/PadRectDelta.ts +57 -0
  89. package/lib/sexpr/classes/PadRoundrectRratio.ts +9 -0
  90. package/lib/sexpr/classes/PadSize.ts +54 -0
  91. package/lib/sexpr/classes/PadSolderMaskMargin.ts +9 -0
  92. package/lib/sexpr/classes/PadSolderPasteMargin.ts +9 -0
  93. package/lib/sexpr/classes/PadSolderPasteMarginRatio.ts +9 -0
  94. package/lib/sexpr/classes/PadTeardrops.ts +208 -0
  95. package/lib/sexpr/classes/PadThermalBridgeAngle.ts +9 -0
  96. package/lib/sexpr/classes/PadThermalGap.ts +9 -0
  97. package/lib/sexpr/classes/PadThermalWidth.ts +9 -0
  98. package/lib/sexpr/classes/PadZoneConnect.ts +9 -0
  99. package/lib/sexpr/classes/Paper.ts +119 -0
  100. package/lib/sexpr/classes/PcbGeneral.ts +75 -0
  101. package/lib/sexpr/classes/PcbGeneralLegacyTeardrops.ts +44 -0
  102. package/lib/sexpr/classes/PcbGeneralThickness.ts +9 -0
  103. package/lib/sexpr/classes/PcbGenerator.ts +16 -0
  104. package/lib/sexpr/classes/PcbGeneratorVersion.ts +16 -0
  105. package/lib/sexpr/classes/PcbLayerDefinition.ts +102 -0
  106. package/lib/sexpr/classes/PcbLayers.ts +34 -0
  107. package/lib/sexpr/classes/PcbNet.ts +56 -0
  108. package/lib/sexpr/classes/PcbVersion.ts +9 -0
  109. package/lib/sexpr/classes/Property.ts +246 -0
  110. package/lib/sexpr/classes/PropertyHide.ts +9 -0
  111. package/lib/sexpr/classes/PropertyUnlocked.ts +9 -0
  112. package/lib/sexpr/classes/Pts.ts +65 -0
  113. package/lib/sexpr/classes/RenderCache.ts +221 -0
  114. package/lib/sexpr/classes/SchematicText.ts +141 -0
  115. package/lib/sexpr/classes/Segment.ts +222 -0
  116. package/lib/sexpr/classes/SegmentEnd.ts +59 -0
  117. package/lib/sexpr/classes/SegmentLocked.ts +33 -0
  118. package/lib/sexpr/classes/SegmentNet.ts +62 -0
  119. package/lib/sexpr/classes/SegmentStart.ts +59 -0
  120. package/lib/sexpr/classes/Setup/PcbPlotParams.ts +729 -0
  121. package/lib/sexpr/classes/Setup/PcbPlotParamsBase.ts +9 -0
  122. package/lib/sexpr/classes/Setup/PcbPlotParamsNumericProperties.ts +105 -0
  123. package/lib/sexpr/classes/Setup/PcbPlotParamsStringPropertiesA.ts +104 -0
  124. package/lib/sexpr/classes/Setup/PcbPlotParamsStringPropertiesB.ts +105 -0
  125. package/lib/sexpr/classes/Setup/Setup.ts +573 -0
  126. package/lib/sexpr/classes/Setup/SetupPropertyTypes.ts +119 -0
  127. package/lib/sexpr/classes/Setup/Stackup.ts +140 -0
  128. package/lib/sexpr/classes/Setup/StackupLayer.ts +233 -0
  129. package/lib/sexpr/classes/Setup/StackupLayerProperties.ts +78 -0
  130. package/lib/sexpr/classes/Setup/StackupProperties.ts +41 -0
  131. package/lib/sexpr/classes/Setup/base.ts +167 -0
  132. package/lib/sexpr/classes/Setup/index.ts +14 -0
  133. package/lib/sexpr/classes/Setup/setupMultiValueProperties.ts +54 -0
  134. package/lib/sexpr/classes/Setup/setupNumericProperties.ts +151 -0
  135. package/lib/sexpr/classes/Setup/setupPropertyHandlers.ts +90 -0
  136. package/lib/sexpr/classes/Setup/setupStringProperties.ts +75 -0
  137. package/lib/sexpr/classes/Sheet.ts +205 -0
  138. package/lib/sexpr/classes/SheetFill.ts +44 -0
  139. package/lib/sexpr/classes/SheetInstances.ts +168 -0
  140. package/lib/sexpr/classes/SheetInstancesRoot.ts +165 -0
  141. package/lib/sexpr/classes/SheetPin.ts +122 -0
  142. package/lib/sexpr/classes/SheetProperty.ts +115 -0
  143. package/lib/sexpr/classes/SheetSize.ts +44 -0
  144. package/lib/sexpr/classes/Stroke.ts +58 -0
  145. package/lib/sexpr/classes/StrokeType.ts +34 -0
  146. package/lib/sexpr/classes/Symbol.ts +1541 -0
  147. package/lib/sexpr/classes/TextEffects.ts +444 -0
  148. package/lib/sexpr/classes/TitleBlock.ts +352 -0
  149. package/lib/sexpr/classes/Unit.ts +28 -0
  150. package/lib/sexpr/classes/Uuid.ts +8 -0
  151. package/lib/sexpr/classes/Via.ts +328 -0
  152. package/lib/sexpr/classes/ViaNet.ts +59 -0
  153. package/lib/sexpr/classes/Width.ts +8 -0
  154. package/lib/sexpr/classes/Wire.ts +91 -0
  155. package/lib/sexpr/classes/Xy.ts +35 -0
  156. package/lib/sexpr/classes/Zone.ts +41 -0
  157. package/lib/sexpr/index.ts +130 -0
  158. package/lib/sexpr/parseKicadSexpr.ts +5 -0
  159. package/lib/sexpr/parseToPrimitiveSExpr.ts +240 -0
  160. package/lib/sexpr/utils/indentLines.ts +3 -0
  161. package/lib/sexpr/utils/parseYesNo.ts +12 -0
  162. package/lib/sexpr/utils/quoteSExprString.ts +8 -0
  163. package/lib/sexpr/utils/strokeFromArgs.ts +19 -0
  164. package/lib/sexpr/utils/toNumberValue.ts +13 -0
  165. package/lib/sexpr/utils/toStringValue.ts +10 -0
  166. package/package.json +26 -0
  167. package/scripts/download-references.ts +66 -0
  168. package/tests/fixtures/expectEqualPrimitiveSExpr.ts +200 -0
  169. package/tests/sexpr/KicadPcbDemos.test.ts +48 -0
  170. package/tests/sexpr/KicadSchDemos.test.ts +49 -0
  171. package/tests/sexpr/classes/Footprint.test.ts +277 -0
  172. package/tests/sexpr/classes/FootprintPad.test.ts +71 -0
  173. package/tests/sexpr/classes/FpArc.test.ts +45 -0
  174. package/tests/sexpr/classes/FpCircle.test.ts +39 -0
  175. package/tests/sexpr/classes/FpPoly.test.ts +43 -0
  176. package/tests/sexpr/classes/FpRect.test.ts +40 -0
  177. package/tests/sexpr/classes/FpTextBox.test.ts +84 -0
  178. package/tests/sexpr/classes/Image.test.ts +50 -0
  179. package/tests/sexpr/classes/KicadSch.test.ts +97 -0
  180. package/tests/sexpr/classes/Paper.test.ts +30 -0
  181. package/tests/sexpr/classes/Property.test.ts +48 -0
  182. package/tests/sexpr/classes/Setup.test.ts +189 -0
  183. package/tests/sexpr/classes/Sheet.test.ts +107 -0
  184. package/tests/sexpr/classes/Stroke.test.ts +15 -0
  185. package/tests/sexpr/classes/Symbol.test.ts +96 -0
  186. package/tests/sexpr/classes/TextEffects.test.ts +56 -0
  187. package/tests/sexpr/classes/TitleBlock.test.ts +40 -0
  188. 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"