@vessel-dsp/compiler 0.8.1 → 0.14.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.
Files changed (46) hide show
  1. package/dist/compile.d.ts.map +1 -1
  2. package/dist/compile.js +46 -0
  3. package/dist/compile.js.map +1 -1
  4. package/dist/device-laws.d.ts +20 -0
  5. package/dist/device-laws.d.ts.map +1 -1
  6. package/dist/device-laws.js +185 -17
  7. package/dist/device-laws.js.map +1 -1
  8. package/dist/diagnostics.d.ts +1 -1
  9. package/dist/diagnostics.d.ts.map +1 -1
  10. package/dist/diagnostics.js +1 -1
  11. package/dist/diagnostics.js.map +1 -1
  12. package/dist/fixtures/circuits.d.ts +87 -4
  13. package/dist/fixtures/circuits.d.ts.map +1 -1
  14. package/dist/fixtures/circuits.js +397 -4
  15. package/dist/fixtures/circuits.js.map +1 -1
  16. package/dist/fixtures/expected.d.ts +10 -0
  17. package/dist/fixtures/expected.d.ts.map +1 -1
  18. package/dist/fixtures/expected.js +48 -0
  19. package/dist/fixtures/expected.js.map +1 -1
  20. package/dist/index.d.ts +1 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +1 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/latch-seed.d.ts +76 -14
  25. package/dist/latch-seed.d.ts.map +1 -1
  26. package/dist/latch-seed.js +184 -41
  27. package/dist/latch-seed.js.map +1 -1
  28. package/dist/lower.d.ts.map +1 -1
  29. package/dist/lower.js +90 -14
  30. package/dist/lower.js.map +1 -1
  31. package/dist/netlist.d.ts.map +1 -1
  32. package/dist/netlist.js +96 -3
  33. package/dist/netlist.js.map +1 -1
  34. package/dist/part-catalog.d.ts.map +1 -1
  35. package/dist/part-catalog.js +307 -41
  36. package/dist/part-catalog.js.map +1 -1
  37. package/dist/partition.d.ts.map +1 -1
  38. package/dist/partition.js +7 -4
  39. package/dist/partition.js.map +1 -1
  40. package/dist/stamp-partition.d.ts +6 -0
  41. package/dist/stamp-partition.d.ts.map +1 -1
  42. package/dist/stamp-partition.js +6 -0
  43. package/dist/stamp-partition.js.map +1 -1
  44. package/dist/types.d.ts +256 -5
  45. package/dist/types.d.ts.map +1 -1
  46. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"part-catalog.d.ts","sourceRoot":"","sources":["../src/part-catalog.ts"],"names":[],"mappings":"AAsDA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1D,OAAO,EAeN,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAI5D,OAAO,EACN,wBAAwB,EACxB,sBAAsB,EACtB,oBAAoB,EACpB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,GACtB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC;AAoIzD,6FAA6F;AAC7F,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CA+B5D;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CAkC9D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CAkC5D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAC1B,MAAM,EAAE,aAAa,EACrB,GAAG,EAAE,MAAM,GAAG,QAAQ,GACpB,SAAS,CAkEX;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CA6B5D;AA+BD,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAInD,CAAC;AA02QF;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACvC,IAAI,EAAE,SAAS,SAAS,EAAE,EAC1B,IAAI,GAAE,SAAS,mBAAmB,EAAyB,EAC3D,UAAU,GAAE,aAAa,CAAC;IAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAA0B,GAClH,SAAS,SAAS,EAAE,CAgHtB;AAeD,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAUlD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,YAE9B,CAAC"}
