simple-circuit-engine 0.0.12 → 0.0.14

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 (99) hide show
  1. package/AGENTS.md +9 -6
  2. package/CLAUDE.md +2 -0
  3. package/README.md +8 -8
  4. package/dist/core/index.js +109 -74
  5. package/dist/core/setup.d.ts +18 -0
  6. package/dist/core/simulation/behaviors/arithmetic/AdderBehavior.d.ts +28 -0
  7. package/dist/core/simulation/behaviors/arithmetic/ArithmeticBehaviorMixin.d.ts +63 -0
  8. package/dist/core/simulation/behaviors/arithmetic/EightBitAdderBehavior.d.ts +51 -0
  9. package/dist/core/simulation/behaviors/arithmetic/EightBitOnesComplementBehavior.d.ts +29 -0
  10. package/dist/core/simulation/behaviors/arithmetic/HalfAdderBehavior.d.ts +22 -0
  11. package/dist/core/simulation/behaviors/arithmetic/index.d.ts +7 -0
  12. package/dist/core/simulation/behaviors/index.d.ts +14 -0
  13. package/dist/core/simulation/behaviors/interface/EightInputBehavior.d.ts +9 -0
  14. package/dist/core/simulation/behaviors/interface/EightLightBehavior.d.ts +9 -0
  15. package/dist/core/simulation/behaviors/interface/FourInputBehavior.d.ts +9 -0
  16. package/dist/core/simulation/behaviors/interface/FourLightBehavior.d.ts +9 -0
  17. package/dist/core/simulation/behaviors/interface/InputBehaviorMixin.d.ts +37 -0
  18. package/dist/core/simulation/behaviors/interface/LightBehaviorMixin.d.ts +60 -0
  19. package/dist/core/simulation/behaviors/interface/OneInputBehavior.d.ts +9 -0
  20. package/dist/core/simulation/behaviors/interface/OneLightBehavior.d.ts +9 -0
  21. package/dist/core/simulation/behaviors/interface/TwoInputBehavior.d.ts +9 -0
  22. package/dist/core/simulation/behaviors/interface/TwoLightBehavior.d.ts +9 -0
  23. package/dist/core/simulation/behaviors/interface/index.d.ts +0 -0
  24. package/dist/core/simulation/states/arithmetic/AdderState.d.ts +16 -0
  25. package/dist/core/simulation/states/arithmetic/ArithmeticState.d.ts +53 -0
  26. package/dist/core/simulation/states/arithmetic/EightBitAdderState.d.ts +25 -0
  27. package/dist/core/simulation/states/arithmetic/EightBitOnesComplementState.d.ts +18 -0
  28. package/dist/core/simulation/states/arithmetic/HalfAdderState.d.ts +16 -0
  29. package/dist/core/simulation/states/arithmetic/index.d.ts +7 -0
  30. package/dist/core/simulation/states/index.d.ts +15 -0
  31. package/dist/core/simulation/states/interface/EightInputState.d.ts +6 -0
  32. package/dist/core/simulation/states/interface/EightLightState.d.ts +6 -0
  33. package/dist/core/simulation/states/interface/FourInputState.d.ts +6 -0
  34. package/dist/core/simulation/states/interface/FourLightState.d.ts +6 -0
  35. package/dist/core/simulation/states/interface/InputState.d.ts +45 -0
  36. package/dist/core/simulation/states/interface/LightState.d.ts +54 -0
  37. package/dist/core/simulation/states/interface/OneInputState.d.ts +6 -0
  38. package/dist/core/simulation/states/interface/OneLightState.d.ts +6 -0
  39. package/dist/core/simulation/states/interface/TwoInputState.d.ts +6 -0
  40. package/dist/core/simulation/states/interface/TwoLightState.d.ts +6 -0
  41. package/dist/core/simulation/types.d.ts +10 -2
  42. package/dist/core/topology/Component.d.ts +6 -1
  43. package/dist/core/topology/ENode.d.ts +7 -2
  44. package/dist/core/topology/index.d.ts +2 -0
  45. package/dist/core/topology/networkTraversal.d.ts +50 -0
  46. package/dist/core/topology/types.d.ts +31 -6
  47. package/dist/core-HH6iRWtB.js +4671 -0
  48. package/dist/core-HH6iRWtB.js.map +1 -0
  49. package/dist/i18n/index.d.ts +1158 -0
  50. package/dist/i18n/locales/en.json.d.ts +366 -0
  51. package/dist/i18n/locales/fr.json.d.ts +366 -0
  52. package/dist/index.d.ts +1 -0
  53. package/dist/index.js +172 -118
  54. package/dist/scene/CircuitEngine.d.ts +49 -4
  55. package/dist/scene/index.d.ts +6 -2
  56. package/dist/scene/index.js +62 -45
  57. package/dist/scene/setup.d.ts +18 -0
  58. package/dist/scene/shared/AbstractCircuitController.d.ts +11 -3
  59. package/dist/scene/shared/HoverManager.d.ts +15 -0
  60. package/dist/scene/shared/components/arithmetic/AdderVisualFactory.d.ts +54 -0
  61. package/dist/scene/shared/components/arithmetic/EightBitAdderVisualFactory.d.ts +45 -0
  62. package/dist/scene/shared/components/arithmetic/EightBitOnesComplementVisualFactory.d.ts +63 -0
  63. package/dist/scene/shared/components/arithmetic/HalfAdderVisualFactory.d.ts +55 -0
  64. package/dist/scene/shared/components/arithmetic/index.d.ts +4 -0
  65. package/dist/scene/shared/components/index.d.ts +14 -0
  66. package/dist/scene/shared/components/interface/EightInputVisualFactory.d.ts +15 -0
  67. package/dist/scene/shared/components/interface/EightLightVisualFactory.d.ts +15 -0
  68. package/dist/scene/shared/components/interface/FourInputVisualFactory.d.ts +15 -0
  69. package/dist/scene/shared/components/interface/FourLightVisualFactory.d.ts +15 -0
  70. package/dist/scene/shared/components/interface/InputVisualFactoryBase.d.ts +50 -0
  71. package/dist/scene/shared/components/interface/LightVisualFactoryBase.d.ts +46 -0
  72. package/dist/scene/shared/components/interface/OneInputVisualFactory.d.ts +15 -0
  73. package/dist/scene/shared/components/interface/OneLightVisualFactory.d.ts +15 -0
  74. package/dist/scene/shared/components/interface/TwoInputVisualFactory.d.ts +15 -0
  75. package/dist/scene/shared/components/interface/TwoLightVisualFactory.d.ts +15 -0
  76. package/dist/scene/shared/types.d.ts +34 -4
  77. package/dist/scene/shared/utils/ControlsUtils.d.ts +1 -1
  78. package/dist/scene/shared/utils/GeometryUtils.d.ts +111 -0
  79. package/dist/scene/static/CircuitController.d.ts +13 -1
  80. package/dist/scene/static/tools/BuildTool.d.ts +81 -0
  81. package/dist/scene/static/tools/ComponentPickerWidget.d.ts +7 -0
  82. package/dist/scene/static/tools/ConfigPanelWidget.d.ts +14 -0
  83. package/dist/scene/static/tools/MultiWiringPlacement.d.ts +40 -0
  84. package/dist/scene/widgets/HelpWidget.d.ts +13 -0
  85. package/dist/scene/widgets/ModeWidget.d.ts +16 -0
  86. package/dist/scene/widgets/MultiWiringWidget.d.ts +21 -0
  87. package/dist/scene/{static → widgets}/PinTooltipWidget.d.ts +7 -1
  88. package/dist/scene/widgets/SimulationPlayerWidget.d.ts +62 -0
  89. package/dist/scene/widgets/ToolsWidget.d.ts +18 -0
  90. package/dist/scene/widgets/WidgetsManager.d.ts +65 -0
  91. package/dist/scene/widgets/assets/icons.d.ts +20 -0
  92. package/dist/scene/widgets/index.d.ts +9 -0
  93. package/dist/scene/widgets/styles.d.ts +33 -0
  94. package/dist/{scene-CVsDdySt.js → scene-C1xhdw_B.js} +3993 -772
  95. package/dist/scene-C1xhdw_B.js.map +1 -0
  96. package/package.json +14 -9
  97. package/dist/core-Bjta9Y7_.js +0 -2707
  98. package/dist/core-Bjta9Y7_.js.map +0 -1
  99. package/dist/scene-CVsDdySt.js.map +0 -1
