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,341 @@
1
+ import { SxClass } from "../base-classes/SxClass"
2
+ import { printSExpr, type PrimitiveSExpr } from "../parseToPrimitiveSExpr"
3
+ import { quoteSExprString } from "../utils/quoteSExprString"
4
+ import { toStringValue } from "../utils/toStringValue"
5
+ import { At } from "./At"
6
+ import { Layer } from "./Layer"
7
+ import { TextEffects } from "./TextEffects"
8
+ import { Uuid } from "./Uuid"
9
+ import { Xy } from "./Xy"
10
+
11
+ export type FpTextType = "reference" | "value" | "user" | string
12
+
13
+ const SUPPORTED_SINGLE_TOKENS = new Set([
14
+ "at",
15
+ "xy",
16
+ "layer",
17
+ "effects",
18
+ "uuid",
19
+ "unlocked",
20
+ "hide",
21
+ ])
22
+
23
+ const SUPPORTED_MULTI_TOKENS = new Set<string>()
24
+
25
+ export class FpText extends SxClass {
26
+ static override token = "fp_text"
27
+ token = "fp_text"
28
+
29
+ private _type?: FpTextType
30
+ private _text = ""
31
+ private _sxPosition?: At | Xy
32
+ private _sxUnlocked?: FpTextUnlocked
33
+ private _sxHide?: FpTextHide
34
+ private _sxLayer?: Layer
35
+ private _sxEffects?: TextEffects
36
+ private _sxUuid?: Uuid
37
+
38
+ static override fromSexprPrimitives(
39
+ primitiveSexprs: PrimitiveSExpr[],
40
+ ): FpText {
41
+ if (primitiveSexprs.length < 2) {
42
+ throw new Error("fp_text requires a type and text value")
43
+ }
44
+
45
+ const [rawType, rawText, ...rest] = primitiveSexprs
46
+ const fpText = new FpText()
47
+
48
+ if (typeof rawType !== "string") {
49
+ throw new Error(
50
+ `fp_text type must be a string token, received ${JSON.stringify(rawType)}`,
51
+ )
52
+ }
53
+ fpText._type = rawType
54
+
55
+ fpText._text = primitiveToString(rawText)
56
+
57
+ const structuredPrimitives: PrimitiveSExpr[] = []
58
+ let sawBareUnlocked = false
59
+ let sawBareHide = false
60
+
61
+ for (const primitive of rest) {
62
+ if (typeof primitive === "string") {
63
+ if (primitive === "unlocked") {
64
+ if (sawBareUnlocked) {
65
+ throw new Error("fp_text encountered duplicate bare unlocked tokens")
66
+ }
67
+ sawBareUnlocked = true
68
+ continue
69
+ }
70
+ if (primitive === "hide") {
71
+ if (sawBareHide) {
72
+ throw new Error("fp_text encountered duplicate bare hide tokens")
73
+ }
74
+ sawBareHide = true
75
+ continue
76
+ }
77
+ throw new Error(
78
+ `fp_text encountered unsupported flag "${primitive}"`,
79
+ )
80
+ }
81
+
82
+ if (!Array.isArray(primitive) || primitive.length === 0) {
83
+ throw new Error(
84
+ `fp_text encountered invalid child expression: ${JSON.stringify(primitive)}`,
85
+ )
86
+ }
87
+
88
+ structuredPrimitives.push(primitive)
89
+ }
90
+
91
+ const { propertyMap, arrayPropertyMap } =
92
+ SxClass.parsePrimitivesToClassProperties(structuredPrimitives, this.token)
93
+
94
+ for (const token of Object.keys(propertyMap)) {
95
+ if (!SUPPORTED_SINGLE_TOKENS.has(token)) {
96
+ throw new Error(
97
+ `fp_text encountered unsupported child token "${token}"`,
98
+ )
99
+ }
100
+ }
101
+
102
+ for (const [token, entries] of Object.entries(arrayPropertyMap)) {
103
+ if (!SUPPORTED_SINGLE_TOKENS.has(token)) {
104
+ throw new Error(
105
+ `fp_text encountered unsupported child token "${token}"`,
106
+ )
107
+ }
108
+ if (!SUPPORTED_MULTI_TOKENS.has(token) && entries.length > 1) {
109
+ throw new Error(
110
+ `fp_text does not support repeated child token "${token}"`,
111
+ )
112
+ }
113
+ }
114
+
115
+ const atInstance = propertyMap.at as At | undefined
116
+ const xyInstance = propertyMap.xy as Xy | undefined
117
+ if (atInstance && xyInstance) {
118
+ throw new Error("fp_text cannot include both at and xy child tokens")
119
+ }
120
+
121
+ fpText._sxPosition = atInstance ?? xyInstance
122
+ fpText._sxLayer = propertyMap.layer as Layer | undefined
123
+ fpText._sxEffects = propertyMap.effects as TextEffects | undefined
124
+ fpText._sxUuid = propertyMap.uuid as Uuid | undefined
125
+
126
+ const unlockedEntry = propertyMap.unlocked as FpTextUnlocked | undefined
127
+ const hideEntry = propertyMap.hide as FpTextHide | undefined
128
+
129
+ if (unlockedEntry && sawBareUnlocked) {
130
+ throw new Error(
131
+ "fp_text encountered both bare and structured unlocked tokens",
132
+ )
133
+ }
134
+ if (hideEntry && sawBareHide) {
135
+ throw new Error(
136
+ "fp_text encountered both bare and structured hide tokens",
137
+ )
138
+ }
139
+
140
+ fpText._sxUnlocked = unlockedEntry
141
+ fpText._sxHide = hideEntry
142
+
143
+ if (sawBareUnlocked) {
144
+ fpText._sxUnlocked = new FpTextUnlocked({ value: true, bare: true })
145
+ }
146
+ if (sawBareHide) {
147
+ fpText._sxHide = new FpTextHide({ value: true, bare: true })
148
+ }
149
+
150
+ return fpText
151
+ }
152
+
153
+ get type(): FpTextType | undefined {
154
+ return this._type
155
+ }
156
+
157
+ set type(value: FpTextType | undefined) {
158
+ this._type = value
159
+ }
160
+
161
+ get text(): string {
162
+ return this._text
163
+ }
164
+
165
+ set text(value: string) {
166
+ this._text = value
167
+ }
168
+
169
+ get position(): At | Xy | undefined {
170
+ return this._sxPosition
171
+ }
172
+
173
+ set position(value: At | Xy | undefined) {
174
+ this._sxPosition = value
175
+ }
176
+
177
+ get unlocked(): boolean {
178
+ return this._sxUnlocked?.value ?? false
179
+ }
180
+
181
+ set unlocked(value: boolean) {
182
+ this._sxUnlocked = value
183
+ ? new FpTextUnlocked({ value: true, bare: true })
184
+ : undefined
185
+ }
186
+
187
+ get hidden(): boolean {
188
+ return this._sxHide?.value ?? false
189
+ }
190
+
191
+ set hidden(value: boolean) {
192
+ this._sxHide = value
193
+ ? new FpTextHide({ value: true, bare: true })
194
+ : undefined
195
+ }
196
+
197
+ get layer(): Layer | undefined {
198
+ return this._sxLayer
199
+ }
200
+
201
+ set layer(value: Layer | string | string[] | undefined) {
202
+ if (value === undefined) {
203
+ this._sxLayer = undefined
204
+ return
205
+ }
206
+ if (value instanceof Layer) {
207
+ this._sxLayer = value
208
+ } else {
209
+ const names = Array.isArray(value) ? value : [value]
210
+ this._sxLayer = new Layer(names)
211
+ }
212
+ }
213
+
214
+ get effects(): TextEffects | undefined {
215
+ return this._sxEffects
216
+ }
217
+
218
+ set effects(value: TextEffects | undefined) {
219
+ this._sxEffects = value
220
+ }
221
+
222
+ get uuid(): Uuid | undefined {
223
+ return this._sxUuid
224
+ }
225
+
226
+ set uuid(value: Uuid | string | undefined) {
227
+ if (value === undefined) {
228
+ this._sxUuid = undefined
229
+ return
230
+ }
231
+ this._sxUuid = value instanceof Uuid ? value : new Uuid(value)
232
+ }
233
+
234
+ override getChildren(): SxClass[] {
235
+ const children: SxClass[] = []
236
+ if (this._sxPosition) children.push(this._sxPosition)
237
+ if (this._sxUnlocked) children.push(this._sxUnlocked)
238
+ if (this._sxLayer) children.push(this._sxLayer)
239
+ if (this._sxHide) children.push(this._sxHide)
240
+ if (this._sxEffects) children.push(this._sxEffects)
241
+ if (this._sxUuid) children.push(this._sxUuid)
242
+ return children
243
+ }
244
+
245
+ override getString(): string {
246
+ const lines = ["(fp_text"]
247
+
248
+ if (this._type !== undefined) {
249
+ lines.push(` ${this._type}`)
250
+ }
251
+
252
+ lines.push(` ${quoteSExprString(this._text)}`)
253
+
254
+ for (const child of this.getChildren()) {
255
+ lines.push(child.getStringIndented())
256
+ }
257
+
258
+ lines.push(")")
259
+ return lines.join("\n")
260
+ }
261
+ }
262
+ SxClass.register(FpText)
263
+
264
+ function primitiveToString(value: PrimitiveSExpr | undefined): string {
265
+ if (value === undefined) return ""
266
+ const str = toStringValue(value)
267
+ if (str !== undefined) return str
268
+ return printSExpr(value)
269
+ }
270
+
271
+ class FpTextUnlocked extends SxClass {
272
+ static override token = "unlocked"
273
+ static override parentToken = "fp_text"
274
+ token = "unlocked"
275
+
276
+ value: boolean
277
+ private readonly renderBare: boolean
278
+
279
+ constructor(options: { value?: boolean; bare?: boolean } = {}) {
280
+ super()
281
+ this.value = options.value ?? true
282
+ this.renderBare = options.bare ?? false
283
+ }
284
+
285
+ static override fromSexprPrimitives(
286
+ primitiveSexprs: PrimitiveSExpr[],
287
+ ): FpTextUnlocked {
288
+ const [raw] = primitiveSexprs
289
+ const rawString = toStringValue(raw)
290
+ const value = rawString === undefined ? true : !/^(no|false)$/iu.test(rawString)
291
+ return new FpTextUnlocked({ value, bare: false })
292
+ }
293
+
294
+ override getChildren(): SxClass[] {
295
+ return []
296
+ }
297
+
298
+ override getString(): string {
299
+ if (this.renderBare) {
300
+ return "unlocked"
301
+ }
302
+ return `(unlocked ${this.value ? "yes" : "no"})`
303
+ }
304
+ }
305
+ SxClass.register(FpTextUnlocked)
306
+
307
+ class FpTextHide extends SxClass {
308
+ static override token = "hide"
309
+ static override parentToken = "fp_text"
310
+ token = "hide"
311
+
312
+ value: boolean
313
+ private readonly renderBare: boolean
314
+
315
+ constructor(options: { value?: boolean; bare?: boolean } = {}) {
316
+ super()
317
+ this.value = options.value ?? true
318
+ this.renderBare = options.bare ?? false
319
+ }
320
+
321
+ static override fromSexprPrimitives(
322
+ primitiveSexprs: PrimitiveSExpr[],
323
+ ): FpTextHide {
324
+ const [raw] = primitiveSexprs
325
+ const rawString = toStringValue(raw)
326
+ const value = rawString === undefined ? true : !/^(no|false)$/iu.test(rawString)
327
+ return new FpTextHide({ value, bare: false })
328
+ }
329
+
330
+ override getChildren(): SxClass[] {
331
+ return []
332
+ }
333
+
334
+ override getString(): string {
335
+ if (this.renderBare) {
336
+ return "hide"
337
+ }
338
+ return `(hide ${this.value ? "yes" : "no"})`
339
+ }
340
+ }
341
+ SxClass.register(FpTextHide)