@tscircuit/props 0.0.707 → 0.0.709
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/README.md +2 -0
- package/dist/index.d.ts +15539 -13994
- package/dist/index.js +1959 -1743
- package/dist/index.js.map +1 -1
- package/lib/assembly/drawing/index.ts +15 -0
- package/lib/assembly/drawing/page-size.ts +37 -0
- package/lib/assembly/drawing/page.ts +64 -0
- package/lib/assembly/drawing/partview.ts +118 -0
- package/lib/assembly/drawing/titleblock.ts +43 -0
- package/lib/assembly/index.ts +3 -0
- package/lib/components/analogtransientsimulation.ts +120 -1
- package/package.json +1 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { assemblyDrawingTitleBlockProps } from "./titleblock"
|
|
2
|
+
import { assemblyDrawingPageProps } from "./page"
|
|
3
|
+
import { assemblyDrawingPartViewProps } from "./partview"
|
|
4
|
+
|
|
5
|
+
export * from "./page"
|
|
6
|
+
export * from "./page-size"
|
|
7
|
+
export * from "./titleblock"
|
|
8
|
+
export * from "./partview"
|
|
9
|
+
|
|
10
|
+
/** Drawing namespace; pages contain configured part views. */
|
|
11
|
+
export const assemblyDrawingProps = {
|
|
12
|
+
page: assemblyDrawingPageProps,
|
|
13
|
+
titleblock: assemblyDrawingTitleBlockProps,
|
|
14
|
+
partview: assemblyDrawingPartViewProps,
|
|
15
|
+
} as const
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { z } from "zod"
|
|
2
|
+
|
|
3
|
+
/** Landscape dimensions in mm. ISO A-series / ASME Y14.1 decimal-inch sheets. */
|
|
4
|
+
export const assemblyDrawingPageSizes = {
|
|
5
|
+
iso_a0: [1189, 841],
|
|
6
|
+
iso_a1: [841, 594],
|
|
7
|
+
iso_a2: [594, 420],
|
|
8
|
+
iso_a3: [420, 297],
|
|
9
|
+
iso_a4: [297, 210],
|
|
10
|
+
ansi_a: [279.4, 215.9],
|
|
11
|
+
ansi_b: [431.8, 279.4],
|
|
12
|
+
ansi_c: [558.8, 431.8],
|
|
13
|
+
ansi_d: [863.6, 558.8],
|
|
14
|
+
ansi_e: [1117.6, 863.6],
|
|
15
|
+
} as const
|
|
16
|
+
export const assemblyDrawingPageSize = z.enum([
|
|
17
|
+
"iso_a0",
|
|
18
|
+
"iso_a1",
|
|
19
|
+
"iso_a2",
|
|
20
|
+
"iso_a3",
|
|
21
|
+
"iso_a4",
|
|
22
|
+
"ansi_a",
|
|
23
|
+
"ansi_b",
|
|
24
|
+
"ansi_c",
|
|
25
|
+
"ansi_d",
|
|
26
|
+
"ansi_e",
|
|
27
|
+
])
|
|
28
|
+
export type AssemblyDrawingPageSize = z.infer<typeof assemblyDrawingPageSize>
|
|
29
|
+
export function getAssemblyDrawingPageDimensions(
|
|
30
|
+
size: AssemblyDrawingPageSize,
|
|
31
|
+
orientation: "landscape" | "portrait" = "landscape",
|
|
32
|
+
) {
|
|
33
|
+
const [width, height] = assemblyDrawingPageSizes[size]
|
|
34
|
+
return orientation === "portrait"
|
|
35
|
+
? { width: height, height: width }
|
|
36
|
+
: { width, height }
|
|
37
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { z } from "zod"
|
|
2
|
+
import {
|
|
3
|
+
assemblyDrawingPageSize,
|
|
4
|
+
getAssemblyDrawingPageDimensions,
|
|
5
|
+
type AssemblyDrawingPageSize,
|
|
6
|
+
} from "./page-size"
|
|
7
|
+
import { distance } from "circuit-json"
|
|
8
|
+
import type { Distance } from "lib/common/distance"
|
|
9
|
+
import { expectTypesMatch } from "lib/typecheck"
|
|
10
|
+
|
|
11
|
+
/** A paper-space drawing page containing configured part views. */
|
|
12
|
+
export interface AssemblyDrawingPageProps {
|
|
13
|
+
name?: string
|
|
14
|
+
displayName?: string
|
|
15
|
+
/** Standard sheet size; landscape by default. Mutually exclusive with width/height. */
|
|
16
|
+
size?: AssemblyDrawingPageSize
|
|
17
|
+
orientation?: "landscape" | "portrait"
|
|
18
|
+
/** Custom paper dimensions in mm when numeric; unit strings are accepted. */
|
|
19
|
+
width?: Distance
|
|
20
|
+
height?: Distance
|
|
21
|
+
children?: any
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const assemblyDrawingPageProps = z
|
|
25
|
+
.object({
|
|
26
|
+
name: z.string().optional(),
|
|
27
|
+
displayName: z.string().optional(),
|
|
28
|
+
size: assemblyDrawingPageSize.optional(),
|
|
29
|
+
orientation: z.enum(["landscape", "portrait"]).optional(),
|
|
30
|
+
width: distance.pipe(z.number().finite().positive()).optional(),
|
|
31
|
+
height: distance.pipe(z.number().finite().positive()).optional(),
|
|
32
|
+
children: z.any().optional(),
|
|
33
|
+
})
|
|
34
|
+
.superRefine((page, ctx) => {
|
|
35
|
+
if (
|
|
36
|
+
page.size
|
|
37
|
+
? page.width != null || page.height != null
|
|
38
|
+
: page.width == null || page.height == null
|
|
39
|
+
)
|
|
40
|
+
ctx.addIssue({
|
|
41
|
+
code: "custom",
|
|
42
|
+
message: "Specify size or both width and height, exclusively",
|
|
43
|
+
})
|
|
44
|
+
if (!page.size && page.orientation)
|
|
45
|
+
ctx.addIssue({
|
|
46
|
+
code: "custom",
|
|
47
|
+
path: ["orientation"],
|
|
48
|
+
message: "Orientation requires a standard size",
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
.transform((page) => ({
|
|
52
|
+
...page,
|
|
53
|
+
...(page.size
|
|
54
|
+
? getAssemblyDrawingPageDimensions(page.size, page.orientation)
|
|
55
|
+
: { width: page.width!, height: page.height! }),
|
|
56
|
+
}))
|
|
57
|
+
|
|
58
|
+
export type InferredAssemblyDrawingPageProps = z.input<
|
|
59
|
+
typeof assemblyDrawingPageProps
|
|
60
|
+
>
|
|
61
|
+
expectTypesMatch<
|
|
62
|
+
AssemblyDrawingPageProps,
|
|
63
|
+
z.input<typeof assemblyDrawingPageProps>
|
|
64
|
+
>(true)
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { z } from "zod"
|
|
2
|
+
import { distance } from "circuit-json"
|
|
3
|
+
import type { Distance } from "lib/common/distance"
|
|
4
|
+
import { expectTypesMatch } from "lib/typecheck"
|
|
5
|
+
|
|
6
|
+
/** Axis names use tscircuit CAD coordinates: mm, +Z up. The camera sits on
|
|
7
|
+
* the named side of the model and looks toward its center. */
|
|
8
|
+
export type AssemblyDrawingPartViewDirection =
|
|
9
|
+
| "x+"
|
|
10
|
+
| "x-"
|
|
11
|
+
| "y+"
|
|
12
|
+
| "y-"
|
|
13
|
+
| "z+"
|
|
14
|
+
| "z-"
|
|
15
|
+
| "isometric"
|
|
16
|
+
|
|
17
|
+
export interface AssemblyDrawingSectionPlane {
|
|
18
|
+
axis: "x" | "y" | "z"
|
|
19
|
+
/** Plane coordinate in CAD world space, numeric mm or a distance string. */
|
|
20
|
+
offset: Distance
|
|
21
|
+
/** Retain coordinates <= offset or >= offset, respectively. */
|
|
22
|
+
keepSide: "less" | "greater"
|
|
23
|
+
/** Physical distance between 45-degree strokes on the model. Defaults to 1mm. */
|
|
24
|
+
hatchSpacing?: Distance
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const assemblyDrawingSectionPlane = z.object({
|
|
28
|
+
axis: z.enum(["x", "y", "z"]),
|
|
29
|
+
offset: distance.pipe(z.number().finite()),
|
|
30
|
+
keepSide: z.enum(["less", "greater"]),
|
|
31
|
+
hatchSpacing: distance.pipe(z.number().finite().positive()).default(1),
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
/** An orthographic viewport within an assembly.drawing.page. */
|
|
35
|
+
export interface AssemblyDrawingPartViewProps {
|
|
36
|
+
name?: string
|
|
37
|
+
displayName?: string
|
|
38
|
+
/** Selector for the board, group or assembly geometry shown in this view. */
|
|
39
|
+
partRef: string
|
|
40
|
+
direction: AssemblyDrawingPartViewDirection
|
|
41
|
+
/** Viewport center relative to the paper center, mm; +X right, +Y up. Defaults to 0 on axes without a relative reference. */
|
|
42
|
+
centerX?: Distance
|
|
43
|
+
centerY?: Distance
|
|
44
|
+
/** Sibling part-view selector; infer centerX with this viewport left of the reference. Conflicts with rightOfRef and centerX. */
|
|
45
|
+
leftOfRef?: string
|
|
46
|
+
/** Sibling part-view selector; infer centerX with this viewport right of the reference. Conflicts with leftOfRef and centerX. */
|
|
47
|
+
rightOfRef?: string
|
|
48
|
+
/** Sibling part-view selector; infer centerY with this viewport above the reference. Conflicts with belowRef and centerY. */
|
|
49
|
+
aboveRef?: string
|
|
50
|
+
/** Sibling part-view selector; infer centerY with this viewport below the reference. Conflicts with aboveRef and centerY. */
|
|
51
|
+
belowRef?: string
|
|
52
|
+
/** Paper-space viewport size; dimensions must be positive. */
|
|
53
|
+
width: Distance
|
|
54
|
+
height: Distance
|
|
55
|
+
/** Draw obscured edges as dashed strokes. Defaults to false. */
|
|
56
|
+
showHiddenEdges?: boolean
|
|
57
|
+
/** A planar cut with diagonal hatching on closed cut surfaces. */
|
|
58
|
+
section?: AssemblyDrawingSectionPlane
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const assemblyDrawingPartViewProps = z
|
|
62
|
+
.object({
|
|
63
|
+
name: z.string().optional(),
|
|
64
|
+
displayName: z.string().optional(),
|
|
65
|
+
partRef: z.string().min(1),
|
|
66
|
+
direction: z.enum(["x+", "x-", "y+", "y-", "z+", "z-", "isometric"]),
|
|
67
|
+
centerX: distance.pipe(z.number().finite()).optional(),
|
|
68
|
+
centerY: distance.pipe(z.number().finite()).optional(),
|
|
69
|
+
leftOfRef: z.string().trim().min(1).optional(),
|
|
70
|
+
rightOfRef: z.string().trim().min(1).optional(),
|
|
71
|
+
aboveRef: z.string().trim().min(1).optional(),
|
|
72
|
+
belowRef: z.string().trim().min(1).optional(),
|
|
73
|
+
width: distance.pipe(z.number().finite().positive()),
|
|
74
|
+
height: distance.pipe(z.number().finite().positive()),
|
|
75
|
+
showHiddenEdges: z.boolean().default(false),
|
|
76
|
+
section: assemblyDrawingSectionPlane.optional(),
|
|
77
|
+
})
|
|
78
|
+
.superRefine((view, ctx) => {
|
|
79
|
+
for (const [center, negative, positive] of [
|
|
80
|
+
["centerX", "leftOfRef", "rightOfRef"],
|
|
81
|
+
["centerY", "belowRef", "aboveRef"],
|
|
82
|
+
] as const) {
|
|
83
|
+
if (view[negative] !== undefined && view[positive] !== undefined)
|
|
84
|
+
ctx.addIssue({
|
|
85
|
+
code: "custom",
|
|
86
|
+
path: [positive],
|
|
87
|
+
message: `${negative} and ${positive} are mutually exclusive`,
|
|
88
|
+
})
|
|
89
|
+
if (
|
|
90
|
+
view[center] !== undefined &&
|
|
91
|
+
(view[negative] !== undefined || view[positive] !== undefined)
|
|
92
|
+
)
|
|
93
|
+
ctx.addIssue({
|
|
94
|
+
code: "custom",
|
|
95
|
+
path: [center],
|
|
96
|
+
message: `${center} cannot be combined with ${negative} or ${positive}`,
|
|
97
|
+
})
|
|
98
|
+
}
|
|
99
|
+
})
|
|
100
|
+
.transform((view) => ({
|
|
101
|
+
...view,
|
|
102
|
+
...(view.leftOfRef || view.rightOfRef
|
|
103
|
+
? {}
|
|
104
|
+
: { centerX: view.centerX ?? 0 }),
|
|
105
|
+
...(view.aboveRef || view.belowRef ? {} : { centerY: view.centerY ?? 0 }),
|
|
106
|
+
}))
|
|
107
|
+
|
|
108
|
+
export type InferredAssemblyDrawingPartViewProps = z.input<
|
|
109
|
+
typeof assemblyDrawingPartViewProps
|
|
110
|
+
>
|
|
111
|
+
expectTypesMatch<
|
|
112
|
+
AssemblyDrawingSectionPlane,
|
|
113
|
+
z.input<typeof assemblyDrawingSectionPlane>
|
|
114
|
+
>(true)
|
|
115
|
+
expectTypesMatch<
|
|
116
|
+
AssemblyDrawingPartViewProps,
|
|
117
|
+
z.input<typeof assemblyDrawingPartViewProps>
|
|
118
|
+
>(true)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { z } from "zod"
|
|
2
|
+
import { expectTypesMatch } from "lib/typecheck"
|
|
3
|
+
|
|
4
|
+
/** Optional page child. Metadata fields reference ISO 7200:2004. */
|
|
5
|
+
export interface AssemblyDrawingTitleBlockProps {
|
|
6
|
+
name?: string
|
|
7
|
+
title: string
|
|
8
|
+
legalOwner?: string
|
|
9
|
+
identificationNumber?: string
|
|
10
|
+
revisionIndex?: string
|
|
11
|
+
dateOfIssue?: string
|
|
12
|
+
creator?: string
|
|
13
|
+
approvalPerson?: string
|
|
14
|
+
sheetNumber?: number
|
|
15
|
+
numberOfSheets?: number
|
|
16
|
+
}
|
|
17
|
+
export const assemblyDrawingTitleBlockProps = z
|
|
18
|
+
.object({
|
|
19
|
+
name: z.string().optional(),
|
|
20
|
+
title: z.string().min(1),
|
|
21
|
+
legalOwner: z.string().optional(),
|
|
22
|
+
identificationNumber: z.string().optional(),
|
|
23
|
+
revisionIndex: z.string().optional(),
|
|
24
|
+
dateOfIssue: z.string().optional(),
|
|
25
|
+
creator: z.string().optional(),
|
|
26
|
+
approvalPerson: z.string().optional(),
|
|
27
|
+
sheetNumber: z.number().int().positive().optional(),
|
|
28
|
+
numberOfSheets: z.number().int().positive().optional(),
|
|
29
|
+
})
|
|
30
|
+
.refine(
|
|
31
|
+
(block) =>
|
|
32
|
+
block.sheetNumber == null ||
|
|
33
|
+
block.numberOfSheets == null ||
|
|
34
|
+
block.sheetNumber <= block.numberOfSheets,
|
|
35
|
+
{
|
|
36
|
+
message: "sheetNumber must not exceed numberOfSheets",
|
|
37
|
+
path: ["sheetNumber"],
|
|
38
|
+
},
|
|
39
|
+
)
|
|
40
|
+
expectTypesMatch<
|
|
41
|
+
AssemblyDrawingTitleBlockProps,
|
|
42
|
+
z.input<typeof assemblyDrawingTitleBlockProps>
|
|
43
|
+
>(true)
|
package/lib/assembly/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { assemblyDrawingProps } from "./drawing"
|
|
1
2
|
import { assemblyCadAssemblyProps } from "./cadassembly"
|
|
2
3
|
import { assemblyCableProps } from "./cable"
|
|
3
4
|
import { assemblyBoltProps } from "./bolt"
|
|
@@ -11,6 +12,7 @@ import { assemblyScreenProps } from "./screen"
|
|
|
11
12
|
import { assemblySubassemblyProps } from "./subassembly"
|
|
12
13
|
import { assemblyExplosionProps } from "./explosion"
|
|
13
14
|
|
|
15
|
+
export * from "./drawing"
|
|
14
16
|
export * from "./board-mounting"
|
|
15
17
|
export * from "./bolt"
|
|
16
18
|
export * from "./fastener"
|
|
@@ -26,6 +28,7 @@ export * from "./cadassembly"
|
|
|
26
28
|
export * from "./explosion"
|
|
27
29
|
|
|
28
30
|
export const assemblyProps = {
|
|
31
|
+
drawing: assemblyDrawingProps,
|
|
29
32
|
explosion: assemblyExplosionProps,
|
|
30
33
|
bolt: assemblyBoltProps,
|
|
31
34
|
fastener: assemblyFastenerProps,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ms } from "circuit-json"
|
|
1
|
+
import { frequency, length, ms } from "circuit-json"
|
|
2
2
|
import { expectTypesMatch } from "lib/typecheck"
|
|
3
3
|
import { z } from "zod"
|
|
4
4
|
import { ibisPinRunState, type IbisPinRunState } from "lib/common/ibis"
|
|
@@ -17,8 +17,119 @@ export interface AnalogTransientSimulationProps
|
|
|
17
17
|
timePerStep?: number | string
|
|
18
18
|
/** Physical pin selectors and per-experiment direction/enable states. Requires spiceEngine="pcb_spice"; rendering only declares the experiment. */
|
|
19
19
|
ibisPinStates?: Record<string, IbisPinRunState>
|
|
20
|
+
pcbSpiceChannel?: PcbSpiceChannelProps
|
|
20
21
|
}
|
|
21
22
|
|
|
23
|
+
export interface PcbSpiceChannelProps {
|
|
24
|
+
reduction: "routed-copper" | "straightened-stages"
|
|
25
|
+
sections: number
|
|
26
|
+
lanes: Array<{ name: string; from: string; to: string }>
|
|
27
|
+
referencePinRef: string
|
|
28
|
+
passiveComponentRefs?: string[]
|
|
29
|
+
extraction: {
|
|
30
|
+
minimumFrequency: number | string
|
|
31
|
+
maximumFrequency: number | string
|
|
32
|
+
modelFrequency: number | string
|
|
33
|
+
filaments: number
|
|
34
|
+
refinementFilaments: number
|
|
35
|
+
convergenceTolerance: number
|
|
36
|
+
capacitanceTolerance: number
|
|
37
|
+
reciprocityTolerance: number
|
|
38
|
+
dcResistanceTolerance: number
|
|
39
|
+
maxPanelLength: number | string
|
|
40
|
+
groundMeshSize?: number | string
|
|
41
|
+
}
|
|
42
|
+
relativePermittivity?: number
|
|
43
|
+
via?: {
|
|
44
|
+
platingThickness?: number | string
|
|
45
|
+
equivalentWidth?: number | string
|
|
46
|
+
omitThroughViaStubs?: boolean
|
|
47
|
+
}
|
|
48
|
+
straightenedStageProfiles?: Record<
|
|
49
|
+
string,
|
|
50
|
+
{
|
|
51
|
+
spacing: number | string
|
|
52
|
+
relativePermittivity: number
|
|
53
|
+
return: {
|
|
54
|
+
width: number | string
|
|
55
|
+
thickness: number | string
|
|
56
|
+
lengthFactor: number
|
|
57
|
+
centerY: number | string
|
|
58
|
+
centerZ: number | string
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
>
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const positiveLength = length.pipe(z.number().finite().positive())
|
|
65
|
+
const signedLength = length.pipe(z.number().finite())
|
|
66
|
+
const positiveFrequency = frequency.pipe(z.number().finite().positive())
|
|
67
|
+
|
|
68
|
+
export const pcbSpiceChannelProps = z.object({
|
|
69
|
+
reduction: z.enum(["routed-copper", "straightened-stages"]),
|
|
70
|
+
sections: z.number().int().min(1).max(128),
|
|
71
|
+
lanes: z
|
|
72
|
+
.array(
|
|
73
|
+
z.object({
|
|
74
|
+
name: z.string().min(1),
|
|
75
|
+
from: z.string().min(1),
|
|
76
|
+
to: z.string().min(1),
|
|
77
|
+
}),
|
|
78
|
+
)
|
|
79
|
+
.min(1)
|
|
80
|
+
.max(3),
|
|
81
|
+
referencePinRef: z.string().min(1),
|
|
82
|
+
passiveComponentRefs: z.array(z.string().min(1)).optional(),
|
|
83
|
+
extraction: z
|
|
84
|
+
.object({
|
|
85
|
+
minimumFrequency: positiveFrequency,
|
|
86
|
+
maximumFrequency: positiveFrequency,
|
|
87
|
+
modelFrequency: positiveFrequency,
|
|
88
|
+
filaments: z.number().int().positive(),
|
|
89
|
+
refinementFilaments: z.number().int().positive(),
|
|
90
|
+
convergenceTolerance: z.number().finite().positive(),
|
|
91
|
+
capacitanceTolerance: z.number().finite().positive(),
|
|
92
|
+
reciprocityTolerance: z.number().finite().positive(),
|
|
93
|
+
dcResistanceTolerance: z.number().finite().positive(),
|
|
94
|
+
maxPanelLength: positiveLength,
|
|
95
|
+
groundMeshSize: positiveLength.optional(),
|
|
96
|
+
})
|
|
97
|
+
.refine(
|
|
98
|
+
(extraction) => extraction.refinementFilaments > extraction.filaments,
|
|
99
|
+
{
|
|
100
|
+
path: ["refinementFilaments"],
|
|
101
|
+
message: "refinementFilaments must be greater than filaments",
|
|
102
|
+
},
|
|
103
|
+
),
|
|
104
|
+
relativePermittivity: z.number().finite().positive().optional(),
|
|
105
|
+
via: z
|
|
106
|
+
.object({
|
|
107
|
+
platingThickness: positiveLength.optional(),
|
|
108
|
+
equivalentWidth: positiveLength.optional(),
|
|
109
|
+
omitThroughViaStubs: z.boolean().optional(),
|
|
110
|
+
})
|
|
111
|
+
.optional(),
|
|
112
|
+
straightenedStageProfiles: z
|
|
113
|
+
.record(
|
|
114
|
+
z.object({
|
|
115
|
+
spacing: positiveLength,
|
|
116
|
+
relativePermittivity: z.number().finite().positive(),
|
|
117
|
+
return: z.object({
|
|
118
|
+
width: positiveLength,
|
|
119
|
+
thickness: positiveLength,
|
|
120
|
+
lengthFactor: z.number().finite().positive(),
|
|
121
|
+
centerY: signedLength,
|
|
122
|
+
centerZ: signedLength,
|
|
123
|
+
}),
|
|
124
|
+
}),
|
|
125
|
+
)
|
|
126
|
+
.optional(),
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
expectTypesMatch<PcbSpiceChannelProps, z.input<typeof pcbSpiceChannelProps>>(
|
|
130
|
+
true,
|
|
131
|
+
)
|
|
132
|
+
|
|
22
133
|
const positiveMilliseconds = ms.refine(
|
|
23
134
|
(milliseconds) => milliseconds > 0,
|
|
24
135
|
"Time must be positive",
|
|
@@ -30,9 +141,17 @@ export const analogTransientSimulationProps = z
|
|
|
30
141
|
duration: positiveMilliseconds.default("10ms"),
|
|
31
142
|
startTime: ms.default("0ms"),
|
|
32
143
|
timePerStep: positiveMilliseconds.default("0.01ms"),
|
|
144
|
+
pcbSpiceChannel: pcbSpiceChannelProps.optional(),
|
|
33
145
|
ibisPinStates: z.record(z.string().min(1), ibisPinRunState).optional(),
|
|
34
146
|
})
|
|
35
147
|
.superRefine((simulation, context) => {
|
|
148
|
+
if (simulation.pcbSpiceChannel && simulation.spiceEngine !== "pcb_spice") {
|
|
149
|
+
context.addIssue({
|
|
150
|
+
code: z.ZodIssueCode.custom,
|
|
151
|
+
path: ["pcbSpiceChannel"],
|
|
152
|
+
message: "PCB SPICE channel settings require spiceEngine=pcb_spice",
|
|
153
|
+
})
|
|
154
|
+
}
|
|
36
155
|
if (simulation.ibisPinStates && simulation.spiceEngine !== "pcb_spice") {
|
|
37
156
|
context.addIssue({
|
|
38
157
|
code: z.ZodIssueCode.custom,
|