package/AGENTS.md CHANGED
@@ -35,15 +35,15 @@ registerGatesComponentsFactories(componentsFactoryRegistry); //... other groups
35
35
  const behaviorRegistry = registerBasicComponentsBehaviors(new BehaviorRegistry());
36
36
  registerGatesComponentsBehaviors(behaviorRegistry); //... other groupsof components if needed
37
37
 
38
+ // Rendering (must exist before engine.initialize — it binds MapControls to the canvas)
39
+ const renderer = new WebGLRenderer();
40
+
38
41
  // Instanciate and Initialize CircuitEngine (it creates and uses a new Circuit by default)
39
42
  const engine = new CircuitEngine(componentsFactoryRegistry, behaviorRegistry);
40
43
  const container = document.getElementById('canvas-container')!;
41
- engine.initialize(container, engineOptions());
44
+ engine.initialize(container, renderer, engineOptions());
42
45
  // set engine circuit to a new empty circuit
43
46
  engine.setCircuit(new Circuit(new CircuitOptions()));
44
-
45
- // Rendering
46
- const renderer = new WebGLRenderer();
47
47
  const width = window.innerWidth,
48
48
  height = window.innerHeight;
49
49
  renderer.setSize(container.clientWidth, container.clientHeight);
@@ -121,8 +121,10 @@ animate();
121
121
  ### Initialize Engine
122
122
 
123
123
  ```typescript
124
+ const renderer = new WebGLRenderer();
124
125
  const engine = new CircuitEngine(factoryRegistry, behaviorRegistry);
125
- engine.initialize(container, engineOptions());
126
+ engine.initialize(container, renderer, engineOptions());
127
+ container.appendChild(renderer.domElement);
126
128
  engine.setCircuit(new Circuit());
127
129
 
128
130
  // Add Component Programmatically
@@ -160,6 +162,7 @@ engine.on('simulationTick', (state) => { ... });
160
162
 
161
163
  ```json
162
164
  {
163
- "three": "^0.183.2"
165
+ "three": "^0.183.2",
166
+ "i18next": ">=25.0.0 <27.0.0"
164
167
  }
