simple-circuit-engine 0.0.11 → 0.0.13
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/AGENTS.md +11 -7
- package/CLAUDE.md +6 -6
- package/README.md +5 -2
- package/dist/core/index.d.ts +0 -1
- package/dist/core/index.js +85 -2115
- package/dist/core/setup.d.ts +25 -0
- package/dist/core/simulation/CircuitRunner.d.ts +176 -0
- package/dist/core/simulation/DirtyTracker.d.ts +87 -0
- package/dist/core/simulation/EventQueue.d.ts +68 -0
- package/dist/core/simulation/StateManager.d.ts +100 -0
- package/dist/core/simulation/behaviors/BehaviorRegistry.d.ts +70 -0
- package/dist/core/simulation/behaviors/ComponentBehavior.d.ts +53 -0
- package/dist/core/simulation/behaviors/arithmetic/AdderBehavior.d.ts +28 -0
- package/dist/core/simulation/behaviors/arithmetic/ArithmeticBehaviorMixin.d.ts +63 -0
- package/dist/core/simulation/behaviors/arithmetic/EightBitAdderBehavior.d.ts +51 -0
- package/dist/core/simulation/behaviors/arithmetic/EightBitOnesComplementBehavior.d.ts +29 -0
- package/dist/core/simulation/behaviors/arithmetic/HalfAdderBehavior.d.ts +22 -0
- package/dist/core/simulation/behaviors/arithmetic/index.d.ts +7 -0
- package/dist/core/simulation/behaviors/basic/BatteryBehavior.d.ts +14 -0
- package/dist/core/simulation/behaviors/basic/ClockBehavior.d.ts +24 -0
- package/dist/core/simulation/behaviors/basic/DoubleThrowSwitchBehavior.d.ts +33 -0
- package/dist/core/simulation/behaviors/basic/LightbulbBehavior.d.ts +23 -0
- package/dist/core/simulation/behaviors/basic/RectangleLEDBehavior.d.ts +24 -0
- package/dist/core/simulation/behaviors/basic/RelayBehavior.d.ts +33 -0
- package/dist/core/simulation/behaviors/basic/SmallLEDBehavior.d.ts +24 -0
- package/dist/core/simulation/behaviors/basic/SwitchBehavior.d.ts +33 -0
- package/dist/core/simulation/behaviors/basic/index.d.ts +20 -0
- package/dist/core/simulation/behaviors/gates/InverterBehavior.d.ts +29 -0
- package/dist/core/simulation/behaviors/gates/Nand4GateBehavior.d.ts +18 -0
- package/dist/core/simulation/behaviors/gates/Nand8GateBehavior.d.ts +18 -0
- package/dist/core/simulation/behaviors/gates/NandGateBehavior.d.ts +28 -0
- package/dist/core/simulation/behaviors/gates/Nor4GateBehavior.d.ts +18 -0
- package/dist/core/simulation/behaviors/gates/Nor8GateBehavior.d.ts +18 -0
- package/dist/core/simulation/behaviors/gates/NorGateBehavior.d.ts +22 -0
- package/dist/core/simulation/behaviors/gates/Xor4GateBehavior.d.ts +18 -0
- package/dist/core/simulation/behaviors/gates/Xor8GateBehavior.d.ts +18 -0
- package/dist/core/simulation/behaviors/gates/XorGateBehavior.d.ts +22 -0
- package/dist/core/simulation/behaviors/gates/index.d.ts +34 -0
- package/dist/core/simulation/behaviors/index.d.ts +28 -0
- package/dist/core/simulation/behaviors/types.d.ts +101 -0
- package/dist/core/simulation/index.d.ts +18 -0
- package/dist/core/simulation/states/ComponentState.d.ts +57 -0
- package/dist/core/simulation/states/SimulationState.d.ts +46 -0
- package/dist/core/simulation/states/arithmetic/AdderState.d.ts +16 -0
- package/dist/core/simulation/states/arithmetic/ArithmeticState.d.ts +53 -0
- package/dist/core/simulation/states/arithmetic/EightBitAdderState.d.ts +25 -0
- package/dist/core/simulation/states/arithmetic/EightBitOnesComplementState.d.ts +18 -0
- package/dist/core/simulation/states/arithmetic/HalfAdderState.d.ts +16 -0
- package/dist/core/simulation/states/arithmetic/index.d.ts +7 -0
- package/dist/core/simulation/states/basic/BatteryState.d.ts +16 -0
- package/dist/core/simulation/states/basic/ClockState.d.ts +16 -0
- package/dist/core/simulation/states/basic/DoubleThrowSwitchState.d.ts +21 -0
- package/dist/core/simulation/states/basic/LightbulbState.d.ts +21 -0
- package/dist/core/simulation/states/basic/RectangleLEDState.d.ts +9 -0
- package/dist/core/simulation/states/basic/RelayState.d.ts +25 -0
- package/dist/core/simulation/states/basic/SmallLEDState.d.ts +21 -0
- package/dist/core/simulation/states/basic/SwitchState.d.ts +25 -0
- package/dist/core/simulation/states/gates/InverterState.d.ts +17 -0
- package/dist/core/simulation/states/gates/Nand4GateState.d.ts +10 -0
- package/dist/core/simulation/states/gates/Nand8GateState.d.ts +10 -0
- package/dist/core/simulation/states/gates/NandGateState.d.ts +16 -0
- package/dist/core/simulation/states/gates/Nor4GateState.d.ts +10 -0
- package/dist/core/simulation/states/gates/Nor8GateState.d.ts +10 -0
- package/dist/core/simulation/states/gates/NorGateState.d.ts +10 -0
- package/dist/core/simulation/states/gates/Xor4GateState.d.ts +10 -0
- package/dist/core/simulation/states/gates/Xor8GateState.d.ts +10 -0
- package/dist/core/simulation/states/gates/XorGateState.d.ts +10 -0
- package/dist/core/simulation/states/gates/index.d.ts +25 -0
- package/dist/core/simulation/states/index.d.ts +31 -0
- package/dist/core/simulation/states/types.d.ts +32 -0
- package/dist/core/simulation/types.d.ts +155 -0
- package/dist/core/topology/Circuit.d.ts +420 -0
- package/dist/core/topology/CircuitMetadata.d.ts +24 -0
- package/dist/core/topology/CircuitOptions.d.ts +14 -0
- package/dist/core/topology/Component.d.ts +153 -0
- package/dist/core/topology/ENode.d.ts +200 -0
- package/dist/core/topology/Wire.d.ts +130 -0
- package/dist/core/topology/delays.d.ts +52 -0
- package/dist/core/topology/index.d.ts +14 -0
- package/dist/core/topology/types.d.ts +189 -0
- package/dist/core/utils/CameraOptions.d.ts +83 -0
- package/dist/core/utils/MemoizeDecorator.d.ts +9 -0
- package/dist/core/utils/Position.d.ts +166 -0
- package/dist/core/utils/Position3D.d.ts +77 -0
- package/dist/core/utils/Rotation.d.ts +82 -0
- package/dist/core/utils/index.d.ts +24 -0
- package/dist/core/utils/types.d.ts +35 -0
- package/dist/core-b6Q8w2sn.js +3560 -0
- package/dist/core-b6Q8w2sn.js.map +1 -0
- package/dist/i18n/index.d.ts +882 -0
- package/dist/i18n/locales/en.json.d.ts +268 -0
- package/dist/i18n/locales/fr.json.d.ts +268 -0
- package/dist/index.d.ts +14 -6306
- package/dist/index.js +136 -112
- package/dist/scene/CircuitEngine.d.ts +283 -0
- package/dist/scene/index.d.ts +1 -2
- package/dist/scene/index.js +50 -41
- package/dist/scene/setup.d.ts +26 -0
- package/dist/scene/shared/AbstractCircuitController.d.ts +217 -0
- package/dist/scene/shared/BranchingPointVisualFactory.d.ts +70 -0
- package/dist/scene/shared/EventEmitter.d.ts +92 -0
- package/dist/scene/shared/HoverManager.d.ts +151 -0
- package/dist/scene/shared/SelectionManager.d.ts +159 -0
- package/dist/scene/shared/WireVisualManager.d.ts +242 -0
- package/dist/scene/shared/components/ComponentVisualFactory.d.ts +438 -0
- package/dist/scene/shared/components/DefaultVisualFactory.d.ts +51 -0
- package/dist/scene/shared/components/FactoryRegistry.d.ts +84 -0
- package/dist/scene/shared/components/GroupedFactoryRegistry.d.ts +153 -0
- package/dist/scene/shared/components/arithmetic/AdderVisualFactory.d.ts +54 -0
- package/dist/scene/shared/components/arithmetic/EightBitAdderVisualFactory.d.ts +45 -0
- package/dist/scene/shared/components/arithmetic/EightBitOnesComplementVisualFactory.d.ts +63 -0
- package/dist/scene/shared/components/arithmetic/HalfAdderVisualFactory.d.ts +55 -0
- package/dist/scene/shared/components/arithmetic/index.d.ts +4 -0
- package/dist/scene/shared/components/basic/BatteryVisualFactory.d.ts +13 -0
- package/dist/scene/shared/components/basic/ClockVisualFactory.d.ts +79 -0
- package/dist/scene/shared/components/basic/DoubleThrowSwitchVisualFactory.d.ts +87 -0
- package/dist/scene/shared/components/basic/LabelVisualFactory.d.ts +148 -0
- package/dist/scene/shared/components/basic/LightbulbVisualFactory.d.ts +72 -0
- package/dist/scene/shared/components/basic/RectangleLEDVisualFactory.d.ts +86 -0
- package/dist/scene/shared/components/basic/RelayVisualFactory.d.ts +92 -0
- package/dist/scene/shared/components/basic/SmallLEDVisualFactory.d.ts +86 -0
- package/dist/scene/shared/components/basic/SwitchVisualFactory.d.ts +85 -0
- package/dist/scene/shared/components/gates/InverterVisualFactory.d.ts +104 -0
- package/dist/scene/shared/components/gates/Nand4GateVisualFactory.d.ts +27 -0
- package/dist/scene/shared/components/gates/Nand8GateVisualFactory.d.ts +27 -0
- package/dist/scene/shared/components/gates/NandGateVisualFactory.d.ts +101 -0
- package/dist/scene/shared/components/gates/Nor4GateVisualFactory.d.ts +27 -0
- package/dist/scene/shared/components/gates/Nor8GateVisualFactory.d.ts +27 -0
- package/dist/scene/shared/components/gates/NorGateVisualFactory.d.ts +101 -0
- package/dist/scene/shared/components/gates/Xor4GateVisualFactory.d.ts +29 -0
- package/dist/scene/shared/components/gates/Xor8GateVisualFactory.d.ts +29 -0
- package/dist/scene/shared/components/gates/XorGateVisualFactory.d.ts +103 -0
- package/dist/scene/shared/components/index.d.ts +33 -0
- package/dist/scene/shared/components/types.d.ts +43 -0
- package/dist/scene/shared/types.d.ts +474 -0
- package/dist/scene/shared/utils/CameraUtils.d.ts +23 -0
- package/dist/scene/shared/utils/ColorUtils.d.ts +26 -0
- package/dist/scene/shared/utils/ControlsUtils.d.ts +8 -0
- package/dist/scene/shared/utils/GeometryUtils.d.ts +337 -0
- package/dist/scene/shared/utils/LayerConstants.d.ts +40 -0
- package/dist/scene/shared/utils/LightingUtils.d.ts +31 -0
- package/dist/scene/shared/utils/MaterialUtils.d.ts +73 -0
- package/dist/scene/shared/utils/Options.d.ts +16 -0
- package/dist/scene/simulation/CircuitRunnerController.d.ts +227 -0
- package/dist/scene/static/CircuitController.d.ts +228 -0
- package/dist/scene/static/CircuitWriter.d.ts +146 -0
- package/dist/scene/static/PinTooltipWidget.d.ts +31 -0
- package/dist/scene/static/tools/BuildTool.d.ts +290 -0
- package/dist/scene/static/tools/ComponentPickerWidget.d.ts +89 -0
- package/dist/scene/static/tools/ConfigPanelWidget.d.ts +107 -0
- package/dist/scene/static/tools/MultiSelectTool.d.ts +265 -0
- package/dist/scene-D4QcWeiq.js +8745 -0
- package/dist/scene-D4QcWeiq.js.map +1 -0
- package/package.json +29 -25
- package/dist/CircuitRunner-BQQlhwjD.js +0 -1981
- package/dist/CircuitRunner-BQQlhwjD.js.map +0 -1
- package/dist/core/index.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/scene/index.js.map +0 -1
- package/dist/setup-CIq_kgaw.js +0 -10230
- package/dist/setup-CIq_kgaw.js.map +0 -1
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ComponentState } from '../ComponentState';
|
|
2
|
+
import { UUID } from '../../../utils/types';
|
|
3
|
+
/**
|
|
4
|
+
* Simulation state for Logic gates components
|
|
5
|
+
* Gates can be "low", "rising", "high", "falling" or "indeterminate" (if their input is not well-defined)
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export declare abstract class LogicGateState extends ComponentState {
|
|
10
|
+
/**
|
|
11
|
+
* Create a new Inverter state.
|
|
12
|
+
*
|
|
13
|
+
* @param componentId - UUID of the Inverter component
|
|
14
|
+
* @param initialState - Initial operational state (default: "low")
|
|
15
|
+
*/
|
|
16
|
+
protected constructor(componentId: UUID, initialState?: string);
|
|
17
|
+
/**
|
|
18
|
+
* Check if output is in a rising or falling transition
|
|
19
|
+
*/
|
|
20
|
+
get isInTransition(): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Check if output is high
|
|
23
|
+
*/
|
|
24
|
+
get isHigh(): boolean;
|
|
25
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simulation state definitions
|
|
3
|
+
* @module core/simulation/states
|
|
4
|
+
*/
|
|
5
|
+
export type { INodeElectricalState } from './types';
|
|
6
|
+
export { unionElectricalStates } from './types';
|
|
7
|
+
export { SimulationState } from './SimulationState.js';
|
|
8
|
+
export { ComponentState } from './ComponentState.js';
|
|
9
|
+
export { BatteryState } from './basic/BatteryState';
|
|
10
|
+
export { LightbulbState } from './basic/LightbulbState';
|
|
11
|
+
export { RectangleLEDState } from './basic/RectangleLEDState';
|
|
12
|
+
export { RelayState } from './basic/RelayState';
|
|
13
|
+
export { SmallLEDState } from './basic/SmallLEDState';
|
|
14
|
+
export { SwitchState } from './basic/SwitchState';
|
|
15
|
+
export { DoubleThrowSwitchState } from './basic/DoubleThrowSwitchState';
|
|
16
|
+
export { ClockState } from './basic/ClockState';
|
|
17
|
+
export { InverterState } from './gates/InverterState';
|
|
18
|
+
export { NandGateState } from './gates/NandGateState';
|
|
19
|
+
export { Nand4GateState } from './gates/Nand4GateState';
|
|
20
|
+
export { Nand8GateState } from './gates/Nand8GateState';
|
|
21
|
+
export { NorGateState } from './gates/NorGateState';
|
|
22
|
+
export { Nor4GateState } from './gates/Nor4GateState';
|
|
23
|
+
export { Nor8GateState } from './gates/Nor8GateState';
|
|
24
|
+
export { XorGateState } from './gates/XorGateState';
|
|
25
|
+
export { Xor4GateState } from './gates/Xor4GateState';
|
|
26
|
+
export { Xor8GateState } from './gates/Xor8GateState';
|
|
27
|
+
export { ArithmeticState } from './arithmetic/ArithmeticState';
|
|
28
|
+
export { HalfAdderState } from './arithmetic/HalfAdderState';
|
|
29
|
+
export { AdderState } from './arithmetic/AdderState';
|
|
30
|
+
export { EightBitAdderState } from './arithmetic/EightBitAdderState';
|
|
31
|
+
export { EightBitOnesComplementState } from './arithmetic/EightBitOnesComplementState';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Binary electrical state for wires and enodes (connection points)
|
|
3
|
+
* @module core/simulation/states
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export interface INodeElectricalState {
|
|
7
|
+
/**
|
|
8
|
+
* True if voltage is present at this node (potential > 0V).
|
|
9
|
+
* False if node is at ground potential or floating.
|
|
10
|
+
*/
|
|
11
|
+
hasVoltage: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* True if current is actively flowing through this node.
|
|
14
|
+
* False if no current flow (open circuit or equilibrium).
|
|
15
|
+
*/
|
|
16
|
+
hasCurrent: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* True only if the node is locked from state changes at circuit build time (ex: battery pins or other fixed-voltage/current pinSources).
|
|
19
|
+
* Important: Those nodes should never have their electrical state modified by the simulation controller!
|
|
20
|
+
* Always false for wires
|
|
21
|
+
*/
|
|
22
|
+
locked: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Compute the union of multiple electrical states.
|
|
26
|
+
* Useful to derive a combined pin state from two or more pins
|
|
27
|
+
* (e.g. cmd_in + cmd_out → coil state).
|
|
28
|
+
*
|
|
29
|
+
* @param states - Two or more electrical states to combine
|
|
30
|
+
* @returns A new state where hasVoltage/hasCurrent are OR'd across inputs, locked is always false
|
|
31
|
+
*/
|
|
32
|
+
export declare function unionElectricalStates(...states: INodeElectricalState[]): INodeElectricalState;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { UUID } from '../utils';
|
|
2
|
+
/**
|
|
3
|
+
* Simulation speed bounds and defaults for ticks per second (TPS).
|
|
4
|
+
* @public
|
|
5
|
+
*/
|
|
6
|
+
export declare const SIMULATION_SPEED: {
|
|
7
|
+
/**
|
|
8
|
+
* Minimum simulation speed in ticks per second
|
|
9
|
+
*/
|
|
10
|
+
readonly MIN_TPS: 1;
|
|
11
|
+
/**
|
|
12
|
+
* Maximum simulation speed in ticks per second
|
|
13
|
+
*/
|
|
14
|
+
readonly MAX_TPS: 100;
|
|
15
|
+
/**
|
|
16
|
+
* Default simulation speed in ticks per second
|
|
17
|
+
*/
|
|
18
|
+
readonly DEFAULT_TPS: 3;
|
|
19
|
+
/**
|
|
20
|
+
* Default tick interval in milliseconds (1000 / DEFAULT_TPS)
|
|
21
|
+
*/
|
|
22
|
+
readonly DEFAULT_INTERVAL_MS: 500;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Default transition timing values for components.
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
export declare const TRANSITION_DEFAULTS: {
|
|
29
|
+
/**
|
|
30
|
+
* Default transitionSpan for relays and transistors in ticks (instant transition)
|
|
31
|
+
*/
|
|
32
|
+
readonly TRANSITION_SPAN_TICKS: 1;
|
|
33
|
+
/**
|
|
34
|
+
* Default transitionUserSpan for switches in milliseconds
|
|
35
|
+
*/
|
|
36
|
+
readonly TRANSITION_USER_SPAN_MS: 200;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* User command to be executed during simulation.
|
|
40
|
+
* Commands can be queued for future ticks or executed immediately.
|
|
41
|
+
*
|
|
42
|
+
* @public
|
|
43
|
+
*/
|
|
44
|
+
export interface IUserCommand {
|
|
45
|
+
/**
|
|
46
|
+
* Type of command.
|
|
47
|
+
*/
|
|
48
|
+
readonly type: 'toggle_switch';
|
|
49
|
+
/**
|
|
50
|
+
* UUID of target component.
|
|
51
|
+
*/
|
|
52
|
+
readonly targetId: UUID;
|
|
53
|
+
/**
|
|
54
|
+
* tick when this command was scheduled.
|
|
55
|
+
*/
|
|
56
|
+
scheduledAtTick: number;
|
|
57
|
+
/**
|
|
58
|
+
* Extra parameters associated with this command.
|
|
59
|
+
*
|
|
60
|
+
* For `toggle_switch` commands:
|
|
61
|
+
* - `tickCount`: Number of ticks for the switch transition. Computed at toggle time
|
|
62
|
+
* using the formula: `ceil(transitionUserSpan × simulationSpeed / 1000)` with minimum of 1.
|
|
63
|
+
* If not provided, behavior uses default transition timing.
|
|
64
|
+
*/
|
|
65
|
+
readonly parameters?: Map<string, string> | null;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* all reachable nodes and wires from a seed
|
|
69
|
+
*/
|
|
70
|
+
export type IReachabilityResult = {
|
|
71
|
+
nodes: Set<UUID>;
|
|
72
|
+
wires: Set<UUID>;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Configuration options for CircuitRunner
|
|
76
|
+
*/
|
|
77
|
+
export interface IRunnerOptions {
|
|
78
|
+
/**
|
|
79
|
+
* Enable historical state tracking.
|
|
80
|
+
* When true, past simulation states are preserved up to historyLimit.
|
|
81
|
+
* When false (default), only current state is retained for better performance.
|
|
82
|
+
* @default false
|
|
83
|
+
*/
|
|
84
|
+
enableHistory?: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Maximum number of historical states to retain when enableHistory is true.
|
|
87
|
+
* Uses circular buffer—oldest states are overwritten when limit is reached.
|
|
88
|
+
* Must be a positive integer.
|
|
89
|
+
* @default 1000
|
|
90
|
+
*/
|
|
91
|
+
historyLimit?: number;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Result statistics of one simulation tick run
|
|
95
|
+
*/
|
|
96
|
+
export interface IRunnerResult {
|
|
97
|
+
startTick: number;
|
|
98
|
+
endTick: number;
|
|
99
|
+
componentUpdateCount: number;
|
|
100
|
+
nodeUpdateCount: number;
|
|
101
|
+
wireUpdateCount: number;
|
|
102
|
+
processedCommandCount: number;
|
|
103
|
+
scheduledEventCount: number;
|
|
104
|
+
firedEventCount: number;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Scheduled event for delayed component transitions.
|
|
108
|
+
* Events are ordered by readyAtTick in a min-heap priority queue.
|
|
109
|
+
* Events with same readyAtTick are processed in FIFO order (by scheduledAtTick).
|
|
110
|
+
*
|
|
111
|
+
* @public
|
|
112
|
+
*/
|
|
113
|
+
export interface IScheduledEvent {
|
|
114
|
+
/**
|
|
115
|
+
* UUID of target component.
|
|
116
|
+
*/
|
|
117
|
+
readonly targetId: UUID;
|
|
118
|
+
/**
|
|
119
|
+
* Tick when this event was scheduled (for FIFO ordering).
|
|
120
|
+
* @readonly
|
|
121
|
+
*/
|
|
122
|
+
readonly scheduledAtTick: number;
|
|
123
|
+
/**
|
|
124
|
+
* Tick when this event should be processed.
|
|
125
|
+
* @readonly
|
|
126
|
+
*/
|
|
127
|
+
readonly readyAtTick: number;
|
|
128
|
+
/**
|
|
129
|
+
* Indicates the type of this event, eg 'ClosingEnd', 'OpeningEnd', etc.
|
|
130
|
+
*/
|
|
131
|
+
readonly type: string;
|
|
132
|
+
/**
|
|
133
|
+
* extra parameters associated with this event.
|
|
134
|
+
*/
|
|
135
|
+
readonly parameters?: Map<string, string> | undefined;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Dirty elements collected during a tick, returned by getDirtyElements().
|
|
139
|
+
*
|
|
140
|
+
* @public
|
|
141
|
+
*/
|
|
142
|
+
export interface IDirtyElements {
|
|
143
|
+
/**
|
|
144
|
+
* Components that changed state.
|
|
145
|
+
*/
|
|
146
|
+
readonly components: ReadonlySet<UUID>;
|
|
147
|
+
/**
|
|
148
|
+
* Wires that changed electrical state.
|
|
149
|
+
*/
|
|
150
|
+
readonly wires: ReadonlySet<UUID>;
|
|
151
|
+
/**
|
|
152
|
+
* ENodes that changed electrical state.
|
|
153
|
+
*/
|
|
154
|
+
readonly enodes: ReadonlySet<UUID>;
|
|
155
|
+
}
|
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
import { UUID, Rotation, Position } from '../utils';
|
|
2
|
+
import { ComponentType, ENodeSourceType, ICircuit } from './types';
|
|
3
|
+
import { CircuitOptions } from './CircuitOptions';
|
|
4
|
+
import { CircuitMetadata } from './CircuitMetadata';
|
|
5
|
+
import { Component } from './Component';
|
|
6
|
+
import { ENode } from './ENode';
|
|
7
|
+
import { Wire } from './Wire';
|
|
8
|
+
/**
|
|
9
|
+
* Circuit container managing components, ENodes, and wires.
|
|
10
|
+
*
|
|
11
|
+
* The Circuit class provides:
|
|
12
|
+
* - Component management (add/remove with automatic pin ENode creation)
|
|
13
|
+
* - Topology queries (get by ID, enumerate all)
|
|
14
|
+
* - Automatic lifecycle management (cascade deletion, orphan cleanup)
|
|
15
|
+
* - JSON serialization for persistence
|
|
16
|
+
*
|
|
17
|
+
* **Key Principles**:
|
|
18
|
+
* - Users manage Components and Wires; ENodes are managed automatically
|
|
19
|
+
* - Removing a Component cascades to remove its pins and connected wires
|
|
20
|
+
* - Orphaned branching ENodes (no wires) are automatically removed
|
|
21
|
+
* - All operations maintain bidirectional consistency
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const circuit = new Circuit();
|
|
26
|
+
*
|
|
27
|
+
* // Add a component at position (10, 20) with 2 pins
|
|
28
|
+
* const lightbulb = circuit.addComponent(
|
|
29
|
+
* new Position(10, 20),
|
|
30
|
+
* new Rotation(90),
|
|
31
|
+
* 2
|
|
32
|
+
* );
|
|
33
|
+
*
|
|
34
|
+
* console.log(lightbulb.id); // UUID
|
|
35
|
+
* console.log(lightbulb.pins); // [pin-uuid-1, pin-uuid-2]
|
|
36
|
+
*
|
|
37
|
+
* // Query components
|
|
38
|
+
* const comp = circuit.getComponent(lightbulb.id);
|
|
39
|
+
* const all = circuit.getAllComponents();
|
|
40
|
+
*
|
|
41
|
+
* // Remove component (cascade deletes pins and wires)
|
|
42
|
+
* circuit.removeComponent(lightbulb.id);
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare class Circuit {
|
|
46
|
+
/**
|
|
47
|
+
* Circuit metadata holding general information.
|
|
48
|
+
* @private
|
|
49
|
+
*/
|
|
50
|
+
metadata: CircuitMetadata;
|
|
51
|
+
/**
|
|
52
|
+
* Map of all components in the circuit (UUID → Component).
|
|
53
|
+
* @private
|
|
54
|
+
*/
|
|
55
|
+
private components;
|
|
56
|
+
/**
|
|
57
|
+
* Map of all electrical nodes in the circuit (UUID → ENode).
|
|
58
|
+
* Includes both pin nodes and branching point nodes.
|
|
59
|
+
* @private
|
|
60
|
+
*/
|
|
61
|
+
private enodes;
|
|
62
|
+
/**
|
|
63
|
+
* Map of all wires in the circuit (UUID → Wire).
|
|
64
|
+
* @private
|
|
65
|
+
*/
|
|
66
|
+
private wires;
|
|
67
|
+
/**
|
|
68
|
+
* Create a new empty circuit.
|
|
69
|
+
*/
|
|
70
|
+
constructor(options: CircuitOptions);
|
|
71
|
+
get name(): string;
|
|
72
|
+
set name(value: string);
|
|
73
|
+
/**
|
|
74
|
+
* Add a new component to the circuit.
|
|
75
|
+
*
|
|
76
|
+
* Automatically creates pin ENodes for the component and links them
|
|
77
|
+
* bidirectionally. Pin ENode UUIDs are stored in the component's pins array.
|
|
78
|
+
* Pin labels are derived from the ComponentType metadata.
|
|
79
|
+
*
|
|
80
|
+
* @param type - Component type (Battery, Switch, LED, etc.)
|
|
81
|
+
* @param position - Grid position (x, y integers)
|
|
82
|
+
* @param rotation - Orientation angle (integer degrees)
|
|
83
|
+
* @param config - Optional configuration map for component-specific settings
|
|
84
|
+
* @returns The created Component
|
|
85
|
+
* @throws {TypeError} If position/rotation coordinates are not integers
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* const lightbulb = circuit.addComponent(
|
|
90
|
+
* new Position(10, 20),
|
|
91
|
+
* new Rotation(90),
|
|
92
|
+
* ComponentType.Lightbulb
|
|
93
|
+
* );
|
|
94
|
+
*
|
|
95
|
+
* console.log(lightbulb.type); // ComponentType.Lightbulb
|
|
96
|
+
* console.log(lightbulb.pins.length); // 2
|
|
97
|
+
* console.log(lightbulb.position.x); // 10
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
addComponent(type: ComponentType, position: Position, rotation: Rotation, config?: Map<string, string> | undefined): Component;
|
|
101
|
+
/**
|
|
102
|
+
* Resolve and update the transitionSpan config for a component
|
|
103
|
+
* if automatic resolution returns undefined nothing is done on the component
|
|
104
|
+
*
|
|
105
|
+
* @param component - Component to resolve transitionSpan for
|
|
106
|
+
*/
|
|
107
|
+
resolveTransitionSpan(component: Component): void;
|
|
108
|
+
/**
|
|
109
|
+
* Remove a component from the circuit.
|
|
110
|
+
*
|
|
111
|
+
* **Cascade deletion** removes:
|
|
112
|
+
* - All pin ENodes belonging to the component
|
|
113
|
+
* - All Wires connected to those pins
|
|
114
|
+
*
|
|
115
|
+
* @param id - Component UUID
|
|
116
|
+
* @throws {Error} If component does not exist
|
|
117
|
+
* @returns Object containing arrays of deleted Wires and ENodes IDs
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```typescript
|
|
121
|
+
* circuit.removeComponent(componentId);
|
|
122
|
+
* // Component, its pins, and connected wires are all removed
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
removeComponent(id: UUID): {
|
|
126
|
+
deletedWires: UUID[];
|
|
127
|
+
deletedENodes: UUID[];
|
|
128
|
+
};
|
|
129
|
+
hasComponent(id: UUID): boolean;
|
|
130
|
+
/**
|
|
131
|
+
* Get a component by ID.
|
|
132
|
+
*
|
|
133
|
+
* @param id - Component UUID
|
|
134
|
+
* @returns The Component or undefined if not found
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```typescript
|
|
138
|
+
* const component = circuit.getComponent(componentId);
|
|
139
|
+
* if (component) {
|
|
140
|
+
* console.log(component.position);
|
|
141
|
+
* }
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
getComponent(id: UUID): Component | undefined;
|
|
145
|
+
/**
|
|
146
|
+
* Get all components in the circuit.
|
|
147
|
+
*
|
|
148
|
+
* Returns a new array on each call (defensive copy).
|
|
149
|
+
*
|
|
150
|
+
* @returns Array of all Components
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```typescript
|
|
154
|
+
* const components = circuit.getAllComponents();
|
|
155
|
+
* console.log(`Circuit has ${components.length} components`);
|
|
156
|
+
*
|
|
157
|
+
* for (const comp of components) {
|
|
158
|
+
* console.log(comp.id, comp.position);
|
|
159
|
+
* }
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
162
|
+
getAllComponents(): Component[];
|
|
163
|
+
getAllComponentsByType(type: ComponentType): Component[];
|
|
164
|
+
getFirstComponentOfType(type: ComponentType): Component | undefined;
|
|
165
|
+
/**
|
|
166
|
+
* Get an electrical node by ID.
|
|
167
|
+
*
|
|
168
|
+
* Note: ENodes are automatically managed and not directly created
|
|
169
|
+
* or removed by users.
|
|
170
|
+
*
|
|
171
|
+
* @param id - ENode UUID
|
|
172
|
+
* @returns The ENode or undefined if not found
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* ```typescript
|
|
176
|
+
* const component = circuit.addComponent(
|
|
177
|
+
* new Position(10, 20),
|
|
178
|
+
* new Rotation(0),
|
|
179
|
+
* 2
|
|
180
|
+
* );
|
|
181
|
+
*
|
|
182
|
+
* const pinId = component.pins[0];
|
|
183
|
+
* const enode = circuit.getENode(pinId);
|
|
184
|
+
* console.log(enode.type); // ENodeType.Pin
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
getENode(id: UUID): ENode | undefined;
|
|
188
|
+
/**
|
|
189
|
+
* Get all electrical nodes in the circuit.
|
|
190
|
+
*
|
|
191
|
+
* Includes both pin nodes (from components) and branching point nodes
|
|
192
|
+
* (from wire splits).
|
|
193
|
+
*
|
|
194
|
+
* Returns a new array on each call (defensive copy).
|
|
195
|
+
*
|
|
196
|
+
* @returns Array of all ENodes
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```typescript
|
|
200
|
+
* const enodes = circuit.getAllENodes();
|
|
201
|
+
* console.log(`Circuit has ${enodes.length} electrical nodes`);
|
|
202
|
+
*
|
|
203
|
+
* for (const enode of enodes) {
|
|
204
|
+
* console.log(enode.id, enode.type);
|
|
205
|
+
* }
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
getAllENodes(): ENode[];
|
|
209
|
+
/**
|
|
210
|
+
* Add a branching point electrical node at a specific position.
|
|
211
|
+
*
|
|
212
|
+
* Branching points are used to split wires and create junctions.
|
|
213
|
+
* @param position - Grid position for the branching point
|
|
214
|
+
* @param sourceType - Optional source type (voltage/current)
|
|
215
|
+
* @returns The created ENode
|
|
216
|
+
*/
|
|
217
|
+
addBranchingPoint(position: Position, sourceType?: ENodeSourceType): ENode;
|
|
218
|
+
/**
|
|
219
|
+
* Remove a branching point electrical node from the circuit.
|
|
220
|
+
* Also removes all wires connected to this branching point if there are ony one or more than 2.
|
|
221
|
+
* In the case there are exactly two wires, they will be merged before removing the branching point.
|
|
222
|
+
*
|
|
223
|
+
* @param id - Branching point ENode UUID
|
|
224
|
+
* @throws {Error} If ENode does not exist or is not a branching point
|
|
225
|
+
*/
|
|
226
|
+
removeBranchingPoint(id: UUID): {
|
|
227
|
+
deletedWires?: UUID[] | undefined;
|
|
228
|
+
mergedWires?: UUID[] | undefined;
|
|
229
|
+
newWire?: Wire | undefined;
|
|
230
|
+
};
|
|
231
|
+
/**
|
|
232
|
+
* Add a wire connecting two electrical nodes.
|
|
233
|
+
*
|
|
234
|
+
* Validates that both nodes exist, not a self-connection, and no duplicate.
|
|
235
|
+
* Updates bidirectional references (Wire ↔ ENodes).
|
|
236
|
+
*
|
|
237
|
+
* @param node1 - First ENode UUID
|
|
238
|
+
* @param node2 - Second ENode UUID
|
|
239
|
+
* @param intermediatePositions - Optional path waypoints for rendering
|
|
240
|
+
* @returns The created Wire, or Error if validation fails
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* ```typescript
|
|
244
|
+
* const comp1 = circuit.addComponent(new Position(0, 0), new Rotation(0), 1);
|
|
245
|
+
* const comp2 = circuit.addComponent(new Position(10, 10), new Rotation(0), 1);
|
|
246
|
+
*
|
|
247
|
+
* const wire = circuit.addWire(comp1.pins[0], comp2.pins[0]);
|
|
248
|
+
* if (wire instanceof Error) {
|
|
249
|
+
* console.error('Failed:', wire.message);
|
|
250
|
+
* }
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
addWire(node1: UUID, node2: UUID, intermediatePositions?: Position[]): Wire | Error;
|
|
254
|
+
/**
|
|
255
|
+
* Remove a wire from the circuit.
|
|
256
|
+
*
|
|
257
|
+
* @param id - Wire UUID
|
|
258
|
+
* @throws {Error} If wire does not exist
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```typescript
|
|
262
|
+
* circuit.removeWire(wireId);
|
|
263
|
+
* // Wire is removed
|
|
264
|
+
* ```
|
|
265
|
+
*/
|
|
266
|
+
removeWire(id: UUID): void;
|
|
267
|
+
/**
|
|
268
|
+
* Split a wire in the circuit.
|
|
269
|
+
*
|
|
270
|
+
* It creates two new wires connected by either the target enode or a new branching point ENode at the specified position.
|
|
271
|
+
* Returns 2 UUIDS of the new wires.
|
|
272
|
+
*
|
|
273
|
+
* @param id - Wire UUID
|
|
274
|
+
* @param position
|
|
275
|
+
* @throws {Error} If wire does not exist
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* ```typescript
|
|
279
|
+
* circuit.splitWire(wireId);
|
|
280
|
+
* // Wire and any orphaned branching points are removed
|
|
281
|
+
* ```
|
|
282
|
+
*/
|
|
283
|
+
/**
|
|
284
|
+
* Split an existing wire at a position, creating a branching point.
|
|
285
|
+
* The original wire is removed and replaced with two new wires
|
|
286
|
+
* connecting through the new branching point.
|
|
287
|
+
* NB : in the special case where targetEnode belongs to a component where the wire is already connected
|
|
288
|
+
* only one new wire will be created as this method don't allow a wire directly connecting two pins of the same component.
|
|
289
|
+
*
|
|
290
|
+
* @param wireId - Wire to split
|
|
291
|
+
* @param position - Position for the new branching point : no effect if targetEnodeId provided
|
|
292
|
+
* @param targetEnodeId - if provided, the existing enode to split the wire at
|
|
293
|
+
* @returns Object containing the new branching point and an array of the two new wires
|
|
294
|
+
* @throws Error if wireId not found
|
|
295
|
+
*/
|
|
296
|
+
splitWire(wireId: UUID, position: Position, targetEnodeId?: UUID | null): {
|
|
297
|
+
branchingPoint: ENode;
|
|
298
|
+
wires: Array<Wire>;
|
|
299
|
+
};
|
|
300
|
+
getWireBetweenNodes(node1: UUID, node2: UUID): Wire | undefined;
|
|
301
|
+
/**
|
|
302
|
+
* Get a wire by ID.
|
|
303
|
+
*
|
|
304
|
+
* @param id - Wire UUID
|
|
305
|
+
* @returns The Wire or undefined if not found
|
|
306
|
+
*/
|
|
307
|
+
getWire(id: UUID): Wire | undefined;
|
|
308
|
+
/**
|
|
309
|
+
* Get all wires in the circuit.
|
|
310
|
+
*
|
|
311
|
+
* Returns a new array on each call (defensive copy).
|
|
312
|
+
*
|
|
313
|
+
* @returns Array of all Wires
|
|
314
|
+
*/
|
|
315
|
+
getAllWires(): Wire[];
|
|
316
|
+
/**
|
|
317
|
+
* Get all wires connected to a specific ENode.
|
|
318
|
+
*
|
|
319
|
+
* @param nodeId - ENode UUID
|
|
320
|
+
* @returns Array of connected Wires, or empty array if node not found
|
|
321
|
+
*/
|
|
322
|
+
getWiresByNode(nodeId: UUID): Wire[];
|
|
323
|
+
/**
|
|
324
|
+
* Get all wires connected to a component, e.g to any pin enode of the component.
|
|
325
|
+
*
|
|
326
|
+
* @param componentId - Component UUID
|
|
327
|
+
* @returns Array of connected Wires, or empty array if component not found
|
|
328
|
+
*/
|
|
329
|
+
getWiresByComponent(componentId: UUID): Wire[];
|
|
330
|
+
/**
|
|
331
|
+
* Get both ENodes connected by a wire.
|
|
332
|
+
*
|
|
333
|
+
* @param wireId - Wire UUID
|
|
334
|
+
* @returns Tuple [node1, node2] or undefined if wire not found
|
|
335
|
+
*/
|
|
336
|
+
getNodesByWire(wireId: UUID): [ENode, ENode] | undefined;
|
|
337
|
+
/**
|
|
338
|
+
* Check if a wire already exists between two nodes.
|
|
339
|
+
*
|
|
340
|
+
* Order-independent: returns true for (A, B) or (B, A).
|
|
341
|
+
*
|
|
342
|
+
* @param node1 - First ENode UUID
|
|
343
|
+
* @param node2 - Second ENode UUID
|
|
344
|
+
* @returns true if wire exists, false otherwise
|
|
345
|
+
*/
|
|
346
|
+
hasWireBetween(node1: UUID, node2: UUID): boolean;
|
|
347
|
+
/**
|
|
348
|
+
* Find all components with pins among the provided enode IDs set.
|
|
349
|
+
*
|
|
350
|
+
* @param pinIds - Set of pins UUIDs
|
|
351
|
+
* @returns Set of components UUIDs
|
|
352
|
+
*/
|
|
353
|
+
getComponentsOfPins(pinIds: Set<UUID>): Set<UUID>;
|
|
354
|
+
/**
|
|
355
|
+
* Get a component's pin ENode by its label.
|
|
356
|
+
* @param component
|
|
357
|
+
* @param pinLabel
|
|
358
|
+
*/
|
|
359
|
+
getComponentPinByLabel(component: Component, pinLabel: string): ENode | undefined;
|
|
360
|
+
/**
|
|
361
|
+
* Update the intermediate positions of a wire.
|
|
362
|
+
* Update the wire in place.
|
|
363
|
+
*
|
|
364
|
+
* @param wireId - Wire to update
|
|
365
|
+
* @param intermediatePositions - New intermediate positions
|
|
366
|
+
* @param simplify - Whether to simplify positions by removing collinear points : useful when finalizing wire routing
|
|
367
|
+
* @returns The updated Wire
|
|
368
|
+
* @throws Error if wireId not found
|
|
369
|
+
*/
|
|
370
|
+
updateWireIntermediatePositions(wireId: UUID, intermediatePositions: Position[], simplify?: boolean): Wire;
|
|
371
|
+
/**
|
|
372
|
+
* Simplify intermediate positions of a wire.
|
|
373
|
+
* Update the wire in place.
|
|
374
|
+
* @param wireId - Wire to simplify
|
|
375
|
+
* @returns The updated Wire
|
|
376
|
+
* @throws Error if wireId not found
|
|
377
|
+
*/
|
|
378
|
+
simplifyWireIntermediatePositions(wireId: UUID): Wire;
|
|
379
|
+
/**
|
|
380
|
+
* Update the source type of an ENode (branching point or component pin).
|
|
381
|
+
* @param enodeId - ENode to update
|
|
382
|
+
* @param sourceType - New source type (null to clear)
|
|
383
|
+
* @throws Error if enodeId not found
|
|
384
|
+
*/
|
|
385
|
+
updateENodeSourceType(enodeId: UUID, sourceType: ENodeSourceType | null): void;
|
|
386
|
+
/**
|
|
387
|
+
* iterate through all components, enodes and wires positions to get the size that allows to enclose all elements.
|
|
388
|
+
* @param margin - optional margin to add to the size
|
|
389
|
+
* @returns size that allows to enclose all elements plus margin
|
|
390
|
+
* @todo if calls to this method at each build operation ends causes slowness see to optimize by restricting checked elements
|
|
391
|
+
*/
|
|
392
|
+
getEnclosingSize(margin?: number): number;
|
|
393
|
+
/**
|
|
394
|
+
* Serialize circuit to JSON.
|
|
395
|
+
*
|
|
396
|
+
* @returns JSON-serializable object containing all components, enodes, and wires
|
|
397
|
+
*
|
|
398
|
+
* @example
|
|
399
|
+
* ```typescript
|
|
400
|
+
* const json = circuit.toJSON();
|
|
401
|
+
* localStorage.setItem('my-circuit', JSON.stringify(json));
|
|
402
|
+
* ```
|
|
403
|
+
*/
|
|
404
|
+
toJSON(): ICircuit;
|
|
405
|
+
/**
|
|
406
|
+
* Deserialize circuit from JSON.
|
|
407
|
+
*
|
|
408
|
+
* @param json - Circuit data
|
|
409
|
+
* @returns Circuit instance
|
|
410
|
+
* @throws {Error} If JSON is invalid or violates invariants
|
|
411
|
+
*
|
|
412
|
+
* @example
|
|
413
|
+
* ```typescript
|
|
414
|
+
* const jsonStr = localStorage.getItem('my-circuit');
|
|
415
|
+
* const json = JSON.parse(jsonStr);
|
|
416
|
+
* const circuit = Circuit.fromJSON(json);
|
|
417
|
+
* ```
|
|
418
|
+
*/
|
|
419
|
+
static fromJSON(json: ICircuit): Circuit;
|
|
420
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { CameraOptions } from '../utils';
|
|
2
|
+
import { CircuitOptions } from './CircuitOptions';
|
|
3
|
+
import { ICircuitMetadata } from './types';
|
|
4
|
+
export declare class CircuitMetadata implements ICircuitMetadata {
|
|
5
|
+
version: string;
|
|
6
|
+
options: CircuitOptions;
|
|
7
|
+
size: number;
|
|
8
|
+
divisions: number;
|
|
9
|
+
cameraOptions: CameraOptions;
|
|
10
|
+
/**
|
|
11
|
+
* Create a new CircuitMetadata holding general information about the Circuit.
|
|
12
|
+
*
|
|
13
|
+
* @param version - Circuit version
|
|
14
|
+
* @param options - Circuit options
|
|
15
|
+
* @param size - Size of the circuit grid
|
|
16
|
+
* @param divisions - Divisions in the circuit grid
|
|
17
|
+
* @param cameraOptions - Camera Options at startup
|
|
18
|
+
* @throws {TypeError} If size or divisions are not integers
|
|
19
|
+
*/
|
|
20
|
+
constructor(version: string, options: CircuitOptions, size: number, divisions: number, cameraOptions: CameraOptions);
|
|
21
|
+
toJSON(): ICircuitMetadata;
|
|
22
|
+
static fromJSON(json: ICircuitMetadata): CircuitMetadata;
|
|
23
|
+
toString(): string;
|
|
24
|
+
}
|