simple-circuit-engine 0.0.8 → 0.0.10
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 +19 -11
- package/CLAUDE.md +4 -3
- package/README.md +4 -4
- package/dist/{CircuitRunner-FXM_s5ll.js → CircuitRunner-DEb7JdNf.js} +543 -211
- package/dist/CircuitRunner-DEb7JdNf.js.map +1 -0
- package/dist/core/index.js +923 -604
- package/dist/core/index.js.map +1 -1
- package/dist/index.d.ts +779 -140
- package/dist/index.js +96 -68
- package/dist/scene/index.d.ts +3 -2
- package/dist/scene/index.js +37 -26
- package/dist/{setup-aoI3UTB5.js → setup-AB1vFiis.js} +3176 -1571
- package/dist/setup-AB1vFiis.js.map +1 -0
- package/package.json +1 -1
- package/dist/CircuitRunner-FXM_s5ll.js.map +0 -1
- package/dist/setup-aoI3UTB5.js.map +0 -1
package/dist/core/index.js
CHANGED
|
@@ -1,208 +1,6 @@
|
|
|
1
|
-
import { e as
|
|
2
|
-
import {
|
|
1
|
+
import { e as O, P as k, C as b, c as B, i as P, j as S, d as y, f as G, b as V, s as C, a as h, T as f } from "../CircuitRunner-DEb7JdNf.js";
|
|
2
|
+
import { k as me, D as we, E as ye, n as ve, h as Se, R as Ce, m as Te, S as Ee, l as Ie, g as Ae } from "../CircuitRunner-DEb7JdNf.js";
|
|
3
3
|
class w {
|
|
4
|
-
/**
|
|
5
|
-
* Unique identifier for this ENode.
|
|
6
|
-
* @readonly
|
|
7
|
-
*/
|
|
8
|
-
id;
|
|
9
|
-
/**
|
|
10
|
-
* Type of electrical node (Pin or BranchingPoint).
|
|
11
|
-
* @readonly
|
|
12
|
-
*/
|
|
13
|
-
type;
|
|
14
|
-
/**
|
|
15
|
-
* Parent component UUID (only for pin nodes).
|
|
16
|
-
* Undefined for branching point nodes.
|
|
17
|
-
* @readonly
|
|
18
|
-
*/
|
|
19
|
-
component;
|
|
20
|
-
/**
|
|
21
|
-
* Pin label within component (only for pin nodes).
|
|
22
|
-
* Undefined for branching point nodes.
|
|
23
|
-
* @readonly
|
|
24
|
-
*/
|
|
25
|
-
pinLabel;
|
|
26
|
-
/**
|
|
27
|
-
* Grid position (only for branching point nodes).
|
|
28
|
-
* Undefined for pin nodes (position derived from component).
|
|
29
|
-
* @readonly
|
|
30
|
-
*/
|
|
31
|
-
position;
|
|
32
|
-
/**
|
|
33
|
-
* Set of wire UUIDs connected to this node.
|
|
34
|
-
* Mutable to allow wire connections/disconnections.
|
|
35
|
-
*/
|
|
36
|
-
wires;
|
|
37
|
-
/**
|
|
38
|
-
* Is the ENode a source of voltage or current?
|
|
39
|
-
*/
|
|
40
|
-
source;
|
|
41
|
-
/**
|
|
42
|
-
* Create a new electrical node.
|
|
43
|
-
*
|
|
44
|
-
* **Note**: Typically ENodes are created automatically by Circuit.
|
|
45
|
-
* This constructor is used internally.
|
|
46
|
-
*
|
|
47
|
-
* @param type - Node type (Pin or BranchingPoint)
|
|
48
|
-
* @param component - Parent component UUID (pin nodes only)
|
|
49
|
-
* @param pinLabel - Pin label (pin nodes only)
|
|
50
|
-
* @param position - Grid position (branching points only)
|
|
51
|
-
* @param source - Source type (Voltage/Current) or undefined
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* ```typescript
|
|
55
|
-
* // Pin node (internal to Circuit)
|
|
56
|
-
* const pinNode = new ENode(
|
|
57
|
-
* ENodeType.Pin,
|
|
58
|
-
* componentId,
|
|
59
|
-
* '0', // first pin
|
|
60
|
-
* undefined,
|
|
61
|
-
* undefined
|
|
62
|
-
* );
|
|
63
|
-
*
|
|
64
|
-
* // Branching point node
|
|
65
|
-
* const branchNode = new ENode(
|
|
66
|
-
* ENodeType.BranchingPoint,
|
|
67
|
-
* undefined,
|
|
68
|
-
* undefined,
|
|
69
|
-
* new Position(15, 25),
|
|
70
|
-
* undefined
|
|
71
|
-
* );
|
|
72
|
-
* ```
|
|
73
|
-
*/
|
|
74
|
-
constructor(e, t, i, n, s = void 0) {
|
|
75
|
-
this.id = T(), this.type = e, this.component = t, this.pinLabel = i, this.position = n, this.wires = /* @__PURE__ */ new Set(), this.source = s;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Get the position of this electrical node.
|
|
79
|
-
*
|
|
80
|
-
* **Pin nodes**: Derives position from parent component.
|
|
81
|
-
* **Branching nodes**: Returns stored position directly.
|
|
82
|
-
*
|
|
83
|
-
* @param circuit - Circuit instance (needed to look up component for pin nodes)
|
|
84
|
-
* @returns Position on the grid
|
|
85
|
-
*
|
|
86
|
-
* @example
|
|
87
|
-
* ```typescript
|
|
88
|
-
* const circuit = new Circuit();
|
|
89
|
-
* const component = circuit.addComponent(
|
|
90
|
-
* new Position(10, 20),
|
|
91
|
-
* new Rotation(0),
|
|
92
|
-
* 1
|
|
93
|
-
* );
|
|
94
|
-
*
|
|
95
|
-
* const pinNode = circuit.getENode(component.pins[0]);
|
|
96
|
-
* const position = pinNode.getPosition(circuit);
|
|
97
|
-
* console.log(position.x); // 10 (derived from component)
|
|
98
|
-
* ```
|
|
99
|
-
*/
|
|
100
|
-
getPosition(e) {
|
|
101
|
-
if (this.type === g.Pin) {
|
|
102
|
-
if (!this.component)
|
|
103
|
-
throw new Error("Pin node missing component reference");
|
|
104
|
-
const t = e.getComponent(this.component);
|
|
105
|
-
if (!t)
|
|
106
|
-
throw new Error(`Component ${this.component} not found for pin node ${this.id}`);
|
|
107
|
-
return t.position;
|
|
108
|
-
}
|
|
109
|
-
if (!this.position)
|
|
110
|
-
throw new Error("Branching point node missing position");
|
|
111
|
-
return this.position;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Update the enode (branching point only)'s position.
|
|
115
|
-
*
|
|
116
|
-
* @param newPosition - The new position for the enode
|
|
117
|
-
*
|
|
118
|
-
* @example
|
|
119
|
-
* ```typescript
|
|
120
|
-
* const component = circuit.getComponent(componentId);
|
|
121
|
-
* component.setPosition(new Position(15, 25));
|
|
122
|
-
* ```
|
|
123
|
-
*/
|
|
124
|
-
setPosition(e) {
|
|
125
|
-
Object.defineProperty(this, "position", {
|
|
126
|
-
value: e,
|
|
127
|
-
writable: !1,
|
|
128
|
-
enumerable: !0,
|
|
129
|
-
configurable: !0
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Update the enode's source type.
|
|
134
|
-
* @param sourceType
|
|
135
|
-
*/
|
|
136
|
-
setSourceType(e) {
|
|
137
|
-
Object.defineProperty(this, "source", {
|
|
138
|
-
value: e,
|
|
139
|
-
writable: !0,
|
|
140
|
-
enumerable: !0,
|
|
141
|
-
configurable: !0
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Serialize ENode to JSON.
|
|
146
|
-
*
|
|
147
|
-
* @returns Plain object representation
|
|
148
|
-
*
|
|
149
|
-
* @example
|
|
150
|
-
* ```typescript
|
|
151
|
-
* const json = enode.toJSON();
|
|
152
|
-
* console.log(json);
|
|
153
|
-
* // Pin node:
|
|
154
|
-
* // {
|
|
155
|
-
* // id: "uuid",
|
|
156
|
-
* // type: "Pin",
|
|
157
|
-
* // component: "component-uuid",
|
|
158
|
-
* // pinLabel: "0"
|
|
159
|
-
* // }
|
|
160
|
-
*
|
|
161
|
-
* // Branching node:
|
|
162
|
-
* // {
|
|
163
|
-
* // id: "uuid",
|
|
164
|
-
* // type: "BranchingPoint",
|
|
165
|
-
* // position: { x: 15, y: 25 }
|
|
166
|
-
* // }
|
|
167
|
-
* ```
|
|
168
|
-
*/
|
|
169
|
-
toJSON() {
|
|
170
|
-
const e = {
|
|
171
|
-
id: this.id,
|
|
172
|
-
type: this.type,
|
|
173
|
-
source: this.source || null
|
|
174
|
-
};
|
|
175
|
-
return this.type === g.Pin ? (e.component = this.component || null, e.pinLabel = this.pinLabel || null) : e.position = this.position?.toJSON() || null, e;
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Deserialize ENode from JSON.
|
|
179
|
-
*
|
|
180
|
-
* @param json - ENode data
|
|
181
|
-
* @returns ENode instance
|
|
182
|
-
*
|
|
183
|
-
* @example
|
|
184
|
-
* ```typescript
|
|
185
|
-
* const json = {
|
|
186
|
-
* id: "uuid",
|
|
187
|
-
* type: "Pin",
|
|
188
|
-
* component: "component-uuid",
|
|
189
|
-
* pinLabel: "0"
|
|
190
|
-
* };
|
|
191
|
-
*
|
|
192
|
-
* const enode = ENode.fromJSON(json);
|
|
193
|
-
* ```
|
|
194
|
-
*/
|
|
195
|
-
static fromJSON(e) {
|
|
196
|
-
const t = e.position ? P.fromJSON(e.position) : void 0, i = new w(e.type, e.component, e.pinLabel, t, e.source);
|
|
197
|
-
return Object.defineProperty(i, "id", {
|
|
198
|
-
value: e.id,
|
|
199
|
-
writable: !1,
|
|
200
|
-
enumerable: !0,
|
|
201
|
-
configurable: !1
|
|
202
|
-
}), i;
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
class f {
|
|
206
4
|
/**
|
|
207
5
|
* Unique identifier for this wire.
|
|
208
6
|
* @readonly
|
|
@@ -248,8 +46,8 @@ class f {
|
|
|
248
46
|
* );
|
|
249
47
|
* ```
|
|
250
48
|
*/
|
|
251
|
-
constructor(
|
|
252
|
-
this.id =
|
|
49
|
+
constructor(t, e, i = []) {
|
|
50
|
+
this.id = O(), this.node1 = t, this.node2 = e, this.intermediatePositions = i;
|
|
253
51
|
}
|
|
254
52
|
/**
|
|
255
53
|
* Check if this is a straight-line wire.
|
|
@@ -290,7 +88,7 @@ class f {
|
|
|
290
88
|
id: this.id,
|
|
291
89
|
node1: this.node1,
|
|
292
90
|
node2: this.node2,
|
|
293
|
-
intermediatePositions: this.intermediatePositions.map((
|
|
91
|
+
intermediatePositions: this.intermediatePositions.map((t) => t.toJSON())
|
|
294
92
|
};
|
|
295
93
|
}
|
|
296
94
|
/**
|
|
@@ -311,10 +109,10 @@ class f {
|
|
|
311
109
|
* const wire = Wire.fromJSON(json);
|
|
312
110
|
* ```
|
|
313
111
|
*/
|
|
314
|
-
static fromJSON(
|
|
315
|
-
const
|
|
112
|
+
static fromJSON(t) {
|
|
113
|
+
const e = t.intermediatePositions.map((n) => k.fromJSON(n)), i = new w(t.node1, t.node2, e);
|
|
316
114
|
return Object.defineProperty(i, "id", {
|
|
317
|
-
value:
|
|
115
|
+
value: t.id,
|
|
318
116
|
writable: !1,
|
|
319
117
|
enumerable: !0,
|
|
320
118
|
configurable: !1
|
|
@@ -331,10 +129,10 @@ class v {
|
|
|
331
129
|
* @param cameraOptions - Camera Options at startup
|
|
332
130
|
* @throws {TypeError} If size or divisions are not integers
|
|
333
131
|
*/
|
|
334
|
-
constructor(
|
|
335
|
-
if (this.name =
|
|
132
|
+
constructor(t, e, i, n) {
|
|
133
|
+
if (this.name = t, this.size = e, this.divisions = i, this.cameraOptions = n, !Number.isInteger(e) || !Number.isInteger(i))
|
|
336
134
|
throw new TypeError(
|
|
337
|
-
`Size and divisions must be integers (got size=${
|
|
135
|
+
`Size and divisions must be integers (got size=${e}, divisions=${i})`
|
|
338
136
|
);
|
|
339
137
|
}
|
|
340
138
|
toJSON() {
|
|
@@ -345,19 +143,19 @@ class v {
|
|
|
345
143
|
cameraOptions: this.cameraOptions.toJSON()
|
|
346
144
|
};
|
|
347
145
|
}
|
|
348
|
-
static fromJSON(
|
|
146
|
+
static fromJSON(t) {
|
|
349
147
|
return new v(
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
b.fromJSON(
|
|
148
|
+
t.name,
|
|
149
|
+
t.size,
|
|
150
|
+
t.divisions,
|
|
151
|
+
b.fromJSON(t.cameraOptions)
|
|
354
152
|
);
|
|
355
153
|
}
|
|
356
154
|
toString() {
|
|
357
155
|
return `CircuitMetadata(${this.name}, ${this.size}, ${this.divisions}, ${this.cameraOptions.toString()})`;
|
|
358
156
|
}
|
|
359
157
|
}
|
|
360
|
-
class
|
|
158
|
+
class _ {
|
|
361
159
|
/**
|
|
362
160
|
* Circuit metadata holding general information.
|
|
363
161
|
* @private
|
|
@@ -382,16 +180,16 @@ class O {
|
|
|
382
180
|
/**
|
|
383
181
|
* Create a new empty circuit.
|
|
384
182
|
*/
|
|
385
|
-
constructor(
|
|
386
|
-
this.metadata = new v(
|
|
183
|
+
constructor(t = "Untitled Circuit") {
|
|
184
|
+
this.metadata = new v(t, 10, 10, new b()), this.components = /* @__PURE__ */ new Map(), this.enodes = /* @__PURE__ */ new Map(), this.wires = /* @__PURE__ */ new Map();
|
|
387
185
|
}
|
|
388
186
|
get name() {
|
|
389
187
|
return this.metadata.name;
|
|
390
188
|
}
|
|
391
|
-
set name(
|
|
392
|
-
if (typeof
|
|
189
|
+
set name(t) {
|
|
190
|
+
if (typeof t != "string" || t.trim() === "")
|
|
393
191
|
throw new TypeError("Circuit name must be a non-empty string");
|
|
394
|
-
this.metadata.name =
|
|
192
|
+
this.metadata.name = t;
|
|
395
193
|
}
|
|
396
194
|
/**
|
|
397
195
|
* Add a new component to the circuit.
|
|
@@ -420,20 +218,20 @@ class O {
|
|
|
420
218
|
* console.log(lightbulb.position.x); // 10
|
|
421
219
|
* ```
|
|
422
220
|
*/
|
|
423
|
-
addComponent(
|
|
424
|
-
const s =
|
|
221
|
+
addComponent(t, e, i, n) {
|
|
222
|
+
const s = B(t), o = new P(t, e, i, []);
|
|
425
223
|
n && (o.config = new Map(n));
|
|
426
224
|
const a = [];
|
|
427
|
-
for (const [r,
|
|
428
|
-
const
|
|
429
|
-
|
|
225
|
+
for (const [r, d] of s.pins) {
|
|
226
|
+
const g = new S(
|
|
227
|
+
y.Pin,
|
|
430
228
|
o.id,
|
|
431
229
|
r,
|
|
432
230
|
void 0,
|
|
433
231
|
// Pin position derived from component,
|
|
434
|
-
|
|
232
|
+
d
|
|
435
233
|
);
|
|
436
|
-
this.enodes.set(
|
|
234
|
+
this.enodes.set(g.id, g), a.push(g.id);
|
|
437
235
|
}
|
|
438
236
|
return Object.defineProperty(o, "pins", {
|
|
439
237
|
value: a,
|
|
@@ -459,12 +257,12 @@ class O {
|
|
|
459
257
|
* // Component, its pins, and connected wires are all removed
|
|
460
258
|
* ```
|
|
461
259
|
*/
|
|
462
|
-
removeComponent(
|
|
463
|
-
const
|
|
464
|
-
if (!
|
|
465
|
-
throw new Error(`Component ${
|
|
260
|
+
removeComponent(t) {
|
|
261
|
+
const e = this.components.get(t);
|
|
262
|
+
if (!e)
|
|
263
|
+
throw new Error(`Component ${t} does not exist`);
|
|
466
264
|
const i = [], n = [];
|
|
467
|
-
for (const s of
|
|
265
|
+
for (const s of e.pins) {
|
|
468
266
|
const o = this.enodes.get(s);
|
|
469
267
|
if (o) {
|
|
470
268
|
const a = Array.from(o.wires);
|
|
@@ -473,10 +271,10 @@ class O {
|
|
|
473
271
|
}
|
|
474
272
|
this.enodes.delete(s), n.push(s);
|
|
475
273
|
}
|
|
476
|
-
return this.components.delete(
|
|
274
|
+
return this.components.delete(t), { deletedWires: i, deletedENodes: n };
|
|
477
275
|
}
|
|
478
|
-
hasComponent(
|
|
479
|
-
return this.components.has(
|
|
276
|
+
hasComponent(t) {
|
|
277
|
+
return this.components.has(t);
|
|
480
278
|
}
|
|
481
279
|
/**
|
|
482
280
|
* Get a component by ID.
|
|
@@ -492,8 +290,8 @@ class O {
|
|
|
492
290
|
* }
|
|
493
291
|
* ```
|
|
494
292
|
*/
|
|
495
|
-
getComponent(
|
|
496
|
-
return this.components.get(
|
|
293
|
+
getComponent(t) {
|
|
294
|
+
return this.components.get(t);
|
|
497
295
|
}
|
|
498
296
|
/**
|
|
499
297
|
* Get all components in the circuit.
|
|
@@ -515,16 +313,16 @@ class O {
|
|
|
515
313
|
getAllComponents() {
|
|
516
314
|
return Array.from(this.components.values());
|
|
517
315
|
}
|
|
518
|
-
getAllComponentsByType(
|
|
519
|
-
const
|
|
316
|
+
getAllComponentsByType(t) {
|
|
317
|
+
const e = [];
|
|
520
318
|
for (const i of this.components.values())
|
|
521
|
-
i.type ===
|
|
522
|
-
return
|
|
319
|
+
i.type === t && e.push(i);
|
|
320
|
+
return e;
|
|
523
321
|
}
|
|
524
|
-
getFirstComponentOfType(
|
|
525
|
-
for (const
|
|
526
|
-
if (
|
|
527
|
-
return
|
|
322
|
+
getFirstComponentOfType(t) {
|
|
323
|
+
for (const e of this.components.values())
|
|
324
|
+
if (e.type === t)
|
|
325
|
+
return e;
|
|
528
326
|
}
|
|
529
327
|
/**
|
|
530
328
|
* Get an electrical node by ID.
|
|
@@ -548,8 +346,8 @@ class O {
|
|
|
548
346
|
* console.log(enode.type); // ENodeType.Pin
|
|
549
347
|
* ```
|
|
550
348
|
*/
|
|
551
|
-
getENode(
|
|
552
|
-
return this.enodes.get(
|
|
349
|
+
getENode(t) {
|
|
350
|
+
return this.enodes.get(t);
|
|
553
351
|
}
|
|
554
352
|
/**
|
|
555
353
|
* Get all electrical nodes in the circuit.
|
|
@@ -582,13 +380,13 @@ class O {
|
|
|
582
380
|
* @param sourceType - Optional source type (voltage/current)
|
|
583
381
|
* @returns The created ENode
|
|
584
382
|
*/
|
|
585
|
-
addBranchingPoint(
|
|
586
|
-
const i = new
|
|
587
|
-
|
|
383
|
+
addBranchingPoint(t, e) {
|
|
384
|
+
const i = new S(
|
|
385
|
+
y.BranchingPoint,
|
|
588
386
|
void 0,
|
|
589
387
|
void 0,
|
|
590
|
-
|
|
591
|
-
|
|
388
|
+
t,
|
|
389
|
+
e
|
|
592
390
|
);
|
|
593
391
|
return this.enodes.set(i.id, i), i;
|
|
594
392
|
}
|
|
@@ -600,29 +398,29 @@ class O {
|
|
|
600
398
|
* @param id - Branching point ENode UUID
|
|
601
399
|
* @throws {Error} If ENode does not exist or is not a branching point
|
|
602
400
|
*/
|
|
603
|
-
removeBranchingPoint(
|
|
604
|
-
const
|
|
605
|
-
if (!
|
|
606
|
-
throw new Error(`Enode ${
|
|
607
|
-
if (
|
|
401
|
+
removeBranchingPoint(t) {
|
|
402
|
+
const e = this.enodes.get(t);
|
|
403
|
+
if (!e)
|
|
404
|
+
throw new Error(`Enode ${t} does not exist`);
|
|
405
|
+
if (e.type !== y.BranchingPoint)
|
|
608
406
|
throw new Error(
|
|
609
|
-
`Enode ${
|
|
407
|
+
`Enode ${t} is not a branching point, it must be removed with its component.`
|
|
610
408
|
);
|
|
611
|
-
const i = {}, n = this.getWiresByNode(
|
|
409
|
+
const i = {}, n = this.getWiresByNode(t);
|
|
612
410
|
if (n.length === 1 || n.length > 2) {
|
|
613
411
|
const s = [];
|
|
614
412
|
for (const o of n)
|
|
615
413
|
this.removeWire(o.id), s.push(o.id);
|
|
616
414
|
Object.assign(i, { deletedWires: s });
|
|
617
415
|
} else if (n.length === 2) {
|
|
618
|
-
const s = n[0], o = n[1], a = s.node1 ===
|
|
619
|
-
a === s.node1 ?
|
|
620
|
-
const
|
|
621
|
-
if (
|
|
622
|
-
throw new Error(`Failed to merge wires at branching point ${
|
|
623
|
-
Object.assign(i, { mergedWires: [s.id, o.id] }), Object.assign(i, { newWire:
|
|
416
|
+
const s = n[0], o = n[1], a = s.node1 === t ? s.node2 : s.node1, r = o.node1 === t ? o.node2 : o.node1, d = [];
|
|
417
|
+
a === s.node1 ? d.push(...s.intermediatePositions) : a === s.node2 && d.push(...[...s.intermediatePositions].reverse()), d.push(e.getPosition(this)), r === o.node1 ? d.push(...[...o.intermediatePositions].reverse()) : r === o.node2 && d.push(...o.intermediatePositions), this.removeWire(s.id), this.removeWire(o.id);
|
|
418
|
+
const g = this.addWire(a, r, d);
|
|
419
|
+
if (g instanceof Error)
|
|
420
|
+
throw new Error(`Failed to merge wires at branching point ${t}: ${g.message}`);
|
|
421
|
+
Object.assign(i, { mergedWires: [s.id, o.id] }), Object.assign(i, { newWire: g });
|
|
624
422
|
}
|
|
625
|
-
return this.enodes.delete(
|
|
423
|
+
return this.enodes.delete(t), i;
|
|
626
424
|
}
|
|
627
425
|
/**
|
|
628
426
|
* Add a wire connecting two electrical nodes.
|
|
@@ -646,15 +444,15 @@ class O {
|
|
|
646
444
|
* }
|
|
647
445
|
* ```
|
|
648
446
|
*/
|
|
649
|
-
addWire(
|
|
650
|
-
if (
|
|
447
|
+
addWire(t, e, i) {
|
|
448
|
+
if (t === e)
|
|
651
449
|
return new Error("Cannot create wire connecting node to itself");
|
|
652
|
-
const n = this.enodes.get(
|
|
450
|
+
const n = this.enodes.get(t), s = this.enodes.get(e);
|
|
653
451
|
if (!n || !s)
|
|
654
452
|
return new Error("Wire requires at least one existing ENode");
|
|
655
|
-
if (this.hasWireBetween(
|
|
453
|
+
if (this.hasWireBetween(t, e))
|
|
656
454
|
return new Error("Duplicate wire between same nodes");
|
|
657
|
-
const o = new
|
|
455
|
+
const o = new w(t, e, i || []);
|
|
658
456
|
return this.wires.set(o.id, o), n.wires.add(o.id), s.wires.add(o.id), o;
|
|
659
457
|
}
|
|
660
458
|
/**
|
|
@@ -669,12 +467,12 @@ class O {
|
|
|
669
467
|
* // Wire is removed
|
|
670
468
|
* ```
|
|
671
469
|
*/
|
|
672
|
-
removeWire(
|
|
673
|
-
const
|
|
674
|
-
if (!
|
|
675
|
-
throw new Error(`Wire ${
|
|
676
|
-
const i = this.enodes.get(
|
|
677
|
-
i && i.wires.delete(
|
|
470
|
+
removeWire(t) {
|
|
471
|
+
const e = this.wires.get(t);
|
|
472
|
+
if (!e)
|
|
473
|
+
throw new Error(`Wire ${t} does not exist`);
|
|
474
|
+
const i = this.enodes.get(e.node1), n = this.enodes.get(e.node2);
|
|
475
|
+
i && i.wires.delete(t), n && n.wires.delete(t), this.wires.delete(t);
|
|
678
476
|
}
|
|
679
477
|
/**
|
|
680
478
|
* Split a wire in the circuit.
|
|
@@ -705,47 +503,47 @@ class O {
|
|
|
705
503
|
* @returns Object containing the new branching point and an array of the two new wires
|
|
706
504
|
* @throws Error if wireId not found
|
|
707
505
|
*/
|
|
708
|
-
splitWire(
|
|
709
|
-
const n = this.wires.get(
|
|
506
|
+
splitWire(t, e, i = null) {
|
|
507
|
+
const n = this.wires.get(t);
|
|
710
508
|
if (!n)
|
|
711
|
-
throw new Error(`Wire ${
|
|
509
|
+
throw new Error(`Wire ${t} does not exist`);
|
|
712
510
|
const s = this.enodes.get(n.node1), o = this.enodes.get(n.node2);
|
|
713
511
|
if (!s || !o)
|
|
714
|
-
throw new Error(`Wire ${
|
|
512
|
+
throw new Error(`Wire ${t} is connected to non-existent ENodes`);
|
|
715
513
|
const a = [
|
|
716
514
|
s.getPosition(this),
|
|
717
515
|
...n.intermediatePositions,
|
|
718
516
|
o.getPosition(this)
|
|
719
|
-
], r =
|
|
720
|
-
this.wires.delete(
|
|
721
|
-
let
|
|
517
|
+
], r = G(a, e), d = a.slice(1, r), g = a.slice(r, a.length - 1);
|
|
518
|
+
this.wires.delete(t), s.wires.delete(t), o.wires.delete(t);
|
|
519
|
+
let l;
|
|
722
520
|
if (i)
|
|
723
521
|
if (this.enodes.get(i))
|
|
724
|
-
|
|
522
|
+
l = this.enodes.get(i);
|
|
725
523
|
else
|
|
726
524
|
throw new Error(`Target ENode ${i} does not exist`);
|
|
727
525
|
else
|
|
728
|
-
|
|
729
|
-
const
|
|
730
|
-
if ((!
|
|
731
|
-
const u = this.addWire(s.id,
|
|
732
|
-
u instanceof
|
|
526
|
+
l = this.addBranchingPoint(e);
|
|
527
|
+
const m = [];
|
|
528
|
+
if ((!l.component || s.component !== l.component) && !this.hasWireBetween(s.id, l.id)) {
|
|
529
|
+
const u = this.addWire(s.id, l.id, d);
|
|
530
|
+
u instanceof w ? (this.simplifyWireIntermediatePositions(u.id), m.push(u)) : console.warn(`Failure to create wire at split : ${u.message}`);
|
|
733
531
|
}
|
|
734
|
-
if ((!
|
|
735
|
-
const u = this.addWire(
|
|
736
|
-
u instanceof
|
|
532
|
+
if ((!l.component || o.component !== l.component) && !this.hasWireBetween(o.id, l.id)) {
|
|
533
|
+
const u = this.addWire(l.id, o.id, g);
|
|
534
|
+
u instanceof w ? (this.simplifyWireIntermediatePositions(u.id), m.push(u)) : console.warn(`Failure to create wire at split : ${u.message}`);
|
|
737
535
|
}
|
|
738
536
|
return {
|
|
739
|
-
branchingPoint:
|
|
740
|
-
wires:
|
|
537
|
+
branchingPoint: l,
|
|
538
|
+
wires: m
|
|
741
539
|
};
|
|
742
540
|
}
|
|
743
|
-
getWireBetweenNodes(
|
|
744
|
-
const i = this.enodes.get(
|
|
541
|
+
getWireBetweenNodes(t, e) {
|
|
542
|
+
const i = this.enodes.get(t);
|
|
745
543
|
if (i)
|
|
746
544
|
for (const n of i.wires) {
|
|
747
545
|
const s = this.wires.get(n);
|
|
748
|
-
if (s && (s.node2 ===
|
|
546
|
+
if (s && (s.node2 === e || s.node1 === e))
|
|
749
547
|
return s;
|
|
750
548
|
}
|
|
751
549
|
}
|
|
@@ -755,8 +553,8 @@ class O {
|
|
|
755
553
|
* @param id - Wire UUID
|
|
756
554
|
* @returns The Wire or undefined if not found
|
|
757
555
|
*/
|
|
758
|
-
getWire(
|
|
759
|
-
return this.wires.get(
|
|
556
|
+
getWire(t) {
|
|
557
|
+
return this.wires.get(t);
|
|
760
558
|
}
|
|
761
559
|
/**
|
|
762
560
|
* Get all wires in the circuit.
|
|
@@ -774,12 +572,12 @@ class O {
|
|
|
774
572
|
* @param nodeId - ENode UUID
|
|
775
573
|
* @returns Array of connected Wires, or empty array if node not found
|
|
776
574
|
*/
|
|
777
|
-
getWiresByNode(
|
|
778
|
-
const
|
|
779
|
-
if (!
|
|
575
|
+
getWiresByNode(t) {
|
|
576
|
+
const e = this.enodes.get(t);
|
|
577
|
+
if (!e)
|
|
780
578
|
return [];
|
|
781
579
|
const i = [];
|
|
782
|
-
for (const n of
|
|
580
|
+
for (const n of e.wires) {
|
|
783
581
|
const s = this.wires.get(n);
|
|
784
582
|
s && i.push(s);
|
|
785
583
|
}
|
|
@@ -791,12 +589,12 @@ class O {
|
|
|
791
589
|
* @param componentId - Component UUID
|
|
792
590
|
* @returns Array of connected Wires, or empty array if component not found
|
|
793
591
|
*/
|
|
794
|
-
getWiresByComponent(
|
|
795
|
-
const
|
|
796
|
-
if (!
|
|
592
|
+
getWiresByComponent(t) {
|
|
593
|
+
const e = this.components.get(t);
|
|
594
|
+
if (!e)
|
|
797
595
|
return [];
|
|
798
596
|
const i = [];
|
|
799
|
-
for (const n of
|
|
597
|
+
for (const n of e.pins)
|
|
800
598
|
i.push(...this.getWiresByNode(n));
|
|
801
599
|
return i;
|
|
802
600
|
}
|
|
@@ -806,11 +604,11 @@ class O {
|
|
|
806
604
|
* @param wireId - Wire UUID
|
|
807
605
|
* @returns Tuple [node1, node2] or undefined if wire not found
|
|
808
606
|
*/
|
|
809
|
-
getNodesByWire(
|
|
810
|
-
const
|
|
811
|
-
if (!
|
|
607
|
+
getNodesByWire(t) {
|
|
608
|
+
const e = this.wires.get(t);
|
|
609
|
+
if (!e)
|
|
812
610
|
return;
|
|
813
|
-
const i = this.enodes.get(
|
|
611
|
+
const i = this.enodes.get(e.node1), n = this.enodes.get(e.node2);
|
|
814
612
|
if (!(!i || !n))
|
|
815
613
|
return [i, n];
|
|
816
614
|
}
|
|
@@ -823,13 +621,13 @@ class O {
|
|
|
823
621
|
* @param node2 - Second ENode UUID
|
|
824
622
|
* @returns true if wire exists, false otherwise
|
|
825
623
|
*/
|
|
826
|
-
hasWireBetween(
|
|
827
|
-
const i = this.enodes.get(
|
|
624
|
+
hasWireBetween(t, e) {
|
|
625
|
+
const i = this.enodes.get(t);
|
|
828
626
|
if (!i)
|
|
829
627
|
return !1;
|
|
830
628
|
for (const n of i.wires) {
|
|
831
629
|
const s = this.wires.get(n);
|
|
832
|
-
if (s && (s.node2 ===
|
|
630
|
+
if (s && (s.node2 === e || s.node1 === e))
|
|
833
631
|
return !0;
|
|
834
632
|
}
|
|
835
633
|
return !1;
|
|
@@ -840,26 +638,26 @@ class O {
|
|
|
840
638
|
* @param pinIds - Set of pins UUIDs
|
|
841
639
|
* @returns Set of components UUIDs
|
|
842
640
|
*/
|
|
843
|
-
getComponentsOfPins(
|
|
844
|
-
const
|
|
845
|
-
for (const i of
|
|
641
|
+
getComponentsOfPins(t) {
|
|
642
|
+
const e = /* @__PURE__ */ new Set();
|
|
643
|
+
for (const i of t) {
|
|
846
644
|
const n = this.enodes.get(i);
|
|
847
|
-
n?.component &&
|
|
645
|
+
n?.component && e.add(n.component);
|
|
848
646
|
}
|
|
849
|
-
return
|
|
647
|
+
return e;
|
|
850
648
|
}
|
|
851
649
|
/**
|
|
852
650
|
* Get a component's pin ENode by its label.
|
|
853
651
|
* @param component
|
|
854
652
|
* @param pinLabel
|
|
855
653
|
*/
|
|
856
|
-
getComponentPinByLabel(
|
|
654
|
+
getComponentPinByLabel(t, e) {
|
|
857
655
|
let i = 0;
|
|
858
|
-
const n =
|
|
859
|
-
for (const o of
|
|
656
|
+
const n = V[t.type], s = Array.from(n.pins.keys());
|
|
657
|
+
for (const o of t.pins) {
|
|
860
658
|
const a = this.enodes.get(o), r = s[i];
|
|
861
659
|
if (r) {
|
|
862
|
-
if (a && r ===
|
|
660
|
+
if (a && r === e)
|
|
863
661
|
return a;
|
|
864
662
|
i++;
|
|
865
663
|
}
|
|
@@ -875,22 +673,22 @@ class O {
|
|
|
875
673
|
* @returns The updated Wire
|
|
876
674
|
* @throws Error if wireId not found
|
|
877
675
|
*/
|
|
878
|
-
updateWireIntermediatePositions(
|
|
879
|
-
const n = this.wires.get(
|
|
676
|
+
updateWireIntermediatePositions(t, e, i = !1) {
|
|
677
|
+
const n = this.wires.get(t);
|
|
880
678
|
if (!n)
|
|
881
|
-
throw new Error(`Wire ${
|
|
679
|
+
throw new Error(`Wire ${t} does not exist`);
|
|
882
680
|
if (i) {
|
|
883
681
|
const s = [
|
|
884
682
|
this.enodes.get(n.node1).getPosition(this),
|
|
885
|
-
...
|
|
683
|
+
...e,
|
|
886
684
|
this.enodes.get(n.node2).getPosition(this)
|
|
887
|
-
], o =
|
|
685
|
+
], o = C(s, 10);
|
|
888
686
|
n.intermediatePositions = o.slice(
|
|
889
687
|
1,
|
|
890
688
|
o.length - 1
|
|
891
689
|
);
|
|
892
690
|
} else
|
|
893
|
-
n.intermediatePositions =
|
|
691
|
+
n.intermediatePositions = e;
|
|
894
692
|
return n;
|
|
895
693
|
}
|
|
896
694
|
/**
|
|
@@ -900,19 +698,19 @@ class O {
|
|
|
900
698
|
* @returns The updated Wire
|
|
901
699
|
* @throws Error if wireId not found
|
|
902
700
|
*/
|
|
903
|
-
simplifyWireIntermediatePositions(
|
|
904
|
-
const
|
|
905
|
-
if (!
|
|
906
|
-
throw new Error(`Wire ${
|
|
701
|
+
simplifyWireIntermediatePositions(t) {
|
|
702
|
+
const e = this.wires.get(t);
|
|
703
|
+
if (!e)
|
|
704
|
+
throw new Error(`Wire ${t} does not exist`);
|
|
907
705
|
const i = [
|
|
908
|
-
this.enodes.get(
|
|
909
|
-
...
|
|
910
|
-
this.enodes.get(
|
|
911
|
-
], n =
|
|
912
|
-
return
|
|
706
|
+
this.enodes.get(e.node1).getPosition(this),
|
|
707
|
+
...e.intermediatePositions,
|
|
708
|
+
this.enodes.get(e.node2).getPosition(this)
|
|
709
|
+
], n = C(i, 5);
|
|
710
|
+
return e.intermediatePositions = n.slice(
|
|
913
711
|
1,
|
|
914
712
|
n.length - 1
|
|
915
|
-
),
|
|
713
|
+
), e.intermediatePositions = C(e.intermediatePositions), e;
|
|
916
714
|
}
|
|
917
715
|
/**
|
|
918
716
|
* Update the source type of an ENode (branching point or component pin).
|
|
@@ -920,30 +718,31 @@ class O {
|
|
|
920
718
|
* @param sourceType - New source type (null to clear)
|
|
921
719
|
* @throws Error if enodeId not found
|
|
922
720
|
*/
|
|
923
|
-
updateENodeSourceType(
|
|
924
|
-
const i = this.enodes.get(
|
|
721
|
+
updateENodeSourceType(t, e) {
|
|
722
|
+
const i = this.enodes.get(t);
|
|
925
723
|
if (!i)
|
|
926
|
-
throw new Error(`ENode ${
|
|
927
|
-
i.source =
|
|
724
|
+
throw new Error(`ENode ${t} does not exist`);
|
|
725
|
+
i.source = e || void 0;
|
|
928
726
|
}
|
|
929
727
|
/**
|
|
930
728
|
* iterate through all components, enodes and wires positions to get the size that allows to enclose all elements.
|
|
931
729
|
* @param margin - optional margin to add to the size
|
|
932
730
|
* @returns size that allows to enclose all elements plus margin
|
|
731
|
+
* @todo if calls to this method at each build operation ends causes slowness see to optimize by restricting checked elements
|
|
933
732
|
*/
|
|
934
|
-
getEnclosingSize(
|
|
935
|
-
let
|
|
733
|
+
getEnclosingSize(t = 0) {
|
|
734
|
+
let e = 0;
|
|
936
735
|
for (const i of this.components.values())
|
|
937
|
-
|
|
736
|
+
e = Math.max(e, Math.abs(i.position.x), Math.abs(i.position.y));
|
|
938
737
|
for (const i of this.enodes.values()) {
|
|
939
|
-
if (i.type ===
|
|
738
|
+
if (i.type === y.Pin) continue;
|
|
940
739
|
const n = i.position;
|
|
941
|
-
n && (
|
|
740
|
+
n && (e = Math.max(e, Math.abs(n.x), Math.abs(n.y)));
|
|
942
741
|
}
|
|
943
742
|
for (const i of this.wires.values())
|
|
944
743
|
for (const n of i.intermediatePositions)
|
|
945
|
-
|
|
946
|
-
return Math.ceil(
|
|
744
|
+
e = Math.max(e, Math.abs(n.x), Math.abs(n.y));
|
|
745
|
+
return Math.ceil(e * 2 + Math.max(t, 0));
|
|
947
746
|
}
|
|
948
747
|
/**
|
|
949
748
|
* Serialize circuit to JSON.
|
|
@@ -959,9 +758,9 @@ class O {
|
|
|
959
758
|
toJSON() {
|
|
960
759
|
return {
|
|
961
760
|
metadata: this.metadata.toJSON(),
|
|
962
|
-
components: this.getAllComponents().map((
|
|
963
|
-
enodes: this.getAllENodes().map((
|
|
964
|
-
wires: this.getAllWires().map((
|
|
761
|
+
components: this.getAllComponents().map((t) => t.toJSON()),
|
|
762
|
+
enodes: this.getAllENodes().map((t) => t.toJSON()),
|
|
763
|
+
wires: this.getAllWires().map((t) => t.toJSON())
|
|
965
764
|
};
|
|
966
765
|
}
|
|
967
766
|
/**
|
|
@@ -978,34 +777,34 @@ class O {
|
|
|
978
777
|
* const circuit = Circuit.fromJSON(json);
|
|
979
778
|
* ```
|
|
980
779
|
*/
|
|
981
|
-
static fromJSON(
|
|
982
|
-
const
|
|
983
|
-
|
|
984
|
-
for (const i of
|
|
985
|
-
const n =
|
|
780
|
+
static fromJSON(t) {
|
|
781
|
+
const e = new _();
|
|
782
|
+
e.metadata = v.fromJSON(t.metadata);
|
|
783
|
+
for (const i of t.components) {
|
|
784
|
+
const n = P.fromJSON(
|
|
986
785
|
i
|
|
987
786
|
);
|
|
988
|
-
|
|
787
|
+
e.components.set(n.id, n);
|
|
989
788
|
}
|
|
990
|
-
for (const i of
|
|
991
|
-
const n =
|
|
789
|
+
for (const i of t.enodes) {
|
|
790
|
+
const n = S.fromJSON(
|
|
992
791
|
i
|
|
993
792
|
);
|
|
994
|
-
|
|
793
|
+
e.enodes.set(n.id, n);
|
|
995
794
|
}
|
|
996
|
-
if (
|
|
997
|
-
for (const i of
|
|
998
|
-
const n =
|
|
795
|
+
if (t.wires)
|
|
796
|
+
for (const i of t.wires) {
|
|
797
|
+
const n = w.fromJSON(
|
|
999
798
|
i
|
|
1000
799
|
);
|
|
1001
|
-
|
|
1002
|
-
const s =
|
|
800
|
+
e.wires.set(n.id, n);
|
|
801
|
+
const s = e.enodes.get(n.node1), o = e.enodes.get(n.node2);
|
|
1003
802
|
s && s.wires.add(n.id), o && o.wires.add(n.id);
|
|
1004
803
|
}
|
|
1005
|
-
return
|
|
804
|
+
return e;
|
|
1006
805
|
}
|
|
1007
806
|
}
|
|
1008
|
-
class
|
|
807
|
+
class ge {
|
|
1009
808
|
behaviors;
|
|
1010
809
|
/**
|
|
1011
810
|
* Create a new empty behavior registry.
|
|
@@ -1021,12 +820,12 @@ class Q {
|
|
|
1021
820
|
* @throws TypeError if behavior is null/undefined or componentType is empty
|
|
1022
821
|
* @returns The registry instance for chaining
|
|
1023
822
|
*/
|
|
1024
|
-
register(
|
|
1025
|
-
if (!
|
|
823
|
+
register(t) {
|
|
824
|
+
if (!t)
|
|
1026
825
|
throw new TypeError("Behavior cannot be null or undefined");
|
|
1027
|
-
if (!
|
|
826
|
+
if (!t.componentType || t.componentType.trim() === "")
|
|
1028
827
|
throw new TypeError("Behavior componentType cannot be empty");
|
|
1029
|
-
return this.behaviors.set(
|
|
828
|
+
return this.behaviors.set(t.componentType, t), this;
|
|
1030
829
|
}
|
|
1031
830
|
/**
|
|
1032
831
|
* Register multiple behaviors at once.
|
|
@@ -1034,8 +833,8 @@ class Q {
|
|
|
1034
833
|
*
|
|
1035
834
|
* @param behaviors - Array of behaviors to register
|
|
1036
835
|
*/
|
|
1037
|
-
registerAll(
|
|
1038
|
-
|
|
836
|
+
registerAll(t) {
|
|
837
|
+
t.forEach((e) => this.register(e));
|
|
1039
838
|
}
|
|
1040
839
|
/**
|
|
1041
840
|
* Get the behavior for a component type.
|
|
@@ -1043,8 +842,8 @@ class Q {
|
|
|
1043
842
|
* @param componentType - Type identifier (e.g., "battery", "led")
|
|
1044
843
|
* @returns The registered behavior, or undefined if not found
|
|
1045
844
|
*/
|
|
1046
|
-
get(
|
|
1047
|
-
return this.behaviors.get(
|
|
845
|
+
get(t) {
|
|
846
|
+
return this.behaviors.get(t);
|
|
1048
847
|
}
|
|
1049
848
|
/**
|
|
1050
849
|
* Check if a behavior is registered for a component type.
|
|
@@ -1052,8 +851,8 @@ class Q {
|
|
|
1052
851
|
* @param componentType - Type identifier to check
|
|
1053
852
|
* @returns True if behavior is registered
|
|
1054
853
|
*/
|
|
1055
|
-
has(
|
|
1056
|
-
return this.behaviors.has(
|
|
854
|
+
has(t) {
|
|
855
|
+
return this.behaviors.has(t);
|
|
1057
856
|
}
|
|
1058
857
|
/**
|
|
1059
858
|
* Unregister a behavior for a component type.
|
|
@@ -1061,8 +860,8 @@ class Q {
|
|
|
1061
860
|
* @param componentType - Type identifier to unregister
|
|
1062
861
|
* @returns True if behavior was found and removed
|
|
1063
862
|
*/
|
|
1064
|
-
unregister(
|
|
1065
|
-
return this.behaviors.delete(
|
|
863
|
+
unregister(t) {
|
|
864
|
+
return this.behaviors.delete(t);
|
|
1066
865
|
}
|
|
1067
866
|
/**
|
|
1068
867
|
* Clear all registered behaviors.
|
|
@@ -1087,7 +886,7 @@ class Q {
|
|
|
1087
886
|
return this.behaviors.size;
|
|
1088
887
|
}
|
|
1089
888
|
}
|
|
1090
|
-
class
|
|
889
|
+
class p {
|
|
1091
890
|
/**
|
|
1092
891
|
* Component UUID this state belongs to.
|
|
1093
892
|
* @readonly
|
|
@@ -1108,37 +907,37 @@ class m {
|
|
|
1108
907
|
* @param componentId - UUID of the component
|
|
1109
908
|
* @param initialState - Initial operational state
|
|
1110
909
|
*/
|
|
1111
|
-
constructor(
|
|
1112
|
-
this.componentId =
|
|
910
|
+
constructor(t, e) {
|
|
911
|
+
this.componentId = t, this.state = e, this.startTick = 0;
|
|
1113
912
|
}
|
|
1114
|
-
hasSameComponent(
|
|
1115
|
-
return this.componentId ===
|
|
913
|
+
hasSameComponent(t) {
|
|
914
|
+
return this.componentId === t.componentId;
|
|
1116
915
|
}
|
|
1117
916
|
}
|
|
1118
|
-
class
|
|
917
|
+
class x extends p {
|
|
1119
918
|
/**
|
|
1120
919
|
* Create a new battery state.
|
|
1121
920
|
*
|
|
1122
921
|
* @param componentId - UUID of the battery component
|
|
1123
922
|
*/
|
|
1124
|
-
constructor(
|
|
1125
|
-
super(
|
|
923
|
+
constructor(t) {
|
|
924
|
+
super(t, "on");
|
|
1126
925
|
}
|
|
1127
926
|
}
|
|
1128
|
-
class
|
|
1129
|
-
componentType =
|
|
927
|
+
class W {
|
|
928
|
+
componentType = h.Battery;
|
|
1130
929
|
/**
|
|
1131
930
|
* Create initial state for a battery.
|
|
1132
931
|
*
|
|
1133
932
|
* @param component - The Battery component
|
|
1134
933
|
* @returns Battery Initial state (always active and delivering voltage)
|
|
1135
934
|
*/
|
|
1136
|
-
createInitialState(
|
|
1137
|
-
if (
|
|
1138
|
-
throw new Error(`Invalid component type for BatteryBehavior: ${
|
|
1139
|
-
return new
|
|
935
|
+
createInitialState(t) {
|
|
936
|
+
if (t.type !== h.Battery)
|
|
937
|
+
throw new Error(`Invalid component type for BatteryBehavior: ${t.type}`);
|
|
938
|
+
return new x(t.id);
|
|
1140
939
|
}
|
|
1141
|
-
allowConductivity(
|
|
940
|
+
allowConductivity(t, e, i, n, s) {
|
|
1142
941
|
return !1;
|
|
1143
942
|
}
|
|
1144
943
|
/**
|
|
@@ -1148,40 +947,40 @@ class k {
|
|
|
1148
947
|
* @param nodeStates
|
|
1149
948
|
* @param _targetTick
|
|
1150
949
|
*/
|
|
1151
|
-
onPinsChange(
|
|
950
|
+
onPinsChange(t, e, i, n) {
|
|
1152
951
|
const s = /* @__PURE__ */ new Map();
|
|
1153
|
-
for (const o in
|
|
1154
|
-
s.set(
|
|
952
|
+
for (const o in t.pins)
|
|
953
|
+
s.set(t.getPinLabel(o), i.get(o));
|
|
1155
954
|
return {
|
|
1156
|
-
componentState:
|
|
955
|
+
componentState: e,
|
|
1157
956
|
hasChanged: !1,
|
|
1158
957
|
scheduledEvents: []
|
|
1159
958
|
};
|
|
1160
959
|
}
|
|
1161
|
-
onUserCommand(
|
|
960
|
+
onUserCommand(t, e, i) {
|
|
1162
961
|
return {
|
|
1163
|
-
componentState:
|
|
962
|
+
componentState: e,
|
|
1164
963
|
hasChanged: !1,
|
|
1165
964
|
scheduledEvents: []
|
|
1166
965
|
};
|
|
1167
966
|
}
|
|
1168
|
-
onEventFiring(
|
|
967
|
+
onEventFiring(t, e, i) {
|
|
1169
968
|
return {
|
|
1170
|
-
componentState:
|
|
969
|
+
componentState: e,
|
|
1171
970
|
hasChanged: !1,
|
|
1172
971
|
scheduledEvents: []
|
|
1173
972
|
};
|
|
1174
973
|
}
|
|
1175
974
|
}
|
|
1176
|
-
class
|
|
975
|
+
class $ extends p {
|
|
1177
976
|
/**
|
|
1178
977
|
* Create a new Lightbulb state.
|
|
1179
978
|
*
|
|
1180
979
|
* @param componentId - UUID of the Lightbulb component
|
|
1181
980
|
* @param initialState - Initial operational state (default: "off")
|
|
1182
981
|
*/
|
|
1183
|
-
constructor(
|
|
1184
|
-
super(
|
|
982
|
+
constructor(t, e = "off") {
|
|
983
|
+
super(t, e);
|
|
1185
984
|
}
|
|
1186
985
|
/**
|
|
1187
986
|
* Check if Lightbulb is in lit state (on or going_on)
|
|
@@ -1190,20 +989,20 @@ class W extends m {
|
|
|
1190
989
|
return this.state === "on" || this.state === "goingOn";
|
|
1191
990
|
}
|
|
1192
991
|
}
|
|
1193
|
-
class
|
|
1194
|
-
componentType =
|
|
992
|
+
class M {
|
|
993
|
+
componentType = h.Lightbulb;
|
|
1195
994
|
/**
|
|
1196
995
|
* Create initial state for a lightbulb.
|
|
1197
996
|
*
|
|
1198
997
|
* @param component - The lightbulb component
|
|
1199
998
|
* @returns lightbulbInitial state (always active and delivering voltage)
|
|
1200
999
|
*/
|
|
1201
|
-
createInitialState(
|
|
1202
|
-
if (
|
|
1203
|
-
throw new Error(`Invalid component type for lightbulbBehavior: ${
|
|
1204
|
-
return new
|
|
1000
|
+
createInitialState(t) {
|
|
1001
|
+
if (t.type !== h.Lightbulb)
|
|
1002
|
+
throw new Error(`Invalid component type for lightbulbBehavior: ${t.type}`);
|
|
1003
|
+
return new $(t.id);
|
|
1205
1004
|
}
|
|
1206
|
-
allowConductivity(
|
|
1005
|
+
allowConductivity(t, e, i, n, s) {
|
|
1207
1006
|
return !0;
|
|
1208
1007
|
}
|
|
1209
1008
|
/**
|
|
@@ -1212,57 +1011,57 @@ class x {
|
|
|
1212
1011
|
* @param nodeStates
|
|
1213
1012
|
* @param targetTick
|
|
1214
1013
|
*/
|
|
1215
|
-
onPinsChange(
|
|
1014
|
+
onPinsChange(t, e, i, n) {
|
|
1216
1015
|
const s = /* @__PURE__ */ new Map();
|
|
1217
|
-
for (const
|
|
1218
|
-
s.set(
|
|
1016
|
+
for (const d of t.pins)
|
|
1017
|
+
s.set(t.getPinLabel(d), i.get(d));
|
|
1219
1018
|
let o = s.get("pin1").hasVoltage && s.get("pin1").hasCurrent || s.get("pin2").hasVoltage && s.get("pin2").hasCurrent || s.get("pin1").hasVoltage && s.get("pin2").hasCurrent || s.get("pin2").hasVoltage && s.get("pin1").hasCurrent, a = !1;
|
|
1220
1019
|
const r = [];
|
|
1221
|
-
return o ? (
|
|
1222
|
-
targetId:
|
|
1020
|
+
return o ? (e.state === "off" || e.state === "goingOff") && (a = !0, e.state = "goingOn", e.startTick = n, r.push({
|
|
1021
|
+
targetId: t.id,
|
|
1223
1022
|
scheduledAtTick: n,
|
|
1224
1023
|
readyAtTick: n + 1,
|
|
1225
1024
|
// TODO handle component config later
|
|
1226
1025
|
type: "GoingOnEnd",
|
|
1227
1026
|
parameters: void 0
|
|
1228
|
-
}),
|
|
1229
|
-
targetId:
|
|
1027
|
+
}), e.state = "goingOn") : (e.state === "on" || e.state === "goingOn") && (a = !0, e.state = "goingOff", e.startTick = n, r.push({
|
|
1028
|
+
targetId: t.id,
|
|
1230
1029
|
scheduledAtTick: n,
|
|
1231
1030
|
readyAtTick: n + 1,
|
|
1232
1031
|
// TODO handle component config later
|
|
1233
1032
|
type: "GoingOffEnd",
|
|
1234
1033
|
parameters: void 0
|
|
1235
|
-
}),
|
|
1236
|
-
componentState:
|
|
1034
|
+
}), e.state = "goingOff"), {
|
|
1035
|
+
componentState: e,
|
|
1237
1036
|
hasChanged: a,
|
|
1238
1037
|
scheduledEvents: r
|
|
1239
1038
|
};
|
|
1240
1039
|
}
|
|
1241
|
-
onUserCommand(
|
|
1040
|
+
onUserCommand(t, e, i) {
|
|
1242
1041
|
return {
|
|
1243
|
-
componentState:
|
|
1042
|
+
componentState: e,
|
|
1244
1043
|
hasChanged: !1,
|
|
1245
1044
|
scheduledEvents: []
|
|
1246
1045
|
};
|
|
1247
1046
|
}
|
|
1248
|
-
onEventFiring(
|
|
1047
|
+
onEventFiring(t, e, i) {
|
|
1249
1048
|
let n = !1;
|
|
1250
|
-
return i.type === "GoingOffEnd" ?
|
|
1251
|
-
componentState:
|
|
1049
|
+
return i.type === "GoingOffEnd" ? e.state !== "off" && (n = !0, e.startTick = i.readyAtTick, e.state = "off") : i.type === "GoingOnEnd" && e.state !== "on" && (n = !0, e.startTick = i.readyAtTick, e.state = "on"), {
|
|
1050
|
+
componentState: e,
|
|
1252
1051
|
hasChanged: n,
|
|
1253
1052
|
scheduledEvents: []
|
|
1254
1053
|
};
|
|
1255
1054
|
}
|
|
1256
1055
|
}
|
|
1257
|
-
class
|
|
1056
|
+
class L extends p {
|
|
1258
1057
|
/**
|
|
1259
1058
|
* Create a new SmallLED state.
|
|
1260
1059
|
*
|
|
1261
1060
|
* @param componentId - UUID of the LED component
|
|
1262
1061
|
* @param initialState - Initial operational state (default: "off")
|
|
1263
1062
|
*/
|
|
1264
|
-
constructor(
|
|
1265
|
-
super(
|
|
1063
|
+
constructor(t, e = "off") {
|
|
1064
|
+
super(t, e);
|
|
1266
1065
|
}
|
|
1267
1066
|
/**
|
|
1268
1067
|
* Check if LED is in lit state (on or going_on)
|
|
@@ -1271,20 +1070,20 @@ class N extends m {
|
|
|
1271
1070
|
return this.state === "on" || this.state === "goingOn";
|
|
1272
1071
|
}
|
|
1273
1072
|
}
|
|
1274
|
-
class
|
|
1275
|
-
componentType =
|
|
1073
|
+
class N {
|
|
1074
|
+
componentType = h.SmallLED;
|
|
1276
1075
|
/**
|
|
1277
1076
|
* Create initial state for a smallLED.
|
|
1278
1077
|
*
|
|
1279
1078
|
* @param component - The smallLED component
|
|
1280
1079
|
* @returns LED Initial state (always active and delivering voltage)
|
|
1281
1080
|
*/
|
|
1282
|
-
createInitialState(
|
|
1283
|
-
if (
|
|
1284
|
-
throw new Error(`Invalid component type for SmallLEDBehavior: ${
|
|
1285
|
-
return new
|
|
1081
|
+
createInitialState(t) {
|
|
1082
|
+
if (t.type !== h.SmallLED)
|
|
1083
|
+
throw new Error(`Invalid component type for SmallLEDBehavior: ${t.type}`);
|
|
1084
|
+
return new L(t.id);
|
|
1286
1085
|
}
|
|
1287
|
-
allowConductivity(
|
|
1086
|
+
allowConductivity(t, e, i, n, s) {
|
|
1288
1087
|
return !0;
|
|
1289
1088
|
}
|
|
1290
1089
|
/**
|
|
@@ -1294,73 +1093,73 @@ class I {
|
|
|
1294
1093
|
* @param nodeStates
|
|
1295
1094
|
* @param targetTick
|
|
1296
1095
|
*/
|
|
1297
|
-
onPinsChange(
|
|
1096
|
+
onPinsChange(t, e, i, n) {
|
|
1298
1097
|
const s = /* @__PURE__ */ new Map();
|
|
1299
|
-
for (const
|
|
1300
|
-
s.set(
|
|
1098
|
+
for (const d of t.pins)
|
|
1099
|
+
s.set(t.getPinLabel(d), i.get(d));
|
|
1301
1100
|
let o = s.get("anode").hasVoltage && s.get("anode").hasCurrent || s.get("cathode").hasVoltage && s.get("cathode").hasCurrent || s.get("anode").hasVoltage && s.get("cathode").hasCurrent || s.get("cathode").hasVoltage && s.get("anode").hasCurrent, a = !1;
|
|
1302
1101
|
const r = [];
|
|
1303
|
-
return o ? (
|
|
1304
|
-
targetId:
|
|
1102
|
+
return o ? (e.state === "off" || e.state === "goingOff") && (a = !0, e.state = "goingOn", e.startTick = n, r.push({
|
|
1103
|
+
targetId: t.id,
|
|
1305
1104
|
scheduledAtTick: n,
|
|
1306
1105
|
readyAtTick: n + 1,
|
|
1307
1106
|
// TODO handle component config later
|
|
1308
1107
|
type: "GoingOnEnd",
|
|
1309
1108
|
parameters: void 0
|
|
1310
|
-
})) : (
|
|
1311
|
-
targetId:
|
|
1109
|
+
})) : (e.state === "on" || e.state === "goingOn") && (a = !0, e.state = "goingOff", e.startTick = n, r.push({
|
|
1110
|
+
targetId: t.id,
|
|
1312
1111
|
scheduledAtTick: n,
|
|
1313
1112
|
readyAtTick: n + 1,
|
|
1314
1113
|
// TODO handle component config later
|
|
1315
1114
|
type: "GoingOffEnd",
|
|
1316
1115
|
parameters: void 0
|
|
1317
1116
|
})), {
|
|
1318
|
-
componentState:
|
|
1117
|
+
componentState: e,
|
|
1319
1118
|
hasChanged: a,
|
|
1320
1119
|
scheduledEvents: r
|
|
1321
1120
|
};
|
|
1322
1121
|
}
|
|
1323
|
-
onUserCommand(
|
|
1122
|
+
onUserCommand(t, e, i) {
|
|
1324
1123
|
return {
|
|
1325
|
-
componentState:
|
|
1124
|
+
componentState: e,
|
|
1326
1125
|
hasChanged: !1,
|
|
1327
1126
|
scheduledEvents: []
|
|
1328
1127
|
};
|
|
1329
1128
|
}
|
|
1330
|
-
onEventFiring(
|
|
1129
|
+
onEventFiring(t, e, i) {
|
|
1331
1130
|
let n = !1;
|
|
1332
|
-
return i.type === "GoingOffEnd" ?
|
|
1333
|
-
componentState:
|
|
1131
|
+
return i.type === "GoingOffEnd" ? e.state !== "off" && (n = !0, e.startTick = i.readyAtTick, e.state = "off") : i.type === "GoingOnEnd" && e.state !== "on" && (n = !0, e.startTick = i.readyAtTick, e.state = "on"), {
|
|
1132
|
+
componentState: e,
|
|
1334
1133
|
hasChanged: n,
|
|
1335
1134
|
scheduledEvents: []
|
|
1336
1135
|
};
|
|
1337
1136
|
}
|
|
1338
1137
|
}
|
|
1339
|
-
class
|
|
1138
|
+
class R extends L {
|
|
1340
1139
|
}
|
|
1341
|
-
class
|
|
1342
|
-
componentType =
|
|
1140
|
+
class F extends N {
|
|
1141
|
+
componentType = h.RectangleLED;
|
|
1343
1142
|
/**
|
|
1344
1143
|
* Create initial state for a RectangleLED.
|
|
1345
1144
|
*
|
|
1346
1145
|
* @param component - The smallLED component
|
|
1347
1146
|
* @returns LED Initial state (always active and delivering voltage)
|
|
1348
1147
|
*/
|
|
1349
|
-
createInitialState(
|
|
1350
|
-
if (
|
|
1351
|
-
throw new Error(`Invalid component type for RectangleLEDBehavior: ${
|
|
1352
|
-
return new
|
|
1148
|
+
createInitialState(t) {
|
|
1149
|
+
if (t.type !== h.RectangleLED)
|
|
1150
|
+
throw new Error(`Invalid component type for RectangleLEDBehavior: ${t.type}`);
|
|
1151
|
+
return new R(t.id);
|
|
1353
1152
|
}
|
|
1354
1153
|
}
|
|
1355
|
-
class
|
|
1154
|
+
class D extends p {
|
|
1356
1155
|
/**
|
|
1357
1156
|
* Create a new Relay state.
|
|
1358
1157
|
*
|
|
1359
1158
|
* @param componentId - UUID of the Relay component
|
|
1360
1159
|
* @param initialState - Initial operational state (default: "open")
|
|
1361
1160
|
*/
|
|
1362
|
-
constructor(
|
|
1363
|
-
super(
|
|
1161
|
+
constructor(t, e = "open") {
|
|
1162
|
+
super(t, e);
|
|
1364
1163
|
}
|
|
1365
1164
|
/**
|
|
1366
1165
|
* Check if relay is in opening or closing state
|
|
@@ -1375,30 +1174,30 @@ class J extends m {
|
|
|
1375
1174
|
return this.state === "closed" || this.state === "closing";
|
|
1376
1175
|
}
|
|
1377
1176
|
}
|
|
1378
|
-
function
|
|
1379
|
-
const
|
|
1380
|
-
return isNaN(
|
|
1177
|
+
function J(c) {
|
|
1178
|
+
const t = parseInt(c.get("transitionSpan") || "", 10);
|
|
1179
|
+
return isNaN(t) || t < 1 ? f.TRANSITION_SPAN_TICKS : t;
|
|
1381
1180
|
}
|
|
1382
|
-
class
|
|
1383
|
-
componentType =
|
|
1181
|
+
class U {
|
|
1182
|
+
componentType = h.Relay;
|
|
1384
1183
|
/**
|
|
1385
1184
|
* Create initial state for a relay.
|
|
1386
1185
|
*
|
|
1387
1186
|
* @param component - The Relay component
|
|
1388
1187
|
* @returns Relay Initial state (open by default)
|
|
1389
1188
|
*/
|
|
1390
|
-
createInitialState(
|
|
1391
|
-
if (
|
|
1392
|
-
throw new Error(`Invalid component type for RelayBehavior: ${
|
|
1393
|
-
const
|
|
1394
|
-
return new
|
|
1189
|
+
createInitialState(t) {
|
|
1190
|
+
if (t.type !== h.Relay)
|
|
1191
|
+
throw new Error(`Invalid component type for RelayBehavior: ${t.type}`);
|
|
1192
|
+
const e = t.config.get("activationLogic") === "negative" ? "closed" : "open";
|
|
1193
|
+
return new D(t.id, e);
|
|
1395
1194
|
}
|
|
1396
|
-
allowConductivity(
|
|
1195
|
+
allowConductivity(t, e, i, n, s) {
|
|
1397
1196
|
if (n === s) return !0;
|
|
1398
|
-
const o =
|
|
1197
|
+
const o = t.getPinLabel(n), a = t.getPinLabel(s);
|
|
1399
1198
|
if (!o || !a) return !1;
|
|
1400
1199
|
const r = [o, a];
|
|
1401
|
-
return r.includes("cmd_in") && r.includes("cmd_out") ? !0 : r.includes("power_in") && r.includes("power_out") ?
|
|
1200
|
+
return r.includes("cmd_in") && r.includes("cmd_out") ? !0 : r.includes("power_in") && r.includes("power_out") ? e.state === "closed" || e.state === "opening" : !1;
|
|
1402
1201
|
}
|
|
1403
1202
|
/**
|
|
1404
1203
|
* Relay cmd pins need to have voltage and current so that relay contactor stays closed
|
|
@@ -1407,56 +1206,56 @@ class R {
|
|
|
1407
1206
|
* @param nodeStates
|
|
1408
1207
|
* @param targetTick
|
|
1409
1208
|
*/
|
|
1410
|
-
onPinsChange(
|
|
1209
|
+
onPinsChange(t, e, i, n) {
|
|
1411
1210
|
const s = /* @__PURE__ */ new Map();
|
|
1412
|
-
for (const
|
|
1413
|
-
s.set(
|
|
1414
|
-
const o = s.get("cmd_in").hasVoltage && s.get("cmd_in").hasCurrent || s.get("cmd_out").hasVoltage && s.get("cmd_out").hasCurrent || s.get("cmd_in").hasVoltage && s.get("cmd_out").hasCurrent || s.get("cmd_out").hasVoltage && s.get("cmd_in").hasCurrent, a =
|
|
1211
|
+
for (const l of t.pins)
|
|
1212
|
+
s.set(t.getPinLabel(l), i.get(l));
|
|
1213
|
+
const o = s.get("cmd_in").hasVoltage && s.get("cmd_in").hasCurrent || s.get("cmd_out").hasVoltage && s.get("cmd_out").hasCurrent || s.get("cmd_in").hasVoltage && s.get("cmd_out").hasCurrent || s.get("cmd_out").hasVoltage && s.get("cmd_in").hasCurrent, a = t.config.get("activationLogic") === "negative" ? !o : o;
|
|
1415
1214
|
let r = !1;
|
|
1416
|
-
const
|
|
1417
|
-
return a ? (
|
|
1418
|
-
targetId:
|
|
1215
|
+
const d = [], g = J(t.config);
|
|
1216
|
+
return a ? (e.state === "open" || e.state === "opening") && (r = !0, e.state = "closing", e.startTick = n, d.push({
|
|
1217
|
+
targetId: t.id,
|
|
1419
1218
|
scheduledAtTick: n,
|
|
1420
|
-
readyAtTick: n +
|
|
1219
|
+
readyAtTick: n + g,
|
|
1421
1220
|
type: "ClosingEnd",
|
|
1422
1221
|
parameters: void 0
|
|
1423
|
-
})) : (
|
|
1424
|
-
targetId:
|
|
1222
|
+
})) : (e.state === "closed" || e.state === "closing") && (r = !0, e.state = "opening", e.startTick = n, d.push({
|
|
1223
|
+
targetId: t.id,
|
|
1425
1224
|
scheduledAtTick: n,
|
|
1426
|
-
readyAtTick: n +
|
|
1225
|
+
readyAtTick: n + g,
|
|
1427
1226
|
type: "OpeningEnd",
|
|
1428
1227
|
parameters: void 0
|
|
1429
1228
|
})), {
|
|
1430
|
-
componentState:
|
|
1229
|
+
componentState: e,
|
|
1431
1230
|
hasChanged: r,
|
|
1432
|
-
scheduledEvents:
|
|
1231
|
+
scheduledEvents: d
|
|
1433
1232
|
};
|
|
1434
1233
|
}
|
|
1435
|
-
onUserCommand(
|
|
1234
|
+
onUserCommand(t, e, i) {
|
|
1436
1235
|
return {
|
|
1437
|
-
componentState:
|
|
1236
|
+
componentState: e,
|
|
1438
1237
|
hasChanged: !1,
|
|
1439
1238
|
scheduledEvents: []
|
|
1440
1239
|
};
|
|
1441
1240
|
}
|
|
1442
|
-
onEventFiring(
|
|
1241
|
+
onEventFiring(t, e, i) {
|
|
1443
1242
|
let n = !1;
|
|
1444
|
-
return i.type === "ClosingEnd" ?
|
|
1445
|
-
componentState:
|
|
1243
|
+
return i.type === "ClosingEnd" ? e.state !== "closed" && (n = !0, e.startTick = i.readyAtTick, e.state = "closed") : i.type === "OpeningEnd" && e.state !== "open" && (n = !0, e.startTick = i.readyAtTick, e.state = "open"), {
|
|
1244
|
+
componentState: e,
|
|
1446
1245
|
hasChanged: n,
|
|
1447
1246
|
scheduledEvents: []
|
|
1448
1247
|
};
|
|
1449
1248
|
}
|
|
1450
1249
|
}
|
|
1451
|
-
class
|
|
1250
|
+
class H extends p {
|
|
1452
1251
|
/**
|
|
1453
1252
|
* Create a new Switch state.
|
|
1454
1253
|
*
|
|
1455
1254
|
* @param componentId - UUID of the Switch component
|
|
1456
1255
|
* @param initialState - Initial operational state (default: "open")
|
|
1457
1256
|
*/
|
|
1458
|
-
constructor(
|
|
1459
|
-
super(
|
|
1257
|
+
constructor(t, e = "open") {
|
|
1258
|
+
super(t, e);
|
|
1460
1259
|
}
|
|
1461
1260
|
/**
|
|
1462
1261
|
* Check if switch is in opening or closing state
|
|
@@ -1471,15 +1270,15 @@ class F extends m {
|
|
|
1471
1270
|
return this.state === "closed" || this.state === "closing";
|
|
1472
1271
|
}
|
|
1473
1272
|
}
|
|
1474
|
-
class
|
|
1273
|
+
class z extends p {
|
|
1475
1274
|
/**
|
|
1476
1275
|
* Create a new Transistor state.
|
|
1477
1276
|
*
|
|
1478
1277
|
* @param componentId - UUID of the Transistor component
|
|
1479
1278
|
* @param initialState - Initial operational state (default: "open")
|
|
1480
1279
|
*/
|
|
1481
|
-
constructor(
|
|
1482
|
-
super(
|
|
1280
|
+
constructor(t, e = "open") {
|
|
1281
|
+
super(t, e);
|
|
1483
1282
|
}
|
|
1484
1283
|
/**
|
|
1485
1284
|
* Check if transistor is in opening or closing state
|
|
@@ -1494,28 +1293,116 @@ class V extends m {
|
|
|
1494
1293
|
return this.state === "closed" || this.state === "closing";
|
|
1495
1294
|
}
|
|
1496
1295
|
}
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1296
|
+
class K extends p {
|
|
1297
|
+
/**
|
|
1298
|
+
* Create a new Buffer state.
|
|
1299
|
+
*
|
|
1300
|
+
* @param componentId - UUID of the Buffer component
|
|
1301
|
+
* @param initialState - Initial operational state (default: "low")
|
|
1302
|
+
*/
|
|
1303
|
+
constructor(t, e = "low") {
|
|
1304
|
+
super(t, e);
|
|
1305
|
+
}
|
|
1306
|
+
/**
|
|
1307
|
+
* Check if output is in a rising or falling transition
|
|
1308
|
+
*/
|
|
1309
|
+
get isInTransition() {
|
|
1310
|
+
return this.state === "rising" || this.state === "falling";
|
|
1311
|
+
}
|
|
1312
|
+
/**
|
|
1313
|
+
* Check if output is high
|
|
1314
|
+
*/
|
|
1315
|
+
get isHigh() {
|
|
1316
|
+
return this.state === "high";
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
class T extends p {
|
|
1320
|
+
/**
|
|
1321
|
+
* Create a new AND Gate state.
|
|
1322
|
+
*
|
|
1323
|
+
* @param componentId - UUID of the AND Gate component
|
|
1324
|
+
* @param initialState - Initial operational state (default: "low")
|
|
1325
|
+
*/
|
|
1326
|
+
constructor(t, e = "low") {
|
|
1327
|
+
super(t, e);
|
|
1328
|
+
}
|
|
1329
|
+
/**
|
|
1330
|
+
* Check if output is in a rising or falling transition
|
|
1331
|
+
*/
|
|
1332
|
+
get isInTransition() {
|
|
1333
|
+
return this.state === "rising" || this.state === "falling";
|
|
1334
|
+
}
|
|
1335
|
+
/**
|
|
1336
|
+
* Check if output is high
|
|
1337
|
+
*/
|
|
1338
|
+
get isHigh() {
|
|
1339
|
+
return this.state === "high";
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
class X extends T {
|
|
1343
|
+
constructor(t, e = "low") {
|
|
1344
|
+
super(t, e);
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
class q extends T {
|
|
1348
|
+
constructor(t, e = "low") {
|
|
1349
|
+
super(t, e);
|
|
1350
|
+
}
|
|
1502
1351
|
}
|
|
1503
|
-
class
|
|
1504
|
-
|
|
1352
|
+
class E extends p {
|
|
1353
|
+
constructor(t, e = "low") {
|
|
1354
|
+
super(t, e);
|
|
1355
|
+
}
|
|
1356
|
+
get isInTransition() {
|
|
1357
|
+
return this.state === "rising" || this.state === "falling";
|
|
1358
|
+
}
|
|
1359
|
+
get isHigh() {
|
|
1360
|
+
return this.state === "high";
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
class Q extends E {
|
|
1364
|
+
constructor(t, e = "low") {
|
|
1365
|
+
super(t, e);
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
class Y extends E {
|
|
1369
|
+
constructor(t, e = "low") {
|
|
1370
|
+
super(t, e);
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1373
|
+
class Z extends p {
|
|
1374
|
+
constructor(t, e = "low") {
|
|
1375
|
+
super(t, e);
|
|
1376
|
+
}
|
|
1377
|
+
get isInTransition() {
|
|
1378
|
+
return this.state === "rising" || this.state === "falling";
|
|
1379
|
+
}
|
|
1380
|
+
get isHigh() {
|
|
1381
|
+
return this.state === "high";
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
function j(c) {
|
|
1385
|
+
if (!c)
|
|
1386
|
+
return f.TRANSITION_SPAN_TICKS;
|
|
1387
|
+
const t = parseInt(c.get("tickCount") || "", 10);
|
|
1388
|
+
return isNaN(t) || t < 1 ? f.TRANSITION_SPAN_TICKS : t;
|
|
1389
|
+
}
|
|
1390
|
+
class ee {
|
|
1391
|
+
componentType = h.Switch;
|
|
1505
1392
|
/**
|
|
1506
1393
|
* Create initial state for a switch.
|
|
1507
1394
|
*
|
|
1508
1395
|
* @param component - The Switch component
|
|
1509
1396
|
* @returns Switch Initial state (open by default)
|
|
1510
1397
|
*/
|
|
1511
|
-
createInitialState(
|
|
1512
|
-
if (
|
|
1513
|
-
throw new Error(`Invalid component type for SwitchBehavior: ${
|
|
1514
|
-
const
|
|
1515
|
-
return new
|
|
1398
|
+
createInitialState(t) {
|
|
1399
|
+
if (t.type !== h.Switch)
|
|
1400
|
+
throw new Error(`Invalid component type for SwitchBehavior: ${t.type}`);
|
|
1401
|
+
const e = t.config.get("initialState") || "open";
|
|
1402
|
+
return new H(t.id, e);
|
|
1516
1403
|
}
|
|
1517
|
-
allowConductivity(
|
|
1518
|
-
return
|
|
1404
|
+
allowConductivity(t, e, i, n, s) {
|
|
1405
|
+
return e.state === "closed" || e.state === "opening";
|
|
1519
1406
|
}
|
|
1520
1407
|
/**
|
|
1521
1408
|
* Switches states depend on user interaction, not their pins so this is more of a decorative function
|
|
@@ -1524,66 +1411,66 @@ class z {
|
|
|
1524
1411
|
* @param _nodeStates
|
|
1525
1412
|
* @param _targetTick
|
|
1526
1413
|
*/
|
|
1527
|
-
onPinsChange(
|
|
1414
|
+
onPinsChange(t, e, i, n) {
|
|
1528
1415
|
return {
|
|
1529
|
-
componentState:
|
|
1416
|
+
componentState: e,
|
|
1530
1417
|
hasChanged: !1,
|
|
1531
1418
|
scheduledEvents: []
|
|
1532
1419
|
};
|
|
1533
1420
|
}
|
|
1534
|
-
onUserCommand(
|
|
1421
|
+
onUserCommand(t, e, i) {
|
|
1535
1422
|
let n = !1;
|
|
1536
1423
|
const s = [];
|
|
1537
|
-
if (i.type === "toggle_switch" && ["open", "closed"].includes(
|
|
1538
|
-
|
|
1539
|
-
const o =
|
|
1424
|
+
if (i.type === "toggle_switch" && ["open", "closed"].includes(e.state)) {
|
|
1425
|
+
e.state = e.state === "open" ? "closing" : "opening", e.startTick = i.scheduledAtTick + 1, n = !0;
|
|
1426
|
+
const o = j(i.parameters);
|
|
1540
1427
|
s.push({
|
|
1541
|
-
targetId:
|
|
1542
|
-
scheduledAtTick:
|
|
1543
|
-
readyAtTick:
|
|
1544
|
-
type:
|
|
1428
|
+
targetId: t.id,
|
|
1429
|
+
scheduledAtTick: e.startTick,
|
|
1430
|
+
readyAtTick: e.startTick + o,
|
|
1431
|
+
type: e.state === "closing" ? "ClosingEnd" : "OpeningEnd",
|
|
1545
1432
|
parameters: void 0
|
|
1546
1433
|
});
|
|
1547
1434
|
}
|
|
1548
1435
|
return {
|
|
1549
|
-
componentState:
|
|
1436
|
+
componentState: e,
|
|
1550
1437
|
hasChanged: n,
|
|
1551
1438
|
scheduledEvents: s
|
|
1552
1439
|
};
|
|
1553
1440
|
}
|
|
1554
|
-
onEventFiring(
|
|
1441
|
+
onEventFiring(t, e, i) {
|
|
1555
1442
|
let n = !1;
|
|
1556
|
-
return i.type === "ClosingEnd" ?
|
|
1557
|
-
componentState:
|
|
1443
|
+
return i.type === "ClosingEnd" ? e.state !== "closed" && (n = !0, e.startTick = i.readyAtTick, e.state = "closed") : i.type === "OpeningEnd" && e.state !== "open" && (n = !0, e.startTick = i.readyAtTick, e.state = "open"), {
|
|
1444
|
+
componentState: e,
|
|
1558
1445
|
hasChanged: n,
|
|
1559
1446
|
scheduledEvents: []
|
|
1560
1447
|
};
|
|
1561
1448
|
}
|
|
1562
1449
|
}
|
|
1563
|
-
function
|
|
1564
|
-
const
|
|
1565
|
-
return isNaN(
|
|
1450
|
+
function te(c) {
|
|
1451
|
+
const t = parseInt(c.get("transitionSpan") || "", 10);
|
|
1452
|
+
return isNaN(t) || t < 1 ? f.TRANSITION_SPAN_TICKS : t;
|
|
1566
1453
|
}
|
|
1567
|
-
class
|
|
1568
|
-
componentType =
|
|
1454
|
+
class ne {
|
|
1455
|
+
componentType = h.Transistor;
|
|
1569
1456
|
/**
|
|
1570
1457
|
* Create initial state for a transistor.
|
|
1571
1458
|
*
|
|
1572
1459
|
* @param component - The Transistor component
|
|
1573
1460
|
* @returns Transistor Initial state (open by default)
|
|
1574
1461
|
*/
|
|
1575
|
-
createInitialState(
|
|
1576
|
-
if (
|
|
1577
|
-
throw new Error(`Invalid component type for TransistorBehavior: ${
|
|
1578
|
-
const
|
|
1579
|
-
return new
|
|
1462
|
+
createInitialState(t) {
|
|
1463
|
+
if (t.type !== h.Transistor)
|
|
1464
|
+
throw new Error(`Invalid component type for TransistorBehavior: ${t.type}`);
|
|
1465
|
+
const e = t.config.get("activationLogic") === "negative" ? "closed" : "open";
|
|
1466
|
+
return new z(t.id, e);
|
|
1580
1467
|
}
|
|
1581
|
-
allowConductivity(
|
|
1468
|
+
allowConductivity(t, e, i, n, s) {
|
|
1582
1469
|
if (n === s) return !0;
|
|
1583
|
-
const o =
|
|
1470
|
+
const o = t.getPinLabel(n), a = t.getPinLabel(s);
|
|
1584
1471
|
if (!o || !a) return !1;
|
|
1585
1472
|
const r = [o, a];
|
|
1586
|
-
return r.includes("collector") && r.includes("emitter") ?
|
|
1473
|
+
return r.includes("collector") && r.includes("emitter") ? e.state === "closed" || e.state === "opening" : !1;
|
|
1587
1474
|
}
|
|
1588
1475
|
/**
|
|
1589
1476
|
* Transistor Base need to have only voltage so that transistor contactor stays closed
|
|
@@ -1592,92 +1479,524 @@ class K {
|
|
|
1592
1479
|
* @param nodeStates
|
|
1593
1480
|
* @param targetTick
|
|
1594
1481
|
*/
|
|
1595
|
-
onPinsChange(
|
|
1482
|
+
onPinsChange(t, e, i, n) {
|
|
1596
1483
|
const s = /* @__PURE__ */ new Map();
|
|
1597
|
-
for (const
|
|
1598
|
-
s.set(
|
|
1599
|
-
const o = s.get("base").hasVoltage, a =
|
|
1484
|
+
for (const l of t.pins)
|
|
1485
|
+
s.set(t.getPinLabel(l), i.get(l));
|
|
1486
|
+
const o = s.get("base").hasVoltage, a = t.config.get("activationLogic") === "negative" ? !o : o;
|
|
1600
1487
|
let r = !1;
|
|
1601
|
-
const
|
|
1602
|
-
return a ? (
|
|
1603
|
-
targetId:
|
|
1488
|
+
const d = [], g = te(t.config);
|
|
1489
|
+
return a ? (e.state === "open" || e.state === "opening") && (r = !0, e.state = "closing", e.startTick = n, d.push({
|
|
1490
|
+
targetId: t.id,
|
|
1604
1491
|
scheduledAtTick: n,
|
|
1605
|
-
readyAtTick: n +
|
|
1492
|
+
readyAtTick: n + g,
|
|
1606
1493
|
type: "ClosingEnd",
|
|
1607
1494
|
parameters: void 0
|
|
1608
|
-
})) : (
|
|
1609
|
-
targetId:
|
|
1495
|
+
})) : (e.state === "closed" || e.state === "closing") && (r = !0, e.state = "opening", e.startTick = n, d.push({
|
|
1496
|
+
targetId: t.id,
|
|
1610
1497
|
scheduledAtTick: n,
|
|
1611
|
-
readyAtTick: n +
|
|
1498
|
+
readyAtTick: n + g,
|
|
1612
1499
|
type: "OpeningEnd",
|
|
1613
1500
|
parameters: void 0
|
|
1614
1501
|
})), {
|
|
1615
|
-
componentState:
|
|
1502
|
+
componentState: e,
|
|
1503
|
+
hasChanged: r,
|
|
1504
|
+
scheduledEvents: d
|
|
1505
|
+
};
|
|
1506
|
+
}
|
|
1507
|
+
onUserCommand(t, e, i) {
|
|
1508
|
+
return {
|
|
1509
|
+
componentState: e,
|
|
1510
|
+
hasChanged: !1,
|
|
1511
|
+
scheduledEvents: []
|
|
1512
|
+
};
|
|
1513
|
+
}
|
|
1514
|
+
onEventFiring(t, e, i) {
|
|
1515
|
+
let n = !1;
|
|
1516
|
+
return i.type === "ClosingEnd" ? e.state !== "closed" && (n = !0, e.startTick = i.readyAtTick, e.state = "closed") : i.type === "OpeningEnd" && e.state !== "open" && (n = !0, e.startTick = i.readyAtTick, e.state = "open"), {
|
|
1517
|
+
componentState: e,
|
|
1518
|
+
hasChanged: n,
|
|
1519
|
+
scheduledEvents: []
|
|
1520
|
+
};
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
function ie(c) {
|
|
1524
|
+
const t = parseInt(c.get("transitionSpan") || "", 10);
|
|
1525
|
+
return isNaN(t) || t < 1 ? f.TRANSITION_SPAN_TICKS : t;
|
|
1526
|
+
}
|
|
1527
|
+
class se {
|
|
1528
|
+
componentType = h.Buffer;
|
|
1529
|
+
/**
|
|
1530
|
+
* Create initial state for a Buffer.
|
|
1531
|
+
*
|
|
1532
|
+
* @param component - The Buffer component
|
|
1533
|
+
* @returns Buffer Initial state (low by default, high for negative activation logic)
|
|
1534
|
+
*/
|
|
1535
|
+
createInitialState(t) {
|
|
1536
|
+
if (t.type !== h.Buffer)
|
|
1537
|
+
throw new Error(`Invalid component type for BufferBehavior: ${t.type}`);
|
|
1538
|
+
const e = t.config.get("activationLogic") === "negative" ? "high" : "low";
|
|
1539
|
+
return new K(t.id, e);
|
|
1540
|
+
}
|
|
1541
|
+
allowConductivity(t, e, i, n, s) {
|
|
1542
|
+
if (n === s) return !0;
|
|
1543
|
+
const o = t.getPinLabel(n), a = t.getPinLabel(s);
|
|
1544
|
+
if (!o || !a) return !1;
|
|
1545
|
+
const r = [o, a];
|
|
1546
|
+
return r.includes("vcc") && r.includes("output") ? e.state === "high" || e.state === "falling" : !1;
|
|
1547
|
+
}
|
|
1548
|
+
/**
|
|
1549
|
+
* Relayer needs voltage on input to drive the output high, and on the contrary Inverter needs no voltage on input
|
|
1550
|
+
* @param component
|
|
1551
|
+
* @param state
|
|
1552
|
+
* @param nodeStates
|
|
1553
|
+
* @param targetTick
|
|
1554
|
+
*/
|
|
1555
|
+
onPinsChange(t, e, i, n) {
|
|
1556
|
+
const s = /* @__PURE__ */ new Map();
|
|
1557
|
+
for (const l of t.pins)
|
|
1558
|
+
s.set(t.getPinLabel(l), i.get(l));
|
|
1559
|
+
const o = s.get("input").hasVoltage, a = t.config.get("activationLogic") === "negative" ? !o : o;
|
|
1560
|
+
let r = !1;
|
|
1561
|
+
const d = [], g = ie(t.config);
|
|
1562
|
+
return a ? (e.state === "low" || e.state === "falling") && (r = !0, e.state = "rising", e.startTick = n, d.push({
|
|
1563
|
+
targetId: t.id,
|
|
1564
|
+
scheduledAtTick: n,
|
|
1565
|
+
readyAtTick: n + g,
|
|
1566
|
+
type: "RisingComplete",
|
|
1567
|
+
parameters: void 0
|
|
1568
|
+
})) : (e.state === "high" || e.state === "rising") && (r = !0, e.state = "falling", e.startTick = n, d.push({
|
|
1569
|
+
targetId: t.id,
|
|
1570
|
+
scheduledAtTick: n,
|
|
1571
|
+
readyAtTick: n + g,
|
|
1572
|
+
type: "FallingComplete",
|
|
1573
|
+
parameters: void 0
|
|
1574
|
+
})), {
|
|
1575
|
+
componentState: e,
|
|
1616
1576
|
hasChanged: r,
|
|
1617
|
-
scheduledEvents:
|
|
1577
|
+
scheduledEvents: d
|
|
1618
1578
|
};
|
|
1619
1579
|
}
|
|
1620
|
-
onUserCommand(
|
|
1580
|
+
onUserCommand(t, e, i) {
|
|
1621
1581
|
return {
|
|
1622
|
-
componentState:
|
|
1582
|
+
componentState: e,
|
|
1623
1583
|
hasChanged: !1,
|
|
1624
1584
|
scheduledEvents: []
|
|
1625
1585
|
};
|
|
1626
1586
|
}
|
|
1627
|
-
onEventFiring(
|
|
1587
|
+
onEventFiring(t, e, i) {
|
|
1628
1588
|
let n = !1;
|
|
1629
|
-
return i.type === "
|
|
1630
|
-
componentState:
|
|
1589
|
+
return i.type === "RisingComplete" ? e.state !== "high" && (n = !0, e.startTick = i.readyAtTick, e.state = "high") : i.type === "FallingComplete" && e.state !== "low" && (n = !0, e.startTick = i.readyAtTick, e.state = "low"), {
|
|
1590
|
+
componentState: e,
|
|
1631
1591
|
hasChanged: n,
|
|
1632
1592
|
scheduledEvents: []
|
|
1633
1593
|
};
|
|
1634
1594
|
}
|
|
1635
1595
|
}
|
|
1636
|
-
|
|
1637
|
-
|
|
1596
|
+
class I {
|
|
1597
|
+
componentType = h.AndGate;
|
|
1598
|
+
/**
|
|
1599
|
+
* Create initial state for an AND Gate.
|
|
1600
|
+
*
|
|
1601
|
+
* @param component - The AND Gate component
|
|
1602
|
+
* @returns Initial state (low by default, high for negative activation logic)
|
|
1603
|
+
*/
|
|
1604
|
+
createInitialState(t) {
|
|
1605
|
+
if (t.type !== h.AndGate)
|
|
1606
|
+
throw new Error(`Invalid component type for AndGateBehavior: ${t.type}`);
|
|
1607
|
+
const e = t.config.get("activationLogic") === "negative" ? "high" : "low";
|
|
1608
|
+
return new T(t.id, e);
|
|
1609
|
+
}
|
|
1610
|
+
allowConductivity(t, e, i, n, s) {
|
|
1611
|
+
if (n === s) return !0;
|
|
1612
|
+
const o = t.getPinLabel(n), a = t.getPinLabel(s);
|
|
1613
|
+
if (!o || !a) return !1;
|
|
1614
|
+
const r = [o, a];
|
|
1615
|
+
return r.includes("vcc") && r.includes("output") ? e.state === "high" || e.state === "falling" : !1;
|
|
1616
|
+
}
|
|
1617
|
+
/**
|
|
1618
|
+
* Get the transition span from component config.
|
|
1619
|
+
* @param config - Component config map
|
|
1620
|
+
* @returns Number of ticks for transition (minimum 1)
|
|
1621
|
+
*/
|
|
1622
|
+
getTransitionSpan(t) {
|
|
1623
|
+
const e = parseInt(t.get("transitionSpan") || "", 10);
|
|
1624
|
+
return isNaN(e) || e < 1 ? f.TRANSITION_SPAN_TICKS : e;
|
|
1625
|
+
}
|
|
1626
|
+
/**
|
|
1627
|
+
* AND gate output goes high when ALL inputs have voltage.
|
|
1628
|
+
* With negative activationLogic (NAND), output goes high when ANY input lacks voltage.
|
|
1629
|
+
*/
|
|
1630
|
+
onPinsChange(t, e, i, n) {
|
|
1631
|
+
const s = /* @__PURE__ */ new Map();
|
|
1632
|
+
for (const l of t.pins)
|
|
1633
|
+
s.set(t.getPinLabel(l), i.get(l));
|
|
1634
|
+
const o = s.get("input1").hasVoltage && s.get("input2").hasVoltage, a = t.config.get("activationLogic") === "negative" ? !o : o;
|
|
1635
|
+
let r = !1;
|
|
1636
|
+
const d = [], g = this.getTransitionSpan(t.config);
|
|
1637
|
+
return a ? (e.state === "low" || e.state === "falling") && (r = !0, e.state = "rising", e.startTick = n, d.push({
|
|
1638
|
+
targetId: t.id,
|
|
1639
|
+
scheduledAtTick: n,
|
|
1640
|
+
readyAtTick: n + g,
|
|
1641
|
+
type: "RisingComplete",
|
|
1642
|
+
parameters: void 0
|
|
1643
|
+
})) : (e.state === "high" || e.state === "rising") && (r = !0, e.state = "falling", e.startTick = n, d.push({
|
|
1644
|
+
targetId: t.id,
|
|
1645
|
+
scheduledAtTick: n,
|
|
1646
|
+
readyAtTick: n + g,
|
|
1647
|
+
type: "FallingComplete",
|
|
1648
|
+
parameters: void 0
|
|
1649
|
+
})), {
|
|
1650
|
+
componentState: e,
|
|
1651
|
+
hasChanged: r,
|
|
1652
|
+
scheduledEvents: d
|
|
1653
|
+
};
|
|
1654
|
+
}
|
|
1655
|
+
onUserCommand(t, e, i) {
|
|
1656
|
+
return {
|
|
1657
|
+
componentState: e,
|
|
1658
|
+
hasChanged: !1,
|
|
1659
|
+
scheduledEvents: []
|
|
1660
|
+
};
|
|
1661
|
+
}
|
|
1662
|
+
onEventFiring(t, e, i) {
|
|
1663
|
+
let n = !1;
|
|
1664
|
+
return i.type === "RisingComplete" ? e.state !== "high" && (n = !0, e.startTick = i.readyAtTick, e.state = "high") : i.type === "FallingComplete" && e.state !== "low" && (n = !0, e.startTick = i.readyAtTick, e.state = "low"), {
|
|
1665
|
+
componentState: e,
|
|
1666
|
+
hasChanged: n,
|
|
1667
|
+
scheduledEvents: []
|
|
1668
|
+
};
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
class oe extends I {
|
|
1672
|
+
componentType = h.And4Gate;
|
|
1673
|
+
createInitialState(t) {
|
|
1674
|
+
if (t.type !== h.And4Gate)
|
|
1675
|
+
throw new Error(`Invalid component type for And4GateBehavior: ${t.type}`);
|
|
1676
|
+
const e = t.config.get("activationLogic") === "negative" ? "high" : "low";
|
|
1677
|
+
return new X(t.id, e);
|
|
1678
|
+
}
|
|
1679
|
+
onPinsChange(t, e, i, n) {
|
|
1680
|
+
const s = /* @__PURE__ */ new Map();
|
|
1681
|
+
for (const l of t.pins)
|
|
1682
|
+
s.set(t.getPinLabel(l), i.get(l));
|
|
1683
|
+
const o = s.get("input1").hasVoltage && s.get("input2").hasVoltage && s.get("input3").hasVoltage && s.get("input4").hasVoltage, a = t.config.get("activationLogic") === "negative" ? !o : o;
|
|
1684
|
+
let r = !1;
|
|
1685
|
+
const d = [], g = this.getTransitionSpan(t.config);
|
|
1686
|
+
return a ? (e.state === "low" || e.state === "falling") && (r = !0, e.state = "rising", e.startTick = n, d.push({
|
|
1687
|
+
targetId: t.id,
|
|
1688
|
+
scheduledAtTick: n,
|
|
1689
|
+
readyAtTick: n + g,
|
|
1690
|
+
type: "RisingComplete",
|
|
1691
|
+
parameters: void 0
|
|
1692
|
+
})) : (e.state === "high" || e.state === "rising") && (r = !0, e.state = "falling", e.startTick = n, d.push({
|
|
1693
|
+
targetId: t.id,
|
|
1694
|
+
scheduledAtTick: n,
|
|
1695
|
+
readyAtTick: n + g,
|
|
1696
|
+
type: "FallingComplete",
|
|
1697
|
+
parameters: void 0
|
|
1698
|
+
})), {
|
|
1699
|
+
componentState: e,
|
|
1700
|
+
hasChanged: r,
|
|
1701
|
+
scheduledEvents: d
|
|
1702
|
+
};
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
class re extends I {
|
|
1706
|
+
componentType = h.And8Gate;
|
|
1707
|
+
createInitialState(t) {
|
|
1708
|
+
if (t.type !== h.And8Gate)
|
|
1709
|
+
throw new Error(`Invalid component type for And8GateBehavior: ${t.type}`);
|
|
1710
|
+
const e = t.config.get("activationLogic") === "negative" ? "high" : "low";
|
|
1711
|
+
return new q(t.id, e);
|
|
1712
|
+
}
|
|
1713
|
+
onPinsChange(t, e, i, n) {
|
|
1714
|
+
const s = /* @__PURE__ */ new Map();
|
|
1715
|
+
for (const l of t.pins)
|
|
1716
|
+
s.set(t.getPinLabel(l), i.get(l));
|
|
1717
|
+
const o = s.get("input1").hasVoltage && s.get("input2").hasVoltage && s.get("input3").hasVoltage && s.get("input4").hasVoltage && s.get("input5").hasVoltage && s.get("input6").hasVoltage && s.get("input7").hasVoltage && s.get("input8").hasVoltage, a = t.config.get("activationLogic") === "negative" ? !o : o;
|
|
1718
|
+
let r = !1;
|
|
1719
|
+
const d = [], g = this.getTransitionSpan(t.config);
|
|
1720
|
+
return a ? (e.state === "low" || e.state === "falling") && (r = !0, e.state = "rising", e.startTick = n, d.push({
|
|
1721
|
+
targetId: t.id,
|
|
1722
|
+
scheduledAtTick: n,
|
|
1723
|
+
readyAtTick: n + g,
|
|
1724
|
+
type: "RisingComplete",
|
|
1725
|
+
parameters: void 0
|
|
1726
|
+
})) : (e.state === "high" || e.state === "rising") && (r = !0, e.state = "falling", e.startTick = n, d.push({
|
|
1727
|
+
targetId: t.id,
|
|
1728
|
+
scheduledAtTick: n,
|
|
1729
|
+
readyAtTick: n + g,
|
|
1730
|
+
type: "FallingComplete",
|
|
1731
|
+
parameters: void 0
|
|
1732
|
+
})), {
|
|
1733
|
+
componentState: e,
|
|
1734
|
+
hasChanged: r,
|
|
1735
|
+
scheduledEvents: d
|
|
1736
|
+
};
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
class A {
|
|
1740
|
+
componentType = h.OrGate;
|
|
1741
|
+
createInitialState(t) {
|
|
1742
|
+
if (t.type !== h.OrGate)
|
|
1743
|
+
throw new Error(`Invalid component type for OrGateBehavior: ${t.type}`);
|
|
1744
|
+
const e = t.config.get("activationLogic") === "negative" ? "high" : "low";
|
|
1745
|
+
return new E(t.id, e);
|
|
1746
|
+
}
|
|
1747
|
+
allowConductivity(t, e, i, n, s) {
|
|
1748
|
+
if (n === s) return !0;
|
|
1749
|
+
const o = t.getPinLabel(n), a = t.getPinLabel(s);
|
|
1750
|
+
if (!o || !a) return !1;
|
|
1751
|
+
const r = [o, a];
|
|
1752
|
+
return r.includes("vcc") && r.includes("output") ? e.state === "high" || e.state === "falling" : !1;
|
|
1753
|
+
}
|
|
1754
|
+
getTransitionSpan(t) {
|
|
1755
|
+
const e = parseInt(t.get("transitionSpan") || "", 10);
|
|
1756
|
+
return isNaN(e) || e < 1 ? f.TRANSITION_SPAN_TICKS : e;
|
|
1757
|
+
}
|
|
1758
|
+
/**
|
|
1759
|
+
* OR gate output goes high when ANY input has voltage.
|
|
1760
|
+
* With negative activationLogic (NOR), output goes high when ALL inputs lack voltage.
|
|
1761
|
+
*/
|
|
1762
|
+
onPinsChange(t, e, i, n) {
|
|
1763
|
+
const s = /* @__PURE__ */ new Map();
|
|
1764
|
+
for (const l of t.pins)
|
|
1765
|
+
s.set(t.getPinLabel(l), i.get(l));
|
|
1766
|
+
const o = s.get("input1").hasVoltage || s.get("input2").hasVoltage, a = t.config.get("activationLogic") === "negative" ? !o : o;
|
|
1767
|
+
let r = !1;
|
|
1768
|
+
const d = [], g = this.getTransitionSpan(t.config);
|
|
1769
|
+
return a ? (e.state === "low" || e.state === "falling") && (r = !0, e.state = "rising", e.startTick = n, d.push({
|
|
1770
|
+
targetId: t.id,
|
|
1771
|
+
scheduledAtTick: n,
|
|
1772
|
+
readyAtTick: n + g,
|
|
1773
|
+
type: "RisingComplete",
|
|
1774
|
+
parameters: void 0
|
|
1775
|
+
})) : (e.state === "high" || e.state === "rising") && (r = !0, e.state = "falling", e.startTick = n, d.push({
|
|
1776
|
+
targetId: t.id,
|
|
1777
|
+
scheduledAtTick: n,
|
|
1778
|
+
readyAtTick: n + g,
|
|
1779
|
+
type: "FallingComplete",
|
|
1780
|
+
parameters: void 0
|
|
1781
|
+
})), {
|
|
1782
|
+
componentState: e,
|
|
1783
|
+
hasChanged: r,
|
|
1784
|
+
scheduledEvents: d
|
|
1785
|
+
};
|
|
1786
|
+
}
|
|
1787
|
+
onUserCommand(t, e, i) {
|
|
1788
|
+
return {
|
|
1789
|
+
componentState: e,
|
|
1790
|
+
hasChanged: !1,
|
|
1791
|
+
scheduledEvents: []
|
|
1792
|
+
};
|
|
1793
|
+
}
|
|
1794
|
+
onEventFiring(t, e, i) {
|
|
1795
|
+
let n = !1;
|
|
1796
|
+
return i.type === "RisingComplete" ? e.state !== "high" && (n = !0, e.startTick = i.readyAtTick, e.state = "high") : i.type === "FallingComplete" && e.state !== "low" && (n = !0, e.startTick = i.readyAtTick, e.state = "low"), {
|
|
1797
|
+
componentState: e,
|
|
1798
|
+
hasChanged: n,
|
|
1799
|
+
scheduledEvents: []
|
|
1800
|
+
};
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
class ae extends A {
|
|
1804
|
+
componentType = h.Or4Gate;
|
|
1805
|
+
createInitialState(t) {
|
|
1806
|
+
if (t.type !== h.Or4Gate)
|
|
1807
|
+
throw new Error(`Invalid component type for Or4GateBehavior: ${t.type}`);
|
|
1808
|
+
const e = t.config.get("activationLogic") === "negative" ? "high" : "low";
|
|
1809
|
+
return new Q(t.id, e);
|
|
1810
|
+
}
|
|
1811
|
+
onPinsChange(t, e, i, n) {
|
|
1812
|
+
const s = /* @__PURE__ */ new Map();
|
|
1813
|
+
for (const l of t.pins)
|
|
1814
|
+
s.set(t.getPinLabel(l), i.get(l));
|
|
1815
|
+
const o = s.get("input1").hasVoltage || s.get("input2").hasVoltage || s.get("input3").hasVoltage || s.get("input4").hasVoltage, a = t.config.get("activationLogic") === "negative" ? !o : o;
|
|
1816
|
+
let r = !1;
|
|
1817
|
+
const d = [], g = this.getTransitionSpan(t.config);
|
|
1818
|
+
return a ? (e.state === "low" || e.state === "falling") && (r = !0, e.state = "rising", e.startTick = n, d.push({
|
|
1819
|
+
targetId: t.id,
|
|
1820
|
+
scheduledAtTick: n,
|
|
1821
|
+
readyAtTick: n + g,
|
|
1822
|
+
type: "RisingComplete",
|
|
1823
|
+
parameters: void 0
|
|
1824
|
+
})) : (e.state === "high" || e.state === "rising") && (r = !0, e.state = "falling", e.startTick = n, d.push({
|
|
1825
|
+
targetId: t.id,
|
|
1826
|
+
scheduledAtTick: n,
|
|
1827
|
+
readyAtTick: n + g,
|
|
1828
|
+
type: "FallingComplete",
|
|
1829
|
+
parameters: void 0
|
|
1830
|
+
})), {
|
|
1831
|
+
componentState: e,
|
|
1832
|
+
hasChanged: r,
|
|
1833
|
+
scheduledEvents: d
|
|
1834
|
+
};
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
class de extends A {
|
|
1838
|
+
componentType = h.Or8Gate;
|
|
1839
|
+
createInitialState(t) {
|
|
1840
|
+
if (t.type !== h.Or8Gate)
|
|
1841
|
+
throw new Error(`Invalid component type for Or8GateBehavior: ${t.type}`);
|
|
1842
|
+
const e = t.config.get("activationLogic") === "negative" ? "high" : "low";
|
|
1843
|
+
return new Y(t.id, e);
|
|
1844
|
+
}
|
|
1845
|
+
onPinsChange(t, e, i, n) {
|
|
1846
|
+
const s = /* @__PURE__ */ new Map();
|
|
1847
|
+
for (const l of t.pins)
|
|
1848
|
+
s.set(t.getPinLabel(l), i.get(l));
|
|
1849
|
+
const o = s.get("input1").hasVoltage || s.get("input2").hasVoltage || s.get("input3").hasVoltage || s.get("input4").hasVoltage || s.get("input5").hasVoltage || s.get("input6").hasVoltage || s.get("input7").hasVoltage || s.get("input8").hasVoltage, a = t.config.get("activationLogic") === "negative" ? !o : o;
|
|
1850
|
+
let r = !1;
|
|
1851
|
+
const d = [], g = this.getTransitionSpan(t.config);
|
|
1852
|
+
return a ? (e.state === "low" || e.state === "falling") && (r = !0, e.state = "rising", e.startTick = n, d.push({
|
|
1853
|
+
targetId: t.id,
|
|
1854
|
+
scheduledAtTick: n,
|
|
1855
|
+
readyAtTick: n + g,
|
|
1856
|
+
type: "RisingComplete",
|
|
1857
|
+
parameters: void 0
|
|
1858
|
+
})) : (e.state === "high" || e.state === "rising") && (r = !0, e.state = "falling", e.startTick = n, d.push({
|
|
1859
|
+
targetId: t.id,
|
|
1860
|
+
scheduledAtTick: n,
|
|
1861
|
+
readyAtTick: n + g,
|
|
1862
|
+
type: "FallingComplete",
|
|
1863
|
+
parameters: void 0
|
|
1864
|
+
})), {
|
|
1865
|
+
componentState: e,
|
|
1866
|
+
hasChanged: r,
|
|
1867
|
+
scheduledEvents: d
|
|
1868
|
+
};
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
class ce {
|
|
1872
|
+
componentType = h.XorGate;
|
|
1873
|
+
createInitialState(t) {
|
|
1874
|
+
if (t.type !== h.XorGate)
|
|
1875
|
+
throw new Error(`Invalid component type for XorGateBehavior: ${t.type}`);
|
|
1876
|
+
const e = t.config.get("activationLogic") === "negative" ? "high" : "low";
|
|
1877
|
+
return new Z(t.id, e);
|
|
1878
|
+
}
|
|
1879
|
+
allowConductivity(t, e, i, n, s) {
|
|
1880
|
+
if (n === s) return !0;
|
|
1881
|
+
const o = t.getPinLabel(n), a = t.getPinLabel(s);
|
|
1882
|
+
if (!o || !a) return !1;
|
|
1883
|
+
const r = [o, a];
|
|
1884
|
+
return r.includes("vcc") && r.includes("output") ? e.state === "high" || e.state === "falling" : !1;
|
|
1885
|
+
}
|
|
1886
|
+
getTransitionSpan(t) {
|
|
1887
|
+
const e = parseInt(t.get("transitionSpan") || "", 10);
|
|
1888
|
+
return isNaN(e) || e < 1 ? f.TRANSITION_SPAN_TICKS : e;
|
|
1889
|
+
}
|
|
1890
|
+
/**
|
|
1891
|
+
* XOR gate output goes high when inputs differ (one high, one low).
|
|
1892
|
+
* With negative activationLogic (XNOR), output goes high when inputs are equal.
|
|
1893
|
+
*/
|
|
1894
|
+
onPinsChange(t, e, i, n) {
|
|
1895
|
+
const s = /* @__PURE__ */ new Map();
|
|
1896
|
+
for (const u of t.pins)
|
|
1897
|
+
s.set(t.getPinLabel(u), i.get(u));
|
|
1898
|
+
const o = s.get("input1").hasVoltage, a = s.get("input2").hasVoltage, r = o !== a, d = t.config.get("activationLogic") === "negative" ? !r : r;
|
|
1899
|
+
let g = !1;
|
|
1900
|
+
const l = [], m = this.getTransitionSpan(t.config);
|
|
1901
|
+
return d ? (e.state === "low" || e.state === "falling") && (g = !0, e.state = "rising", e.startTick = n, l.push({
|
|
1902
|
+
targetId: t.id,
|
|
1903
|
+
scheduledAtTick: n,
|
|
1904
|
+
readyAtTick: n + m,
|
|
1905
|
+
type: "RisingComplete",
|
|
1906
|
+
parameters: void 0
|
|
1907
|
+
})) : (e.state === "high" || e.state === "rising") && (g = !0, e.state = "falling", e.startTick = n, l.push({
|
|
1908
|
+
targetId: t.id,
|
|
1909
|
+
scheduledAtTick: n,
|
|
1910
|
+
readyAtTick: n + m,
|
|
1911
|
+
type: "FallingComplete",
|
|
1912
|
+
parameters: void 0
|
|
1913
|
+
})), {
|
|
1914
|
+
componentState: e,
|
|
1915
|
+
hasChanged: g,
|
|
1916
|
+
scheduledEvents: l
|
|
1917
|
+
};
|
|
1918
|
+
}
|
|
1919
|
+
onUserCommand(t, e, i) {
|
|
1920
|
+
return {
|
|
1921
|
+
componentState: e,
|
|
1922
|
+
hasChanged: !1,
|
|
1923
|
+
scheduledEvents: []
|
|
1924
|
+
};
|
|
1925
|
+
}
|
|
1926
|
+
onEventFiring(t, e, i) {
|
|
1927
|
+
let n = !1;
|
|
1928
|
+
return i.type === "RisingComplete" ? e.state !== "high" && (n = !0, e.startTick = i.readyAtTick, e.state = "high") : i.type === "FallingComplete" && e.state !== "low" && (n = !0, e.startTick = i.readyAtTick, e.state = "low"), {
|
|
1929
|
+
componentState: e,
|
|
1930
|
+
hasChanged: n,
|
|
1931
|
+
scheduledEvents: []
|
|
1932
|
+
};
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
function he(c) {
|
|
1936
|
+
return c.register(new W()).register(new M()).register(new F()).register(new U()).register(new N()).register(new ee()).register(new ne()).register(new se()), c;
|
|
1937
|
+
}
|
|
1938
|
+
function ue(c) {
|
|
1939
|
+
return c.register(new I()).register(new oe()).register(new re()).register(new A()).register(new ae()).register(new de()).register(new ce()), c;
|
|
1638
1940
|
}
|
|
1639
1941
|
export {
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1942
|
+
oe as And4GateBehavior,
|
|
1943
|
+
X as And4GateState,
|
|
1944
|
+
re as And8GateBehavior,
|
|
1945
|
+
q as And8GateState,
|
|
1946
|
+
I as AndGateBehavior,
|
|
1947
|
+
T as AndGateState,
|
|
1948
|
+
W as BatteryBehavior,
|
|
1949
|
+
x as BatteryState,
|
|
1950
|
+
ge as BehaviorRegistry,
|
|
1951
|
+
se as BufferBehavior,
|
|
1952
|
+
K as BufferState,
|
|
1953
|
+
V as COMPONENT_TYPE_METADATA,
|
|
1644
1954
|
b as CameraOptions,
|
|
1645
|
-
|
|
1955
|
+
_ as Circuit,
|
|
1646
1956
|
v as CircuitMetadata,
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1957
|
+
me as CircuitRunner,
|
|
1958
|
+
P as Component,
|
|
1959
|
+
p as ComponentState,
|
|
1960
|
+
h as ComponentType,
|
|
1961
|
+
we as DirtyTracker,
|
|
1962
|
+
S as ENode,
|
|
1963
|
+
ye as ENodeSourceType,
|
|
1964
|
+
y as ENodeType,
|
|
1965
|
+
ve as EventQueue,
|
|
1966
|
+
M as LightbulbBehavior,
|
|
1967
|
+
$ as LightbulbState,
|
|
1968
|
+
ae as Or4GateBehavior,
|
|
1969
|
+
Q as Or4GateState,
|
|
1970
|
+
de as Or8GateBehavior,
|
|
1971
|
+
Y as Or8GateState,
|
|
1972
|
+
A as OrGateBehavior,
|
|
1973
|
+
E as OrGateState,
|
|
1974
|
+
k as Position,
|
|
1975
|
+
Se as Position3D,
|
|
1976
|
+
F as RectangleLEDBehavior,
|
|
1977
|
+
R as RectangleLEDState,
|
|
1978
|
+
U as RelayBehavior,
|
|
1979
|
+
D as RelayState,
|
|
1980
|
+
Ce as Rotation,
|
|
1981
|
+
Te as SIMULATION_SPEED,
|
|
1982
|
+
Ee as SimulationState,
|
|
1983
|
+
N as SmallLEDBehavior,
|
|
1984
|
+
L as SmallLEDState,
|
|
1985
|
+
Ie as StateManager,
|
|
1986
|
+
ee as SwitchBehavior,
|
|
1987
|
+
H as SwitchState,
|
|
1988
|
+
f as TRANSITION_DEFAULTS,
|
|
1989
|
+
ne as TransistorBehavior,
|
|
1990
|
+
z as TransistorState,
|
|
1991
|
+
w as Wire,
|
|
1992
|
+
ce as XorGateBehavior,
|
|
1993
|
+
Z as XorGateState,
|
|
1994
|
+
G as findPositionBestIndex,
|
|
1995
|
+
O as generateUUID,
|
|
1996
|
+
Ae as getAllComponentTypes,
|
|
1997
|
+
B as getComponentTypeMetadata,
|
|
1998
|
+
he as registerBasicComponentsBehaviors,
|
|
1999
|
+
ue as registerGatesComponentsBehaviors,
|
|
2000
|
+
C as simplifyPositions
|
|
1682
2001
|
};
|
|
1683
2002
|
//# sourceMappingURL=index.js.map
|