165
168
  ```
package/CLAUDE.md CHANGED
@@ -18,6 +18,7 @@ However, it aims to teach real-world electronic design principles so modeling of
18
18
  - TypeScript 6.0+ (strict mode), targeting ES2022
19
19
  - Three.js 0.183+ (scene, camera, controls, 3D objects, Line2)
20
20
  - lil-gui as helper for small interactive modal forms
21
+ - i18next for internationalization (see `src/i18n/CLAUDE.md` for conventions)
21
22
  - in-memory circuit model, optional loading/saving from/to a JSON file
22
23
 
23
24
  ## Project Structure
@@ -26,6 +27,7 @@ Simple Circuit Engine follows a **Model-Controller** architecture with clear sep
26
27
 
27
28
  - **Core module** (`src/core/`): Pure TypeScript domain **Model** and simulation engine (no dependencies).
28
29
  - **Scene module** (`src/scene/`): Three.js visualization layer with editing **Controller** and its tools and the simulation animated **Controller**.
30
+ - **i18next Internationalization** (`src/i18n/`) : localization setup and locales
29
31
 
30
32
  ### Core Module (`src/core/`)
31
33
 
package/README.md CHANGED
@@ -44,21 +44,21 @@ const componentsFactoryRegistry = registerBasicComponentsFactories(new GroupedFa
44
44
  // Create behavior registry with basic components behaviors (for simulation)
45
45
  const behaviorRegistry = registerBasicComponentsBehaviors(new BehaviorRegistry());
46
46
 
47
+ // Create and setup WebGL renderer (must exist before engine.initialize — it binds MapControls to the canvas)
48
+ const renderer = new WebGLRenderer({ antialias: true, alpha: false });
49
+ renderer.setClearColor(0x1a1a2e);
50
+ const container = document.getElementById('canva-container')!;
51
+ renderer.setSize(container.clientWidth, container.clientHeight);
52
+ renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
53
+
47
54
  // Initialize CircuitEngine
48
55
  // It creates THREE.js scene, camera, controls, lights, etc
49
56
  // and the interactive controllers (edit and simulation) of simple-circuit-engine
50
- const container = document.getElementById('canva-container')!;
51
57
  const engine = new CircuitEngine(componentsFactoryRegistry, behaviorRegistry);
52
- engine.initialize(container, engineOptions());
58
+ engine.initialize(container, renderer, engineOptions());
53
59
  // set engine circuit to a new empty circuit
54
60
  engine.setCircuit(new Circuit(new CircuitOptions()));
55
61
 
56
- // Create and setup WebGL renderer
57
- const renderer = new WebGLRenderer({ antialias: true, alpha: false });
58
- renderer.setClearColor(0x1a1a2e);
59
- const width = window.innerWidth, height = window.innerHeight;
60
- renderer.setSize(container.clientWidth, container.clientHeight);
61
- renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
62
62
  // Append renderer to DOM
63
63
  container.appendChild(renderer.domElement);
64
64
 
@@ -1,77 +1,112 @@
1
- import { $ as t, A as e, B as s, C as o, D as i, E as r, F as n, G as S, H as h, I as v, J as B, K as G, L as c, M as l, N, O as E, P as p, Q as T, R as m, S as u, T as C, U as I, V as L, W as D, X as d, Y as y, Z as g, _, _t as A, a as R, at as M, b as O, bt as b, c as P, ct as w, d as U, dt as X, et as f, f as F, ft as k, g as x, gt as z, h as Y, ht as Q, i as V, it as W, j, k as q, l as H, lt as J, m as K, mt as Z, n as $, nt as aa, o as ta, ot as ea, p as sa, pt as oa, q as ia, r as ra, rt as na, s as Sa, st as ha, t as va, tt as Ba, u as Ga, ut as ca, v as la, vt as Na, w as Ea, x as pa, y as Ta, yt as ma, z as ua } from "../core-Bjta9Y7_.js";
1
+ import { $ as a, $t as e, A as s, At as i, B as o, Bt as r, C as n, Ct as h, D as S, Dt as B, E as v, Et as p, F as g, Ft as u, G as c, Gt as d, H as E, Ht as I, I as L, It as l, J as m, Jt as G, K as T, Kt as C, L as N, Lt as A, M as D, Mt as O, N as y, Nt as R, O as f, Ot as F, P as M, Pt as P, Q as w, Qt as _, R as b, Rt as U, S as X, St as x, T as k, Tt as W, U as z, Ut as H, V as Y, Vt as Q, W as V, Wt as j, X as q, Xt as J, Y as K, Yt as Z, Z as $, Zt as tt, _ as at, _t as et, a as st, at as it, b as ot, bt as rt, c as nt, ct as ht, d as St, dt as Bt, en as vt, et as pt, f as gt, ft as ut, g as ct, gt as dt, h as Et, ht as It, i as Lt, it as lt, j as mt, jt as Gt, k as Tt, kt as Ct, l as Nt, lt as At, m as Dt, mt as Ot, n as yt, nt as Rt, o as ft, ot as Ft, p as Mt, pt as Pt, q as wt, qt as _t, r as bt, rt as Ut, s as Xt, st as xt, t as kt, tn as Wt, tt as zt, u as Ht, ut as Yt, v as Qt, vt as Vt, w as jt, wt as qt, x as Jt, xt as Kt, y as Zt, yt as $t, z as ta, zt as aa } from "../core-HH6iRWtB.js";
2
2
  export {
3
- M as ALL_LOGIC_FAMILIES,
4
- Ea as BatteryBehavior,
5
- D as BatteryState,
6
- r as BehaviorRegistry,
7
- ea as CIRCUIT_FILE_VERSION,
8
- ha as COMPONENT_TYPE_METADATA,
9
- A as CameraOptions,
10
- d as Circuit,
11
- f as CircuitMetadata,
12
- Ba as CircuitOptions,
13
- ra as CircuitRunner,
14
- _ as ClockBehavior,
15
- c as ClockState,
16
- aa as Component,
17
- S as ComponentState,
18
- w as ComponentType,
19
- J as DEFAULT_LOGIC_FAMILY,
20
- R as DirtyTracker,
21
- la as DoubleThrowSwitchBehavior,
22
- m as DoubleThrowSwitchState,
23
- W as ENode,
24
- ca as ENodeSourceType,
25
- X as ENodeType,
26
- ta as EventQueue,
27
- x as InverterBehavior,
28
- v as InverterState,
29
- o as LightbulbBehavior,
30
- I as LightbulbState,
31
- ma as Memoize,
32
- b as MemoizeExpiring,
33
- K as Nand4GateBehavior,
34
- p as Nand4GateState,
35
- sa as Nand8GateBehavior,
36
- N as Nand8GateState,
37
- Y as NandGateBehavior,
38
- n as NandGateState,
39
- U as Nor4GateBehavior,
40
- j as Nor4GateState,
41
- Ga as Nor8GateBehavior,
42
- e as Nor8GateState,
43
- F as NorGateBehavior,
44
- l as NorGateState,
3
+ r as ALL_LOGIC_FAMILIES,
4
+ Jt as AdderBehavior,
5
+ zt as AdderState,
6
+ Ut as ArithmeticState,
7
+ o as BatteryBehavior,
8
+ Kt as BatteryState,
9
+ E as BehaviorRegistry,
10
+ Q as CIRCUIT_FILE_VERSION,
11
+ I as COMPONENT_TYPE_METADATA,
12
+ _ as CameraOptions,
13
+ Gt as Circuit,
14
+ u as CircuitMetadata,
15
+ l as CircuitOptions,
16
+ st as CircuitRunner,
17
+ y as ClockBehavior,
18
+ Ot as ClockState,
19
+ A as Component,
20
+ x as ComponentState,
21
+ H as ComponentType,
22
+ j as DEFAULT_LOGIC_FAMILY,
23
+ Xt as DirtyTracker,
24
+ M as DoubleThrowSwitchBehavior,
25
+ It as DoubleThrowSwitchState,
26
+ aa as ENode,
27
+ d as ENodeSourceType,
28
+ C as ENodeType,
29
+ ot as EightBitAdderBehavior,
30
+ pt as EightBitAdderState,
31
+ Zt as EightBitOnesComplementBehavior,
32
+ a as EightBitOnesComplementState,
33
+ Dt as EightInputBehavior,
34
+ m as EightInputState,
35
+ Nt as EightLightBehavior,
36
+ z as EightLightState,
37
+ nt as EventQueue,
38
+ Et as FourInputBehavior,
39
+ K as FourInputState,
40
+ Ht as FourLightBehavior,
41
+ V as FourLightState,
42
+ X as HalfAdderBehavior,
43
+ Rt as HalfAdderState,
44
+ Qt as InputBehaviorMixin,
45
+ w as InputState,
46
+ D as InverterBehavior,
47
+ Pt as InverterState,
48
+ Mt as LightBehaviorMixin,
49
+ wt as LightState,
50
+ ta as LightbulbBehavior,
51
+ rt as LightbulbState,
52
+ vt as Memoize,
53
+ Wt as MemoizeExpiring,
54
+ s as Nand4GateBehavior,
55
+ Bt as Nand4GateState,
56
+ Tt as Nand8GateBehavior,
57
+ Yt as Nand8GateState,
58
+ mt as NandGateBehavior,
59
+ ut as NandGateState,
60
+ S as Nor4GateBehavior,
61
+ ht as Nor4GateState,
62
+ v as Nor8GateBehavior,
63
+ xt as Nor8GateState,
64
+ f as NorGateBehavior,
65
+ At as NorGateState,
66
+ at as OneInputBehavior,
67
+ $ as OneInputState,
68
+ gt as OneLightBehavior,
69
+ T as OneLightState,
45
70
  Z as Position,
46
- Na as Position3D,
47
- u as RectangleLEDBehavior,
48
- L as RectangleLEDState,
49
- pa as RelayBehavior,
50
- s as RelayState,
51
- oa as Rotation,
52
- B as SIMULATION_SPEED,
53
- G as SimulationState,
54
- O as SmallLEDBehavior,
55
- h as SmallLEDState,
56
- V as StateManager,
57
- Ta as SwitchBehavior,
58
- ua as SwitchState,
59
- y as TRANSITION_DEFAULTS,
60
- na as Wire,
61
- P as Xor4GateBehavior,
62
- E as Xor4GateState,
63
- Sa as Xor8GateBehavior,
64
- i as Xor8GateState,
65
- H as XorGateBehavior,
66
- q as XorGateState,
67
- g as classifyGate,
68
- T as computeGateDelay,
69
- t as computeTransitionSpan,
70
- Q as findPositionBestIndex,
71
- k as generateUUID,
72
- C as getTransitionSpan,
73
- va as registerBasicComponentsBehaviors,
74
- $ as registerGatesComponentsBehaviors,
75
- z as simplifyPositions,
76
- ia as unionElectricalStates
71
+ e as Position3D,
72
+ b as RectangleLEDBehavior,
73
+ Vt as RectangleLEDState,
74
+ N as RelayBehavior,
75
+ et as RelayState,
76
+ G as Rotation,
77
+ W as SIMULATION_SPEED,
78
+ h as SimulationState,
79
+ L as SmallLEDBehavior,
80
+ $t as SmallLEDState,
81
+ ft as StateManager,
82
+ g as SwitchBehavior,
83
+ dt as SwitchState,
84
+ p as TRANSITION_DEFAULTS,
85
+ ct as TwoInputBehavior,
86
+ q as TwoInputState,
87
+ St as TwoLightBehavior,
88
+ c as TwoLightState,
89
+ U as Wire,
90
+ jt as Xor4GateBehavior,
91
+ it as Xor4GateState,
92
+ n as Xor8GateBehavior,
93
+ lt as Xor8GateState,
94
+ k as XorGateBehavior,
95
+ Ft as XorGateState,
96
+ O as classifyGate,
97
+ R as computeGateDelay,
98
+ P as computeTransitionSpan,
99
+ B as findBpsAtLogicDistance,
100
+ F as findBpsAtLogicDistanceWithPath,
101
+ Ct as findPinsReachableFromBp,
102
+ i as findPinsReachableFromBpWithPath,
103
+ J as findPositionBestIndex,
104
+ _t as generateUUID,
105
+ Y as getTransitionSpan,
106
+ kt as registerArithmeticComponentsBehaviors,
107
+ yt as registerBasicComponentsBehaviors,
108
+ bt as registerGatesComponentsBehaviors,
109
+ Lt as registerInterfaceComponentsBehaviors,
110
+ tt as simplifyPositions,
111
+ qt as unionElectricalStates
77
112
  };
@@ -15,3 +15,21 @@ export declare function registerBasicComponentsBehaviors(registry: BehaviorRegis
15
15
  * @return the input behavior registry for chaining
16
16
  */
17
17
  export declare function registerGatesComponentsBehaviors(registry: BehaviorRegistry): BehaviorRegistry;
18
+ /**
19
+ * Register all arithmetic component behaviors in the given registry
20
+ * Arithmetic components are : HalfAdder, Adder, 8bit adder, 8bit one's complement
21
+ * @public
22
+ * @param registry
23
+ * @return the input behavior registry for chaining
24
+ */
25
+ export declare function registerArithmeticComponentsBehaviors(registry: BehaviorRegistry): BehaviorRegistry;
26
+ /**
27
+ * Register all interface component behaviors in the given registry.
28
+ * Interface components are:
29
+ * - inputs: OneInput, TwoInput, FourInput, EightInput
30
+ * - lights: OneLight, TwoLight, FourLight, EightLight
31
+ * @public
32
+ * @param registry
33
+ * @return the input behavior registry for chaining
34
+ */
35
+ export declare function registerInterfaceComponentsBehaviors(registry: BehaviorRegistry): BehaviorRegistry;
@@ -0,0 +1,28 @@
1
+ import { Component } from '../../../topology/Component';
2
+ import { ComponentState } from '../../states/ComponentState';
3
+ import { INodeElectricalState } from '../../states/types';
4
+ import { IComponentBehavior } from '../types';
5
+ import { ArithmeticBehaviorMixin } from './ArithmeticBehaviorMixin';
6
+ /**
7
+ * Behavior for the Full Adder component (two half adders + OR on carries).
8
+ *
9
+ * Three logic inputs (`inputA`, `inputB`, `carryIn`) and two logic outputs
10
+ * (`sum`, `carryOut`):
11
+ *
12
+ * - `sum = A XOR B XOR carryIn` (parity of the three inputs)
13
+ * - `carryOut = majority(A, B, carryIn)` (two or more inputs high)
14
+ *
15
+ * State encoding follows `${sumBit}${carryBit}` — see {@link AdderState}. All
16
+ * four stable states are reachable; `A = B = carryIn = 1` yields `'11'`.
17
+ *
18
+ * A single medium `transitionSpan` from config is used for every transition,
19
+ * since modeling the cumulative XOR/AND/OR delays per input-output pair would
20
+ * be more complexity than this library's teaching scope warrants.
21
+ *
22
+ * @public
23
+ */
24
+ export declare class AdderBehavior extends ArithmeticBehaviorMixin implements IComponentBehavior {
25
+ constructor();
26
+ createInitialState(component: Component): ComponentState;
27
+ protected computeTargetStableState(pinStates: Map<string, INodeElectricalState>): string;
28
+ }
@@ -0,0 +1,63 @@
1
+ import { Component } from '../../../topology/Component';
2
+ import { ComponentState } from '../../states/ComponentState';
3
+ import { INodeElectricalState } from '../../states/types';
4
+ import { UUID } from '../../../utils/types';
5
+ import { ENodeSourceType } from '../../../topology/types';
6
+ import { IBehaviorResult } from '../types';
7
+ import { IScheduledEvent } from '../../types';
8
+ import { ComponentBehaviorMixin } from '../ComponentBehavior';
9
+ import { ArithmeticState } from '../../states/arithmetic/ArithmeticState';
10
+ /**
11
+ * Factorises the common plumbing of arithmetic component behaviors:
12
+ *
13
+ * - `vccGuardBehavior` — on vcc loss, drop all outputs low immediately.
14
+ * - `nonLogicInputGuardBehavior` — on any ill-defined logic input, go to
15
+ * `'indeterminate'` immediately.
16
+ * - `onPinsChange` is a **template method** that runs the guards then calls
17
+ * `computeTargetStableState` (subclass-provided) and schedules the
18
+ * transition via `scheduleTransition`.
19
+ * - `scheduleTransition` — encode the `to${target}` transient state, schedule
20
+ * the completion event and preserve the previous stable state in
21
+ * `parameters.prevState` so `allowConductivity` keeps the old outputs
22
+ * energized until the transition fires.
23
+ * - `onEventFiring` — land on the target stable state when the scheduled
24
+ * transition completes.
25
+ * - `allowConductivity` — generic per-output lookup driven by
26
+ *
27
+ * Subclasses must declare `outputPinLabels` in the **same order** as the
28
+ * state encoding used by their {@link ArithmeticState} subclass and
29
+ * implement `computeTargetStableState` to turn the current input pins into
30
+ * that encoding.
31
+ */
32
+ export declare abstract class ArithmeticBehaviorMixin extends ComponentBehaviorMixin {
33
+ /**
34
+ * Compute the target stable-state encoding from the current pin states.
35
+ * Called only after vcc / non-logic guards have passed.
36
+ */
37
+ protected abstract computeTargetStableState(pinStates: Map<string, INodeElectricalState>): string;
38
+ onPinsChange(component: Component, state: ComponentState, nodeStates: ReadonlyMap<UUID, INodeElectricalState>, targetTick: number): IBehaviorResult;
39
+ onEventFiring(_component: Component, state: ComponentState, event: IScheduledEvent): IBehaviorResult;
40
+ allowConductivity(component: Component, state: ComponentState, _conductivityType: ENodeSourceType, pinId: string, otherPinId: string): boolean;
41
+ /**
42
+ * On vcc loss: all outputs go low immediately.
43
+ * Returns `null` when vcc is present so callers can proceed.
44
+ */
45
+ protected vccGuardBehavior(state: ArithmeticState, pinStates: Map<string, INodeElectricalState>, targetTick: number): IBehaviorResult | null;
46
+ /**
47
+ * Scan all logic inputs; if any is ill-defined (both voltage and ground,
48
+ * or neither), switch to `'indeterminate'` immediately. Otherwise returns
49
+ * `null` so the caller can proceed.
50
+ */
51
+ protected nonLogicInputGuardBehavior(state: ArithmeticState, pinStates: Map<string, INodeElectricalState>, targetTick: number): IBehaviorResult | null;
52
+ /**
53
+ * Schedule a transition toward the given stable target state. If already
54
+ * there (or already heading there) returns a no-change result.
55
+ *
56
+ * Preserves the currently-driving stable state in `parameters.prevState` so
57
+ * `allowConductivity` keeps the old outputs energized until the scheduled
58
+ * event fires. When the previous effective state is `'indeterminate'` the
59
+ * fallback is all-zeros.
60
+ */
61
+ protected scheduleTransition(component: Component, state: ArithmeticState, targetState: string, targetTick: number): IBehaviorResult;
62
+ protected noChange(state: ComponentState): IBehaviorResult;
63
+ }
@@ -0,0 +1,51 @@
1
+ import { Component } from '../../../topology/Component';
2
+ import { ComponentState } from '../../states/ComponentState';
3
+ import { INodeElectricalState } from '../../states/types';
4
+ import { IComponentBehavior, IBehaviorResult } from '../types';
5
+ import { IScheduledEvent } from '../../types';
6
+ import { UUID } from '../../../utils/types';
7
+ import { ArithmeticBehaviorMixin } from './ArithmeticBehaviorMixin';
8
+ /**
9
+ * Behavior for the 8-bit ripple carry adder (8 full adders in series).
10
+ *
11
+ * Unlike the single full adder whose output settles in one transition, the
12
+ * 8-bit adder models **carry propagation**: when inputs change, only stage 0
13
+ * recomputes immediately (with its own propagation delay); the carry then
14
+ * ripples through stages 1–7, one `transitionSpan` per stage.
15
+ *
16
+ * ### State encoding
17
+ *
18
+ * 16 interleaved bits `C7S7 C6S6 … C1S1 C0S0` stored as a 4-digit hex
19
+ * string. Sum at bit `2*i`, carry at bit `2*i+1`.
20
+ * See {@link EightBitAdderState}.
21
+ *
22
+ * ### Ripple algorithm
23
+ *
24
+ * - **`onPinsChange`**: computes ALL 8 stages with new inputs but **old
25
+ * carries** from the current effective state, producing an intermediate
26
+ * state. Schedules one event for carry propagation starting at stage 1.
27
+ * Uses `shouldCancelPending: true` to restart the ripple cleanly when
28
+ * inputs change mid-propagation.
29
+ *
30
+ * - **`onEventFiring`**: lands on the intermediate, then checks whether the
31
+ * next stage's carry-in changed. If so, recomputes that stage, builds the
32
+ * next intermediate, and schedules the following stage. If not, the carry
33
+ * has stopped and the state is stable. Uses `shouldCancelPending: false`.
34
+ *
35
+ * - **Initialization shortcut**: at `targetTick === 0` the full stable state
36
+ * is computed directly via {@link computeTargetStableState} to avoid the
37
+ * init-loop limitation where chained events are dropped.
38
+ *
39
+ * @public
40
+ */
41
+ export declare class EightBitAdderBehavior extends ArithmeticBehaviorMixin implements IComponentBehavior {
42
+ constructor();
43
+ createInitialState(component: Component): ComponentState;
44
+ onPinsChange(component: Component, state: ComponentState, nodeStates: ReadonlyMap<UUID, INodeElectricalState>, targetTick: number): IBehaviorResult;
45
+ onEventFiring(component: Component, state: ComponentState, event: IScheduledEvent): IBehaviorResult;
46
+ /**
47
+ * Compute the fully-settled stable state by propagating the carry chain
48
+ * through all 8 stages. Used at initialization and for test verification.
49
+ */
50
+ protected computeTargetStableState(pinStates: Map<string, INodeElectricalState>): string;
51
+ }
@@ -0,0 +1,29 @@
1
+ import { Component } from '../../../topology/Component';
2
+ import { ComponentState } from '../../states/ComponentState';
3
+ import { INodeElectricalState } from '../../states/types';
4
+ import { IComponentBehavior } from '../types';
5
+ import { ENodeSourceType } from '../../../topology/types';
6
+ import { ArithmeticBehaviorMixin } from './ArithmeticBehaviorMixin';
7
+ /**
8
+ * Behavior for the 8-bit one's complement (8 parallel XOR gates with shared
9
+ * `invert` input).
10
+ *
11
+ * When `invert` is high every output is the bitwise NOT of its input; when low
12
+ * outputs pass through unchanged. All 8 gates fire in parallel — a single
13
+ * `transitionSpan` covers the whole transition (no ripple).
14
+ *
15
+ * State encoding: 9 bits as a 3-hex-char string. Bits 0–7 are outputs,
16
+ * bit 8 is the invert flag. See {@link EightBitOnesComplementState}.
17
+ *
18
+ * The mixin's default `onPinsChange` / `onEventFiring` / `scheduleTransition`
19
+ * handle everything — only `computeTargetStableState` and
20
+ * `allowConductivity` need implementation.
21
+ *
22
+ * @public
23
+ */
24
+ export declare class EightBitOnesComplementBehavior extends ArithmeticBehaviorMixin implements IComponentBehavior {
25
+ constructor();
26
+ createInitialState(component: Component): ComponentState;
27
+ allowConductivity(component: Component, state: ComponentState, _conductivityType: ENodeSourceType, pinId: string, otherPinId: string): boolean;
28
+ protected computeTargetStableState(pinStates: Map<string, INodeElectricalState>): string;
29
+ }
@@ -0,0 +1,22 @@
1
+ import { Component } from '../../../topology/Component';
2
+ import { ComponentState } from '../../states/ComponentState';
3
+ import { INodeElectricalState } from '../../states/types';
4
+ import { IComponentBehavior } from '../types';
5
+ import { ArithmeticBehaviorMixin } from './ArithmeticBehaviorMixin';
6
+ /**
7
+ * Behavior for the Half Adder component (XOR + AND in one block).
8
+ *
9
+ * - `sum = A XOR B`
10
+ * - `carry = A AND B`
11
+ *
12
+ * State encoding follows `${sumBit}${carryBit}` — see {@link HalfAdderState}.
13
+ * Because `sum` and `carry` can never both be high, only three stable states
14
+ * are reachable: `'00' | '10' | '01'`.
15
+ *
16
+ * @public
17
+ */
18
+ export declare class HalfAdderBehavior extends ArithmeticBehaviorMixin implements IComponentBehavior {
19
+ constructor();
20
+ createInitialState(component: Component): ComponentState;
21
+ protected computeTargetStableState(pinStates: Map<string, INodeElectricalState>): string;
22
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Arithmetic components behaviors
3
+ * @module core/simulation/behaviors
4
+ */
5
+ export { ArithmeticBehaviorMixin } from './ArithmeticBehaviorMixin';
6
+ export { HalfAdderBehavior } from './HalfAdderBehavior';
7
+ export { AdderBehavior } from './AdderBehavior';
@@ -22,3 +22,17 @@ export { Nor8GateBehavior } from './gates/Nor8GateBehavior';
22
22
  export { XorGateBehavior } from './gates/XorGateBehavior';
23
23
  export { Xor4GateBehavior } from './gates/Xor4GateBehavior';
24
24
  export { Xor8GateBehavior } from './gates/Xor8GateBehavior';
25
+ export { HalfAdderBehavior } from './arithmetic/HalfAdderBehavior';
26
+ export { AdderBehavior } from './arithmetic/AdderBehavior';
27
+ export { EightBitAdderBehavior } from './arithmetic/EightBitAdderBehavior';
28
+ export { EightBitOnesComplementBehavior } from './arithmetic/EightBitOnesComplementBehavior';
29
+ export { InputBehaviorMixin } from './interface/InputBehaviorMixin';
30
+ export { OneInputBehavior } from './interface/OneInputBehavior';
31
+ export { TwoInputBehavior } from './interface/TwoInputBehavior';
32
+ export { FourInputBehavior } from './interface/FourInputBehavior';
33
+ export { EightInputBehavior } from './interface/EightInputBehavior';
34
+ export { LightBehaviorMixin } from './interface/LightBehaviorMixin';
35
+ export { OneLightBehavior } from './interface/OneLightBehavior';
36
+ export { TwoLightBehavior } from './interface/TwoLightBehavior';
37
+ export { FourLightBehavior } from './interface/FourLightBehavior';
38
+ export { EightLightBehavior } from './interface/EightLightBehavior';
@@ -0,0 +1,9 @@
1
+ import { Component } from '../../../topology/Component';
2
+ import { ComponentState } from '../../states/ComponentState';
3
+ import { IComponentBehavior } from '../types';
4
+ import { InputBehaviorMixin } from './InputBehaviorMixin';
5
+ /** Eight-switch user input. See {@link InputBehaviorMixin}. */
6
+ export declare class EightInputBehavior extends InputBehaviorMixin implements IComponentBehavior {
7
+ constructor();
8
+ createInitialState(component: Component): ComponentState;
9
+ }
@@ -0,0 +1,9 @@
1
+ import { Component } from '../../../topology/Component';
2
+ import { ComponentState } from '../../states/ComponentState';
3
+ import { IComponentBehavior } from '../types';
4
+ import { LightBehaviorMixin } from './LightBehaviorMixin';
5
+ /** Eight-light input mirror. See {@link LightBehaviorMixin}. */
6
+ export declare class EightLightBehavior extends LightBehaviorMixin implements IComponentBehavior {
7
+ constructor();
8
+ createInitialState(component: Component): ComponentState;
9
+ }
@@ -0,0 +1,9 @@
1
+ import { Component } from '../../../topology/Component';
2
+ import { ComponentState } from '../../states/ComponentState';
3
+ import { IComponentBehavior } from '../types';
4
+ import { InputBehaviorMixin } from './InputBehaviorMixin';
5
+ /** Four-switch user input. See {@link InputBehaviorMixin}. */
6
+ export declare class FourInputBehavior extends InputBehaviorMixin implements IComponentBehavior {
7
+ constructor();
8
+ createInitialState(component: Component): ComponentState;
9
+ }
@@ -0,0 +1,9 @@
1
+ import { Component } from '../../../topology/Component';
2
+ import { ComponentState } from '../../states/ComponentState';
3
+ import { IComponentBehavior } from '../types';
4
+ import { LightBehaviorMixin } from './LightBehaviorMixin';
5
+ /** Four-light input mirror. See {@link LightBehaviorMixin}. */
6
+ export declare class FourLightBehavior extends LightBehaviorMixin implements IComponentBehavior {
7
+ constructor();
8
+ createInitialState(component: Component): ComponentState;
9
+ }
@@ -0,0 +1,37 @@
1
+ import { Component } from '../../../topology/Component';
2
+ import { ComponentState } from '../../states/ComponentState';
3
+ import { INodeElectricalState } from '../../states/types';
4
+ import { UUID } from '../../../utils/types';
5
+ import { ENodeSourceType } from '../../../topology/types';
6
+ import { IScheduledEvent, IUserCommand } from '../../types';
7
+ import { IBehaviorResult } from '../types';
8
+ import { ComponentBehaviorMixin } from '../ComponentBehavior';
9
+ /**
10
+ * Factorises the plumbing shared by `OneInput`, `TwoInput`, `FourInput` and
11
+ * `EightInput` behaviors.
12
+ *
13
+ * These components only react to user actions (`toggle_input` commands) — they
14
+ * have no logic inputs. The state encodes the current outputs as a hex value
15
+ * (e.g. `'5'` = `0101` for FourInput); while at least one switch is moving the
16
+ * state literal is `'moving'` and a parameter map tracks each pending switch
17
+ * (`${index}` → `${target}-${startTick}-${endTick}`) plus the actual driving
18
+ * value in `prevState`.
19
+ *
20
+ * Concurrency model:
21
+ * - Toggling a different switch while another is still moving simply adds a
22
+ * new pending entry — both transitions resolve independently. No
23
+ * `shouldCancelPending`.
24
+ * - Toggling the *same* switch a second time is debounced (the second command
25
+ * is silently ignored).
26
+ * - Vcc loss collapses the state to `allLowState` and clears all pending
27
+ * transitions.
28
+ *
29
+ * @public
30
+ */
31
+ export declare abstract class InputBehaviorMixin extends ComponentBehaviorMixin {
32
+ onPinsChange(component: Component, state: ComponentState, nodeStates: ReadonlyMap<UUID, INodeElectricalState>, targetTick: number): IBehaviorResult;
33
+ onUserCommand(component: Component, state: ComponentState, command: IUserCommand): IBehaviorResult;
34
+ onEventFiring(_component: Component, state: ComponentState, event: IScheduledEvent): IBehaviorResult;
35
+ allowConductivity(component: Component, state: ComponentState, _conductivityType: ENodeSourceType, pinId: string, otherPinId: string): boolean;
36
+ protected noChange(state: ComponentState): IBehaviorResult;
37
+ }