@solidjs/signals 2.0.0-beta.19 → 2.0.0-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/dev.js +670 -371
  2. package/dist/node.cjs +1878 -1606
  3. package/dist/prod/affects.js +17 -21
  4. package/dist/prod/core/action.js +19 -6
  5. package/dist/prod/core/async.js +57 -71
  6. package/dist/prod/core/constants.js +15 -1
  7. package/dist/prod/core/core.js +39 -39
  8. package/dist/prod/core/effect.js +14 -14
  9. package/dist/prod/core/graph.js +1 -1
  10. package/dist/prod/core/heap.js +2 -2
  11. package/dist/prod/core/lanes.js +23 -13
  12. package/dist/prod/core/optimistic.js +107 -99
  13. package/dist/prod/core/owner.js +23 -23
  14. package/dist/prod/core/scheduler.js +180 -180
  15. package/dist/prod/core/verdict.js +12 -13
  16. package/dist/prod/map.js +196 -167
  17. package/dist/prod/signals.js +1 -1
  18. package/dist/prod/store/optimistic.js +103 -68
  19. package/dist/prod/store/reconcile.js +80 -46
  20. package/dist/prod/store/store.js +204 -73
  21. package/dist/prod/store/utils.js +61 -42
  22. package/dist/types/core/action.d.ts +19 -6
  23. package/dist/types/core/constants.d.ts +12 -0
  24. package/dist/types/core/dev.d.ts +7 -0
  25. package/dist/types/core/lanes.d.ts +2 -0
  26. package/dist/types/core/scheduler.d.ts +2 -6
  27. package/dist/types/core/types.d.ts +9 -1
  28. package/dist/types/store/store.d.ts +8 -2
  29. package/dist/types-cjs/core/action.d.cts +19 -6
  30. package/dist/types-cjs/core/constants.d.cts +12 -0
  31. package/dist/types-cjs/core/dev.d.cts +7 -0
  32. package/dist/types-cjs/core/lanes.d.cts +2 -0
  33. package/dist/types-cjs/core/scheduler.d.cts +2 -6
  34. package/dist/types-cjs/core/types.d.cts +9 -1
  35. package/dist/types-cjs/store/store.d.cts +8 -2
  36. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
- import { NOT_PENDING, STATUS_UNINITIALIZED, STATUS_PENDING, CONFIG_OWNED_WRITE, REACTIVE_MANUAL_WRITE, REACTIVE_OPTIMISTIC_DIRTY, EFFECT_RENDER, EFFECT_USER } from "./constants.js";
1
+ import { NOT_PENDING, unwrapOverride, STATUS_UNINITIALIZED, OVERRIDE_UNDEFINED, STATUS_PENDING, CONFIG_OWNED_WRITE, REACTIVE_MANUAL_WRITE, REACTIVE_OPTIMISTIC_DIRTY, EFFECT_RENDER, EFFECT_USER } from "./constants.js";
2
2
 
3
- import { latestReadActive, stale, currentOptimisticLane } from "./core.js";
3
+ import { latestReadActive, currentOptimisticLane, stale } from "./core.js";
4
4
 
5
5
  import { NotReadyError } from "./error.js";
6
6
 
