@vessel-dsp/compiler 0.0.0-stage → 0.3.0
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 +118 -2
- package/dist/bake.d.ts +38 -0
- package/dist/bake.d.ts.map +1 -0
- package/dist/bake.js +101 -0
- package/dist/bake.js.map +1 -0
- package/dist/bbd-clock.d.ts +171 -0
- package/dist/bbd-clock.d.ts.map +1 -0
- package/dist/bbd-clock.js +1750 -0
- package/dist/bbd-clock.js.map +1 -0
- package/dist/block-row.d.ts +51 -0
- package/dist/block-row.d.ts.map +1 -0
- package/dist/block-row.js +17 -0
- package/dist/block-row.js.map +1 -0
- package/dist/bypass.d.ts +3 -0
- package/dist/bypass.d.ts.map +1 -0
- package/dist/bypass.js +228 -0
- package/dist/bypass.js.map +1 -0
- package/dist/compile.d.ts +24 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +348 -0
- package/dist/compile.js.map +1 -0
- package/dist/converter-scale.d.ts +14 -0
- package/dist/converter-scale.d.ts.map +1 -0
- package/dist/converter-scale.js +133 -0
- package/dist/converter-scale.js.map +1 -0
- package/dist/couple.d.ts +28 -0
- package/dist/couple.d.ts.map +1 -0
- package/dist/couple.js +567 -0
- package/dist/couple.js.map +1 -0
- package/dist/dangling-active-terminal.d.ts +47 -0
- package/dist/dangling-active-terminal.d.ts.map +1 -0
- package/dist/dangling-active-terminal.js +542 -0
- package/dist/dangling-active-terminal.js.map +1 -0
- package/dist/declared-program.d.ts +23 -0
- package/dist/declared-program.d.ts.map +1 -0
- package/dist/declared-program.js +387 -0
- package/dist/declared-program.js.map +1 -0
- package/dist/denomination.d.ts +48 -0
- package/dist/denomination.d.ts.map +1 -0
- package/dist/denomination.js +27 -0
- package/dist/denomination.js.map +1 -0
- package/dist/device-laws.d.ts +237 -0
- package/dist/device-laws.d.ts.map +1 -0
- package/dist/device-laws.js +3513 -0
- package/dist/device-laws.js.map +1 -0
- package/dist/diagnostics.d.ts +13 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +19 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/emit.d.ts +8 -0
- package/dist/emit.d.ts.map +1 -0
- package/dist/emit.js +43 -0
- package/dist/emit.js.map +1 -0
- package/dist/errors.d.ts +22 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +39 -0
- package/dist/errors.js.map +1 -0
- package/dist/firmware-class.d.ts +69 -0
- package/dist/firmware-class.d.ts.map +1 -0
- package/dist/firmware-class.js +20 -0
- package/dist/firmware-class.js.map +1 -0
- package/dist/fixtures/circuits.d.ts +1742 -0
- package/dist/fixtures/circuits.d.ts.map +1 -0
- package/dist/fixtures/circuits.js +13896 -0
- package/dist/fixtures/circuits.js.map +1 -0
- package/dist/fixtures/expected.d.ts +261 -0
- package/dist/fixtures/expected.d.ts.map +1 -0
- package/dist/fixtures/expected.js +315 -0
- package/dist/fixtures/expected.js.map +1 -0
- package/dist/fixtures/index.d.ts +4 -0
- package/dist/fixtures/index.d.ts.map +1 -0
- package/dist/fixtures/index.js +8 -0
- package/dist/fixtures/index.js.map +1 -0
- package/dist/fixtures/registry.d.ts +52 -0
- package/dist/fixtures/registry.d.ts.map +1 -0
- package/dist/fixtures/registry.js +341 -0
- package/dist/fixtures/registry.js.map +1 -0
- package/dist/generic-tube-fit.d.ts +12 -0
- package/dist/generic-tube-fit.d.ts.map +1 -0
- package/dist/generic-tube-fit.js +45 -0
- package/dist/generic-tube-fit.js.map +1 -0
- package/dist/grounded-clock-supply.d.ts +13 -0
- package/dist/grounded-clock-supply.d.ts.map +1 -0
- package/dist/grounded-clock-supply.js +45 -0
- package/dist/grounded-clock-supply.js.map +1 -0
- package/dist/identify.d.ts +50 -0
- package/dist/identify.d.ts.map +1 -0
- package/dist/identify.js +319 -0
- package/dist/identify.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/inert-controls.d.ts +15 -0
- package/dist/inert-controls.d.ts.map +1 -0
- package/dist/inert-controls.js +266 -0
- package/dist/inert-controls.js.map +1 -0
- package/dist/latch-seed.d.ts +53 -0
- package/dist/latch-seed.d.ts.map +1 -0
- package/dist/latch-seed.js +257 -0
- package/dist/latch-seed.js.map +1 -0
- package/dist/link.d.ts +7 -0
- package/dist/link.d.ts.map +1 -0
- package/dist/link.js +270 -0
- package/dist/link.js.map +1 -0
- package/dist/lower.d.ts +79 -0
- package/dist/lower.d.ts.map +1 -0
- package/dist/lower.js +1855 -0
- package/dist/lower.js.map +1 -0
- package/dist/netlist.d.ts +79 -0
- package/dist/netlist.d.ts.map +1 -0
- package/dist/netlist.js +4746 -0
- package/dist/netlist.js.map +1 -0
- package/dist/non-executable-clock-drivers.d.ts +8 -0
- package/dist/non-executable-clock-drivers.d.ts.map +1 -0
- package/dist/non-executable-clock-drivers.js +33 -0
- package/dist/non-executable-clock-drivers.js.map +1 -0
- package/dist/open-category.d.ts +98 -0
- package/dist/open-category.d.ts.map +1 -0
- package/dist/open-category.js +111 -0
- package/dist/open-category.js.map +1 -0
- package/dist/over-driven-node.d.ts +33 -0
- package/dist/over-driven-node.d.ts.map +1 -0
- package/dist/over-driven-node.js +188 -0
- package/dist/over-driven-node.js.map +1 -0
- package/dist/part-catalog.d.ts +15 -0
- package/dist/part-catalog.d.ts.map +1 -0
- package/dist/part-catalog.js +6712 -0
- package/dist/part-catalog.js.map +1 -0
- package/dist/part-number.d.ts +32 -0
- package/dist/part-number.d.ts.map +1 -0
- package/dist/part-number.js +80 -0
- package/dist/part-number.js.map +1 -0
- package/dist/partition.d.ts +7 -0
- package/dist/partition.d.ts.map +1 -0
- package/dist/partition.js +242 -0
- package/dist/partition.js.map +1 -0
- package/dist/port-full-scale.d.ts +70 -0
- package/dist/port-full-scale.d.ts.map +1 -0
- package/dist/port-full-scale.js +235 -0
- package/dist/port-full-scale.js.map +1 -0
- package/dist/pot-orientation.d.ts +114 -0
- package/dist/pot-orientation.d.ts.map +1 -0
- package/dist/pot-orientation.js +551 -0
- package/dist/pot-orientation.js.map +1 -0
- package/dist/power-domain-control.d.ts +40 -0
- package/dist/power-domain-control.d.ts.map +1 -0
- package/dist/power-domain-control.js +142 -0
- package/dist/power-domain-control.js.map +1 -0
- package/dist/proxy-declaration.d.ts +121 -0
- package/dist/proxy-declaration.d.ts.map +1 -0
- package/dist/proxy-declaration.js +50 -0
- package/dist/proxy-declaration.js.map +1 -0
- package/dist/registry.d.ts +323 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +192 -0
- package/dist/registry.js.map +1 -0
- package/dist/sparse-schedule.d.ts +65 -0
- package/dist/sparse-schedule.d.ts.map +1 -0
- package/dist/sparse-schedule.js +421 -0
- package/dist/sparse-schedule.js.map +1 -0
- package/dist/speaker-load.d.ts +38 -0
- package/dist/speaker-load.d.ts.map +1 -0
- package/dist/speaker-load.js +97 -0
- package/dist/speaker-load.js.map +1 -0
- package/dist/stage-coverage.d.ts +21 -0
- package/dist/stage-coverage.d.ts.map +1 -0
- package/dist/stage-coverage.js +124 -0
- package/dist/stage-coverage.js.map +1 -0
- package/dist/stamp-partition.d.ts +314 -0
- package/dist/stamp-partition.d.ts.map +1 -0
- package/dist/stamp-partition.js +472 -0
- package/dist/stamp-partition.js.map +1 -0
- package/dist/supply-reference.d.ts +19 -0
- package/dist/supply-reference.d.ts.map +1 -0
- package/dist/supply-reference.js +66 -0
- package/dist/supply-reference.js.map +1 -0
- package/dist/supply-short.d.ts +32 -0
- package/dist/supply-short.d.ts.map +1 -0
- package/dist/supply-short.js +118 -0
- package/dist/supply-short.js.map +1 -0
- package/dist/supply-stamps.d.ts +51 -0
- package/dist/supply-stamps.d.ts.map +1 -0
- package/dist/supply-stamps.js +363 -0
- package/dist/supply-stamps.js.map +1 -0
- package/dist/terminal-role.d.ts +109 -0
- package/dist/terminal-role.d.ts.map +1 -0
- package/dist/terminal-role.js +46 -0
- package/dist/terminal-role.js.map +1 -0
- package/dist/terminal-roles.d.ts +59 -0
- package/dist/terminal-roles.d.ts.map +1 -0
- package/dist/terminal-roles.js +92 -0
- package/dist/terminal-roles.js.map +1 -0
- package/dist/transformer.d.ts +181 -0
- package/dist/transformer.d.ts.map +1 -0
- package/dist/transformer.js +476 -0
- package/dist/transformer.js.map +1 -0
- package/dist/types.d.ts +3157 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/dist/unbounded-operating-point.d.ts +35 -0
- package/dist/unbounded-operating-point.d.ts.map +1 -0
- package/dist/unbounded-operating-point.js +181 -0
- package/dist/unbounded-operating-point.js.map +1 -0
- package/dist/unexecuted-region.d.ts +3 -0
- package/dist/unexecuted-region.d.ts.map +1 -0
- package/dist/unexecuted-region.js +122 -0
- package/dist/unexecuted-region.js.map +1 -0
- package/dist/unimplemented-control-role.d.ts +3 -0
- package/dist/unimplemented-control-role.d.ts.map +1 -0
- package/dist/unimplemented-control-role.js +61 -0
- package/dist/unimplemented-control-role.js.map +1 -0
- package/dist/unreachable-output.d.ts +3 -0
- package/dist/unreachable-output.d.ts.map +1 -0
- package/dist/unreachable-output.js +97 -0
- package/dist/unreachable-output.js.map +1 -0
- package/dist/unreadable-terminal-role.d.ts +67 -0
- package/dist/unreadable-terminal-role.d.ts.map +1 -0
- package/dist/unreadable-terminal-role.js +409 -0
- package/dist/unreadable-terminal-role.js.map +1 -0
- package/dist/unverified-pinout.d.ts +27 -0
- package/dist/unverified-pinout.d.ts.map +1 -0
- package/dist/unverified-pinout.js +121 -0
- package/dist/unverified-pinout.js.map +1 -0
- package/package.json +75 -5
package/dist/compile.js
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
// The pipeline: `.vdsp` source text -> a program, or an explanation of the refusal.
|
|
2
|
+
//
|
|
3
|
+
// Seven stages, composed. The registry is a parameter rather than an import, so the
|
|
4
|
+
// compiler holds no knowledge of any specific part -- and compiling with an empty
|
|
5
|
+
// registry is a legitimate configuration that measures what works with no part
|
|
6
|
+
// knowledge at all.
|
|
7
|
+
import { attachDeviceLaws, composeMacroBlocks, findElectricallyIsolatedIcs, findIcsNotExecuted, findUnimplementedDeviceLaws, JFET_DEFAULT_THRESHOLD_VOLTS, JFET_DEFAULT_TRANSCONDUCTANCE, SILICON_FORWARD_BETA, SILICON_SATURATION_CURRENT, } from "./device-laws.js";
|
|
8
|
+
import { findMultiDeviceShells, findUnreadableTerminalRoles, } from "./unreadable-terminal-role.js";
|
|
9
|
+
import { findUnexecutedRegions } from "./unexecuted-region.js";
|
|
10
|
+
import { deriveBypass } from "./bypass.js";
|
|
11
|
+
import { applyConverterScale } from "./converter-scale.js";
|
|
12
|
+
import { couple } from "./couple.js";
|
|
13
|
+
import { emit } from "./emit.js";
|
|
14
|
+
import { StageRefusal } from "./errors.js";
|
|
15
|
+
import { findInertControls } from "./inert-controls.js";
|
|
16
|
+
import { link } from "./link.js";
|
|
17
|
+
import { lower } from "./lower.js";
|
|
18
|
+
import { readNetlist } from "./netlist.js";
|
|
19
|
+
import { partition } from "./partition.js";
|
|
20
|
+
import { emptyRegistry, registryLawFor } from "./registry.js";
|
|
21
|
+
import { findDanglingActiveTerminals, synthesizeOpampImplicitBias, } from "./dangling-active-terminal.js";
|
|
22
|
+
import { findOverDrivenNodes } from "./over-driven-node.js";
|
|
23
|
+
import { findSupplyShorts } from "./supply-short.js";
|
|
24
|
+
import { findUnreachableOutput } from "./unreachable-output.js";
|
|
25
|
+
import { findPowerDomainControls } from "./power-domain-control.js";
|
|
26
|
+
import { findUnimplementedControlRoles } from "./unimplemented-control-role.js";
|
|
27
|
+
import { findUnverifiedPinoutBindings } from "./unverified-pinout.js";
|
|
28
|
+
import { findGenericTubeFits } from "./generic-tube-fit.js";
|
|
29
|
+
import { findGroundedClockSupplies } from "./grounded-clock-supply.js";
|
|
30
|
+
import { findNonExecutableClockDrivers } from "./non-executable-clock-drivers.js";
|
|
31
|
+
import { GROUND } from "./types.js";
|
|
32
|
+
import { findUnboundedOpamps } from "./unbounded-operating-point.js";
|
|
33
|
+
/**
|
|
34
|
+
* Compile, or explain the refusal. This never throws for a document it cannot use.
|
|
35
|
+
*
|
|
36
|
+
* A stage raises a `StageRefusal` when the *source* does not support a program, and
|
|
37
|
+
* that becomes a result rather than an exception: one malformed packet must not take
|
|
38
|
+
* down a batch, and "could not read the document" is an answer a caller can act on.
|
|
39
|
+
*
|
|
40
|
+
* Anything else propagates. A compiler bug reported as an unsupported pedal would be
|
|
41
|
+
* a wrong answer about someone's circuit, so the catch is deliberately narrow.
|
|
42
|
+
*/
|
|
43
|
+
export function compile(source, options = { registry: emptyRegistry }) {
|
|
44
|
+
try {
|
|
45
|
+
return run(source, options);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
if (!(error instanceof StageRefusal)) {
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
status: "unsupported",
|
|
53
|
+
reasons: [
|
|
54
|
+
{ stage: error.stage, device: error.device, reason: error.message },
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function run(source, options) {
|
|
60
|
+
const netlist = readNetlist(source, {
|
|
61
|
+
inputJack: options.inputJack,
|
|
62
|
+
outputJack: options.outputJack,
|
|
63
|
+
});
|
|
64
|
+
const lawed = attachDeviceLaws(netlist, options.registry ?? emptyRegistry);
|
|
65
|
+
// Decision 1: an unmodellable device makes the whole pedal/amp unsupported, and
|
|
66
|
+
// the refusal names every component and reason rather than the first one.
|
|
67
|
+
const unsupported = lawed.resolutions.filter((resolution) => resolution.outcome === "unsupported");
|
|
68
|
+
if (unsupported.length > 0) {
|
|
69
|
+
return {
|
|
70
|
+
status: "unsupported",
|
|
71
|
+
reasons: unsupported.map((resolution) => ({
|
|
72
|
+
stage: "device-laws",
|
|
73
|
+
device: resolution.device,
|
|
74
|
+
reason: resolution.outcome === "unsupported" ? resolution.reason : "",
|
|
75
|
+
})),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const partitioning = partition(lawed);
|
|
79
|
+
const lowered = lower(partitioning, lawed);
|
|
80
|
+
// Stage 5.5: a macro's `coupled`/`parameter` ports reference other blocks, so wiring them
|
|
81
|
+
// happens once every region has one, not while `lower` is still producing them one at a time.
|
|
82
|
+
// `couple` also corrects the dependency graph's audio-out edge (clause 3, the region
|
|
83
|
+
// schedule) -- `link` must sort against that corrected graph, not stage 4's original one, or
|
|
84
|
+
// a coupled seam's downstream side would be free to run before the macro that feeds it.
|
|
85
|
+
const coupled = couple(lowered, partitioning, lawed);
|
|
86
|
+
const bypass = deriveBypass(netlist);
|
|
87
|
+
// Stage 5.75 (board-p3 row 4): the three decomposed models execute as
|
|
88
|
+
// catalog-parameterized compositions. Unconditional since board-p3 row 7 deleted the
|
|
89
|
+
// dispatched kernels: there is no second route to emit, and both runtimes refuse a
|
|
90
|
+
// `macro` block by name rather than execute one.
|
|
91
|
+
const composed = composeMacroBlocks(coupled.blocks);
|
|
92
|
+
const linked = link(composed, { ...partitioning, dependencies: coupled.dependencies }, netlist.controls, netlist.ports, netlist.portImpedanceOhms, netlist.portDeclaredFullScaleVolts, bypass);
|
|
93
|
+
// Stage 6.5: an op-amp the topology leaves genuinely undefined (no DC path back to its
|
|
94
|
+
// inverting input, or none from its non-inverting input to any reference) gets an implicit
|
|
95
|
+
// bias so its operating point is bounded rather than left to whatever `gmin` alone settles
|
|
96
|
+
// into -- see `dangling-active-terminal.ts`'s "implicit op-amp DC-bias synthesis" section.
|
|
97
|
+
// Every later Program-consuming stage below reads the bridged program, because that is the
|
|
98
|
+
// one the runtime will actually execute.
|
|
99
|
+
// Stage 6.75: a composed program between two converters takes their full-scale ratio as its
|
|
100
|
+
// level, or says why it cannot. Read from the catalog by exact part id and found by
|
|
101
|
+
// connectivity, so nothing about it is declared in the document.
|
|
102
|
+
const scaled = applyConverterScale(synthesizeOpampImplicitBias(linked), netlist, options.registry ?? emptyRegistry);
|
|
103
|
+
const program = scaled.program;
|
|
104
|
+
// A program with no blocks has nothing to execute, so calling it `ok` reports a
|
|
105
|
+
// compiled pedal that can only ever render silence. `boss-ps-2` reaches here: its
|
|
106
|
+
// jacks and ground are wired and its 223 electrically active parts declare no
|
|
107
|
+
// terminals, so every one is correctly dropped and nothing is left to solve.
|
|
108
|
+
if (program.blocks.length === 0) {
|
|
109
|
+
return {
|
|
110
|
+
status: "unsupported",
|
|
111
|
+
reasons: [
|
|
112
|
+
{
|
|
113
|
+
stage: "link",
|
|
114
|
+
device: null,
|
|
115
|
+
reason: "no component contributes to the signal path, so the program has nothing to execute",
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
// Strict Admission: Floating wipers or completely disconnected devices are genuine structural
|
|
121
|
+
// defects in the source capture that must be refused. Controls in unscheduled blocks (e.g.
|
|
122
|
+
// unselected channels or scope exclusions documented in packet boundary) remain warnings.
|
|
123
|
+
const inertControls = findInertControls(netlist, program);
|
|
124
|
+
const structuralDefects = inertControls.filter((w) => w.isStructuralDefect);
|
|
125
|
+
if (structuralDefects.length > 0) {
|
|
126
|
+
return {
|
|
127
|
+
status: "unsupported",
|
|
128
|
+
reasons: structuralDefects.map((w) => ({
|
|
129
|
+
stage: "link",
|
|
130
|
+
device: (w.devices && w.devices.length > 0) ? w.devices[0] : null,
|
|
131
|
+
reason: w.detail,
|
|
132
|
+
})),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
// Warnings are computed only for a program that exists and whose controls are connected.
|
|
136
|
+
return {
|
|
137
|
+
status: "ok",
|
|
138
|
+
program,
|
|
139
|
+
warnings: [
|
|
140
|
+
...(netlist.warnings ?? []),
|
|
141
|
+
...inertControls.filter((w) => !w.isStructuralDefect),
|
|
142
|
+
...findUnboundedOpamps(netlist),
|
|
143
|
+
...findSupplyShorts(netlist),
|
|
144
|
+
...findOverDrivenNodes(program),
|
|
145
|
+
...findDanglingActiveTerminals(program),
|
|
146
|
+
...findGroundedClockSupplies(program),
|
|
147
|
+
...findNonExecutableClockDrivers(netlist, options.registry ?? emptyRegistry),
|
|
148
|
+
...findGenericTubeFits(netlist, options.registry ?? emptyRegistry),
|
|
149
|
+
...findUnverifiedPinoutBindings(netlist, options.registry ?? emptyRegistry),
|
|
150
|
+
...findPowerDomainControls(netlist, program.controls ?? [], [netlist.ports.input, netlist.ports.output].filter((node) => typeof node === "number")),
|
|
151
|
+
...findUnimplementedControlRoles(program.controls ?? []),
|
|
152
|
+
...findElectricallyIsolatedIcs(netlist),
|
|
153
|
+
...findIcsNotExecuted(lawed, netlist, options.registry ?? emptyRegistry),
|
|
154
|
+
...findUnreadableTerminalRoles(lawed),
|
|
155
|
+
...findMultiDeviceShells(lawed),
|
|
156
|
+
...findUnimplementedDeviceLaws(lawed),
|
|
157
|
+
...findUnreachableOutput(program, netlist),
|
|
158
|
+
...findUnexecutedRegions(program),
|
|
159
|
+
...findDeclaredDelays(program),
|
|
160
|
+
...findUnmodelledModulation(program),
|
|
161
|
+
...findRailsWithoutVoltage(netlist),
|
|
162
|
+
...findFetLawDefaults(netlist, options.registry ?? emptyRegistry),
|
|
163
|
+
...findBjtLawDefaults(netlist),
|
|
164
|
+
...findOpampLawDefaults(lawed),
|
|
165
|
+
...scaled.warnings,
|
|
166
|
+
],
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Delay macros whose modulation input the part declares and the document wires, but which
|
|
171
|
+
* admission refused -- so the delay is a constant and whatever sweeps it in the real pedal does
|
|
172
|
+
* not reach it.
|
|
173
|
+
*
|
|
174
|
+
* This is the difference between a flanger and a fixed comb filter, and the two compiled to
|
|
175
|
+
* indistinguishable programs. The refusal itself is correct -- gate 1b measured that an
|
|
176
|
+
* LFO-swept clock is a signal rather than a control-rate parameter -- but a correct refusal that
|
|
177
|
+
* nobody is told about renders a pedal doing none of what it is named for.
|
|
178
|
+
*/
|
|
179
|
+
function findUnmodelledModulation(program) {
|
|
180
|
+
return program.blocks.flatMap((block) => (block.kind === "macro" || block.kind === "composed") &&
|
|
181
|
+
typeof block.modulationRefusal === "string"
|
|
182
|
+
? [
|
|
183
|
+
{
|
|
184
|
+
code: "modulation-not-modelled",
|
|
185
|
+
device: null,
|
|
186
|
+
detail: `${block.id} declares a modulation input this document wires, but ` +
|
|
187
|
+
`${block.modulationRefusal}. ` +
|
|
188
|
+
// The consequence is not the same in both cases, and saying the wrong
|
|
189
|
+
// one discredits the warning: a delay that derives from its own clock
|
|
190
|
+
// network still works, it just cannot be swept.
|
|
191
|
+
(block.clockControl != null || block.delayProvenance === "derived"
|
|
192
|
+
? "Its delay still follows its own clock network, but nothing in the " +
|
|
193
|
+
"circuit can sweep it."
|
|
194
|
+
: "Its delay is therefore a constant, and whatever sweeps it in the " +
|
|
195
|
+
"real pedal does not reach it."),
|
|
196
|
+
},
|
|
197
|
+
]
|
|
198
|
+
: []);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Delay macros whose delay time was typed into the source instead of derived from the clock
|
|
202
|
+
* network they are wired to.
|
|
203
|
+
*
|
|
204
|
+
* A derived delay is a consequence of the packet's own R and C: change either and it moves, and
|
|
205
|
+
* a wrong value shows up as a wrong delay. A declared `DelayMs` renders exactly what it says and
|
|
206
|
+
* is therefore unfalsifiable by any render -- which is precisely why it must not pass silently.
|
|
207
|
+
* The two were indistinguishable in the program until now, so a reader could not tell a
|
|
208
|
+
* simulated delay from a reported one.
|
|
209
|
+
*/
|
|
210
|
+
function findDeclaredDelays(program) {
|
|
211
|
+
return program.blocks.flatMap((block) => (block.kind === "macro" || block.kind === "composed") &&
|
|
212
|
+
block.delayProvenance === "declared"
|
|
213
|
+
? [
|
|
214
|
+
{
|
|
215
|
+
code: "declared-delay-not-derived",
|
|
216
|
+
device: null,
|
|
217
|
+
detail: `${block.id} runs ${block.modelId} at ` +
|
|
218
|
+
`${((block.parameters.delaySeconds ?? 0) * 1000).toFixed(1)} ms taken from the ` +
|
|
219
|
+
`source's declared DelayMs, not derived from a clock network: ` +
|
|
220
|
+
`${block.delayDeclaredReason ?? "no reason recorded"}. That number renders ` +
|
|
221
|
+
`whatever it says, so it is not evidence about this circuit's delay time.`,
|
|
222
|
+
},
|
|
223
|
+
]
|
|
224
|
+
: []);
|
|
225
|
+
}
|
|
226
|
+
/** Voltage-less rails that something is connected to. See `RailWithoutVoltageWarning`. */
|
|
227
|
+
function findRailsWithoutVoltage(netlist) {
|
|
228
|
+
const loaded = new Map();
|
|
229
|
+
for (const device of netlist.devices) {
|
|
230
|
+
for (const node of new Set(device.nodes))
|
|
231
|
+
loaded.set(node, (loaded.get(node) ?? 0) + 1);
|
|
232
|
+
}
|
|
233
|
+
return netlist.devices.flatMap((device) => {
|
|
234
|
+
if (device.kind !== "rail")
|
|
235
|
+
return [];
|
|
236
|
+
const volts = device.parameters.volts;
|
|
237
|
+
if (volts !== undefined && Number.isFinite(volts))
|
|
238
|
+
return [];
|
|
239
|
+
const attached = [...new Set(device.nodes)].filter((node) => node !== GROUND && (loaded.get(node) ?? 0) > 1);
|
|
240
|
+
if (attached.length === 0)
|
|
241
|
+
return [];
|
|
242
|
+
return [
|
|
243
|
+
{
|
|
244
|
+
code: "rail-without-voltage",
|
|
245
|
+
device: device.id,
|
|
246
|
+
detail: `${device.id} declares no voltage, so it asserts nothing and lowers open; ` +
|
|
247
|
+
`${attached.length === 1 ? `node ${attached[0]} has` : `nodes ${attached.join(", ")} have`} ` +
|
|
248
|
+
"other devices attached, and they see only gmin to ground. A supply the sheet draws " +
|
|
249
|
+
"there solves at 0 V.",
|
|
250
|
+
},
|
|
251
|
+
];
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
/** JFETs stamped with the fet law's own defaults. See `FetLawDefaultWarning`. */
|
|
255
|
+
function findFetLawDefaults(netlist, registry) {
|
|
256
|
+
const defaulted = netlist.devices.filter((device) => device.kind === "jfet" &&
|
|
257
|
+
(device.parameters.thresholdVolts === undefined ||
|
|
258
|
+
device.parameters.transconductance === undefined) &&
|
|
259
|
+
// A registered part runs on its catalog entry, not the class default --
|
|
260
|
+
// naming it here would claim the opposite. Exact part id only, the same
|
|
261
|
+
// rung `device-laws.ts` refines on.
|
|
262
|
+
registryLawFor(registry, device.identity.partNumber, "fet") === null);
|
|
263
|
+
if (defaulted.length === 0)
|
|
264
|
+
return [];
|
|
265
|
+
const listed = defaulted.map((device) => {
|
|
266
|
+
const missing = [
|
|
267
|
+
device.parameters.thresholdVolts === undefined ? "Vt0" : null,
|
|
268
|
+
device.parameters.transconductance === undefined ? "Beta" : null,
|
|
269
|
+
].filter((name) => name !== null);
|
|
270
|
+
const part = device.identity.partNumber;
|
|
271
|
+
return `${device.id}${part === null ? "" : ` (${part})`} without ${missing.join("/")}`;
|
|
272
|
+
});
|
|
273
|
+
return [
|
|
274
|
+
{
|
|
275
|
+
code: "fet-law-default-parameters",
|
|
276
|
+
device: null,
|
|
277
|
+
devices: defaulted.map((device) => device.id),
|
|
278
|
+
detail: `${defaulted.length} JFET(s) run on the fet law's own defaults ` +
|
|
279
|
+
`(Vt0 ${JFET_DEFAULT_THRESHOLD_VOLTS} V, Beta ${JFET_DEFAULT_TRANSCONDUCTANCE * 1e3} mS), ` +
|
|
280
|
+
`which are not any part's values: ${listed.join("; ")}. Harmless for a switch that is ` +
|
|
281
|
+
"fully on or off; decisive for one biased near its knee.",
|
|
282
|
+
},
|
|
283
|
+
];
|
|
284
|
+
}
|
|
285
|
+
/** BJTs stamped with the bjt law's own defaults. See `BjtLawDefaultWarning`. */
|
|
286
|
+
function findBjtLawDefaults(netlist) {
|
|
287
|
+
const defaulted = netlist.devices.filter((device) => device.kind === "bjt" &&
|
|
288
|
+
(device.parameters.saturationCurrent === undefined ||
|
|
289
|
+
device.parameters.beta === undefined));
|
|
290
|
+
if (defaulted.length === 0)
|
|
291
|
+
return [];
|
|
292
|
+
const listed = defaulted.map((device) => {
|
|
293
|
+
const missing = [
|
|
294
|
+
device.parameters.saturationCurrent === undefined ? "IS" : null,
|
|
295
|
+
device.parameters.beta === undefined ? "BF" : null,
|
|
296
|
+
].filter((name) => name !== null);
|
|
297
|
+
const part = device.identity.partNumber;
|
|
298
|
+
return `${device.id}${part === null ? "" : ` (${part})`} without ${missing.join("/")}`;
|
|
299
|
+
});
|
|
300
|
+
return [
|
|
301
|
+
{
|
|
302
|
+
code: "bjt-law-default-parameters",
|
|
303
|
+
device: null,
|
|
304
|
+
devices: defaulted.map((device) => device.id),
|
|
305
|
+
detail: `${defaulted.length} BJT(s) run on the bjt law's own defaults ` +
|
|
306
|
+
`(IS ${SILICON_SATURATION_CURRENT} A, BF ${SILICON_FORWARD_BETA}), ` +
|
|
307
|
+
`which are not any part's values: ${listed.join("; ")}. Harmless for a saturated ` +
|
|
308
|
+
"switch; decisive for a biased stage.",
|
|
309
|
+
},
|
|
310
|
+
];
|
|
311
|
+
}
|
|
312
|
+
/** Op-amps that state no output-swing drop. See `OpampLawDefaultWarning`. */
|
|
313
|
+
function findOpampLawDefaults(lawed) {
|
|
314
|
+
const byId = new Map(lawed.netlist.devices.map((device) => [device.id, device]));
|
|
315
|
+
const stated = new Map();
|
|
316
|
+
for (const resolution of lawed.resolutions) {
|
|
317
|
+
if (resolution.outcome !== "law" || resolution.law.kind !== "ideal-opamp")
|
|
318
|
+
continue;
|
|
319
|
+
// A section of a package is lowered as `<device>#<index>`; the warning names the device.
|
|
320
|
+
const id = resolution.device.replace(/#\d+$/, "");
|
|
321
|
+
stated.set(id, (stated.get(id) ?? true) && resolution.law.outputSwingDropVolts !== undefined);
|
|
322
|
+
}
|
|
323
|
+
const defaulted = [...stated].flatMap(([id, has]) => (has ? [] : [id]));
|
|
324
|
+
if (defaulted.length === 0)
|
|
325
|
+
return [];
|
|
326
|
+
const listed = defaulted.map((id) => {
|
|
327
|
+
const part = byId.get(id)?.identity.partNumber ?? null;
|
|
328
|
+
return `${id}${part === null ? "" : ` (${part})`}`;
|
|
329
|
+
});
|
|
330
|
+
return [
|
|
331
|
+
{
|
|
332
|
+
code: "opamp-law-default-parameters",
|
|
333
|
+
device: null,
|
|
334
|
+
devices: defaulted,
|
|
335
|
+
detail: `${defaulted.length} op-amp(s) swing the full supply because the part states no ` +
|
|
336
|
+
`output-swing drop: ${listed.join("; ")}. Harmless for a stage that never nears ` +
|
|
337
|
+
"the rails; decisive for a comparator, an LFO or a clipper.",
|
|
338
|
+
},
|
|
339
|
+
];
|
|
340
|
+
}
|
|
341
|
+
export function compileToArtifact(source, options) {
|
|
342
|
+
const result = compile(source, options);
|
|
343
|
+
return {
|
|
344
|
+
result,
|
|
345
|
+
artifact: result.status === "ok" ? emit(result.program) : null,
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
//# sourceMappingURL=compile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile.js","sourceRoot":"","sources":["../src/compile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type PartRegistry } from "./registry";
|
|
2
|
+
import type { ConverterScaleNotModelledWarning, Netlist, Program } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Scale every composed block that sits between two cited converters, and name every one that
|
|
5
|
+
* touches a converter but cannot be scaled.
|
|
6
|
+
*
|
|
7
|
+
* A block no converter touches is left alone and raises nothing: a bucket-brigade composition
|
|
8
|
+
* is analog end to end and has no full scale to be wrong about.
|
|
9
|
+
*/
|
|
10
|
+
export declare function applyConverterScale(program: Program, netlist: Netlist, registry: PartRegistry): {
|
|
11
|
+
readonly program: Program;
|
|
12
|
+
readonly warnings: readonly ConverterScaleNotModelledWarning[];
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=converter-scale.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"converter-scale.d.ts","sourceRoot":"","sources":["../src/converter-scale.ts"],"names":[],"mappings":"AAkBA,OAAO,EAGN,KAAK,YAAY,EACjB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EACX,gCAAgC,EAEhC,OAAO,EAEP,OAAO,EACP,MAAM,SAAS,CAAC;AA4BjB;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAClC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,YAAY,GACpB;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,gCAAgC,EAAE,CAAA;CAAE,CAoG/F"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// Converter full scale: the gain a program between an ADC and a DAC actually has.
|
|
2
|
+
//
|
|
3
|
+
// A composed program runs in volts: its input is the solved voltage at its input node and its
|
|
4
|
+
// output drives its output node in volts. That is exact only when the chip's converters have
|
|
5
|
+
// equal full scales. In the pedal the ADC maps its full scale to digital 1.0 and the DAC maps
|
|
6
|
+
// digital 1.0 back to its own, so the program's volts-to-volts gain is `dac / adc` times
|
|
7
|
+
// whatever the firmware does. The firmware is the program; the ratio is a fact about two parts.
|
|
8
|
+
//
|
|
9
|
+
// **Connectivity, not names.** A converter is the one on the block's input or output node, found
|
|
10
|
+
// by the node the circuit shares with it, and it is a converter because its exact part id has a
|
|
11
|
+
// `converter` entry in the catalog. Nothing is declared in the document.
|
|
12
|
+
//
|
|
13
|
+
// **Unity and a warning, never a guess, when a side is unknown.** The ratio is applied only when
|
|
14
|
+
// both sides are wired and both full scales are cited. Otherwise the program stays unity in volts,
|
|
15
|
+
// which is a level assumption the reader must be told about: `boss-dd-5` sits ~7.5 dB below
|
|
16
|
+
// its own deck for exactly this reason.
|
|
17
|
+
import { canonicalPartId } from "./part-number.js";
|
|
18
|
+
import { foldPartId, } from "./registry.js";
|
|
19
|
+
/** The catalog's converter declaration for a device's exact part id, or null. */
|
|
20
|
+
function converterOf(device, registry) {
|
|
21
|
+
const partNumber = device.identity.partNumber;
|
|
22
|
+
if (partNumber === null)
|
|
23
|
+
return null;
|
|
24
|
+
const canonical = foldPartId(canonicalPartId(partNumber));
|
|
25
|
+
for (const entry of registry.entries) {
|
|
26
|
+
if (entry.converter !== undefined &&
|
|
27
|
+
entry.partIds.some((id) => foldPartId(canonicalPartId(id)) === canonical)) {
|
|
28
|
+
return entry.converter;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
function describe(converter) {
|
|
34
|
+
const fullScale = converter.declaration.fullScaleVoltsPeakToPeak;
|
|
35
|
+
return (`${converter.device.id} ${converter.device.identity.partNumber} ` +
|
|
36
|
+
(fullScale === null ? "(full scale not cited)" : `(${fullScale} Vp-p full scale)`));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Scale every composed block that sits between two cited converters, and name every one that
|
|
40
|
+
* touches a converter but cannot be scaled.
|
|
41
|
+
*
|
|
42
|
+
* A block no converter touches is left alone and raises nothing: a bucket-brigade composition
|
|
43
|
+
* is analog end to end and has no full scale to be wrong about.
|
|
44
|
+
*/
|
|
45
|
+
export function applyConverterScale(program, netlist, registry) {
|
|
46
|
+
const converters = netlist.devices.flatMap((device) => {
|
|
47
|
+
const declaration = converterOf(device, registry);
|
|
48
|
+
return declaration === null ? [] : [{ device, declaration }];
|
|
49
|
+
});
|
|
50
|
+
if (converters.length === 0)
|
|
51
|
+
return { program, warnings: [] };
|
|
52
|
+
// Ports and stamps address MNA rows, not source nodes, so both are translated through the
|
|
53
|
+
// owning block's `nodeIds` before they can be compared with a converter's terminals.
|
|
54
|
+
const sourceNode = new Map();
|
|
55
|
+
const outputNodeOf = new Map();
|
|
56
|
+
for (const block of program.blocks) {
|
|
57
|
+
if (block.kind !== "mna")
|
|
58
|
+
continue;
|
|
59
|
+
sourceNode.set(block.id, block.nodeIds);
|
|
60
|
+
for (const stamp of block.stamps) {
|
|
61
|
+
const node = block.nodeIds[stamp.kind === "macro-audio-source" ? stamp.node : -1];
|
|
62
|
+
if (stamp.kind === "macro-audio-source" && node !== undefined) {
|
|
63
|
+
outputNodeOf.set(stamp.macroId, node);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const on = (node, direction) => node === undefined
|
|
68
|
+
? []
|
|
69
|
+
: converters.filter((converter) => converter.declaration.direction === direction &&
|
|
70
|
+
converter.device.nodes.includes(node));
|
|
71
|
+
const warnings = [];
|
|
72
|
+
const blocks = program.blocks.map((block) => {
|
|
73
|
+
if (block.kind !== "composed")
|
|
74
|
+
return block;
|
|
75
|
+
const adcs = on(block.audioIn === null
|
|
76
|
+
? undefined
|
|
77
|
+
: sourceNode.get(block.audioIn.block)?.[block.audioIn.node], "adc");
|
|
78
|
+
const dacs = on(outputNodeOf.get(block.id), "dac");
|
|
79
|
+
// A reprogrammable chip's program sits behind converters by construction, so in a document
|
|
80
|
+
// that has them its volts-in, volts-out assumption is named even where neither is wired to it.
|
|
81
|
+
if (adcs.length === 0 && dacs.length === 0 && block.modelSource !== "declared")
|
|
82
|
+
return block;
|
|
83
|
+
const adc = adcs.length === 1 ? adcs[0] : undefined;
|
|
84
|
+
const dac = dacs.length === 1 ? dacs[0] : undefined;
|
|
85
|
+
const adcScale = adc?.declaration.fullScaleVoltsPeakToPeak ?? null;
|
|
86
|
+
const dacScale = dac?.declaration.fullScaleVoltsPeakToPeak ?? null;
|
|
87
|
+
if (adcScale !== null && dacScale !== null) {
|
|
88
|
+
const gain = dacScale / adcScale;
|
|
89
|
+
return {
|
|
90
|
+
...block,
|
|
91
|
+
positions: block.positions.map((position) => ({
|
|
92
|
+
...position,
|
|
93
|
+
ops: [
|
|
94
|
+
...position.ops,
|
|
95
|
+
{
|
|
96
|
+
op: "mix",
|
|
97
|
+
terms: [{ source: { kind: "temp", index: position.out }, gain }],
|
|
98
|
+
out: position.ops.length,
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
out: position.ops.length,
|
|
102
|
+
})),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const side = (found, direction, node) => {
|
|
106
|
+
if (found.length === 1)
|
|
107
|
+
return `its ${node} is ${describe(found[0])}`;
|
|
108
|
+
if (found.length > 1) {
|
|
109
|
+
return `its ${node} touches ${found.length} ${direction.toUpperCase()}s (${found.map((c) => c.device.id).join(", ")}), so which one converts is not decidable`;
|
|
110
|
+
}
|
|
111
|
+
const elsewhere = converters.filter((c) => c.declaration.direction === direction);
|
|
112
|
+
return (`its ${node} reaches no ${direction.toUpperCase()}` +
|
|
113
|
+
(elsewhere.length > 0
|
|
114
|
+
? `; ${elsewhere.map(describe).join(" and ")} ${elsewhere.length === 1 ? "is" : "are"} in the document, not wired to it`
|
|
115
|
+
: ""));
|
|
116
|
+
};
|
|
117
|
+
warnings.push({
|
|
118
|
+
code: "converter-scale-not-modelled",
|
|
119
|
+
device: null,
|
|
120
|
+
detail: `${block.id} runs in volts, unity from input to output, but ` +
|
|
121
|
+
`${side(adcs, "adc", "input")}, and ${side(dacs, "dac", "output")}. ` +
|
|
122
|
+
"The pedal's gain there is the DAC's full scale over the ADC's, so the level of " +
|
|
123
|
+
"everything this program outputs is unmodelled by that ratio." +
|
|
124
|
+
[...adcs, ...dacs, ...converters]
|
|
125
|
+
.filter((c, i, all) => all.indexOf(c) === i && c.declaration.fullScaleVoltsPeakToPeak === null)
|
|
126
|
+
.map((c) => ` ${c.device.identity.partNumber}: ${c.declaration.basis}`)
|
|
127
|
+
.join(""),
|
|
128
|
+
});
|
|
129
|
+
return block;
|
|
130
|
+
});
|
|
131
|
+
return { program: { ...program, blocks }, warnings };
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=converter-scale.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"converter-scale.js","sourceRoot":"","sources":["../src/converter-scale.ts"],"names":[],"mappings":"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"}
|
package/dist/couple.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Block, LawedNetlist, Partitioning, Stamp } from "./types";
|
|
2
|
+
export type Coupled = {
|
|
3
|
+
readonly blocks: readonly Block[];
|
|
4
|
+
/**
|
|
5
|
+
* `partitioning.dependencies`, corrected for every macro's audio-out edge -- see this
|
|
6
|
+
* file's header. This is what `link.ts` must sort against instead of the stage-4 graph,
|
|
7
|
+
* so a coupled seam's two sides land in the right order within a sample rather than the
|
|
8
|
+
* downstream side reading last sample's write-back by accident.
|
|
9
|
+
*/
|
|
10
|
+
readonly dependencies: Partitioning["dependencies"];
|
|
11
|
+
};
|
|
12
|
+
export declare function couple(blocks: readonly Block[], partitioning: Partitioning, lawed: LawedNetlist): Coupled;
|
|
13
|
+
/**
|
|
14
|
+
* A new stamp, added to a block whose `linear`/`controlFree` are re-derived rather than
|
|
15
|
+
* assumed unchanged -- the same rule `lowerRegion` itself follows, so a stamp this stage adds
|
|
16
|
+
* cannot silently leave a block claiming a solver cost or a control independence its own
|
|
17
|
+
* stamps contradict.
|
|
18
|
+
*
|
|
19
|
+
* Exported for `dangling-active-terminal.ts`'s implicit op-amp bias synthesis, which adds a
|
|
20
|
+
* stamp to an already-linked block for the same reason this stage does: a block's derived
|
|
21
|
+
* fields must never describe a stamps array it does not have.
|
|
22
|
+
*/
|
|
23
|
+
export declare function withStamp(block: Extract<Block, {
|
|
24
|
+
readonly kind: "mna";
|
|
25
|
+
}>, stamp: Stamp): Extract<Block, {
|
|
26
|
+
readonly kind: "mna";
|
|
27
|
+
}>;
|
|
28
|
+
//# sourceMappingURL=couple.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"couple.d.ts","sourceRoot":"","sources":["../src/couple.ts"],"names":[],"mappings":"AAoHA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAU,YAAY,EAAU,KAAK,EAAE,MAAM,SAAS,CAAC;AAGxF,MAAM,MAAM,OAAO,GAAG;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC;CACpD,CAAC;AA6BF,wBAAgB,MAAM,CACrB,MAAM,EAAE,SAAS,KAAK,EAAE,EACxB,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAE,YAAY,GACjB,OAAO,CAgaT;AAcD;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CACxB,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAA;CAAE,CAAC,EAC/C,KAAK,EAAE,KAAK,GACV,OAAO,CAAC,KAAK,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAA;CAAE,CAAC,CAgC1C"}
|