1
+ {"version":3,"file":"part-catalog.d.ts","sourceRoot":"","sources":["../src/part-catalog.ts"],"names":[],"mappings":"AAsDA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG1D,OAAO,EAeN,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAI5D,OAAO,EACN,wBAAwB,EACxB,sBAAsB,EACtB,oBAAoB,EACpB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,GACtB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC;AAoIzD,6FAA6F;AAC7F,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CA+B5D;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CAkC9D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CAkC5D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAC1B,MAAM,EAAE,aAAa,EACrB,GAAG,EAAE,MAAM,GAAG,QAAQ,GACpB,SAAS,CAkEX;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CA6B5D;AA+BD,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAInD,CAAC;AAsnRF;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACvC,IAAI,EAAE,SAAS,SAAS,EAAE,EAC1B,IAAI,GAAE,SAAS,mBAAmB,EAAyB,EAC3D,UAAU,GAAE,aAAa,CAAC;IAAE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAA0B,GAClH,SAAS,SAAS,EAAE,CAgHtB;AAeD,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAUlD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,YAE9B,CAAC"}
@@ -1272,19 +1272,75 @@ const entries = [
1272
1272
  // BA728F", ROHM), Fig. 4's BA718 9-pin SIP block diagram and pin row, which states pin 1
1273
1273
  // through 9 as: VCC, VOUT(1ch), I1, IN1, VEE, IN2, I2, VOUT(2ch), VCC. Electrical
1274
1274
  // characteristics (Ta=25C, VCC=6V, VEE=-6V): "Large signal voltage gain Av ... Min 86 Typ
1275
- // 100 ... dB". Used as `openLoopGain: decibelGain(100)`, the typ figure, matching this
1275
+ // 100 ... dB". Used as `openLoopGain: 100000`, the typ figure, matching this
1276
1276
  // file's convention for the other op-amps above.
1277
1277
  //
1278
- // `boss-cs-3.vdsp`'s `IC4` declares only 5 of the real 9 pins, named plainly `pin1`
1279
- // through `pin5` (no suffix, so `terminalRoleToken` folds every one of them to `null` --
1280
- // this entry cannot be pinout-guarded, the same bound `identify.ts` documents for a part
1281
- // numbered `pin1..pinN`). Declaration order there is sequential ascending pin number, the
1282
- // same convention verified for the NE570 entry above: `pin1`=idx0 through `pin5`=idx4. Read
1283
- // against the real 9-pin table, that is exactly channel 1's five pins in order -- VCC, OUT1,
1284
- // I1 (the inverting/feedback node), IN1, VEE -- a self-contained single-op-amp capture of
1285
- // the chip's first section, with channel 2's pins 6-9 simply absent from this component.
1286
- // Only the three audio terminals matter to `ideal-opamp`; VCC/VEE are not read (rails come
1287
- // from the circuit's own supply set, same as every other entry here).
1278
+ // Two shapes share this part id (one entry each, told apart by arity, the M5218 dual-split
1279
+ // precedent): the full 9-pin dual declaration first, then the older 5-pin single-section
1280
+ // capture. The re-traced `boss-cs-3.vdsp` `IC4` declares all nine in strict sequential
1281
+ // ascending pin order (`pin1`..`pin9`, bare names folding to null roles, so this entry
1282
+ // cannot be pinout-guarded and stays on the documented-positional route with the
1283
+ // cross-check below, the NE570 precedent):
1284
+ // 4a: out=pin2 (node 42), -in=pin3/I1 (node 41), +in=pin4/IN1 (node 5, the 4.5 V rail),
1285
+ // VEE=pin5 (node 0, ground); 4b: +in=pin6/IN2 (node 76, SUSTAIN/ATTACK wiper net),
1286
+ // out=pin7 (node 47 into D6), -in=pin8/I2 (node 47, follower strap), VCC=pin1/pin9
1287
+ // (node 4, 9 V). Each section below carries only its own three audio terminals in the
1288
+ // `ideal-opamp` [+, -, out] order; VCC/VEE are not read (rails come from the circuit's
1289
+ // own supply set, same as every other entry here).
1290
+ {
1291
+ "partIds": [
1292
+ "BA718"
1293
+ ],
1294
+ "declaredTypes": [],
1295
+ "terminalRoleGroups": [],
1296
+ "model": {
1297
+ "kind": "sections",
1298
+ "sections": [
1299
+ {
1300
+ "law": {
1301
+ "kind": "ideal-opamp",
1302
+ "railHigh": null,
1303
+ "railLow": null,
1304
+ "openLoopGain": 100000
1305
+ },
1306
+ "terminals": [
1307
+ 3,
1308
+ 2,
1309
+ 1
1310
+ ]
1311
+ },
1312
+ {
1313
+ "law": {
1314
+ "kind": "ideal-opamp",
1315
+ "railHigh": null,
1316
+ "railLow": null,
1317
+ "openLoopGain": 100000
1318
+ },
1319
+ "terminals": [
1320
+ 5,
1321
+ 6,
1322
+ 7
1323
+ ]
1324
+ }
1325
+ ],
1326
+ "pinout": [
1327
+ null,
1328
+ null,
1329
+ null,
1330
+ null,
1331
+ null,
1332
+ null,
1333
+ null,
1334
+ null,
1335
+ null
1336
+ ]
1337
+ }
1338
+ },
1339
+ // The older BA718 5-pin single-section capture: channel 1's five pins in declaration
1340
+ // order (VCC, OUT1, I1, IN1, VEE), kept working for the pre-retrace capture that declares
1341
+ // only them. Same part id, same typ gain; the 9-pin entry above serves the full dual
1342
+ // declaration. Bare `pin1`..`pin5` names fold to null roles here too, so this entry is
1343
+ // likewise positional with the declaration order as its only assertion.
1288
1344
  {
1289
1345
  "partIds": [
1290
1346
  "BA718"
@@ -4301,6 +4357,90 @@ const entries = [
4301
4357
  // constant is -5.9 mV per dB, over a +/-30 dB range, matching `boss-lm-2`'s own
4302
4358
  // `boss-lm-2-upc1252h2-vca-control.cir` reference deck (`gain_db = -v(ctrl)/0.0059`).
4303
4359
  //
4360
+ // BEHAVIORAL LAW v4 (session-calibrated: threshold/rest-gain + release).
4361
+ // v2 rendered the pedal linear (flat 0.303: the island sigmoid needs volts, GC1
4362
+ // delivers millivolts) and v3 rendered it expanding (the v2 envelope rectified the
4363
+ // cell's virtual-ground node volts, ~100x too small, while raw audio on node 70
4364
+ // pumped the gain). v4 fits the session threshold curves directly: SUSTAIN-coupled
4365
+ // rest (sustainGain -4.23, sustainRef 4.6504 V -- rest gain rises with SUSTAIN,
4366
+ // +27.5 dB across the engine-measured V70 rest span 4.6325->4.6728, inverting the
4367
+ // old -6.8 dB SUSTAIN response with the session curves quoted as cause) plus a
4368
+ // log-domain envelope with a SUSTAIN-tracked knee (envelopeSlope 0.049 V/neper,
4369
+ // kneeBase -0.069 V at V70 4.65 rising 4.36 V/V): below the knee the pedal holds
4370
+ // rest gain, above it each input decade adds the same dB of reduction, and the knee
4371
+ // tracks SUSTAIN so sus-min stays flat to 300 mV while centre and sus-max engage
4372
+ // progressively. Joint fit to the 12-point session sweep (worst residual 0.7 dB);
4373
+ // hot points stay within ~1 dB of the coordinator's renders (no regression).
4374
+ // The island still quotes 4.5 V for its off-chip ctrl_bus (both quoted).
4375
+ //
4376
+ // CENTER (rest span, both quoted): the GC rest moves 4.6325->4.6728 across SUSTAIN
4377
+ // 0->1 (engine-measured at declared defaults). sustainRef 4.6504 V with sustainGain
4378
+ // -4.23 maps that span onto the session rest gains (sus-min -13.2, centre +5.68,
4379
+ // sus-max +14.28 dB at 10 mV in).
4380
+ //
4381
+ // KNEE (threshold moves with SUSTAIN): the knee must sit above 300 mV-equivalent
4382
+ // at sus-min (flat -13.2), near 30-50 mV at centre, and near 10 mV at sus-max --
4383
+ // a fixed knee cannot satisfy 30 mV-off (centre) and 30 mV-on (sus-max) at once,
4384
+ // so it tracks V70 at +4.36 V/V. The chip's true threshold mechanism is
4385
+ // silicon-internal (excluded); LM-2's biasing is unverified (workbench-side).
4386
+ //
4387
+ // SMOOTHING (load-bearing as in v3): node 70 carries tens of millivolts of audio,
4388
+ // so both the external control and the rectified input are smoothed with
4389
+ // attack/release (C8 4.7 uF by R13 10k ~ 47 ms release, D6 charge path ~ 0.5 ms
4390
+ // attack) and held across the Newton loop. Release TC varies with suppression
4391
+ // depth (releaseSlowdown 2400: 50 ms near top, minutes-slow from deep suppression;
4392
+ // fit hook for the hot-start + 60 s take, which does not exist yet) -- a fixed
4393
+ // release is refuted by the session (pips annihilated after hot history, passing
4394
+ // after mild history, across the same gap). The 4a/Q6/Q8 auxiliary chain cannot
4395
+ // substitute: 4a's audio input is an open trace residual.
4396
+ //
4397
+ // SHUTDOWN (v5, session-8 victim dependence, on top of the untouched v4 above):
4398
+ // the depth-only release clears slowly everywhere-post-hot, but hardware clears
4399
+ // in <1 s under tone while holding across a 30 s gap -- so the release from a
4400
+ // post-gap transient crush must be victim-dependent, not just depth-dependent.
4401
+ // A fourth follower holds the shutdown: pumped only by hot peaks while primed
4402
+ // (silence builds prime over ~10 s, signal disarms in fractions of a second),
4403
+ // with an absolute gulp threshold (shutdownEdgeVolts) and quadratic size
4404
+ // (shutdownGain fit: D6 conducting hard into the depleted C8 on the first
4405
+ // post-gap peak, the square the D6 diode exponential over the range; the
4406
+ // absolute threshold is the diode forward drop plus topped-C8 headroom, which
4407
+ // is why sine ripple and mild peaks never pump). Render onsets and continuous
4408
+ // tones never pump (priming starts at zero and signal holds it there): the v4
4409
+ // threshold fit is structurally untouched. The shutdown bleeds
4410
+ // victim-dependently (shutdownFastSeconds under sustained signal through the
4411
+ // signal-driven Q6/Q8 collector plus Q7 transconductance discharge,
4412
+ // shutdownSlowSeconds R-only in silence: holds across takes, finite).
4413
+ // Session-8 fit: post-gap pip 0.007x mild, tone from +1 s at baseline flat,
4414
+ // no creep.
4415
+ //
4416
+ // BINDING. `boss-lm-2`'s `IC1_UPC1252H2` spells its pins with role suffixes
4417
+ // (`pin1_input`, `pin2_gc2`, `pin3_gc1`, `pin4_symmetry`, `pin5_iset`,
4418
+ // `pin6_ground_reference`, `pin7_vcc`, `pin8_output`), which fold to
4419
+ // input/gc2/gc1/symmetry/iset/groundreference/vcc/output -- every group below
4420
+ // resolves onto exactly one of those, so it binds by clean role bijection with no
4421
+ // positional assumption. `boss-cs-3`'s `IC3` names its pins bare `pin1`..`pin8`
4422
+ // (roles all null), so it binds positionally in strict sequential pin order, the
4423
+ // NE570 precedent, cross-checked here: pin1 = node 14 (signal in through R9),
4424
+ // pin2/pin3 = node 70 (GC pair, driven by the R11/Q7 detector network), pin4/pin6 =
4425
+ // node 15 (GC3/GND side, coupled to 70 through R8), pin5 = node 17 (ISET through R7
4426
+ // to ground), pin7 = node 4 (9 V rail), pin8 = node 18 (signal out through R6/C5).
4427
+ // The single section below carries [in, ref, out, control] in the `dbx-vca` law order
4428
+ // as canonical positions [0, 5, 7, 2]: in = pin1, ref = pin6 (GND), out = pin8,
4429
+ // control = pin3 (GC1 -- the detector-driven GC pin on both pedals: on `boss-lm-2`
4430
+ // D8/D9 feed node 6, which is pin3_gc1, while pin2_gc2 sits on node 17).
4431
+ //
4432
+ // `inputSiemens` 0.01 is the current-input impedance convention this file already
4433
+ // uses for a current-input VCA pin (the `linear-vca` entries carry the same 0.01);
4434
+ // the absolute level is then set by the external transimpedance (CS-3's R6 10k into
4435
+ // IC2's inverting stage), not by this number alone.
4436
+ //
4437
+ // KNOWN DEVIATIONS (documented, not hidden):
4438
+ // - SUSTAIN rest span, knee track, and envelope slope are fitted to the session
4439
+ // threshold curves (worst residual 0.7 dB); a packet re-trace moving the
4440
+ // SUSTAIN-default bias moves rest with it. LM-2's biasing is unverified:
4441
+ // the entry's numbers are the CS-3's, and LM-2 calibration belongs
4442
+ // workbench-side.
4443
+ //
4304
4444
  // `declaredTypes` deliberately empty. It listed `Circuit.IC`, the format's generic "this is a
4305
4445
  // chip", which identifies nothing and could only ever act as a catch-all: measured 2026-09-04,
4306
4446
  // both corpus users (`boss-cs-3`'s `IC3` and `boss-lm-2`'s `IC1_UPC1252H2`) match by exact part
@@ -4342,11 +4482,13 @@ const entries = [
4342
4482
  "pin6",
4343
4483
  "gnd",
4344
4484
  "ref",
4345
- "ground"
4485
+ "ground",
4486
+ "groundreference"
4346
4487
  ],
4347
4488
  [
4348
4489
  "pin7",
4349
- "vc"
4490
+ "vc",
4491
+ "vcc"
4350
4492
  ],
4351
4493
  [
4352
4494
  "pin8",
@@ -4360,23 +4502,32 @@ const entries = [
4360
4502
  "sections": [
4361
4503
  {
4362
4504
  "law": {
4363
- "kind": "conductance",
4364
- "siemens": 0.01
4365
- },
4366
- "terminals": [
4367
- 0,
4368
- 5
4369
- ]
4370
- },
4371
- {
4372
- "law": {
4373
- "kind": "ota",
4374
- "transconductance": 0.01
4505
+ "kind": "dbx-vca",
4506
+ "inputSiemens": 0.01,
4507
+ "sustainGain": -4.23,
4508
+ "sustainRef": 4.6504,
4509
+ "envelopeSlope": 0.049,
4510
+ "kneeBaseVolts": -0.069,
4511
+ "kneeTrack": 4.36,
4512
+ "attackSeconds": 0.0005,
4513
+ "releaseSeconds": 0.05,
4514
+ "releaseSlowdown": 2400,
4515
+ "shutdownEdgeVolts": 0.08,
4516
+ "shutdownGain": 28,
4517
+ "primeRiseSeconds": 10,
4518
+ "primeFallSeconds": 0.15,
4519
+ "shutdownAttackSeconds": 0.00015,
4520
+ "shutdownFastSeconds": 0.025,
4521
+ "shutdownSlowSeconds": 300,
4522
+ "primeRefCurrent": 0.0000005,
4523
+ "minGainDb": -30,
4524
+ "maxGainDb": 30
4375
4525
  },
4376
4526
  "terminals": [
4377
4527
  0,
4378
4528
  5,
4379
- 7
4529
+ 7,
4530
+ 2
4380
4531
  ]
4381
4532
  }
4382
4533
  ],
@@ -5143,9 +5294,10 @@ const entries = [
5143
5294
  // `runoffgroove-tremulus-lune`'s packet cites a real VTL5C2 datasheet current-resistance curve
5144
5295
  // (R@1mA=5.5k, R@10mA=800, R@40mA=200, dark>=1M) that this row's placeholder bounds
5145
5296
  // (ldrMinOhms=100, ldrMaxOhms=10M with the generic exp(-1000*amps) law) put 56.7% of the way to
5146
- // fully dark at a genuinely-lit 0.567 mA. None of the other parts here carry a cited curve, so
5147
- // this row is untouched -- moving them to chase the one part that has evidence is the mistake
5148
- // this repo calls a seventeenth spelling table.
5297
+ // fully dark at a genuinely-lit 0.567 mA. The `P873G35` spellings split out the same way
5298
+ // below (a third-party measured power-law fit, provisional). None of the other parts here
5299
+ // carry a cited curve, so this row is untouched -- moving them to chase the parts that have
5300
+ // evidence is the mistake this repo calls a seventeenth spelling table.
5149
5301
  {
5150
5302
  "partIds": [
5151
5303
  "PC817",
@@ -5153,10 +5305,7 @@ const entries = [
5153
5305
  "VTL5C1",
5154
5306
  "VTL3C3",
5155
5307
  "VTL5C3",
5156
- "VTL5C4",
5157
- "P873G35-380",
5158
- "P873G35",
5159
- "P873G35380"
5308
+ "VTL5C4"
5160
5309
  ],
5161
5310
  "declaredTypes": [],
5162
5311
  "terminalRoleGroups": [
@@ -5212,6 +5361,115 @@ const entries = [
5212
5361
  ]
5213
5362
  }
5214
5363
  },
5364
+ // --- P873G35 / P873G35-380 (measured table cell; unblocks boss-aw-2) -------------------------------------------------------------
5365
+ //
5366
+ // Own entry, split out of the PC817/MOC3021 row above the way `VTL5C2` already was:
5367
+ // `boss-aw-2` files the part as `P873G35-38`, which exact folded equality does not
5368
+ // match to any existing id, so the device fell to the optocoupler class default and
5369
+ // sat at megohms through the lamp's whole 0.02-0.5 mA sweep. `P873G35-38` joins this
5370
+ // entry's `partIds` by the 2026-10-23 owner decision (the service note's `-38` reads
5371
+ // as the `-380` grade). The law is the geometric mean of 18 measured P873-G35-380
5372
+ // units in a 2005 hobbyist table (electro-music.org topic 27276, 22 C), stored as a
5373
+ // measured `ldrTableCurrentAmps`/`ldrTableOhms` table and evaluated by log-log
5374
+ // interpolation -- NOT a manufacturer curve; the Hamamatsu sheets available list
5375
+ // neither `-380` nor `-38` with a resistance-vs-current curve. A single power-law fit
5376
+ // cannot cover this cell: fitted over 0.3-20 mA (`ohms = 105.6 * amps^-0.4360`,
5377
+ // max residual x1.14) it gives ~11 kohm at 0.03 mA where the measured geometric
5378
+ // mean is 60.1 kohm, so a low-current circuit like the AW-2's lamp (0.02-0.5 mA)
5379
+ // cannot relax as low as the real pedal. The table carries the six measured points
5380
+ // directly (0.03, 0.1, 0.3, 1, 10, 20 mA -> 60.1, 11.5, 4.03, 1.88, 0.74, 0.64 kohm),
5381
+ // so no fit range has to be picked per pedal. The LED figures and both clamps
5382
+ // keep the generic row's values exactly (1.6 V, 1e-3, 100 ohm, 1e7). The table is
5383
+ // third-party evidence, so both table parameters ride `provisionalParams` and compile
5384
+ // raises `registry-provisional-value` for devices that run on them -- the same
5385
+ // mechanism the `2SC2458`/`2SC2459` community saturation currents use.
5386
+ {
5387
+ "partIds": [
5388
+ "P873G35",
5389
+ "P873G35-380",
5390
+ "P873G35380",
5391
+ "P873G35-38"
5392
+ ],
5393
+ "declaredTypes": [],
5394
+ "terminalRoleGroups": [
5395
+ [
5396
+ "ledanode",
5397
+ "anode",
5398
+ "led_anode",
5399
+ "pin1"
5400
+ ],
5401
+ [
5402
+ "ledcathode",
5403
+ "cathode",
5404
+ "led_cathode",
5405
+ "pin2"
5406
+ ],
5407
+ [
5408
+ "ldra",
5409
+ "a",
5410
+ "ldr_a",
5411
+ "pin3"
5412
+ ],
5413
+ [
5414
+ "ldrb",
5415
+ "b",
5416
+ "ldr_b",
5417
+ "pin4"
5418
+ ]
5419
+ ],
5420
+ "provisionalParams": [
5421
+ {
5422
+ "name": "ldrTableCurrentAmps",
5423
+ "url": "https://electro-music.org/forum/topic-27276.html"
5424
+ },
5425
+ {
5426
+ "name": "ldrTableOhms",
5427
+ "url": "https://electro-music.org/forum/topic-27276.html"
5428
+ }
5429
+ ],
5430
+ "model": {
5431
+ "kind": "sections",
5432
+ "sections": [
5433
+ {
5434
+ "law": {
5435
+ "kind": "optocoupler",
5436
+ "ledThresholdVolts": 1.6,
5437
+ "ledTransconductance": 0.001,
5438
+ "ldrMinOhms": 100,
5439
+ "ldrMaxOhms": 10000000,
5440
+ "ldrTableCurrentAmps": [
5441
+ 0.00003,
5442
+ 0.0001,
5443
+ 0.0003,
5444
+ 0.001,
5445
+ 0.01,
5446
+ 0.02
5447
+ ],
5448
+ "ldrTableOhms": [
5449
+ 60100,
5450
+ 11500,
5451
+ 4030,
5452
+ 1880,
5453
+ 740,
5454
+ 640
5455
+ ]
5456
+ },
5457
+ "terminals": [
5458
+ 0,
5459
+ 1,
5460
+ 2,
5461
+ 3
5462
+ ]
5463
+ }
5464
+ ],
5465
+ "pinout": [
5466
+ "led_anode",
5467
+ "led_cathode",
5468
+ "ldr_a",
5469
+ "ldr_b"
5470
+ ]
5471
+ }
5472
+ },
5215
5473
  // --- Vactec VTL5C2 (unblocks runoffgroove-tremulus-lune) ----------------------------------------------------------------------
5216
5474
  //
5217
5475
  // Own entry, split out of the PC817/MOC3021 row above (2026-09-15). `runoffgroove-tremulus-lune`
@@ -5220,12 +5478,12 @@ const entries = [
5220
5478
  // R@10mA=800, R@40mA=200, dark/off resistance >=1M. Those three points are linear in log-log
5221
5479
  // space (pairwise slopes -0.837 and -1.000), which the generic bucket's exponential-in-current
5222
5480
  // law cannot fit at any choice of constant -- confirmed by attempting the fit and finding no
5223
- // sane solution (see changelog). `ldrPowerLawCoefficientOhms`/`ldrPowerLawExponent` are a
5224
- // least-squares power-law fit to those three anchors instead: `ohms = 11.9861 *
5225
- // amps^-0.892233`, clamped to `[ldrMinOhms, ldrMaxOhms]`. Residuals against the cited anchors:
5226
- // +3.5% at 1 mA, -8.8% at 10 mA, +5.9% at 40 mA. `ldrMaxOhms` is tightened to 1e6 (the packet's
5227
- // own cited dark floor) from the generic bucket's placeholder 1e7; `ldrMinOhms` keeps the
5228
- // generic 100 ohm floor, which the datasheet does not further constrain below the 40 mA point.
5481
+ // sane solution (see changelog). The cell is the three cited anchors as a measured
5482
+ // `ldrTableCurrentAmps`/`ldrTableOhms` table (no fit): 1, 10, 40 mA -> 5.5k, 800, 200 ohm,
5483
+ // evaluated by log-log interpolation, clamped to `[ldrMinOhms, ldrMaxOhms]`. `ldrMaxOhms`
5484
+ // is tightened to 1e6 (the packet's own cited dark floor) from the generic bucket's
5485
+ // placeholder 1e7; `ldrMinOhms` keeps the generic 100 ohm floor, which the datasheet
5486
+ // does not further constrain below the 40 mA point.
5229
5487
  {
5230
5488
  "partIds": [
5231
5489
  "VTL5C2"
@@ -5267,8 +5525,16 @@ const entries = [
5267
5525
  "ledTransconductance": 0.001,
5268
5526
  "ldrMinOhms": 100,
5269
5527
  "ldrMaxOhms": 1000000,
5270
- "ldrPowerLawCoefficientOhms": 11.9861,
5271
- "ldrPowerLawExponent": -0.892233
5528
+ "ldrTableCurrentAmps": [
5529
+ 0.001,
5530
+ 0.01,
5531
+ 0.04
5532
+ ],
5533
+ "ldrTableOhms": [
5534
+ 5500,
5535
+ 800,
5536
+ 200
5537
+ ]
5272
5538
  },
5273
5539
  "terminals": [
5274
5540
  0,