@@ -29,33 +29,40 @@ import { GlobalQueue, activeTransition, globalQueue, clock, insertSubs, schedule
29
29
  // committed-view rerun. Keep that override local to the stash flush.
30
30
  let stashedOptimisticReads = null;
31
31
 
32
- /** The optimistic half of setSignal, fired when `_overrideValue !== undefined`. */ function optimisticWrite(e, t) {
33
- const n = e.be !== NOT_PENDING;
34
- const i = n ? e.be : e.Ue;
35
- if (typeof t === "function") t = t(i);
36
- const u = !!(e.i & STATUS_UNINITIALIZED) || !e.Ge || !e.Ge(i, t);
32
+ /** The optimistic half of setSignal, fired when `_overrideValue !== undefined`. */ function optimisticWrite(e, n) {
33
+ const t = e.be !== NOT_PENDING;
34
+ const i = t ? unwrapOverride(e.be) : e.Ue;
35
+ if (typeof n === "function") n = n(i);
36
+ const u = !!(e.i & STATUS_UNINITIALIZED) || !e.Ge || !e.Ge(i, n);
37
37
  if (!u) {
38
38
  // Same-value write with an active override still entangles the current
39
39
  // action's transition — the hold must outlast all overlapping actions.
40
- if (n) {
41
- const t = resolveTransition(e);
42
- if (t && activeTransition !== t) globalQueue.initTransition(t);
40
+ if (t) {
41
+ const n = resolveTransition(e);
42
+ if (n && activeTransition !== n) globalQueue.initTransition(n);
43
43
  }
44
- return t;
44
+ return n;
45
45
  }
46
- if (n) globalQueue.initTransition(resolveTransition(e));
46
+ if (t) globalQueue.initTransition(resolveTransition(e));
47
47
  // No revert target is stashed: while the override is active every reader
48
48
  // sees it (A17), so authoritative arrivals commit silently into _value and
49
49
  // reverting is just dropping the override — _value is already correct.
50
- else globalQueue.Be.push(e);
50
+ else globalQueue.N.Be.push(e);
51
+ // Stamp ownership on the node (post-merge, so entangled writers share the
52
+ // joint root). resolveTransition prefers this over the lane's _transition,
53
+ // which a shared subscriber can merge across transactions (#2912).
54
+ e.fn = activeTransition;
51
55
  const s = getOrCreateLane(e);
52
56
  e.Je = s;
53
- e.be = t;
54
- GlobalQueue._e !== null && GlobalQueue._e(e, t);
57
+ // Literal undefined must not land raw: the slot doubles as the optimistic
58
+ // brand, and erasing it makes the write invisible and routes follow-up
59
+ // writes off the optimistic path into permanent commits (#2898).
60
+ e.be = n === undefined ? OVERRIDE_UNDEFINED : n;
61
+ GlobalQueue._e !== null && GlobalQueue._e(e, n);
55
62
  e.Ie = clock;
56
63
  insertSubs(e, true);
57
64
  schedule();
58
- return t;
65
+ return n;
59
66
  }
60
67
 
61
68
  function readStashed(e) {
@@ -63,8 +70,8 @@ function readStashed(e) {
63
70
  }
64
71
 
65
72
  function queueStashedOptimisticEffects(e) {
66
- for (let t = e.p; t !== null; t = t.de) {
67
- const e = t.Ee;
73
+ for (let n = e.p; n !== null; n = n.de) {
74
+ const e = n.Ee;
68
75
  if (!e.De) continue;
69
76
  enqueueSub(e);
70
77
  }
@@ -75,11 +82,11 @@ function queueStashedOptimisticEffects(e) {
75
82
  * optimistic nodes: give plain optimistic signals one committed-view rerun.
76
83
  */ function stashOptimistic(e) {
77
84
  stashedOptimisticReads = new Set;
78
- for (let t = 0; t < e.Be.length; t++) {
79
- const n = e.Be[t];
80
- if (n.xe || n.U & CONFIG_OWNED_WRITE) continue;
81
- stashedOptimisticReads.add(n);
82
- queueStashedOptimisticEffects(n);
85
+ for (let n = 0; n < e.Be.length; n++) {
86
+ const t = e.Be[n];
87
+ if (t.xe || t.U & CONFIG_OWNED_WRITE) continue;
88
+ stashedOptimisticReads.add(t);
89
+ queueStashedOptimisticEffects(t);
83
90
  }
84
91
  try {
85
92
  finalizePureQueue(null, true);
@@ -93,13 +100,13 @@ function queueStashedOptimisticEffects(e) {
93
100
  * while one of its optimistic nodes holds an active override that is still
94
101
  * pending on real (non-affects-sentinel) async.
95
102
  */ function transitionBlocked(e) {
96
- for (let t = 0; t < e.Be.length; t++) {
97
- const n = e.Be[t];
98
- if (hasActiveOverride(n) && "i" in n && n.i & STATUS_PENDING && n.k instanceof NotReadyError &&
103
+ for (let n = 0; n < e.Be.length; n++) {
104
+ const t = e.Be[n];
105
+ if (hasActiveOverride(t) && "i" in t && t.i & STATUS_PENDING && t.k instanceof NotReadyError &&
99
106
  // Mark-sourced pending never blocks settlement: affects() releases AT
100
107
  // settle, so counting its sentinel here would deadlock the window it
101
108
  // is scoped to.
102
- !n.k.source?.l) {
109
+ !t.k.source?.l) {
103
110
  return true;
104
111
  }
105
112
  }
@@ -110,62 +117,63 @@ function resolveOptimisticNodes(e) {
110
117
  // Settlement writes below (snapCompanionsToState → updatePendingSignal-style
111
118
  // notifications) may push fresh optimistic nodes; only this batch settles
112
119
  // now, so iterate a fixed window and splice it out at the end.
113
- const t = e.length;
114
- for (let n = 0; n < t; n++) {
115
- const t = e[n];
116
- t.Je = undefined;
120
+ const n = e.length;
121
+ for (let t = 0; t < n; t++) {
122
+ const n = e[t];
123
+ n.Je = undefined;
117
124
  // Revert is a pure drop: there is no revert target to commit —
118
125
  // override-covered authoritative values hold in _pendingValue and
119
126
  // elevate on their OWN transition's schedule (A18 as re-ruled 2026-07-07).
120
- if (!(t.i & STATUS_PENDING)) t.i &= ~STATUS_UNINITIALIZED;
121
- const i = t.be;
122
- t.be = NOT_PENDING;
123
- if (i !== NOT_PENDING && t.Ue !== i) insertSubs(t, true);
124
- t.ve = null;
127
+ if (!(n.i & STATUS_PENDING)) n.i &= ~STATUS_UNINITIALIZED;
128
+ const i = n.be;
129
+ n.be = NOT_PENDING;
130
+ if (i !== NOT_PENDING && n.Ue !== unwrapOverride(i)) insertSubs(n, true);
131
+ n.ve = null;
132
+ n.fn = null;
125
133
  }
126
134
  // Settlement checkpoint (#2838): companions caught in this batch (or owned
127
135
  // by a node in it) re-derive from committed state, so verdicts survive the
128
136
  // transition that produced them (A19 — pending is a property of the data).
129
- for (let n = 0; n < t; n++) {
130
- const t = e[n];
131
- if (t.ye || t.pe) GlobalQueue.R(t);
132
- const i = t.en;
133
- if (i && (i.ye === t || i.pe === t)) GlobalQueue.R(i);
137
+ for (let t = 0; t < n; t++) {
138
+ const n = e[t];
139
+ if (n.ye || n.pe) GlobalQueue.R(n);
140
+ const i = n.en;
141
+ if (i && (i.ye === n || i.pe === n)) GlobalQueue.R(i);
134
142
  }
135
- e.splice(0, t);
143
+ e.splice(0, n);
136
144
  }
137
145
 
138
- function runQueue(e, t) {
139
- for (let n = 0; n < e.length; n++) e[n](t);
146
+ function runQueue(e, n) {
147
+ for (let t = 0; t < e.length; t++) e[t](n);
140
148
  }
141
149
 
142
150
  /**
143
151
  * Run effects from all lanes that are ready (no pending async).
144
152
  */ function runLaneEffects(e) {
145
- for (const t of activeLanes) {
146
- if (t.rn || t.Pe.size > 0) continue;
147
- const n = t.tn[e - 1];
148
- if (n.length) {
149
- t.tn[e - 1] = [];
150
- runQueue(n, e);
153
+ for (const n of activeLanes) {
154
+ if (n.an || n.Pe.size > 0) continue;
155
+ const t = n.tn[e - 1];
156
+ if (t.length) {
157
+ n.tn[e - 1] = [];
158
+ runQueue(t, e);
151
159
  }
152
160
  }
153
161
  }
154
162
 
155
163
  function cleanupCompletedLanes(e) {
156
- for (const t of activeLanes) {
157
- const n = e ? t.ve === e : !t.ve;
158
- if (!n) continue;
159
- if (!t.rn) {
160
- if (t.tn[0].length) runQueue(t.tn[0], EFFECT_RENDER);
161
- if (t.tn[1].length) runQueue(t.tn[1], EFFECT_USER);
164
+ for (const n of activeLanes) {
165
+ const t = e ? n.ve === e : !n.ve;
166
+ if (!t) continue;
167
+ if (!n.an) {
168
+ if (n.tn[0].length) runQueue(n.tn[0], EFFECT_RENDER);
169
+ if (n.tn[1].length) runQueue(n.tn[1], EFFECT_USER);
162
170
  }
163
- if (t.an.Je === t) t.an.Je = undefined;
164
- t.Pe.clear();
165
- t.tn[0].length = 0;
166
- t.tn[1].length = 0;
167
- activeLanes.delete(t);
168
- signalLanes.delete(t.an);
171
+ if (n.rn.Je === n) n.rn.Je = undefined;
172
+ n.Pe.clear();
173
+ n.tn[0].length = 0;
174
+ n.tn[1].length = 0;
175
+ activeLanes.delete(n);
176
+ signalLanes.delete(n.rn);
169
177
  }
170
178
  }
171
179
 
@@ -173,44 +181,44 @@ function cleanupCompletedLanes(e) {
173
181
  // Per-lane suspension: only throw if in same lane as pending async
174
182
  // AND the node doesn't have an active override (overrides are the visible value,
175
183
  // downstream in the lane should read the override, not throw)
176
- const t = e.Je;
177
- if (!t) return false;
178
- return findLane(t) === findLane(currentOptimisticLane) && !hasActiveOverride(e);
184
+ const n = e.Je;
185
+ if (!n) return false;
186
+ return findLane(n) === findLane(currentOptimisticLane) && !hasActiveOverride(e);
179
187
  }
180
188
 
181
189
  /**
182
190
  * read()'s entanglement gate: a reader recomputing under an optimistic lane
183
191
  * that reads a pending mid-transition write sees the committed value; the sub
184
192
  * is recorded for replay at commit.
185
- */ function gatedRead(e, t, n) {
186
- if (latestReadActive || e.ge === NOT_PENDING || e.xe || t !== e && !(t.u & REACTIVE_MANUAL_WRITE)) {
193
+ */ function gatedRead(e, n, t) {
194
+ if (latestReadActive || e.ge === NOT_PENDING || e.xe || n !== e && !(n.u & REACTIVE_MANUAL_WRITE)) {
187
195
  return false;
188
196
  }
189
- activeTransition.Qt.add(n);
197
+ activeTransition.un.add(t);
190
198
  return true;
191
199
  }
192
200
 
193
201
  /**
194
202
  * read()'s value selection under a lane: return the committed `_value` for
195
203
  * optimistic/lane-assigned signals, stale-mode reads, and pending owners.
196
- */ function laneReadsCommitted(e, t, n) {
197
- return e.be !== undefined || !!e.Je || t === e && stale && n.en !== e || !!(t.i & STATUS_PENDING);
204
+ */ function laneReadsCommitted(e, n, t) {
205
+ return e.be !== undefined || !!e.Je || n === e && stale && t.en !== e || !!(n.i & STATUS_PENDING);
198
206
  }
199
207
 
200
208
  /**
201
209
  * recompute()'s lane posture: resolve the node's own lane (own=true), or adopt
202
210
  * a dependency's optimistic lane (own=false — parent-deeper-than-owned-child
203
211
  * can run before its OPT-dirty child propagates).
204
- */ function recomputeLane(e, t) {
205
- if (t) return resolveLane(e) ?? null;
206
- for (let t = e.S; t; t = t.st) {
207
- const n = t.ot;
208
- if (n.u & REACTIVE_OPTIMISTIC_DIRTY) {
209
- const t = resolveLane(n);
210
- if (t) {
212
+ */ function recomputeLane(e, n) {
213
+ if (n) return resolveLane(e) ?? null;
214
+ for (let n = e.S; n; n = n.st) {
215
+ const t = n.ot;
216
+ if (t.u & REACTIVE_OPTIMISTIC_DIRTY) {
217
+ const n = resolveLane(t);
218
+ if (n) {
211
219
  e.u |= REACTIVE_OPTIMISTIC_DIRTY;
212
- assignOrMergeLane(e, t);
213
- return t;
220
+ assignOrMergeLane(e, n);
221
+ return n;
214
222
  }
215
223
  }
216
224
  }
@@ -218,25 +226,25 @@ function cleanupCompletedLanes(e) {
218
226
  }
219
227
 
220
228
  /** recompute()'s catch path: track pending async in the current lane. */ function laneAsyncPending(e) {
221
- const t = findLane(currentOptimisticLane);
222
- if (t.an !== e) {
223
- t.Pe.add(e);
224
- e.Je = t;
225
- GlobalQueue._ !== null && GlobalQueue._(t.an);
229
+ const n = findLane(currentOptimisticLane);
230
+ if (n.rn !== e) {
231
+ n.Pe.add(e);
232
+ e.Je = n;
233
+ GlobalQueue.P !== null && GlobalQueue.P(n.rn);
226
234
  }
227
235
  }
228
236
 
229
237
  /** recompute()'s success path: the node's async settled, clear it from its lane. */ function laneAsyncSettled(e) {
230
- const t = resolveLane(e);
231
- if (t) {
232
- t.Pe.delete(e);
233
- GlobalQueue._ !== null && GlobalQueue._(t.an);
238
+ const n = resolveLane(e);
239
+ if (n) {
240
+ n.Pe.delete(e);
241
+ GlobalQueue.P !== null && GlobalQueue.P(n.rn);
234
242
  }
235
243
  }
236
244
 
237
245
  function trackOptimisticStore(e) {
238
- // After initTransition, globalQueue._optimisticStores IS activeTransition._optimisticStores (same reference)
239
- globalQueue.Lt.add(e);
246
+ // After initTransition, globalQueue._batch IS activeTransition (same reference)
247
+ globalQueue.N.dn.add(e);
240
248
  schedule();
241
249
  }
242
250
 
@@ -247,19 +255,19 @@ function trackOptimisticStore(e) {
247
255
  */ function installOptimisticEngine() {
248
256
  if (GlobalQueue.bt !== null) return;
249
257
  GlobalQueue.bt = optimisticWrite;
250
- GlobalQueue.Ut = resolveOptimisticNodes;
251
- GlobalQueue.yt = stashOptimistic;
252
- GlobalQueue.Wt = transitionBlocked;
253
- GlobalQueue.jt = cleanupCompletedLanes;
254
- GlobalQueue.Mt = runLaneEffects;
255
- GlobalQueue.gt = readStashed;
256
- GlobalQueue.Dt = gatedRead;
258
+ GlobalQueue.En = resolveOptimisticNodes;
259
+ GlobalQueue.Tn = stashOptimistic;
260
+ GlobalQueue.In = transitionBlocked;
261
+ GlobalQueue.Nn = cleanupCompletedLanes;
262
+ GlobalQueue.On = runLaneEffects;
263
+ GlobalQueue.Dt = readStashed;
264
+ GlobalQueue.gt = gatedRead;
257
265
  GlobalQueue.ht = laneSuspends;
258
- GlobalQueue.kt = laneReadsCommitted;
266
+ GlobalQueue.vt = laneReadsCommitted;
259
267
  GlobalQueue.$e = recomputeLane;
260
268
  GlobalQueue.et = laneAsyncPending;
261
269
  GlobalQueue.Xe = laneAsyncSettled;
262
- GlobalQueue.Vt = trackOptimisticStore;
270
+ GlobalQueue.mn = trackOptimisticStore;
263
271
  }
264
272
 
265
273
  export { installOptimisticEngine };
@@ -1,4 +1,4 @@
1
- import { defaultContext, CONFIG_TRANSPARENT, REACTIVE_DISPOSED, REACTIVE_ZOMBIE, REACTIVE_IN_HEAP, REACTIVE_IN_HEAP_HEIGHT } from "./constants.js";
1
+ import { REACTIVE_DISPOSED, REACTIVE_ZOMBIE, REACTIVE_IN_HEAP, REACTIVE_IN_HEAP_HEIGHT, CONFIG_TRANSPARENT, defaultContext } from "./constants.js";
2
2
 
3
3
  import { context, runWithOwner, pendingCheckActive, latestReadActive, tracking } from "./core.js";
4
4
 
@@ -6,13 +6,13 @@ import { unlinkSubs } from "./graph.js";
6
6
 
7
7
  import { deleteFromHeap, queueFor, insertIntoHeap, insertIntoHeapHeight } from "./heap.js";
8
8
 
9
- import { globalQueue, GlobalQueue, zombieQueue, dirtyQueue } from "./scheduler.js";
9
+ import { GlobalQueue, zombieQueue, dirtyQueue, globalQueue } from "./scheduler.js";
10
10
 
11
11
  const PENDING_OWNER = {};
12
12
 
13
13
  // Dummy owner to trigger store's read() path
14
14
  function markDisposal(e) {
15
- let n = e.Fe;
15
+ let n = e.He;
16
16
  while (n) {
17
17
  const e = n.u;
18
18
  n.u = e | REACTIVE_ZOMBIE;
@@ -54,7 +54,7 @@ function disposeChildren(e, n = false, t) {
54
54
  if (n.ye || n.pe) GlobalQueue.R(n);
55
55
  }
56
56
  if (n && e.xe) e.Ae = null;
57
- let l = t ? e.Ze : e.Fe;
57
+ let l = t ? e.Ze : e.He;
58
58
  while (l) {
59
59
  const e = l.Ve;
60
60
  if (l.S) {
@@ -73,26 +73,26 @@ function disposeChildren(e, n = false, t) {
73
73
  if (t) {
74
74
  e.Ze = null;
75
75
  } else {
76
- e.Fe = null;
76
+ e.He = null;
77
77
  e.je = 0;
78
78
  }
79
79
  // O(1) splice out of parent's chain on individual dispose. Skipped during
80
80
  // batch dispose (parent already disposed) and zombie disposal (node sits on
81
81
  // parent's _pendingFirstChild). We leave node._nextSibling intact so outer
82
82
  // walks that already advanced past us still reach later siblings.
83
- if (n && !t && !(i & REACTIVE_ZOMBIE) && e.He !== null && !(e.He.u & REACTIVE_DISPOSED)) {
84
- const n = e.Tt;
83
+ if (n && !t && !(i & REACTIVE_ZOMBIE) && e.Fe !== null && !(e.Fe.u & REACTIVE_DISPOSED)) {
84
+ const n = e.Nt;
85
85
  const t = e.Ve;
86
- if (n !== null) n.Ve = t; else e.He.Fe = t;
87
- if (t !== null) t.Tt = n;
88
- e.Tt = null;
86
+ if (n !== null) n.Ve = t; else e.Fe.He = t;
87
+ if (t !== null) t.Nt = n;
88
+ e.Nt = null;
89
89
  }
90
90
  runDisposal(e, t);
91
91
  // Final effect-returned cleanup fires at true disposal, after `_disposal`
92
92
  // to mirror rerun ordering (compute-phase teardown first, cleanup last).
93
- if (n && e.At) {
94
- const n = e.At;
95
- e.At = undefined;
93
+ if (n && e.dt) {
94
+ const n = e.dt;
95
+ e.dt = undefined;
96
96
  n();
97
97
  }
98
98
  }
@@ -113,7 +113,7 @@ function runDisposal(e, n) {
113
113
 
114
114
  function childId(e, n) {
115
115
  let t = e;
116
- while (t.U & CONFIG_TRANSPARENT && t.He) t = t.He;
116
+ while (t.U & CONFIG_TRANSPARENT && t.Fe) t = t.Fe;
117
117
  if (t.id != null) return formatId(t.id, n ? t.je++ : t.je);
118
118
  throw new Error("");
119
119
  }
@@ -235,28 +235,28 @@ function disposeRootSelf(e = true) {
235
235
  const i = {
236
236
  id: inheritId(e, t, n),
237
237
  U: t ? CONFIG_TRANSPARENT : 0,
238
- dt: true,
239
- Ct: n?.dt ? n.Ct : n,
240
- Fe: null,
238
+ At: true,
239
+ Ct: n?.At ? n.Ct : n,
240
+ He: null,
241
241
  Ve: null,
242
- Tt: null,
242
+ Nt: null,
243
243
  Me: null,
244
244
  v: n?.v ?? globalQueue,
245
245
  we: n?.we || defaultContext,
246
246
  je: 0,
247
247
  We: null,
248
248
  Ze: null,
249
- He: n,
249
+ Fe: n,
250
250
  dispose: disposeRootSelf
251
251
  };
252
252
  if (n) {
253
- const e = n.Fe;
253
+ const e = n.He;
254
254
  if (e === null) {
255
- n.Fe = i;
255
+ n.He = i;
256
256
  } else {
257
257
  i.Ve = e;
258
- e.Tt = i;
259
- n.Fe = i;
258
+ e.Nt = i;
259
+ n.He = i;
260
260
  }
261
261
  }
262
262
  return i;