UNPKG

645 kBJavaScriptView Raw
1/**
2 * @license React
3 * react-test-renderer.development.js
4 *
5 * Copyright (c) Facebook, Inc. and its affiliates.
6 *
7 * This source code is licensed under the MIT license found in the
8 * LICENSE file in the root directory of this source tree.
9 */
10(function (global, factory) {
11 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('scheduler/unstable_mock'), require('scheduler')) :
12 typeof define === 'function' && define.amd ? define(['exports', 'react', 'scheduler/unstable_mock', 'scheduler'], factory) :
13 (global = global || self, factory(global.ReactTestRenderer = {}, global.React, global.SchedulerMock, global.Scheduler));
14}(this, (function (exports, React, Scheduler, Scheduler$1) { 'use strict';
15
16 var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
17
18 // by calls to these methods by a Babel plugin.
19 //
20 // In PROD (or in packages without access to React internals),
21 // they are left as they are instead.
22
23 function warn(format) {
24 {
25 {
26 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
27 args[_key - 1] = arguments[_key];
28 }
29
30 printWarning('warn', format, args);
31 }
32 }
33 }
34 function error(format) {
35 {
36 {
37 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
38 args[_key2 - 1] = arguments[_key2];
39 }
40
41 printWarning('error', format, args);
42 }
43 }
44 }
45
46 function printWarning(level, format, args) {
47 // When changing this logic, you might want to also
48 // update consoleWithStackDev.www.js as well.
49 {
50 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
51 var stack = ReactDebugCurrentFrame.getStackAddendum();
52
53 if (stack !== '') {
54 format += '%s';
55 args = args.concat([stack]);
56 } // eslint-disable-next-line react-internal/safe-string-coercion
57
58
59 var argsWithFormat = args.map(function (item) {
60 return String(item);
61 }); // Careful: RN currently depends on this prefix
62
63 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
64 // breaks IE9: https://github.com/facebook/react/issues/13610
65 // eslint-disable-next-line react-internal/no-production-logging
66
67 Function.prototype.apply.call(console[level], console, argsWithFormat);
68 }
69 }
70
71 function _defineProperties(target, props) {
72 for (var i = 0; i < props.length; i++) {
73 var descriptor = props[i];
74 descriptor.enumerable = descriptor.enumerable || false;
75 descriptor.configurable = true;
76 if ("value" in descriptor) descriptor.writable = true;
77 Object.defineProperty(target, descriptor.key, descriptor);
78 }
79 }
80
81 function _createClass(Constructor, protoProps, staticProps) {
82 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
83 if (staticProps) _defineProperties(Constructor, staticProps);
84 return Constructor;
85 }
86
87 function _objectWithoutPropertiesLoose(source, excluded) {
88 if (source == null) return {};
89 var target = {};
90 var sourceKeys = Object.keys(source);
91 var key, i;
92
93 for (i = 0; i < sourceKeys.length; i++) {
94 key = sourceKeys[i];
95 if (excluded.indexOf(key) >= 0) continue;
96 target[key] = source[key];
97 }
98
99 return target;
100 }
101
102 var assign = Object.assign;
103
104 /**
105 * `ReactInstanceMap` maintains a mapping from a public facing stateful
106 * instance (key) and the internal representation (value). This allows public
107 * methods to accept the user facing instance as an argument and map them back
108 * to internal methods.
109 *
110 * Note that this module is currently shared and assumed to be stateless.
111 * If this becomes an actual Map, that will break.
112 */
113 function get(key) {
114 return key._reactInternals;
115 }
116 function set(key, value) {
117 key._reactInternals = value;
118 }
119
120 var enableSchedulingProfiler = false;
121 var enableProfilerTimer = true;
122 var enableProfilerCommitHooks = true;
123 var enableLazyElements = false;
124 var warnAboutStringRefs = false;
125 var enableSuspenseAvoidThisFallback = false;
126 var enableNewReconciler = false;
127 var enableLazyContextPropagation = false;
128 var enableLegacyHidden = false;
129
130 var FunctionComponent = 0;
131 var ClassComponent = 1;
132 var IndeterminateComponent = 2; // Before we know whether it is function or class
133
134 var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
135
136 var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
137
138 var HostComponent = 5;
139 var HostText = 6;
140 var Fragment = 7;
141 var Mode = 8;
142 var ContextConsumer = 9;
143 var ContextProvider = 10;
144 var ForwardRef = 11;
145 var Profiler = 12;
146 var SuspenseComponent = 13;
147 var MemoComponent = 14;
148 var SimpleMemoComponent = 15;
149 var LazyComponent = 16;
150 var IncompleteClassComponent = 17;
151 var DehydratedFragment = 18;
152 var SuspenseListComponent = 19;
153 var ScopeComponent = 21;
154 var OffscreenComponent = 22;
155 var LegacyHiddenComponent = 23;
156 var CacheComponent = 24;
157 var TracingMarkerComponent = 25;
158
159 // ATTENTION
160 // When adding new symbols to this file,
161 // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
162 // The Symbol used to tag the ReactElement-like types.
163 var REACT_ELEMENT_TYPE = Symbol.for('react.element');
164 var REACT_PORTAL_TYPE = Symbol.for('react.portal');
165 var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
166 var REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode');
167 var REACT_PROFILER_TYPE = Symbol.for('react.profiler');
168 var REACT_PROVIDER_TYPE = Symbol.for('react.provider');
169 var REACT_CONTEXT_TYPE = Symbol.for('react.context');
170 var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
171 var REACT_SUSPENSE_TYPE = Symbol.for('react.suspense');
172 var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list');
173 var REACT_MEMO_TYPE = Symbol.for('react.memo');
174 var REACT_LAZY_TYPE = Symbol.for('react.lazy');
175 var REACT_SCOPE_TYPE = Symbol.for('react.scope');
176 var REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for('react.debug_trace_mode');
177 var REACT_OFFSCREEN_TYPE = Symbol.for('react.offscreen');
178 var REACT_LEGACY_HIDDEN_TYPE = Symbol.for('react.legacy_hidden');
179 var REACT_CACHE_TYPE = Symbol.for('react.cache');
180 var REACT_TRACING_MARKER_TYPE = Symbol.for('react.tracing_marker');
181 var MAYBE_ITERATOR_SYMBOL = Symbol.iterator;
182 var FAUX_ITERATOR_SYMBOL = '@@iterator';
183 function getIteratorFn(maybeIterable) {
184 if (maybeIterable === null || typeof maybeIterable !== 'object') {
185 return null;
186 }
187
188 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
189
190 if (typeof maybeIterator === 'function') {
191 return maybeIterator;
192 }
193
194 return null;
195 }
196
197 function getWrappedName(outerType, innerType, wrapperName) {
198 var displayName = outerType.displayName;
199
200 if (displayName) {
201 return displayName;
202 }
203
204 var functionName = innerType.displayName || innerType.name || '';
205 return functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName;
206 } // Keep in sync with react-reconciler/getComponentNameFromFiber
207
208
209 function getContextName(type) {
210 return type.displayName || 'Context';
211 } // Note that the reconciler package should generally prefer to use getComponentNameFromFiber() instead.
212
213
214 function getComponentNameFromType(type) {
215 if (type == null) {
216 // Host root, text node or just invalid type.
217 return null;
218 }
219
220 {
221 if (typeof type.tag === 'number') {
222 error('Received an unexpected object in getComponentNameFromType(). ' + 'This is likely a bug in React. Please file an issue.');
223 }
224 }
225
226 if (typeof type === 'function') {
227 return type.displayName || type.name || null;
228 }
229
230 if (typeof type === 'string') {
231 return type;
232 }
233
234 switch (type) {
235 case REACT_FRAGMENT_TYPE:
236 return 'Fragment';
237
238 case REACT_PORTAL_TYPE:
239 return 'Portal';
240
241 case REACT_PROFILER_TYPE:
242 return 'Profiler';
243
244 case REACT_STRICT_MODE_TYPE:
245 return 'StrictMode';
246
247 case REACT_SUSPENSE_TYPE:
248 return 'Suspense';
249
250 case REACT_SUSPENSE_LIST_TYPE:
251 return 'SuspenseList';
252
253 }
254
255 if (typeof type === 'object') {
256 switch (type.$$typeof) {
257 case REACT_CONTEXT_TYPE:
258 var context = type;
259 return getContextName(context) + '.Consumer';
260
261 case REACT_PROVIDER_TYPE:
262 var provider = type;
263 return getContextName(provider._context) + '.Provider';
264
265 case REACT_FORWARD_REF_TYPE:
266 return getWrappedName(type, type.render, 'ForwardRef');
267
268 case REACT_MEMO_TYPE:
269 var outerName = type.displayName || null;
270
271 if (outerName !== null) {
272 return outerName;
273 }
274
275 return getComponentNameFromType(type.type) || 'Memo';
276
277 case REACT_LAZY_TYPE:
278 {
279 var lazyComponent = type;
280 var payload = lazyComponent._payload;
281 var init = lazyComponent._init;
282
283 try {
284 return getComponentNameFromType(init(payload));
285 } catch (x) {
286 return null;
287 }
288 }
289
290 // eslint-disable-next-line no-fallthrough
291 }
292 }
293
294 return null;
295 }
296
297 function getWrappedName$1(outerType, innerType, wrapperName) {
298 var functionName = innerType.displayName || innerType.name || '';
299 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
300 } // Keep in sync with shared/getComponentNameFromType
301
302
303 function getContextName$1(type) {
304 return type.displayName || 'Context';
305 }
306
307 function getComponentNameFromFiber(fiber) {
308 var tag = fiber.tag,
309 type = fiber.type;
310
311 switch (tag) {
312 case CacheComponent:
313 return 'Cache';
314
315 case ContextConsumer:
316 var context = type;
317 return getContextName$1(context) + '.Consumer';
318
319 case ContextProvider:
320 var provider = type;
321 return getContextName$1(provider._context) + '.Provider';
322
323 case DehydratedFragment:
324 return 'DehydratedFragment';
325
326 case ForwardRef:
327 return getWrappedName$1(type, type.render, 'ForwardRef');
328
329 case Fragment:
330 return 'Fragment';
331
332 case HostComponent:
333 // Host component type is the display name (e.g. "div", "View")
334 return type;
335
336 case HostPortal:
337 return 'Portal';
338
339 case HostRoot:
340 return 'Root';
341
342 case HostText:
343 return 'Text';
344
345 case LazyComponent:
346 // Name comes from the type in this case; we don't have a tag.
347 return getComponentNameFromType(type);
348
349 case Mode:
350 if (type === REACT_STRICT_MODE_TYPE) {
351 // Don't be less specific than shared/getComponentNameFromType
352 return 'StrictMode';
353 }
354
355 return 'Mode';
356
357 case OffscreenComponent:
358 return 'Offscreen';
359
360 case Profiler:
361 return 'Profiler';
362
363 case ScopeComponent:
364 return 'Scope';
365
366 case SuspenseComponent:
367 return 'Suspense';
368
369 case SuspenseListComponent:
370 return 'SuspenseList';
371
372 case TracingMarkerComponent:
373 return 'TracingMarker';
374 // The display name for this tags come from the user-provided type:
375
376 case ClassComponent:
377 case FunctionComponent:
378 case IncompleteClassComponent:
379 case IndeterminateComponent:
380 case MemoComponent:
381 case SimpleMemoComponent:
382 if (typeof type === 'function') {
383 return type.displayName || type.name || null;
384 }
385
386 if (typeof type === 'string') {
387 return type;
388 }
389
390 break;
391
392 }
393
394 return null;
395 }
396
397 // Don't change these two values. They're used by React Dev Tools.
398 var NoFlags =
399 /* */
400 0;
401 var PerformedWork =
402 /* */
403 1; // You can change the rest (and add more).
404
405 var Placement =
406 /* */
407 2;
408 var Update =
409 /* */
410 4;
411 var PlacementAndUpdate =
412 /* */
413 Placement | Update;
414 var ChildDeletion =
415 /* */
416 16;
417 var ContentReset =
418 /* */
419 32;
420 var Callback =
421 /* */
422 64;
423 var DidCapture =
424 /* */
425 128;
426 var ForceClientRender =
427 /* */
428 256;
429 var Ref =
430 /* */
431 512;
432 var Snapshot =
433 /* */
434 1024;
435 var Passive =
436 /* */
437 2048;
438 var Hydrating =
439 /* */
440 4096;
441 var HydratingAndUpdate =
442 /* */
443 Hydrating | Update;
444 var Visibility =
445 /* */
446 8192;
447 var StoreConsistency =
448 /* */
449 16384;
450 var LifecycleEffectMask = Passive | Update | Callback | Ref | Snapshot | StoreConsistency; // Union of all commit flags (flags with the lifetime of a particular commit)
451
452 var HostEffectMask =
453 /* */
454 32767; // These are not really side effects, but we still reuse this field.
455
456 var Incomplete =
457 /* */
458 32768;
459 var ShouldCapture =
460 /* */
461 65536;
462 var ForceUpdateForLegacySuspense =
463 /* */
464 131072;
465 var Forked =
466 /* */
467 1048576; // Static tags describe aspects of a fiber that are not specific to a render,
468 // e.g. a fiber uses a passive effect (even if there are no updates on this particular render).
469 // This enables us to defer more work in the unmount case,
470 // since we can defer traversing the tree during layout to look for Passive effects,
471 // and instead rely on the static flag as a signal that there may be cleanup work.
472
473 var RefStatic =
474 /* */
475 2097152;
476 var LayoutStatic =
477 /* */
478 4194304;
479 var PassiveStatic =
480 /* */
481 8388608; // These flags allow us to traverse to fibers that have effects on mount
482 // don't contain effects, by checking subtreeFlags.
483
484 var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visibility
485 // flag logic (see #20043)
486 Update | Snapshot | ( 0);
487 var MutationMask = Placement | Update | ChildDeletion | ContentReset | Ref | Hydrating | Visibility;
488 var LayoutMask = Update | Callback | Ref | Visibility; // TODO: Split into PassiveMountMask and PassiveUnmountMask
489
490 var PassiveMask = Passive | ChildDeletion; // Union of tags that don't get reset on clones.
491 // This allows certain concepts to persist without recalculating them,
492 // e.g. whether a subtree contains passive effects or portals.
493
494 var StaticMask = LayoutStatic | PassiveStatic | RefStatic;
495
496 var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
497 function getNearestMountedFiber(fiber) {
498 var node = fiber;
499 var nearestMounted = fiber;
500
501 if (!fiber.alternate) {
502 // If there is no alternate, this might be a new tree that isn't inserted
503 // yet. If it is, then it will have a pending insertion effect on it.
504 var nextNode = node;
505
506 do {
507 node = nextNode;
508
509 if ((node.flags & (Placement | Hydrating)) !== NoFlags) {
510 // This is an insertion or in-progress hydration. The nearest possible
511 // mounted fiber is the parent but we need to continue to figure out
512 // if that one is still mounted.
513 nearestMounted = node.return;
514 }
515
516 nextNode = node.return;
517 } while (nextNode);
518 } else {
519 while (node.return) {
520 node = node.return;
521 }
522 }
523
524 if (node.tag === HostRoot) {
525 // TODO: Check if this was a nested HostRoot when used with
526 // renderContainerIntoSubtree.
527 return nearestMounted;
528 } // If we didn't hit the root, that means that we're in an disconnected tree
529 // that has been unmounted.
530
531
532 return null;
533 }
534 function isFiberMounted(fiber) {
535 return getNearestMountedFiber(fiber) === fiber;
536 }
537 function isMounted(component) {
538 {
539 var owner = ReactCurrentOwner.current;
540
541 if (owner !== null && owner.tag === ClassComponent) {
542 var ownerFiber = owner;
543 var instance = ownerFiber.stateNode;
544
545 if (!instance._warnedAboutRefsInRender) {
546 error('%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentNameFromFiber(ownerFiber) || 'A component');
547 }
548
549 instance._warnedAboutRefsInRender = true;
550 }
551 }
552
553 var fiber = get(component);
554
555 if (!fiber) {
556 return false;
557 }
558
559 return getNearestMountedFiber(fiber) === fiber;
560 }
561
562 function assertIsMounted(fiber) {
563 if (getNearestMountedFiber(fiber) !== fiber) {
564 throw new Error('Unable to find node on an unmounted component.');
565 }
566 }
567
568 function findCurrentFiberUsingSlowPath(fiber) {
569 var alternate = fiber.alternate;
570
571 if (!alternate) {
572 // If there is no alternate, then we only need to check if it is mounted.
573 var nearestMounted = getNearestMountedFiber(fiber);
574
575 if (nearestMounted === null) {
576 throw new Error('Unable to find node on an unmounted component.');
577 }
578
579 if (nearestMounted !== fiber) {
580 return null;
581 }
582
583 return fiber;
584 } // If we have two possible branches, we'll walk backwards up to the root
585 // to see what path the root points to. On the way we may hit one of the
586 // special cases and we'll deal with them.
587
588
589 var a = fiber;
590 var b = alternate;
591
592 while (true) {
593 var parentA = a.return;
594
595 if (parentA === null) {
596 // We're at the root.
597 break;
598 }
599
600 var parentB = parentA.alternate;
601
602 if (parentB === null) {
603 // There is no alternate. This is an unusual case. Currently, it only
604 // happens when a Suspense component is hidden. An extra fragment fiber
605 // is inserted in between the Suspense fiber and its children. Skip
606 // over this extra fragment fiber and proceed to the next parent.
607 var nextParent = parentA.return;
608
609 if (nextParent !== null) {
610 a = b = nextParent;
611 continue;
612 } // If there's no parent, we're at the root.
613
614
615 break;
616 } // If both copies of the parent fiber point to the same child, we can
617 // assume that the child is current. This happens when we bailout on low
618 // priority: the bailed out fiber's child reuses the current child.
619
620
621 if (parentA.child === parentB.child) {
622 var child = parentA.child;
623
624 while (child) {
625 if (child === a) {
626 // We've determined that A is the current branch.
627 assertIsMounted(parentA);
628 return fiber;
629 }
630
631 if (child === b) {
632 // We've determined that B is the current branch.
633 assertIsMounted(parentA);
634 return alternate;
635 }
636
637 child = child.sibling;
638 } // We should never have an alternate for any mounting node. So the only
639 // way this could possibly happen is if this was unmounted, if at all.
640
641
642 throw new Error('Unable to find node on an unmounted component.');
643 }
644
645 if (a.return !== b.return) {
646 // The return pointer of A and the return pointer of B point to different
647 // fibers. We assume that return pointers never criss-cross, so A must
648 // belong to the child set of A.return, and B must belong to the child
649 // set of B.return.
650 a = parentA;
651 b = parentB;
652 } else {
653 // The return pointers point to the same fiber. We'll have to use the
654 // default, slow path: scan the child sets of each parent alternate to see
655 // which child belongs to which set.
656 //
657 // Search parent A's child set
658 var didFindChild = false;
659 var _child = parentA.child;
660
661 while (_child) {
662 if (_child === a) {
663 didFindChild = true;
664 a = parentA;
665 b = parentB;
666 break;
667 }
668
669 if (_child === b) {
670 didFindChild = true;
671 b = parentA;
672 a = parentB;
673 break;
674 }
675
676 _child = _child.sibling;
677 }
678
679 if (!didFindChild) {
680 // Search parent B's child set
681 _child = parentB.child;
682
683 while (_child) {
684 if (_child === a) {
685 didFindChild = true;
686 a = parentB;
687 b = parentA;
688 break;
689 }
690
691 if (_child === b) {
692 didFindChild = true;
693 b = parentB;
694 a = parentA;
695 break;
696 }
697
698 _child = _child.sibling;
699 }
700
701 if (!didFindChild) {
702 throw new Error('Child was not found in either parent set. This indicates a bug ' + 'in React related to the return pointer. Please file an issue.');
703 }
704 }
705 }
706
707 if (a.alternate !== b) {
708 throw new Error("Return fibers should always be each others' alternates. " + 'This error is likely caused by a bug in React. Please file an issue.');
709 }
710 } // If the root is not a host container, we're in a disconnected tree. I.e.
711 // unmounted.
712
713
714 if (a.tag !== HostRoot) {
715 throw new Error('Unable to find node on an unmounted component.');
716 }
717
718 if (a.stateNode.current === a) {
719 // We've determined that A is the current branch.
720 return fiber;
721 } // Otherwise B has to be current branch.
722
723
724 return alternate;
725 }
726 function findCurrentHostFiber(parent) {
727 var currentParent = findCurrentFiberUsingSlowPath(parent);
728 return currentParent !== null ? findCurrentHostFiberImpl(currentParent) : null;
729 }
730
731 function findCurrentHostFiberImpl(node) {
732 // Next we'll drill down this component to find the first HostComponent/Text.
733 if (node.tag === HostComponent || node.tag === HostText) {
734 return node;
735 }
736
737 var child = node.child;
738
739 while (child !== null) {
740 var match = findCurrentHostFiberImpl(child);
741
742 if (match !== null) {
743 return match;
744 }
745
746 child = child.sibling;
747 }
748
749 return null;
750 }
751
752 var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare
753
754 function isArray(a) {
755 return isArrayImpl(a);
756 }
757
758 // This module only exists as an ESM wrapper around the external CommonJS
759 var scheduleCallback = Scheduler$1.unstable_scheduleCallback;
760 var cancelCallback = Scheduler$1.unstable_cancelCallback;
761 var shouldYield = Scheduler$1.unstable_shouldYield;
762 var requestPaint = Scheduler$1.unstable_requestPaint;
763 var now = Scheduler$1.unstable_now;
764 var ImmediatePriority = Scheduler$1.unstable_ImmediatePriority;
765 var UserBlockingPriority = Scheduler$1.unstable_UserBlockingPriority;
766 var NormalPriority = Scheduler$1.unstable_NormalPriority;
767 var IdlePriority = Scheduler$1.unstable_IdlePriority;
768
769 // Helpers to patch console.logs to avoid logging during side-effect free
770 // replaying on render function. This currently only patches the object
771 // lazily which won't cover if the log function was extracted eagerly.
772 // We could also eagerly patch the method.
773 var disabledDepth = 0;
774 var prevLog;
775 var prevInfo;
776 var prevWarn;
777 var prevError;
778 var prevGroup;
779 var prevGroupCollapsed;
780 var prevGroupEnd;
781
782 function disabledLog() {}
783
784 disabledLog.__reactDisabledLog = true;
785 function disableLogs() {
786 {
787 if (disabledDepth === 0) {
788 /* eslint-disable react-internal/no-production-logging */
789 prevLog = console.log;
790 prevInfo = console.info;
791 prevWarn = console.warn;
792 prevError = console.error;
793 prevGroup = console.group;
794 prevGroupCollapsed = console.groupCollapsed;
795 prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099
796
797 var props = {
798 configurable: true,
799 enumerable: true,
800 value: disabledLog,
801 writable: true
802 }; // $FlowFixMe Flow thinks console is immutable.
803
804 Object.defineProperties(console, {
805 info: props,
806 log: props,
807 warn: props,
808 error: props,
809 group: props,
810 groupCollapsed: props,
811 groupEnd: props
812 });
813 /* eslint-enable react-internal/no-production-logging */
814 }
815
816 disabledDepth++;
817 }
818 }
819 function reenableLogs() {
820 {
821 disabledDepth--;
822
823 if (disabledDepth === 0) {
824 /* eslint-disable react-internal/no-production-logging */
825 var props = {
826 configurable: true,
827 enumerable: true,
828 writable: true
829 }; // $FlowFixMe Flow thinks console is immutable.
830
831 Object.defineProperties(console, {
832 log: assign({}, props, {
833 value: prevLog
834 }),
835 info: assign({}, props, {
836 value: prevInfo
837 }),
838 warn: assign({}, props, {
839 value: prevWarn
840 }),
841 error: assign({}, props, {
842 value: prevError
843 }),
844 group: assign({}, props, {
845 value: prevGroup
846 }),
847 groupCollapsed: assign({}, props, {
848 value: prevGroupCollapsed
849 }),
850 groupEnd: assign({}, props, {
851 value: prevGroupEnd
852 })
853 });
854 /* eslint-enable react-internal/no-production-logging */
855 }
856
857 if (disabledDepth < 0) {
858 error('disabledDepth fell below zero. ' + 'This is a bug in React. Please file an issue.');
859 }
860 }
861 }
862
863 var rendererID = null;
864 var injectedHook = null;
865 var hasLoggedError = false;
866 var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
867 function injectInternals(internals) {
868 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
869 // No DevTools
870 return false;
871 }
872
873 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
874
875 if (hook.isDisabled) {
876 // This isn't a real property on the hook, but it can be set to opt out
877 // of DevTools integration and associated warnings and logs.
878 // https://github.com/facebook/react/issues/3877
879 return true;
880 }
881
882 if (!hook.supportsFiber) {
883 {
884 error('The installed version of React DevTools is too old and will not work ' + 'with the current version of React. Please update React DevTools. ' + 'https://reactjs.org/link/react-devtools');
885 } // DevTools exists, even though it doesn't support Fiber.
886
887
888 return true;
889 }
890
891 try {
892 if (enableSchedulingProfiler) {
893 // Conditionally inject these hooks only if Timeline profiler is supported by this build.
894 // This gives DevTools a way to feature detect that isn't tied to version number
895 // (since profiling and timeline are controlled by different feature flags).
896 internals = assign({}, internals, {
897 getLaneLabelMap: getLaneLabelMap,
898 injectProfilingHooks: injectProfilingHooks
899 });
900 }
901
902 rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
903
904 injectedHook = hook;
905 } catch (err) {
906 // Catch all errors because it is unsafe to throw during initialization.
907 {
908 error('React instrumentation encountered an error: %s.', err);
909 }
910 }
911
912 if (hook.checkDCE) {
913 // This is the real DevTools.
914 return true;
915 } else {
916 // This is likely a hook installed by Fast Refresh runtime.
917 return false;
918 }
919 }
920 function onScheduleRoot(root, children) {
921 {
922 if (injectedHook && typeof injectedHook.onScheduleFiberRoot === 'function') {
923 try {
924 injectedHook.onScheduleFiberRoot(rendererID, root, children);
925 } catch (err) {
926 if ( !hasLoggedError) {
927 hasLoggedError = true;
928
929 error('React instrumentation encountered an error: %s', err);
930 }
931 }
932 }
933 }
934 }
935 function onCommitRoot(root, eventPriority) {
936 if (injectedHook && typeof injectedHook.onCommitFiberRoot === 'function') {
937 try {
938 var didError = (root.current.flags & DidCapture) === DidCapture;
939
940 if (enableProfilerTimer) {
941 var schedulerPriority;
942
943 switch (eventPriority) {
944 case DiscreteEventPriority:
945 schedulerPriority = ImmediatePriority;
946 break;
947
948 case ContinuousEventPriority:
949 schedulerPriority = UserBlockingPriority;
950 break;
951
952 case DefaultEventPriority:
953 schedulerPriority = NormalPriority;
954 break;
955
956 case IdleEventPriority:
957 schedulerPriority = IdlePriority;
958 break;
959
960 default:
961 schedulerPriority = NormalPriority;
962 break;
963 }
964
965 injectedHook.onCommitFiberRoot(rendererID, root, schedulerPriority, didError);
966 } else {
967 injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError);
968 }
969 } catch (err) {
970 {
971 if (!hasLoggedError) {
972 hasLoggedError = true;
973
974 error('React instrumentation encountered an error: %s', err);
975 }
976 }
977 }
978 }
979 }
980 function onPostCommitRoot(root) {
981 if (injectedHook && typeof injectedHook.onPostCommitFiberRoot === 'function') {
982 try {
983 injectedHook.onPostCommitFiberRoot(rendererID, root);
984 } catch (err) {
985 {
986 if (!hasLoggedError) {
987 hasLoggedError = true;
988
989 error('React instrumentation encountered an error: %s', err);
990 }
991 }
992 }
993 }
994 }
995 function onCommitUnmount(fiber) {
996 if (injectedHook && typeof injectedHook.onCommitFiberUnmount === 'function') {
997 try {
998 injectedHook.onCommitFiberUnmount(rendererID, fiber);
999 } catch (err) {
1000 {
1001 if (!hasLoggedError) {
1002 hasLoggedError = true;
1003
1004 error('React instrumentation encountered an error: %s', err);
1005 }
1006 }
1007 }
1008 }
1009 }
1010
1011 function injectProfilingHooks(profilingHooks) {
1012 }
1013
1014 function getLaneLabelMap() {
1015 {
1016 return null;
1017 }
1018 }
1019 function markComponentRenderStopped() {
1020 }
1021 function markComponentErrored(fiber, thrownValue, lanes) {
1022 }
1023 function markComponentSuspended(fiber, wakeable, lanes) {
1024 }
1025
1026 var NoMode =
1027 /* */
1028 0; // TODO: Remove ConcurrentMode by reading from the root tag instead
1029
1030 var ConcurrentMode =
1031 /* */
1032 1;
1033 var ProfileMode =
1034 /* */
1035 2;
1036 var StrictLegacyMode =
1037 /* */
1038 8;
1039
1040 // TODO: This is pretty well supported by browsers. Maybe we can drop it.
1041 var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros.
1042 // Based on:
1043 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
1044
1045 var log = Math.log;
1046 var LN2 = Math.LN2;
1047
1048 function clz32Fallback(x) {
1049 var asUint = x >>> 0;
1050
1051 if (asUint === 0) {
1052 return 32;
1053 }
1054
1055 return 31 - (log(asUint) / LN2 | 0) | 0;
1056 }
1057
1058 // If those values are changed that package should be rebuilt and redeployed.
1059
1060 var TotalLanes = 31;
1061 var NoLanes =
1062 /* */
1063 0;
1064 var NoLane =
1065 /* */
1066 0;
1067 var SyncLane =
1068 /* */
1069 1;
1070 var InputContinuousHydrationLane =
1071 /* */
1072 2;
1073 var InputContinuousLane =
1074 /* */
1075 4;
1076 var DefaultHydrationLane =
1077 /* */
1078 8;
1079 var DefaultLane =
1080 /* */
1081 16;
1082 var TransitionHydrationLane =
1083 /* */
1084 32;
1085 var TransitionLanes =
1086 /* */
1087 4194240;
1088 var TransitionLane1 =
1089 /* */
1090 64;
1091 var TransitionLane2 =
1092 /* */
1093 128;
1094 var TransitionLane3 =
1095 /* */
1096 256;
1097 var TransitionLane4 =
1098 /* */
1099 512;
1100 var TransitionLane5 =
1101 /* */
1102 1024;
1103 var TransitionLane6 =
1104 /* */
1105 2048;
1106 var TransitionLane7 =
1107 /* */
1108 4096;
1109 var TransitionLane8 =
1110 /* */
1111 8192;
1112 var TransitionLane9 =
1113 /* */
1114 16384;
1115 var TransitionLane10 =
1116 /* */
1117 32768;
1118 var TransitionLane11 =
1119 /* */
1120 65536;
1121 var TransitionLane12 =
1122 /* */
1123 131072;
1124 var TransitionLane13 =
1125 /* */
1126 262144;
1127 var TransitionLane14 =
1128 /* */
1129 524288;
1130 var TransitionLane15 =
1131 /* */
1132 1048576;
1133 var TransitionLane16 =
1134 /* */
1135 2097152;
1136 var RetryLanes =
1137 /* */
1138 130023424;
1139 var RetryLane1 =
1140 /* */
1141 4194304;
1142 var RetryLane2 =
1143 /* */
1144 8388608;
1145 var RetryLane3 =
1146 /* */
1147 16777216;
1148 var RetryLane4 =
1149 /* */
1150 33554432;
1151 var RetryLane5 =
1152 /* */
1153 67108864;
1154 var SomeRetryLane = RetryLane1;
1155 var SelectiveHydrationLane =
1156 /* */
1157 134217728;
1158 var NonIdleLanes =
1159 /* */
1160 268435455;
1161 var IdleHydrationLane =
1162 /* */
1163 268435456;
1164 var IdleLane =
1165 /* */
1166 536870912;
1167 var OffscreenLane =
1168 /* */
1169 1073741824; // This function is used for the experimental timeline (react-devtools-timeline)
1170 var NoTimestamp = -1;
1171 var nextTransitionLane = TransitionLane1;
1172 var nextRetryLane = RetryLane1;
1173
1174 function getHighestPriorityLanes(lanes) {
1175 switch (getHighestPriorityLane(lanes)) {
1176 case SyncLane:
1177 return SyncLane;
1178
1179 case InputContinuousHydrationLane:
1180 return InputContinuousHydrationLane;
1181
1182 case InputContinuousLane:
1183 return InputContinuousLane;
1184
1185 case DefaultHydrationLane:
1186 return DefaultHydrationLane;
1187
1188 case DefaultLane:
1189 return DefaultLane;
1190
1191 case TransitionHydrationLane:
1192 return TransitionHydrationLane;
1193
1194 case TransitionLane1:
1195 case TransitionLane2:
1196 case TransitionLane3:
1197 case TransitionLane4:
1198 case TransitionLane5:
1199 case TransitionLane6:
1200 case TransitionLane7:
1201 case TransitionLane8:
1202 case TransitionLane9:
1203 case TransitionLane10:
1204 case TransitionLane11:
1205 case TransitionLane12:
1206 case TransitionLane13:
1207 case TransitionLane14:
1208 case TransitionLane15:
1209 case TransitionLane16:
1210 return lanes & TransitionLanes;
1211
1212 case RetryLane1:
1213 case RetryLane2:
1214 case RetryLane3:
1215 case RetryLane4:
1216 case RetryLane5:
1217 return lanes & RetryLanes;
1218
1219 case SelectiveHydrationLane:
1220 return SelectiveHydrationLane;
1221
1222 case IdleHydrationLane:
1223 return IdleHydrationLane;
1224
1225 case IdleLane:
1226 return IdleLane;
1227
1228 case OffscreenLane:
1229 return OffscreenLane;
1230
1231 default:
1232 {
1233 error('Should have found matching lanes. This is a bug in React.');
1234 } // This shouldn't be reachable, but as a fallback, return the entire bitmask.
1235
1236
1237 return lanes;
1238 }
1239 }
1240
1241 function getNextLanes(root, wipLanes) {
1242 // Early bailout if there's no pending work left.
1243 var pendingLanes = root.pendingLanes;
1244
1245 if (pendingLanes === NoLanes) {
1246 return NoLanes;
1247 }
1248
1249 var nextLanes = NoLanes;
1250 var suspendedLanes = root.suspendedLanes;
1251 var pingedLanes = root.pingedLanes; // Do not work on any idle work until all the non-idle work has finished,
1252 // even if the work is suspended.
1253
1254 var nonIdlePendingLanes = pendingLanes & NonIdleLanes;
1255
1256 if (nonIdlePendingLanes !== NoLanes) {
1257 var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes;
1258
1259 if (nonIdleUnblockedLanes !== NoLanes) {
1260 nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes);
1261 } else {
1262 var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes;
1263
1264 if (nonIdlePingedLanes !== NoLanes) {
1265 nextLanes = getHighestPriorityLanes(nonIdlePingedLanes);
1266 }
1267 }
1268 } else {
1269 // The only remaining work is Idle.
1270 var unblockedLanes = pendingLanes & ~suspendedLanes;
1271
1272 if (unblockedLanes !== NoLanes) {
1273 nextLanes = getHighestPriorityLanes(unblockedLanes);
1274 } else {
1275 if (pingedLanes !== NoLanes) {
1276 nextLanes = getHighestPriorityLanes(pingedLanes);
1277 }
1278 }
1279 }
1280
1281 if (nextLanes === NoLanes) {
1282 // This should only be reachable if we're suspended
1283 // TODO: Consider warning in this path if a fallback timer is not scheduled.
1284 return NoLanes;
1285 } // If we're already in the middle of a render, switching lanes will interrupt
1286 // it and we'll lose our progress. We should only do this if the new lanes are
1287 // higher priority.
1288
1289
1290 if (wipLanes !== NoLanes && wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't
1291 // bother waiting until the root is complete.
1292 (wipLanes & suspendedLanes) === NoLanes) {
1293 var nextLane = getHighestPriorityLane(nextLanes);
1294 var wipLane = getHighestPriorityLane(wipLanes);
1295
1296 if ( // Tests whether the next lane is equal or lower priority than the wip
1297 // one. This works because the bits decrease in priority as you go left.
1298 nextLane >= wipLane || // Default priority updates should not interrupt transition updates. The
1299 // only difference between default updates and transition updates is that
1300 // default updates do not support refresh transitions.
1301 nextLane === DefaultLane && (wipLane & TransitionLanes) !== NoLanes) {
1302 // Keep working on the existing in-progress tree. Do not interrupt.
1303 return wipLanes;
1304 }
1305 }
1306
1307 if ((nextLanes & InputContinuousLane) !== NoLanes) {
1308 // When updates are sync by default, we entangle continuous priority updates
1309 // and default updates, so they render in the same batch. The only reason
1310 // they use separate lanes is because continuous updates should interrupt
1311 // transitions, but default updates should not.
1312 nextLanes |= pendingLanes & DefaultLane;
1313 } // Check for entangled lanes and add them to the batch.
1314 //
1315 // A lane is said to be entangled with another when it's not allowed to render
1316 // in a batch that does not also include the other lane. Typically we do this
1317 // when multiple updates have the same source, and we only want to respond to
1318 // the most recent event from that source.
1319 //
1320 // Note that we apply entanglements *after* checking for partial work above.
1321 // This means that if a lane is entangled during an interleaved event while
1322 // it's already rendering, we won't interrupt it. This is intentional, since
1323 // entanglement is usually "best effort": we'll try our best to render the
1324 // lanes in the same batch, but it's not worth throwing out partially
1325 // completed work in order to do it.
1326 // TODO: Reconsider this. The counter-argument is that the partial work
1327 // represents an intermediate state, which we don't want to show to the user.
1328 // And by spending extra time finishing it, we're increasing the amount of
1329 // time it takes to show the final state, which is what they are actually
1330 // waiting for.
1331 //
1332 // For those exceptions where entanglement is semantically important, like
1333 // useMutableSource, we should ensure that there is no partial work at the
1334 // time we apply the entanglement.
1335
1336
1337 var entangledLanes = root.entangledLanes;
1338
1339 if (entangledLanes !== NoLanes) {
1340 var entanglements = root.entanglements;
1341 var lanes = nextLanes & entangledLanes;
1342
1343 while (lanes > 0) {
1344 var index = pickArbitraryLaneIndex(lanes);
1345 var lane = 1 << index;
1346 nextLanes |= entanglements[index];
1347 lanes &= ~lane;
1348 }
1349 }
1350
1351 return nextLanes;
1352 }
1353 function getMostRecentEventTime(root, lanes) {
1354 var eventTimes = root.eventTimes;
1355 var mostRecentEventTime = NoTimestamp;
1356
1357 while (lanes > 0) {
1358 var index = pickArbitraryLaneIndex(lanes);
1359 var lane = 1 << index;
1360 var eventTime = eventTimes[index];
1361
1362 if (eventTime > mostRecentEventTime) {
1363 mostRecentEventTime = eventTime;
1364 }
1365
1366 lanes &= ~lane;
1367 }
1368
1369 return mostRecentEventTime;
1370 }
1371
1372 function computeExpirationTime(lane, currentTime) {
1373 switch (lane) {
1374 case SyncLane:
1375 case InputContinuousHydrationLane:
1376 case InputContinuousLane:
1377 // User interactions should expire slightly more quickly.
1378 //
1379 // NOTE: This is set to the corresponding constant as in Scheduler.js.
1380 // When we made it larger, a product metric in www regressed, suggesting
1381 // there's a user interaction that's being starved by a series of
1382 // synchronous updates. If that theory is correct, the proper solution is
1383 // to fix the starvation. However, this scenario supports the idea that
1384 // expiration times are an important safeguard when starvation
1385 // does happen.
1386 return currentTime + 250;
1387
1388 case DefaultHydrationLane:
1389 case DefaultLane:
1390 case TransitionHydrationLane:
1391 case TransitionLane1:
1392 case TransitionLane2:
1393 case TransitionLane3:
1394 case TransitionLane4:
1395 case TransitionLane5:
1396 case TransitionLane6:
1397 case TransitionLane7:
1398 case TransitionLane8:
1399 case TransitionLane9:
1400 case TransitionLane10:
1401 case TransitionLane11:
1402 case TransitionLane12:
1403 case TransitionLane13:
1404 case TransitionLane14:
1405 case TransitionLane15:
1406 case TransitionLane16:
1407 return currentTime + 5000;
1408
1409 case RetryLane1:
1410 case RetryLane2:
1411 case RetryLane3:
1412 case RetryLane4:
1413 case RetryLane5:
1414 // TODO: Retries should be allowed to expire if they are CPU bound for
1415 // too long, but when I made this change it caused a spike in browser
1416 // crashes. There must be some other underlying bug; not super urgent but
1417 // ideally should figure out why and fix it. Unfortunately we don't have
1418 // a repro for the crashes, only detected via production metrics.
1419 return NoTimestamp;
1420
1421 case SelectiveHydrationLane:
1422 case IdleHydrationLane:
1423 case IdleLane:
1424 case OffscreenLane:
1425 // Anything idle priority or lower should never expire.
1426 return NoTimestamp;
1427
1428 default:
1429 {
1430 error('Should have found matching lanes. This is a bug in React.');
1431 }
1432
1433 return NoTimestamp;
1434 }
1435 }
1436
1437 function markStarvedLanesAsExpired(root, currentTime) {
1438 // TODO: This gets called every time we yield. We can optimize by storing
1439 // the earliest expiration time on the root. Then use that to quickly bail out
1440 // of this function.
1441 var pendingLanes = root.pendingLanes;
1442 var suspendedLanes = root.suspendedLanes;
1443 var pingedLanes = root.pingedLanes;
1444 var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their
1445 // expiration time. If so, we'll assume the update is being starved and mark
1446 // it as expired to force it to finish.
1447
1448 var lanes = pendingLanes;
1449
1450 while (lanes > 0) {
1451 var index = pickArbitraryLaneIndex(lanes);
1452 var lane = 1 << index;
1453 var expirationTime = expirationTimes[index];
1454
1455 if (expirationTime === NoTimestamp) {
1456 // Found a pending lane with no expiration time. If it's not suspended, or
1457 // if it's pinged, assume it's CPU-bound. Compute a new expiration time
1458 // using the current time.
1459 if ((lane & suspendedLanes) === NoLanes || (lane & pingedLanes) !== NoLanes) {
1460 // Assumes timestamps are monotonically increasing.
1461 expirationTimes[index] = computeExpirationTime(lane, currentTime);
1462 }
1463 } else if (expirationTime <= currentTime) {
1464 // This lane expired
1465 root.expiredLanes |= lane;
1466 }
1467
1468 lanes &= ~lane;
1469 }
1470 } // This returns the highest priority pending lanes regardless of whether they
1471 function getLanesToRetrySynchronouslyOnError(root) {
1472 var everythingButOffscreen = root.pendingLanes & ~OffscreenLane;
1473
1474 if (everythingButOffscreen !== NoLanes) {
1475 return everythingButOffscreen;
1476 }
1477
1478 if (everythingButOffscreen & OffscreenLane) {
1479 return OffscreenLane;
1480 }
1481
1482 return NoLanes;
1483 }
1484 function includesSyncLane(lanes) {
1485 return (lanes & SyncLane) !== NoLanes;
1486 }
1487 function includesNonIdleWork(lanes) {
1488 return (lanes & NonIdleLanes) !== NoLanes;
1489 }
1490 function includesOnlyRetries(lanes) {
1491 return (lanes & RetryLanes) === lanes;
1492 }
1493 function includesOnlyTransitions(lanes) {
1494 return (lanes & TransitionLanes) === lanes;
1495 }
1496 function includesBlockingLane(root, lanes) {
1497
1498 var SyncDefaultLanes = InputContinuousHydrationLane | InputContinuousLane | DefaultHydrationLane | DefaultLane;
1499 return (lanes & SyncDefaultLanes) !== NoLanes;
1500 }
1501 function includesExpiredLane(root, lanes) {
1502 // This is a separate check from includesBlockingLane because a lane can
1503 // expire after a render has already started.
1504 return (lanes & root.expiredLanes) !== NoLanes;
1505 }
1506 function isTransitionLane(lane) {
1507 return (lane & TransitionLanes) !== 0;
1508 }
1509 function claimNextTransitionLane() {
1510 // Cycle through the lanes, assigning each new transition to the next lane.
1511 // In most cases, this means every transition gets its own lane, until we
1512 // run out of lanes and cycle back to the beginning.
1513 var lane = nextTransitionLane;
1514 nextTransitionLane <<= 1;
1515
1516 if ((nextTransitionLane & TransitionLanes) === 0) {
1517 nextTransitionLane = TransitionLane1;
1518 }
1519
1520 return lane;
1521 }
1522 function claimNextRetryLane() {
1523 var lane = nextRetryLane;
1524 nextRetryLane <<= 1;
1525
1526 if ((nextRetryLane & RetryLanes) === 0) {
1527 nextRetryLane = RetryLane1;
1528 }
1529
1530 return lane;
1531 }
1532 function getHighestPriorityLane(lanes) {
1533 return lanes & -lanes;
1534 }
1535 function pickArbitraryLane(lanes) {
1536 // This wrapper function gets inlined. Only exists so to communicate that it
1537 // doesn't matter which bit is selected; you can pick any bit without
1538 // affecting the algorithms where its used. Here I'm using
1539 // getHighestPriorityLane because it requires the fewest operations.
1540 return getHighestPriorityLane(lanes);
1541 }
1542
1543 function pickArbitraryLaneIndex(lanes) {
1544 return 31 - clz32(lanes);
1545 }
1546
1547 function laneToIndex(lane) {
1548 return pickArbitraryLaneIndex(lane);
1549 }
1550
1551 function includesSomeLane(a, b) {
1552 return (a & b) !== NoLanes;
1553 }
1554 function isSubsetOfLanes(set, subset) {
1555 return (set & subset) === subset;
1556 }
1557 function mergeLanes(a, b) {
1558 return a | b;
1559 }
1560 function removeLanes(set, subset) {
1561 return set & ~subset;
1562 }
1563 function intersectLanes(a, b) {
1564 return a & b;
1565 } // Seems redundant, but it changes the type from a single lane (used for
1566 // updates) to a group of lanes (used for flushing work).
1567
1568 function laneToLanes(lane) {
1569 return lane;
1570 }
1571 function createLaneMap(initial) {
1572 // Intentionally pushing one by one.
1573 // https://v8.dev/blog/elements-kinds#avoid-creating-holes
1574 var laneMap = [];
1575
1576 for (var i = 0; i < TotalLanes; i++) {
1577 laneMap.push(initial);
1578 }
1579
1580 return laneMap;
1581 }
1582 function markRootUpdated(root, updateLane, eventTime) {
1583 root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update
1584 // could unblock them. Clear the suspended lanes so that we can try rendering
1585 // them again.
1586 //
1587 // TODO: We really only need to unsuspend only lanes that are in the
1588 // `subtreeLanes` of the updated fiber, or the update lanes of the return
1589 // path. This would exclude suspended updates in an unrelated sibling tree,
1590 // since there's no way for this update to unblock it.
1591 //
1592 // We don't do this if the incoming update is idle, because we never process
1593 // idle updates until after all the regular updates have finished; there's no
1594 // way it could unblock a transition.
1595
1596 if (updateLane !== IdleLane) {
1597 root.suspendedLanes = NoLanes;
1598 root.pingedLanes = NoLanes;
1599 }
1600
1601 var eventTimes = root.eventTimes;
1602 var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most
1603 // recent event, and we assume time is monotonically increasing.
1604
1605 eventTimes[index] = eventTime;
1606 }
1607 function markRootSuspended(root, suspendedLanes) {
1608 root.suspendedLanes |= suspendedLanes;
1609 root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times.
1610
1611 var expirationTimes = root.expirationTimes;
1612 var lanes = suspendedLanes;
1613
1614 while (lanes > 0) {
1615 var index = pickArbitraryLaneIndex(lanes);
1616 var lane = 1 << index;
1617 expirationTimes[index] = NoTimestamp;
1618 lanes &= ~lane;
1619 }
1620 }
1621 function markRootPinged(root, pingedLanes, eventTime) {
1622 root.pingedLanes |= root.suspendedLanes & pingedLanes;
1623 }
1624 function markRootFinished(root, remainingLanes) {
1625 var noLongerPendingLanes = root.pendingLanes & ~remainingLanes;
1626 root.pendingLanes = remainingLanes; // Let's try everything again
1627
1628 root.suspendedLanes = 0;
1629 root.pingedLanes = 0;
1630 root.expiredLanes &= remainingLanes;
1631 root.mutableReadLanes &= remainingLanes;
1632 root.entangledLanes &= remainingLanes;
1633 var entanglements = root.entanglements;
1634 var eventTimes = root.eventTimes;
1635 var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work
1636
1637 var lanes = noLongerPendingLanes;
1638
1639 while (lanes > 0) {
1640 var index = pickArbitraryLaneIndex(lanes);
1641 var lane = 1 << index;
1642 entanglements[index] = NoLanes;
1643 eventTimes[index] = NoTimestamp;
1644 expirationTimes[index] = NoTimestamp;
1645 lanes &= ~lane;
1646 }
1647 }
1648 function markRootEntangled(root, entangledLanes) {
1649 // In addition to entangling each of the given lanes with each other, we also
1650 // have to consider _transitive_ entanglements. For each lane that is already
1651 // entangled with *any* of the given lanes, that lane is now transitively
1652 // entangled with *all* the given lanes.
1653 //
1654 // Translated: If C is entangled with A, then entangling A with B also
1655 // entangles C with B.
1656 //
1657 // If this is hard to grasp, it might help to intentionally break this
1658 // function and look at the tests that fail in ReactTransition-test.js. Try
1659 // commenting out one of the conditions below.
1660 var rootEntangledLanes = root.entangledLanes |= entangledLanes;
1661 var entanglements = root.entanglements;
1662 var lanes = rootEntangledLanes;
1663
1664 while (lanes) {
1665 var index = pickArbitraryLaneIndex(lanes);
1666 var lane = 1 << index;
1667
1668 if ( // Is this one of the newly entangled lanes?
1669 lane & entangledLanes | // Is this lane transitively entangled with the newly entangled lanes?
1670 entanglements[index] & entangledLanes) {
1671 entanglements[index] |= entangledLanes;
1672 }
1673
1674 lanes &= ~lane;
1675 }
1676 }
1677
1678 var DiscreteEventPriority = SyncLane;
1679 var ContinuousEventPriority = InputContinuousLane;
1680 var DefaultEventPriority = DefaultLane;
1681 var IdleEventPriority = IdleLane;
1682 var currentUpdatePriority = NoLane;
1683 function getCurrentUpdatePriority() {
1684 return currentUpdatePriority;
1685 }
1686 function setCurrentUpdatePriority(newPriority) {
1687 currentUpdatePriority = newPriority;
1688 }
1689 function higherEventPriority(a, b) {
1690 return a !== 0 && a < b ? a : b;
1691 }
1692 function lowerEventPriority(a, b) {
1693 return a === 0 || a > b ? a : b;
1694 }
1695 function isHigherEventPriority(a, b) {
1696 return a !== 0 && a < b;
1697 }
1698 function lanesToEventPriority(lanes) {
1699 var lane = getHighestPriorityLane(lanes);
1700
1701 if (!isHigherEventPriority(DiscreteEventPriority, lane)) {
1702 return DiscreteEventPriority;
1703 }
1704
1705 if (!isHigherEventPriority(ContinuousEventPriority, lane)) {
1706 return ContinuousEventPriority;
1707 }
1708
1709 if (includesNonIdleWork(lane)) {
1710 return DefaultEventPriority;
1711 }
1712
1713 return IdleEventPriority;
1714 }
1715
1716 // Renderers that don't support hydration
1717 // can re-export everything from this module.
1718 function shim() {
1719 throw new Error('The current renderer does not support hydration. ' + 'This error is likely caused by a bug in React. ' + 'Please file an issue.');
1720 } // Hydration (when unsupported)
1721 var isSuspenseInstancePending = shim;
1722 var isSuspenseInstanceFallback = shim;
1723 var hydrateTextInstance = shim;
1724 var errorHydratingContainer = shim;
1725
1726 var NO_CONTEXT = {};
1727 var UPDATE_SIGNAL = {};
1728 var nodeToInstanceMap = new WeakMap();
1729
1730 {
1731 Object.freeze(NO_CONTEXT);
1732 Object.freeze(UPDATE_SIGNAL);
1733 }
1734
1735 function getPublicInstance(inst) {
1736 switch (inst.tag) {
1737 case 'INSTANCE':
1738 var createNodeMock = inst.rootContainerInstance.createNodeMock;
1739 var mockNode = createNodeMock({
1740 type: inst.type,
1741 props: inst.props
1742 });
1743
1744 if (typeof mockNode === 'object' && mockNode !== null) {
1745 nodeToInstanceMap.set(mockNode, inst);
1746 }
1747
1748 return mockNode;
1749
1750 default:
1751 return inst;
1752 }
1753 }
1754 function appendChild(parentInstance, child) {
1755 {
1756 if (!isArray(parentInstance.children)) {
1757 error('An invalid container has been provided. ' + 'This may indicate that another renderer is being used in addition to the test renderer. ' + '(For example, ReactDOM.createPortal inside of a ReactTestRenderer tree.) ' + 'This is not supported.');
1758 }
1759 }
1760
1761 var index = parentInstance.children.indexOf(child);
1762
1763 if (index !== -1) {
1764 parentInstance.children.splice(index, 1);
1765 }
1766
1767 parentInstance.children.push(child);
1768 }
1769 function insertBefore(parentInstance, child, beforeChild) {
1770 var index = parentInstance.children.indexOf(child);
1771
1772 if (index !== -1) {
1773 parentInstance.children.splice(index, 1);
1774 }
1775
1776 var beforeIndex = parentInstance.children.indexOf(beforeChild);
1777 parentInstance.children.splice(beforeIndex, 0, child);
1778 }
1779 function removeChild(parentInstance, child) {
1780 var index = parentInstance.children.indexOf(child);
1781 parentInstance.children.splice(index, 1);
1782 }
1783 function clearContainer(container) {
1784 container.children.splice(0);
1785 }
1786 function getRootHostContext(rootContainerInstance) {
1787 return NO_CONTEXT;
1788 }
1789 function getChildHostContext(parentHostContext, type, rootContainerInstance) {
1790 return NO_CONTEXT;
1791 }
1792 function prepareForCommit(containerInfo) {
1793 // noop
1794 return null;
1795 }
1796 function resetAfterCommit(containerInfo) {// noop
1797 }
1798 function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
1799 return {
1800 type: type,
1801 props: props,
1802 isHidden: false,
1803 children: [],
1804 internalInstanceHandle: internalInstanceHandle,
1805 rootContainerInstance: rootContainerInstance,
1806 tag: 'INSTANCE'
1807 };
1808 }
1809 function appendInitialChild(parentInstance, child) {
1810 var index = parentInstance.children.indexOf(child);
1811
1812 if (index !== -1) {
1813 parentInstance.children.splice(index, 1);
1814 }
1815
1816 parentInstance.children.push(child);
1817 }
1818 function prepareUpdate(testElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
1819 return UPDATE_SIGNAL;
1820 }
1821 function shouldSetTextContent(type, props) {
1822 return false;
1823 }
1824 function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
1825 return {
1826 text: text,
1827 isHidden: false,
1828 tag: 'TEXT'
1829 };
1830 }
1831 function getCurrentEventPriority() {
1832 return DefaultEventPriority;
1833 }
1834 var scheduleTimeout = setTimeout;
1835 var cancelTimeout = clearTimeout;
1836 var noTimeout = -1; // -------------------
1837 function commitUpdate(instance, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
1838 instance.type = type;
1839 instance.props = newProps;
1840 }
1841 function commitTextUpdate(textInstance, oldText, newText) {
1842 textInstance.text = newText;
1843 }
1844 function resetTextContent(testElement) {// noop
1845 }
1846 var appendChildToContainer = appendChild;
1847 var insertInContainerBefore = insertBefore;
1848 var removeChildFromContainer = removeChild;
1849 function hideInstance(instance) {
1850 instance.isHidden = true;
1851 }
1852 function hideTextInstance(textInstance) {
1853 textInstance.isHidden = true;
1854 }
1855 function unhideInstance(instance, props) {
1856 instance.isHidden = false;
1857 }
1858 function unhideTextInstance(textInstance, text) {
1859 textInstance.isHidden = false;
1860 }
1861 function preparePortalMount(portalInstance) {// noop
1862 }
1863
1864 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
1865 var prefix;
1866 function describeBuiltInComponentFrame(name, source, ownerFn) {
1867 {
1868 if (prefix === undefined) {
1869 // Extract the VM specific prefix used by each line.
1870 try {
1871 throw Error();
1872 } catch (x) {
1873 var match = x.stack.trim().match(/\n( *(at )?)/);
1874 prefix = match && match[1] || '';
1875 }
1876 } // We use the prefix to ensure our stacks line up with native stack frames.
1877
1878
1879 return '\n' + prefix + name;
1880 }
1881 }
1882 var reentry = false;
1883 var componentFrameCache;
1884
1885 {
1886 var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
1887 componentFrameCache = new PossiblyWeakMap();
1888 }
1889
1890 function describeNativeComponentFrame(fn, construct) {
1891 // If something asked for a stack inside a fake render, it should get ignored.
1892 if ( !fn || reentry) {
1893 return '';
1894 }
1895
1896 {
1897 var frame = componentFrameCache.get(fn);
1898
1899 if (frame !== undefined) {
1900 return frame;
1901 }
1902 }
1903
1904 var control;
1905 reentry = true;
1906 var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe It does accept undefined.
1907
1908 Error.prepareStackTrace = undefined;
1909 var previousDispatcher;
1910
1911 {
1912 previousDispatcher = ReactCurrentDispatcher.current; // Set the dispatcher in DEV because this might be call in the render function
1913 // for warnings.
1914
1915 ReactCurrentDispatcher.current = null;
1916 disableLogs();
1917 }
1918
1919 try {
1920 // This should throw.
1921 if (construct) {
1922 // Something should be setting the props in the constructor.
1923 var Fake = function () {
1924 throw Error();
1925 }; // $FlowFixMe
1926
1927
1928 Object.defineProperty(Fake.prototype, 'props', {
1929 set: function () {
1930 // We use a throwing setter instead of frozen or non-writable props
1931 // because that won't throw in a non-strict mode function.
1932 throw Error();
1933 }
1934 });
1935
1936 if (typeof Reflect === 'object' && Reflect.construct) {
1937 // We construct a different control for this case to include any extra
1938 // frames added by the construct call.
1939 try {
1940 Reflect.construct(Fake, []);
1941 } catch (x) {
1942 control = x;
1943 }
1944
1945 Reflect.construct(fn, [], Fake);
1946 } else {
1947 try {
1948 Fake.call();
1949 } catch (x) {
1950 control = x;
1951 }
1952
1953 fn.call(Fake.prototype);
1954 }
1955 } else {
1956 try {
1957 throw Error();
1958 } catch (x) {
1959 control = x;
1960 }
1961
1962 fn();
1963 }
1964 } catch (sample) {
1965 // This is inlined manually because closure doesn't do it for us.
1966 if (sample && control && typeof sample.stack === 'string') {
1967 // This extracts the first frame from the sample that isn't also in the control.
1968 // Skipping one frame that we assume is the frame that calls the two.
1969 var sampleLines = sample.stack.split('\n');
1970 var controlLines = control.stack.split('\n');
1971 var s = sampleLines.length - 1;
1972 var c = controlLines.length - 1;
1973
1974 while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {
1975 // We expect at least one stack frame to be shared.
1976 // Typically this will be the root most one. However, stack frames may be
1977 // cut off due to maximum stack limits. In this case, one maybe cut off
1978 // earlier than the other. We assume that the sample is longer or the same
1979 // and there for cut off earlier. So we should find the root most frame in
1980 // the sample somewhere in the control.
1981 c--;
1982 }
1983
1984 for (; s >= 1 && c >= 0; s--, c--) {
1985 // Next we find the first one that isn't the same which should be the
1986 // frame that called our sample function and the control.
1987 if (sampleLines[s] !== controlLines[c]) {
1988 // In V8, the first line is describing the message but other VMs don't.
1989 // If we're about to return the first line, and the control is also on the same
1990 // line, that's a pretty good indicator that our sample threw at same line as
1991 // the control. I.e. before we entered the sample frame. So we ignore this result.
1992 // This can happen if you passed a class to function component, or non-function.
1993 if (s !== 1 || c !== 1) {
1994 do {
1995 s--;
1996 c--; // We may still have similar intermediate frames from the construct call.
1997 // The next one that isn't the same should be our match though.
1998
1999 if (c < 0 || sampleLines[s] !== controlLines[c]) {
2000 // V8 adds a "new" prefix for native classes. Let's remove it to make it prettier.
2001 var _frame = '\n' + sampleLines[s].replace(' at new ', ' at '); // If our component frame is labeled "<anonymous>"
2002 // but we have a user-provided "displayName"
2003 // splice it in to make the stack more readable.
2004
2005
2006 if (fn.displayName && _frame.includes('<anonymous>')) {
2007 _frame = _frame.replace('<anonymous>', fn.displayName);
2008 }
2009
2010 {
2011 if (typeof fn === 'function') {
2012 componentFrameCache.set(fn, _frame);
2013 }
2014 } // Return the line we found.
2015
2016
2017 return _frame;
2018 }
2019 } while (s >= 1 && c >= 0);
2020 }
2021
2022 break;
2023 }
2024 }
2025 }
2026 } finally {
2027 reentry = false;
2028
2029 {
2030 ReactCurrentDispatcher.current = previousDispatcher;
2031 reenableLogs();
2032 }
2033
2034 Error.prepareStackTrace = previousPrepareStackTrace;
2035 } // Fallback to just using the name if we couldn't make it throw.
2036
2037
2038 var name = fn ? fn.displayName || fn.name : '';
2039 var syntheticFrame = name ? describeBuiltInComponentFrame(name) : '';
2040
2041 {
2042 if (typeof fn === 'function') {
2043 componentFrameCache.set(fn, syntheticFrame);
2044 }
2045 }
2046
2047 return syntheticFrame;
2048 }
2049
2050 function describeClassComponentFrame(ctor, source, ownerFn) {
2051 {
2052 return describeNativeComponentFrame(ctor, true);
2053 }
2054 }
2055 function describeFunctionComponentFrame(fn, source, ownerFn) {
2056 {
2057 return describeNativeComponentFrame(fn, false);
2058 }
2059 }
2060
2061 function shouldConstruct(Component) {
2062 var prototype = Component.prototype;
2063 return !!(prototype && prototype.isReactComponent);
2064 }
2065
2066 function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) {
2067
2068 if (type == null) {
2069 return '';
2070 }
2071
2072 if (typeof type === 'function') {
2073 {
2074 return describeNativeComponentFrame(type, shouldConstruct(type));
2075 }
2076 }
2077
2078 if (typeof type === 'string') {
2079 return describeBuiltInComponentFrame(type);
2080 }
2081
2082 switch (type) {
2083 case REACT_SUSPENSE_TYPE:
2084 return describeBuiltInComponentFrame('Suspense');
2085
2086 case REACT_SUSPENSE_LIST_TYPE:
2087 return describeBuiltInComponentFrame('SuspenseList');
2088 }
2089
2090 if (typeof type === 'object') {
2091 switch (type.$$typeof) {
2092 case REACT_FORWARD_REF_TYPE:
2093 return describeFunctionComponentFrame(type.render);
2094
2095 case REACT_MEMO_TYPE:
2096 // Memo may contain any component type so we recursively resolve it.
2097 return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn);
2098
2099 case REACT_LAZY_TYPE:
2100 {
2101 var lazyComponent = type;
2102 var payload = lazyComponent._payload;
2103 var init = lazyComponent._init;
2104
2105 try {
2106 // Lazy may contain any component type so we recursively resolve it.
2107 return describeUnknownElementTypeFrameInDEV(init(payload), source, ownerFn);
2108 } catch (x) {}
2109 }
2110 }
2111 }
2112
2113 return '';
2114 }
2115
2116 var hasOwnProperty = Object.prototype.hasOwnProperty;
2117
2118 var loggedTypeFailures = {};
2119 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
2120
2121 function setCurrentlyValidatingElement(element) {
2122 {
2123 if (element) {
2124 var owner = element._owner;
2125 var stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null);
2126 ReactDebugCurrentFrame.setExtraStackFrame(stack);
2127 } else {
2128 ReactDebugCurrentFrame.setExtraStackFrame(null);
2129 }
2130 }
2131 }
2132
2133 function checkPropTypes(typeSpecs, values, location, componentName, element) {
2134 {
2135 // $FlowFixMe This is okay but Flow doesn't know it.
2136 var has = Function.call.bind(hasOwnProperty);
2137
2138 for (var typeSpecName in typeSpecs) {
2139 if (has(typeSpecs, typeSpecName)) {
2140 var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to
2141 // fail the render phase where it didn't fail before. So we log it.
2142 // After these have been cleaned up, we'll let them throw.
2143
2144 try {
2145 // This is intentionally an invariant that gets caught. It's the same
2146 // behavior as without this statement except with a better message.
2147 if (typeof typeSpecs[typeSpecName] !== 'function') {
2148 // eslint-disable-next-line react-internal/prod-error-codes
2149 var err = Error((componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' + 'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.');
2150 err.name = 'Invariant Violation';
2151 throw err;
2152 }
2153
2154 error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
2155 } catch (ex) {
2156 error$1 = ex;
2157 }
2158
2159 if (error$1 && !(error$1 instanceof Error)) {
2160 setCurrentlyValidatingElement(element);
2161
2162 error('%s: type specification of %s' + ' `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', location, typeSpecName, typeof error$1);
2163
2164 setCurrentlyValidatingElement(null);
2165 }
2166
2167 if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) {
2168 // Only monitor this failure once because there tends to be a lot of the
2169 // same error.
2170 loggedTypeFailures[error$1.message] = true;
2171 setCurrentlyValidatingElement(element);
2172
2173 error('Failed %s type: %s', location, error$1.message);
2174
2175 setCurrentlyValidatingElement(null);
2176 }
2177 }
2178 }
2179 }
2180 }
2181
2182 var valueStack = [];
2183 var fiberStack;
2184
2185 {
2186 fiberStack = [];
2187 }
2188
2189 var index = -1;
2190
2191 function createCursor(defaultValue) {
2192 return {
2193 current: defaultValue
2194 };
2195 }
2196
2197 function pop(cursor, fiber) {
2198 if (index < 0) {
2199 {
2200 error('Unexpected pop.');
2201 }
2202
2203 return;
2204 }
2205
2206 {
2207 if (fiber !== fiberStack[index]) {
2208 error('Unexpected Fiber popped.');
2209 }
2210 }
2211
2212 cursor.current = valueStack[index];
2213 valueStack[index] = null;
2214
2215 {
2216 fiberStack[index] = null;
2217 }
2218
2219 index--;
2220 }
2221
2222 function push(cursor, value, fiber) {
2223 index++;
2224 valueStack[index] = cursor.current;
2225
2226 {
2227 fiberStack[index] = fiber;
2228 }
2229
2230 cursor.current = value;
2231 }
2232
2233 var warnedAboutMissingGetChildContext;
2234
2235 {
2236 warnedAboutMissingGetChildContext = {};
2237 }
2238
2239 var emptyContextObject = {};
2240
2241 {
2242 Object.freeze(emptyContextObject);
2243 } // A cursor to the current merged context object on the stack.
2244
2245
2246 var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.
2247
2248 var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.
2249 // We use this to get access to the parent context after we have already
2250 // pushed the next context provider, and now need to merge their contexts.
2251
2252 var previousContext = emptyContextObject;
2253
2254 function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
2255 {
2256 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
2257 // If the fiber is a context provider itself, when we read its context
2258 // we may have already pushed its own child context on the stack. A context
2259 // provider should not "see" its own child context. Therefore we read the
2260 // previous (parent) context instead for a context provider.
2261 return previousContext;
2262 }
2263
2264 return contextStackCursor.current;
2265 }
2266 }
2267
2268 function cacheContext(workInProgress, unmaskedContext, maskedContext) {
2269 {
2270 var instance = workInProgress.stateNode;
2271 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
2272 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
2273 }
2274 }
2275
2276 function getMaskedContext(workInProgress, unmaskedContext) {
2277 {
2278 var type = workInProgress.type;
2279 var contextTypes = type.contextTypes;
2280
2281 if (!contextTypes) {
2282 return emptyContextObject;
2283 } // Avoid recreating masked context unless unmasked context has changed.
2284 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
2285 // This may trigger infinite loops if componentWillReceiveProps calls setState.
2286
2287
2288 var instance = workInProgress.stateNode;
2289
2290 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
2291 return instance.__reactInternalMemoizedMaskedChildContext;
2292 }
2293
2294 var context = {};
2295
2296 for (var key in contextTypes) {
2297 context[key] = unmaskedContext[key];
2298 }
2299
2300 {
2301 var name = getComponentNameFromFiber(workInProgress) || 'Unknown';
2302 checkPropTypes(contextTypes, context, 'context', name);
2303 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
2304 // Context is created before the class component is instantiated so check for instance.
2305
2306
2307 if (instance) {
2308 cacheContext(workInProgress, unmaskedContext, context);
2309 }
2310
2311 return context;
2312 }
2313 }
2314
2315 function hasContextChanged() {
2316 {
2317 return didPerformWorkStackCursor.current;
2318 }
2319 }
2320
2321 function isContextProvider(type) {
2322 {
2323 var childContextTypes = type.childContextTypes;
2324 return childContextTypes !== null && childContextTypes !== undefined;
2325 }
2326 }
2327
2328 function popContext(fiber) {
2329 {
2330 pop(didPerformWorkStackCursor, fiber);
2331 pop(contextStackCursor, fiber);
2332 }
2333 }
2334
2335 function popTopLevelContextObject(fiber) {
2336 {
2337 pop(didPerformWorkStackCursor, fiber);
2338 pop(contextStackCursor, fiber);
2339 }
2340 }
2341
2342 function pushTopLevelContextObject(fiber, context, didChange) {
2343 {
2344 if (contextStackCursor.current !== emptyContextObject) {
2345 throw new Error('Unexpected context found on stack. ' + 'This error is likely caused by a bug in React. Please file an issue.');
2346 }
2347
2348 push(contextStackCursor, context, fiber);
2349 push(didPerformWorkStackCursor, didChange, fiber);
2350 }
2351 }
2352
2353 function processChildContext(fiber, type, parentContext) {
2354 {
2355 var instance = fiber.stateNode;
2356 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.
2357 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
2358
2359 if (typeof instance.getChildContext !== 'function') {
2360 {
2361 var componentName = getComponentNameFromFiber(fiber) || 'Unknown';
2362
2363 if (!warnedAboutMissingGetChildContext[componentName]) {
2364 warnedAboutMissingGetChildContext[componentName] = true;
2365
2366 error('%s.childContextTypes is specified but there is no getChildContext() method ' + 'on the instance. You can either define getChildContext() on %s or remove ' + 'childContextTypes from it.', componentName, componentName);
2367 }
2368 }
2369
2370 return parentContext;
2371 }
2372
2373 var childContext = instance.getChildContext();
2374
2375 for (var contextKey in childContext) {
2376 if (!(contextKey in childContextTypes)) {
2377 throw new Error((getComponentNameFromFiber(fiber) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes.");
2378 }
2379 }
2380
2381 {
2382 var name = getComponentNameFromFiber(fiber) || 'Unknown';
2383 checkPropTypes(childContextTypes, childContext, 'child context', name);
2384 }
2385
2386 return assign({}, parentContext, childContext);
2387 }
2388 }
2389
2390 function pushContextProvider(workInProgress) {
2391 {
2392 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.
2393 // If the instance does not exist yet, we will push null at first,
2394 // and replace it on the stack later when invalidating the context.
2395
2396 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.
2397 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
2398
2399 previousContext = contextStackCursor.current;
2400 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
2401 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
2402 return true;
2403 }
2404 }
2405
2406 function invalidateContextProvider(workInProgress, type, didChange) {
2407 {
2408 var instance = workInProgress.stateNode;
2409
2410 if (!instance) {
2411 throw new Error('Expected to have an instance by this point. ' + 'This error is likely caused by a bug in React. Please file an issue.');
2412 }
2413
2414 if (didChange) {
2415 // Merge parent and own context.
2416 // Skip this if we're not updating due to sCU.
2417 // This avoids unnecessarily recomputing memoized values.
2418 var mergedContext = processChildContext(workInProgress, type, previousContext);
2419 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.
2420 // It is important to unwind the context in the reverse order.
2421
2422 pop(didPerformWorkStackCursor, workInProgress);
2423 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.
2424
2425 push(contextStackCursor, mergedContext, workInProgress);
2426 push(didPerformWorkStackCursor, didChange, workInProgress);
2427 } else {
2428 pop(didPerformWorkStackCursor, workInProgress);
2429 push(didPerformWorkStackCursor, didChange, workInProgress);
2430 }
2431 }
2432 }
2433
2434 function findCurrentUnmaskedContext(fiber) {
2435 {
2436 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
2437 // makes sense elsewhere
2438 if (!isFiberMounted(fiber) || fiber.tag !== ClassComponent) {
2439 throw new Error('Expected subtree parent to be a mounted class component. ' + 'This error is likely caused by a bug in React. Please file an issue.');
2440 }
2441
2442 var node = fiber;
2443
2444 do {
2445 switch (node.tag) {
2446 case HostRoot:
2447 return node.stateNode.context;
2448
2449 case ClassComponent:
2450 {
2451 var Component = node.type;
2452
2453 if (isContextProvider(Component)) {
2454 return node.stateNode.__reactInternalMemoizedMergedChildContext;
2455 }
2456
2457 break;
2458 }
2459 }
2460
2461 node = node.return;
2462 } while (node !== null);
2463
2464 throw new Error('Found unexpected detached subtree parent. ' + 'This error is likely caused by a bug in React. Please file an issue.');
2465 }
2466 }
2467
2468 var LegacyRoot = 0;
2469 var ConcurrentRoot = 1;
2470
2471 /**
2472 * inlined Object.is polyfill to avoid requiring consumers ship their own
2473 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
2474 */
2475 function is(x, y) {
2476 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
2477 ;
2478 }
2479
2480 var objectIs = typeof Object.is === 'function' ? Object.is : is;
2481
2482 var syncQueue = null;
2483 var includesLegacySyncCallbacks = false;
2484 var isFlushingSyncQueue = false;
2485 function scheduleSyncCallback(callback) {
2486 // Push this callback into an internal queue. We'll flush these either in
2487 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
2488 if (syncQueue === null) {
2489 syncQueue = [callback];
2490 } else {
2491 // Push onto existing queue. Don't need to schedule a callback because
2492 // we already scheduled one when we created the queue.
2493 syncQueue.push(callback);
2494 }
2495 }
2496 function scheduleLegacySyncCallback(callback) {
2497 includesLegacySyncCallbacks = true;
2498 scheduleSyncCallback(callback);
2499 }
2500 function flushSyncCallbacksOnlyInLegacyMode() {
2501 // Only flushes the queue if there's a legacy sync callback scheduled.
2502 // TODO: There's only a single type of callback: performSyncOnWorkOnRoot. So
2503 // it might make more sense for the queue to be a list of roots instead of a
2504 // list of generic callbacks. Then we can have two: one for legacy roots, one
2505 // for concurrent roots. And this method would only flush the legacy ones.
2506 if (includesLegacySyncCallbacks) {
2507 flushSyncCallbacks();
2508 }
2509 }
2510 function flushSyncCallbacks() {
2511 if (!isFlushingSyncQueue && syncQueue !== null) {
2512 // Prevent re-entrance.
2513 isFlushingSyncQueue = true;
2514 var i = 0;
2515 var previousUpdatePriority = getCurrentUpdatePriority();
2516
2517 try {
2518 var isSync = true;
2519 var queue = syncQueue; // TODO: Is this necessary anymore? The only user code that runs in this
2520 // queue is in the render or commit phases.
2521
2522 setCurrentUpdatePriority(DiscreteEventPriority);
2523
2524 for (; i < queue.length; i++) {
2525 var callback = queue[i];
2526
2527 do {
2528 callback = callback(isSync);
2529 } while (callback !== null);
2530 }
2531
2532 syncQueue = null;
2533 includesLegacySyncCallbacks = false;
2534 } catch (error) {
2535 // If something throws, leave the remaining callbacks on the queue.
2536 if (syncQueue !== null) {
2537 syncQueue = syncQueue.slice(i + 1);
2538 } // Resume flushing in the next tick
2539
2540
2541 scheduleCallback(ImmediatePriority, flushSyncCallbacks);
2542 throw error;
2543 } finally {
2544 setCurrentUpdatePriority(previousUpdatePriority);
2545 isFlushingSyncQueue = false;
2546 }
2547 }
2548
2549 return null;
2550 }
2551
2552 // This is imported by the event replaying implementation in React DOM. It's
2553 // in a separate file to break a circular dependency between the renderer and
2554 // the reconciler.
2555 function isRootDehydrated(root) {
2556 var currentState = root.current.memoizedState;
2557 return currentState.isDehydrated;
2558 }
2559
2560 var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
2561 var NoTransition = null;
2562 function requestCurrentTransition() {
2563 return ReactCurrentBatchConfig.transition;
2564 }
2565
2566 /**
2567 * Performs equality by iterating through keys on an object and returning false
2568 * when any key has values which are not strictly equal between the arguments.
2569 * Returns true when the values of all keys are strictly equal.
2570 */
2571
2572 function shallowEqual(objA, objB) {
2573 if (objectIs(objA, objB)) {
2574 return true;
2575 }
2576
2577 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
2578 return false;
2579 }
2580
2581 var keysA = Object.keys(objA);
2582 var keysB = Object.keys(objB);
2583
2584 if (keysA.length !== keysB.length) {
2585 return false;
2586 } // Test for A's keys different from B.
2587
2588
2589 for (var i = 0; i < keysA.length; i++) {
2590 var currentKey = keysA[i];
2591
2592 if (!hasOwnProperty.call(objB, currentKey) || !objectIs(objA[currentKey], objB[currentKey])) {
2593 return false;
2594 }
2595 }
2596
2597 return true;
2598 }
2599
2600 function describeFiber(fiber) {
2601 var owner = fiber._debugOwner ? fiber._debugOwner.type : null ;
2602 var source = fiber._debugSource ;
2603
2604 switch (fiber.tag) {
2605 case HostComponent:
2606 return describeBuiltInComponentFrame(fiber.type);
2607
2608 case LazyComponent:
2609 return describeBuiltInComponentFrame('Lazy');
2610
2611 case SuspenseComponent:
2612 return describeBuiltInComponentFrame('Suspense');
2613
2614 case SuspenseListComponent:
2615 return describeBuiltInComponentFrame('SuspenseList');
2616
2617 case FunctionComponent:
2618 case IndeterminateComponent:
2619 case SimpleMemoComponent:
2620 return describeFunctionComponentFrame(fiber.type);
2621
2622 case ForwardRef:
2623 return describeFunctionComponentFrame(fiber.type.render);
2624
2625 case ClassComponent:
2626 return describeClassComponentFrame(fiber.type);
2627
2628 default:
2629 return '';
2630 }
2631 }
2632
2633 function getStackByFiberInDevAndProd(workInProgress) {
2634 try {
2635 var info = '';
2636 var node = workInProgress;
2637
2638 do {
2639 info += describeFiber(node);
2640 node = node.return;
2641 } while (node);
2642
2643 return info;
2644 } catch (x) {
2645 return '\nError generating stack: ' + x.message + '\n' + x.stack;
2646 }
2647 }
2648
2649 var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
2650 var current = null;
2651 var isRendering = false;
2652 function getCurrentFiberOwnerNameInDevOrNull() {
2653 {
2654 if (current === null) {
2655 return null;
2656 }
2657
2658 var owner = current._debugOwner;
2659
2660 if (owner !== null && typeof owner !== 'undefined') {
2661 return getComponentNameFromFiber(owner);
2662 }
2663 }
2664
2665 return null;
2666 }
2667
2668 function getCurrentFiberStackInDev() {
2669 {
2670 if (current === null) {
2671 return '';
2672 } // Safe because if current fiber exists, we are reconciling,
2673 // and it is guaranteed to be the work-in-progress version.
2674
2675
2676 return getStackByFiberInDevAndProd(current);
2677 }
2678 }
2679
2680 function resetCurrentFiber() {
2681 {
2682 ReactDebugCurrentFrame$1.getCurrentStack = null;
2683 current = null;
2684 isRendering = false;
2685 }
2686 }
2687 function setCurrentFiber(fiber) {
2688 {
2689 ReactDebugCurrentFrame$1.getCurrentStack = getCurrentFiberStackInDev;
2690 current = fiber;
2691 isRendering = false;
2692 }
2693 }
2694 function setIsRendering(rendering) {
2695 {
2696 isRendering = rendering;
2697 }
2698 }
2699
2700 var ReactStrictModeWarnings = {
2701 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
2702 flushPendingUnsafeLifecycleWarnings: function () {},
2703 recordLegacyContextWarning: function (fiber, instance) {},
2704 flushLegacyContextWarning: function () {},
2705 discardPendingWarnings: function () {}
2706 };
2707
2708 {
2709 var findStrictRoot = function (fiber) {
2710 var maybeStrictRoot = null;
2711 var node = fiber;
2712
2713 while (node !== null) {
2714 if (node.mode & StrictLegacyMode) {
2715 maybeStrictRoot = node;
2716 }
2717
2718 node = node.return;
2719 }
2720
2721 return maybeStrictRoot;
2722 };
2723
2724 var setToSortedString = function (set) {
2725 var array = [];
2726 set.forEach(function (value) {
2727 array.push(value);
2728 });
2729 return array.sort().join(', ');
2730 };
2731
2732 var pendingComponentWillMountWarnings = [];
2733 var pendingUNSAFE_ComponentWillMountWarnings = [];
2734 var pendingComponentWillReceivePropsWarnings = [];
2735 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2736 var pendingComponentWillUpdateWarnings = [];
2737 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
2738
2739 var didWarnAboutUnsafeLifecycles = new Set();
2740
2741 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
2742 // Dedupe strategy: Warn once per component.
2743 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
2744 return;
2745 }
2746
2747 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.
2748 instance.componentWillMount.__suppressDeprecationWarning !== true) {
2749 pendingComponentWillMountWarnings.push(fiber);
2750 }
2751
2752 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillMount === 'function') {
2753 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
2754 }
2755
2756 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
2757 pendingComponentWillReceivePropsWarnings.push(fiber);
2758 }
2759
2760 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
2761 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
2762 }
2763
2764 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
2765 pendingComponentWillUpdateWarnings.push(fiber);
2766 }
2767
2768 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
2769 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
2770 }
2771 };
2772
2773 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
2774 // We do an initial pass to gather component names
2775 var componentWillMountUniqueNames = new Set();
2776
2777 if (pendingComponentWillMountWarnings.length > 0) {
2778 pendingComponentWillMountWarnings.forEach(function (fiber) {
2779 componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
2780 didWarnAboutUnsafeLifecycles.add(fiber.type);
2781 });
2782 pendingComponentWillMountWarnings = [];
2783 }
2784
2785 var UNSAFE_componentWillMountUniqueNames = new Set();
2786
2787 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
2788 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
2789 UNSAFE_componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
2790 didWarnAboutUnsafeLifecycles.add(fiber.type);
2791 });
2792 pendingUNSAFE_ComponentWillMountWarnings = [];
2793 }
2794
2795 var componentWillReceivePropsUniqueNames = new Set();
2796
2797 if (pendingComponentWillReceivePropsWarnings.length > 0) {
2798 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
2799 componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
2800 didWarnAboutUnsafeLifecycles.add(fiber.type);
2801 });
2802 pendingComponentWillReceivePropsWarnings = [];
2803 }
2804
2805 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
2806
2807 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
2808 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
2809 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
2810 didWarnAboutUnsafeLifecycles.add(fiber.type);
2811 });
2812 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2813 }
2814
2815 var componentWillUpdateUniqueNames = new Set();
2816
2817 if (pendingComponentWillUpdateWarnings.length > 0) {
2818 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
2819 componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
2820 didWarnAboutUnsafeLifecycles.add(fiber.type);
2821 });
2822 pendingComponentWillUpdateWarnings = [];
2823 }
2824
2825 var UNSAFE_componentWillUpdateUniqueNames = new Set();
2826
2827 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
2828 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
2829 UNSAFE_componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
2830 didWarnAboutUnsafeLifecycles.add(fiber.type);
2831 });
2832 pendingUNSAFE_ComponentWillUpdateWarnings = [];
2833 } // Finally, we flush all the warnings
2834 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
2835
2836
2837 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
2838 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
2839
2840 error('Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '\nPlease update the following components: %s', sortedNames);
2841 }
2842
2843 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
2844 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
2845
2846 error('Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, " + 'refactor your code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://reactjs.org/link/derived-state\n' + '\nPlease update the following components: %s', _sortedNames);
2847 }
2848
2849 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
2850 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
2851
2852 error('Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '\nPlease update the following components: %s', _sortedNames2);
2853 }
2854
2855 if (componentWillMountUniqueNames.size > 0) {
2856 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
2857
2858 warn('componentWillMount has been renamed, and is not recommended for use. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress ' + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames3);
2859 }
2860
2861 if (componentWillReceivePropsUniqueNames.size > 0) {
2862 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
2863
2864 warn('componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, refactor your " + 'code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://reactjs.org/link/derived-state\n' + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames4);
2865 }
2866
2867 if (componentWillUpdateUniqueNames.size > 0) {
2868 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
2869
2870 warn('componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress ' + 'this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames5);
2871 }
2872 };
2873
2874 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
2875
2876 var didWarnAboutLegacyContext = new Set();
2877
2878 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
2879 var strictRoot = findStrictRoot(fiber);
2880
2881 if (strictRoot === null) {
2882 error('Expected to find a StrictMode component in a strict mode tree. ' + 'This error is likely caused by a bug in React. Please file an issue.');
2883
2884 return;
2885 } // Dedup strategy: Warn once per component.
2886
2887
2888 if (didWarnAboutLegacyContext.has(fiber.type)) {
2889 return;
2890 }
2891
2892 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
2893
2894 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
2895 if (warningsForRoot === undefined) {
2896 warningsForRoot = [];
2897 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
2898 }
2899
2900 warningsForRoot.push(fiber);
2901 }
2902 };
2903
2904 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
2905 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
2906 if (fiberArray.length === 0) {
2907 return;
2908 }
2909
2910 var firstFiber = fiberArray[0];
2911 var uniqueNames = new Set();
2912 fiberArray.forEach(function (fiber) {
2913 uniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
2914 didWarnAboutLegacyContext.add(fiber.type);
2915 });
2916 var sortedNames = setToSortedString(uniqueNames);
2917
2918 try {
2919 setCurrentFiber(firstFiber);
2920
2921 error('Legacy context API has been detected within a strict-mode tree.' + '\n\nThe old API will be supported in all 16.x releases, but applications ' + 'using it should migrate to the new version.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here: https://reactjs.org/link/legacy-context', sortedNames);
2922 } finally {
2923 resetCurrentFiber();
2924 }
2925 });
2926 };
2927
2928 ReactStrictModeWarnings.discardPendingWarnings = function () {
2929 pendingComponentWillMountWarnings = [];
2930 pendingUNSAFE_ComponentWillMountWarnings = [];
2931 pendingComponentWillReceivePropsWarnings = [];
2932 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2933 pendingComponentWillUpdateWarnings = [];
2934 pendingUNSAFE_ComponentWillUpdateWarnings = [];
2935 pendingLegacyContextWarning = new Map();
2936 };
2937 }
2938
2939 /*
2940 * The `'' + value` pattern (used in in perf-sensitive code) throws for Symbol
2941 * and Temporal.* types. See https://github.com/facebook/react/pull/22064.
2942 *
2943 * The functions in this module will throw an easier-to-understand,
2944 * easier-to-debug exception with a clear errors message message explaining the
2945 * problem. (Instead of a confusing exception thrown inside the implementation
2946 * of the `value` object).
2947 */
2948 // $FlowFixMe only called in DEV, so void return is not possible.
2949 function typeName(value) {
2950 {
2951 // toStringTag is needed for namespaced types like Temporal.Instant
2952 var hasToStringTag = typeof Symbol === 'function' && Symbol.toStringTag;
2953 var type = hasToStringTag && value[Symbol.toStringTag] || value.constructor.name || 'Object';
2954 return type;
2955 }
2956 } // $FlowFixMe only called in DEV, so void return is not possible.
2957
2958
2959 function willCoercionThrow(value) {
2960 {
2961 try {
2962 testStringCoercion(value);
2963 return false;
2964 } catch (e) {
2965 return true;
2966 }
2967 }
2968 }
2969
2970 function testStringCoercion(value) {
2971 // If you ended up here by following an exception call stack, here's what's
2972 // happened: you supplied an object or symbol value to React (as a prop, key,
2973 // DOM attribute, CSS property, string ref, etc.) and when React tried to
2974 // coerce it to a string using `'' + value`, an exception was thrown.
2975 //
2976 // The most common types that will cause this exception are `Symbol` instances
2977 // and Temporal objects like `Temporal.Instant`. But any object that has a
2978 // `valueOf` or `[Symbol.toPrimitive]` method that throws will also cause this
2979 // exception. (Library authors do this to prevent users from using built-in
2980 // numeric operators like `+` or comparison operators like `>=` because custom
2981 // methods are needed to perform accurate arithmetic or comparison.)
2982 //
2983 // To fix the problem, coerce this object or symbol value to a string before
2984 // passing it to React. The most reliable way is usually `String(value)`.
2985 //
2986 // To find which value is throwing, check the browser or debugger console.
2987 // Before this exception was thrown, there should be `console.error` output
2988 // that shows the type (Symbol, Temporal.PlainDate, etc.) that caused the
2989 // problem and how that type was used: key, atrribute, input value prop, etc.
2990 // In most cases, this console output also shows the component and its
2991 // ancestor components where the exception happened.
2992 //
2993 // eslint-disable-next-line react-internal/safe-string-coercion
2994 return '' + value;
2995 }
2996 function checkPropStringCoercion(value, propName) {
2997 {
2998 if (willCoercionThrow(value)) {
2999 error('The provided `%s` prop is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', propName, typeName(value));
3000
3001 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
3002 }
3003 }
3004 }
3005
3006 function resolveDefaultProps(Component, baseProps) {
3007 if (Component && Component.defaultProps) {
3008 // Resolve default props. Taken from ReactElement
3009 var props = assign({}, baseProps);
3010 var defaultProps = Component.defaultProps;
3011
3012 for (var propName in defaultProps) {
3013 if (props[propName] === undefined) {
3014 props[propName] = defaultProps[propName];
3015 }
3016 }
3017
3018 return props;
3019 }
3020
3021 return baseProps;
3022 }
3023
3024 var valueCursor = createCursor(null);
3025 var rendererSigil;
3026
3027 {
3028 // Use this to detect multiple renderers using the same context
3029 rendererSigil = {};
3030 }
3031
3032 var currentlyRenderingFiber = null;
3033 var lastContextDependency = null;
3034 var lastFullyObservedContext = null;
3035 var isDisallowedContextReadInDEV = false;
3036 function resetContextDependencies() {
3037 // This is called right before React yields execution, to ensure `readContext`
3038 // cannot be called outside the render phase.
3039 currentlyRenderingFiber = null;
3040 lastContextDependency = null;
3041 lastFullyObservedContext = null;
3042
3043 {
3044 isDisallowedContextReadInDEV = false;
3045 }
3046 }
3047 function enterDisallowedContextReadInDEV() {
3048 {
3049 isDisallowedContextReadInDEV = true;
3050 }
3051 }
3052 function exitDisallowedContextReadInDEV() {
3053 {
3054 isDisallowedContextReadInDEV = false;
3055 }
3056 }
3057 function pushProvider(providerFiber, context, nextValue) {
3058 {
3059 push(valueCursor, context._currentValue2, providerFiber);
3060 context._currentValue2 = nextValue;
3061
3062 {
3063 if (context._currentRenderer2 !== undefined && context._currentRenderer2 !== null && context._currentRenderer2 !== rendererSigil) {
3064 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.');
3065 }
3066
3067 context._currentRenderer2 = rendererSigil;
3068 }
3069 }
3070 }
3071 function popProvider(context, providerFiber) {
3072 var currentValue = valueCursor.current;
3073 pop(valueCursor, providerFiber);
3074
3075 {
3076 {
3077 context._currentValue2 = currentValue;
3078 }
3079 }
3080 }
3081 function scheduleContextWorkOnParentPath(parent, renderLanes, propagationRoot) {
3082 // Update the child lanes of all the ancestors, including the alternates.
3083 var node = parent;
3084
3085 while (node !== null) {
3086 var alternate = node.alternate;
3087
3088 if (!isSubsetOfLanes(node.childLanes, renderLanes)) {
3089 node.childLanes = mergeLanes(node.childLanes, renderLanes);
3090
3091 if (alternate !== null) {
3092 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
3093 }
3094 } else if (alternate !== null && !isSubsetOfLanes(alternate.childLanes, renderLanes)) {
3095 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
3096 }
3097
3098 if (node === propagationRoot) {
3099 break;
3100 }
3101
3102 node = node.return;
3103 }
3104
3105 {
3106 if (node !== propagationRoot) {
3107 error('Expected to find the propagation root when scheduling context work. ' + 'This error is likely caused by a bug in React. Please file an issue.');
3108 }
3109 }
3110 }
3111 function propagateContextChange(workInProgress, context, renderLanes) {
3112 {
3113 propagateContextChange_eager(workInProgress, context, renderLanes);
3114 }
3115 }
3116
3117 function propagateContextChange_eager(workInProgress, context, renderLanes) {
3118
3119 var fiber = workInProgress.child;
3120
3121 if (fiber !== null) {
3122 // Set the return pointer of the child to the work-in-progress fiber.
3123 fiber.return = workInProgress;
3124 }
3125
3126 while (fiber !== null) {
3127 var nextFiber = void 0; // Visit this fiber.
3128
3129 var list = fiber.dependencies;
3130
3131 if (list !== null) {
3132 nextFiber = fiber.child;
3133 var dependency = list.firstContext;
3134
3135 while (dependency !== null) {
3136 // Check if the context matches.
3137 if (dependency.context === context) {
3138 // Match! Schedule an update on this fiber.
3139 if (fiber.tag === ClassComponent) {
3140 // Schedule a force update on the work-in-progress.
3141 var lane = pickArbitraryLane(renderLanes);
3142 var update = createUpdate(NoTimestamp, lane);
3143 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
3144 // update to the current fiber, too, which means it will persist even if
3145 // this render is thrown away. Since it's a race condition, not sure it's
3146 // worth fixing.
3147 // Inlined `enqueueUpdate` to remove interleaved update check
3148
3149 var updateQueue = fiber.updateQueue;
3150
3151 if (updateQueue === null) ; else {
3152 var sharedQueue = updateQueue.shared;
3153 var pending = sharedQueue.pending;
3154
3155 if (pending === null) {
3156 // This is the first update. Create a circular list.
3157 update.next = update;
3158 } else {
3159 update.next = pending.next;
3160 pending.next = update;
3161 }
3162
3163 sharedQueue.pending = update;
3164 }
3165 }
3166
3167 fiber.lanes = mergeLanes(fiber.lanes, renderLanes);
3168 var alternate = fiber.alternate;
3169
3170 if (alternate !== null) {
3171 alternate.lanes = mergeLanes(alternate.lanes, renderLanes);
3172 }
3173
3174 scheduleContextWorkOnParentPath(fiber.return, renderLanes, workInProgress); // Mark the updated lanes on the list, too.
3175
3176 list.lanes = mergeLanes(list.lanes, renderLanes); // Since we already found a match, we can stop traversing the
3177 // dependency list.
3178
3179 break;
3180 }
3181
3182 dependency = dependency.next;
3183 }
3184 } else if (fiber.tag === ContextProvider) {
3185 // Don't scan deeper if this is a matching provider
3186 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
3187 } else {
3188 // Traverse down.
3189 nextFiber = fiber.child;
3190 }
3191
3192 if (nextFiber !== null) {
3193 // Set the return pointer of the child to the work-in-progress fiber.
3194 nextFiber.return = fiber;
3195 } else {
3196 // No child. Traverse to next sibling.
3197 nextFiber = fiber;
3198
3199 while (nextFiber !== null) {
3200 if (nextFiber === workInProgress) {
3201 // We're back to the root of this subtree. Exit.
3202 nextFiber = null;
3203 break;
3204 }
3205
3206 var sibling = nextFiber.sibling;
3207
3208 if (sibling !== null) {
3209 // Set the return pointer of the sibling to the work-in-progress fiber.
3210 sibling.return = nextFiber.return;
3211 nextFiber = sibling;
3212 break;
3213 } // No more siblings. Traverse up.
3214
3215
3216 nextFiber = nextFiber.return;
3217 }
3218 }
3219
3220 fiber = nextFiber;
3221 }
3222 }
3223 function prepareToReadContext(workInProgress, renderLanes) {
3224 currentlyRenderingFiber = workInProgress;
3225 lastContextDependency = null;
3226 lastFullyObservedContext = null;
3227 var dependencies = workInProgress.dependencies;
3228
3229 if (dependencies !== null) {
3230 {
3231 var firstContext = dependencies.firstContext;
3232
3233 if (firstContext !== null) {
3234 if (includesSomeLane(dependencies.lanes, renderLanes)) {
3235 // Context list has a pending update. Mark that this fiber performed work.
3236 markWorkInProgressReceivedUpdate();
3237 } // Reset the work-in-progress list
3238
3239
3240 dependencies.firstContext = null;
3241 }
3242 }
3243 }
3244 }
3245 function readContext(context) {
3246 {
3247 // This warning would fire if you read context inside a Hook like useMemo.
3248 // Unlike the class check below, it's not enforced in production for perf.
3249 if (isDisallowedContextReadInDEV) {
3250 error('Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().');
3251 }
3252 }
3253
3254 var value = context._currentValue2;
3255
3256 if (lastFullyObservedContext === context) ; else {
3257 var contextItem = {
3258 context: context,
3259 memoizedValue: value,
3260 next: null
3261 };
3262
3263 if (lastContextDependency === null) {
3264 if (currentlyRenderingFiber === null) {
3265 throw new Error('Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().');
3266 } // This is the first dependency for this component. Create a new list.
3267
3268
3269 lastContextDependency = contextItem;
3270 currentlyRenderingFiber.dependencies = {
3271 lanes: NoLanes,
3272 firstContext: contextItem
3273 };
3274 } else {
3275 // Append a new context item.
3276 lastContextDependency = lastContextDependency.next = contextItem;
3277 }
3278 }
3279
3280 return value;
3281 }
3282
3283 // An array of all update queues that received updates during the current
3284 // render. When this render exits, either because it finishes or because it is
3285 // interrupted, the interleaved updates will be transferred onto the main part
3286 // of the queue.
3287 var interleavedQueues = null;
3288 function pushInterleavedQueue(queue) {
3289 if (interleavedQueues === null) {
3290 interleavedQueues = [queue];
3291 } else {
3292 interleavedQueues.push(queue);
3293 }
3294 }
3295 function enqueueInterleavedUpdates() {
3296 // Transfer the interleaved updates onto the main queue. Each queue has a
3297 // `pending` field and an `interleaved` field. When they are not null, they
3298 // point to the last node in a circular linked list. We need to append the
3299 // interleaved list to the end of the pending list by joining them into a
3300 // single, circular list.
3301 if (interleavedQueues !== null) {
3302 for (var i = 0; i < interleavedQueues.length; i++) {
3303 var queue = interleavedQueues[i];
3304 var lastInterleavedUpdate = queue.interleaved;
3305
3306 if (lastInterleavedUpdate !== null) {
3307 queue.interleaved = null;
3308 var firstInterleavedUpdate = lastInterleavedUpdate.next;
3309 var lastPendingUpdate = queue.pending;
3310
3311 if (lastPendingUpdate !== null) {
3312 var firstPendingUpdate = lastPendingUpdate.next;
3313 lastPendingUpdate.next = firstInterleavedUpdate;
3314 lastInterleavedUpdate.next = firstPendingUpdate;
3315 }
3316
3317 queue.pending = lastInterleavedUpdate;
3318 }
3319 }
3320
3321 interleavedQueues = null;
3322 }
3323 }
3324
3325 var UpdateState = 0;
3326 var ReplaceState = 1;
3327 var ForceUpdate = 2;
3328 var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
3329 // It should only be read right after calling `processUpdateQueue`, via
3330 // `checkHasForceUpdateAfterProcessing`.
3331
3332 var hasForceUpdate = false;
3333 var didWarnUpdateInsideUpdate;
3334 var currentlyProcessingQueue;
3335
3336 {
3337 didWarnUpdateInsideUpdate = false;
3338 currentlyProcessingQueue = null;
3339 }
3340
3341 function initializeUpdateQueue(fiber) {
3342 var queue = {
3343 baseState: fiber.memoizedState,
3344 firstBaseUpdate: null,
3345 lastBaseUpdate: null,
3346 shared: {
3347 pending: null,
3348 interleaved: null,
3349 lanes: NoLanes
3350 },
3351 effects: null
3352 };
3353 fiber.updateQueue = queue;
3354 }
3355 function cloneUpdateQueue(current, workInProgress) {
3356 // Clone the update queue from current. Unless it's already a clone.
3357 var queue = workInProgress.updateQueue;
3358 var currentQueue = current.updateQueue;
3359
3360 if (queue === currentQueue) {
3361 var clone = {
3362 baseState: currentQueue.baseState,
3363 firstBaseUpdate: currentQueue.firstBaseUpdate,
3364 lastBaseUpdate: currentQueue.lastBaseUpdate,
3365 shared: currentQueue.shared,
3366 effects: currentQueue.effects
3367 };
3368 workInProgress.updateQueue = clone;
3369 }
3370 }
3371 function createUpdate(eventTime, lane) {
3372 var update = {
3373 eventTime: eventTime,
3374 lane: lane,
3375 tag: UpdateState,
3376 payload: null,
3377 callback: null,
3378 next: null
3379 };
3380 return update;
3381 }
3382 function enqueueUpdate(fiber, update, lane) {
3383 var updateQueue = fiber.updateQueue;
3384
3385 if (updateQueue === null) {
3386 // Only occurs if the fiber has been unmounted.
3387 return;
3388 }
3389
3390 var sharedQueue = updateQueue.shared;
3391
3392 if (isInterleavedUpdate(fiber)) {
3393 var interleaved = sharedQueue.interleaved;
3394
3395 if (interleaved === null) {
3396 // This is the first update. Create a circular list.
3397 update.next = update; // At the end of the current render, this queue's interleaved updates will
3398 // be transferred to the pending queue.
3399
3400 pushInterleavedQueue(sharedQueue);
3401 } else {
3402 update.next = interleaved.next;
3403 interleaved.next = update;
3404 }
3405
3406 sharedQueue.interleaved = update;
3407 } else {
3408 var pending = sharedQueue.pending;
3409
3410 if (pending === null) {
3411 // This is the first update. Create a circular list.
3412 update.next = update;
3413 } else {
3414 update.next = pending.next;
3415 pending.next = update;
3416 }
3417
3418 sharedQueue.pending = update;
3419 }
3420
3421 {
3422 if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) {
3423 error('An update (setState, replaceState, or forceUpdate) was scheduled ' + 'from inside an update function. Update functions should be pure, ' + 'with zero side-effects. Consider using componentDidUpdate or a ' + 'callback.');
3424
3425 didWarnUpdateInsideUpdate = true;
3426 }
3427 }
3428 }
3429 function entangleTransitions(root, fiber, lane) {
3430 var updateQueue = fiber.updateQueue;
3431
3432 if (updateQueue === null) {
3433 // Only occurs if the fiber has been unmounted.
3434 return;
3435 }
3436
3437 var sharedQueue = updateQueue.shared;
3438
3439 if (isTransitionLane(lane)) {
3440 var queueLanes = sharedQueue.lanes; // If any entangled lanes are no longer pending on the root, then they must
3441 // have finished. We can remove them from the shared queue, which represents
3442 // a superset of the actually pending lanes. In some cases we may entangle
3443 // more than we need to, but that's OK. In fact it's worse if we *don't*
3444 // entangle when we should.
3445
3446 queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes.
3447
3448 var newQueueLanes = mergeLanes(queueLanes, lane);
3449 sharedQueue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if
3450 // the lane finished since the last time we entangled it. So we need to
3451 // entangle it again, just to be sure.
3452
3453 markRootEntangled(root, newQueueLanes);
3454 }
3455 }
3456 function enqueueCapturedUpdate(workInProgress, capturedUpdate) {
3457 // Captured updates are updates that are thrown by a child during the render
3458 // phase. They should be discarded if the render is aborted. Therefore,
3459 // we should only put them on the work-in-progress queue, not the current one.
3460 var queue = workInProgress.updateQueue; // Check if the work-in-progress queue is a clone.
3461
3462 var current = workInProgress.alternate;
3463
3464 if (current !== null) {
3465 var currentQueue = current.updateQueue;
3466
3467 if (queue === currentQueue) {
3468 // The work-in-progress queue is the same as current. This happens when
3469 // we bail out on a parent fiber that then captures an error thrown by
3470 // a child. Since we want to append the update only to the work-in
3471 // -progress queue, we need to clone the updates. We usually clone during
3472 // processUpdateQueue, but that didn't happen in this case because we
3473 // skipped over the parent when we bailed out.
3474 var newFirst = null;
3475 var newLast = null;
3476 var firstBaseUpdate = queue.firstBaseUpdate;
3477
3478 if (firstBaseUpdate !== null) {
3479 // Loop through the updates and clone them.
3480 var update = firstBaseUpdate;
3481
3482 do {
3483 var clone = {
3484 eventTime: update.eventTime,
3485 lane: update.lane,
3486 tag: update.tag,
3487 payload: update.payload,
3488 callback: update.callback,
3489 next: null
3490 };
3491
3492 if (newLast === null) {
3493 newFirst = newLast = clone;
3494 } else {
3495 newLast.next = clone;
3496 newLast = clone;
3497 }
3498
3499 update = update.next;
3500 } while (update !== null); // Append the captured update the end of the cloned list.
3501
3502
3503 if (newLast === null) {
3504 newFirst = newLast = capturedUpdate;
3505 } else {
3506 newLast.next = capturedUpdate;
3507 newLast = capturedUpdate;
3508 }
3509 } else {
3510 // There are no base updates.
3511 newFirst = newLast = capturedUpdate;
3512 }
3513
3514 queue = {
3515 baseState: currentQueue.baseState,
3516 firstBaseUpdate: newFirst,
3517 lastBaseUpdate: newLast,
3518 shared: currentQueue.shared,
3519 effects: currentQueue.effects
3520 };
3521 workInProgress.updateQueue = queue;
3522 return;
3523 }
3524 } // Append the update to the end of the list.
3525
3526
3527 var lastBaseUpdate = queue.lastBaseUpdate;
3528
3529 if (lastBaseUpdate === null) {
3530 queue.firstBaseUpdate = capturedUpdate;
3531 } else {
3532 lastBaseUpdate.next = capturedUpdate;
3533 }
3534
3535 queue.lastBaseUpdate = capturedUpdate;
3536 }
3537
3538 function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
3539 switch (update.tag) {
3540 case ReplaceState:
3541 {
3542 var payload = update.payload;
3543
3544 if (typeof payload === 'function') {
3545 // Updater function
3546 {
3547 enterDisallowedContextReadInDEV();
3548 }
3549
3550 var nextState = payload.call(instance, prevState, nextProps);
3551
3552 {
3553
3554 exitDisallowedContextReadInDEV();
3555 }
3556
3557 return nextState;
3558 } // State object
3559
3560
3561 return payload;
3562 }
3563
3564 case CaptureUpdate:
3565 {
3566 workInProgress.flags = workInProgress.flags & ~ShouldCapture | DidCapture;
3567 }
3568 // Intentional fallthrough
3569
3570 case UpdateState:
3571 {
3572 var _payload = update.payload;
3573 var partialState;
3574
3575 if (typeof _payload === 'function') {
3576 // Updater function
3577 {
3578 enterDisallowedContextReadInDEV();
3579 }
3580
3581 partialState = _payload.call(instance, prevState, nextProps);
3582
3583 {
3584
3585 exitDisallowedContextReadInDEV();
3586 }
3587 } else {
3588 // Partial state object
3589 partialState = _payload;
3590 }
3591
3592 if (partialState === null || partialState === undefined) {
3593 // Null and undefined are treated as no-ops.
3594 return prevState;
3595 } // Merge the partial state and the previous state.
3596
3597
3598 return assign({}, prevState, partialState);
3599 }
3600
3601 case ForceUpdate:
3602 {
3603 hasForceUpdate = true;
3604 return prevState;
3605 }
3606 }
3607
3608 return prevState;
3609 }
3610
3611 function processUpdateQueue(workInProgress, props, instance, renderLanes) {
3612 // This is always non-null on a ClassComponent or HostRoot
3613 var queue = workInProgress.updateQueue;
3614 hasForceUpdate = false;
3615
3616 {
3617 currentlyProcessingQueue = queue.shared;
3618 }
3619
3620 var firstBaseUpdate = queue.firstBaseUpdate;
3621 var lastBaseUpdate = queue.lastBaseUpdate; // Check if there are pending updates. If so, transfer them to the base queue.
3622
3623 var pendingQueue = queue.shared.pending;
3624
3625 if (pendingQueue !== null) {
3626 queue.shared.pending = null; // The pending queue is circular. Disconnect the pointer between first
3627 // and last so that it's non-circular.
3628
3629 var lastPendingUpdate = pendingQueue;
3630 var firstPendingUpdate = lastPendingUpdate.next;
3631 lastPendingUpdate.next = null; // Append pending updates to base queue
3632
3633 if (lastBaseUpdate === null) {
3634 firstBaseUpdate = firstPendingUpdate;
3635 } else {
3636 lastBaseUpdate.next = firstPendingUpdate;
3637 }
3638
3639 lastBaseUpdate = lastPendingUpdate; // If there's a current queue, and it's different from the base queue, then
3640 // we need to transfer the updates to that queue, too. Because the base
3641 // queue is a singly-linked list with no cycles, we can append to both
3642 // lists and take advantage of structural sharing.
3643 // TODO: Pass `current` as argument
3644
3645 var current = workInProgress.alternate;
3646
3647 if (current !== null) {
3648 // This is always non-null on a ClassComponent or HostRoot
3649 var currentQueue = current.updateQueue;
3650 var currentLastBaseUpdate = currentQueue.lastBaseUpdate;
3651
3652 if (currentLastBaseUpdate !== lastBaseUpdate) {
3653 if (currentLastBaseUpdate === null) {
3654 currentQueue.firstBaseUpdate = firstPendingUpdate;
3655 } else {
3656 currentLastBaseUpdate.next = firstPendingUpdate;
3657 }
3658
3659 currentQueue.lastBaseUpdate = lastPendingUpdate;
3660 }
3661 }
3662 } // These values may change as we process the queue.
3663
3664
3665 if (firstBaseUpdate !== null) {
3666 // Iterate through the list of updates to compute the result.
3667 var newState = queue.baseState; // TODO: Don't need to accumulate this. Instead, we can remove renderLanes
3668 // from the original lanes.
3669
3670 var newLanes = NoLanes;
3671 var newBaseState = null;
3672 var newFirstBaseUpdate = null;
3673 var newLastBaseUpdate = null;
3674 var update = firstBaseUpdate;
3675
3676 do {
3677 var updateLane = update.lane;
3678 var updateEventTime = update.eventTime;
3679
3680 if (!isSubsetOfLanes(renderLanes, updateLane)) {
3681 // Priority is insufficient. Skip this update. If this is the first
3682 // skipped update, the previous update/state is the new base
3683 // update/state.
3684 var clone = {
3685 eventTime: updateEventTime,
3686 lane: updateLane,
3687 tag: update.tag,
3688 payload: update.payload,
3689 callback: update.callback,
3690 next: null
3691 };
3692
3693 if (newLastBaseUpdate === null) {
3694 newFirstBaseUpdate = newLastBaseUpdate = clone;
3695 newBaseState = newState;
3696 } else {
3697 newLastBaseUpdate = newLastBaseUpdate.next = clone;
3698 } // Update the remaining priority in the queue.
3699
3700
3701 newLanes = mergeLanes(newLanes, updateLane);
3702 } else {
3703 // This update does have sufficient priority.
3704 if (newLastBaseUpdate !== null) {
3705 var _clone = {
3706 eventTime: updateEventTime,
3707 // This update is going to be committed so we never want uncommit
3708 // it. Using NoLane works because 0 is a subset of all bitmasks, so
3709 // this will never be skipped by the check above.
3710 lane: NoLane,
3711 tag: update.tag,
3712 payload: update.payload,
3713 callback: update.callback,
3714 next: null
3715 };
3716 newLastBaseUpdate = newLastBaseUpdate.next = _clone;
3717 } // Process this update.
3718
3719
3720 newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance);
3721 var callback = update.callback;
3722
3723 if (callback !== null && // If the update was already committed, we should not queue its
3724 // callback again.
3725 update.lane !== NoLane) {
3726 workInProgress.flags |= Callback;
3727 var effects = queue.effects;
3728
3729 if (effects === null) {
3730 queue.effects = [update];
3731 } else {
3732 effects.push(update);
3733 }
3734 }
3735 }
3736
3737 update = update.next;
3738
3739 if (update === null) {
3740 pendingQueue = queue.shared.pending;
3741
3742 if (pendingQueue === null) {
3743 break;
3744 } else {
3745 // An update was scheduled from inside a reducer. Add the new
3746 // pending updates to the end of the list and keep processing.
3747 var _lastPendingUpdate = pendingQueue; // Intentionally unsound. Pending updates form a circular list, but we
3748 // unravel them when transferring them to the base queue.
3749
3750 var _firstPendingUpdate = _lastPendingUpdate.next;
3751 _lastPendingUpdate.next = null;
3752 update = _firstPendingUpdate;
3753 queue.lastBaseUpdate = _lastPendingUpdate;
3754 queue.shared.pending = null;
3755 }
3756 }
3757 } while (true);
3758
3759 if (newLastBaseUpdate === null) {
3760 newBaseState = newState;
3761 }
3762
3763 queue.baseState = newBaseState;
3764 queue.firstBaseUpdate = newFirstBaseUpdate;
3765 queue.lastBaseUpdate = newLastBaseUpdate; // Interleaved updates are stored on a separate queue. We aren't going to
3766 // process them during this render, but we do need to track which lanes
3767 // are remaining.
3768
3769 var lastInterleaved = queue.shared.interleaved;
3770
3771 if (lastInterleaved !== null) {
3772 var interleaved = lastInterleaved;
3773
3774 do {
3775 newLanes = mergeLanes(newLanes, interleaved.lane);
3776 interleaved = interleaved.next;
3777 } while (interleaved !== lastInterleaved);
3778 } else if (firstBaseUpdate === null) {
3779 // `queue.lanes` is used for entangling transitions. We can set it back to
3780 // zero once the queue is empty.
3781 queue.shared.lanes = NoLanes;
3782 } // Set the remaining expiration time to be whatever is remaining in the queue.
3783 // This should be fine because the only two other things that contribute to
3784 // expiration time are props and context. We're already in the middle of the
3785 // begin phase by the time we start processing the queue, so we've already
3786 // dealt with the props. Context in components that specify
3787 // shouldComponentUpdate is tricky; but we'll have to account for
3788 // that regardless.
3789
3790
3791 markSkippedUpdateLanes(newLanes);
3792 workInProgress.lanes = newLanes;
3793 workInProgress.memoizedState = newState;
3794 }
3795
3796 {
3797 currentlyProcessingQueue = null;
3798 }
3799 }
3800
3801 function callCallback(callback, context) {
3802 if (typeof callback !== 'function') {
3803 throw new Error('Invalid argument passed as callback. Expected a function. Instead ' + ("received: " + callback));
3804 }
3805
3806 callback.call(context);
3807 }
3808
3809 function resetHasForceUpdateBeforeProcessing() {
3810 hasForceUpdate = false;
3811 }
3812 function checkHasForceUpdateAfterProcessing() {
3813 return hasForceUpdate;
3814 }
3815 function commitUpdateQueue(finishedWork, finishedQueue, instance) {
3816 // Commit the effects
3817 var effects = finishedQueue.effects;
3818 finishedQueue.effects = null;
3819
3820 if (effects !== null) {
3821 for (var i = 0; i < effects.length; i++) {
3822 var effect = effects[i];
3823 var callback = effect.callback;
3824
3825 if (callback !== null) {
3826 effect.callback = null;
3827 callCallback(callback, instance);
3828 }
3829 }
3830 }
3831 }
3832
3833 var fakeInternalInstance = {}; // React.Component uses a shared frozen object by default.
3834 // We'll use it to determine whether we need to initialize legacy refs.
3835
3836 var emptyRefsObject = new React.Component().refs;
3837 var didWarnAboutStateAssignmentForComponent;
3838 var didWarnAboutUninitializedState;
3839 var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
3840 var didWarnAboutLegacyLifecyclesAndDerivedState;
3841 var didWarnAboutUndefinedDerivedState;
3842 var warnOnUndefinedDerivedState;
3843 var warnOnInvalidCallback;
3844 var didWarnAboutDirectlyAssigningPropsToState;
3845 var didWarnAboutContextTypeAndContextTypes;
3846 var didWarnAboutInvalidateContextType;
3847
3848 {
3849 didWarnAboutStateAssignmentForComponent = new Set();
3850 didWarnAboutUninitializedState = new Set();
3851 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
3852 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
3853 didWarnAboutDirectlyAssigningPropsToState = new Set();
3854 didWarnAboutUndefinedDerivedState = new Set();
3855 didWarnAboutContextTypeAndContextTypes = new Set();
3856 didWarnAboutInvalidateContextType = new Set();
3857 var didWarnOnInvalidCallback = new Set();
3858
3859 warnOnInvalidCallback = function (callback, callerName) {
3860 if (callback === null || typeof callback === 'function') {
3861 return;
3862 }
3863
3864 var key = callerName + '_' + callback;
3865
3866 if (!didWarnOnInvalidCallback.has(key)) {
3867 didWarnOnInvalidCallback.add(key);
3868
3869 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
3870 }
3871 };
3872
3873 warnOnUndefinedDerivedState = function (type, partialState) {
3874 if (partialState === undefined) {
3875 var componentName = getComponentNameFromType(type) || 'Component';
3876
3877 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
3878 didWarnAboutUndefinedDerivedState.add(componentName);
3879
3880 error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
3881 }
3882 }
3883 }; // This is so gross but it's at least non-critical and can be removed if
3884 // it causes problems. This is meant to give a nicer error message for
3885 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
3886 // ...)) which otherwise throws a "_processChildContext is not a function"
3887 // exception.
3888
3889
3890 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
3891 enumerable: false,
3892 value: function () {
3893 throw new Error('_processChildContext is not available in React 16+. This likely ' + 'means you have multiple copies of React and are attempting to nest ' + 'a React 15 tree inside a React 16 tree using ' + "unstable_renderSubtreeIntoContainer, which isn't supported. Try " + 'to make sure you have only one copy of React (and ideally, switch ' + 'to ReactDOM.createPortal).');
3894 }
3895 });
3896 Object.freeze(fakeInternalInstance);
3897 }
3898
3899 function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
3900 var prevState = workInProgress.memoizedState;
3901 var partialState = getDerivedStateFromProps(nextProps, prevState);
3902
3903 {
3904
3905 warnOnUndefinedDerivedState(ctor, partialState);
3906 } // Merge the partial state and the previous state.
3907
3908
3909 var memoizedState = partialState === null || partialState === undefined ? prevState : assign({}, prevState, partialState);
3910 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
3911 // base state.
3912
3913 if (workInProgress.lanes === NoLanes) {
3914 // Queue is always non-null for classes
3915 var updateQueue = workInProgress.updateQueue;
3916 updateQueue.baseState = memoizedState;
3917 }
3918 }
3919
3920 var classComponentUpdater = {
3921 isMounted: isMounted,
3922 enqueueSetState: function (inst, payload, callback) {
3923 var fiber = get(inst);
3924 var eventTime = requestEventTime();
3925 var lane = requestUpdateLane(fiber);
3926 var update = createUpdate(eventTime, lane);
3927 update.payload = payload;
3928
3929 if (callback !== undefined && callback !== null) {
3930 {
3931 warnOnInvalidCallback(callback, 'setState');
3932 }
3933
3934 update.callback = callback;
3935 }
3936
3937 enqueueUpdate(fiber, update);
3938 var root = scheduleUpdateOnFiber(fiber, lane, eventTime);
3939
3940 if (root !== null) {
3941 entangleTransitions(root, fiber, lane);
3942 }
3943 },
3944 enqueueReplaceState: function (inst, payload, callback) {
3945 var fiber = get(inst);
3946 var eventTime = requestEventTime();
3947 var lane = requestUpdateLane(fiber);
3948 var update = createUpdate(eventTime, lane);
3949 update.tag = ReplaceState;
3950 update.payload = payload;
3951
3952 if (callback !== undefined && callback !== null) {
3953 {
3954 warnOnInvalidCallback(callback, 'replaceState');
3955 }
3956
3957 update.callback = callback;
3958 }
3959
3960 enqueueUpdate(fiber, update);
3961 var root = scheduleUpdateOnFiber(fiber, lane, eventTime);
3962
3963 if (root !== null) {
3964 entangleTransitions(root, fiber, lane);
3965 }
3966 },
3967 enqueueForceUpdate: function (inst, callback) {
3968 var fiber = get(inst);
3969 var eventTime = requestEventTime();
3970 var lane = requestUpdateLane(fiber);
3971 var update = createUpdate(eventTime, lane);
3972 update.tag = ForceUpdate;
3973
3974 if (callback !== undefined && callback !== null) {
3975 {
3976 warnOnInvalidCallback(callback, 'forceUpdate');
3977 }
3978
3979 update.callback = callback;
3980 }
3981
3982 enqueueUpdate(fiber, update);
3983 var root = scheduleUpdateOnFiber(fiber, lane, eventTime);
3984
3985 if (root !== null) {
3986 entangleTransitions(root, fiber, lane);
3987 }
3988 }
3989 };
3990
3991 function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
3992 var instance = workInProgress.stateNode;
3993
3994 if (typeof instance.shouldComponentUpdate === 'function') {
3995 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
3996
3997 {
3998
3999 if (shouldUpdate === undefined) {
4000 error('%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentNameFromType(ctor) || 'Component');
4001 }
4002 }
4003
4004 return shouldUpdate;
4005 }
4006
4007 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
4008 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
4009 }
4010
4011 return true;
4012 }
4013
4014 function checkClassInstance(workInProgress, ctor, newProps) {
4015 var instance = workInProgress.stateNode;
4016
4017 {
4018 var name = getComponentNameFromType(ctor) || 'Component';
4019 var renderPresent = instance.render;
4020
4021 if (!renderPresent) {
4022 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
4023 error('%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
4024 } else {
4025 error('%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
4026 }
4027 }
4028
4029 if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) {
4030 error('getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', name);
4031 }
4032
4033 if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) {
4034 error('getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', name);
4035 }
4036
4037 if (instance.propTypes) {
4038 error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
4039 }
4040
4041 if (instance.contextType) {
4042 error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name);
4043 }
4044
4045 {
4046 if (instance.contextTypes) {
4047 error('contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
4048 }
4049
4050 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
4051 didWarnAboutContextTypeAndContextTypes.add(ctor);
4052
4053 error('%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
4054 }
4055 }
4056
4057 if (typeof instance.componentShouldUpdate === 'function') {
4058 error('%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', name);
4059 }
4060
4061 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
4062 error('%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentNameFromType(ctor) || 'A pure component');
4063 }
4064
4065 if (typeof instance.componentDidUnmount === 'function') {
4066 error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
4067 }
4068
4069 if (typeof instance.componentDidReceiveProps === 'function') {
4070 error('%s has a method called ' + 'componentDidReceiveProps(). But there is no such lifecycle method. ' + 'If you meant to update the state in response to changing props, ' + 'use componentWillReceiveProps(). If you meant to fetch data or ' + 'run side-effects or mutations after React has updated the UI, use componentDidUpdate().', name);
4071 }
4072
4073 if (typeof instance.componentWillRecieveProps === 'function') {
4074 error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
4075 }
4076
4077 if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') {
4078 error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);
4079 }
4080
4081 var hasMutatedProps = instance.props !== newProps;
4082
4083 if (instance.props !== undefined && hasMutatedProps) {
4084 error('%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name);
4085 }
4086
4087 if (instance.defaultProps) {
4088 error('Setting defaultProps as an instance property on %s is not supported and will be ignored.' + ' Instead, define defaultProps as a static property on %s.', name, name);
4089 }
4090
4091 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
4092 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
4093
4094 error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentNameFromType(ctor));
4095 }
4096
4097 if (typeof instance.getDerivedStateFromProps === 'function') {
4098 error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
4099 }
4100
4101 if (typeof instance.getDerivedStateFromError === 'function') {
4102 error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
4103 }
4104
4105 if (typeof ctor.getSnapshotBeforeUpdate === 'function') {
4106 error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name);
4107 }
4108
4109 var _state = instance.state;
4110
4111 if (_state && (typeof _state !== 'object' || isArray(_state))) {
4112 error('%s.state: must be set to an object or null', name);
4113 }
4114
4115 if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') {
4116 error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name);
4117 }
4118 }
4119 }
4120
4121 function adoptClassInstance(workInProgress, instance) {
4122 instance.updater = classComponentUpdater;
4123 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
4124
4125 set(instance, workInProgress);
4126
4127 {
4128 instance._reactInternalInstance = fakeInternalInstance;
4129 }
4130 }
4131
4132 function constructClassInstance(workInProgress, ctor, props) {
4133 var isLegacyContextConsumer = false;
4134 var unmaskedContext = emptyContextObject;
4135 var context = emptyContextObject;
4136 var contextType = ctor.contextType;
4137
4138 {
4139 if ('contextType' in ctor) {
4140 var isValid = // Allow null for conditional declaration
4141 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
4142
4143 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
4144 didWarnAboutInvalidateContextType.add(ctor);
4145 var addendum = '';
4146
4147 if (contextType === undefined) {
4148 addendum = ' However, it is set to undefined. ' + 'This can be caused by a typo or by mixing up named and default imports. ' + 'This can also happen due to a circular dependency, so ' + 'try moving the createContext() call to a separate file.';
4149 } else if (typeof contextType !== 'object') {
4150 addendum = ' However, it is set to a ' + typeof contextType + '.';
4151 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
4152 addendum = ' Did you accidentally pass the Context.Provider instead?';
4153 } else if (contextType._context !== undefined) {
4154 // <Context.Consumer>
4155 addendum = ' Did you accidentally pass the Context.Consumer instead?';
4156 } else {
4157 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
4158 }
4159
4160 error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentNameFromType(ctor) || 'Component', addendum);
4161 }
4162 }
4163 }
4164
4165 if (typeof contextType === 'object' && contextType !== null) {
4166 context = readContext(contextType);
4167 } else {
4168 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4169 var contextTypes = ctor.contextTypes;
4170 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
4171 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
4172 }
4173
4174 var instance = new ctor(props, context); // Instantiate twice to help detect side-effects.
4175
4176 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
4177 adoptClassInstance(workInProgress, instance);
4178
4179 {
4180 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
4181 var componentName = getComponentNameFromType(ctor) || 'Component';
4182
4183 if (!didWarnAboutUninitializedState.has(componentName)) {
4184 didWarnAboutUninitializedState.add(componentName);
4185
4186 error('`%s` uses `getDerivedStateFromProps` but its initial state is ' + '%s. This is not recommended. Instead, define the initial state by ' + 'assigning an object to `this.state` in the constructor of `%s`. ' + 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.', componentName, instance.state === null ? 'null' : 'undefined', componentName);
4187 }
4188 } // If new component APIs are defined, "unsafe" lifecycles won't be called.
4189 // Warn about these lifecycles if they are present.
4190 // Don't warn about react-lifecycles-compat polyfilled methods though.
4191
4192
4193 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
4194 var foundWillMountName = null;
4195 var foundWillReceivePropsName = null;
4196 var foundWillUpdateName = null;
4197
4198 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
4199 foundWillMountName = 'componentWillMount';
4200 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
4201 foundWillMountName = 'UNSAFE_componentWillMount';
4202 }
4203
4204 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
4205 foundWillReceivePropsName = 'componentWillReceiveProps';
4206 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4207 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
4208 }
4209
4210 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
4211 foundWillUpdateName = 'componentWillUpdate';
4212 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4213 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
4214 }
4215
4216 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
4217 var _componentName = getComponentNameFromType(ctor) || 'Component';
4218
4219 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
4220
4221 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
4222 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
4223
4224 error('Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' + '%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n' + 'The above lifecycles should be removed. Learn more about this warning here:\n' + 'https://reactjs.org/link/unsafe-component-lifecycles', _componentName, newApiName, foundWillMountName !== null ? "\n " + foundWillMountName : '', foundWillReceivePropsName !== null ? "\n " + foundWillReceivePropsName : '', foundWillUpdateName !== null ? "\n " + foundWillUpdateName : '');
4225 }
4226 }
4227 }
4228 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
4229 // ReactFiberContext usually updates this cache but can't for newly-created instances.
4230
4231
4232 if (isLegacyContextConsumer) {
4233 cacheContext(workInProgress, unmaskedContext, context);
4234 }
4235
4236 return instance;
4237 }
4238
4239 function callComponentWillMount(workInProgress, instance) {
4240 var oldState = instance.state;
4241
4242 if (typeof instance.componentWillMount === 'function') {
4243 instance.componentWillMount();
4244 }
4245
4246 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4247 instance.UNSAFE_componentWillMount();
4248 }
4249
4250 if (oldState !== instance.state) {
4251 {
4252 error('%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentNameFromFiber(workInProgress) || 'Component');
4253 }
4254
4255 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4256 }
4257 }
4258
4259 function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
4260 var oldState = instance.state;
4261
4262 if (typeof instance.componentWillReceiveProps === 'function') {
4263 instance.componentWillReceiveProps(newProps, nextContext);
4264 }
4265
4266 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4267 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
4268 }
4269
4270 if (instance.state !== oldState) {
4271 {
4272 var componentName = getComponentNameFromFiber(workInProgress) || 'Component';
4273
4274 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
4275 didWarnAboutStateAssignmentForComponent.add(componentName);
4276
4277 error('%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
4278 }
4279 }
4280
4281 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4282 }
4283 } // Invokes the mount life-cycles on a previously never rendered instance.
4284
4285
4286 function mountClassInstance(workInProgress, ctor, newProps, renderLanes) {
4287 {
4288 checkClassInstance(workInProgress, ctor, newProps);
4289 }
4290
4291 var instance = workInProgress.stateNode;
4292 instance.props = newProps;
4293 instance.state = workInProgress.memoizedState;
4294 instance.refs = emptyRefsObject;
4295 initializeUpdateQueue(workInProgress);
4296 var contextType = ctor.contextType;
4297
4298 if (typeof contextType === 'object' && contextType !== null) {
4299 instance.context = readContext(contextType);
4300 } else {
4301 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4302 instance.context = getMaskedContext(workInProgress, unmaskedContext);
4303 }
4304
4305 {
4306 if (instance.state === newProps) {
4307 var componentName = getComponentNameFromType(ctor) || 'Component';
4308
4309 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
4310 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
4311
4312 error('%s: It is not recommended to assign props directly to state ' + "because updates to props won't be reflected in state. " + 'In most cases, it is better to use props directly.', componentName);
4313 }
4314 }
4315
4316 if (workInProgress.mode & StrictLegacyMode) {
4317 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
4318 }
4319
4320 {
4321 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
4322 }
4323 }
4324
4325 instance.state = workInProgress.memoizedState;
4326 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4327
4328 if (typeof getDerivedStateFromProps === 'function') {
4329 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4330 instance.state = workInProgress.memoizedState;
4331 } // In order to support react-lifecycles-compat polyfilled components,
4332 // Unsafe lifecycles should not be invoked for components using the new APIs.
4333
4334
4335 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4336 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
4337 // process them now.
4338
4339 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
4340 instance.state = workInProgress.memoizedState;
4341 }
4342
4343 if (typeof instance.componentDidMount === 'function') {
4344 var fiberFlags = Update;
4345
4346 workInProgress.flags |= fiberFlags;
4347 }
4348 }
4349
4350 function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) {
4351 var instance = workInProgress.stateNode;
4352 var oldProps = workInProgress.memoizedProps;
4353 instance.props = oldProps;
4354 var oldContext = instance.context;
4355 var contextType = ctor.contextType;
4356 var nextContext = emptyContextObject;
4357
4358 if (typeof contextType === 'object' && contextType !== null) {
4359 nextContext = readContext(contextType);
4360 } else {
4361 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4362 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
4363 }
4364
4365 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4366 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
4367 // ever the previously attempted to render - not the "current". However,
4368 // during componentDidUpdate we pass the "current" props.
4369 // In order to support react-lifecycles-compat polyfilled components,
4370 // Unsafe lifecycles should not be invoked for components using the new APIs.
4371
4372 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4373 if (oldProps !== newProps || oldContext !== nextContext) {
4374 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4375 }
4376 }
4377
4378 resetHasForceUpdateBeforeProcessing();
4379 var oldState = workInProgress.memoizedState;
4380 var newState = instance.state = oldState;
4381 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
4382 newState = workInProgress.memoizedState;
4383
4384 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4385 // If an update was already in progress, we should schedule an Update
4386 // effect even though we're bailing out, so that cWU/cDU are called.
4387 if (typeof instance.componentDidMount === 'function') {
4388 var fiberFlags = Update;
4389
4390 workInProgress.flags |= fiberFlags;
4391 }
4392
4393 return false;
4394 }
4395
4396 if (typeof getDerivedStateFromProps === 'function') {
4397 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4398 newState = workInProgress.memoizedState;
4399 }
4400
4401 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4402
4403 if (shouldUpdate) {
4404 // In order to support react-lifecycles-compat polyfilled components,
4405 // Unsafe lifecycles should not be invoked for components using the new APIs.
4406 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4407 if (typeof instance.componentWillMount === 'function') {
4408 instance.componentWillMount();
4409 }
4410
4411 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4412 instance.UNSAFE_componentWillMount();
4413 }
4414 }
4415
4416 if (typeof instance.componentDidMount === 'function') {
4417 var _fiberFlags = Update;
4418
4419 workInProgress.flags |= _fiberFlags;
4420 }
4421 } else {
4422 // If an update was already in progress, we should schedule an Update
4423 // effect even though we're bailing out, so that cWU/cDU are called.
4424 if (typeof instance.componentDidMount === 'function') {
4425 var _fiberFlags2 = Update;
4426
4427 workInProgress.flags |= _fiberFlags2;
4428 } // If shouldComponentUpdate returned false, we should still update the
4429 // memoized state to indicate that this work can be reused.
4430
4431
4432 workInProgress.memoizedProps = newProps;
4433 workInProgress.memoizedState = newState;
4434 } // Update the existing instance's state, props, and context pointers even
4435 // if shouldComponentUpdate returns false.
4436
4437
4438 instance.props = newProps;
4439 instance.state = newState;
4440 instance.context = nextContext;
4441 return shouldUpdate;
4442 } // Invokes the update life-cycles and returns false if it shouldn't rerender.
4443
4444
4445 function updateClassInstance(current, workInProgress, ctor, newProps, renderLanes) {
4446 var instance = workInProgress.stateNode;
4447 cloneUpdateQueue(current, workInProgress);
4448 var unresolvedOldProps = workInProgress.memoizedProps;
4449 var oldProps = workInProgress.type === workInProgress.elementType ? unresolvedOldProps : resolveDefaultProps(workInProgress.type, unresolvedOldProps);
4450 instance.props = oldProps;
4451 var unresolvedNewProps = workInProgress.pendingProps;
4452 var oldContext = instance.context;
4453 var contextType = ctor.contextType;
4454 var nextContext = emptyContextObject;
4455
4456 if (typeof contextType === 'object' && contextType !== null) {
4457 nextContext = readContext(contextType);
4458 } else {
4459 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4460 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
4461 }
4462
4463 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4464 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
4465 // ever the previously attempted to render - not the "current". However,
4466 // during componentDidUpdate we pass the "current" props.
4467 // In order to support react-lifecycles-compat polyfilled components,
4468 // Unsafe lifecycles should not be invoked for components using the new APIs.
4469
4470 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4471 if (unresolvedOldProps !== unresolvedNewProps || oldContext !== nextContext) {
4472 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4473 }
4474 }
4475
4476 resetHasForceUpdateBeforeProcessing();
4477 var oldState = workInProgress.memoizedState;
4478 var newState = instance.state = oldState;
4479 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
4480 newState = workInProgress.memoizedState;
4481
4482 if (unresolvedOldProps === unresolvedNewProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing() && !(enableLazyContextPropagation )) {
4483 // If an update was already in progress, we should schedule an Update
4484 // effect even though we're bailing out, so that cWU/cDU are called.
4485 if (typeof instance.componentDidUpdate === 'function') {
4486 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4487 workInProgress.flags |= Update;
4488 }
4489 }
4490
4491 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4492 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4493 workInProgress.flags |= Snapshot;
4494 }
4495 }
4496
4497 return false;
4498 }
4499
4500 if (typeof getDerivedStateFromProps === 'function') {
4501 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4502 newState = workInProgress.memoizedState;
4503 }
4504
4505 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) || // TODO: In some cases, we'll end up checking if context has changed twice,
4506 // both before and after `shouldComponentUpdate` has been called. Not ideal,
4507 // but I'm loath to refactor this function. This only happens for memoized
4508 // components so it's not that common.
4509 enableLazyContextPropagation ;
4510
4511 if (shouldUpdate) {
4512 // In order to support react-lifecycles-compat polyfilled components,
4513 // Unsafe lifecycles should not be invoked for components using the new APIs.
4514 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
4515 if (typeof instance.componentWillUpdate === 'function') {
4516 instance.componentWillUpdate(newProps, newState, nextContext);
4517 }
4518
4519 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4520 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
4521 }
4522 }
4523
4524 if (typeof instance.componentDidUpdate === 'function') {
4525 workInProgress.flags |= Update;
4526 }
4527
4528 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4529 workInProgress.flags |= Snapshot;
4530 }
4531 } else {
4532 // If an update was already in progress, we should schedule an Update
4533 // effect even though we're bailing out, so that cWU/cDU are called.
4534 if (typeof instance.componentDidUpdate === 'function') {
4535 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4536 workInProgress.flags |= Update;
4537 }
4538 }
4539
4540 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4541 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4542 workInProgress.flags |= Snapshot;
4543 }
4544 } // If shouldComponentUpdate returned false, we should still update the
4545 // memoized props/state to indicate that this work can be reused.
4546
4547
4548 workInProgress.memoizedProps = newProps;
4549 workInProgress.memoizedState = newState;
4550 } // Update the existing instance's state, props, and context pointers even
4551 // if shouldComponentUpdate returns false.
4552
4553
4554 instance.props = newProps;
4555 instance.state = newState;
4556 instance.context = nextContext;
4557 return shouldUpdate;
4558 }
4559
4560 // TODO: Use the unified fiber stack module instead of this local one?
4561 // Intentionally not using it yet to derisk the initial implementation, because
4562 // the way we push/pop these values is a bit unusual. If there's a mistake, I'd
4563 // rather the ids be wrong than crash the whole reconciler.
4564 var forkStack = [];
4565 var forkStackIndex = 0;
4566 var treeForkProvider = null;
4567 var treeForkCount = 0;
4568 var idStack = [];
4569 var idStackIndex = 0;
4570 var treeContextProvider = null;
4571 var treeContextId = 1;
4572 var treeContextOverflow = '';
4573
4574 function popTreeContext(workInProgress) {
4575 // Restore the previous values.
4576 // This is a bit more complicated than other context-like modules in Fiber
4577 // because the same Fiber may appear on the stack multiple times and for
4578 // different reasons. We have to keep popping until the work-in-progress is
4579 // no longer at the top of the stack.
4580 while (workInProgress === treeForkProvider) {
4581 treeForkProvider = forkStack[--forkStackIndex];
4582 forkStack[forkStackIndex] = null;
4583 treeForkCount = forkStack[--forkStackIndex];
4584 forkStack[forkStackIndex] = null;
4585 }
4586
4587 while (workInProgress === treeContextProvider) {
4588 treeContextProvider = idStack[--idStackIndex];
4589 idStack[idStackIndex] = null;
4590 treeContextOverflow = idStack[--idStackIndex];
4591 idStack[idStackIndex] = null;
4592 treeContextId = idStack[--idStackIndex];
4593 idStack[idStackIndex] = null;
4594 }
4595 }
4596
4597 var isHydrating = false;
4598
4599 function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
4600 {
4601 throw new Error('Expected prepareToHydrateHostInstance() to never be called. ' + 'This error is likely caused by a bug in React. Please file an issue.');
4602 }
4603 }
4604
4605 function prepareToHydrateHostTextInstance(fiber) {
4606 {
4607 throw new Error('Expected prepareToHydrateHostTextInstance() to never be called. ' + 'This error is likely caused by a bug in React. Please file an issue.');
4608 }
4609 var shouldUpdate = hydrateTextInstance();
4610 }
4611
4612 function popHydrationState(fiber) {
4613 {
4614 return false;
4615 }
4616 }
4617
4618 function getIsHydrating() {
4619 return isHydrating;
4620 }
4621
4622 var didWarnAboutMaps;
4623 var didWarnAboutGenerators;
4624 var didWarnAboutStringRefs;
4625 var ownerHasKeyUseWarning;
4626 var ownerHasFunctionTypeWarning;
4627
4628 var warnForMissingKey = function (child, returnFiber) {};
4629
4630 {
4631 didWarnAboutMaps = false;
4632 didWarnAboutGenerators = false;
4633 didWarnAboutStringRefs = {};
4634 /**
4635 * Warn if there's no key explicitly set on dynamic arrays of children or
4636 * object keys are not valid. This allows us to keep track of children between
4637 * updates.
4638 */
4639
4640 ownerHasKeyUseWarning = {};
4641 ownerHasFunctionTypeWarning = {};
4642
4643 warnForMissingKey = function (child, returnFiber) {
4644 if (child === null || typeof child !== 'object') {
4645 return;
4646 }
4647
4648 if (!child._store || child._store.validated || child.key != null) {
4649 return;
4650 }
4651
4652 if (typeof child._store !== 'object') {
4653 throw new Error('React Component in warnForMissingKey should have a _store. ' + 'This error is likely caused by a bug in React. Please file an issue.');
4654 }
4655
4656 child._store.validated = true;
4657 var componentName = getComponentNameFromFiber(returnFiber) || 'Component';
4658
4659 if (ownerHasKeyUseWarning[componentName]) {
4660 return;
4661 }
4662
4663 ownerHasKeyUseWarning[componentName] = true;
4664
4665 error('Each child in a list should have a unique ' + '"key" prop. See https://reactjs.org/link/warning-keys for ' + 'more information.');
4666 };
4667 }
4668
4669 function coerceRef(returnFiber, current, element) {
4670 var mixedRef = element.ref;
4671
4672 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
4673 {
4674 // TODO: Clean this up once we turn on the string ref warning for
4675 // everyone, because the strict mode case will no longer be relevant
4676 if ((returnFiber.mode & StrictLegacyMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs
4677 // because these cannot be automatically converted to an arrow function
4678 // using a codemod. Therefore, we don't have to warn about string refs again.
4679 !(element._owner && element._self && element._owner.stateNode !== element._self)) {
4680 var componentName = getComponentNameFromFiber(returnFiber) || 'Component';
4681
4682 if (!didWarnAboutStringRefs[componentName]) {
4683 {
4684 error('A string ref, "%s", has been found within a strict mode tree. ' + 'String refs are a source of potential bugs and should be avoided. ' + 'We recommend using useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-string-ref', mixedRef);
4685 }
4686
4687 didWarnAboutStringRefs[componentName] = true;
4688 }
4689 }
4690 }
4691
4692 if (element._owner) {
4693 var owner = element._owner;
4694 var inst;
4695
4696 if (owner) {
4697 var ownerFiber = owner;
4698
4699 if (ownerFiber.tag !== ClassComponent) {
4700 throw new Error('Function components cannot have string refs. ' + 'We recommend using useRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-string-ref');
4701 }
4702
4703 inst = ownerFiber.stateNode;
4704 }
4705
4706 if (!inst) {
4707 throw new Error("Missing owner for string ref " + mixedRef + ". This error is likely caused by a " + 'bug in React. Please file an issue.');
4708 } // Assigning this to a const so Flow knows it won't change in the closure
4709
4710
4711 var resolvedInst = inst;
4712
4713 {
4714 checkPropStringCoercion(mixedRef, 'ref');
4715 }
4716
4717 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref
4718
4719 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
4720 return current.ref;
4721 }
4722
4723 var ref = function (value) {
4724 var refs = resolvedInst.refs;
4725
4726 if (refs === emptyRefsObject) {
4727 // This is a lazy pooled frozen object, so we need to initialize.
4728 refs = resolvedInst.refs = {};
4729 }
4730
4731 if (value === null) {
4732 delete refs[stringRef];
4733 } else {
4734 refs[stringRef] = value;
4735 }
4736 };
4737
4738 ref._stringRef = stringRef;
4739 return ref;
4740 } else {
4741 if (typeof mixedRef !== 'string') {
4742 throw new Error('Expected ref to be a function, a string, an object returned by React.createRef(), or null.');
4743 }
4744
4745 if (!element._owner) {
4746 throw new Error("Element ref was specified as a string (" + mixedRef + ") but no owner was set. This could happen for one of" + ' the following reasons:\n' + '1. You may be adding a ref to a function component\n' + "2. You may be adding a ref to a component that was not created inside a component's render method\n" + '3. You have multiple copies of React loaded\n' + 'See https://reactjs.org/link/refs-must-have-owner for more information.');
4747 }
4748 }
4749 }
4750
4751 return mixedRef;
4752 }
4753
4754 function throwOnInvalidObjectType(returnFiber, newChild) {
4755 var childString = Object.prototype.toString.call(newChild);
4756 throw new Error("Objects are not valid as a React child (found: " + (childString === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : childString) + "). " + 'If you meant to render a collection of children, use an array ' + 'instead.');
4757 }
4758
4759 function warnOnFunctionType(returnFiber) {
4760 {
4761 var componentName = getComponentNameFromFiber(returnFiber) || 'Component';
4762
4763 if (ownerHasFunctionTypeWarning[componentName]) {
4764 return;
4765 }
4766
4767 ownerHasFunctionTypeWarning[componentName] = true;
4768
4769 error('Functions are not valid as a React child. This may happen if ' + 'you return a Component instead of <Component /> from render. ' + 'Or maybe you meant to call this function rather than return it.');
4770 }
4771 }
4772 // to be able to optimize each path individually by branching early. This needs
4773 // a compiler or we can do it manually. Helpers that don't need this branching
4774 // live outside of this function.
4775
4776
4777 function ChildReconciler(shouldTrackSideEffects) {
4778 function deleteChild(returnFiber, childToDelete) {
4779 if (!shouldTrackSideEffects) {
4780 // Noop.
4781 return;
4782 }
4783
4784 var deletions = returnFiber.deletions;
4785
4786 if (deletions === null) {
4787 returnFiber.deletions = [childToDelete];
4788 returnFiber.flags |= ChildDeletion;
4789 } else {
4790 deletions.push(childToDelete);
4791 }
4792 }
4793
4794 function deleteRemainingChildren(returnFiber, currentFirstChild) {
4795 if (!shouldTrackSideEffects) {
4796 // Noop.
4797 return null;
4798 } // TODO: For the shouldClone case, this could be micro-optimized a bit by
4799 // assuming that after the first child we've already added everything.
4800
4801
4802 var childToDelete = currentFirstChild;
4803
4804 while (childToDelete !== null) {
4805 deleteChild(returnFiber, childToDelete);
4806 childToDelete = childToDelete.sibling;
4807 }
4808
4809 return null;
4810 }
4811
4812 function mapRemainingChildren(returnFiber, currentFirstChild) {
4813 // Add the remaining children to a temporary map so that we can find them by
4814 // keys quickly. Implicit (null) keys get added to this set with their index
4815 // instead.
4816 var existingChildren = new Map();
4817 var existingChild = currentFirstChild;
4818
4819 while (existingChild !== null) {
4820 if (existingChild.key !== null) {
4821 existingChildren.set(existingChild.key, existingChild);
4822 } else {
4823 existingChildren.set(existingChild.index, existingChild);
4824 }
4825
4826 existingChild = existingChild.sibling;
4827 }
4828
4829 return existingChildren;
4830 }
4831
4832 function useFiber(fiber, pendingProps) {
4833 // We currently set sibling to null and index to 0 here because it is easy
4834 // to forget to do before returning it. E.g. for the single child case.
4835 var clone = createWorkInProgress(fiber, pendingProps);
4836 clone.index = 0;
4837 clone.sibling = null;
4838 return clone;
4839 }
4840
4841 function placeChild(newFiber, lastPlacedIndex, newIndex) {
4842 newFiber.index = newIndex;
4843
4844 if (!shouldTrackSideEffects) {
4845 // During hydration, the useId algorithm needs to know which fibers are
4846 // part of a list of children (arrays, iterators).
4847 newFiber.flags |= Forked;
4848 return lastPlacedIndex;
4849 }
4850
4851 var current = newFiber.alternate;
4852
4853 if (current !== null) {
4854 var oldIndex = current.index;
4855
4856 if (oldIndex < lastPlacedIndex) {
4857 // This is a move.
4858 newFiber.flags |= Placement;
4859 return lastPlacedIndex;
4860 } else {
4861 // This item can stay in place.
4862 return oldIndex;
4863 }
4864 } else {
4865 // This is an insertion.
4866 newFiber.flags |= Placement;
4867 return lastPlacedIndex;
4868 }
4869 }
4870
4871 function placeSingleChild(newFiber) {
4872 // This is simpler for the single child case. We only need to do a
4873 // placement for inserting new children.
4874 if (shouldTrackSideEffects && newFiber.alternate === null) {
4875 newFiber.flags |= Placement;
4876 }
4877
4878 return newFiber;
4879 }
4880
4881 function updateTextNode(returnFiber, current, textContent, lanes) {
4882 if (current === null || current.tag !== HostText) {
4883 // Insert
4884 var created = createFiberFromText(textContent, returnFiber.mode, lanes);
4885 created.return = returnFiber;
4886 return created;
4887 } else {
4888 // Update
4889 var existing = useFiber(current, textContent);
4890 existing.return = returnFiber;
4891 return existing;
4892 }
4893 }
4894
4895 function updateElement(returnFiber, current, element, lanes) {
4896 var elementType = element.type;
4897
4898 if (elementType === REACT_FRAGMENT_TYPE) {
4899 return updateFragment(returnFiber, current, element.props.children, lanes, element.key);
4900 }
4901
4902 if (current !== null) {
4903 if (current.elementType === elementType || ( // Keep this check inline so it only runs on the false path:
4904 isCompatibleFamilyForHotReloading(current, element) ) || // Lazy types should reconcile their resolved type.
4905 // We need to do this after the Hot Reloading check above,
4906 // because hot reloading has different semantics than prod because
4907 // it doesn't resuspend. So we can't let the call below suspend.
4908 enableLazyElements ) {
4909 // Move based on index
4910 var existing = useFiber(current, element.props);
4911 existing.ref = coerceRef(returnFiber, current, element);
4912 existing.return = returnFiber;
4913
4914 {
4915 existing._debugSource = element._source;
4916 existing._debugOwner = element._owner;
4917 }
4918
4919 return existing;
4920 }
4921 } // Insert
4922
4923
4924 var created = createFiberFromElement(element, returnFiber.mode, lanes);
4925 created.ref = coerceRef(returnFiber, current, element);
4926 created.return = returnFiber;
4927 return created;
4928 }
4929
4930 function updatePortal(returnFiber, current, portal, lanes) {
4931 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
4932 // Insert
4933 var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
4934 created.return = returnFiber;
4935 return created;
4936 } else {
4937 // Update
4938 var existing = useFiber(current, portal.children || []);
4939 existing.return = returnFiber;
4940 return existing;
4941 }
4942 }
4943
4944 function updateFragment(returnFiber, current, fragment, lanes, key) {
4945 if (current === null || current.tag !== Fragment) {
4946 // Insert
4947 var created = createFiberFromFragment(fragment, returnFiber.mode, lanes, key);
4948 created.return = returnFiber;
4949 return created;
4950 } else {
4951 // Update
4952 var existing = useFiber(current, fragment);
4953 existing.return = returnFiber;
4954 return existing;
4955 }
4956 }
4957
4958 function createChild(returnFiber, newChild, lanes) {
4959 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
4960 // Text nodes don't have keys. If the previous node is implicitly keyed
4961 // we can continue to replace it without aborting even if it is not a text
4962 // node.
4963 var created = createFiberFromText('' + newChild, returnFiber.mode, lanes);
4964 created.return = returnFiber;
4965 return created;
4966 }
4967
4968 if (typeof newChild === 'object' && newChild !== null) {
4969 switch (newChild.$$typeof) {
4970 case REACT_ELEMENT_TYPE:
4971 {
4972 var _created = createFiberFromElement(newChild, returnFiber.mode, lanes);
4973
4974 _created.ref = coerceRef(returnFiber, null, newChild);
4975 _created.return = returnFiber;
4976 return _created;
4977 }
4978
4979 case REACT_PORTAL_TYPE:
4980 {
4981 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, lanes);
4982
4983 _created2.return = returnFiber;
4984 return _created2;
4985 }
4986 }
4987
4988 if (isArray(newChild) || getIteratorFn(newChild)) {
4989 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, lanes, null);
4990
4991 _created3.return = returnFiber;
4992 return _created3;
4993 }
4994
4995 throwOnInvalidObjectType(returnFiber, newChild);
4996 }
4997
4998 {
4999 if (typeof newChild === 'function') {
5000 warnOnFunctionType(returnFiber);
5001 }
5002 }
5003
5004 return null;
5005 }
5006
5007 function updateSlot(returnFiber, oldFiber, newChild, lanes) {
5008 // Update the fiber if the keys match, otherwise return null.
5009 var key = oldFiber !== null ? oldFiber.key : null;
5010
5011 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
5012 // Text nodes don't have keys. If the previous node is implicitly keyed
5013 // we can continue to replace it without aborting even if it is not a text
5014 // node.
5015 if (key !== null) {
5016 return null;
5017 }
5018
5019 return updateTextNode(returnFiber, oldFiber, '' + newChild, lanes);
5020 }
5021
5022 if (typeof newChild === 'object' && newChild !== null) {
5023 switch (newChild.$$typeof) {
5024 case REACT_ELEMENT_TYPE:
5025 {
5026 if (newChild.key === key) {
5027 return updateElement(returnFiber, oldFiber, newChild, lanes);
5028 } else {
5029 return null;
5030 }
5031 }
5032
5033 case REACT_PORTAL_TYPE:
5034 {
5035 if (newChild.key === key) {
5036 return updatePortal(returnFiber, oldFiber, newChild, lanes);
5037 } else {
5038 return null;
5039 }
5040 }
5041 }
5042
5043 if (isArray(newChild) || getIteratorFn(newChild)) {
5044 if (key !== null) {
5045 return null;
5046 }
5047
5048 return updateFragment(returnFiber, oldFiber, newChild, lanes, null);
5049 }
5050
5051 throwOnInvalidObjectType(returnFiber, newChild);
5052 }
5053
5054 {
5055 if (typeof newChild === 'function') {
5056 warnOnFunctionType(returnFiber);
5057 }
5058 }
5059
5060 return null;
5061 }
5062
5063 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, lanes) {
5064 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
5065 // Text nodes don't have keys, so we neither have to check the old nor
5066 // new node for the key. If both are text nodes, they match.
5067 var matchedFiber = existingChildren.get(newIdx) || null;
5068 return updateTextNode(returnFiber, matchedFiber, '' + newChild, lanes);
5069 }
5070
5071 if (typeof newChild === 'object' && newChild !== null) {
5072 switch (newChild.$$typeof) {
5073 case REACT_ELEMENT_TYPE:
5074 {
5075 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
5076
5077 return updateElement(returnFiber, _matchedFiber, newChild, lanes);
5078 }
5079
5080 case REACT_PORTAL_TYPE:
5081 {
5082 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
5083
5084 return updatePortal(returnFiber, _matchedFiber2, newChild, lanes);
5085 }
5086
5087 }
5088
5089 if (isArray(newChild) || getIteratorFn(newChild)) {
5090 var _matchedFiber3 = existingChildren.get(newIdx) || null;
5091
5092 return updateFragment(returnFiber, _matchedFiber3, newChild, lanes, null);
5093 }
5094
5095 throwOnInvalidObjectType(returnFiber, newChild);
5096 }
5097
5098 {
5099 if (typeof newChild === 'function') {
5100 warnOnFunctionType(returnFiber);
5101 }
5102 }
5103
5104 return null;
5105 }
5106 /**
5107 * Warns if there is a duplicate or missing key
5108 */
5109
5110
5111 function warnOnInvalidKey(child, knownKeys, returnFiber) {
5112 {
5113 if (typeof child !== 'object' || child === null) {
5114 return knownKeys;
5115 }
5116
5117 switch (child.$$typeof) {
5118 case REACT_ELEMENT_TYPE:
5119 case REACT_PORTAL_TYPE:
5120 warnForMissingKey(child, returnFiber);
5121 var key = child.key;
5122
5123 if (typeof key !== 'string') {
5124 break;
5125 }
5126
5127 if (knownKeys === null) {
5128 knownKeys = new Set();
5129 knownKeys.add(key);
5130 break;
5131 }
5132
5133 if (!knownKeys.has(key)) {
5134 knownKeys.add(key);
5135 break;
5136 }
5137
5138 error('Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key);
5139
5140 break;
5141 }
5142 }
5143
5144 return knownKeys;
5145 }
5146
5147 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, lanes) {
5148 // This algorithm can't optimize by searching from both ends since we
5149 // don't have backpointers on fibers. I'm trying to see how far we can get
5150 // with that model. If it ends up not being worth the tradeoffs, we can
5151 // add it later.
5152 // Even with a two ended optimization, we'd want to optimize for the case
5153 // where there are few changes and brute force the comparison instead of
5154 // going for the Map. It'd like to explore hitting that path first in
5155 // forward-only mode and only go for the Map once we notice that we need
5156 // lots of look ahead. This doesn't handle reversal as well as two ended
5157 // search but that's unusual. Besides, for the two ended optimization to
5158 // work on Iterables, we'd need to copy the whole set.
5159 // In this first iteration, we'll just live with hitting the bad case
5160 // (adding everything to a Map) in for every insert/move.
5161 // If you change this code, also update reconcileChildrenIterator() which
5162 // uses the same algorithm.
5163 {
5164 // First, validate keys.
5165 var knownKeys = null;
5166
5167 for (var i = 0; i < newChildren.length; i++) {
5168 var child = newChildren[i];
5169 knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber);
5170 }
5171 }
5172
5173 var resultingFirstChild = null;
5174 var previousNewFiber = null;
5175 var oldFiber = currentFirstChild;
5176 var lastPlacedIndex = 0;
5177 var newIdx = 0;
5178 var nextOldFiber = null;
5179
5180 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
5181 if (oldFiber.index > newIdx) {
5182 nextOldFiber = oldFiber;
5183 oldFiber = null;
5184 } else {
5185 nextOldFiber = oldFiber.sibling;
5186 }
5187
5188 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], lanes);
5189
5190 if (newFiber === null) {
5191 // TODO: This breaks on empty slots like null children. That's
5192 // unfortunate because it triggers the slow path all the time. We need
5193 // a better way to communicate whether this was a miss or null,
5194 // boolean, undefined, etc.
5195 if (oldFiber === null) {
5196 oldFiber = nextOldFiber;
5197 }
5198
5199 break;
5200 }
5201
5202 if (shouldTrackSideEffects) {
5203 if (oldFiber && newFiber.alternate === null) {
5204 // We matched the slot, but we didn't reuse the existing fiber, so we
5205 // need to delete the existing child.
5206 deleteChild(returnFiber, oldFiber);
5207 }
5208 }
5209
5210 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
5211
5212 if (previousNewFiber === null) {
5213 // TODO: Move out of the loop. This only happens for the first run.
5214 resultingFirstChild = newFiber;
5215 } else {
5216 // TODO: Defer siblings if we're not at the right index for this slot.
5217 // I.e. if we had null values before, then we want to defer this
5218 // for each null value. However, we also don't want to call updateSlot
5219 // with the previous one.
5220 previousNewFiber.sibling = newFiber;
5221 }
5222
5223 previousNewFiber = newFiber;
5224 oldFiber = nextOldFiber;
5225 }
5226
5227 if (newIdx === newChildren.length) {
5228 // We've reached the end of the new children. We can delete the rest.
5229 deleteRemainingChildren(returnFiber, oldFiber);
5230
5231 return resultingFirstChild;
5232 }
5233
5234 if (oldFiber === null) {
5235 // If we don't have any more existing children we can choose a fast path
5236 // since the rest will all be insertions.
5237 for (; newIdx < newChildren.length; newIdx++) {
5238 var _newFiber = createChild(returnFiber, newChildren[newIdx], lanes);
5239
5240 if (_newFiber === null) {
5241 continue;
5242 }
5243
5244 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
5245
5246 if (previousNewFiber === null) {
5247 // TODO: Move out of the loop. This only happens for the first run.
5248 resultingFirstChild = _newFiber;
5249 } else {
5250 previousNewFiber.sibling = _newFiber;
5251 }
5252
5253 previousNewFiber = _newFiber;
5254 }
5255
5256 return resultingFirstChild;
5257 } // Add all children to a key map for quick lookups.
5258
5259
5260 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
5261
5262 for (; newIdx < newChildren.length; newIdx++) {
5263 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], lanes);
5264
5265 if (_newFiber2 !== null) {
5266 if (shouldTrackSideEffects) {
5267 if (_newFiber2.alternate !== null) {
5268 // The new fiber is a work in progress, but if there exists a
5269 // current, that means that we reused the fiber. We need to delete
5270 // it from the child list so that we don't add it to the deletion
5271 // list.
5272 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
5273 }
5274 }
5275
5276 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
5277
5278 if (previousNewFiber === null) {
5279 resultingFirstChild = _newFiber2;
5280 } else {
5281 previousNewFiber.sibling = _newFiber2;
5282 }
5283
5284 previousNewFiber = _newFiber2;
5285 }
5286 }
5287
5288 if (shouldTrackSideEffects) {
5289 // Any existing children that weren't consumed above were deleted. We need
5290 // to add them to the deletion list.
5291 existingChildren.forEach(function (child) {
5292 return deleteChild(returnFiber, child);
5293 });
5294 }
5295
5296 return resultingFirstChild;
5297 }
5298
5299 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, lanes) {
5300 // This is the same implementation as reconcileChildrenArray(),
5301 // but using the iterator instead.
5302 var iteratorFn = getIteratorFn(newChildrenIterable);
5303
5304 if (typeof iteratorFn !== 'function') {
5305 throw new Error('An object is not an iterable. This error is likely caused by a bug in ' + 'React. Please file an issue.');
5306 }
5307
5308 {
5309 // We don't support rendering Generators because it's a mutation.
5310 // See https://github.com/facebook/react/issues/12995
5311 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag
5312 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
5313 if (!didWarnAboutGenerators) {
5314 error('Using Generators as children is unsupported and will likely yield ' + 'unexpected results because enumerating a generator mutates it. ' + 'You may convert it to an array with `Array.from()` or the ' + '`[...spread]` operator before rendering. Keep in mind ' + 'you might need to polyfill these features for older browsers.');
5315 }
5316
5317 didWarnAboutGenerators = true;
5318 } // Warn about using Maps as children
5319
5320
5321 if (newChildrenIterable.entries === iteratorFn) {
5322 if (!didWarnAboutMaps) {
5323 error('Using Maps as children is not supported. ' + 'Use an array of keyed ReactElements instead.');
5324 }
5325
5326 didWarnAboutMaps = true;
5327 } // First, validate keys.
5328 // We'll get a different iterator later for the main pass.
5329
5330
5331 var _newChildren = iteratorFn.call(newChildrenIterable);
5332
5333 if (_newChildren) {
5334 var knownKeys = null;
5335
5336 var _step = _newChildren.next();
5337
5338 for (; !_step.done; _step = _newChildren.next()) {
5339 var child = _step.value;
5340 knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber);
5341 }
5342 }
5343 }
5344
5345 var newChildren = iteratorFn.call(newChildrenIterable);
5346
5347 if (newChildren == null) {
5348 throw new Error('An iterable object provided no iterator.');
5349 }
5350
5351 var resultingFirstChild = null;
5352 var previousNewFiber = null;
5353 var oldFiber = currentFirstChild;
5354 var lastPlacedIndex = 0;
5355 var newIdx = 0;
5356 var nextOldFiber = null;
5357 var step = newChildren.next();
5358
5359 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
5360 if (oldFiber.index > newIdx) {
5361 nextOldFiber = oldFiber;
5362 oldFiber = null;
5363 } else {
5364 nextOldFiber = oldFiber.sibling;
5365 }
5366
5367 var newFiber = updateSlot(returnFiber, oldFiber, step.value, lanes);
5368
5369 if (newFiber === null) {
5370 // TODO: This breaks on empty slots like null children. That's
5371 // unfortunate because it triggers the slow path all the time. We need
5372 // a better way to communicate whether this was a miss or null,
5373 // boolean, undefined, etc.
5374 if (oldFiber === null) {
5375 oldFiber = nextOldFiber;
5376 }
5377
5378 break;
5379 }
5380
5381 if (shouldTrackSideEffects) {
5382 if (oldFiber && newFiber.alternate === null) {
5383 // We matched the slot, but we didn't reuse the existing fiber, so we
5384 // need to delete the existing child.
5385 deleteChild(returnFiber, oldFiber);
5386 }
5387 }
5388
5389 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
5390
5391 if (previousNewFiber === null) {
5392 // TODO: Move out of the loop. This only happens for the first run.
5393 resultingFirstChild = newFiber;
5394 } else {
5395 // TODO: Defer siblings if we're not at the right index for this slot.
5396 // I.e. if we had null values before, then we want to defer this
5397 // for each null value. However, we also don't want to call updateSlot
5398 // with the previous one.
5399 previousNewFiber.sibling = newFiber;
5400 }
5401
5402 previousNewFiber = newFiber;
5403 oldFiber = nextOldFiber;
5404 }
5405
5406 if (step.done) {
5407 // We've reached the end of the new children. We can delete the rest.
5408 deleteRemainingChildren(returnFiber, oldFiber);
5409
5410 return resultingFirstChild;
5411 }
5412
5413 if (oldFiber === null) {
5414 // If we don't have any more existing children we can choose a fast path
5415 // since the rest will all be insertions.
5416 for (; !step.done; newIdx++, step = newChildren.next()) {
5417 var _newFiber3 = createChild(returnFiber, step.value, lanes);
5418
5419 if (_newFiber3 === null) {
5420 continue;
5421 }
5422
5423 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
5424
5425 if (previousNewFiber === null) {
5426 // TODO: Move out of the loop. This only happens for the first run.
5427 resultingFirstChild = _newFiber3;
5428 } else {
5429 previousNewFiber.sibling = _newFiber3;
5430 }
5431
5432 previousNewFiber = _newFiber3;
5433 }
5434
5435 return resultingFirstChild;
5436 } // Add all children to a key map for quick lookups.
5437
5438
5439 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
5440
5441 for (; !step.done; newIdx++, step = newChildren.next()) {
5442 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, lanes);
5443
5444 if (_newFiber4 !== null) {
5445 if (shouldTrackSideEffects) {
5446 if (_newFiber4.alternate !== null) {
5447 // The new fiber is a work in progress, but if there exists a
5448 // current, that means that we reused the fiber. We need to delete
5449 // it from the child list so that we don't add it to the deletion
5450 // list.
5451 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
5452 }
5453 }
5454
5455 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
5456
5457 if (previousNewFiber === null) {
5458 resultingFirstChild = _newFiber4;
5459 } else {
5460 previousNewFiber.sibling = _newFiber4;
5461 }
5462
5463 previousNewFiber = _newFiber4;
5464 }
5465 }
5466
5467 if (shouldTrackSideEffects) {
5468 // Any existing children that weren't consumed above were deleted. We need
5469 // to add them to the deletion list.
5470 existingChildren.forEach(function (child) {
5471 return deleteChild(returnFiber, child);
5472 });
5473 }
5474
5475 return resultingFirstChild;
5476 }
5477
5478 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, lanes) {
5479 // There's no need to check for keys on text nodes since we don't have a
5480 // way to define them.
5481 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
5482 // We already have an existing node so let's just update it and delete
5483 // the rest.
5484 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
5485 var existing = useFiber(currentFirstChild, textContent);
5486 existing.return = returnFiber;
5487 return existing;
5488 } // The existing first child is not a text node so we need to create one
5489 // and delete the existing ones.
5490
5491
5492 deleteRemainingChildren(returnFiber, currentFirstChild);
5493 var created = createFiberFromText(textContent, returnFiber.mode, lanes);
5494 created.return = returnFiber;
5495 return created;
5496 }
5497
5498 function reconcileSingleElement(returnFiber, currentFirstChild, element, lanes) {
5499 var key = element.key;
5500 var child = currentFirstChild;
5501
5502 while (child !== null) {
5503 // TODO: If key === null and child.key === null, then this only applies to
5504 // the first item in the list.
5505 if (child.key === key) {
5506 var elementType = element.type;
5507
5508 if (elementType === REACT_FRAGMENT_TYPE) {
5509 if (child.tag === Fragment) {
5510 deleteRemainingChildren(returnFiber, child.sibling);
5511 var existing = useFiber(child, element.props.children);
5512 existing.return = returnFiber;
5513
5514 {
5515 existing._debugSource = element._source;
5516 existing._debugOwner = element._owner;
5517 }
5518
5519 return existing;
5520 }
5521 } else {
5522 if (child.elementType === elementType || ( // Keep this check inline so it only runs on the false path:
5523 isCompatibleFamilyForHotReloading(child, element) ) || // Lazy types should reconcile their resolved type.
5524 // We need to do this after the Hot Reloading check above,
5525 // because hot reloading has different semantics than prod because
5526 // it doesn't resuspend. So we can't let the call below suspend.
5527 enableLazyElements ) {
5528 deleteRemainingChildren(returnFiber, child.sibling);
5529
5530 var _existing = useFiber(child, element.props);
5531
5532 _existing.ref = coerceRef(returnFiber, child, element);
5533 _existing.return = returnFiber;
5534
5535 {
5536 _existing._debugSource = element._source;
5537 _existing._debugOwner = element._owner;
5538 }
5539
5540 return _existing;
5541 }
5542 } // Didn't match.
5543
5544
5545 deleteRemainingChildren(returnFiber, child);
5546 break;
5547 } else {
5548 deleteChild(returnFiber, child);
5549 }
5550
5551 child = child.sibling;
5552 }
5553
5554 if (element.type === REACT_FRAGMENT_TYPE) {
5555 var created = createFiberFromFragment(element.props.children, returnFiber.mode, lanes, element.key);
5556 created.return = returnFiber;
5557 return created;
5558 } else {
5559 var _created4 = createFiberFromElement(element, returnFiber.mode, lanes);
5560
5561 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
5562 _created4.return = returnFiber;
5563 return _created4;
5564 }
5565 }
5566
5567 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, lanes) {
5568 var key = portal.key;
5569 var child = currentFirstChild;
5570
5571 while (child !== null) {
5572 // TODO: If key === null and child.key === null, then this only applies to
5573 // the first item in the list.
5574 if (child.key === key) {
5575 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
5576 deleteRemainingChildren(returnFiber, child.sibling);
5577 var existing = useFiber(child, portal.children || []);
5578 existing.return = returnFiber;
5579 return existing;
5580 } else {
5581 deleteRemainingChildren(returnFiber, child);
5582 break;
5583 }
5584 } else {
5585 deleteChild(returnFiber, child);
5586 }
5587
5588 child = child.sibling;
5589 }
5590
5591 var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
5592 created.return = returnFiber;
5593 return created;
5594 } // This API will tag the children with the side-effect of the reconciliation
5595 // itself. They will be added to the side-effect list as we pass through the
5596 // children and the parent.
5597
5598
5599 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, lanes) {
5600 // This function is not recursive.
5601 // If the top level item is an array, we treat it as a set of children,
5602 // not as a fragment. Nested arrays on the other hand will be treated as
5603 // fragment nodes. Recursion happens at the normal flow.
5604 // Handle top level unkeyed fragments as if they were arrays.
5605 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
5606 // We treat the ambiguous cases above the same.
5607 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
5608
5609 if (isUnkeyedTopLevelFragment) {
5610 newChild = newChild.props.children;
5611 } // Handle object types
5612
5613
5614 if (typeof newChild === 'object' && newChild !== null) {
5615 switch (newChild.$$typeof) {
5616 case REACT_ELEMENT_TYPE:
5617 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, lanes));
5618
5619 case REACT_PORTAL_TYPE:
5620 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, lanes));
5621
5622 }
5623
5624 if (isArray(newChild)) {
5625 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, lanes);
5626 }
5627
5628 if (getIteratorFn(newChild)) {
5629 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, lanes);
5630 }
5631
5632 throwOnInvalidObjectType(returnFiber, newChild);
5633 }
5634
5635 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
5636 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, lanes));
5637 }
5638
5639 {
5640 if (typeof newChild === 'function') {
5641 warnOnFunctionType(returnFiber);
5642 }
5643 } // Remaining cases are all treated as empty.
5644
5645
5646 return deleteRemainingChildren(returnFiber, currentFirstChild);
5647 }
5648
5649 return reconcileChildFibers;
5650 }
5651
5652 var reconcileChildFibers = ChildReconciler(true);
5653 var mountChildFibers = ChildReconciler(false);
5654 function cloneChildFibers(current, workInProgress) {
5655 if (current !== null && workInProgress.child !== current.child) {
5656 throw new Error('Resuming work not yet implemented.');
5657 }
5658
5659 if (workInProgress.child === null) {
5660 return;
5661 }
5662
5663 var currentChild = workInProgress.child;
5664 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps);
5665 workInProgress.child = newChild;
5666 newChild.return = workInProgress;
5667
5668 while (currentChild.sibling !== null) {
5669 currentChild = currentChild.sibling;
5670 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps);
5671 newChild.return = workInProgress;
5672 }
5673
5674 newChild.sibling = null;
5675 } // Reset a workInProgress child set to prepare it for a second pass.
5676
5677 function resetChildFibers(workInProgress, lanes) {
5678 var child = workInProgress.child;
5679
5680 while (child !== null) {
5681 resetWorkInProgress(child, lanes);
5682 child = child.sibling;
5683 }
5684 }
5685
5686 var NO_CONTEXT$1 = {};
5687 var contextStackCursor$1 = createCursor(NO_CONTEXT$1);
5688 var contextFiberStackCursor = createCursor(NO_CONTEXT$1);
5689 var rootInstanceStackCursor = createCursor(NO_CONTEXT$1);
5690
5691 function requiredContext(c) {
5692 if (c === NO_CONTEXT$1) {
5693 throw new Error('Expected host context to exist. This error is likely caused by a bug ' + 'in React. Please file an issue.');
5694 }
5695
5696 return c;
5697 }
5698
5699 function getRootHostContainer() {
5700 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5701 return rootInstance;
5702 }
5703
5704 function pushHostContainer(fiber, nextRootInstance) {
5705 // Push current root instance onto the stack;
5706 // This allows us to reset root when portals are popped.
5707 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
5708 // This enables us to pop only Fibers that provide unique contexts.
5709
5710 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
5711 // However, we can't just call getRootHostContext() and push it because
5712 // we'd have a different number of entries on the stack depending on
5713 // whether getRootHostContext() throws somewhere in renderer code or not.
5714 // So we push an empty value first. This lets us safely unwind on errors.
5715
5716 push(contextStackCursor$1, NO_CONTEXT$1, fiber);
5717 var nextRootContext = getRootHostContext(); // Now that we know this function doesn't throw, replace it.
5718
5719 pop(contextStackCursor$1, fiber);
5720 push(contextStackCursor$1, nextRootContext, fiber);
5721 }
5722
5723 function popHostContainer(fiber) {
5724 pop(contextStackCursor$1, fiber);
5725 pop(contextFiberStackCursor, fiber);
5726 pop(rootInstanceStackCursor, fiber);
5727 }
5728
5729 function getHostContext() {
5730 var context = requiredContext(contextStackCursor$1.current);
5731 return context;
5732 }
5733
5734 function pushHostContext(fiber) {
5735 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5736 var context = requiredContext(contextStackCursor$1.current);
5737 var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique.
5738
5739 if (context === nextContext) {
5740 return;
5741 } // Track the context and the Fiber that provided it.
5742 // This enables us to pop only Fibers that provide unique contexts.
5743
5744
5745 push(contextFiberStackCursor, fiber, fiber);
5746 push(contextStackCursor$1, nextContext, fiber);
5747 }
5748
5749 function popHostContext(fiber) {
5750 // Do not pop unless this Fiber provided the current context.
5751 // pushHostContext() only pushes Fibers that provide unique contexts.
5752 if (contextFiberStackCursor.current !== fiber) {
5753 return;
5754 }
5755
5756 pop(contextStackCursor$1, fiber);
5757 pop(contextFiberStackCursor, fiber);
5758 }
5759
5760 var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is
5761 // inherited deeply down the subtree. The upper bits only affect
5762 // this immediate suspense boundary and gets reset each new
5763 // boundary or suspense list.
5764
5765 var SubtreeSuspenseContextMask = 1; // Subtree Flags:
5766 // InvisibleParentSuspenseContext indicates that one of our parent Suspense
5767 // boundaries is not currently showing visible main content.
5768 // Either because it is already showing a fallback or is not mounted at all.
5769 // We can use this to determine if it is desirable to trigger a fallback at
5770 // the parent. If not, then we might need to trigger undesirable boundaries
5771 // and/or suspend the commit to avoid hiding the parent content.
5772
5773 var InvisibleParentSuspenseContext = 1; // Shallow Flags:
5774 // ForceSuspenseFallback can be used by SuspenseList to force newly added
5775 // items into their fallback state during one of the render passes.
5776
5777 var ForceSuspenseFallback = 2;
5778 var suspenseStackCursor = createCursor(DefaultSuspenseContext);
5779 function hasSuspenseContext(parentContext, flag) {
5780 return (parentContext & flag) !== 0;
5781 }
5782 function setDefaultShallowSuspenseContext(parentContext) {
5783 return parentContext & SubtreeSuspenseContextMask;
5784 }
5785 function setShallowSuspenseContext(parentContext, shallowContext) {
5786 return parentContext & SubtreeSuspenseContextMask | shallowContext;
5787 }
5788 function addSubtreeSuspenseContext(parentContext, subtreeContext) {
5789 return parentContext | subtreeContext;
5790 }
5791 function pushSuspenseContext(fiber, newContext) {
5792 push(suspenseStackCursor, newContext, fiber);
5793 }
5794 function popSuspenseContext(fiber) {
5795 pop(suspenseStackCursor, fiber);
5796 }
5797
5798 function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
5799 // If it was the primary children that just suspended, capture and render the
5800 // fallback. Otherwise, don't capture and bubble to the next boundary.
5801 var nextState = workInProgress.memoizedState;
5802
5803 if (nextState !== null) {
5804 if (nextState.dehydrated !== null) {
5805 // A dehydrated boundary always captures.
5806 return true;
5807 }
5808
5809 return false;
5810 }
5811
5812 var props = workInProgress.memoizedProps; // Regular boundaries always capture.
5813
5814 {
5815 return true;
5816 } // If it's a boundary we should avoid, then we prefer to bubble up to the
5817 }
5818 function findFirstSuspended(row) {
5819 var node = row;
5820
5821 while (node !== null) {
5822 if (node.tag === SuspenseComponent) {
5823 var state = node.memoizedState;
5824
5825 if (state !== null) {
5826 var dehydrated = state.dehydrated;
5827
5828 if (dehydrated === null || isSuspenseInstancePending() || isSuspenseInstanceFallback()) {
5829 return node;
5830 }
5831 }
5832 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
5833 // keep track of whether it suspended or not.
5834 node.memoizedProps.revealOrder !== undefined) {
5835 var didSuspend = (node.flags & DidCapture) !== NoFlags;
5836
5837 if (didSuspend) {
5838 return node;
5839 }
5840 } else if (node.child !== null) {
5841 node.child.return = node;
5842 node = node.child;
5843 continue;
5844 }
5845
5846 if (node === row) {
5847 return null;
5848 }
5849
5850 while (node.sibling === null) {
5851 if (node.return === null || node.return === row) {
5852 return null;
5853 }
5854
5855 node = node.return;
5856 }
5857
5858 node.sibling.return = node.return;
5859 node = node.sibling;
5860 }
5861
5862 return null;
5863 }
5864
5865 var NoFlags$1 =
5866 /* */
5867 0; // Represents whether effect should fire.
5868
5869 var HasEffect =
5870 /* */
5871 1; // Represents the phase in which the effect (not the clean-up) fires.
5872
5873 var Insertion =
5874 /* */
5875 2;
5876 var Layout =
5877 /* */
5878 4;
5879 var Passive$1 =
5880 /* */
5881 8;
5882
5883 // and should be reset before starting a new render.
5884 // This tracks which mutable sources need to be reset after a render.
5885
5886 var workInProgressSources = [];
5887 function resetWorkInProgressVersions() {
5888 for (var i = 0; i < workInProgressSources.length; i++) {
5889 var mutableSource = workInProgressSources[i];
5890
5891 {
5892 mutableSource._workInProgressVersionSecondary = null;
5893 }
5894 }
5895
5896 workInProgressSources.length = 0;
5897 }
5898
5899 var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher,
5900 ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig;
5901 var didWarnAboutMismatchedHooksForComponent;
5902 var didWarnUncachedGetSnapshot;
5903
5904 {
5905 didWarnAboutMismatchedHooksForComponent = new Set();
5906 }
5907
5908 // These are set right before calling the component.
5909 var renderLanes = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from
5910 // the work-in-progress hook.
5911
5912 var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
5913 // current hook list is the list that belongs to the current fiber. The
5914 // work-in-progress hook list is a new list that will be added to the
5915 // work-in-progress fiber.
5916
5917 var currentHook = null;
5918 var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This
5919 // does not get reset if we do another render pass; only when we're completely
5920 // finished evaluating this component. This is an optimization so we know
5921 // whether we need to clear render phase updates after a throw.
5922
5923 var didScheduleRenderPhaseUpdate = false; // Where an update was scheduled only during the current render pass. This
5924 // gets reset after each attempt.
5925 // TODO: Maybe there's some way to consolidate this with
5926 // `didScheduleRenderPhaseUpdate`. Or with `numberOfReRenders`.
5927
5928 var didScheduleRenderPhaseUpdateDuringThisPass = false; // Counts the number of useId hooks in this component.
5929 // hydration). This counter is global, so client ids are not stable across
5930 // render attempts.
5931
5932 var globalClientIdCounter = 0;
5933 var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
5934
5935 var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
5936 // The list stores the order of hooks used during the initial render (mount).
5937 // Subsequent renders (updates) reference this list.
5938
5939 var hookTypesDev = null;
5940 var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
5941 // the dependencies for Hooks that need them (e.g. useEffect or useMemo).
5942 // When true, such Hooks will always be "remounted". Only used during hot reload.
5943
5944 var ignorePreviousDependencies = false;
5945
5946 function mountHookTypesDev() {
5947 {
5948 var hookName = currentHookNameInDev;
5949
5950 if (hookTypesDev === null) {
5951 hookTypesDev = [hookName];
5952 } else {
5953 hookTypesDev.push(hookName);
5954 }
5955 }
5956 }
5957
5958 function updateHookTypesDev() {
5959 {
5960 var hookName = currentHookNameInDev;
5961
5962 if (hookTypesDev !== null) {
5963 hookTypesUpdateIndexDev++;
5964
5965 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
5966 warnOnHookMismatchInDev(hookName);
5967 }
5968 }
5969 }
5970 }
5971
5972 function checkDepsAreArrayDev(deps) {
5973 {
5974 if (deps !== undefined && deps !== null && !isArray(deps)) {
5975 // Verify deps, but only on mount to avoid extra checks.
5976 // It's unlikely their type would change as usually you define them inline.
5977 error('%s received a final argument that is not an array (instead, received `%s`). When ' + 'specified, the final argument must be an array.', currentHookNameInDev, typeof deps);
5978 }
5979 }
5980 }
5981
5982 function warnOnHookMismatchInDev(currentHookName) {
5983 {
5984 var componentName = getComponentNameFromFiber(currentlyRenderingFiber$1);
5985
5986 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
5987 didWarnAboutMismatchedHooksForComponent.add(componentName);
5988
5989 if (hookTypesDev !== null) {
5990 var table = '';
5991 var secondColumnStart = 30;
5992
5993 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
5994 var oldHookName = hookTypesDev[i];
5995 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
5996 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
5997 // lol @ IE not supporting String#repeat
5998
5999 while (row.length < secondColumnStart) {
6000 row += ' ';
6001 }
6002
6003 row += newHookName + '\n';
6004 table += row;
6005 }
6006
6007 error('React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' ------------------------------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table);
6008 }
6009 }
6010 }
6011 }
6012
6013 function throwInvalidHookError() {
6014 throw new Error('Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + ' one of the following reasons:\n' + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + '2. You might be breaking the Rules of Hooks\n' + '3. You might have more than one copy of React in the same app\n' + 'See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.');
6015 }
6016
6017 function areHookInputsEqual(nextDeps, prevDeps) {
6018 {
6019 if (ignorePreviousDependencies) {
6020 // Only true when this component is being hot reloaded.
6021 return false;
6022 }
6023 }
6024
6025 if (prevDeps === null) {
6026 {
6027 error('%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', currentHookNameInDev);
6028 }
6029
6030 return false;
6031 }
6032
6033 {
6034 // Don't bother comparing lengths in prod because these arrays should be
6035 // passed inline.
6036 if (nextDeps.length !== prevDeps.length) {
6037 error('The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + 'Incoming: %s', currentHookNameInDev, "[" + prevDeps.join(', ') + "]", "[" + nextDeps.join(', ') + "]");
6038 }
6039 }
6040
6041 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
6042 if (objectIs(nextDeps[i], prevDeps[i])) {
6043 continue;
6044 }
6045
6046 return false;
6047 }
6048
6049 return true;
6050 }
6051
6052 function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderLanes) {
6053 renderLanes = nextRenderLanes;
6054 currentlyRenderingFiber$1 = workInProgress;
6055
6056 {
6057 hookTypesDev = current !== null ? current._debugHookTypes : null;
6058 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
6059
6060 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
6061 }
6062
6063 workInProgress.memoizedState = null;
6064 workInProgress.updateQueue = null;
6065 workInProgress.lanes = NoLanes; // The following should have already been reset
6066 // currentHook = null;
6067 // workInProgressHook = null;
6068 // didScheduleRenderPhaseUpdate = false;
6069 // localIdCounter = 0;
6070 // TODO Warn if no hooks are used at all during mount, then some are used during update.
6071 // Currently we will identify the update render as a mount because memoizedState === null.
6072 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
6073 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.
6074 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
6075 // so memoizedState would be null during updates and mounts.
6076
6077 {
6078 if (current !== null && current.memoizedState !== null) {
6079 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
6080 } else if (hookTypesDev !== null) {
6081 // This dispatcher handles an edge case where a component is updating,
6082 // but no stateful hooks have been used.
6083 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
6084 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
6085 // This dispatcher does that.
6086 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
6087 } else {
6088 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
6089 }
6090 }
6091
6092 var children = Component(props, secondArg); // Check if there was a render phase update
6093
6094 if (didScheduleRenderPhaseUpdateDuringThisPass) {
6095 // Keep rendering in a loop for as long as render phase updates continue to
6096 // be scheduled. Use a counter to prevent infinite loops.
6097 var numberOfReRenders = 0;
6098
6099 do {
6100 didScheduleRenderPhaseUpdateDuringThisPass = false;
6101
6102 if (numberOfReRenders >= RE_RENDER_LIMIT) {
6103 throw new Error('Too many re-renders. React limits the number of renders to prevent ' + 'an infinite loop.');
6104 }
6105
6106 numberOfReRenders += 1;
6107
6108 {
6109 // Even when hot reloading, allow dependencies to stabilize
6110 // after first render to prevent infinite render phase updates.
6111 ignorePreviousDependencies = false;
6112 } // Start over from the beginning of the list
6113
6114
6115 currentHook = null;
6116 workInProgressHook = null;
6117 workInProgress.updateQueue = null;
6118
6119 {
6120 // Also validate hook order for cascading updates.
6121 hookTypesUpdateIndexDev = -1;
6122 }
6123
6124 ReactCurrentDispatcher$1.current = HooksDispatcherOnRerenderInDEV ;
6125 children = Component(props, secondArg);
6126 } while (didScheduleRenderPhaseUpdateDuringThisPass);
6127 } // We can assume the previous dispatcher is always this one, since we set it
6128 // at the beginning of the render phase and there's no re-entrance.
6129
6130
6131 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
6132
6133 {
6134 workInProgress._debugHookTypes = hookTypesDev;
6135 } // This check uses currentHook so that it works the same in DEV and prod bundles.
6136 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
6137
6138
6139 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
6140 renderLanes = NoLanes;
6141 currentlyRenderingFiber$1 = null;
6142 currentHook = null;
6143 workInProgressHook = null;
6144
6145 {
6146 currentHookNameInDev = null;
6147 hookTypesDev = null;
6148 hookTypesUpdateIndexDev = -1; // Confirm that a static flag was not added or removed since the last
6149 // render. If this fires, it suggests that we incorrectly reset the static
6150 // flags in some other part of the codebase. This has happened before, for
6151 // example, in the SuspenseList implementation.
6152
6153 if (current !== null && (current.flags & StaticMask) !== (workInProgress.flags & StaticMask) && // Disable this warning in legacy mode, because legacy Suspense is weird
6154 // and creates false positives. To make this work in legacy mode, we'd
6155 // need to mark fibers that commit in an incomplete state, somehow. For
6156 // now I'll disable the warning that most of the bugs that would trigger
6157 // it are either exclusive to concurrent mode or exist in both.
6158 (current.mode & ConcurrentMode) !== NoMode) {
6159 error('Internal React error: Expected static flag was missing. Please ' + 'notify the React team.');
6160 }
6161 }
6162
6163 didScheduleRenderPhaseUpdate = false; // This is reset by checkDidRenderIdHook
6164 // localIdCounter = 0;
6165
6166 if (didRenderTooFewHooks) {
6167 throw new Error('Rendered fewer hooks than expected. This may be caused by an accidental ' + 'early return statement.');
6168 }
6169
6170 return children;
6171 }
6172 function bailoutHooks(current, workInProgress, lanes) {
6173 workInProgress.updateQueue = current.updateQueue; // TODO: Don't need to reset the flags here, because they're reset in the
6174 // complete phase (bubbleProperties).
6175
6176 {
6177 workInProgress.flags &= ~(Passive | Update);
6178 }
6179
6180 current.lanes = removeLanes(current.lanes, lanes);
6181 }
6182 function resetHooksAfterThrow() {
6183 // We can assume the previous dispatcher is always this one, since we set it
6184 // at the beginning of the render phase and there's no re-entrance.
6185 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
6186
6187 if (didScheduleRenderPhaseUpdate) {
6188 // There were render phase updates. These are only valid for this render
6189 // phase, which we are now aborting. Remove the updates from the queues so
6190 // they do not persist to the next render. Do not remove updates from hooks
6191 // that weren't processed.
6192 //
6193 // Only reset the updates from the queue if it has a clone. If it does
6194 // not have a clone, that means it wasn't processed, and the updates were
6195 // scheduled before we entered the render phase.
6196 var hook = currentlyRenderingFiber$1.memoizedState;
6197
6198 while (hook !== null) {
6199 var queue = hook.queue;
6200
6201 if (queue !== null) {
6202 queue.pending = null;
6203 }
6204
6205 hook = hook.next;
6206 }
6207
6208 didScheduleRenderPhaseUpdate = false;
6209 }
6210
6211 renderLanes = NoLanes;
6212 currentlyRenderingFiber$1 = null;
6213 currentHook = null;
6214 workInProgressHook = null;
6215
6216 {
6217 hookTypesDev = null;
6218 hookTypesUpdateIndexDev = -1;
6219 currentHookNameInDev = null;
6220 isUpdatingOpaqueValueInRenderPhase = false;
6221 }
6222
6223 didScheduleRenderPhaseUpdateDuringThisPass = false;
6224 }
6225
6226 function mountWorkInProgressHook() {
6227 var hook = {
6228 memoizedState: null,
6229 baseState: null,
6230 baseQueue: null,
6231 queue: null,
6232 next: null
6233 };
6234
6235 if (workInProgressHook === null) {
6236 // This is the first hook in the list
6237 currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;
6238 } else {
6239 // Append to the end of the list
6240 workInProgressHook = workInProgressHook.next = hook;
6241 }
6242
6243 return workInProgressHook;
6244 }
6245
6246 function updateWorkInProgressHook() {
6247 // This function is used both for updates and for re-renders triggered by a
6248 // render phase update. It assumes there is either a current hook we can
6249 // clone, or a work-in-progress hook from a previous render pass that we can
6250 // use as a base. When we reach the end of the base list, we must switch to
6251 // the dispatcher used for mounts.
6252 var nextCurrentHook;
6253
6254 if (currentHook === null) {
6255 var current = currentlyRenderingFiber$1.alternate;
6256
6257 if (current !== null) {
6258 nextCurrentHook = current.memoizedState;
6259 } else {
6260 nextCurrentHook = null;
6261 }
6262 } else {
6263 nextCurrentHook = currentHook.next;
6264 }
6265
6266 var nextWorkInProgressHook;
6267
6268 if (workInProgressHook === null) {
6269 nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;
6270 } else {
6271 nextWorkInProgressHook = workInProgressHook.next;
6272 }
6273
6274 if (nextWorkInProgressHook !== null) {
6275 // There's already a work-in-progress. Reuse it.
6276 workInProgressHook = nextWorkInProgressHook;
6277 nextWorkInProgressHook = workInProgressHook.next;
6278 currentHook = nextCurrentHook;
6279 } else {
6280 // Clone from the current hook.
6281 if (nextCurrentHook === null) {
6282 throw new Error('Rendered more hooks than during the previous render.');
6283 }
6284
6285 currentHook = nextCurrentHook;
6286 var newHook = {
6287 memoizedState: currentHook.memoizedState,
6288 baseState: currentHook.baseState,
6289 baseQueue: currentHook.baseQueue,
6290 queue: currentHook.queue,
6291 next: null
6292 };
6293
6294 if (workInProgressHook === null) {
6295 // This is the first hook in the list.
6296 currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;
6297 } else {
6298 // Append to the end of the list.
6299 workInProgressHook = workInProgressHook.next = newHook;
6300 }
6301 }
6302
6303 return workInProgressHook;
6304 }
6305
6306 function createFunctionComponentUpdateQueue() {
6307 return {
6308 lastEffect: null,
6309 stores: null
6310 };
6311 }
6312
6313 function basicStateReducer(state, action) {
6314 // $FlowFixMe: Flow doesn't like mixed types
6315 return typeof action === 'function' ? action(state) : action;
6316 }
6317
6318 function mountReducer(reducer, initialArg, init) {
6319 var hook = mountWorkInProgressHook();
6320 var initialState;
6321
6322 if (init !== undefined) {
6323 initialState = init(initialArg);
6324 } else {
6325 initialState = initialArg;
6326 }
6327
6328 hook.memoizedState = hook.baseState = initialState;
6329 var queue = {
6330 pending: null,
6331 interleaved: null,
6332 lanes: NoLanes,
6333 dispatch: null,
6334 lastRenderedReducer: reducer,
6335 lastRenderedState: initialState
6336 };
6337 hook.queue = queue;
6338 var dispatch = queue.dispatch = dispatchReducerAction.bind(null, currentlyRenderingFiber$1, queue);
6339 return [hook.memoizedState, dispatch];
6340 }
6341
6342 function updateReducer(reducer, initialArg, init) {
6343 var hook = updateWorkInProgressHook();
6344 var queue = hook.queue;
6345
6346 if (queue === null) {
6347 throw new Error('Should have a queue. This is likely a bug in React. Please file an issue.');
6348 }
6349
6350 queue.lastRenderedReducer = reducer;
6351 var current = currentHook; // The last rebase update that is NOT part of the base state.
6352
6353 var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet.
6354
6355 var pendingQueue = queue.pending;
6356
6357 if (pendingQueue !== null) {
6358 // We have new updates that haven't been processed yet.
6359 // We'll add them to the base queue.
6360 if (baseQueue !== null) {
6361 // Merge the pending queue and the base queue.
6362 var baseFirst = baseQueue.next;
6363 var pendingFirst = pendingQueue.next;
6364 baseQueue.next = pendingFirst;
6365 pendingQueue.next = baseFirst;
6366 }
6367
6368 {
6369 if (current.baseQueue !== baseQueue) {
6370 // Internal invariant that should never happen, but feasibly could in
6371 // the future if we implement resuming, or some form of that.
6372 error('Internal error: Expected work-in-progress queue to be a clone. ' + 'This is a bug in React.');
6373 }
6374 }
6375
6376 current.baseQueue = baseQueue = pendingQueue;
6377 queue.pending = null;
6378 }
6379
6380 if (baseQueue !== null) {
6381 // We have a queue to process.
6382 var first = baseQueue.next;
6383 var newState = current.baseState;
6384 var newBaseState = null;
6385 var newBaseQueueFirst = null;
6386 var newBaseQueueLast = null;
6387 var update = first;
6388
6389 do {
6390 var updateLane = update.lane;
6391
6392 if (!isSubsetOfLanes(renderLanes, updateLane)) {
6393 // Priority is insufficient. Skip this update. If this is the first
6394 // skipped update, the previous update/state is the new base
6395 // update/state.
6396 var clone = {
6397 lane: updateLane,
6398 action: update.action,
6399 hasEagerState: update.hasEagerState,
6400 eagerState: update.eagerState,
6401 next: null
6402 };
6403
6404 if (newBaseQueueLast === null) {
6405 newBaseQueueFirst = newBaseQueueLast = clone;
6406 newBaseState = newState;
6407 } else {
6408 newBaseQueueLast = newBaseQueueLast.next = clone;
6409 } // Update the remaining priority in the queue.
6410 // TODO: Don't need to accumulate this. Instead, we can remove
6411 // renderLanes from the original lanes.
6412
6413
6414 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, updateLane);
6415 markSkippedUpdateLanes(updateLane);
6416 } else {
6417 // This update does have sufficient priority.
6418 if (newBaseQueueLast !== null) {
6419 var _clone = {
6420 // This update is going to be committed so we never want uncommit
6421 // it. Using NoLane works because 0 is a subset of all bitmasks, so
6422 // this will never be skipped by the check above.
6423 lane: NoLane,
6424 action: update.action,
6425 hasEagerState: update.hasEagerState,
6426 eagerState: update.eagerState,
6427 next: null
6428 };
6429 newBaseQueueLast = newBaseQueueLast.next = _clone;
6430 } // Process this update.
6431
6432
6433 if (update.hasEagerState) {
6434 // If this update is a state update (not a reducer) and was processed eagerly,
6435 // we can use the eagerly computed state
6436 newState = update.eagerState;
6437 } else {
6438 var action = update.action;
6439 newState = reducer(newState, action);
6440 }
6441 }
6442
6443 update = update.next;
6444 } while (update !== null && update !== first);
6445
6446 if (newBaseQueueLast === null) {
6447 newBaseState = newState;
6448 } else {
6449 newBaseQueueLast.next = newBaseQueueFirst;
6450 } // Mark that the fiber performed work, but only if the new state is
6451 // different from the current state.
6452
6453
6454 if (!objectIs(newState, hook.memoizedState)) {
6455 markWorkInProgressReceivedUpdate();
6456 }
6457
6458 hook.memoizedState = newState;
6459 hook.baseState = newBaseState;
6460 hook.baseQueue = newBaseQueueLast;
6461 queue.lastRenderedState = newState;
6462 } // Interleaved updates are stored on a separate queue. We aren't going to
6463 // process them during this render, but we do need to track which lanes
6464 // are remaining.
6465
6466
6467 var lastInterleaved = queue.interleaved;
6468
6469 if (lastInterleaved !== null) {
6470 var interleaved = lastInterleaved;
6471
6472 do {
6473 var interleavedLane = interleaved.lane;
6474 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, interleavedLane);
6475 markSkippedUpdateLanes(interleavedLane);
6476 interleaved = interleaved.next;
6477 } while (interleaved !== lastInterleaved);
6478 } else if (baseQueue === null) {
6479 // `queue.lanes` is used for entangling transitions. We can set it back to
6480 // zero once the queue is empty.
6481 queue.lanes = NoLanes;
6482 }
6483
6484 var dispatch = queue.dispatch;
6485 return [hook.memoizedState, dispatch];
6486 }
6487
6488 function rerenderReducer(reducer, initialArg, init) {
6489 var hook = updateWorkInProgressHook();
6490 var queue = hook.queue;
6491
6492 if (queue === null) {
6493 throw new Error('Should have a queue. This is likely a bug in React. Please file an issue.');
6494 }
6495
6496 queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous
6497 // work-in-progress hook.
6498
6499 var dispatch = queue.dispatch;
6500 var lastRenderPhaseUpdate = queue.pending;
6501 var newState = hook.memoizedState;
6502
6503 if (lastRenderPhaseUpdate !== null) {
6504 // The queue doesn't persist past this render pass.
6505 queue.pending = null;
6506 var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;
6507 var update = firstRenderPhaseUpdate;
6508
6509 do {
6510 // Process this render phase update. We don't have to check the
6511 // priority because it will always be the same as the current
6512 // render's.
6513 var action = update.action;
6514 newState = reducer(newState, action);
6515 update = update.next;
6516 } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is
6517 // different from the current state.
6518
6519
6520 if (!objectIs(newState, hook.memoizedState)) {
6521 markWorkInProgressReceivedUpdate();
6522 }
6523
6524 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
6525 // the base state unless the queue is empty.
6526 // TODO: Not sure if this is the desired semantics, but it's what we
6527 // do for gDSFP. I can't remember why.
6528
6529 if (hook.baseQueue === null) {
6530 hook.baseState = newState;
6531 }
6532
6533 queue.lastRenderedState = newState;
6534 }
6535
6536 return [newState, dispatch];
6537 }
6538
6539 function mountMutableSource(source, getSnapshot, subscribe) {
6540 {
6541 return undefined;
6542 }
6543 }
6544
6545 function updateMutableSource(source, getSnapshot, subscribe) {
6546 {
6547 return undefined;
6548 }
6549 }
6550
6551 function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
6552 var fiber = currentlyRenderingFiber$1;
6553 var hook = mountWorkInProgressHook();
6554 var nextSnapshot;
6555
6556 {
6557 nextSnapshot = getSnapshot();
6558
6559 {
6560 if (!didWarnUncachedGetSnapshot) {
6561 var cachedSnapshot = getSnapshot();
6562
6563 if (!objectIs(nextSnapshot, cachedSnapshot)) {
6564 error('The result of getSnapshot should be cached to avoid an infinite loop');
6565
6566 didWarnUncachedGetSnapshot = true;
6567 }
6568 }
6569 } // Unless we're rendering a blocking lane, schedule a consistency check.
6570 // Right before committing, we will walk the tree and check if any of the
6571 // stores were mutated.
6572 //
6573 // We won't do this if we're hydrating server-rendered content, because if
6574 // the content is stale, it's already visible anyway. Instead we'll patch
6575 // it up in a passive effect.
6576
6577
6578 var root = getWorkInProgressRoot();
6579
6580 if (root === null) {
6581 throw new Error('Expected a work-in-progress root. This is a bug in React. Please file an issue.');
6582 }
6583
6584 if (!includesBlockingLane(root, renderLanes)) {
6585 pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
6586 }
6587 } // Read the current snapshot from the store on every render. This breaks the
6588 // normal rules of React, and only works because store updates are
6589 // always synchronous.
6590
6591
6592 hook.memoizedState = nextSnapshot;
6593 var inst = {
6594 value: nextSnapshot,
6595 getSnapshot: getSnapshot
6596 };
6597 hook.queue = inst; // Schedule an effect to subscribe to the store.
6598
6599 mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]); // Schedule an effect to update the mutable instance fields. We will update
6600 // this whenever subscribe, getSnapshot, or value changes. Because there's no
6601 // clean-up function, and we track the deps correctly, we can call pushEffect
6602 // directly, without storing any additional state. For the same reason, we
6603 // don't need to set a static flag, either.
6604 // TODO: We can move this to the passive phase once we add a pre-commit
6605 // consistency check. See the next comment.
6606
6607 fiber.flags |= Passive;
6608 pushEffect(HasEffect | Passive$1, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), undefined, null);
6609 return nextSnapshot;
6610 }
6611
6612 function updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
6613 var fiber = currentlyRenderingFiber$1;
6614 var hook = updateWorkInProgressHook(); // Read the current snapshot from the store on every render. This breaks the
6615 // normal rules of React, and only works because store updates are
6616 // always synchronous.
6617
6618 var nextSnapshot = getSnapshot();
6619
6620 {
6621 if (!didWarnUncachedGetSnapshot) {
6622 var cachedSnapshot = getSnapshot();
6623
6624 if (!objectIs(nextSnapshot, cachedSnapshot)) {
6625 error('The result of getSnapshot should be cached to avoid an infinite loop');
6626
6627 didWarnUncachedGetSnapshot = true;
6628 }
6629 }
6630 }
6631
6632 var prevSnapshot = hook.memoizedState;
6633 var snapshotChanged = !objectIs(prevSnapshot, nextSnapshot);
6634
6635 if (snapshotChanged) {
6636 hook.memoizedState = nextSnapshot;
6637 markWorkInProgressReceivedUpdate();
6638 }
6639
6640 var inst = hook.queue;
6641 updateEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]); // Whenever getSnapshot or subscribe changes, we need to check in the
6642 // commit phase if there was an interleaved mutation. In concurrent mode
6643 // this can happen all the time, but even in synchronous mode, an earlier
6644 // effect may have mutated the store.
6645
6646 if (inst.getSnapshot !== getSnapshot || snapshotChanged || // Check if the susbcribe function changed. We can save some memory by
6647 // checking whether we scheduled a subscription effect above.
6648 workInProgressHook !== null && workInProgressHook.memoizedState.tag & HasEffect) {
6649 fiber.flags |= Passive;
6650 pushEffect(HasEffect | Passive$1, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), undefined, null); // Unless we're rendering a blocking lane, schedule a consistency check.
6651 // Right before committing, we will walk the tree and check if any of the
6652 // stores were mutated.
6653
6654 var root = getWorkInProgressRoot();
6655
6656 if (root === null) {
6657 throw new Error('Expected a work-in-progress root. This is a bug in React. Please file an issue.');
6658 }
6659
6660 if (!includesBlockingLane(root, renderLanes)) {
6661 pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
6662 }
6663 }
6664
6665 return nextSnapshot;
6666 }
6667
6668 function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) {
6669 fiber.flags |= StoreConsistency;
6670 var check = {
6671 getSnapshot: getSnapshot,
6672 value: renderedSnapshot
6673 };
6674 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
6675
6676 if (componentUpdateQueue === null) {
6677 componentUpdateQueue = createFunctionComponentUpdateQueue();
6678 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
6679 componentUpdateQueue.stores = [check];
6680 } else {
6681 var stores = componentUpdateQueue.stores;
6682
6683 if (stores === null) {
6684 componentUpdateQueue.stores = [check];
6685 } else {
6686 stores.push(check);
6687 }
6688 }
6689 }
6690
6691 function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) {
6692 // These are updated in the passive phase
6693 inst.value = nextSnapshot;
6694 inst.getSnapshot = getSnapshot; // Something may have been mutated in between render and commit. This could
6695 // have been in an event that fired before the passive effects, or it could
6696 // have been in a layout effect. In that case, we would have used the old
6697 // snapsho and getSnapshot values to bail out. We need to check one more time.
6698
6699 if (checkIfSnapshotChanged(inst)) {
6700 // Force a re-render.
6701 forceStoreRerender(fiber);
6702 }
6703 }
6704
6705 function subscribeToStore(fiber, inst, subscribe) {
6706 var handleStoreChange = function () {
6707 // The store changed. Check if the snapshot changed since the last time we
6708 // read from the store.
6709 if (checkIfSnapshotChanged(inst)) {
6710 // Force a re-render.
6711 forceStoreRerender(fiber);
6712 }
6713 }; // Subscribe to the store and return a clean-up function.
6714
6715
6716 return subscribe(handleStoreChange);
6717 }
6718
6719 function checkIfSnapshotChanged(inst) {
6720 var latestGetSnapshot = inst.getSnapshot;
6721 var prevValue = inst.value;
6722
6723 try {
6724 var nextValue = latestGetSnapshot();
6725 return !objectIs(prevValue, nextValue);
6726 } catch (error) {
6727 return true;
6728 }
6729 }
6730
6731 function forceStoreRerender(fiber) {
6732 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
6733 }
6734
6735 function mountState(initialState) {
6736 var hook = mountWorkInProgressHook();
6737
6738 if (typeof initialState === 'function') {
6739 // $FlowFixMe: Flow doesn't like mixed types
6740 initialState = initialState();
6741 }
6742
6743 hook.memoizedState = hook.baseState = initialState;
6744 var queue = {
6745 pending: null,
6746 interleaved: null,
6747 lanes: NoLanes,
6748 dispatch: null,
6749 lastRenderedReducer: basicStateReducer,
6750 lastRenderedState: initialState
6751 };
6752 hook.queue = queue;
6753 var dispatch = queue.dispatch = dispatchSetState.bind(null, currentlyRenderingFiber$1, queue);
6754 return [hook.memoizedState, dispatch];
6755 }
6756
6757 function updateState(initialState) {
6758 return updateReducer(basicStateReducer);
6759 }
6760
6761 function rerenderState(initialState) {
6762 return rerenderReducer(basicStateReducer);
6763 }
6764
6765 function pushEffect(tag, create, destroy, deps) {
6766 var effect = {
6767 tag: tag,
6768 create: create,
6769 destroy: destroy,
6770 deps: deps,
6771 // Circular
6772 next: null
6773 };
6774 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
6775
6776 if (componentUpdateQueue === null) {
6777 componentUpdateQueue = createFunctionComponentUpdateQueue();
6778 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
6779 componentUpdateQueue.lastEffect = effect.next = effect;
6780 } else {
6781 var lastEffect = componentUpdateQueue.lastEffect;
6782
6783 if (lastEffect === null) {
6784 componentUpdateQueue.lastEffect = effect.next = effect;
6785 } else {
6786 var firstEffect = lastEffect.next;
6787 lastEffect.next = effect;
6788 effect.next = firstEffect;
6789 componentUpdateQueue.lastEffect = effect;
6790 }
6791 }
6792
6793 return effect;
6794 }
6795
6796 function mountRef(initialValue) {
6797 var hook = mountWorkInProgressHook();
6798
6799 {
6800 var _ref2 = {
6801 current: initialValue
6802 };
6803 hook.memoizedState = _ref2;
6804 return _ref2;
6805 }
6806 }
6807
6808 function updateRef(initialValue) {
6809 var hook = updateWorkInProgressHook();
6810 return hook.memoizedState;
6811 }
6812
6813 function mountEffectImpl(fiberFlags, hookFlags, create, deps) {
6814 var hook = mountWorkInProgressHook();
6815 var nextDeps = deps === undefined ? null : deps;
6816 currentlyRenderingFiber$1.flags |= fiberFlags;
6817 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, undefined, nextDeps);
6818 }
6819
6820 function updateEffectImpl(fiberFlags, hookFlags, create, deps) {
6821 var hook = updateWorkInProgressHook();
6822 var nextDeps = deps === undefined ? null : deps;
6823 var destroy = undefined;
6824
6825 if (currentHook !== null) {
6826 var prevEffect = currentHook.memoizedState;
6827 destroy = prevEffect.destroy;
6828
6829 if (nextDeps !== null) {
6830 var prevDeps = prevEffect.deps;
6831
6832 if (areHookInputsEqual(nextDeps, prevDeps)) {
6833 hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps);
6834 return;
6835 }
6836 }
6837 }
6838
6839 currentlyRenderingFiber$1.flags |= fiberFlags;
6840 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, destroy, nextDeps);
6841 }
6842
6843 function mountEffect(create, deps) {
6844 {
6845 return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps);
6846 }
6847 }
6848
6849 function updateEffect(create, deps) {
6850 return updateEffectImpl(Passive, Passive$1, create, deps);
6851 }
6852
6853 function mountInsertionEffect(create, deps) {
6854 return mountEffectImpl(Update, Insertion, create, deps);
6855 }
6856
6857 function updateInsertionEffect(create, deps) {
6858 return updateEffectImpl(Update, Insertion, create, deps);
6859 }
6860
6861 function mountLayoutEffect(create, deps) {
6862 var fiberFlags = Update;
6863
6864 return mountEffectImpl(fiberFlags, Layout, create, deps);
6865 }
6866
6867 function updateLayoutEffect(create, deps) {
6868 return updateEffectImpl(Update, Layout, create, deps);
6869 }
6870
6871 function imperativeHandleEffect(create, ref) {
6872 if (typeof ref === 'function') {
6873 var refCallback = ref;
6874
6875 var _inst = create();
6876
6877 refCallback(_inst);
6878 return function () {
6879 refCallback(null);
6880 };
6881 } else if (ref !== null && ref !== undefined) {
6882 var refObject = ref;
6883
6884 {
6885 if (!refObject.hasOwnProperty('current')) {
6886 error('Expected useImperativeHandle() first argument to either be a ' + 'ref callback or React.createRef() object. Instead received: %s.', 'an object with keys {' + Object.keys(refObject).join(', ') + '}');
6887 }
6888 }
6889
6890 var _inst2 = create();
6891
6892 refObject.current = _inst2;
6893 return function () {
6894 refObject.current = null;
6895 };
6896 }
6897 }
6898
6899 function mountImperativeHandle(ref, create, deps) {
6900 {
6901 if (typeof create !== 'function') {
6902 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
6903 }
6904 } // TODO: If deps are provided, should we skip comparing the ref itself?
6905
6906
6907 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6908 var fiberFlags = Update;
6909
6910 return mountEffectImpl(fiberFlags, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6911 }
6912
6913 function updateImperativeHandle(ref, create, deps) {
6914 {
6915 if (typeof create !== 'function') {
6916 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
6917 }
6918 } // TODO: If deps are provided, should we skip comparing the ref itself?
6919
6920
6921 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6922 return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6923 }
6924
6925 function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.
6926 // The react-debug-hooks package injects its own implementation
6927 // so that e.g. DevTools can display custom hook values.
6928 }
6929
6930 var updateDebugValue = mountDebugValue;
6931
6932 function mountCallback(callback, deps) {
6933 var hook = mountWorkInProgressHook();
6934 var nextDeps = deps === undefined ? null : deps;
6935 hook.memoizedState = [callback, nextDeps];
6936 return callback;
6937 }
6938
6939 function updateCallback(callback, deps) {
6940 var hook = updateWorkInProgressHook();
6941 var nextDeps = deps === undefined ? null : deps;
6942 var prevState = hook.memoizedState;
6943
6944 if (prevState !== null) {
6945 if (nextDeps !== null) {
6946 var prevDeps = prevState[1];
6947
6948 if (areHookInputsEqual(nextDeps, prevDeps)) {
6949 return prevState[0];
6950 }
6951 }
6952 }
6953
6954 hook.memoizedState = [callback, nextDeps];
6955 return callback;
6956 }
6957
6958 function mountMemo(nextCreate, deps) {
6959 var hook = mountWorkInProgressHook();
6960 var nextDeps = deps === undefined ? null : deps;
6961 var nextValue = nextCreate();
6962 hook.memoizedState = [nextValue, nextDeps];
6963 return nextValue;
6964 }
6965
6966 function updateMemo(nextCreate, deps) {
6967 var hook = updateWorkInProgressHook();
6968 var nextDeps = deps === undefined ? null : deps;
6969 var prevState = hook.memoizedState;
6970
6971 if (prevState !== null) {
6972 // Assume these are defined. If they're not, areHookInputsEqual will warn.
6973 if (nextDeps !== null) {
6974 var prevDeps = prevState[1];
6975
6976 if (areHookInputsEqual(nextDeps, prevDeps)) {
6977 return prevState[0];
6978 }
6979 }
6980 }
6981
6982 var nextValue = nextCreate();
6983 hook.memoizedState = [nextValue, nextDeps];
6984 return nextValue;
6985 }
6986
6987 function mountDeferredValue(value) {
6988 var _mountState = mountState(value),
6989 prevValue = _mountState[0],
6990 setValue = _mountState[1];
6991
6992 mountEffect(function () {
6993 var prevTransition = ReactCurrentBatchConfig$1.transition;
6994 ReactCurrentBatchConfig$1.transition = {};
6995
6996 try {
6997 setValue(value);
6998 } finally {
6999 ReactCurrentBatchConfig$1.transition = prevTransition;
7000 }
7001 }, [value]);
7002 return prevValue;
7003 }
7004
7005 function updateDeferredValue(value) {
7006 var _updateState = updateState(),
7007 prevValue = _updateState[0],
7008 setValue = _updateState[1];
7009
7010 updateEffect(function () {
7011 var prevTransition = ReactCurrentBatchConfig$1.transition;
7012 ReactCurrentBatchConfig$1.transition = {};
7013
7014 try {
7015 setValue(value);
7016 } finally {
7017 ReactCurrentBatchConfig$1.transition = prevTransition;
7018 }
7019 }, [value]);
7020 return prevValue;
7021 }
7022
7023 function rerenderDeferredValue(value) {
7024 var _rerenderState = rerenderState(),
7025 prevValue = _rerenderState[0],
7026 setValue = _rerenderState[1];
7027
7028 updateEffect(function () {
7029 var prevTransition = ReactCurrentBatchConfig$1.transition;
7030 ReactCurrentBatchConfig$1.transition = {};
7031
7032 try {
7033 setValue(value);
7034 } finally {
7035 ReactCurrentBatchConfig$1.transition = prevTransition;
7036 }
7037 }, [value]);
7038 return prevValue;
7039 }
7040
7041 function startTransition(setPending, callback, options) {
7042 var previousPriority = getCurrentUpdatePriority();
7043 setCurrentUpdatePriority(higherEventPriority(previousPriority, ContinuousEventPriority));
7044 setPending(true);
7045 var prevTransition = ReactCurrentBatchConfig$1.transition;
7046 ReactCurrentBatchConfig$1.transition = {};
7047 var currentTransition = ReactCurrentBatchConfig$1.transition;
7048
7049 {
7050 ReactCurrentBatchConfig$1.transition._updatedFibers = new Set();
7051 }
7052
7053 try {
7054 setPending(false);
7055 callback();
7056 } finally {
7057 setCurrentUpdatePriority(previousPriority);
7058 ReactCurrentBatchConfig$1.transition = prevTransition;
7059
7060 {
7061 if (prevTransition === null && currentTransition._updatedFibers) {
7062 var updatedFibersCount = currentTransition._updatedFibers.size;
7063
7064 if (updatedFibersCount > 10) {
7065 warn('Detected a large number of updates inside startTransition. ' + 'If this is due to a subscription please re-write it to use React provided hooks. ' + 'Otherwise concurrent mode guarantees are off the table.');
7066 }
7067
7068 currentTransition._updatedFibers.clear();
7069 }
7070 }
7071 }
7072 }
7073
7074 function mountTransition() {
7075 var _mountState2 = mountState(false),
7076 isPending = _mountState2[0],
7077 setPending = _mountState2[1]; // The `start` method never changes.
7078
7079
7080 var start = startTransition.bind(null, setPending);
7081 var hook = mountWorkInProgressHook();
7082 hook.memoizedState = start;
7083 return [isPending, start];
7084 }
7085
7086 function updateTransition() {
7087 var _updateState2 = updateState(),
7088 isPending = _updateState2[0];
7089
7090 var hook = updateWorkInProgressHook();
7091 var start = hook.memoizedState;
7092 return [isPending, start];
7093 }
7094
7095 function rerenderTransition() {
7096 var _rerenderState2 = rerenderState(),
7097 isPending = _rerenderState2[0];
7098
7099 var hook = updateWorkInProgressHook();
7100 var start = hook.memoizedState;
7101 return [isPending, start];
7102 }
7103
7104 var isUpdatingOpaqueValueInRenderPhase = false;
7105 function getIsUpdatingOpaqueValueInRenderPhaseInDEV() {
7106 {
7107 return isUpdatingOpaqueValueInRenderPhase;
7108 }
7109 }
7110
7111 function mountId() {
7112 var hook = mountWorkInProgressHook();
7113 var root = getWorkInProgressRoot(); // TODO: In Fizz, id generation is specific to each server config. Maybe we
7114 // should do this in Fiber, too? Deferring this decision for now because
7115 // there's no other place to store the prefix except for an internal field on
7116 // the public createRoot object, which the fiber tree does not currently have
7117 // a reference to.
7118
7119 var identifierPrefix = root.identifierPrefix;
7120 var id;
7121
7122 {
7123 // Use a lowercase r prefix for client-generated ids.
7124 var globalClientId = globalClientIdCounter++;
7125 id = ':' + identifierPrefix + 'r' + globalClientId.toString(32) + ':';
7126 }
7127
7128 hook.memoizedState = id;
7129 return id;
7130 }
7131
7132 function updateId() {
7133 var hook = updateWorkInProgressHook();
7134 var id = hook.memoizedState;
7135 return id;
7136 }
7137
7138 function dispatchReducerAction(fiber, queue, action) {
7139 {
7140 if (typeof arguments[3] === 'function') {
7141 error("State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().');
7142 }
7143 }
7144
7145 var lane = requestUpdateLane(fiber);
7146 var update = {
7147 lane: lane,
7148 action: action,
7149 hasEagerState: false,
7150 eagerState: null,
7151 next: null
7152 };
7153
7154 if (isRenderPhaseUpdate(fiber)) {
7155 enqueueRenderPhaseUpdate(queue, update);
7156 } else {
7157 enqueueUpdate$1(fiber, queue, update);
7158 var eventTime = requestEventTime();
7159 var root = scheduleUpdateOnFiber(fiber, lane, eventTime);
7160
7161 if (root !== null) {
7162 entangleTransitionUpdate(root, queue, lane);
7163 }
7164 }
7165 }
7166
7167 function dispatchSetState(fiber, queue, action) {
7168 {
7169 if (typeof arguments[3] === 'function') {
7170 error("State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().');
7171 }
7172 }
7173
7174 var lane = requestUpdateLane(fiber);
7175 var update = {
7176 lane: lane,
7177 action: action,
7178 hasEagerState: false,
7179 eagerState: null,
7180 next: null
7181 };
7182
7183 if (isRenderPhaseUpdate(fiber)) {
7184 enqueueRenderPhaseUpdate(queue, update);
7185 } else {
7186 enqueueUpdate$1(fiber, queue, update);
7187 var alternate = fiber.alternate;
7188
7189 if (fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes)) {
7190 // The queue is currently empty, which means we can eagerly compute the
7191 // next state before entering the render phase. If the new state is the
7192 // same as the current state, we may be able to bail out entirely.
7193 var lastRenderedReducer = queue.lastRenderedReducer;
7194
7195 if (lastRenderedReducer !== null) {
7196 var prevDispatcher;
7197
7198 {
7199 prevDispatcher = ReactCurrentDispatcher$1.current;
7200 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7201 }
7202
7203 try {
7204 var currentState = queue.lastRenderedState;
7205 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
7206 // it, on the update object. If the reducer hasn't changed by the
7207 // time we enter the render phase, then the eager state can be used
7208 // without calling the reducer again.
7209
7210 update.hasEagerState = true;
7211 update.eagerState = eagerState;
7212
7213 if (objectIs(eagerState, currentState)) {
7214 // Fast path. We can bail out without scheduling React to re-render.
7215 // It's still possible that we'll need to rebase this update later,
7216 // if the component re-renders for a different reason and by that
7217 // time the reducer has changed.
7218 return;
7219 }
7220 } catch (error) {// Suppress the error. It will throw again in the render phase.
7221 } finally {
7222 {
7223 ReactCurrentDispatcher$1.current = prevDispatcher;
7224 }
7225 }
7226 }
7227 }
7228
7229 var eventTime = requestEventTime();
7230 var root = scheduleUpdateOnFiber(fiber, lane, eventTime);
7231
7232 if (root !== null) {
7233 entangleTransitionUpdate(root, queue, lane);
7234 }
7235 }
7236 }
7237
7238 function isRenderPhaseUpdate(fiber) {
7239 var alternate = fiber.alternate;
7240 return fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1;
7241 }
7242
7243 function enqueueRenderPhaseUpdate(queue, update) {
7244 // This is a render phase update. Stash it in a lazily-created map of
7245 // queue -> linked list of updates. After this render pass, we'll restart
7246 // and apply the stashed updates on top of the work-in-progress hook.
7247 didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true;
7248 var pending = queue.pending;
7249
7250 if (pending === null) {
7251 // This is the first update. Create a circular list.
7252 update.next = update;
7253 } else {
7254 update.next = pending.next;
7255 pending.next = update;
7256 }
7257
7258 queue.pending = update;
7259 }
7260
7261 function enqueueUpdate$1(fiber, queue, update, lane) {
7262 if (isInterleavedUpdate(fiber)) {
7263 var interleaved = queue.interleaved;
7264
7265 if (interleaved === null) {
7266 // This is the first update. Create a circular list.
7267 update.next = update; // At the end of the current render, this queue's interleaved updates will
7268 // be transferred to the pending queue.
7269
7270 pushInterleavedQueue(queue);
7271 } else {
7272 update.next = interleaved.next;
7273 interleaved.next = update;
7274 }
7275
7276 queue.interleaved = update;
7277 } else {
7278 var pending = queue.pending;
7279
7280 if (pending === null) {
7281 // This is the first update. Create a circular list.
7282 update.next = update;
7283 } else {
7284 update.next = pending.next;
7285 pending.next = update;
7286 }
7287
7288 queue.pending = update;
7289 }
7290 }
7291
7292 function entangleTransitionUpdate(root, queue, lane) {
7293 if (isTransitionLane(lane)) {
7294 var queueLanes = queue.lanes; // If any entangled lanes are no longer pending on the root, then they
7295 // must have finished. We can remove them from the shared queue, which
7296 // represents a superset of the actually pending lanes. In some cases we
7297 // may entangle more than we need to, but that's OK. In fact it's worse if
7298 // we *don't* entangle when we should.
7299
7300 queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes.
7301
7302 var newQueueLanes = mergeLanes(queueLanes, lane);
7303 queue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if
7304 // the lane finished since the last time we entangled it. So we need to
7305 // entangle it again, just to be sure.
7306
7307 markRootEntangled(root, newQueueLanes);
7308 }
7309 }
7310
7311 var ContextOnlyDispatcher = {
7312 readContext: readContext,
7313 useCallback: throwInvalidHookError,
7314 useContext: throwInvalidHookError,
7315 useEffect: throwInvalidHookError,
7316 useImperativeHandle: throwInvalidHookError,
7317 useInsertionEffect: throwInvalidHookError,
7318 useLayoutEffect: throwInvalidHookError,
7319 useMemo: throwInvalidHookError,
7320 useReducer: throwInvalidHookError,
7321 useRef: throwInvalidHookError,
7322 useState: throwInvalidHookError,
7323 useDebugValue: throwInvalidHookError,
7324 useDeferredValue: throwInvalidHookError,
7325 useTransition: throwInvalidHookError,
7326 useMutableSource: throwInvalidHookError,
7327 useSyncExternalStore: throwInvalidHookError,
7328 useId: throwInvalidHookError,
7329 unstable_isNewReconciler: enableNewReconciler
7330 };
7331
7332 var HooksDispatcherOnMountInDEV = null;
7333 var HooksDispatcherOnMountWithHookTypesInDEV = null;
7334 var HooksDispatcherOnUpdateInDEV = null;
7335 var HooksDispatcherOnRerenderInDEV = null;
7336 var InvalidNestedHooksDispatcherOnMountInDEV = null;
7337 var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
7338 var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
7339
7340 {
7341 var warnInvalidContextAccess = function () {
7342 error('Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().');
7343 };
7344
7345 var warnInvalidHookAccess = function () {
7346 error('Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' + 'You can only call Hooks at the top level of your React function. ' + 'For more information, see ' + 'https://reactjs.org/link/rules-of-hooks');
7347 };
7348
7349 HooksDispatcherOnMountInDEV = {
7350 readContext: function (context) {
7351 return readContext(context);
7352 },
7353 useCallback: function (callback, deps) {
7354 currentHookNameInDev = 'useCallback';
7355 mountHookTypesDev();
7356 checkDepsAreArrayDev(deps);
7357 return mountCallback(callback, deps);
7358 },
7359 useContext: function (context) {
7360 currentHookNameInDev = 'useContext';
7361 mountHookTypesDev();
7362 return readContext(context);
7363 },
7364 useEffect: function (create, deps) {
7365 currentHookNameInDev = 'useEffect';
7366 mountHookTypesDev();
7367 checkDepsAreArrayDev(deps);
7368 return mountEffect(create, deps);
7369 },
7370 useImperativeHandle: function (ref, create, deps) {
7371 currentHookNameInDev = 'useImperativeHandle';
7372 mountHookTypesDev();
7373 checkDepsAreArrayDev(deps);
7374 return mountImperativeHandle(ref, create, deps);
7375 },
7376 useInsertionEffect: function (create, deps) {
7377 currentHookNameInDev = 'useInsertionEffect';
7378 mountHookTypesDev();
7379 checkDepsAreArrayDev(deps);
7380 return mountInsertionEffect(create, deps);
7381 },
7382 useLayoutEffect: function (create, deps) {
7383 currentHookNameInDev = 'useLayoutEffect';
7384 mountHookTypesDev();
7385 checkDepsAreArrayDev(deps);
7386 return mountLayoutEffect(create, deps);
7387 },
7388 useMemo: function (create, deps) {
7389 currentHookNameInDev = 'useMemo';
7390 mountHookTypesDev();
7391 checkDepsAreArrayDev(deps);
7392 var prevDispatcher = ReactCurrentDispatcher$1.current;
7393 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7394
7395 try {
7396 return mountMemo(create, deps);
7397 } finally {
7398 ReactCurrentDispatcher$1.current = prevDispatcher;
7399 }
7400 },
7401 useReducer: function (reducer, initialArg, init) {
7402 currentHookNameInDev = 'useReducer';
7403 mountHookTypesDev();
7404 var prevDispatcher = ReactCurrentDispatcher$1.current;
7405 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7406
7407 try {
7408 return mountReducer(reducer, initialArg, init);
7409 } finally {
7410 ReactCurrentDispatcher$1.current = prevDispatcher;
7411 }
7412 },
7413 useRef: function (initialValue) {
7414 currentHookNameInDev = 'useRef';
7415 mountHookTypesDev();
7416 return mountRef(initialValue);
7417 },
7418 useState: function (initialState) {
7419 currentHookNameInDev = 'useState';
7420 mountHookTypesDev();
7421 var prevDispatcher = ReactCurrentDispatcher$1.current;
7422 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7423
7424 try {
7425 return mountState(initialState);
7426 } finally {
7427 ReactCurrentDispatcher$1.current = prevDispatcher;
7428 }
7429 },
7430 useDebugValue: function (value, formatterFn) {
7431 currentHookNameInDev = 'useDebugValue';
7432 mountHookTypesDev();
7433 return mountDebugValue();
7434 },
7435 useDeferredValue: function (value) {
7436 currentHookNameInDev = 'useDeferredValue';
7437 mountHookTypesDev();
7438 return mountDeferredValue(value);
7439 },
7440 useTransition: function () {
7441 currentHookNameInDev = 'useTransition';
7442 mountHookTypesDev();
7443 return mountTransition();
7444 },
7445 useMutableSource: function (source, getSnapshot, subscribe) {
7446 currentHookNameInDev = 'useMutableSource';
7447 mountHookTypesDev();
7448 return mountMutableSource();
7449 },
7450 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
7451 currentHookNameInDev = 'useSyncExternalStore';
7452 mountHookTypesDev();
7453 return mountSyncExternalStore(subscribe, getSnapshot);
7454 },
7455 useId: function () {
7456 currentHookNameInDev = 'useId';
7457 mountHookTypesDev();
7458 return mountId();
7459 },
7460 unstable_isNewReconciler: enableNewReconciler
7461 };
7462
7463 HooksDispatcherOnMountWithHookTypesInDEV = {
7464 readContext: function (context) {
7465 return readContext(context);
7466 },
7467 useCallback: function (callback, deps) {
7468 currentHookNameInDev = 'useCallback';
7469 updateHookTypesDev();
7470 return mountCallback(callback, deps);
7471 },
7472 useContext: function (context) {
7473 currentHookNameInDev = 'useContext';
7474 updateHookTypesDev();
7475 return readContext(context);
7476 },
7477 useEffect: function (create, deps) {
7478 currentHookNameInDev = 'useEffect';
7479 updateHookTypesDev();
7480 return mountEffect(create, deps);
7481 },
7482 useImperativeHandle: function (ref, create, deps) {
7483 currentHookNameInDev = 'useImperativeHandle';
7484 updateHookTypesDev();
7485 return mountImperativeHandle(ref, create, deps);
7486 },
7487 useInsertionEffect: function (create, deps) {
7488 currentHookNameInDev = 'useInsertionEffect';
7489 updateHookTypesDev();
7490 return mountInsertionEffect(create, deps);
7491 },
7492 useLayoutEffect: function (create, deps) {
7493 currentHookNameInDev = 'useLayoutEffect';
7494 updateHookTypesDev();
7495 return mountLayoutEffect(create, deps);
7496 },
7497 useMemo: function (create, deps) {
7498 currentHookNameInDev = 'useMemo';
7499 updateHookTypesDev();
7500 var prevDispatcher = ReactCurrentDispatcher$1.current;
7501 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7502
7503 try {
7504 return mountMemo(create, deps);
7505 } finally {
7506 ReactCurrentDispatcher$1.current = prevDispatcher;
7507 }
7508 },
7509 useReducer: function (reducer, initialArg, init) {
7510 currentHookNameInDev = 'useReducer';
7511 updateHookTypesDev();
7512 var prevDispatcher = ReactCurrentDispatcher$1.current;
7513 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7514
7515 try {
7516 return mountReducer(reducer, initialArg, init);
7517 } finally {
7518 ReactCurrentDispatcher$1.current = prevDispatcher;
7519 }
7520 },
7521 useRef: function (initialValue) {
7522 currentHookNameInDev = 'useRef';
7523 updateHookTypesDev();
7524 return mountRef(initialValue);
7525 },
7526 useState: function (initialState) {
7527 currentHookNameInDev = 'useState';
7528 updateHookTypesDev();
7529 var prevDispatcher = ReactCurrentDispatcher$1.current;
7530 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7531
7532 try {
7533 return mountState(initialState);
7534 } finally {
7535 ReactCurrentDispatcher$1.current = prevDispatcher;
7536 }
7537 },
7538 useDebugValue: function (value, formatterFn) {
7539 currentHookNameInDev = 'useDebugValue';
7540 updateHookTypesDev();
7541 return mountDebugValue();
7542 },
7543 useDeferredValue: function (value) {
7544 currentHookNameInDev = 'useDeferredValue';
7545 updateHookTypesDev();
7546 return mountDeferredValue(value);
7547 },
7548 useTransition: function () {
7549 currentHookNameInDev = 'useTransition';
7550 updateHookTypesDev();
7551 return mountTransition();
7552 },
7553 useMutableSource: function (source, getSnapshot, subscribe) {
7554 currentHookNameInDev = 'useMutableSource';
7555 updateHookTypesDev();
7556 return mountMutableSource();
7557 },
7558 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
7559 currentHookNameInDev = 'useSyncExternalStore';
7560 updateHookTypesDev();
7561 return mountSyncExternalStore(subscribe, getSnapshot);
7562 },
7563 useId: function () {
7564 currentHookNameInDev = 'useId';
7565 updateHookTypesDev();
7566 return mountId();
7567 },
7568 unstable_isNewReconciler: enableNewReconciler
7569 };
7570
7571 HooksDispatcherOnUpdateInDEV = {
7572 readContext: function (context) {
7573 return readContext(context);
7574 },
7575 useCallback: function (callback, deps) {
7576 currentHookNameInDev = 'useCallback';
7577 updateHookTypesDev();
7578 return updateCallback(callback, deps);
7579 },
7580 useContext: function (context) {
7581 currentHookNameInDev = 'useContext';
7582 updateHookTypesDev();
7583 return readContext(context);
7584 },
7585 useEffect: function (create, deps) {
7586 currentHookNameInDev = 'useEffect';
7587 updateHookTypesDev();
7588 return updateEffect(create, deps);
7589 },
7590 useImperativeHandle: function (ref, create, deps) {
7591 currentHookNameInDev = 'useImperativeHandle';
7592 updateHookTypesDev();
7593 return updateImperativeHandle(ref, create, deps);
7594 },
7595 useInsertionEffect: function (create, deps) {
7596 currentHookNameInDev = 'useInsertionEffect';
7597 updateHookTypesDev();
7598 return updateInsertionEffect(create, deps);
7599 },
7600 useLayoutEffect: function (create, deps) {
7601 currentHookNameInDev = 'useLayoutEffect';
7602 updateHookTypesDev();
7603 return updateLayoutEffect(create, deps);
7604 },
7605 useMemo: function (create, deps) {
7606 currentHookNameInDev = 'useMemo';
7607 updateHookTypesDev();
7608 var prevDispatcher = ReactCurrentDispatcher$1.current;
7609 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7610
7611 try {
7612 return updateMemo(create, deps);
7613 } finally {
7614 ReactCurrentDispatcher$1.current = prevDispatcher;
7615 }
7616 },
7617 useReducer: function (reducer, initialArg, init) {
7618 currentHookNameInDev = 'useReducer';
7619 updateHookTypesDev();
7620 var prevDispatcher = ReactCurrentDispatcher$1.current;
7621 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7622
7623 try {
7624 return updateReducer(reducer, initialArg, init);
7625 } finally {
7626 ReactCurrentDispatcher$1.current = prevDispatcher;
7627 }
7628 },
7629 useRef: function (initialValue) {
7630 currentHookNameInDev = 'useRef';
7631 updateHookTypesDev();
7632 return updateRef();
7633 },
7634 useState: function (initialState) {
7635 currentHookNameInDev = 'useState';
7636 updateHookTypesDev();
7637 var prevDispatcher = ReactCurrentDispatcher$1.current;
7638 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7639
7640 try {
7641 return updateState(initialState);
7642 } finally {
7643 ReactCurrentDispatcher$1.current = prevDispatcher;
7644 }
7645 },
7646 useDebugValue: function (value, formatterFn) {
7647 currentHookNameInDev = 'useDebugValue';
7648 updateHookTypesDev();
7649 return updateDebugValue();
7650 },
7651 useDeferredValue: function (value) {
7652 currentHookNameInDev = 'useDeferredValue';
7653 updateHookTypesDev();
7654 return updateDeferredValue(value);
7655 },
7656 useTransition: function () {
7657 currentHookNameInDev = 'useTransition';
7658 updateHookTypesDev();
7659 return updateTransition();
7660 },
7661 useMutableSource: function (source, getSnapshot, subscribe) {
7662 currentHookNameInDev = 'useMutableSource';
7663 updateHookTypesDev();
7664 return updateMutableSource();
7665 },
7666 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
7667 currentHookNameInDev = 'useSyncExternalStore';
7668 updateHookTypesDev();
7669 return updateSyncExternalStore(subscribe, getSnapshot);
7670 },
7671 useId: function () {
7672 currentHookNameInDev = 'useId';
7673 updateHookTypesDev();
7674 return updateId();
7675 },
7676 unstable_isNewReconciler: enableNewReconciler
7677 };
7678
7679 HooksDispatcherOnRerenderInDEV = {
7680 readContext: function (context) {
7681 return readContext(context);
7682 },
7683 useCallback: function (callback, deps) {
7684 currentHookNameInDev = 'useCallback';
7685 updateHookTypesDev();
7686 return updateCallback(callback, deps);
7687 },
7688 useContext: function (context) {
7689 currentHookNameInDev = 'useContext';
7690 updateHookTypesDev();
7691 return readContext(context);
7692 },
7693 useEffect: function (create, deps) {
7694 currentHookNameInDev = 'useEffect';
7695 updateHookTypesDev();
7696 return updateEffect(create, deps);
7697 },
7698 useImperativeHandle: function (ref, create, deps) {
7699 currentHookNameInDev = 'useImperativeHandle';
7700 updateHookTypesDev();
7701 return updateImperativeHandle(ref, create, deps);
7702 },
7703 useInsertionEffect: function (create, deps) {
7704 currentHookNameInDev = 'useInsertionEffect';
7705 updateHookTypesDev();
7706 return updateInsertionEffect(create, deps);
7707 },
7708 useLayoutEffect: function (create, deps) {
7709 currentHookNameInDev = 'useLayoutEffect';
7710 updateHookTypesDev();
7711 return updateLayoutEffect(create, deps);
7712 },
7713 useMemo: function (create, deps) {
7714 currentHookNameInDev = 'useMemo';
7715 updateHookTypesDev();
7716 var prevDispatcher = ReactCurrentDispatcher$1.current;
7717 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
7718
7719 try {
7720 return updateMemo(create, deps);
7721 } finally {
7722 ReactCurrentDispatcher$1.current = prevDispatcher;
7723 }
7724 },
7725 useReducer: function (reducer, initialArg, init) {
7726 currentHookNameInDev = 'useReducer';
7727 updateHookTypesDev();
7728 var prevDispatcher = ReactCurrentDispatcher$1.current;
7729 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
7730
7731 try {
7732 return rerenderReducer(reducer, initialArg, init);
7733 } finally {
7734 ReactCurrentDispatcher$1.current = prevDispatcher;
7735 }
7736 },
7737 useRef: function (initialValue) {
7738 currentHookNameInDev = 'useRef';
7739 updateHookTypesDev();
7740 return updateRef();
7741 },
7742 useState: function (initialState) {
7743 currentHookNameInDev = 'useState';
7744 updateHookTypesDev();
7745 var prevDispatcher = ReactCurrentDispatcher$1.current;
7746 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
7747
7748 try {
7749 return rerenderState(initialState);
7750 } finally {
7751 ReactCurrentDispatcher$1.current = prevDispatcher;
7752 }
7753 },
7754 useDebugValue: function (value, formatterFn) {
7755 currentHookNameInDev = 'useDebugValue';
7756 updateHookTypesDev();
7757 return updateDebugValue();
7758 },
7759 useDeferredValue: function (value) {
7760 currentHookNameInDev = 'useDeferredValue';
7761 updateHookTypesDev();
7762 return rerenderDeferredValue(value);
7763 },
7764 useTransition: function () {
7765 currentHookNameInDev = 'useTransition';
7766 updateHookTypesDev();
7767 return rerenderTransition();
7768 },
7769 useMutableSource: function (source, getSnapshot, subscribe) {
7770 currentHookNameInDev = 'useMutableSource';
7771 updateHookTypesDev();
7772 return updateMutableSource();
7773 },
7774 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
7775 currentHookNameInDev = 'useSyncExternalStore';
7776 updateHookTypesDev();
7777 return updateSyncExternalStore(subscribe, getSnapshot);
7778 },
7779 useId: function () {
7780 currentHookNameInDev = 'useId';
7781 updateHookTypesDev();
7782 return updateId();
7783 },
7784 unstable_isNewReconciler: enableNewReconciler
7785 };
7786
7787 InvalidNestedHooksDispatcherOnMountInDEV = {
7788 readContext: function (context) {
7789 warnInvalidContextAccess();
7790 return readContext(context);
7791 },
7792 useCallback: function (callback, deps) {
7793 currentHookNameInDev = 'useCallback';
7794 warnInvalidHookAccess();
7795 mountHookTypesDev();
7796 return mountCallback(callback, deps);
7797 },
7798 useContext: function (context) {
7799 currentHookNameInDev = 'useContext';
7800 warnInvalidHookAccess();
7801 mountHookTypesDev();
7802 return readContext(context);
7803 },
7804 useEffect: function (create, deps) {
7805 currentHookNameInDev = 'useEffect';
7806 warnInvalidHookAccess();
7807 mountHookTypesDev();
7808 return mountEffect(create, deps);
7809 },
7810 useImperativeHandle: function (ref, create, deps) {
7811 currentHookNameInDev = 'useImperativeHandle';
7812 warnInvalidHookAccess();
7813 mountHookTypesDev();
7814 return mountImperativeHandle(ref, create, deps);
7815 },
7816 useInsertionEffect: function (create, deps) {
7817 currentHookNameInDev = 'useInsertionEffect';
7818 warnInvalidHookAccess();
7819 mountHookTypesDev();
7820 return mountInsertionEffect(create, deps);
7821 },
7822 useLayoutEffect: function (create, deps) {
7823 currentHookNameInDev = 'useLayoutEffect';
7824 warnInvalidHookAccess();
7825 mountHookTypesDev();
7826 return mountLayoutEffect(create, deps);
7827 },
7828 useMemo: function (create, deps) {
7829 currentHookNameInDev = 'useMemo';
7830 warnInvalidHookAccess();
7831 mountHookTypesDev();
7832 var prevDispatcher = ReactCurrentDispatcher$1.current;
7833 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7834
7835 try {
7836 return mountMemo(create, deps);
7837 } finally {
7838 ReactCurrentDispatcher$1.current = prevDispatcher;
7839 }
7840 },
7841 useReducer: function (reducer, initialArg, init) {
7842 currentHookNameInDev = 'useReducer';
7843 warnInvalidHookAccess();
7844 mountHookTypesDev();
7845 var prevDispatcher = ReactCurrentDispatcher$1.current;
7846 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7847
7848 try {
7849 return mountReducer(reducer, initialArg, init);
7850 } finally {
7851 ReactCurrentDispatcher$1.current = prevDispatcher;
7852 }
7853 },
7854 useRef: function (initialValue) {
7855 currentHookNameInDev = 'useRef';
7856 warnInvalidHookAccess();
7857 mountHookTypesDev();
7858 return mountRef(initialValue);
7859 },
7860 useState: function (initialState) {
7861 currentHookNameInDev = 'useState';
7862 warnInvalidHookAccess();
7863 mountHookTypesDev();
7864 var prevDispatcher = ReactCurrentDispatcher$1.current;
7865 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7866
7867 try {
7868 return mountState(initialState);
7869 } finally {
7870 ReactCurrentDispatcher$1.current = prevDispatcher;
7871 }
7872 },
7873 useDebugValue: function (value, formatterFn) {
7874 currentHookNameInDev = 'useDebugValue';
7875 warnInvalidHookAccess();
7876 mountHookTypesDev();
7877 return mountDebugValue();
7878 },
7879 useDeferredValue: function (value) {
7880 currentHookNameInDev = 'useDeferredValue';
7881 warnInvalidHookAccess();
7882 mountHookTypesDev();
7883 return mountDeferredValue(value);
7884 },
7885 useTransition: function () {
7886 currentHookNameInDev = 'useTransition';
7887 warnInvalidHookAccess();
7888 mountHookTypesDev();
7889 return mountTransition();
7890 },
7891 useMutableSource: function (source, getSnapshot, subscribe) {
7892 currentHookNameInDev = 'useMutableSource';
7893 warnInvalidHookAccess();
7894 mountHookTypesDev();
7895 return mountMutableSource();
7896 },
7897 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
7898 currentHookNameInDev = 'useSyncExternalStore';
7899 warnInvalidHookAccess();
7900 mountHookTypesDev();
7901 return mountSyncExternalStore(subscribe, getSnapshot);
7902 },
7903 useId: function () {
7904 currentHookNameInDev = 'useId';
7905 warnInvalidHookAccess();
7906 mountHookTypesDev();
7907 return mountId();
7908 },
7909 unstable_isNewReconciler: enableNewReconciler
7910 };
7911
7912 InvalidNestedHooksDispatcherOnUpdateInDEV = {
7913 readContext: function (context) {
7914 warnInvalidContextAccess();
7915 return readContext(context);
7916 },
7917 useCallback: function (callback, deps) {
7918 currentHookNameInDev = 'useCallback';
7919 warnInvalidHookAccess();
7920 updateHookTypesDev();
7921 return updateCallback(callback, deps);
7922 },
7923 useContext: function (context) {
7924 currentHookNameInDev = 'useContext';
7925 warnInvalidHookAccess();
7926 updateHookTypesDev();
7927 return readContext(context);
7928 },
7929 useEffect: function (create, deps) {
7930 currentHookNameInDev = 'useEffect';
7931 warnInvalidHookAccess();
7932 updateHookTypesDev();
7933 return updateEffect(create, deps);
7934 },
7935 useImperativeHandle: function (ref, create, deps) {
7936 currentHookNameInDev = 'useImperativeHandle';
7937 warnInvalidHookAccess();
7938 updateHookTypesDev();
7939 return updateImperativeHandle(ref, create, deps);
7940 },
7941 useInsertionEffect: function (create, deps) {
7942 currentHookNameInDev = 'useInsertionEffect';
7943 warnInvalidHookAccess();
7944 updateHookTypesDev();
7945 return updateInsertionEffect(create, deps);
7946 },
7947 useLayoutEffect: function (create, deps) {
7948 currentHookNameInDev = 'useLayoutEffect';
7949 warnInvalidHookAccess();
7950 updateHookTypesDev();
7951 return updateLayoutEffect(create, deps);
7952 },
7953 useMemo: function (create, deps) {
7954 currentHookNameInDev = 'useMemo';
7955 warnInvalidHookAccess();
7956 updateHookTypesDev();
7957 var prevDispatcher = ReactCurrentDispatcher$1.current;
7958 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7959
7960 try {
7961 return updateMemo(create, deps);
7962 } finally {
7963 ReactCurrentDispatcher$1.current = prevDispatcher;
7964 }
7965 },
7966 useReducer: function (reducer, initialArg, init) {
7967 currentHookNameInDev = 'useReducer';
7968 warnInvalidHookAccess();
7969 updateHookTypesDev();
7970 var prevDispatcher = ReactCurrentDispatcher$1.current;
7971 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7972
7973 try {
7974 return updateReducer(reducer, initialArg, init);
7975 } finally {
7976 ReactCurrentDispatcher$1.current = prevDispatcher;
7977 }
7978 },
7979 useRef: function (initialValue) {
7980 currentHookNameInDev = 'useRef';
7981 warnInvalidHookAccess();
7982 updateHookTypesDev();
7983 return updateRef();
7984 },
7985 useState: function (initialState) {
7986 currentHookNameInDev = 'useState';
7987 warnInvalidHookAccess();
7988 updateHookTypesDev();
7989 var prevDispatcher = ReactCurrentDispatcher$1.current;
7990 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7991
7992 try {
7993 return updateState(initialState);
7994 } finally {
7995 ReactCurrentDispatcher$1.current = prevDispatcher;
7996 }
7997 },
7998 useDebugValue: function (value, formatterFn) {
7999 currentHookNameInDev = 'useDebugValue';
8000 warnInvalidHookAccess();
8001 updateHookTypesDev();
8002 return updateDebugValue();
8003 },
8004 useDeferredValue: function (value) {
8005 currentHookNameInDev = 'useDeferredValue';
8006 warnInvalidHookAccess();
8007 updateHookTypesDev();
8008 return updateDeferredValue(value);
8009 },
8010 useTransition: function () {
8011 currentHookNameInDev = 'useTransition';
8012 warnInvalidHookAccess();
8013 updateHookTypesDev();
8014 return updateTransition();
8015 },
8016 useMutableSource: function (source, getSnapshot, subscribe) {
8017 currentHookNameInDev = 'useMutableSource';
8018 warnInvalidHookAccess();
8019 updateHookTypesDev();
8020 return updateMutableSource();
8021 },
8022 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
8023 currentHookNameInDev = 'useSyncExternalStore';
8024 warnInvalidHookAccess();
8025 updateHookTypesDev();
8026 return updateSyncExternalStore(subscribe, getSnapshot);
8027 },
8028 useId: function () {
8029 currentHookNameInDev = 'useId';
8030 warnInvalidHookAccess();
8031 updateHookTypesDev();
8032 return updateId();
8033 },
8034 unstable_isNewReconciler: enableNewReconciler
8035 };
8036
8037 InvalidNestedHooksDispatcherOnRerenderInDEV = {
8038 readContext: function (context) {
8039 warnInvalidContextAccess();
8040 return readContext(context);
8041 },
8042 useCallback: function (callback, deps) {
8043 currentHookNameInDev = 'useCallback';
8044 warnInvalidHookAccess();
8045 updateHookTypesDev();
8046 return updateCallback(callback, deps);
8047 },
8048 useContext: function (context) {
8049 currentHookNameInDev = 'useContext';
8050 warnInvalidHookAccess();
8051 updateHookTypesDev();
8052 return readContext(context);
8053 },
8054 useEffect: function (create, deps) {
8055 currentHookNameInDev = 'useEffect';
8056 warnInvalidHookAccess();
8057 updateHookTypesDev();
8058 return updateEffect(create, deps);
8059 },
8060 useImperativeHandle: function (ref, create, deps) {
8061 currentHookNameInDev = 'useImperativeHandle';
8062 warnInvalidHookAccess();
8063 updateHookTypesDev();
8064 return updateImperativeHandle(ref, create, deps);
8065 },
8066 useInsertionEffect: function (create, deps) {
8067 currentHookNameInDev = 'useInsertionEffect';
8068 warnInvalidHookAccess();
8069 updateHookTypesDev();
8070 return updateInsertionEffect(create, deps);
8071 },
8072 useLayoutEffect: function (create, deps) {
8073 currentHookNameInDev = 'useLayoutEffect';
8074 warnInvalidHookAccess();
8075 updateHookTypesDev();
8076 return updateLayoutEffect(create, deps);
8077 },
8078 useMemo: function (create, deps) {
8079 currentHookNameInDev = 'useMemo';
8080 warnInvalidHookAccess();
8081 updateHookTypesDev();
8082 var prevDispatcher = ReactCurrentDispatcher$1.current;
8083 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
8084
8085 try {
8086 return updateMemo(create, deps);
8087 } finally {
8088 ReactCurrentDispatcher$1.current = prevDispatcher;
8089 }
8090 },
8091 useReducer: function (reducer, initialArg, init) {
8092 currentHookNameInDev = 'useReducer';
8093 warnInvalidHookAccess();
8094 updateHookTypesDev();
8095 var prevDispatcher = ReactCurrentDispatcher$1.current;
8096 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
8097
8098 try {
8099 return rerenderReducer(reducer, initialArg, init);
8100 } finally {
8101 ReactCurrentDispatcher$1.current = prevDispatcher;
8102 }
8103 },
8104 useRef: function (initialValue) {
8105 currentHookNameInDev = 'useRef';
8106 warnInvalidHookAccess();
8107 updateHookTypesDev();
8108 return updateRef();
8109 },
8110 useState: function (initialState) {
8111 currentHookNameInDev = 'useState';
8112 warnInvalidHookAccess();
8113 updateHookTypesDev();
8114 var prevDispatcher = ReactCurrentDispatcher$1.current;
8115 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
8116
8117 try {
8118 return rerenderState(initialState);
8119 } finally {
8120 ReactCurrentDispatcher$1.current = prevDispatcher;
8121 }
8122 },
8123 useDebugValue: function (value, formatterFn) {
8124 currentHookNameInDev = 'useDebugValue';
8125 warnInvalidHookAccess();
8126 updateHookTypesDev();
8127 return updateDebugValue();
8128 },
8129 useDeferredValue: function (value) {
8130 currentHookNameInDev = 'useDeferredValue';
8131 warnInvalidHookAccess();
8132 updateHookTypesDev();
8133 return rerenderDeferredValue(value);
8134 },
8135 useTransition: function () {
8136 currentHookNameInDev = 'useTransition';
8137 warnInvalidHookAccess();
8138 updateHookTypesDev();
8139 return rerenderTransition();
8140 },
8141 useMutableSource: function (source, getSnapshot, subscribe) {
8142 currentHookNameInDev = 'useMutableSource';
8143 warnInvalidHookAccess();
8144 updateHookTypesDev();
8145 return updateMutableSource();
8146 },
8147 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
8148 currentHookNameInDev = 'useSyncExternalStore';
8149 warnInvalidHookAccess();
8150 updateHookTypesDev();
8151 return updateSyncExternalStore(subscribe, getSnapshot);
8152 },
8153 useId: function () {
8154 currentHookNameInDev = 'useId';
8155 warnInvalidHookAccess();
8156 updateHookTypesDev();
8157 return updateId();
8158 },
8159 unstable_isNewReconciler: enableNewReconciler
8160 };
8161 }
8162
8163 var now$1 = Scheduler$1.unstable_now;
8164 var commitTime = 0;
8165 var layoutEffectStartTime = -1;
8166 var profilerStartTime = -1;
8167 var passiveEffectStartTime = -1;
8168 /**
8169 * Tracks whether the current update was a nested/cascading update (scheduled from a layout effect).
8170 *
8171 * The overall sequence is:
8172 * 1. render
8173 * 2. commit (and call `onRender`, `onCommit`)
8174 * 3. check for nested updates
8175 * 4. flush passive effects (and call `onPostCommit`)
8176 *
8177 * Nested updates are identified in step 3 above,
8178 * but step 4 still applies to the work that was just committed.
8179 * We use two flags to track nested updates then:
8180 * one tracks whether the upcoming update is a nested update,
8181 * and the other tracks whether the current update was a nested update.
8182 * The first value gets synced to the second at the start of the render phase.
8183 */
8184
8185 var currentUpdateIsNested = false;
8186 var nestedUpdateScheduled = false;
8187
8188 function isCurrentUpdateNested() {
8189 return currentUpdateIsNested;
8190 }
8191
8192 function markNestedUpdateScheduled() {
8193 {
8194 nestedUpdateScheduled = true;
8195 }
8196 }
8197
8198 function resetNestedUpdateFlag() {
8199 {
8200 currentUpdateIsNested = false;
8201 nestedUpdateScheduled = false;
8202 }
8203 }
8204
8205 function syncNestedUpdateFlag() {
8206 {
8207 currentUpdateIsNested = nestedUpdateScheduled;
8208 nestedUpdateScheduled = false;
8209 }
8210 }
8211
8212 function getCommitTime() {
8213 return commitTime;
8214 }
8215
8216 function recordCommitTime() {
8217
8218 commitTime = now$1();
8219 }
8220
8221 function startProfilerTimer(fiber) {
8222
8223 profilerStartTime = now$1();
8224
8225 if (fiber.actualStartTime < 0) {
8226 fiber.actualStartTime = now$1();
8227 }
8228 }
8229
8230 function stopProfilerTimerIfRunning(fiber) {
8231
8232 profilerStartTime = -1;
8233 }
8234
8235 function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
8236
8237 if (profilerStartTime >= 0) {
8238 var elapsedTime = now$1() - profilerStartTime;
8239 fiber.actualDuration += elapsedTime;
8240
8241 if (overrideBaseTime) {
8242 fiber.selfBaseDuration = elapsedTime;
8243 }
8244
8245 profilerStartTime = -1;
8246 }
8247 }
8248
8249 function recordLayoutEffectDuration(fiber) {
8250
8251 if (layoutEffectStartTime >= 0) {
8252 var elapsedTime = now$1() - layoutEffectStartTime;
8253 layoutEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor
8254 // Or the root (for the DevTools Profiler to read)
8255
8256 var parentFiber = fiber.return;
8257
8258 while (parentFiber !== null) {
8259 switch (parentFiber.tag) {
8260 case HostRoot:
8261 var root = parentFiber.stateNode;
8262 root.effectDuration += elapsedTime;
8263 return;
8264
8265 case Profiler:
8266 var parentStateNode = parentFiber.stateNode;
8267 parentStateNode.effectDuration += elapsedTime;
8268 return;
8269 }
8270
8271 parentFiber = parentFiber.return;
8272 }
8273 }
8274 }
8275
8276 function recordPassiveEffectDuration(fiber) {
8277
8278 if (passiveEffectStartTime >= 0) {
8279 var elapsedTime = now$1() - passiveEffectStartTime;
8280 passiveEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor
8281 // Or the root (for the DevTools Profiler to read)
8282
8283 var parentFiber = fiber.return;
8284
8285 while (parentFiber !== null) {
8286 switch (parentFiber.tag) {
8287 case HostRoot:
8288 var root = parentFiber.stateNode;
8289
8290 if (root !== null) {
8291 root.passiveEffectDuration += elapsedTime;
8292 }
8293
8294 return;
8295
8296 case Profiler:
8297 var parentStateNode = parentFiber.stateNode;
8298
8299 if (parentStateNode !== null) {
8300 // Detached fibers have their state node cleared out.
8301 // In this case, the return pointer is also cleared out,
8302 // so we won't be able to report the time spent in this Profiler's subtree.
8303 parentStateNode.passiveEffectDuration += elapsedTime;
8304 }
8305
8306 return;
8307 }
8308
8309 parentFiber = parentFiber.return;
8310 }
8311 }
8312 }
8313
8314 function startLayoutEffectTimer() {
8315
8316 layoutEffectStartTime = now$1();
8317 }
8318
8319 function startPassiveEffectTimer() {
8320
8321 passiveEffectStartTime = now$1();
8322 }
8323
8324 function transferActualDuration(fiber) {
8325 // Transfer time spent rendering these children so we don't lose it
8326 // after we rerender. This is used as a helper in special cases
8327 // where we should count the work of multiple passes.
8328 var child = fiber.child;
8329
8330 while (child) {
8331 fiber.actualDuration += child.actualDuration;
8332 child = child.sibling;
8333 }
8334 }
8335
8336 function createCapturedValue(value, source) {
8337 // If the value is an error, call this function immediately after it is thrown
8338 // so the stack is accurate.
8339 return {
8340 value: value,
8341 source: source,
8342 stack: getStackByFiberInDevAndProd(source)
8343 };
8344 }
8345
8346 // This module is forked in different environments.
8347 // By default, return `true` to log errors to the console.
8348 // Forks can return `false` if this isn't desirable.
8349 function showErrorDialog(boundary, errorInfo) {
8350 return true;
8351 }
8352
8353 function logCapturedError(boundary, errorInfo) {
8354 try {
8355 var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging.
8356 // This enables renderers like ReactNative to better manage redbox behavior.
8357
8358 if (logError === false) {
8359 return;
8360 }
8361
8362 var error = errorInfo.value;
8363
8364 if (true) {
8365 var source = errorInfo.source;
8366 var stack = errorInfo.stack;
8367 var componentStack = stack !== null ? stack : ''; // Browsers support silencing uncaught errors by calling
8368 // `preventDefault()` in window `error` handler.
8369 // We record this information as an expando on the error.
8370
8371 if (error != null && error._suppressLogging) {
8372 if (boundary.tag === ClassComponent) {
8373 // The error is recoverable and was silenced.
8374 // Ignore it and don't print the stack addendum.
8375 // This is handy for testing error boundaries without noise.
8376 return;
8377 } // The error is fatal. Since the silencing might have
8378 // been accidental, we'll surface it anyway.
8379 // However, the browser would have silenced the original error
8380 // so we'll print it first, and then print the stack addendum.
8381
8382
8383 console['error'](error); // Don't transform to our wrapper
8384 // For a more detailed description of this block, see:
8385 // https://github.com/facebook/react/pull/13384
8386 }
8387
8388 var componentName = source ? getComponentNameFromFiber(source) : null;
8389 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:';
8390 var errorBoundaryMessage;
8391
8392 if (boundary.tag === HostRoot) {
8393 errorBoundaryMessage = 'Consider adding an error boundary to your tree to customize error handling behavior.\n' + 'Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.';
8394 } else {
8395 var errorBoundaryName = getComponentNameFromFiber(boundary) || 'Anonymous';
8396 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
8397 }
8398
8399 var combinedMessage = componentNameMessage + "\n" + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.
8400 // We don't include the original error message and JS stack because the browser
8401 // has already printed it. Even if the application swallows the error, it is still
8402 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
8403
8404 console['error'](combinedMessage); // Don't transform to our wrapper
8405 } else {
8406 // In production, we print the error directly.
8407 // This will include the message, the JS stack, and anything the browser wants to show.
8408 // We pass the error object instead of custom message so that the browser displays the error natively.
8409 console['error'](error); // Don't transform to our wrapper
8410 }
8411 } catch (e) {
8412 // This method must not throw, or React internal state will get messed up.
8413 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
8414 // we want to report this error outside of the normal stack as a last resort.
8415 // https://github.com/facebook/react/issues/13188
8416 setTimeout(function () {
8417 throw e;
8418 });
8419 }
8420 }
8421
8422 var PossiblyWeakMap$1 = typeof WeakMap === 'function' ? WeakMap : Map;
8423
8424 function createRootErrorUpdate(fiber, errorInfo, lane) {
8425 var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null.
8426
8427 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
8428 // being called "element".
8429
8430 update.payload = {
8431 element: null
8432 };
8433 var error = errorInfo.value;
8434
8435 update.callback = function () {
8436 onUncaughtError(error);
8437 logCapturedError(fiber, errorInfo);
8438 };
8439
8440 return update;
8441 }
8442
8443 function createClassErrorUpdate(fiber, errorInfo, lane) {
8444 var update = createUpdate(NoTimestamp, lane);
8445 update.tag = CaptureUpdate;
8446 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
8447
8448 if (typeof getDerivedStateFromError === 'function') {
8449 var error$1 = errorInfo.value;
8450
8451 update.payload = function () {
8452 return getDerivedStateFromError(error$1);
8453 };
8454
8455 update.callback = function () {
8456 {
8457 markFailedErrorBoundaryForHotReloading(fiber);
8458 }
8459
8460 logCapturedError(fiber, errorInfo);
8461 };
8462 }
8463
8464 var inst = fiber.stateNode;
8465
8466 if (inst !== null && typeof inst.componentDidCatch === 'function') {
8467 update.callback = function callback() {
8468 {
8469 markFailedErrorBoundaryForHotReloading(fiber);
8470 }
8471
8472 logCapturedError(fiber, errorInfo);
8473
8474 if (typeof getDerivedStateFromError !== 'function') {
8475 // To preserve the preexisting retry behavior of error boundaries,
8476 // we keep track of which ones already failed during this batch.
8477 // This gets reset before we yield back to the browser.
8478 // TODO: Warn in strict mode if getDerivedStateFromError is
8479 // not defined.
8480 markLegacyErrorBoundaryAsFailed(this);
8481 }
8482
8483 var error$1 = errorInfo.value;
8484 var stack = errorInfo.stack;
8485 this.componentDidCatch(error$1, {
8486 componentStack: stack !== null ? stack : ''
8487 });
8488
8489 {
8490 if (typeof getDerivedStateFromError !== 'function') {
8491 // If componentDidCatch is the only error boundary method defined,
8492 // then it needs to call setState to recover from errors.
8493 // If no state update is scheduled then the boundary will swallow the error.
8494 if (!includesSomeLane(fiber.lanes, SyncLane)) {
8495 error('%s: Error boundaries should implement getDerivedStateFromError(). ' + 'In that method, return a state update to display an error message or fallback UI.', getComponentNameFromFiber(fiber) || 'Unknown');
8496 }
8497 }
8498 }
8499 };
8500 }
8501
8502 return update;
8503 }
8504
8505 function attachPingListener(root, wakeable, lanes) {
8506 // Attach a ping listener
8507 //
8508 // The data might resolve before we have a chance to commit the fallback. Or,
8509 // in the case of a refresh, we'll never commit a fallback. So we need to
8510 // attach a listener now. When it resolves ("pings"), we can decide whether to
8511 // try rendering the tree again.
8512 //
8513 // Only attach a listener if one does not already exist for the lanes
8514 // we're currently rendering (which acts like a "thread ID" here).
8515 //
8516 // We only need to do this in concurrent mode. Legacy Suspense always
8517 // commits fallbacks synchronously, so there are no pings.
8518 var pingCache = root.pingCache;
8519 var threadIDs;
8520
8521 if (pingCache === null) {
8522 pingCache = root.pingCache = new PossiblyWeakMap$1();
8523 threadIDs = new Set();
8524 pingCache.set(wakeable, threadIDs);
8525 } else {
8526 threadIDs = pingCache.get(wakeable);
8527
8528 if (threadIDs === undefined) {
8529 threadIDs = new Set();
8530 pingCache.set(wakeable, threadIDs);
8531 }
8532 }
8533
8534 if (!threadIDs.has(lanes)) {
8535 // Memoize using the thread ID to prevent redundant listeners.
8536 threadIDs.add(lanes);
8537 var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes);
8538
8539 wakeable.then(ping, ping);
8540 }
8541 }
8542
8543 function attachRetryListener(suspenseBoundary, root, wakeable, lanes) {
8544 // Retry listener
8545 //
8546 // If the fallback does commit, we need to attach a different type of
8547 // listener. This one schedules an update on the Suspense boundary to turn
8548 // the fallback state off.
8549 //
8550 // Stash the wakeable on the boundary fiber so we can access it in the
8551 // commit phase.
8552 //
8553 // When the wakeable resolves, we'll attempt to render the boundary
8554 // again ("retry").
8555 var wakeables = suspenseBoundary.updateQueue;
8556
8557 if (wakeables === null) {
8558 var updateQueue = new Set();
8559 updateQueue.add(wakeable);
8560 suspenseBoundary.updateQueue = updateQueue;
8561 } else {
8562 wakeables.add(wakeable);
8563 }
8564 }
8565
8566 function resetSuspendedComponent(sourceFiber, rootRenderLanes) {
8567 // A legacy mode Suspense quirk, only relevant to hook components.
8568
8569
8570 var tag = sourceFiber.tag;
8571
8572 if ((sourceFiber.mode & ConcurrentMode) === NoMode && (tag === FunctionComponent || tag === ForwardRef || tag === SimpleMemoComponent)) {
8573 var currentSource = sourceFiber.alternate;
8574
8575 if (currentSource) {
8576 sourceFiber.updateQueue = currentSource.updateQueue;
8577 sourceFiber.memoizedState = currentSource.memoizedState;
8578 sourceFiber.lanes = currentSource.lanes;
8579 } else {
8580 sourceFiber.updateQueue = null;
8581 sourceFiber.memoizedState = null;
8582 }
8583 }
8584 }
8585
8586 function getNearestSuspenseBoundaryToCapture(returnFiber) {
8587 var node = returnFiber;
8588
8589 do {
8590 if (node.tag === SuspenseComponent && shouldCaptureSuspense(node)) {
8591 return node;
8592 } // This boundary already captured during this render. Continue to the next
8593 // boundary.
8594
8595
8596 node = node.return;
8597 } while (node !== null);
8598
8599 return null;
8600 }
8601
8602 function markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes) {
8603 // This marks a Suspense boundary so that when we're unwinding the stack,
8604 // it captures the suspended "exception" and does a second (fallback) pass.
8605 if ((suspenseBoundary.mode & ConcurrentMode) === NoMode) {
8606 // Legacy Mode Suspense
8607 //
8608 // If the boundary is in legacy mode, we should *not*
8609 // suspend the commit. Pretend as if the suspended component rendered
8610 // null and keep rendering. When the Suspense boundary completes,
8611 // we'll do a second pass to render the fallback.
8612 if (suspenseBoundary === returnFiber) {
8613 // Special case where we suspended while reconciling the children of
8614 // a Suspense boundary's inner Offscreen wrapper fiber. This happens
8615 // when a React.lazy component is a direct child of a
8616 // Suspense boundary.
8617 //
8618 // Suspense boundaries are implemented as multiple fibers, but they
8619 // are a single conceptual unit. The legacy mode behavior where we
8620 // pretend the suspended fiber committed as `null` won't work,
8621 // because in this case the "suspended" fiber is the inner
8622 // Offscreen wrapper.
8623 //
8624 // Because the contents of the boundary haven't started rendering
8625 // yet (i.e. nothing in the tree has partially rendered) we can
8626 // switch to the regular, concurrent mode behavior: mark the
8627 // boundary with ShouldCapture and enter the unwind phase.
8628 suspenseBoundary.flags |= ShouldCapture;
8629 } else {
8630 suspenseBoundary.flags |= DidCapture;
8631 sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete.
8632 // But we shouldn't call any lifecycle methods or callbacks. Remove
8633 // all lifecycle effect tags.
8634
8635 sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete);
8636
8637 if (sourceFiber.tag === ClassComponent) {
8638 var currentSourceFiber = sourceFiber.alternate;
8639
8640 if (currentSourceFiber === null) {
8641 // This is a new mount. Change the tag so it's not mistaken for a
8642 // completed class component. For example, we should not call
8643 // componentWillUnmount if it is deleted.
8644 sourceFiber.tag = IncompleteClassComponent;
8645 } else {
8646 // When we try rendering again, we should not reuse the current fiber,
8647 // since it's known to be in an inconsistent state. Use a force update to
8648 // prevent a bail out.
8649 var update = createUpdate(NoTimestamp, SyncLane);
8650 update.tag = ForceUpdate;
8651 enqueueUpdate(sourceFiber, update);
8652 }
8653 } // The source fiber did not complete. Mark it with Sync priority to
8654 // indicate that it still has pending work.
8655
8656
8657 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane);
8658 }
8659
8660 return suspenseBoundary;
8661 } // Confirmed that the boundary is in a concurrent mode tree. Continue
8662 // with the normal suspend path.
8663 //
8664 // After this we'll use a set of heuristics to determine whether this
8665 // render pass will run to completion or restart or "suspend" the commit.
8666 // The actual logic for this is spread out in different places.
8667 //
8668 // This first principle is that if we're going to suspend when we complete
8669 // a root, then we should also restart if we get an update or ping that
8670 // might unsuspend it, and vice versa. The only reason to suspend is
8671 // because you think you might want to restart before committing. However,
8672 // it doesn't make sense to restart only while in the period we're suspended.
8673 //
8674 // Restarting too aggressively is also not good because it starves out any
8675 // intermediate loading state. So we use heuristics to determine when.
8676 // Suspense Heuristics
8677 //
8678 // If nothing threw a Promise or all the same fallbacks are already showing,
8679 // then don't suspend/restart.
8680 //
8681 // If this is an initial render of a new tree of Suspense boundaries and
8682 // those trigger a fallback, then don't suspend/restart. We want to ensure
8683 // that we can show the initial loading state as quickly as possible.
8684 //
8685 // If we hit a "Delayed" case, such as when we'd switch from content back into
8686 // a fallback, then we should always suspend/restart. Transitions apply
8687 // to this case. If none is defined, JND is used instead.
8688 //
8689 // If we're already showing a fallback and it gets "retried", allowing us to show
8690 // another level, but there's still an inner boundary that would show a fallback,
8691 // then we suspend/restart for 500ms since the last time we showed a fallback
8692 // anywhere in the tree. This effectively throttles progressive loading into a
8693 // consistent train of commits. This also gives us an opportunity to restart to
8694 // get to the completed state slightly earlier.
8695 //
8696 // If there's ambiguity due to batching it's resolved in preference of:
8697 // 1) "delayed", 2) "initial render", 3) "retry".
8698 //
8699 // We want to ensure that a "busy" state doesn't get force committed. We want to
8700 // ensure that new initial loading states can commit as soon as possible.
8701
8702
8703 suspenseBoundary.flags |= ShouldCapture; // TODO: I think we can remove this, since we now use `DidCapture` in
8704 // the begin phase to prevent an early bailout.
8705
8706 suspenseBoundary.lanes = rootRenderLanes;
8707 return suspenseBoundary;
8708 }
8709
8710 function throwException(root, returnFiber, sourceFiber, value, rootRenderLanes) {
8711 // The source fiber did not complete.
8712 sourceFiber.flags |= Incomplete;
8713
8714 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
8715 // This is a wakeable. The component suspended.
8716 var wakeable = value;
8717 resetSuspendedComponent(sourceFiber);
8718
8719
8720 var suspenseBoundary = getNearestSuspenseBoundaryToCapture(returnFiber);
8721
8722 if (suspenseBoundary !== null) {
8723 suspenseBoundary.flags &= ~ForceClientRender;
8724 markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes); // We only attach ping listeners in concurrent mode. Legacy Suspense always
8725 // commits fallbacks synchronously, so there are no pings.
8726
8727 if (suspenseBoundary.mode & ConcurrentMode) {
8728 attachPingListener(root, wakeable, rootRenderLanes);
8729 }
8730
8731 attachRetryListener(suspenseBoundary, root, wakeable);
8732 return;
8733 } else {
8734 // No boundary was found. Unless this is a sync update, this is OK.
8735 // We can suspend and wait for more data to arrive.
8736 if (!includesSyncLane(rootRenderLanes)) {
8737 // This is not a sync update. Suspend. Since we're not activating a
8738 // Suspense boundary, this will unwind all the way to the root without
8739 // performing a second pass to render a fallback. (This is arguably how
8740 // refresh transitions should work, too, since we're not going to commit
8741 // the fallbacks anyway.)
8742 //
8743 // This case also applies to initial hydration.
8744 attachPingListener(root, wakeable, rootRenderLanes);
8745 renderDidSuspendDelayIfPossible();
8746 return;
8747 } // This is a sync/discrete update. We treat this case like an error
8748 // because discrete renders are expected to produce a complete tree
8749 // synchronously to maintain consistency with external state.
8750
8751
8752 var uncaughtSuspenseError = new Error('A component suspended while responding to synchronous input. This ' + 'will cause the UI to be replaced with a loading indicator. To ' + 'fix, updates that suspend should be wrapped ' + 'with startTransition.'); // If we're outside a transition, fall through to the regular error path.
8753 // The error will be caught by the nearest suspense boundary.
8754
8755 value = uncaughtSuspenseError;
8756 }
8757 } // We didn't find a boundary that could handle this type of exception. Start
8758 // over and traverse parent path again, this time treating the exception
8759 // as an error.
8760
8761
8762 renderDidError(value);
8763 value = createCapturedValue(value, sourceFiber);
8764 var workInProgress = returnFiber;
8765
8766 do {
8767 switch (workInProgress.tag) {
8768 case HostRoot:
8769 {
8770 var _errorInfo = value;
8771 workInProgress.flags |= ShouldCapture;
8772 var lane = pickArbitraryLane(rootRenderLanes);
8773 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);
8774 var update = createRootErrorUpdate(workInProgress, _errorInfo, lane);
8775 enqueueCapturedUpdate(workInProgress, update);
8776 return;
8777 }
8778
8779 case ClassComponent:
8780 // Capture and retry
8781 var errorInfo = value;
8782 var ctor = workInProgress.type;
8783 var instance = workInProgress.stateNode;
8784
8785 if ((workInProgress.flags & DidCapture) === NoFlags && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
8786 workInProgress.flags |= ShouldCapture;
8787
8788 var _lane = pickArbitraryLane(rootRenderLanes);
8789
8790 workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state
8791
8792 var _update = createClassErrorUpdate(workInProgress, errorInfo, _lane);
8793
8794 enqueueCapturedUpdate(workInProgress, _update);
8795 return;
8796 }
8797
8798 break;
8799 }
8800
8801 workInProgress = workInProgress.return;
8802 } while (workInProgress !== null);
8803 }
8804
8805 function getSuspendedCache() {
8806 {
8807 return null;
8808 } // This function is called when a Suspense boundary suspends. It returns the
8809 }
8810
8811 function markUpdate(workInProgress) {
8812 // Tag the fiber with an update effect. This turns a Placement into
8813 // a PlacementAndUpdate.
8814 workInProgress.flags |= Update;
8815 }
8816
8817 function markRef(workInProgress) {
8818 workInProgress.flags |= Ref;
8819 }
8820
8821 var appendAllChildren;
8822 var updateHostContainer;
8823 var updateHostComponent;
8824 var updateHostText;
8825
8826 {
8827 // Mutation mode
8828 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
8829 // We only have the top Fiber that was created but we need recurse down its
8830 // children to find all the terminal nodes.
8831 var node = workInProgress.child;
8832
8833 while (node !== null) {
8834 if (node.tag === HostComponent || node.tag === HostText) {
8835 appendInitialChild(parent, node.stateNode);
8836 } else if (node.tag === HostPortal) ; else if (node.child !== null) {
8837 node.child.return = node;
8838 node = node.child;
8839 continue;
8840 }
8841
8842 if (node === workInProgress) {
8843 return;
8844 }
8845
8846 while (node.sibling === null) {
8847 if (node.return === null || node.return === workInProgress) {
8848 return;
8849 }
8850
8851 node = node.return;
8852 }
8853
8854 node.sibling.return = node.return;
8855 node = node.sibling;
8856 }
8857 };
8858
8859 updateHostContainer = function (current, workInProgress) {// Noop
8860 };
8861
8862 updateHostComponent = function (current, workInProgress, type, newProps, rootContainerInstance) {
8863 // If we have an alternate, that means this is an update and we need to
8864 // schedule a side-effect to do the updates.
8865 var oldProps = current.memoizedProps;
8866
8867 if (oldProps === newProps) {
8868 // In mutation mode, this is sufficient for a bailout because
8869 // we won't touch this node even if children changed.
8870 return;
8871 } // If we get updated because one of our children updated, we don't
8872 // have newProps so we'll have to reuse them.
8873 // TODO: Split the update API as separate for the props vs. children.
8874 // Even better would be if children weren't special cased at all tho.
8875
8876
8877 var instance = workInProgress.stateNode;
8878 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host
8879 // component is hitting the resume path. Figure out why. Possibly
8880 // related to `hidden`.
8881
8882 var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component.
8883
8884 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
8885 // is a new ref we mark this as an update. All the work is done in commitWork.
8886
8887 if (updatePayload) {
8888 markUpdate(workInProgress);
8889 }
8890 };
8891
8892 updateHostText = function (current, workInProgress, oldText, newText) {
8893 // If the text differs, mark it as an update. All the work in done in commitWork.
8894 if (oldText !== newText) {
8895 markUpdate(workInProgress);
8896 }
8897 };
8898 }
8899
8900 function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
8901
8902 switch (renderState.tailMode) {
8903 case 'hidden':
8904 {
8905 // Any insertions at the end of the tail list after this point
8906 // should be invisible. If there are already mounted boundaries
8907 // anything before them are not considered for collapsing.
8908 // Therefore we need to go through the whole tail to find if
8909 // there are any.
8910 var tailNode = renderState.tail;
8911 var lastTailNode = null;
8912
8913 while (tailNode !== null) {
8914 if (tailNode.alternate !== null) {
8915 lastTailNode = tailNode;
8916 }
8917
8918 tailNode = tailNode.sibling;
8919 } // Next we're simply going to delete all insertions after the
8920 // last rendered item.
8921
8922
8923 if (lastTailNode === null) {
8924 // All remaining items in the tail are insertions.
8925 renderState.tail = null;
8926 } else {
8927 // Detach the insertion after the last node that was already
8928 // inserted.
8929 lastTailNode.sibling = null;
8930 }
8931
8932 break;
8933 }
8934
8935 case 'collapsed':
8936 {
8937 // Any insertions at the end of the tail list after this point
8938 // should be invisible. If there are already mounted boundaries
8939 // anything before them are not considered for collapsing.
8940 // Therefore we need to go through the whole tail to find if
8941 // there are any.
8942 var _tailNode = renderState.tail;
8943 var _lastTailNode = null;
8944
8945 while (_tailNode !== null) {
8946 if (_tailNode.alternate !== null) {
8947 _lastTailNode = _tailNode;
8948 }
8949
8950 _tailNode = _tailNode.sibling;
8951 } // Next we're simply going to delete all insertions after the
8952 // last rendered item.
8953
8954
8955 if (_lastTailNode === null) {
8956 // All remaining items in the tail are insertions.
8957 if (!hasRenderedATailFallback && renderState.tail !== null) {
8958 // We suspended during the head. We want to show at least one
8959 // row at the tail. So we'll keep on and cut off the rest.
8960 renderState.tail.sibling = null;
8961 } else {
8962 renderState.tail = null;
8963 }
8964 } else {
8965 // Detach the insertion after the last node that was already
8966 // inserted.
8967 _lastTailNode.sibling = null;
8968 }
8969
8970 break;
8971 }
8972 }
8973 }
8974
8975 function bubbleProperties(completedWork) {
8976 var didBailout = completedWork.alternate !== null && completedWork.alternate.child === completedWork.child;
8977 var newChildLanes = NoLanes;
8978 var subtreeFlags = NoFlags;
8979
8980 if (!didBailout) {
8981 // Bubble up the earliest expiration time.
8982 if ( (completedWork.mode & ProfileMode) !== NoMode) {
8983 // In profiling mode, resetChildExpirationTime is also used to reset
8984 // profiler durations.
8985 var actualDuration = completedWork.actualDuration;
8986 var treeBaseDuration = completedWork.selfBaseDuration;
8987 var child = completedWork.child;
8988
8989 while (child !== null) {
8990 newChildLanes = mergeLanes(newChildLanes, mergeLanes(child.lanes, child.childLanes));
8991 subtreeFlags |= child.subtreeFlags;
8992 subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will
8993 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
8994 // When work is done, it should bubble to the parent's actualDuration. If
8995 // the fiber has not been cloned though, (meaning no work was done), then
8996 // this value will reflect the amount of time spent working on a previous
8997 // render. In that case it should not bubble. We determine whether it was
8998 // cloned by comparing the child pointer.
8999
9000 actualDuration += child.actualDuration;
9001 treeBaseDuration += child.treeBaseDuration;
9002 child = child.sibling;
9003 }
9004
9005 completedWork.actualDuration = actualDuration;
9006 completedWork.treeBaseDuration = treeBaseDuration;
9007 } else {
9008 var _child = completedWork.child;
9009
9010 while (_child !== null) {
9011 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child.lanes, _child.childLanes));
9012 subtreeFlags |= _child.subtreeFlags;
9013 subtreeFlags |= _child.flags; // Update the return pointer so the tree is consistent. This is a code
9014 // smell because it assumes the commit phase is never concurrent with
9015 // the render phase. Will address during refactor to alternate model.
9016
9017 _child.return = completedWork;
9018 _child = _child.sibling;
9019 }
9020 }
9021
9022 completedWork.subtreeFlags |= subtreeFlags;
9023 } else {
9024 // Bubble up the earliest expiration time.
9025 if ( (completedWork.mode & ProfileMode) !== NoMode) {
9026 // In profiling mode, resetChildExpirationTime is also used to reset
9027 // profiler durations.
9028 var _treeBaseDuration = completedWork.selfBaseDuration;
9029 var _child2 = completedWork.child;
9030
9031 while (_child2 !== null) {
9032 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child2.lanes, _child2.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to,
9033 // so we should bubble those up even during a bailout. All the other
9034 // flags have a lifetime only of a single render + commit, so we should
9035 // ignore them.
9036
9037 subtreeFlags |= _child2.subtreeFlags & StaticMask;
9038 subtreeFlags |= _child2.flags & StaticMask;
9039 _treeBaseDuration += _child2.treeBaseDuration;
9040 _child2 = _child2.sibling;
9041 }
9042
9043 completedWork.treeBaseDuration = _treeBaseDuration;
9044 } else {
9045 var _child3 = completedWork.child;
9046
9047 while (_child3 !== null) {
9048 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child3.lanes, _child3.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to,
9049 // so we should bubble those up even during a bailout. All the other
9050 // flags have a lifetime only of a single render + commit, so we should
9051 // ignore them.
9052
9053 subtreeFlags |= _child3.subtreeFlags & StaticMask;
9054 subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code
9055 // smell because it assumes the commit phase is never concurrent with
9056 // the render phase. Will address during refactor to alternate model.
9057
9058 _child3.return = completedWork;
9059 _child3 = _child3.sibling;
9060 }
9061 }
9062
9063 completedWork.subtreeFlags |= subtreeFlags;
9064 }
9065
9066 completedWork.childLanes = newChildLanes;
9067 return didBailout;
9068 }
9069
9070 function completeWork(current, workInProgress, renderLanes) {
9071 var newProps = workInProgress.pendingProps; // Note: This intentionally doesn't check if we're hydrating because comparing
9072 // to the current tree provider fiber is just as fast and less error-prone.
9073 // Ideally we would have a special version of the work loop only
9074 // for hydration.
9075
9076 popTreeContext(workInProgress);
9077
9078 switch (workInProgress.tag) {
9079 case IndeterminateComponent:
9080 case LazyComponent:
9081 case SimpleMemoComponent:
9082 case FunctionComponent:
9083 case ForwardRef:
9084 case Fragment:
9085 case Mode:
9086 case Profiler:
9087 case ContextConsumer:
9088 case MemoComponent:
9089 bubbleProperties(workInProgress);
9090 return null;
9091
9092 case ClassComponent:
9093 {
9094 var Component = workInProgress.type;
9095
9096 if (isContextProvider(Component)) {
9097 popContext(workInProgress);
9098 }
9099
9100 bubbleProperties(workInProgress);
9101 return null;
9102 }
9103
9104 case HostRoot:
9105 {
9106 var fiberRoot = workInProgress.stateNode;
9107
9108 popHostContainer(workInProgress);
9109 popTopLevelContextObject(workInProgress);
9110 resetWorkInProgressVersions();
9111
9112 if (fiberRoot.pendingContext) {
9113 fiberRoot.context = fiberRoot.pendingContext;
9114 fiberRoot.pendingContext = null;
9115 }
9116
9117 if (current === null || current.child === null) {
9118 // If we hydrated, pop so that we can delete any remaining children
9119 // that weren't hydrated.
9120 var wasHydrated = popHydrationState();
9121
9122 if (wasHydrated) {
9123 // If we hydrated, then we'll need to schedule an update for
9124 // the commit side-effects on the root.
9125 markUpdate(workInProgress);
9126 } else {
9127 if (current !== null) {
9128 var prevState = current.memoizedState;
9129
9130 if ( // Check if this is a client root
9131 !prevState.isDehydrated || // Check if we reverted to client rendering (e.g. due to an error)
9132 (workInProgress.flags & ForceClientRender) !== NoFlags) {
9133 // Schedule an effect to clear this container at the start of the
9134 // next commit. This handles the case of React rendering into a
9135 // container with previous children. It's also safe to do for
9136 // updates too, because current.child would only be null if the
9137 // previous render was null (so the container would already
9138 // be empty).
9139 workInProgress.flags |= Snapshot; // If this was a forced client render, there may have been
9140 }
9141 }
9142 }
9143 }
9144
9145 updateHostContainer(current, workInProgress);
9146 bubbleProperties(workInProgress);
9147 return null;
9148 }
9149
9150 case HostComponent:
9151 {
9152 popHostContext(workInProgress);
9153 var rootContainerInstance = getRootHostContainer();
9154 var type = workInProgress.type;
9155
9156 if (current !== null && workInProgress.stateNode != null) {
9157 updateHostComponent(current, workInProgress, type, newProps, rootContainerInstance);
9158
9159 if (current.ref !== workInProgress.ref) {
9160 markRef(workInProgress);
9161 }
9162 } else {
9163 if (!newProps) {
9164 if (workInProgress.stateNode === null) {
9165 throw new Error('We must have new props for new mounts. This error is likely ' + 'caused by a bug in React. Please file an issue.');
9166 } // This can happen when we abort work.
9167
9168
9169 bubbleProperties(workInProgress);
9170 return null;
9171 }
9172
9173 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
9174 // "stack" as the parent. Then append children as we go in beginWork
9175 // or completeWork depending on whether we want to add them top->down or
9176 // bottom->up. Top->down is faster in IE11.
9177
9178 var _wasHydrated = popHydrationState();
9179
9180 if (_wasHydrated) {
9181 // TODO: Move this and createInstance step into the beginPhase
9182 // to consolidate.
9183 if (prepareToHydrateHostInstance()) {
9184 // If changes to the hydrated node need to be applied at the
9185 // commit-phase we mark this as such.
9186 markUpdate(workInProgress);
9187 }
9188 } else {
9189 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
9190 appendAllChildren(instance, workInProgress, false, false);
9191 workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount.
9192 }
9193
9194 if (workInProgress.ref !== null) {
9195 // If there is a ref on a host node we need to schedule a callback
9196 markRef(workInProgress);
9197 }
9198 }
9199
9200 bubbleProperties(workInProgress);
9201 return null;
9202 }
9203
9204 case HostText:
9205 {
9206 var newText = newProps;
9207
9208 if (current && workInProgress.stateNode != null) {
9209 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
9210 // to schedule a side-effect to do the updates.
9211
9212 updateHostText(current, workInProgress, oldText, newText);
9213 } else {
9214 if (typeof newText !== 'string') {
9215 if (workInProgress.stateNode === null) {
9216 throw new Error('We must have new props for new mounts. This error is likely ' + 'caused by a bug in React. Please file an issue.');
9217 } // This can happen when we abort work.
9218
9219 }
9220
9221 var _rootContainerInstance = getRootHostContainer();
9222
9223 var _currentHostContext = getHostContext();
9224
9225 var _wasHydrated2 = popHydrationState();
9226
9227 if (_wasHydrated2) {
9228 if (prepareToHydrateHostTextInstance()) {
9229 markUpdate(workInProgress);
9230 }
9231 } else {
9232 workInProgress.stateNode = createTextInstance(newText);
9233 }
9234 }
9235
9236 bubbleProperties(workInProgress);
9237 return null;
9238 }
9239
9240 case SuspenseComponent:
9241 {
9242 popSuspenseContext(workInProgress);
9243 var nextState = workInProgress.memoizedState;
9244
9245 if ((workInProgress.flags & DidCapture) !== NoFlags) {
9246 // Something suspended. Re-render with the fallback children.
9247 workInProgress.lanes = renderLanes; // Do not reset the effect list.
9248
9249 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
9250 transferActualDuration(workInProgress);
9251 } // Don't bubble properties in this case.
9252
9253
9254 return workInProgress;
9255 }
9256
9257 var nextDidTimeout = nextState !== null;
9258 var prevDidTimeout = false;
9259
9260 if (current === null) ; else {
9261 var _prevState = current.memoizedState;
9262 prevDidTimeout = _prevState !== null;
9263 }
9264 // an effect to toggle the subtree's visibility. When we switch from
9265 // fallback -> primary, the inner Offscreen fiber schedules this effect
9266 // as part of its normal complete phase. But when we switch from
9267 // primary -> fallback, the inner Offscreen fiber does not have a complete
9268 // phase. So we need to schedule its effect here.
9269 //
9270 // We also use this flag to connect/disconnect the effects, but the same
9271 // logic applies: when re-connecting, the Offscreen fiber's complete
9272 // phase will handle scheduling the effect. It's only when the fallback
9273 // is active that we have to do anything special.
9274
9275
9276 if (nextDidTimeout && !prevDidTimeout) {
9277 var _offscreenFiber = workInProgress.child;
9278 _offscreenFiber.flags |= Visibility; // TODO: This will still suspend a synchronous tree if anything
9279 // in the concurrent tree already suspended during this render.
9280 // This is a known bug.
9281
9282 if ((workInProgress.mode & ConcurrentMode) !== NoMode) {
9283 // TODO: Move this back to throwException because this is too late
9284 // if this is a large tree which is common for initial loads. We
9285 // don't know if we should restart a render or not until we get
9286 // this marker, and this is too late.
9287 // If this render already had a ping or lower pri updates,
9288 // and this is the first time we know we're going to suspend we
9289 // should be able to immediately restart from within throwException.
9290 var hasInvisibleChildContext = current === null && (workInProgress.memoizedProps.unstable_avoidThisFallback !== true || !enableSuspenseAvoidThisFallback);
9291
9292 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
9293 // If this was in an invisible tree or a new render, then showing
9294 // this boundary is ok.
9295 renderDidSuspend();
9296 } else {
9297 // Otherwise, we're going to have to hide content so we should
9298 // suspend for longer if possible.
9299 renderDidSuspendDelayIfPossible();
9300 }
9301 }
9302 }
9303
9304 var wakeables = workInProgress.updateQueue;
9305
9306 if (wakeables !== null) {
9307 // Schedule an effect to attach a retry listener to the promise.
9308 // TODO: Move to passive phase
9309 workInProgress.flags |= Update;
9310 }
9311
9312 bubbleProperties(workInProgress);
9313
9314 {
9315 if ((workInProgress.mode & ProfileMode) !== NoMode) {
9316 if (nextDidTimeout) {
9317 // Don't count time spent in a timed out Suspense subtree as part of the base duration.
9318 var _primaryChildFragment2 = workInProgress.child;
9319
9320 if (_primaryChildFragment2 !== null) {
9321 // $FlowFixMe Flow doesn't support type casting in combination with the -= operator
9322 workInProgress.treeBaseDuration -= _primaryChildFragment2.treeBaseDuration;
9323 }
9324 }
9325 }
9326 }
9327
9328 return null;
9329 }
9330
9331 case HostPortal:
9332 popHostContainer(workInProgress);
9333 updateHostContainer(current, workInProgress);
9334
9335 if (current === null) {
9336 preparePortalMount(workInProgress.stateNode.containerInfo);
9337 }
9338
9339 bubbleProperties(workInProgress);
9340 return null;
9341
9342 case ContextProvider:
9343 // Pop provider fiber
9344 var context = workInProgress.type._context;
9345 popProvider(context, workInProgress);
9346 bubbleProperties(workInProgress);
9347 return null;
9348
9349 case IncompleteClassComponent:
9350 {
9351 // Same as class component case. I put it down here so that the tags are
9352 // sequential to ensure this switch is compiled to a jump table.
9353 var _Component = workInProgress.type;
9354
9355 if (isContextProvider(_Component)) {
9356 popContext(workInProgress);
9357 }
9358
9359 bubbleProperties(workInProgress);
9360 return null;
9361 }
9362
9363 case SuspenseListComponent:
9364 {
9365 popSuspenseContext(workInProgress);
9366 var renderState = workInProgress.memoizedState;
9367
9368 if (renderState === null) {
9369 // We're running in the default, "independent" mode.
9370 // We don't do anything in this mode.
9371 bubbleProperties(workInProgress);
9372 return null;
9373 }
9374
9375 var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags;
9376 var renderedTail = renderState.rendering;
9377
9378 if (renderedTail === null) {
9379 // We just rendered the head.
9380 if (!didSuspendAlready) {
9381 // This is the first pass. We need to figure out if anything is still
9382 // suspended in the rendered set.
9383 // If new content unsuspended, but there's still some content that
9384 // didn't. Then we need to do a second pass that forces everything
9385 // to keep showing their fallbacks.
9386 // We might be suspended if something in this render pass suspended, or
9387 // something in the previous committed pass suspended. Otherwise,
9388 // there's no chance so we can skip the expensive call to
9389 // findFirstSuspended.
9390 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.flags & DidCapture) === NoFlags);
9391
9392 if (!cannotBeSuspended) {
9393 var row = workInProgress.child;
9394
9395 while (row !== null) {
9396 var suspended = findFirstSuspended(row);
9397
9398 if (suspended !== null) {
9399 didSuspendAlready = true;
9400 workInProgress.flags |= DidCapture;
9401 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
9402 // part of the second pass. In that case nothing will subscribe to
9403 // its thenables. Instead, we'll transfer its thenables to the
9404 // SuspenseList so that it can retry if they resolve.
9405 // There might be multiple of these in the list but since we're
9406 // going to wait for all of them anyway, it doesn't really matter
9407 // which ones gets to ping. In theory we could get clever and keep
9408 // track of how many dependencies remain but it gets tricky because
9409 // in the meantime, we can add/remove/change items and dependencies.
9410 // We might bail out of the loop before finding any but that
9411 // doesn't matter since that means that the other boundaries that
9412 // we did find already has their listeners attached.
9413
9414 var newThenables = suspended.updateQueue;
9415
9416 if (newThenables !== null) {
9417 workInProgress.updateQueue = newThenables;
9418 workInProgress.flags |= Update;
9419 } // Rerender the whole list, but this time, we'll force fallbacks
9420 // to stay in place.
9421 // Reset the effect flags before doing the second pass since that's now invalid.
9422 // Reset the child fibers to their original state.
9423
9424
9425 workInProgress.subtreeFlags = NoFlags;
9426 resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately
9427 // rerender the children.
9428
9429 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback)); // Don't bubble properties in this case.
9430
9431 return workInProgress.child;
9432 }
9433
9434 row = row.sibling;
9435 }
9436 }
9437
9438 if (renderState.tail !== null && now() > getRenderTargetTime()) {
9439 // We have already passed our CPU deadline but we still have rows
9440 // left in the tail. We'll just give up further attempts to render
9441 // the main content and only render fallbacks.
9442 workInProgress.flags |= DidCapture;
9443 didSuspendAlready = true;
9444 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
9445 // to get it started back up to attempt the next item. While in terms
9446 // of priority this work has the same priority as this current render,
9447 // it's not part of the same transition once the transition has
9448 // committed. If it's sync, we still want to yield so that it can be
9449 // painted. Conceptually, this is really the same as pinging.
9450 // We can use any RetryLane even if it's the one currently rendering
9451 // since we're leaving it behind on this node.
9452
9453 workInProgress.lanes = SomeRetryLane;
9454 }
9455 } else {
9456 cutOffTailIfNeeded(renderState, false);
9457 } // Next we're going to render the tail.
9458
9459 } else {
9460 // Append the rendered row to the child list.
9461 if (!didSuspendAlready) {
9462 var _suspended = findFirstSuspended(renderedTail);
9463
9464 if (_suspended !== null) {
9465 workInProgress.flags |= DidCapture;
9466 didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't
9467 // get lost if this row ends up dropped during a second pass.
9468
9469 var _newThenables = _suspended.updateQueue;
9470
9471 if (_newThenables !== null) {
9472 workInProgress.updateQueue = _newThenables;
9473 workInProgress.flags |= Update;
9474 }
9475
9476 cutOffTailIfNeeded(renderState, true); // This might have been modified.
9477
9478 if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate && !getIsHydrating() // We don't cut it if we're hydrating.
9479 ) {
9480 // We're done.
9481 bubbleProperties(workInProgress);
9482 return null;
9483 }
9484 } else if ( // The time it took to render last row is greater than the remaining
9485 // time we have to render. So rendering one more row would likely
9486 // exceed it.
9487 now() * 2 - renderState.renderingStartTime > getRenderTargetTime() && renderLanes !== OffscreenLane) {
9488 // We have now passed our CPU deadline and we'll just give up further
9489 // attempts to render the main content and only render fallbacks.
9490 // The assumption is that this is usually faster.
9491 workInProgress.flags |= DidCapture;
9492 didSuspendAlready = true;
9493 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
9494 // to get it started back up to attempt the next item. While in terms
9495 // of priority this work has the same priority as this current render,
9496 // it's not part of the same transition once the transition has
9497 // committed. If it's sync, we still want to yield so that it can be
9498 // painted. Conceptually, this is really the same as pinging.
9499 // We can use any RetryLane even if it's the one currently rendering
9500 // since we're leaving it behind on this node.
9501
9502 workInProgress.lanes = SomeRetryLane;
9503 }
9504 }
9505
9506 if (renderState.isBackwards) {
9507 // The effect list of the backwards tail will have been added
9508 // to the end. This breaks the guarantee that life-cycles fire in
9509 // sibling order but that isn't a strong guarantee promised by React.
9510 // Especially since these might also just pop in during future commits.
9511 // Append to the beginning of the list.
9512 renderedTail.sibling = workInProgress.child;
9513 workInProgress.child = renderedTail;
9514 } else {
9515 var previousSibling = renderState.last;
9516
9517 if (previousSibling !== null) {
9518 previousSibling.sibling = renderedTail;
9519 } else {
9520 workInProgress.child = renderedTail;
9521 }
9522
9523 renderState.last = renderedTail;
9524 }
9525 }
9526
9527 if (renderState.tail !== null) {
9528 // We still have tail rows to render.
9529 // Pop a row.
9530 var next = renderState.tail;
9531 renderState.rendering = next;
9532 renderState.tail = next.sibling;
9533 renderState.renderingStartTime = now();
9534 next.sibling = null; // Restore the context.
9535 // TODO: We can probably just avoid popping it instead and only
9536 // setting it the first time we go from not suspended to suspended.
9537
9538 var suspenseContext = suspenseStackCursor.current;
9539
9540 if (didSuspendAlready) {
9541 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
9542 } else {
9543 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
9544 }
9545
9546 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
9547 // Don't bubble properties in this case.
9548
9549 return next;
9550 }
9551
9552 bubbleProperties(workInProgress);
9553 return null;
9554 }
9555
9556 case ScopeComponent:
9557 {
9558
9559 break;
9560 }
9561
9562 case OffscreenComponent:
9563 case LegacyHiddenComponent:
9564 {
9565 popRenderLanes(workInProgress);
9566 var _nextState = workInProgress.memoizedState;
9567 var nextIsHidden = _nextState !== null;
9568
9569 if (current !== null) {
9570 var _prevState2 = current.memoizedState;
9571 var prevIsHidden = _prevState2 !== null;
9572
9573 if (prevIsHidden !== nextIsHidden && ( // LegacyHidden doesn't do any hiding — it only pre-renders.
9574 !enableLegacyHidden )) {
9575 workInProgress.flags |= Visibility;
9576 }
9577 }
9578
9579 if (!nextIsHidden || (workInProgress.mode & ConcurrentMode) === NoMode) {
9580 bubbleProperties(workInProgress);
9581 } else {
9582 // Don't bubble properties for hidden children unless we're rendering
9583 // at offscreen priority.
9584 if (includesSomeLane(subtreeRenderLanes, OffscreenLane)) {
9585 bubbleProperties(workInProgress);
9586
9587 {
9588 // Check if there was an insertion or update in the hidden subtree.
9589 // If so, we need to hide those nodes in the commit phase, so
9590 // schedule a visibility effect.
9591 if ( workInProgress.subtreeFlags & (Placement | Update)) {
9592 workInProgress.flags |= Visibility;
9593 }
9594 }
9595 }
9596 }
9597
9598 return null;
9599 }
9600
9601 case CacheComponent:
9602 {
9603
9604 return null;
9605 }
9606
9607 case TracingMarkerComponent:
9608 {
9609
9610 return null;
9611 }
9612 }
9613
9614 throw new Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in " + 'React. Please file an issue.');
9615 }
9616
9617 var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
9618 var didReceiveUpdate = false;
9619 var didWarnAboutBadClass;
9620 var didWarnAboutModulePatternComponent;
9621 var didWarnAboutContextTypeOnFunctionComponent;
9622 var didWarnAboutGetDerivedStateOnFunctionComponent;
9623 var didWarnAboutFunctionRefs;
9624 var didWarnAboutReassigningProps;
9625 var didWarnAboutRevealOrder;
9626 var didWarnAboutTailOptions;
9627
9628 {
9629 didWarnAboutBadClass = {};
9630 didWarnAboutModulePatternComponent = {};
9631 didWarnAboutContextTypeOnFunctionComponent = {};
9632 didWarnAboutGetDerivedStateOnFunctionComponent = {};
9633 didWarnAboutFunctionRefs = {};
9634 didWarnAboutReassigningProps = false;
9635 didWarnAboutRevealOrder = {};
9636 didWarnAboutTailOptions = {};
9637 }
9638
9639 function reconcileChildren(current, workInProgress, nextChildren, renderLanes) {
9640 if (current === null) {
9641 // If this is a fresh new component that hasn't been rendered yet, we
9642 // won't update its child set by applying minimal side-effects. Instead,
9643 // we will add them all to the child before it gets rendered. That means
9644 // we can optimize this reconciliation pass by not tracking side-effects.
9645 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderLanes);
9646 } else {
9647 // If the current child is the same as the work in progress, it means that
9648 // we haven't yet started any work on these children. Therefore, we use
9649 // the clone algorithm to create a copy of all the current children.
9650 // If we had any progressed work already, that is invalid at this point so
9651 // let's throw it out.
9652 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderLanes);
9653 }
9654 }
9655
9656 function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes) {
9657 // This function is fork of reconcileChildren. It's used in cases where we
9658 // want to reconcile without matching against the existing set. This has the
9659 // effect of all current children being unmounted; even if the type and key
9660 // are the same, the old child is unmounted and a new child is created.
9661 //
9662 // To do this, we're going to go through the reconcile algorithm twice. In
9663 // the first pass, we schedule a deletion for all the current children by
9664 // passing null.
9665 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderLanes); // In the second pass, we mount the new children. The trick here is that we
9666 // pass null in place of where we usually pass the current child set. This has
9667 // the effect of remounting all children regardless of whether their
9668 // identities match.
9669
9670 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes);
9671 }
9672
9673 function updateForwardRef(current, workInProgress, Component, nextProps, renderLanes) {
9674 // TODO: current can be non-null here even if the component
9675 // hasn't yet mounted. This happens after the first render suspends.
9676 // We'll need to figure out if this is fine or can cause issues.
9677 {
9678 if (workInProgress.type !== workInProgress.elementType) {
9679 // Lazy component props can't be validated in createElement
9680 // because they're only guaranteed to be resolved here.
9681 var innerPropTypes = Component.propTypes;
9682
9683 if (innerPropTypes) {
9684 checkPropTypes(innerPropTypes, nextProps, // Resolved props
9685 'prop', getComponentNameFromType(Component));
9686 }
9687 }
9688 }
9689
9690 var render = Component.render;
9691 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent
9692
9693 var nextChildren;
9694 prepareToReadContext(workInProgress, renderLanes);
9695
9696 {
9697 ReactCurrentOwner$1.current = workInProgress;
9698 setIsRendering(true);
9699 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes);
9700
9701 setIsRendering(false);
9702 }
9703
9704 if (current !== null && !didReceiveUpdate) {
9705 bailoutHooks(current, workInProgress, renderLanes);
9706 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
9707 }
9708
9709
9710 workInProgress.flags |= PerformedWork;
9711 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
9712 return workInProgress.child;
9713 }
9714
9715 function updateMemoComponent(current, workInProgress, Component, nextProps, renderLanes) {
9716 if (current === null) {
9717 var type = Component.type;
9718
9719 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.
9720 Component.defaultProps === undefined) {
9721 var resolvedType = type;
9722
9723 {
9724 resolvedType = resolveFunctionForHotReloading(type);
9725 } // If this is a plain function component without default props,
9726 // and with only the default shallow comparison, we upgrade it
9727 // to a SimpleMemoComponent to allow fast path updates.
9728
9729
9730 workInProgress.tag = SimpleMemoComponent;
9731 workInProgress.type = resolvedType;
9732
9733 {
9734 validateFunctionComponentInDev(workInProgress, type);
9735 }
9736
9737 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, renderLanes);
9738 }
9739
9740 {
9741 var innerPropTypes = type.propTypes;
9742
9743 if (innerPropTypes) {
9744 // Inner memo component props aren't currently validated in createElement.
9745 // We could move it there, but we'd still need this for lazy code path.
9746 checkPropTypes(innerPropTypes, nextProps, // Resolved props
9747 'prop', getComponentNameFromType(type));
9748 }
9749 }
9750
9751 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, workInProgress, workInProgress.mode, renderLanes);
9752 child.ref = workInProgress.ref;
9753 child.return = workInProgress;
9754 workInProgress.child = child;
9755 return child;
9756 }
9757
9758 {
9759 var _type = Component.type;
9760 var _innerPropTypes = _type.propTypes;
9761
9762 if (_innerPropTypes) {
9763 // Inner memo component props aren't currently validated in createElement.
9764 // We could move it there, but we'd still need this for lazy code path.
9765 checkPropTypes(_innerPropTypes, nextProps, // Resolved props
9766 'prop', getComponentNameFromType(_type));
9767 }
9768 }
9769
9770 var currentChild = current.child; // This is always exactly one child
9771
9772 var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current, renderLanes);
9773
9774 if (!hasScheduledUpdateOrContext) {
9775 // This will be the props with resolved defaultProps,
9776 // unlike current.memoizedProps which will be the unresolved ones.
9777 var prevProps = currentChild.memoizedProps; // Default to shallow comparison
9778
9779 var compare = Component.compare;
9780 compare = compare !== null ? compare : shallowEqual;
9781
9782 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
9783 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
9784 }
9785 } // React DevTools reads this flag.
9786
9787
9788 workInProgress.flags |= PerformedWork;
9789 var newChild = createWorkInProgress(currentChild, nextProps);
9790 newChild.ref = workInProgress.ref;
9791 newChild.return = workInProgress;
9792 workInProgress.child = newChild;
9793 return newChild;
9794 }
9795
9796 function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, renderLanes) {
9797 // TODO: current can be non-null here even if the component
9798 // hasn't yet mounted. This happens when the inner render suspends.
9799 // We'll need to figure out if this is fine or can cause issues.
9800 {
9801 if (workInProgress.type !== workInProgress.elementType) {
9802 // Lazy component props can't be validated in createElement
9803 // because they're only guaranteed to be resolved here.
9804 var outerMemoType = workInProgress.elementType;
9805
9806 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
9807 // We warn when you define propTypes on lazy()
9808 // so let's just skip over it to find memo() outer wrapper.
9809 // Inner props for memo are validated later.
9810 var lazyComponent = outerMemoType;
9811 var payload = lazyComponent._payload;
9812 var init = lazyComponent._init;
9813
9814 try {
9815 outerMemoType = init(payload);
9816 } catch (x) {
9817 outerMemoType = null;
9818 } // Inner propTypes will be validated in the function component path.
9819
9820
9821 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
9822
9823 if (outerPropTypes) {
9824 checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
9825 'prop', getComponentNameFromType(outerMemoType));
9826 }
9827 }
9828 }
9829 }
9830
9831 if (current !== null) {
9832 var prevProps = current.memoizedProps;
9833
9834 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload.
9835 workInProgress.type === current.type )) {
9836 didReceiveUpdate = false;
9837
9838 if (!checkScheduledUpdateOrContext(current, renderLanes)) {
9839 // The pending lanes were cleared at the beginning of beginWork. We're
9840 // about to bail out, but there might be other lanes that weren't
9841 // included in the current render. Usually, the priority level of the
9842 // remaining updates is accumulated during the evaluation of the
9843 // component (i.e. when processing the update queue). But since since
9844 // we're bailing out early *without* evaluating the component, we need
9845 // to account for it here, too. Reset to the value of the current fiber.
9846 // NOTE: This only applies to SimpleMemoComponent, not MemoComponent,
9847 // because a MemoComponent fiber does not have hooks or an update queue;
9848 // rather, it wraps around an inner component, which may or may not
9849 // contains hooks.
9850 // TODO: Move the reset at in beginWork out of the common path so that
9851 // this is no longer necessary.
9852 workInProgress.lanes = current.lanes;
9853 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
9854 } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) {
9855 // This is a special case that only exists for legacy mode.
9856 // See https://github.com/facebook/react/pull/19216.
9857 didReceiveUpdate = true;
9858 }
9859 }
9860 }
9861
9862 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes);
9863 }
9864
9865 function updateOffscreenComponent(current, workInProgress, renderLanes) {
9866 var nextProps = workInProgress.pendingProps;
9867 var nextChildren = nextProps.children;
9868 var prevState = current !== null ? current.memoizedState : null;
9869
9870 if (nextProps.mode === 'hidden' || enableLegacyHidden ) {
9871 // Rendering a hidden tree.
9872 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
9873 // In legacy sync mode, don't defer the subtree. Render it now.
9874 var nextState = {
9875 baseLanes: NoLanes,
9876 cachePool: null
9877 };
9878 workInProgress.memoizedState = nextState;
9879
9880 pushRenderLanes(workInProgress, renderLanes);
9881 } else if (!includesSomeLane(renderLanes, OffscreenLane)) {
9882 var spawnedCachePool = null; // We're hidden, and we're not rendering at Offscreen. We will bail out
9883 // and resume this tree later.
9884
9885 var nextBaseLanes;
9886
9887 if (prevState !== null) {
9888 var prevBaseLanes = prevState.baseLanes;
9889 nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes);
9890 } else {
9891 nextBaseLanes = renderLanes;
9892 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
9893
9894
9895 workInProgress.lanes = workInProgress.childLanes = laneToLanes(OffscreenLane);
9896 var _nextState = {
9897 baseLanes: nextBaseLanes,
9898 cachePool: spawnedCachePool
9899 };
9900 workInProgress.memoizedState = _nextState;
9901 workInProgress.updateQueue = null;
9902 // to avoid a push/pop misalignment.
9903
9904
9905 pushRenderLanes(workInProgress, nextBaseLanes);
9906
9907 return null;
9908 } else {
9909 // This is the second render. The surrounding visible content has already
9910 // committed. Now we resume rendering the hidden tree.
9911 // Rendering at offscreen, so we can clear the base lanes.
9912 var _nextState2 = {
9913 baseLanes: NoLanes,
9914 cachePool: null
9915 };
9916 workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out.
9917
9918 var subtreeRenderLanes = prevState !== null ? prevState.baseLanes : renderLanes;
9919
9920 pushRenderLanes(workInProgress, subtreeRenderLanes);
9921 }
9922 } else {
9923 // Rendering a visible tree.
9924 var _subtreeRenderLanes;
9925
9926 if (prevState !== null) {
9927 // We're going from hidden -> visible.
9928 _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes);
9929
9930
9931 workInProgress.memoizedState = null;
9932 } else {
9933 // We weren't previously hidden, and we still aren't, so there's nothing
9934 // special to do. Need to push to the stack regardless, though, to avoid
9935 // a push/pop misalignment.
9936 _subtreeRenderLanes = renderLanes;
9937 }
9938
9939 pushRenderLanes(workInProgress, _subtreeRenderLanes);
9940 }
9941
9942 {
9943 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
9944 return workInProgress.child;
9945 }
9946 }
9947
9948 function updateFragment(current, workInProgress, renderLanes) {
9949 var nextChildren = workInProgress.pendingProps;
9950 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
9951 return workInProgress.child;
9952 }
9953
9954 function updateMode(current, workInProgress, renderLanes) {
9955 var nextChildren = workInProgress.pendingProps.children;
9956 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
9957 return workInProgress.child;
9958 }
9959
9960 function updateProfiler(current, workInProgress, renderLanes) {
9961 {
9962 workInProgress.flags |= Update;
9963
9964 {
9965 // Reset effect durations for the next eventual effect phase.
9966 // These are reset during render to allow the DevTools commit hook a chance to read them,
9967 var stateNode = workInProgress.stateNode;
9968 stateNode.effectDuration = 0;
9969 stateNode.passiveEffectDuration = 0;
9970 }
9971 }
9972
9973 var nextProps = workInProgress.pendingProps;
9974 var nextChildren = nextProps.children;
9975 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
9976 return workInProgress.child;
9977 }
9978
9979 function markRef$1(current, workInProgress) {
9980 var ref = workInProgress.ref;
9981
9982 if (current === null && ref !== null || current !== null && current.ref !== ref) {
9983 // Schedule a Ref effect
9984 workInProgress.flags |= Ref;
9985 }
9986 }
9987
9988 function updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes) {
9989 {
9990 if (workInProgress.type !== workInProgress.elementType) {
9991 // Lazy component props can't be validated in createElement
9992 // because they're only guaranteed to be resolved here.
9993 var innerPropTypes = Component.propTypes;
9994
9995 if (innerPropTypes) {
9996 checkPropTypes(innerPropTypes, nextProps, // Resolved props
9997 'prop', getComponentNameFromType(Component));
9998 }
9999 }
10000 }
10001
10002 var context;
10003
10004 {
10005 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
10006 context = getMaskedContext(workInProgress, unmaskedContext);
10007 }
10008
10009 var nextChildren;
10010 prepareToReadContext(workInProgress, renderLanes);
10011
10012 {
10013 ReactCurrentOwner$1.current = workInProgress;
10014 setIsRendering(true);
10015 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes);
10016
10017 setIsRendering(false);
10018 }
10019
10020 if (current !== null && !didReceiveUpdate) {
10021 bailoutHooks(current, workInProgress, renderLanes);
10022 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
10023 }
10024
10025
10026 workInProgress.flags |= PerformedWork;
10027 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
10028 return workInProgress.child;
10029 }
10030
10031 function updateClassComponent(current, workInProgress, Component, nextProps, renderLanes) {
10032 {
10033 // This is used by DevTools to force a boundary to error.
10034 switch (shouldError(workInProgress)) {
10035 case false:
10036 {
10037 var _instance = workInProgress.stateNode;
10038 var ctor = workInProgress.type; // TODO This way of resetting the error boundary state is a hack.
10039 // Is there a better way to do this?
10040
10041 var tempInstance = new ctor(workInProgress.memoizedProps, _instance.context);
10042 var state = tempInstance.state;
10043
10044 _instance.updater.enqueueSetState(_instance, state, null);
10045
10046 break;
10047 }
10048
10049 case true:
10050 {
10051 workInProgress.flags |= DidCapture;
10052 workInProgress.flags |= ShouldCapture; // eslint-disable-next-line react-internal/prod-error-codes
10053
10054 var error$1 = new Error('Simulated error coming from DevTools');
10055 var lane = pickArbitraryLane(renderLanes);
10056 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); // Schedule the error boundary to re-render using updated state
10057
10058 var update = createClassErrorUpdate(workInProgress, createCapturedValue(error$1, workInProgress), lane);
10059 enqueueCapturedUpdate(workInProgress, update);
10060 break;
10061 }
10062 }
10063
10064 if (workInProgress.type !== workInProgress.elementType) {
10065 // Lazy component props can't be validated in createElement
10066 // because they're only guaranteed to be resolved here.
10067 var innerPropTypes = Component.propTypes;
10068
10069 if (innerPropTypes) {
10070 checkPropTypes(innerPropTypes, nextProps, // Resolved props
10071 'prop', getComponentNameFromType(Component));
10072 }
10073 }
10074 } // Push context providers early to prevent context stack mismatches.
10075 // During mounting we don't know the child context yet as the instance doesn't exist.
10076 // We will invalidate the child context in finishClassComponent() right after rendering.
10077
10078
10079 var hasContext;
10080
10081 if (isContextProvider(Component)) {
10082 hasContext = true;
10083 pushContextProvider(workInProgress);
10084 } else {
10085 hasContext = false;
10086 }
10087
10088 prepareToReadContext(workInProgress, renderLanes);
10089 var instance = workInProgress.stateNode;
10090 var shouldUpdate;
10091
10092 if (instance === null) {
10093 if (current !== null) {
10094 // A class component without an instance only mounts if it suspended
10095 // inside a non-concurrent tree, in an inconsistent state. We want to
10096 // treat it like a new mount, even though an empty version of it already
10097 // committed. Disconnect the alternate pointers.
10098 current.alternate = null;
10099 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
10100
10101 workInProgress.flags |= Placement;
10102 } // In the initial pass we might need to construct the instance.
10103
10104
10105 constructClassInstance(workInProgress, Component, nextProps);
10106 mountClassInstance(workInProgress, Component, nextProps, renderLanes);
10107 shouldUpdate = true;
10108 } else if (current === null) {
10109 // In a resume, we'll already have an instance we can reuse.
10110 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderLanes);
10111 } else {
10112 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderLanes);
10113 }
10114
10115 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes);
10116
10117 {
10118 var inst = workInProgress.stateNode;
10119
10120 if (shouldUpdate && inst.props !== nextProps) {
10121 if (!didWarnAboutReassigningProps) {
10122 error('It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentNameFromFiber(workInProgress) || 'a component');
10123 }
10124
10125 didWarnAboutReassigningProps = true;
10126 }
10127 }
10128
10129 return nextUnitOfWork;
10130 }
10131
10132 function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes) {
10133 // Refs should update even if shouldComponentUpdate returns false
10134 markRef$1(current, workInProgress);
10135 var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags;
10136
10137 if (!shouldUpdate && !didCaptureError) {
10138 // Context providers should defer to sCU for rendering
10139 if (hasContext) {
10140 invalidateContextProvider(workInProgress, Component, false);
10141 }
10142
10143 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
10144 }
10145
10146 var instance = workInProgress.stateNode; // Rerender
10147
10148 ReactCurrentOwner$1.current = workInProgress;
10149 var nextChildren;
10150
10151 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
10152 // If we captured an error, but getDerivedStateFromError is not defined,
10153 // unmount all the children. componentDidCatch will schedule an update to
10154 // re-render a fallback. This is temporary until we migrate everyone to
10155 // the new API.
10156 // TODO: Warn in a future release.
10157 nextChildren = null;
10158
10159 {
10160 stopProfilerTimerIfRunning();
10161 }
10162 } else {
10163
10164 {
10165 setIsRendering(true);
10166 nextChildren = instance.render();
10167
10168 setIsRendering(false);
10169 }
10170 } // React DevTools reads this flag.
10171
10172
10173 workInProgress.flags |= PerformedWork;
10174
10175 if (current !== null && didCaptureError) {
10176 // If we're recovering from an error, reconcile without reusing any of
10177 // the existing children. Conceptually, the normal children and the children
10178 // that are shown on error are two different sets, so we shouldn't reuse
10179 // normal children even if their identities match.
10180 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes);
10181 } else {
10182 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
10183 } // Memoize state using the values we just used to render.
10184 // TODO: Restructure so we never read values from the instance.
10185
10186
10187 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
10188
10189 if (hasContext) {
10190 invalidateContextProvider(workInProgress, Component, true);
10191 }
10192
10193 return workInProgress.child;
10194 }
10195
10196 function pushHostRootContext(workInProgress) {
10197 var root = workInProgress.stateNode;
10198
10199 if (root.pendingContext) {
10200 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
10201 } else if (root.context) {
10202 // Should always be set
10203 pushTopLevelContextObject(workInProgress, root.context, false);
10204 }
10205
10206 pushHostContainer(workInProgress, root.containerInfo);
10207 }
10208
10209 function updateHostRoot(current, workInProgress, renderLanes) {
10210 pushHostRootContext(workInProgress);
10211
10212 if (current === null) {
10213 throw new Error('Should have a current fiber. This is a bug in React.');
10214 }
10215
10216 var nextProps = workInProgress.pendingProps;
10217 var prevState = workInProgress.memoizedState;
10218 var prevChildren = prevState.element;
10219 cloneUpdateQueue(current, workInProgress);
10220 processUpdateQueue(workInProgress, nextProps, null, renderLanes);
10221 var nextState = workInProgress.memoizedState;
10222 var root = workInProgress.stateNode;
10223 // being called "element".
10224
10225
10226 var nextChildren = nextState.element;
10227
10228 {
10229
10230 if (nextChildren === prevChildren) {
10231 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
10232 }
10233
10234 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
10235 }
10236
10237 return workInProgress.child;
10238 }
10239
10240 function updateHostComponent$1(current, workInProgress, renderLanes) {
10241 pushHostContext(workInProgress);
10242
10243 var type = workInProgress.type;
10244 var nextProps = workInProgress.pendingProps;
10245 var prevProps = current !== null ? current.memoizedProps : null;
10246 var nextChildren = nextProps.children;
10247
10248 if (prevProps !== null && shouldSetTextContent()) {
10249 // If we're switching from a direct text child to a normal child, or to
10250 // empty, we need to schedule the text content to be reset.
10251 workInProgress.flags |= ContentReset;
10252 }
10253
10254 markRef$1(current, workInProgress);
10255 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
10256 return workInProgress.child;
10257 }
10258
10259 function updateHostText$1(current, workInProgress) {
10260 // immediately after.
10261
10262
10263 return null;
10264 }
10265
10266 function mountLazyComponent(_current, workInProgress, elementType, renderLanes) {
10267 if (_current !== null) {
10268 // A lazy component only mounts if it suspended inside a non-
10269 // concurrent tree, in an inconsistent state. We want to treat it like
10270 // a new mount, even though an empty version of it already committed.
10271 // Disconnect the alternate pointers.
10272 _current.alternate = null;
10273 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
10274
10275 workInProgress.flags |= Placement;
10276 }
10277
10278 var props = workInProgress.pendingProps;
10279 var lazyComponent = elementType;
10280 var payload = lazyComponent._payload;
10281 var init = lazyComponent._init;
10282 var Component = init(payload); // Store the unwrapped component in the type.
10283
10284 workInProgress.type = Component;
10285 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
10286 var resolvedProps = resolveDefaultProps(Component, props);
10287 var child;
10288
10289 switch (resolvedTag) {
10290 case FunctionComponent:
10291 {
10292 {
10293 validateFunctionComponentInDev(workInProgress, Component);
10294 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
10295 }
10296
10297 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderLanes);
10298 return child;
10299 }
10300
10301 case ClassComponent:
10302 {
10303 {
10304 workInProgress.type = Component = resolveClassForHotReloading(Component);
10305 }
10306
10307 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderLanes);
10308 return child;
10309 }
10310
10311 case ForwardRef:
10312 {
10313 {
10314 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
10315 }
10316
10317 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderLanes);
10318 return child;
10319 }
10320
10321 case MemoComponent:
10322 {
10323 {
10324 if (workInProgress.type !== workInProgress.elementType) {
10325 var outerPropTypes = Component.propTypes;
10326
10327 if (outerPropTypes) {
10328 checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only
10329 'prop', getComponentNameFromType(Component));
10330 }
10331 }
10332 }
10333
10334 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
10335 renderLanes);
10336 return child;
10337 }
10338 }
10339
10340 var hint = '';
10341
10342 {
10343 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
10344 hint = ' Did you wrap a component in React.lazy() more than once?';
10345 }
10346 } // This message intentionally doesn't mention ForwardRef or MemoComponent
10347 // because the fact that it's a separate type of work is an
10348 // implementation detail.
10349
10350
10351 throw new Error("Element type is invalid. Received a promise that resolves to: " + Component + ". " + ("Lazy element type must resolve to a class or function." + hint));
10352 }
10353
10354 function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderLanes) {
10355 if (_current !== null) {
10356 // An incomplete component only mounts if it suspended inside a non-
10357 // concurrent tree, in an inconsistent state. We want to treat it like
10358 // a new mount, even though an empty version of it already committed.
10359 // Disconnect the alternate pointers.
10360 _current.alternate = null;
10361 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
10362
10363 workInProgress.flags |= Placement;
10364 } // Promote the fiber to a class and try rendering again.
10365
10366
10367 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`
10368 // Push context providers early to prevent context stack mismatches.
10369 // During mounting we don't know the child context yet as the instance doesn't exist.
10370 // We will invalidate the child context in finishClassComponent() right after rendering.
10371
10372 var hasContext;
10373
10374 if (isContextProvider(Component)) {
10375 hasContext = true;
10376 pushContextProvider(workInProgress);
10377 } else {
10378 hasContext = false;
10379 }
10380
10381 prepareToReadContext(workInProgress, renderLanes);
10382 constructClassInstance(workInProgress, Component, nextProps);
10383 mountClassInstance(workInProgress, Component, nextProps, renderLanes);
10384 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes);
10385 }
10386
10387 function mountIndeterminateComponent(_current, workInProgress, Component, renderLanes) {
10388 if (_current !== null) {
10389 // An indeterminate component only mounts if it suspended inside a non-
10390 // concurrent tree, in an inconsistent state. We want to treat it like
10391 // a new mount, even though an empty version of it already committed.
10392 // Disconnect the alternate pointers.
10393 _current.alternate = null;
10394 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
10395
10396 workInProgress.flags |= Placement;
10397 }
10398
10399 var props = workInProgress.pendingProps;
10400 var context;
10401
10402 {
10403 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
10404 context = getMaskedContext(workInProgress, unmaskedContext);
10405 }
10406
10407 prepareToReadContext(workInProgress, renderLanes);
10408 var value;
10409
10410 {
10411 if (Component.prototype && typeof Component.prototype.render === 'function') {
10412 var componentName = getComponentNameFromType(Component) || 'Unknown';
10413
10414 if (!didWarnAboutBadClass[componentName]) {
10415 error("The <%s /> component appears to have a render method, but doesn't extend React.Component. " + 'This is likely to cause errors. Change %s to extend React.Component instead.', componentName, componentName);
10416
10417 didWarnAboutBadClass[componentName] = true;
10418 }
10419 }
10420
10421 if (workInProgress.mode & StrictLegacyMode) {
10422 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
10423 }
10424
10425 setIsRendering(true);
10426 ReactCurrentOwner$1.current = workInProgress;
10427 value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes);
10428 setIsRendering(false);
10429 }
10430
10431
10432 workInProgress.flags |= PerformedWork;
10433
10434 {
10435 // Support for module components is deprecated and is removed behind a flag.
10436 // Whether or not it would crash later, we want to show a good message in DEV first.
10437 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
10438 var _componentName = getComponentNameFromType(Component) || 'Unknown';
10439
10440 if (!didWarnAboutModulePatternComponent[_componentName]) {
10441 error('The <%s /> component appears to be a function component that returns a class instance. ' + 'Change %s to a class that extends React.Component instead. ' + "If you can't use a class try assigning the prototype on the function as a workaround. " + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + 'cannot be called with `new` by React.', _componentName, _componentName, _componentName);
10442
10443 didWarnAboutModulePatternComponent[_componentName] = true;
10444 }
10445 }
10446 }
10447
10448 if ( // Run these checks in production only if the flag is off.
10449 // Eventually we'll delete this branch altogether.
10450 typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
10451 {
10452 var _componentName2 = getComponentNameFromType(Component) || 'Unknown';
10453
10454 if (!didWarnAboutModulePatternComponent[_componentName2]) {
10455 error('The <%s /> component appears to be a function component that returns a class instance. ' + 'Change %s to a class that extends React.Component instead. ' + "If you can't use a class try assigning the prototype on the function as a workaround. " + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + 'cannot be called with `new` by React.', _componentName2, _componentName2, _componentName2);
10456
10457 didWarnAboutModulePatternComponent[_componentName2] = true;
10458 }
10459 } // Proceed under the assumption that this is a class instance
10460
10461
10462 workInProgress.tag = ClassComponent; // Throw out any hooks that were used.
10463
10464 workInProgress.memoizedState = null;
10465 workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches.
10466 // During mounting we don't know the child context yet as the instance doesn't exist.
10467 // We will invalidate the child context in finishClassComponent() right after rendering.
10468
10469 var hasContext = false;
10470
10471 if (isContextProvider(Component)) {
10472 hasContext = true;
10473 pushContextProvider(workInProgress);
10474 } else {
10475 hasContext = false;
10476 }
10477
10478 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
10479 initializeUpdateQueue(workInProgress);
10480 adoptClassInstance(workInProgress, value);
10481 mountClassInstance(workInProgress, Component, props, renderLanes);
10482 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes);
10483 } else {
10484 // Proceed under the assumption that this is a function component
10485 workInProgress.tag = FunctionComponent;
10486
10487 reconcileChildren(null, workInProgress, value, renderLanes);
10488
10489 {
10490 validateFunctionComponentInDev(workInProgress, Component);
10491 }
10492
10493 return workInProgress.child;
10494 }
10495 }
10496
10497 function validateFunctionComponentInDev(workInProgress, Component) {
10498 {
10499 if (Component) {
10500 if (Component.childContextTypes) {
10501 error('%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component');
10502 }
10503 }
10504
10505 if (workInProgress.ref !== null) {
10506 var info = '';
10507 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
10508
10509 if (ownerName) {
10510 info += '\n\nCheck the render method of `' + ownerName + '`.';
10511 }
10512
10513 var warningKey = ownerName || '';
10514 var debugSource = workInProgress._debugSource;
10515
10516 if (debugSource) {
10517 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
10518 }
10519
10520 if (!didWarnAboutFunctionRefs[warningKey]) {
10521 didWarnAboutFunctionRefs[warningKey] = true;
10522
10523 error('Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
10524 }
10525 }
10526
10527 if (typeof Component.getDerivedStateFromProps === 'function') {
10528 var _componentName3 = getComponentNameFromType(Component) || 'Unknown';
10529
10530 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) {
10531 error('%s: Function components do not support getDerivedStateFromProps.', _componentName3);
10532
10533 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true;
10534 }
10535 }
10536
10537 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
10538 var _componentName4 = getComponentNameFromType(Component) || 'Unknown';
10539
10540 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) {
10541 error('%s: Function components do not support contextType.', _componentName4);
10542
10543 didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true;
10544 }
10545 }
10546 }
10547 }
10548
10549 var SUSPENDED_MARKER = {
10550 dehydrated: null,
10551 treeContext: null,
10552 retryLane: NoLane
10553 };
10554
10555 function mountSuspenseOffscreenState(renderLanes) {
10556 return {
10557 baseLanes: renderLanes,
10558 cachePool: getSuspendedCache()
10559 };
10560 }
10561
10562 function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) {
10563 var cachePool = null;
10564
10565 return {
10566 baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes),
10567 cachePool: cachePool
10568 };
10569 } // TODO: Probably should inline this back
10570
10571
10572 function shouldRemainOnFallback(suspenseContext, current, workInProgress, renderLanes) {
10573 // If we're already showing a fallback, there are cases where we need to
10574 // remain on that fallback regardless of whether the content has resolved.
10575 // For example, SuspenseList coordinates when nested content appears.
10576 if (current !== null) {
10577 var suspenseState = current.memoizedState;
10578
10579 if (suspenseState === null) {
10580 // Currently showing content. Don't hide it, even if ForceSuspenseFallback
10581 // is true. More precise name might be "ForceRemainSuspenseFallback".
10582 // Note: This is a factoring smell. Can't remain on a fallback if there's
10583 // no fallback to remain on.
10584 return false;
10585 }
10586 } // Not currently showing content. Consult the Suspense context.
10587
10588
10589 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
10590 }
10591
10592 function getRemainingWorkInPrimaryTree(current, renderLanes) {
10593 // TODO: Should not remove render lanes that were pinged during this render
10594 return removeLanes(current.childLanes, renderLanes);
10595 }
10596
10597 function updateSuspenseComponent(current, workInProgress, renderLanes) {
10598 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
10599
10600 {
10601 if (shouldSuspend(workInProgress)) {
10602 workInProgress.flags |= DidCapture;
10603 }
10604 }
10605
10606 var suspenseContext = suspenseStackCursor.current;
10607 var showFallback = false;
10608 var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags;
10609
10610 if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) {
10611 // Something in this boundary's subtree already suspended. Switch to
10612 // rendering the fallback children.
10613 showFallback = true;
10614 workInProgress.flags &= ~DidCapture;
10615 } else {
10616 // Attempting the main content
10617 if (current === null || current.memoizedState !== null) {
10618 // This is a new mount or this boundary is already showing a fallback state.
10619 // Mark this subtree context as having at least one invisible parent that could
10620 // handle the fallback state.
10621 // Avoided boundaries are not considered since they cannot handle preferred fallback states.
10622 {
10623 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
10624 }
10625 }
10626 }
10627
10628 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
10629 pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense
10630 // boundary's children. This involves some custom reconciliation logic. Two
10631 // main reasons this is so complicated.
10632 //
10633 // First, Legacy Mode has different semantics for backwards compatibility. The
10634 // primary tree will commit in an inconsistent state, so when we do the
10635 // second pass to render the fallback, we do some exceedingly, uh, clever
10636 // hacks to make that not totally break. Like transferring effects and
10637 // deletions from hidden tree. In Concurrent Mode, it's much simpler,
10638 // because we bailout on the primary tree completely and leave it in its old
10639 // state, no effects. Same as what we do for Offscreen (except that
10640 // Offscreen doesn't have the first render pass).
10641 //
10642 // Second is hydration. During hydration, the Suspense fiber has a slightly
10643 // different layout, where the child points to a dehydrated fragment, which
10644 // contains the DOM rendered by the server.
10645 //
10646 // Third, even if you set all that aside, Suspense is like error boundaries in
10647 // that we first we try to render one tree, and if that fails, we render again
10648 // and switch to a different tree. Like a try/catch block. So we have to track
10649 // which branch we're currently rendering. Ideally we would model this using
10650 // a stack.
10651
10652 if (current === null) {
10653
10654 var nextPrimaryChildren = nextProps.children;
10655 var nextFallbackChildren = nextProps.fallback;
10656
10657 if (showFallback) {
10658 var fallbackFragment = mountSuspenseFallbackChildren(workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes);
10659 var primaryChildFragment = workInProgress.child;
10660 primaryChildFragment.memoizedState = mountSuspenseOffscreenState(renderLanes);
10661 workInProgress.memoizedState = SUSPENDED_MARKER;
10662 return fallbackFragment;
10663 } else {
10664 return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren);
10665 }
10666 } else {
10667 // This is an update.
10668 // If the current fiber has a SuspenseState, that means it's already showing
10669 // a fallback.
10670 var prevState = current.memoizedState;
10671
10672 if (prevState !== null) {
10673
10674 if (showFallback) {
10675 var _nextFallbackChildren2 = nextProps.fallback;
10676 var _nextPrimaryChildren2 = nextProps.children;
10677
10678 var _fallbackChildFragment = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren2, _nextFallbackChildren2, renderLanes);
10679
10680 var _primaryChildFragment3 = workInProgress.child;
10681 var prevOffscreenState = current.child.memoizedState;
10682 _primaryChildFragment3.memoizedState = prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(prevOffscreenState, renderLanes);
10683 _primaryChildFragment3.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes);
10684 workInProgress.memoizedState = SUSPENDED_MARKER;
10685 return _fallbackChildFragment;
10686 } else {
10687 var _nextPrimaryChildren3 = nextProps.children;
10688
10689 var _primaryChildFragment4 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren3, renderLanes);
10690
10691 workInProgress.memoizedState = null;
10692 return _primaryChildFragment4;
10693 }
10694 } else {
10695 // The current tree is not already showing a fallback.
10696 if (showFallback) {
10697 // Timed out.
10698 var _nextFallbackChildren3 = nextProps.fallback;
10699 var _nextPrimaryChildren4 = nextProps.children;
10700
10701 var _fallbackChildFragment2 = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren4, _nextFallbackChildren3, renderLanes);
10702
10703 var _primaryChildFragment5 = workInProgress.child;
10704 var _prevOffscreenState = current.child.memoizedState;
10705 _primaryChildFragment5.memoizedState = _prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(_prevOffscreenState, renderLanes);
10706 _primaryChildFragment5.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes); // Skip the primary children, and continue working on the
10707 // fallback children.
10708
10709 workInProgress.memoizedState = SUSPENDED_MARKER;
10710 return _fallbackChildFragment2;
10711 } else {
10712 // Still haven't timed out. Continue rendering the children, like we
10713 // normally do.
10714 var _nextPrimaryChildren5 = nextProps.children;
10715
10716 var _primaryChildFragment6 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren5, renderLanes);
10717
10718 workInProgress.memoizedState = null;
10719 return _primaryChildFragment6;
10720 }
10721 }
10722 }
10723 }
10724
10725 function mountSuspensePrimaryChildren(workInProgress, primaryChildren, renderLanes) {
10726 var mode = workInProgress.mode;
10727 var primaryChildProps = {
10728 mode: 'visible',
10729 children: primaryChildren
10730 };
10731 var primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode);
10732 primaryChildFragment.return = workInProgress;
10733 workInProgress.child = primaryChildFragment;
10734 return primaryChildFragment;
10735 }
10736
10737 function mountSuspenseFallbackChildren(workInProgress, primaryChildren, fallbackChildren, renderLanes) {
10738 var mode = workInProgress.mode;
10739 var progressedPrimaryFragment = workInProgress.child;
10740 var primaryChildProps = {
10741 mode: 'hidden',
10742 children: primaryChildren
10743 };
10744 var primaryChildFragment;
10745 var fallbackChildFragment;
10746
10747 if ((mode & ConcurrentMode) === NoMode && progressedPrimaryFragment !== null) {
10748 // In legacy mode, we commit the primary tree as if it successfully
10749 // completed, even though it's in an inconsistent state.
10750 primaryChildFragment = progressedPrimaryFragment;
10751 primaryChildFragment.childLanes = NoLanes;
10752 primaryChildFragment.pendingProps = primaryChildProps;
10753
10754 if ( workInProgress.mode & ProfileMode) {
10755 // Reset the durations from the first pass so they aren't included in the
10756 // final amounts. This seems counterintuitive, since we're intentionally
10757 // not measuring part of the render phase, but this makes it match what we
10758 // do in Concurrent Mode.
10759 primaryChildFragment.actualDuration = 0;
10760 primaryChildFragment.actualStartTime = -1;
10761 primaryChildFragment.selfBaseDuration = 0;
10762 primaryChildFragment.treeBaseDuration = 0;
10763 }
10764
10765 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null);
10766 } else {
10767 primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode);
10768 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null);
10769 }
10770
10771 primaryChildFragment.return = workInProgress;
10772 fallbackChildFragment.return = workInProgress;
10773 primaryChildFragment.sibling = fallbackChildFragment;
10774 workInProgress.child = primaryChildFragment;
10775 return fallbackChildFragment;
10776 }
10777
10778 function mountWorkInProgressOffscreenFiber(offscreenProps, mode, renderLanes) {
10779 // The props argument to `createFiberFromOffscreen` is `any` typed, so we use
10780 // this wrapper function to constrain it.
10781 return createFiberFromOffscreen(offscreenProps, mode, NoLanes, null);
10782 }
10783
10784 function updateWorkInProgressOffscreenFiber(current, offscreenProps) {
10785 // The props argument to `createWorkInProgress` is `any` typed, so we use this
10786 // wrapper function to constrain it.
10787 return createWorkInProgress(current, offscreenProps);
10788 }
10789
10790 function updateSuspensePrimaryChildren(current, workInProgress, primaryChildren, renderLanes) {
10791 var currentPrimaryChildFragment = current.child;
10792 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
10793 var primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, {
10794 mode: 'visible',
10795 children: primaryChildren
10796 });
10797
10798 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
10799 primaryChildFragment.lanes = renderLanes;
10800 }
10801
10802 primaryChildFragment.return = workInProgress;
10803 primaryChildFragment.sibling = null;
10804
10805 if (currentFallbackChildFragment !== null) {
10806 // Delete the fallback child fragment
10807 var deletions = workInProgress.deletions;
10808
10809 if (deletions === null) {
10810 workInProgress.deletions = [currentFallbackChildFragment];
10811 workInProgress.flags |= ChildDeletion;
10812 } else {
10813 deletions.push(currentFallbackChildFragment);
10814 }
10815 }
10816
10817 workInProgress.child = primaryChildFragment;
10818 return primaryChildFragment;
10819 }
10820
10821 function updateSuspenseFallbackChildren(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) {
10822 var mode = workInProgress.mode;
10823 var currentPrimaryChildFragment = current.child;
10824 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
10825 var primaryChildProps = {
10826 mode: 'hidden',
10827 children: primaryChildren
10828 };
10829 var primaryChildFragment;
10830
10831 if ( // In legacy mode, we commit the primary tree as if it successfully
10832 // completed, even though it's in an inconsistent state.
10833 (mode & ConcurrentMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was
10834 // already cloned. In legacy mode, the only case where this isn't true is
10835 // when DevTools forces us to display a fallback; we skip the first render
10836 // pass entirely and go straight to rendering the fallback. (In Concurrent
10837 // Mode, SuspenseList can also trigger this scenario, but this is a legacy-
10838 // only codepath.)
10839 workInProgress.child !== currentPrimaryChildFragment) {
10840 var progressedPrimaryFragment = workInProgress.child;
10841 primaryChildFragment = progressedPrimaryFragment;
10842 primaryChildFragment.childLanes = NoLanes;
10843 primaryChildFragment.pendingProps = primaryChildProps;
10844
10845 if ( workInProgress.mode & ProfileMode) {
10846 // Reset the durations from the first pass so they aren't included in the
10847 // final amounts. This seems counterintuitive, since we're intentionally
10848 // not measuring part of the render phase, but this makes it match what we
10849 // do in Concurrent Mode.
10850 primaryChildFragment.actualDuration = 0;
10851 primaryChildFragment.actualStartTime = -1;
10852 primaryChildFragment.selfBaseDuration = currentPrimaryChildFragment.selfBaseDuration;
10853 primaryChildFragment.treeBaseDuration = currentPrimaryChildFragment.treeBaseDuration;
10854 }
10855 // However, since we're going to remain on the fallback, we no longer want
10856 // to delete it.
10857
10858
10859 workInProgress.deletions = null;
10860 } else {
10861 primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, primaryChildProps);
10862 // (We don't do this in legacy mode, because in legacy mode we don't re-use
10863 // the current tree; see previous branch.)
10864
10865
10866 primaryChildFragment.subtreeFlags = currentPrimaryChildFragment.subtreeFlags & StaticMask;
10867 }
10868
10869 var fallbackChildFragment;
10870
10871 if (currentFallbackChildFragment !== null) {
10872 fallbackChildFragment = createWorkInProgress(currentFallbackChildFragment, fallbackChildren);
10873 } else {
10874 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null); // Needs a placement effect because the parent (the Suspense boundary) already
10875 // mounted but this is a new fiber.
10876
10877 fallbackChildFragment.flags |= Placement;
10878 }
10879
10880 fallbackChildFragment.return = workInProgress;
10881 primaryChildFragment.return = workInProgress;
10882 primaryChildFragment.sibling = fallbackChildFragment;
10883 workInProgress.child = primaryChildFragment;
10884 return fallbackChildFragment;
10885 }
10886
10887 function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) {
10888 fiber.lanes = mergeLanes(fiber.lanes, renderLanes);
10889 var alternate = fiber.alternate;
10890
10891 if (alternate !== null) {
10892 alternate.lanes = mergeLanes(alternate.lanes, renderLanes);
10893 }
10894
10895 scheduleContextWorkOnParentPath(fiber.return, renderLanes, propagationRoot);
10896 }
10897
10898 function propagateSuspenseContextChange(workInProgress, firstChild, renderLanes) {
10899 // Mark any Suspense boundaries with fallbacks as having work to do.
10900 // If they were previously forced into fallbacks, they may now be able
10901 // to unblock.
10902 var node = firstChild;
10903
10904 while (node !== null) {
10905 if (node.tag === SuspenseComponent) {
10906 var state = node.memoizedState;
10907
10908 if (state !== null) {
10909 scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress);
10910 }
10911 } else if (node.tag === SuspenseListComponent) {
10912 // If the tail is hidden there might not be an Suspense boundaries
10913 // to schedule work on. In this case we have to schedule it on the
10914 // list itself.
10915 // We don't have to traverse to the children of the list since
10916 // the list will propagate the change when it rerenders.
10917 scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress);
10918 } else if (node.child !== null) {
10919 node.child.return = node;
10920 node = node.child;
10921 continue;
10922 }
10923
10924 if (node === workInProgress) {
10925 return;
10926 }
10927
10928 while (node.sibling === null) {
10929 if (node.return === null || node.return === workInProgress) {
10930 return;
10931 }
10932
10933 node = node.return;
10934 }
10935
10936 node.sibling.return = node.return;
10937 node = node.sibling;
10938 }
10939 }
10940
10941 function findLastContentRow(firstChild) {
10942 // This is going to find the last row among these children that is already
10943 // showing content on the screen, as opposed to being in fallback state or
10944 // new. If a row has multiple Suspense boundaries, any of them being in the
10945 // fallback state, counts as the whole row being in a fallback state.
10946 // Note that the "rows" will be workInProgress, but any nested children
10947 // will still be current since we haven't rendered them yet. The mounted
10948 // order may not be the same as the new order. We use the new order.
10949 var row = firstChild;
10950 var lastContentRow = null;
10951
10952 while (row !== null) {
10953 var currentRow = row.alternate; // New rows can't be content rows.
10954
10955 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
10956 lastContentRow = row;
10957 }
10958
10959 row = row.sibling;
10960 }
10961
10962 return lastContentRow;
10963 }
10964
10965 function validateRevealOrder(revealOrder) {
10966 {
10967 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
10968 didWarnAboutRevealOrder[revealOrder] = true;
10969
10970 if (typeof revealOrder === 'string') {
10971 switch (revealOrder.toLowerCase()) {
10972 case 'together':
10973 case 'forwards':
10974 case 'backwards':
10975 {
10976 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
10977
10978 break;
10979 }
10980
10981 case 'forward':
10982 case 'backward':
10983 {
10984 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase());
10985
10986 break;
10987 }
10988
10989 default:
10990 error('"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
10991
10992 break;
10993 }
10994 } else {
10995 error('%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
10996 }
10997 }
10998 }
10999 }
11000
11001 function validateTailOptions(tailMode, revealOrder) {
11002 {
11003 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
11004 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
11005 didWarnAboutTailOptions[tailMode] = true;
11006
11007 error('"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
11008 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
11009 didWarnAboutTailOptions[tailMode] = true;
11010
11011 error('<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
11012 }
11013 }
11014 }
11015 }
11016
11017 function validateSuspenseListNestedChild(childSlot, index) {
11018 {
11019 var isAnArray = isArray(childSlot);
11020 var isIterable = !isAnArray && typeof getIteratorFn(childSlot) === 'function';
11021
11022 if (isAnArray || isIterable) {
11023 var type = isAnArray ? 'array' : 'iterable';
11024
11025 error('A nested %s was passed to row #%s in <SuspenseList />. Wrap it in ' + 'an additional SuspenseList to configure its revealOrder: ' + '<SuspenseList revealOrder=...> ... ' + '<SuspenseList revealOrder=...>{%s}</SuspenseList> ... ' + '</SuspenseList>', type, index, type);
11026
11027 return false;
11028 }
11029 }
11030
11031 return true;
11032 }
11033
11034 function validateSuspenseListChildren(children, revealOrder) {
11035 {
11036 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
11037 if (isArray(children)) {
11038 for (var i = 0; i < children.length; i++) {
11039 if (!validateSuspenseListNestedChild(children[i], i)) {
11040 return;
11041 }
11042 }
11043 } else {
11044 var iteratorFn = getIteratorFn(children);
11045
11046 if (typeof iteratorFn === 'function') {
11047 var childrenIterator = iteratorFn.call(children);
11048
11049 if (childrenIterator) {
11050 var step = childrenIterator.next();
11051 var _i = 0;
11052
11053 for (; !step.done; step = childrenIterator.next()) {
11054 if (!validateSuspenseListNestedChild(step.value, _i)) {
11055 return;
11056 }
11057
11058 _i++;
11059 }
11060 }
11061 } else {
11062 error('A single row was passed to a <SuspenseList revealOrder="%s" />. ' + 'This is not useful since it needs multiple rows. ' + 'Did you mean to pass multiple children or an array?', revealOrder);
11063 }
11064 }
11065 }
11066 }
11067 }
11068
11069 function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode) {
11070 var renderState = workInProgress.memoizedState;
11071
11072 if (renderState === null) {
11073 workInProgress.memoizedState = {
11074 isBackwards: isBackwards,
11075 rendering: null,
11076 renderingStartTime: 0,
11077 last: lastContentRow,
11078 tail: tail,
11079 tailMode: tailMode
11080 };
11081 } else {
11082 // We can reuse the existing object from previous renders.
11083 renderState.isBackwards = isBackwards;
11084 renderState.rendering = null;
11085 renderState.renderingStartTime = 0;
11086 renderState.last = lastContentRow;
11087 renderState.tail = tail;
11088 renderState.tailMode = tailMode;
11089 }
11090 } // This can end up rendering this component multiple passes.
11091 // The first pass splits the children fibers into two sets. A head and tail.
11092 // We first render the head. If anything is in fallback state, we do another
11093 // pass through beginWork to rerender all children (including the tail) with
11094 // the force suspend context. If the first render didn't have anything in
11095 // in fallback state. Then we render each row in the tail one-by-one.
11096 // That happens in the completeWork phase without going back to beginWork.
11097
11098
11099 function updateSuspenseListComponent(current, workInProgress, renderLanes) {
11100 var nextProps = workInProgress.pendingProps;
11101 var revealOrder = nextProps.revealOrder;
11102 var tailMode = nextProps.tail;
11103 var newChildren = nextProps.children;
11104 validateRevealOrder(revealOrder);
11105 validateTailOptions(tailMode, revealOrder);
11106 validateSuspenseListChildren(newChildren, revealOrder);
11107 reconcileChildren(current, workInProgress, newChildren, renderLanes);
11108 var suspenseContext = suspenseStackCursor.current;
11109 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
11110
11111 if (shouldForceFallback) {
11112 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
11113 workInProgress.flags |= DidCapture;
11114 } else {
11115 var didSuspendBefore = current !== null && (current.flags & DidCapture) !== NoFlags;
11116
11117 if (didSuspendBefore) {
11118 // If we previously forced a fallback, we need to schedule work
11119 // on any nested boundaries to let them know to try to render
11120 // again. This is the same as context updating.
11121 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderLanes);
11122 }
11123
11124 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
11125 }
11126
11127 pushSuspenseContext(workInProgress, suspenseContext);
11128
11129 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
11130 // In legacy mode, SuspenseList doesn't work so we just
11131 // use make it a noop by treating it as the default revealOrder.
11132 workInProgress.memoizedState = null;
11133 } else {
11134 switch (revealOrder) {
11135 case 'forwards':
11136 {
11137 var lastContentRow = findLastContentRow(workInProgress.child);
11138 var tail;
11139
11140 if (lastContentRow === null) {
11141 // The whole list is part of the tail.
11142 // TODO: We could fast path by just rendering the tail now.
11143 tail = workInProgress.child;
11144 workInProgress.child = null;
11145 } else {
11146 // Disconnect the tail rows after the content row.
11147 // We're going to render them separately later.
11148 tail = lastContentRow.sibling;
11149 lastContentRow.sibling = null;
11150 }
11151
11152 initSuspenseListRenderState(workInProgress, false, // isBackwards
11153 tail, lastContentRow, tailMode);
11154 break;
11155 }
11156
11157 case 'backwards':
11158 {
11159 // We're going to find the first row that has existing content.
11160 // At the same time we're going to reverse the list of everything
11161 // we pass in the meantime. That's going to be our tail in reverse
11162 // order.
11163 var _tail = null;
11164 var row = workInProgress.child;
11165 workInProgress.child = null;
11166
11167 while (row !== null) {
11168 var currentRow = row.alternate; // New rows can't be content rows.
11169
11170 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
11171 // This is the beginning of the main content.
11172 workInProgress.child = row;
11173 break;
11174 }
11175
11176 var nextRow = row.sibling;
11177 row.sibling = _tail;
11178 _tail = row;
11179 row = nextRow;
11180 } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
11181
11182
11183 initSuspenseListRenderState(workInProgress, true, // isBackwards
11184 _tail, null, // last
11185 tailMode);
11186 break;
11187 }
11188
11189 case 'together':
11190 {
11191 initSuspenseListRenderState(workInProgress, false, // isBackwards
11192 null, // tail
11193 null, // last
11194 undefined);
11195 break;
11196 }
11197
11198 default:
11199 {
11200 // The default reveal order is the same as not having
11201 // a boundary.
11202 workInProgress.memoizedState = null;
11203 }
11204 }
11205 }
11206
11207 return workInProgress.child;
11208 }
11209
11210 function updatePortalComponent(current, workInProgress, renderLanes) {
11211 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
11212 var nextChildren = workInProgress.pendingProps;
11213
11214 if (current === null) {
11215 // Portals are special because we don't append the children during mount
11216 // but at commit. Therefore we need to track insertions which the normal
11217 // flow doesn't do during mount. This doesn't happen at the root because
11218 // the root always starts with a "current" with a null child.
11219 // TODO: Consider unifying this with how the root works.
11220 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes);
11221 } else {
11222 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
11223 }
11224
11225 return workInProgress.child;
11226 }
11227
11228 var hasWarnedAboutUsingNoValuePropOnContextProvider = false;
11229
11230 function updateContextProvider(current, workInProgress, renderLanes) {
11231 var providerType = workInProgress.type;
11232 var context = providerType._context;
11233 var newProps = workInProgress.pendingProps;
11234 var oldProps = workInProgress.memoizedProps;
11235 var newValue = newProps.value;
11236
11237 {
11238 if (!('value' in newProps)) {
11239 if (!hasWarnedAboutUsingNoValuePropOnContextProvider) {
11240 hasWarnedAboutUsingNoValuePropOnContextProvider = true;
11241
11242 error('The `value` prop is required for the `<Context.Provider>`. Did you misspell it or forget to pass it?');
11243 }
11244 }
11245
11246 var providerPropTypes = workInProgress.type.propTypes;
11247
11248 if (providerPropTypes) {
11249 checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider');
11250 }
11251 }
11252
11253 pushProvider(workInProgress, context, newValue);
11254
11255 {
11256 if (oldProps !== null) {
11257 var oldValue = oldProps.value;
11258
11259 if (objectIs(oldValue, newValue)) {
11260 // No change. Bailout early if children are the same.
11261 if (oldProps.children === newProps.children && !hasContextChanged()) {
11262 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
11263 }
11264 } else {
11265 // The context value changed. Search for matching consumers and schedule
11266 // them to update.
11267 propagateContextChange(workInProgress, context, renderLanes);
11268 }
11269 }
11270 }
11271
11272 var newChildren = newProps.children;
11273 reconcileChildren(current, workInProgress, newChildren, renderLanes);
11274 return workInProgress.child;
11275 }
11276
11277 var hasWarnedAboutUsingContextAsConsumer = false;
11278
11279 function updateContextConsumer(current, workInProgress, renderLanes) {
11280 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In
11281 // DEV mode, we create a separate object for Context.Consumer that acts
11282 // like a proxy to Context. This proxy object adds unnecessary code in PROD
11283 // so we use the old behaviour (Context.Consumer references Context) to
11284 // reduce size and overhead. The separate object references context via
11285 // a property called "_context", which also gives us the ability to check
11286 // in DEV mode if this property exists or not and warn if it does not.
11287
11288 {
11289 if (context._context === undefined) {
11290 // This may be because it's a Context (rather than a Consumer).
11291 // Or it may be because it's older React where they're the same thing.
11292 // We only want to warn if we're sure it's a new React.
11293 if (context !== context.Consumer) {
11294 if (!hasWarnedAboutUsingContextAsConsumer) {
11295 hasWarnedAboutUsingContextAsConsumer = true;
11296
11297 error('Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
11298 }
11299 }
11300 } else {
11301 context = context._context;
11302 }
11303 }
11304
11305 var newProps = workInProgress.pendingProps;
11306 var render = newProps.children;
11307
11308 {
11309 if (typeof render !== 'function') {
11310 error('A context consumer was rendered with multiple children, or a child ' + "that isn't a function. A context consumer expects a single child " + 'that is a function. If you did pass a function, make sure there ' + 'is no trailing or leading whitespace around it.');
11311 }
11312 }
11313
11314 prepareToReadContext(workInProgress, renderLanes);
11315 var newValue = readContext(context);
11316
11317 var newChildren;
11318
11319 {
11320 ReactCurrentOwner$1.current = workInProgress;
11321 setIsRendering(true);
11322 newChildren = render(newValue);
11323 setIsRendering(false);
11324 }
11325
11326
11327 workInProgress.flags |= PerformedWork;
11328 reconcileChildren(current, workInProgress, newChildren, renderLanes);
11329 return workInProgress.child;
11330 }
11331
11332 function markWorkInProgressReceivedUpdate() {
11333 didReceiveUpdate = true;
11334 }
11335
11336 function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) {
11337 if (current !== null) {
11338 // Reuse previous dependencies
11339 workInProgress.dependencies = current.dependencies;
11340 }
11341
11342 {
11343 // Don't update "base" render times for bailouts.
11344 stopProfilerTimerIfRunning();
11345 }
11346
11347 markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work.
11348
11349 if (!includesSomeLane(renderLanes, workInProgress.childLanes)) {
11350 // The children don't have any work either. We can skip them.
11351 // TODO: Once we add back resuming, we should check if the children are
11352 // a work-in-progress set. If so, we need to transfer their effects.
11353 {
11354 return null;
11355 }
11356 } // This fiber doesn't have work, but its subtree does. Clone the child
11357 // fibers and continue.
11358
11359
11360 cloneChildFibers(current, workInProgress);
11361 return workInProgress.child;
11362 }
11363
11364 function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
11365 {
11366 var returnFiber = oldWorkInProgress.return;
11367
11368 if (returnFiber === null) {
11369 // eslint-disable-next-line react-internal/prod-error-codes
11370 throw new Error('Cannot swap the root fiber.');
11371 } // Disconnect from the old current.
11372 // It will get deleted.
11373
11374
11375 current.alternate = null;
11376 oldWorkInProgress.alternate = null; // Connect to the new tree.
11377
11378 newWorkInProgress.index = oldWorkInProgress.index;
11379 newWorkInProgress.sibling = oldWorkInProgress.sibling;
11380 newWorkInProgress.return = oldWorkInProgress.return;
11381 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.
11382
11383 if (oldWorkInProgress === returnFiber.child) {
11384 returnFiber.child = newWorkInProgress;
11385 } else {
11386 var prevSibling = returnFiber.child;
11387
11388 if (prevSibling === null) {
11389 // eslint-disable-next-line react-internal/prod-error-codes
11390 throw new Error('Expected parent to have a child.');
11391 }
11392
11393 while (prevSibling.sibling !== oldWorkInProgress) {
11394 prevSibling = prevSibling.sibling;
11395
11396 if (prevSibling === null) {
11397 // eslint-disable-next-line react-internal/prod-error-codes
11398 throw new Error('Expected to find the previous sibling.');
11399 }
11400 }
11401
11402 prevSibling.sibling = newWorkInProgress;
11403 } // Delete the old fiber and place the new one.
11404 // Since the old fiber is disconnected, we have to schedule it manually.
11405
11406
11407 var deletions = returnFiber.deletions;
11408
11409 if (deletions === null) {
11410 returnFiber.deletions = [current];
11411 returnFiber.flags |= ChildDeletion;
11412 } else {
11413 deletions.push(current);
11414 }
11415
11416 newWorkInProgress.flags |= Placement; // Restart work from the new fiber.
11417
11418 return newWorkInProgress;
11419 }
11420 }
11421
11422 function checkScheduledUpdateOrContext(current, renderLanes) {
11423 // Before performing an early bailout, we must check if there are pending
11424 // updates or context.
11425 var updateLanes = current.lanes;
11426
11427 if (includesSomeLane(updateLanes, renderLanes)) {
11428 return true;
11429 } // No pending update, but because context is propagated lazily, we need
11430
11431 return false;
11432 }
11433
11434 function attemptEarlyBailoutIfNoScheduledUpdate(current, workInProgress, renderLanes) {
11435 // This fiber does not have any pending work. Bailout without entering
11436 // the begin phase. There's still some bookkeeping we that needs to be done
11437 // in this optimized path, mostly pushing stuff onto the stack.
11438 switch (workInProgress.tag) {
11439 case HostRoot:
11440 pushHostRootContext(workInProgress);
11441 var root = workInProgress.stateNode;
11442 break;
11443
11444 case HostComponent:
11445 pushHostContext(workInProgress);
11446 break;
11447
11448 case ClassComponent:
11449 {
11450 var Component = workInProgress.type;
11451
11452 if (isContextProvider(Component)) {
11453 pushContextProvider(workInProgress);
11454 }
11455
11456 break;
11457 }
11458
11459 case HostPortal:
11460 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
11461 break;
11462
11463 case ContextProvider:
11464 {
11465 var newValue = workInProgress.memoizedProps.value;
11466 var context = workInProgress.type._context;
11467 pushProvider(workInProgress, context, newValue);
11468 break;
11469 }
11470
11471 case Profiler:
11472 {
11473 // Profiler should only call onRender when one of its descendants actually rendered.
11474 var hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes);
11475
11476 if (hasChildWork) {
11477 workInProgress.flags |= Update;
11478 }
11479
11480 {
11481 // Reset effect durations for the next eventual effect phase.
11482 // These are reset during render to allow the DevTools commit hook a chance to read them,
11483 var stateNode = workInProgress.stateNode;
11484 stateNode.effectDuration = 0;
11485 stateNode.passiveEffectDuration = 0;
11486 }
11487 }
11488
11489 break;
11490
11491 case SuspenseComponent:
11492 {
11493 var state = workInProgress.memoizedState;
11494
11495 if (state !== null) {
11496 // whether to retry the primary children, or to skip over it and
11497 // go straight to the fallback. Check the priority of the primary
11498 // child fragment.
11499
11500
11501 var primaryChildFragment = workInProgress.child;
11502 var primaryChildLanes = primaryChildFragment.childLanes;
11503
11504 if (includesSomeLane(renderLanes, primaryChildLanes)) {
11505 // The primary children have pending work. Use the normal path
11506 // to attempt to render the primary children again.
11507 return updateSuspenseComponent(current, workInProgress, renderLanes);
11508 } else {
11509 // The primary child fragment does not have pending work marked
11510 // on it
11511 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient
11512 // priority. Bailout.
11513
11514 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
11515
11516 if (child !== null) {
11517 // The fallback children have pending work. Skip over the
11518 // primary children and work on the fallback.
11519 return child.sibling;
11520 } else {
11521 // Note: We can return `null` here because we already checked
11522 // whether there were nested context consumers, via the call to
11523 // `bailoutOnAlreadyFinishedWork` above.
11524 return null;
11525 }
11526 }
11527 } else {
11528 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
11529 }
11530
11531 break;
11532 }
11533
11534 case SuspenseListComponent:
11535 {
11536 var didSuspendBefore = (current.flags & DidCapture) !== NoFlags;
11537
11538 var _hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes);
11539
11540 if (didSuspendBefore) {
11541 if (_hasChildWork) {
11542 // If something was in fallback state last time, and we have all the
11543 // same children then we're still in progressive loading state.
11544 // Something might get unblocked by state updates or retries in the
11545 // tree which will affect the tail. So we need to use the normal
11546 // path to compute the correct tail.
11547 return updateSuspenseListComponent(current, workInProgress, renderLanes);
11548 } // If none of the children had any work, that means that none of
11549 // them got retried so they'll still be blocked in the same way
11550 // as before. We can fast bail out.
11551
11552
11553 workInProgress.flags |= DidCapture;
11554 } // If nothing suspended before and we're rendering the same children,
11555 // then the tail doesn't matter. Anything new that suspends will work
11556 // in the "together" mode, so we can continue from the state we had.
11557
11558
11559 var renderState = workInProgress.memoizedState;
11560
11561 if (renderState !== null) {
11562 // Reset to the "together" mode in case we've started a different
11563 // update in the past but didn't complete it.
11564 renderState.rendering = null;
11565 renderState.tail = null;
11566 renderState.lastEffect = null;
11567 }
11568
11569 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
11570
11571 if (_hasChildWork) {
11572 break;
11573 } else {
11574 // If none of the children had any work, that means that none of
11575 // them got retried so they'll still be blocked in the same way
11576 // as before. We can fast bail out.
11577 return null;
11578 }
11579 }
11580
11581 case OffscreenComponent:
11582 case LegacyHiddenComponent:
11583 {
11584 // Need to check if the tree still needs to be deferred. This is
11585 // almost identical to the logic used in the normal update path,
11586 // so we'll just enter that. The only difference is we'll bail out
11587 // at the next level instead of this one, because the child props
11588 // have not changed. Which is fine.
11589 // TODO: Probably should refactor `beginWork` to split the bailout
11590 // path from the normal path. I'm tempted to do a labeled break here
11591 // but I won't :)
11592 workInProgress.lanes = NoLanes;
11593 return updateOffscreenComponent(current, workInProgress, renderLanes);
11594 }
11595 }
11596
11597 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
11598 }
11599
11600 function beginWork(current, workInProgress, renderLanes) {
11601 {
11602 if (workInProgress._debugNeedsRemount && current !== null) {
11603 // This will restart the begin phase with a new fiber.
11604 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.lanes));
11605 }
11606 }
11607
11608 if (current !== null) {
11609 var oldProps = current.memoizedProps;
11610 var newProps = workInProgress.pendingProps;
11611
11612 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
11613 workInProgress.type !== current.type )) {
11614 // If props or context changed, mark the fiber as having performed work.
11615 // This may be unset if the props are determined to be equal later (memo).
11616 didReceiveUpdate = true;
11617 } else {
11618 // Neither props nor legacy context changes. Check if there's a pending
11619 // update or context change.
11620 var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current, renderLanes);
11621
11622 if (!hasScheduledUpdateOrContext && // If this is the second pass of an error or suspense boundary, there
11623 // may not be work scheduled on `current`, so we check for this flag.
11624 (workInProgress.flags & DidCapture) === NoFlags) {
11625 // No pending updates or context. Bail out now.
11626 didReceiveUpdate = false;
11627 return attemptEarlyBailoutIfNoScheduledUpdate(current, workInProgress, renderLanes);
11628 }
11629
11630 if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) {
11631 // This is a special case that only exists for legacy mode.
11632 // See https://github.com/facebook/react/pull/19216.
11633 didReceiveUpdate = true;
11634 } else {
11635 // An update was scheduled on this fiber, but there are no new props
11636 // nor legacy context. Set this to false. If an update queue or context
11637 // consumer produces a changed value, it will set this to true. Otherwise,
11638 // the component will assume the children have not changed and bail out.
11639 didReceiveUpdate = false;
11640 }
11641 }
11642 } else {
11643 didReceiveUpdate = false;
11644 } // Before entering the begin phase, clear pending update priority.
11645 // TODO: This assumes that we're about to evaluate the component and process
11646 // the update queue. However, there's an exception: SimpleMemoComponent
11647 // sometimes bails out later in the begin phase. This indicates that we should
11648 // move this assignment out of the common path and into each branch.
11649
11650
11651 workInProgress.lanes = NoLanes;
11652
11653 switch (workInProgress.tag) {
11654 case IndeterminateComponent:
11655 {
11656 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderLanes);
11657 }
11658
11659 case LazyComponent:
11660 {
11661 var elementType = workInProgress.elementType;
11662 return mountLazyComponent(current, workInProgress, elementType, renderLanes);
11663 }
11664
11665 case FunctionComponent:
11666 {
11667 var Component = workInProgress.type;
11668 var unresolvedProps = workInProgress.pendingProps;
11669 var resolvedProps = workInProgress.elementType === Component ? unresolvedProps : resolveDefaultProps(Component, unresolvedProps);
11670 return updateFunctionComponent(current, workInProgress, Component, resolvedProps, renderLanes);
11671 }
11672
11673 case ClassComponent:
11674 {
11675 var _Component = workInProgress.type;
11676 var _unresolvedProps = workInProgress.pendingProps;
11677
11678 var _resolvedProps = workInProgress.elementType === _Component ? _unresolvedProps : resolveDefaultProps(_Component, _unresolvedProps);
11679
11680 return updateClassComponent(current, workInProgress, _Component, _resolvedProps, renderLanes);
11681 }
11682
11683 case HostRoot:
11684 return updateHostRoot(current, workInProgress, renderLanes);
11685
11686 case HostComponent:
11687 return updateHostComponent$1(current, workInProgress, renderLanes);
11688
11689 case HostText:
11690 return updateHostText$1();
11691
11692 case SuspenseComponent:
11693 return updateSuspenseComponent(current, workInProgress, renderLanes);
11694
11695 case HostPortal:
11696 return updatePortalComponent(current, workInProgress, renderLanes);
11697
11698 case ForwardRef:
11699 {
11700 var type = workInProgress.type;
11701 var _unresolvedProps2 = workInProgress.pendingProps;
11702
11703 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
11704
11705 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderLanes);
11706 }
11707
11708 case Fragment:
11709 return updateFragment(current, workInProgress, renderLanes);
11710
11711 case Mode:
11712 return updateMode(current, workInProgress, renderLanes);
11713
11714 case Profiler:
11715 return updateProfiler(current, workInProgress, renderLanes);
11716
11717 case ContextProvider:
11718 return updateContextProvider(current, workInProgress, renderLanes);
11719
11720 case ContextConsumer:
11721 return updateContextConsumer(current, workInProgress, renderLanes);
11722
11723 case MemoComponent:
11724 {
11725 var _type2 = workInProgress.type;
11726 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
11727
11728 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
11729
11730 {
11731 if (workInProgress.type !== workInProgress.elementType) {
11732 var outerPropTypes = _type2.propTypes;
11733
11734 if (outerPropTypes) {
11735 checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only
11736 'prop', getComponentNameFromType(_type2));
11737 }
11738 }
11739 }
11740
11741 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
11742 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, renderLanes);
11743 }
11744
11745 case SimpleMemoComponent:
11746 {
11747 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, renderLanes);
11748 }
11749
11750 case IncompleteClassComponent:
11751 {
11752 var _Component2 = workInProgress.type;
11753 var _unresolvedProps4 = workInProgress.pendingProps;
11754
11755 var _resolvedProps4 = workInProgress.elementType === _Component2 ? _unresolvedProps4 : resolveDefaultProps(_Component2, _unresolvedProps4);
11756
11757 return mountIncompleteClassComponent(current, workInProgress, _Component2, _resolvedProps4, renderLanes);
11758 }
11759
11760 case SuspenseListComponent:
11761 {
11762 return updateSuspenseListComponent(current, workInProgress, renderLanes);
11763 }
11764
11765 case ScopeComponent:
11766 {
11767
11768 break;
11769 }
11770
11771 case OffscreenComponent:
11772 {
11773 return updateOffscreenComponent(current, workInProgress, renderLanes);
11774 }
11775 }
11776
11777 throw new Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in " + 'React. Please file an issue.');
11778 }
11779
11780 function unwindWork(current, workInProgress, renderLanes) {
11781 // Note: This intentionally doesn't check if we're hydrating because comparing
11782 // to the current tree provider fiber is just as fast and less error-prone.
11783 // Ideally we would have a special version of the work loop only
11784 // for hydration.
11785 popTreeContext(workInProgress);
11786
11787 switch (workInProgress.tag) {
11788 case ClassComponent:
11789 {
11790 var Component = workInProgress.type;
11791
11792 if (isContextProvider(Component)) {
11793 popContext(workInProgress);
11794 }
11795
11796 var flags = workInProgress.flags;
11797
11798 if (flags & ShouldCapture) {
11799 workInProgress.flags = flags & ~ShouldCapture | DidCapture;
11800
11801 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
11802 transferActualDuration(workInProgress);
11803 }
11804
11805 return workInProgress;
11806 }
11807
11808 return null;
11809 }
11810
11811 case HostRoot:
11812 {
11813
11814 popHostContainer(workInProgress);
11815 popTopLevelContextObject(workInProgress);
11816 resetWorkInProgressVersions();
11817 var _flags = workInProgress.flags;
11818
11819 if ((_flags & ShouldCapture) !== NoFlags && (_flags & DidCapture) === NoFlags) {
11820 // There was an error during render that wasn't captured by a suspense
11821 // boundary. Do a second pass on the root to unmount the children.
11822 workInProgress.flags = _flags & ~ShouldCapture | DidCapture;
11823 return workInProgress;
11824 } // We unwound to the root without completing it. Exit.
11825
11826
11827 return null;
11828 }
11829
11830 case HostComponent:
11831 {
11832 // TODO: popHydrationState
11833 popHostContext(workInProgress);
11834 return null;
11835 }
11836
11837 case SuspenseComponent:
11838 {
11839 popSuspenseContext(workInProgress);
11840
11841 var _flags2 = workInProgress.flags;
11842
11843 if (_flags2 & ShouldCapture) {
11844 workInProgress.flags = _flags2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
11845
11846 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
11847 transferActualDuration(workInProgress);
11848 }
11849
11850 return workInProgress;
11851 }
11852
11853 return null;
11854 }
11855
11856 case SuspenseListComponent:
11857 {
11858 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
11859 // caught by a nested boundary. If not, it should bubble through.
11860
11861 return null;
11862 }
11863
11864 case HostPortal:
11865 popHostContainer(workInProgress);
11866 return null;
11867
11868 case ContextProvider:
11869 var context = workInProgress.type._context;
11870 popProvider(context, workInProgress);
11871 return null;
11872
11873 case OffscreenComponent:
11874 case LegacyHiddenComponent:
11875 popRenderLanes(workInProgress);
11876
11877 return null;
11878
11879 case CacheComponent:
11880
11881 return null;
11882
11883 default:
11884 return null;
11885 }
11886 }
11887
11888 function unwindInterruptedWork(current, interruptedWork, renderLanes) {
11889 // Note: This intentionally doesn't check if we're hydrating because comparing
11890 // to the current tree provider fiber is just as fast and less error-prone.
11891 // Ideally we would have a special version of the work loop only
11892 // for hydration.
11893 popTreeContext(interruptedWork);
11894
11895 switch (interruptedWork.tag) {
11896 case ClassComponent:
11897 {
11898 var childContextTypes = interruptedWork.type.childContextTypes;
11899
11900 if (childContextTypes !== null && childContextTypes !== undefined) {
11901 popContext(interruptedWork);
11902 }
11903
11904 break;
11905 }
11906
11907 case HostRoot:
11908 {
11909
11910 popHostContainer(interruptedWork);
11911 popTopLevelContextObject(interruptedWork);
11912 resetWorkInProgressVersions();
11913 break;
11914 }
11915
11916 case HostComponent:
11917 {
11918 popHostContext(interruptedWork);
11919 break;
11920 }
11921
11922 case HostPortal:
11923 popHostContainer(interruptedWork);
11924 break;
11925
11926 case SuspenseComponent:
11927 popSuspenseContext(interruptedWork);
11928 break;
11929
11930 case SuspenseListComponent:
11931 popSuspenseContext(interruptedWork);
11932 break;
11933
11934 case ContextProvider:
11935 var context = interruptedWork.type._context;
11936 popProvider(context, interruptedWork);
11937 break;
11938
11939 case OffscreenComponent:
11940 case LegacyHiddenComponent:
11941 popRenderLanes(interruptedWork);
11942
11943 break;
11944 }
11945 }
11946
11947 function invokeGuardedCallbackProd(name, func, context, a, b, c, d, e, f) {
11948 var funcArgs = Array.prototype.slice.call(arguments, 3);
11949
11950 try {
11951 func.apply(context, funcArgs);
11952 } catch (error) {
11953 this.onError(error);
11954 }
11955 }
11956
11957 var invokeGuardedCallbackImpl = invokeGuardedCallbackProd;
11958
11959 {
11960 // In DEV mode, we swap out invokeGuardedCallback for a special version
11961 // that plays more nicely with the browser's DevTools. The idea is to preserve
11962 // "Pause on exceptions" behavior. Because React wraps all user-provided
11963 // functions in invokeGuardedCallback, and the production version of
11964 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
11965 // like caught exceptions, and the DevTools won't pause unless the developer
11966 // takes the extra step of enabling pause on caught exceptions. This is
11967 // unintuitive, though, because even though React has caught the error, from
11968 // the developer's perspective, the error is uncaught.
11969 //
11970 // To preserve the expected "Pause on exceptions" behavior, we don't use a
11971 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
11972 // DOM node, and call the user-provided callback from inside an event handler
11973 // for that fake event. If the callback throws, the error is "captured" using
11974 // a global event handler. But because the error happens in a different
11975 // event loop context, it does not interrupt the normal program flow.
11976 // Effectively, this gives us try-catch behavior without actually using
11977 // try-catch. Neat!
11978 // Check that the browser supports the APIs we need to implement our special
11979 // DEV version of invokeGuardedCallback
11980 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
11981 var fakeNode = document.createElement('react');
11982
11983 invokeGuardedCallbackImpl = function invokeGuardedCallbackDev(name, func, context, a, b, c, d, e, f) {
11984 // If document doesn't exist we know for sure we will crash in this method
11985 // when we call document.createEvent(). However this can cause confusing
11986 // errors: https://github.com/facebook/create-react-app/issues/3482
11987 // So we preemptively throw with a better message instead.
11988 if (typeof document === 'undefined' || document === null) {
11989 throw new Error('The `document` global was defined when React was initialized, but is not ' + 'defined anymore. This can happen in a test environment if a component ' + 'schedules an update from an asynchronous callback, but the test has already ' + 'finished running. To solve this, you can either unmount the component at ' + 'the end of your test (and ensure that any asynchronous operations get ' + 'canceled in `componentWillUnmount`), or you can change the test itself ' + 'to be asynchronous.');
11990 }
11991
11992 var evt = document.createEvent('Event');
11993 var didCall = false; // Keeps track of whether the user-provided callback threw an error. We
11994 // set this to true at the beginning, then set it to false right after
11995 // calling the function. If the function errors, `didError` will never be
11996 // set to false. This strategy works even if the browser is flaky and
11997 // fails to call our global error handler, because it doesn't rely on
11998 // the error event at all.
11999
12000 var didError = true; // Keeps track of the value of window.event so that we can reset it
12001 // during the callback to let user code access window.event in the
12002 // browsers that support it.
12003
12004 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event
12005 // dispatching: https://github.com/facebook/react/issues/13688
12006
12007 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
12008
12009 function restoreAfterDispatch() {
12010 // We immediately remove the callback from event listeners so that
12011 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
12012 // nested call would trigger the fake event handlers of any call higher
12013 // in the stack.
12014 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the
12015 // window.event assignment in both IE <= 10 as they throw an error
12016 // "Member not found" in strict mode, and in Firefox which does not
12017 // support window.event.
12018
12019 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
12020 window.event = windowEvent;
12021 }
12022 } // Create an event handler for our fake event. We will synchronously
12023 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
12024 // call the user-provided callback.
12025
12026
12027 var funcArgs = Array.prototype.slice.call(arguments, 3);
12028
12029 function callCallback() {
12030 didCall = true;
12031 restoreAfterDispatch();
12032 func.apply(context, funcArgs);
12033 didError = false;
12034 } // Create a global error event handler. We use this to capture the value
12035 // that was thrown. It's possible that this error handler will fire more
12036 // than once; for example, if non-React code also calls `dispatchEvent`
12037 // and a handler for that event throws. We should be resilient to most of
12038 // those cases. Even if our error event handler fires more than once, the
12039 // last error event is always used. If the callback actually does error,
12040 // we know that the last error event is the correct one, because it's not
12041 // possible for anything else to have happened in between our callback
12042 // erroring and the code that follows the `dispatchEvent` call below. If
12043 // the callback doesn't error, but the error event was fired, we know to
12044 // ignore it because `didError` will be false, as described above.
12045
12046
12047 var error; // Use this to track whether the error event is ever called.
12048
12049 var didSetError = false;
12050 var isCrossOriginError = false;
12051
12052 function handleWindowError(event) {
12053 error = event.error;
12054 didSetError = true;
12055
12056 if (error === null && event.colno === 0 && event.lineno === 0) {
12057 isCrossOriginError = true;
12058 }
12059
12060 if (event.defaultPrevented) {
12061 // Some other error handler has prevented default.
12062 // Browsers silence the error report if this happens.
12063 // We'll remember this to later decide whether to log it or not.
12064 if (error != null && typeof error === 'object') {
12065 try {
12066 error._suppressLogging = true;
12067 } catch (inner) {// Ignore.
12068 }
12069 }
12070 }
12071 } // Create a fake event type.
12072
12073
12074 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers
12075
12076 window.addEventListener('error', handleWindowError);
12077 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function
12078 // errors, it will trigger our global error handler.
12079
12080 evt.initEvent(evtType, false, false);
12081 fakeNode.dispatchEvent(evt);
12082
12083 if (windowEventDescriptor) {
12084 Object.defineProperty(window, 'event', windowEventDescriptor);
12085 }
12086
12087 if (didCall && didError) {
12088 if (!didSetError) {
12089 // The callback errored, but the error event never fired.
12090 // eslint-disable-next-line react-internal/prod-error-codes
12091 error = new Error('An error was thrown inside one of your components, but React ' + "doesn't know what it was. This is likely due to browser " + 'flakiness. React does its best to preserve the "Pause on ' + 'exceptions" behavior of the DevTools, which requires some ' + "DEV-mode only tricks. It's possible that these don't work in " + 'your browser. Try triggering the error in production mode, ' + 'or switching to a modern browser. If you suspect that this is ' + 'actually an issue with React, please file an issue.');
12092 } else if (isCrossOriginError) {
12093 // eslint-disable-next-line react-internal/prod-error-codes
12094 error = new Error("A cross-origin error was thrown. React doesn't have access to " + 'the actual error object in development. ' + 'See https://reactjs.org/link/crossorigin-error for more information.');
12095 }
12096
12097 this.onError(error);
12098 } // Remove our event listeners
12099
12100
12101 window.removeEventListener('error', handleWindowError);
12102
12103 if (!didCall) {
12104 // Something went really wrong, and our event was not dispatched.
12105 // https://github.com/facebook/react/issues/16734
12106 // https://github.com/facebook/react/issues/16585
12107 // Fall back to the production implementation.
12108 restoreAfterDispatch();
12109 return invokeGuardedCallbackProd.apply(this, arguments);
12110 }
12111 };
12112 }
12113 }
12114
12115 var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
12116
12117 var hasError = false;
12118 var caughtError = null; // Used by event system to capture/rethrow the first error.
12119 var reporter = {
12120 onError: function (error) {
12121 hasError = true;
12122 caughtError = error;
12123 }
12124 };
12125 /**
12126 * Call a function while guarding against errors that happens within it.
12127 * Returns an error if it throws, otherwise null.
12128 *
12129 * In production, this is implemented using a try-catch. The reason we don't
12130 * use a try-catch directly is so that we can swap out a different
12131 * implementation in DEV mode.
12132 *
12133 * @param {String} name of the guard to use for logging or debugging
12134 * @param {Function} func The function to invoke
12135 * @param {*} context The context to use when calling the function
12136 * @param {...*} args Arguments for function
12137 */
12138
12139 function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
12140 hasError = false;
12141 caughtError = null;
12142 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
12143 }
12144 function clearCaughtError() {
12145 if (hasError) {
12146 var error = caughtError;
12147 hasError = false;
12148 caughtError = null;
12149 return error;
12150 } else {
12151 throw new Error('clearCaughtError was called but no error was captured. This error ' + 'is likely caused by a bug in React. Please file an issue.');
12152 }
12153 }
12154
12155 var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
12156
12157 {
12158 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
12159 } // Used during the commit phase to track the state of the Offscreen component stack.
12160 var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
12161 var nextEffect = null; // Used for Profiling builds to track updaters.
12162
12163 function reportUncaughtErrorInDEV(error) {
12164 // Wrapping each small part of the commit phase into a guarded
12165 // callback is a bit too slow (https://github.com/facebook/react/pull/21666).
12166 // But we rely on it to surface errors to DEV tools like overlays
12167 // (https://github.com/facebook/react/issues/21712).
12168 // As a compromise, rethrow only caught errors in a guard.
12169 {
12170 invokeGuardedCallback(null, function () {
12171 throw error;
12172 });
12173 clearCaughtError();
12174 }
12175 }
12176
12177 var callComponentWillUnmountWithTimer = function (current, instance) {
12178 instance.props = current.memoizedProps;
12179 instance.state = current.memoizedState;
12180
12181 if ( current.mode & ProfileMode) {
12182 try {
12183 startLayoutEffectTimer();
12184 instance.componentWillUnmount();
12185 } finally {
12186 recordLayoutEffectDuration(current);
12187 }
12188 } else {
12189 instance.componentWillUnmount();
12190 }
12191 }; // Capture errors so they don't interrupt mounting.
12192
12193
12194 function safelyCallComponentWillUnmount(current, nearestMountedAncestor, instance) {
12195 try {
12196 callComponentWillUnmountWithTimer(current, instance);
12197 } catch (error) {
12198 reportUncaughtErrorInDEV(error);
12199 captureCommitPhaseError(current, nearestMountedAncestor, error);
12200 }
12201 } // Capture errors so they don't interrupt mounting.
12202
12203 function safelyDetachRef(current, nearestMountedAncestor) {
12204 var ref = current.ref;
12205
12206 if (ref !== null) {
12207 if (typeof ref === 'function') {
12208 var retVal;
12209
12210 try {
12211 if (enableProfilerTimer && enableProfilerCommitHooks && current.mode & ProfileMode) {
12212 try {
12213 startLayoutEffectTimer();
12214 retVal = ref(null);
12215 } finally {
12216 recordLayoutEffectDuration(current);
12217 }
12218 } else {
12219 retVal = ref(null);
12220 }
12221 } catch (error) {
12222 reportUncaughtErrorInDEV(error);
12223 captureCommitPhaseError(current, nearestMountedAncestor, error);
12224 }
12225
12226 {
12227 if (typeof retVal === 'function') {
12228 error('Unexpected return value from a callback ref in %s. ' + 'A callback ref should not return a function.', getComponentNameFromFiber(current));
12229 }
12230 }
12231 } else {
12232 ref.current = null;
12233 }
12234 }
12235 }
12236
12237 function safelyCallDestroy(current, nearestMountedAncestor, destroy) {
12238 try {
12239 destroy();
12240 } catch (error) {
12241 reportUncaughtErrorInDEV(error);
12242 captureCommitPhaseError(current, nearestMountedAncestor, error);
12243 }
12244 }
12245
12246 var focusedInstanceHandle = null;
12247 var shouldFireAfterActiveInstanceBlur = false;
12248 function commitBeforeMutationEffects(root, firstChild) {
12249 focusedInstanceHandle = prepareForCommit(root.containerInfo);
12250 nextEffect = firstChild;
12251 commitBeforeMutationEffects_begin(); // We no longer need to track the active instance fiber
12252
12253 var shouldFire = shouldFireAfterActiveInstanceBlur;
12254 shouldFireAfterActiveInstanceBlur = false;
12255 focusedInstanceHandle = null;
12256 return shouldFire;
12257 }
12258
12259 function commitBeforeMutationEffects_begin() {
12260 while (nextEffect !== null) {
12261 var fiber = nextEffect; // This phase is only used for beforeActiveInstanceBlur.
12262
12263 var child = fiber.child;
12264
12265 if ((fiber.subtreeFlags & BeforeMutationMask) !== NoFlags && child !== null) {
12266 ensureCorrectReturnPointer(child, fiber);
12267 nextEffect = child;
12268 } else {
12269 commitBeforeMutationEffects_complete();
12270 }
12271 }
12272 }
12273
12274 function commitBeforeMutationEffects_complete() {
12275 while (nextEffect !== null) {
12276 var fiber = nextEffect;
12277 setCurrentFiber(fiber);
12278
12279 try {
12280 commitBeforeMutationEffectsOnFiber(fiber);
12281 } catch (error) {
12282 reportUncaughtErrorInDEV(error);
12283 captureCommitPhaseError(fiber, fiber.return, error);
12284 }
12285
12286 resetCurrentFiber();
12287 var sibling = fiber.sibling;
12288
12289 if (sibling !== null) {
12290 ensureCorrectReturnPointer(sibling, fiber.return);
12291 nextEffect = sibling;
12292 return;
12293 }
12294
12295 nextEffect = fiber.return;
12296 }
12297 }
12298
12299 function commitBeforeMutationEffectsOnFiber(finishedWork) {
12300 var current = finishedWork.alternate;
12301 var flags = finishedWork.flags;
12302
12303 if ((flags & Snapshot) !== NoFlags) {
12304 setCurrentFiber(finishedWork);
12305
12306 switch (finishedWork.tag) {
12307 case FunctionComponent:
12308 case ForwardRef:
12309 case SimpleMemoComponent:
12310 {
12311 break;
12312 }
12313
12314 case ClassComponent:
12315 {
12316 if (current !== null) {
12317 var prevProps = current.memoizedProps;
12318 var prevState = current.memoizedState;
12319 var instance = finishedWork.stateNode; // We could update instance props and state here,
12320 // but instead we rely on them being set during last render.
12321 // TODO: revisit this when we implement resuming.
12322
12323 {
12324 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
12325 if (instance.props !== finishedWork.memoizedProps) {
12326 error('Expected %s props to match memoized props before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
12327 }
12328
12329 if (instance.state !== finishedWork.memoizedState) {
12330 error('Expected %s state to match memoized state before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
12331 }
12332 }
12333 }
12334
12335 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
12336
12337 {
12338 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
12339
12340 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
12341 didWarnSet.add(finishedWork.type);
12342
12343 error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentNameFromFiber(finishedWork));
12344 }
12345 }
12346
12347 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
12348 }
12349
12350 break;
12351 }
12352
12353 case HostRoot:
12354 {
12355 {
12356 var root = finishedWork.stateNode;
12357 clearContainer(root.containerInfo);
12358 }
12359
12360 break;
12361 }
12362
12363 case HostComponent:
12364 case HostText:
12365 case HostPortal:
12366 case IncompleteClassComponent:
12367 // Nothing to do for these component types
12368 break;
12369
12370 default:
12371 {
12372 throw new Error('This unit of work tag should not have side-effects. This error is ' + 'likely caused by a bug in React. Please file an issue.');
12373 }
12374 }
12375
12376 resetCurrentFiber();
12377 }
12378 }
12379
12380 function commitHookEffectListUnmount(flags, finishedWork, nearestMountedAncestor) {
12381 var updateQueue = finishedWork.updateQueue;
12382 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
12383
12384 if (lastEffect !== null) {
12385 var firstEffect = lastEffect.next;
12386 var effect = firstEffect;
12387
12388 do {
12389 if ((effect.tag & flags) === flags) {
12390 // Unmount
12391 var destroy = effect.destroy;
12392 effect.destroy = undefined;
12393
12394 if (destroy !== undefined) {
12395
12396 safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy);
12397 }
12398 }
12399
12400 effect = effect.next;
12401 } while (effect !== firstEffect);
12402 }
12403 }
12404
12405 function commitHookEffectListMount(flags, finishedWork) {
12406 var updateQueue = finishedWork.updateQueue;
12407 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
12408
12409 if (lastEffect !== null) {
12410 var firstEffect = lastEffect.next;
12411 var effect = firstEffect;
12412
12413 do {
12414 if ((effect.tag & flags) === flags) {
12415
12416
12417 var create = effect.create;
12418 effect.destroy = create();
12419
12420 {
12421 var destroy = effect.destroy;
12422
12423 if (destroy !== undefined && typeof destroy !== 'function') {
12424 var hookName = void 0;
12425
12426 if ((effect.tag & Layout) !== NoFlags) {
12427 hookName = 'useLayoutEffect';
12428 } else if ((effect.tag & Insertion) !== NoFlags) {
12429 hookName = 'useInsertionEffect';
12430 } else {
12431 hookName = 'useEffect';
12432 }
12433
12434 var addendum = void 0;
12435
12436 if (destroy === null) {
12437 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
12438 } else if (typeof destroy.then === 'function') {
12439 addendum = '\n\nIt looks like you wrote ' + hookName + '(async () => ...) or returned a Promise. ' + 'Instead, write the async function inside your effect ' + 'and call it immediately:\n\n' + hookName + '(() => {\n' + ' async function fetchData() {\n' + ' // You can await here\n' + ' const response = await MyAPI.getData(someId);\n' + ' // ...\n' + ' }\n' + ' fetchData();\n' + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + 'Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching';
12440 } else {
12441 addendum = ' You returned: ' + destroy;
12442 }
12443
12444 error('%s must not return anything besides a function, ' + 'which is used for clean-up.%s', hookName, addendum);
12445 }
12446 }
12447 }
12448
12449 effect = effect.next;
12450 } while (effect !== firstEffect);
12451 }
12452 }
12453
12454 function commitPassiveEffectDurations(finishedRoot, finishedWork) {
12455 {
12456 // Only Profilers with work in their subtree will have an Update effect scheduled.
12457 if ((finishedWork.flags & Update) !== NoFlags) {
12458 switch (finishedWork.tag) {
12459 case Profiler:
12460 {
12461 var passiveEffectDuration = finishedWork.stateNode.passiveEffectDuration;
12462 var _finishedWork$memoize = finishedWork.memoizedProps,
12463 id = _finishedWork$memoize.id,
12464 onPostCommit = _finishedWork$memoize.onPostCommit; // This value will still reflect the previous commit phase.
12465 // It does not get reset until the start of the next commit phase.
12466
12467 var commitTime = getCommitTime();
12468 var phase = finishedWork.alternate === null ? 'mount' : 'update';
12469
12470 {
12471 if (isCurrentUpdateNested()) {
12472 phase = 'nested-update';
12473 }
12474 }
12475
12476 if (typeof onPostCommit === 'function') {
12477 onPostCommit(id, phase, passiveEffectDuration, commitTime);
12478 } // Bubble times to the next nearest ancestor Profiler.
12479 // After we process that Profiler, we'll bubble further up.
12480
12481
12482 var parentFiber = finishedWork.return;
12483
12484 outer: while (parentFiber !== null) {
12485 switch (parentFiber.tag) {
12486 case HostRoot:
12487 var root = parentFiber.stateNode;
12488 root.passiveEffectDuration += passiveEffectDuration;
12489 break outer;
12490
12491 case Profiler:
12492 var parentStateNode = parentFiber.stateNode;
12493 parentStateNode.passiveEffectDuration += passiveEffectDuration;
12494 break outer;
12495 }
12496
12497 parentFiber = parentFiber.return;
12498 }
12499
12500 break;
12501 }
12502 }
12503 }
12504 }
12505 }
12506
12507 function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork, committedLanes) {
12508 if ((finishedWork.flags & LayoutMask) !== NoFlags) {
12509 switch (finishedWork.tag) {
12510 case FunctionComponent:
12511 case ForwardRef:
12512 case SimpleMemoComponent:
12513 {
12514 {
12515 // At this point layout effects have already been destroyed (during mutation phase).
12516 // This is done to prevent sibling component effects from interfering with each other,
12517 // e.g. a destroy function in one component should never override a ref set
12518 // by a create function in another component during the same commit.
12519 if ( finishedWork.mode & ProfileMode) {
12520 try {
12521 startLayoutEffectTimer();
12522 commitHookEffectListMount(Layout | HasEffect, finishedWork);
12523 } finally {
12524 recordLayoutEffectDuration(finishedWork);
12525 }
12526 } else {
12527 commitHookEffectListMount(Layout | HasEffect, finishedWork);
12528 }
12529 }
12530
12531 break;
12532 }
12533
12534 case ClassComponent:
12535 {
12536 var instance = finishedWork.stateNode;
12537
12538 if (finishedWork.flags & Update) {
12539 {
12540 if (current === null) {
12541 // We could update instance props and state here,
12542 // but instead we rely on them being set during last render.
12543 // TODO: revisit this when we implement resuming.
12544 {
12545 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
12546 if (instance.props !== finishedWork.memoizedProps) {
12547 error('Expected %s props to match memoized props before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
12548 }
12549
12550 if (instance.state !== finishedWork.memoizedState) {
12551 error('Expected %s state to match memoized state before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
12552 }
12553 }
12554 }
12555
12556 if ( finishedWork.mode & ProfileMode) {
12557 try {
12558 startLayoutEffectTimer();
12559 instance.componentDidMount();
12560 } finally {
12561 recordLayoutEffectDuration(finishedWork);
12562 }
12563 } else {
12564 instance.componentDidMount();
12565 }
12566 } else {
12567 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
12568 var prevState = current.memoizedState; // We could update instance props and state here,
12569 // but instead we rely on them being set during last render.
12570 // TODO: revisit this when we implement resuming.
12571
12572 {
12573 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
12574 if (instance.props !== finishedWork.memoizedProps) {
12575 error('Expected %s props to match memoized props before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
12576 }
12577
12578 if (instance.state !== finishedWork.memoizedState) {
12579 error('Expected %s state to match memoized state before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
12580 }
12581 }
12582 }
12583
12584 if ( finishedWork.mode & ProfileMode) {
12585 try {
12586 startLayoutEffectTimer();
12587 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
12588 } finally {
12589 recordLayoutEffectDuration(finishedWork);
12590 }
12591 } else {
12592 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
12593 }
12594 }
12595 }
12596 } // TODO: I think this is now always non-null by the time it reaches the
12597 // commit phase. Consider removing the type check.
12598
12599
12600 var updateQueue = finishedWork.updateQueue;
12601
12602 if (updateQueue !== null) {
12603 {
12604 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
12605 if (instance.props !== finishedWork.memoizedProps) {
12606 error('Expected %s props to match memoized props before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
12607 }
12608
12609 if (instance.state !== finishedWork.memoizedState) {
12610 error('Expected %s state to match memoized state before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
12611 }
12612 }
12613 } // We could update instance props and state here,
12614 // but instead we rely on them being set during last render.
12615 // TODO: revisit this when we implement resuming.
12616
12617
12618 commitUpdateQueue(finishedWork, updateQueue, instance);
12619 }
12620
12621 break;
12622 }
12623
12624 case HostRoot:
12625 {
12626 // TODO: I think this is now always non-null by the time it reaches the
12627 // commit phase. Consider removing the type check.
12628 var _updateQueue = finishedWork.updateQueue;
12629
12630 if (_updateQueue !== null) {
12631 var _instance = null;
12632
12633 if (finishedWork.child !== null) {
12634 switch (finishedWork.child.tag) {
12635 case HostComponent:
12636 _instance = getPublicInstance(finishedWork.child.stateNode);
12637 break;
12638
12639 case ClassComponent:
12640 _instance = finishedWork.child.stateNode;
12641 break;
12642 }
12643 }
12644
12645 commitUpdateQueue(finishedWork, _updateQueue, _instance);
12646 }
12647
12648 break;
12649 }
12650
12651 case HostComponent:
12652 {
12653 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted
12654 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
12655 // These effects should only be committed when components are first mounted,
12656 // aka when there is no current/alternate.
12657
12658 if (current === null && finishedWork.flags & Update) {
12659 var type = finishedWork.type;
12660 var props = finishedWork.memoizedProps;
12661 }
12662
12663 break;
12664 }
12665
12666 case HostText:
12667 {
12668 // We have no life-cycles associated with text.
12669 break;
12670 }
12671
12672 case HostPortal:
12673 {
12674 // We have no life-cycles associated with portals.
12675 break;
12676 }
12677
12678 case Profiler:
12679 {
12680 {
12681 var _finishedWork$memoize2 = finishedWork.memoizedProps,
12682 onCommit = _finishedWork$memoize2.onCommit,
12683 onRender = _finishedWork$memoize2.onRender;
12684 var effectDuration = finishedWork.stateNode.effectDuration;
12685 var commitTime = getCommitTime();
12686 var phase = current === null ? 'mount' : 'update';
12687
12688 {
12689 if (isCurrentUpdateNested()) {
12690 phase = 'nested-update';
12691 }
12692 }
12693
12694 if (typeof onRender === 'function') {
12695 onRender(finishedWork.memoizedProps.id, phase, finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, commitTime);
12696 }
12697
12698 {
12699 if (typeof onCommit === 'function') {
12700 onCommit(finishedWork.memoizedProps.id, phase, effectDuration, commitTime);
12701 } // Schedule a passive effect for this Profiler to call onPostCommit hooks.
12702 // This effect should be scheduled even if there is no onPostCommit callback for this Profiler,
12703 // because the effect is also where times bubble to parent Profilers.
12704
12705
12706 enqueuePendingPassiveProfilerEffect(finishedWork); // Propagate layout effect durations to the next nearest Profiler ancestor.
12707 // Do not reset these values until the next render so DevTools has a chance to read them first.
12708
12709 var parentFiber = finishedWork.return;
12710
12711 outer: while (parentFiber !== null) {
12712 switch (parentFiber.tag) {
12713 case HostRoot:
12714 var root = parentFiber.stateNode;
12715 root.effectDuration += effectDuration;
12716 break outer;
12717
12718 case Profiler:
12719 var parentStateNode = parentFiber.stateNode;
12720 parentStateNode.effectDuration += effectDuration;
12721 break outer;
12722 }
12723
12724 parentFiber = parentFiber.return;
12725 }
12726 }
12727 }
12728
12729 break;
12730 }
12731
12732 case SuspenseComponent:
12733 {
12734 break;
12735 }
12736
12737 case SuspenseListComponent:
12738 case IncompleteClassComponent:
12739 case ScopeComponent:
12740 case OffscreenComponent:
12741 case LegacyHiddenComponent:
12742 {
12743 break;
12744 }
12745
12746 default:
12747 throw new Error('This unit of work tag should not have side-effects. This error is ' + 'likely caused by a bug in React. Please file an issue.');
12748 }
12749 }
12750
12751 {
12752 {
12753 if (finishedWork.flags & Ref) {
12754 commitAttachRef(finishedWork);
12755 }
12756 }
12757 }
12758 }
12759
12760 function hideOrUnhideAllChildren(finishedWork, isHidden) {
12761 // Only hide or unhide the top-most host nodes.
12762 var hostSubtreeRoot = null;
12763
12764 {
12765 // We only have the top Fiber that was inserted but we need to recurse down its
12766 // children to find all the terminal nodes.
12767 var node = finishedWork;
12768
12769 while (true) {
12770 if (node.tag === HostComponent) {
12771 if (hostSubtreeRoot === null) {
12772 hostSubtreeRoot = node;
12773 var instance = node.stateNode;
12774
12775 if (isHidden) {
12776 hideInstance(instance);
12777 } else {
12778 unhideInstance(node.stateNode, node.memoizedProps);
12779 }
12780 }
12781 } else if (node.tag === HostText) {
12782 if (hostSubtreeRoot === null) {
12783 var _instance3 = node.stateNode;
12784
12785 if (isHidden) {
12786 hideTextInstance(_instance3);
12787 } else {
12788 unhideTextInstance(_instance3, node.memoizedProps);
12789 }
12790 }
12791 } else if ((node.tag === OffscreenComponent || node.tag === LegacyHiddenComponent) && node.memoizedState !== null && node !== finishedWork) ; else if (node.child !== null) {
12792 node.child.return = node;
12793 node = node.child;
12794 continue;
12795 }
12796
12797 if (node === finishedWork) {
12798 return;
12799 }
12800
12801 while (node.sibling === null) {
12802 if (node.return === null || node.return === finishedWork) {
12803 return;
12804 }
12805
12806 if (hostSubtreeRoot === node) {
12807 hostSubtreeRoot = null;
12808 }
12809
12810 node = node.return;
12811 }
12812
12813 if (hostSubtreeRoot === node) {
12814 hostSubtreeRoot = null;
12815 }
12816
12817 node.sibling.return = node.return;
12818 node = node.sibling;
12819 }
12820 }
12821 }
12822
12823 function commitAttachRef(finishedWork) {
12824 var ref = finishedWork.ref;
12825
12826 if (ref !== null) {
12827 var instance = finishedWork.stateNode;
12828 var instanceToUse;
12829
12830 switch (finishedWork.tag) {
12831 case HostComponent:
12832 instanceToUse = getPublicInstance(instance);
12833 break;
12834
12835 default:
12836 instanceToUse = instance;
12837 } // Moved outside to ensure DCE works with this flag
12838
12839 if (typeof ref === 'function') {
12840 var retVal;
12841
12842 if ( finishedWork.mode & ProfileMode) {
12843 try {
12844 startLayoutEffectTimer();
12845 retVal = ref(instanceToUse);
12846 } finally {
12847 recordLayoutEffectDuration(finishedWork);
12848 }
12849 } else {
12850 retVal = ref(instanceToUse);
12851 }
12852
12853 {
12854 if (typeof retVal === 'function') {
12855 error('Unexpected return value from a callback ref in %s. ' + 'A callback ref should not return a function.', getComponentNameFromFiber(finishedWork));
12856 }
12857 }
12858 } else {
12859 {
12860 if (!ref.hasOwnProperty('current')) {
12861 error('Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().', getComponentNameFromFiber(finishedWork));
12862 }
12863 }
12864
12865 ref.current = instanceToUse;
12866 }
12867 }
12868 }
12869
12870 function commitDetachRef(current) {
12871 var currentRef = current.ref;
12872
12873 if (currentRef !== null) {
12874 if (typeof currentRef === 'function') {
12875 if ( current.mode & ProfileMode) {
12876 try {
12877 startLayoutEffectTimer();
12878 currentRef(null);
12879 } finally {
12880 recordLayoutEffectDuration(current);
12881 }
12882 } else {
12883 currentRef(null);
12884 }
12885 } else {
12886 currentRef.current = null;
12887 }
12888 }
12889 } // User-originating errors (lifecycles and refs) should not interrupt
12890 // deletion, so don't let them throw. Host-originating errors should
12891 // interrupt deletion, so it's okay
12892
12893
12894 function commitUnmount(finishedRoot, current, nearestMountedAncestor) {
12895 onCommitUnmount(current);
12896
12897 switch (current.tag) {
12898 case FunctionComponent:
12899 case ForwardRef:
12900 case MemoComponent:
12901 case SimpleMemoComponent:
12902 {
12903 var updateQueue = current.updateQueue;
12904
12905 if (updateQueue !== null) {
12906 var lastEffect = updateQueue.lastEffect;
12907
12908 if (lastEffect !== null) {
12909 var firstEffect = lastEffect.next;
12910 var effect = firstEffect;
12911
12912 do {
12913 var _effect = effect,
12914 destroy = _effect.destroy,
12915 tag = _effect.tag;
12916
12917 if (destroy !== undefined) {
12918 if ((tag & Insertion) !== NoFlags$1) {
12919 safelyCallDestroy(current, nearestMountedAncestor, destroy);
12920 } else if ((tag & Layout) !== NoFlags$1) {
12921
12922 if ( current.mode & ProfileMode) {
12923 startLayoutEffectTimer();
12924 safelyCallDestroy(current, nearestMountedAncestor, destroy);
12925 recordLayoutEffectDuration(current);
12926 } else {
12927 safelyCallDestroy(current, nearestMountedAncestor, destroy);
12928 }
12929 }
12930 }
12931
12932 effect = effect.next;
12933 } while (effect !== firstEffect);
12934 }
12935 }
12936
12937 return;
12938 }
12939
12940 case ClassComponent:
12941 {
12942 safelyDetachRef(current, nearestMountedAncestor);
12943 var instance = current.stateNode;
12944
12945 if (typeof instance.componentWillUnmount === 'function') {
12946 safelyCallComponentWillUnmount(current, nearestMountedAncestor, instance);
12947 }
12948
12949 return;
12950 }
12951
12952 case HostComponent:
12953 {
12954 safelyDetachRef(current, nearestMountedAncestor);
12955 return;
12956 }
12957
12958 case HostPortal:
12959 {
12960 // TODO: this is recursive.
12961 // We are also not using this parent because
12962 // the portal will get pushed immediately.
12963 {
12964 unmountHostComponents(finishedRoot, current, nearestMountedAncestor);
12965 }
12966
12967 return;
12968 }
12969
12970 case DehydratedFragment:
12971 {
12972
12973 return;
12974 }
12975
12976 case ScopeComponent:
12977 {
12978
12979 return;
12980 }
12981 }
12982 }
12983
12984 function commitNestedUnmounts(finishedRoot, root, nearestMountedAncestor) {
12985 // While we're inside a removed host node we don't want to call
12986 // removeChild on the inner nodes because they're removed by the top
12987 // call anyway. We also want to call componentWillUnmount on all
12988 // composites before this host node is removed from the tree. Therefore
12989 // we do an inner loop while we're still inside the host node.
12990 var node = root;
12991
12992 while (true) {
12993 commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because they may contain more composite or host nodes.
12994 // Skip portals because commitUnmount() currently visits them recursively.
12995
12996 if (node.child !== null && ( // If we use mutation we drill down into portals using commitUnmount above.
12997 // If we don't use mutation we drill down into portals here instead.
12998 node.tag !== HostPortal)) {
12999 node.child.return = node;
13000 node = node.child;
13001 continue;
13002 }
13003
13004 if (node === root) {
13005 return;
13006 }
13007
13008 while (node.sibling === null) {
13009 if (node.return === null || node.return === root) {
13010 return;
13011 }
13012
13013 node = node.return;
13014 }
13015
13016 node.sibling.return = node.return;
13017 node = node.sibling;
13018 }
13019 }
13020
13021 function detachFiberMutation(fiber) {
13022 // Cut off the return pointer to disconnect it from the tree.
13023 // This enables us to detect and warn against state updates on an unmounted component.
13024 // It also prevents events from bubbling from within disconnected components.
13025 //
13026 // Ideally, we should also clear the child pointer of the parent alternate to let this
13027 // get GC:ed but we don't know which for sure which parent is the current
13028 // one so we'll settle for GC:ing the subtree of this child.
13029 // This child itself will be GC:ed when the parent updates the next time.
13030 //
13031 // Note that we can't clear child or sibling pointers yet.
13032 // They're needed for passive effects and for findDOMNode.
13033 // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects).
13034 //
13035 // Don't reset the alternate yet, either. We need that so we can detach the
13036 // alternate's fields in the passive phase. Clearing the return pointer is
13037 // sufficient for findDOMNode semantics.
13038 var alternate = fiber.alternate;
13039
13040 if (alternate !== null) {
13041 alternate.return = null;
13042 }
13043
13044 fiber.return = null;
13045 }
13046
13047 function detachFiberAfterEffects(fiber) {
13048 var alternate = fiber.alternate;
13049
13050 if (alternate !== null) {
13051 fiber.alternate = null;
13052 detachFiberAfterEffects(alternate);
13053 } // Note: Defensively using negation instead of < in case
13054 // `deletedTreeCleanUpLevel` is undefined.
13055
13056
13057 {
13058 // Clear cyclical Fiber fields. This level alone is designed to roughly
13059 // approximate the planned Fiber refactor. In that world, `setState` will be
13060 // bound to a special "instance" object instead of a Fiber. The Instance
13061 // object will not have any of these fields. It will only be connected to
13062 // the fiber tree via a single link at the root. So if this level alone is
13063 // sufficient to fix memory issues, that bodes well for our plans.
13064 fiber.child = null;
13065 fiber.deletions = null;
13066 fiber.sibling = null; // The `stateNode` is cyclical because on host nodes it points to the host
13067 // tree, which has its own pointers to children, parents, and siblings.
13068 // The other host nodes also point back to fibers, so we should detach that
13069 // one, too.
13070
13071 if (fiber.tag === HostComponent) {
13072 var hostInstance = fiber.stateNode;
13073 }
13074
13075 fiber.stateNode = null; // I'm intentionally not clearing the `return` field in this level. We
13076 // already disconnect the `return` pointer at the root of the deleted
13077 // subtree (in `detachFiberMutation`). Besides, `return` by itself is not
13078 // cyclical — it's only cyclical when combined with `child`, `sibling`, and
13079 // `alternate`. But we'll clear it in the next level anyway, just in case.
13080
13081 {
13082 fiber._debugOwner = null;
13083 }
13084
13085 {
13086 // Theoretically, nothing in here should be necessary, because we already
13087 // disconnected the fiber from the tree. So even if something leaks this
13088 // particular fiber, it won't leak anything else
13089 //
13090 // The purpose of this branch is to be super aggressive so we can measure
13091 // if there's any difference in memory impact. If there is, that could
13092 // indicate a React leak we don't know about.
13093 fiber.return = null;
13094 fiber.dependencies = null;
13095 fiber.memoizedProps = null;
13096 fiber.memoizedState = null;
13097 fiber.pendingProps = null;
13098 fiber.stateNode = null; // TODO: Move to `commitPassiveUnmountInsideDeletedTreeOnFiber` instead.
13099
13100 fiber.updateQueue = null;
13101 }
13102 }
13103 }
13104
13105 function getHostParentFiber(fiber) {
13106 var parent = fiber.return;
13107
13108 while (parent !== null) {
13109 if (isHostParent(parent)) {
13110 return parent;
13111 }
13112
13113 parent = parent.return;
13114 }
13115
13116 throw new Error('Expected to find a host parent. This error is likely caused by a bug ' + 'in React. Please file an issue.');
13117 }
13118
13119 function isHostParent(fiber) {
13120 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
13121 }
13122
13123 function getHostSibling(fiber) {
13124 // We're going to search forward into the tree until we find a sibling host
13125 // node. Unfortunately, if multiple insertions are done in a row we have to
13126 // search past them. This leads to exponential search for the next sibling.
13127 // TODO: Find a more efficient way to do this.
13128 var node = fiber;
13129
13130 siblings: while (true) {
13131 // If we didn't find anything, let's try the next sibling.
13132 while (node.sibling === null) {
13133 if (node.return === null || isHostParent(node.return)) {
13134 // If we pop out of the root or hit the parent the fiber we are the
13135 // last sibling.
13136 return null;
13137 }
13138
13139 node = node.return;
13140 }
13141
13142 node.sibling.return = node.return;
13143 node = node.sibling;
13144
13145 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {
13146 // If it is not host node and, we might have a host node inside it.
13147 // Try to search down until we find one.
13148 if (node.flags & Placement) {
13149 // If we don't have a child, try the siblings instead.
13150 continue siblings;
13151 } // If we don't have a child, try the siblings instead.
13152 // We also skip portals because they are not part of this host tree.
13153
13154
13155 if (node.child === null || node.tag === HostPortal) {
13156 continue siblings;
13157 } else {
13158 node.child.return = node;
13159 node = node.child;
13160 }
13161 } // Check if this host node is stable or about to be placed.
13162
13163
13164 if (!(node.flags & Placement)) {
13165 // Found it!
13166 return node.stateNode;
13167 }
13168 }
13169 }
13170
13171 function commitPlacement(finishedWork) {
13172
13173
13174 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.
13175
13176 switch (parentFiber.tag) {
13177 case HostComponent:
13178 {
13179 var parent = parentFiber.stateNode;
13180
13181 if (parentFiber.flags & ContentReset) {
13182
13183 parentFiber.flags &= ~ContentReset;
13184 }
13185
13186 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
13187 // children to find all the terminal nodes.
13188
13189 insertOrAppendPlacementNode(finishedWork, before, parent);
13190 break;
13191 }
13192
13193 case HostRoot:
13194 case HostPortal:
13195 {
13196 var _parent = parentFiber.stateNode.containerInfo;
13197
13198 var _before = getHostSibling(finishedWork);
13199
13200 insertOrAppendPlacementNodeIntoContainer(finishedWork, _before, _parent);
13201 break;
13202 }
13203 // eslint-disable-next-line-no-fallthrough
13204
13205 default:
13206 throw new Error('Invalid host parent fiber. This error is likely caused by a bug ' + 'in React. Please file an issue.');
13207 }
13208 }
13209
13210 function insertOrAppendPlacementNodeIntoContainer(node, before, parent) {
13211 var tag = node.tag;
13212 var isHost = tag === HostComponent || tag === HostText;
13213
13214 if (isHost) {
13215 var stateNode = node.stateNode;
13216
13217 if (before) {
13218 insertInContainerBefore(parent, stateNode, before);
13219 } else {
13220 appendChildToContainer(parent, stateNode);
13221 }
13222 } else if (tag === HostPortal) ; else {
13223 var child = node.child;
13224
13225 if (child !== null) {
13226 insertOrAppendPlacementNodeIntoContainer(child, before, parent);
13227 var sibling = child.sibling;
13228
13229 while (sibling !== null) {
13230 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);
13231 sibling = sibling.sibling;
13232 }
13233 }
13234 }
13235 }
13236
13237 function insertOrAppendPlacementNode(node, before, parent) {
13238 var tag = node.tag;
13239 var isHost = tag === HostComponent || tag === HostText;
13240
13241 if (isHost) {
13242 var stateNode = node.stateNode;
13243
13244 if (before) {
13245 insertBefore(parent, stateNode, before);
13246 } else {
13247 appendChild(parent, stateNode);
13248 }
13249 } else if (tag === HostPortal) ; else {
13250 var child = node.child;
13251
13252 if (child !== null) {
13253 insertOrAppendPlacementNode(child, before, parent);
13254 var sibling = child.sibling;
13255
13256 while (sibling !== null) {
13257 insertOrAppendPlacementNode(sibling, before, parent);
13258 sibling = sibling.sibling;
13259 }
13260 }
13261 }
13262 }
13263
13264 function unmountHostComponents(finishedRoot, current, nearestMountedAncestor) {
13265 // We only have the top Fiber that was deleted but we need to recurse down its
13266 // children to find all the terminal nodes.
13267 var node = current; // Each iteration, currentParent is populated with node's host parent if not
13268 // currentParentIsValid.
13269
13270 var currentParentIsValid = false; // Note: these two variables *must* always be updated together.
13271
13272 var currentParent;
13273 var currentParentIsContainer;
13274
13275 while (true) {
13276 if (!currentParentIsValid) {
13277 var parent = node.return;
13278
13279 findParent: while (true) {
13280 if (parent === null) {
13281 throw new Error('Expected to find a host parent. This error is likely caused by ' + 'a bug in React. Please file an issue.');
13282 }
13283
13284 var parentStateNode = parent.stateNode;
13285
13286 switch (parent.tag) {
13287 case HostComponent:
13288 currentParent = parentStateNode;
13289 currentParentIsContainer = false;
13290 break findParent;
13291
13292 case HostRoot:
13293 currentParent = parentStateNode.containerInfo;
13294 currentParentIsContainer = true;
13295 break findParent;
13296
13297 case HostPortal:
13298 currentParent = parentStateNode.containerInfo;
13299 currentParentIsContainer = true;
13300 break findParent;
13301 }
13302
13303 parent = parent.return;
13304 }
13305
13306 currentParentIsValid = true;
13307 }
13308
13309 if (node.tag === HostComponent || node.tag === HostText) {
13310 commitNestedUnmounts(finishedRoot, node, nearestMountedAncestor); // After all the children have unmounted, it is now safe to remove the
13311 // node from the tree.
13312
13313 if (currentParentIsContainer) {
13314 removeChildFromContainer(currentParent, node.stateNode);
13315 } else {
13316 removeChild(currentParent, node.stateNode);
13317 } // Don't visit children because we already visited them.
13318
13319 } else if (node.tag === HostPortal) {
13320 if (node.child !== null) {
13321 // When we go into a portal, it becomes the parent to remove from.
13322 // We will reassign it back when we pop the portal on the way up.
13323 currentParent = node.stateNode.containerInfo;
13324 currentParentIsContainer = true; // Visit children because portals might contain host components.
13325
13326 node.child.return = node;
13327 node = node.child;
13328 continue;
13329 }
13330 } else {
13331 commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because we may find more host components below.
13332
13333 if (node.child !== null) {
13334 node.child.return = node;
13335 node = node.child;
13336 continue;
13337 }
13338 }
13339
13340 if (node === current) {
13341 return;
13342 }
13343
13344 while (node.sibling === null) {
13345 if (node.return === null || node.return === current) {
13346 return;
13347 }
13348
13349 node = node.return;
13350
13351 if (node.tag === HostPortal) {
13352 // When we go out of the portal, we need to restore the parent.
13353 // Since we don't keep a stack of them, we will search for it.
13354 currentParentIsValid = false;
13355 }
13356 }
13357
13358 node.sibling.return = node.return;
13359 node = node.sibling;
13360 }
13361 }
13362
13363 function commitDeletion(finishedRoot, current, nearestMountedAncestor) {
13364 {
13365 // Recursively delete all host nodes from the parent.
13366 // Detach refs and call componentWillUnmount() on the whole subtree.
13367 unmountHostComponents(finishedRoot, current, nearestMountedAncestor);
13368 }
13369
13370 detachFiberMutation(current);
13371 }
13372
13373 function commitWork(current, finishedWork) {
13374
13375 switch (finishedWork.tag) {
13376 case FunctionComponent:
13377 case ForwardRef:
13378 case MemoComponent:
13379 case SimpleMemoComponent:
13380 {
13381 commitHookEffectListUnmount(Insertion | HasEffect, finishedWork, finishedWork.return);
13382 commitHookEffectListMount(Insertion | HasEffect, finishedWork); // Layout effects are destroyed during the mutation phase so that all
13383 // destroy functions for all fibers are called before any create functions.
13384 // This prevents sibling component effects from interfering with each other,
13385 // e.g. a destroy function in one component should never override a ref set
13386 // by a create function in another component during the same commit.
13387
13388 if ( finishedWork.mode & ProfileMode) {
13389 try {
13390 startLayoutEffectTimer();
13391 commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return);
13392 } finally {
13393 recordLayoutEffectDuration(finishedWork);
13394 }
13395 } else {
13396 commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return);
13397 }
13398
13399 return;
13400 }
13401
13402 case ClassComponent:
13403 {
13404 return;
13405 }
13406
13407 case HostComponent:
13408 {
13409 var instance = finishedWork.stateNode;
13410
13411 if (instance != null) {
13412 // Commit the work prepared earlier.
13413 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
13414 // as the newProps. The updatePayload will contain the real change in
13415 // this case.
13416
13417 var oldProps = current !== null ? current.memoizedProps : newProps;
13418 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.
13419
13420 var updatePayload = finishedWork.updateQueue;
13421 finishedWork.updateQueue = null;
13422
13423 if (updatePayload !== null) {
13424 commitUpdate(instance, updatePayload, type, oldProps, newProps);
13425 }
13426 }
13427
13428 return;
13429 }
13430
13431 case HostText:
13432 {
13433 if (finishedWork.stateNode === null) {
13434 throw new Error('This should have a text node initialized. This error is likely ' + 'caused by a bug in React. Please file an issue.');
13435 }
13436
13437 var textInstance = finishedWork.stateNode;
13438 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
13439 // as the newProps. The updatePayload will contain the real change in
13440 // this case.
13441
13442 var oldText = current !== null ? current.memoizedProps : newText;
13443 commitTextUpdate(textInstance, oldText, newText);
13444 return;
13445 }
13446
13447 case HostRoot:
13448 {
13449
13450 return;
13451 }
13452
13453 case Profiler:
13454 {
13455 return;
13456 }
13457
13458 case SuspenseComponent:
13459 {
13460 commitSuspenseCallback(finishedWork);
13461 attachSuspenseRetryListeners(finishedWork);
13462 return;
13463 }
13464
13465 case SuspenseListComponent:
13466 {
13467 attachSuspenseRetryListeners(finishedWork);
13468 return;
13469 }
13470
13471 case IncompleteClassComponent:
13472 {
13473 return;
13474 }
13475 }
13476
13477 throw new Error('This unit of work tag should not have side-effects. This error is ' + 'likely caused by a bug in React. Please file an issue.');
13478 }
13479
13480 function commitSuspenseCallback(finishedWork) {
13481 // TODO: Move this to passive phase
13482 var newState = finishedWork.memoizedState;
13483 }
13484
13485 function attachSuspenseRetryListeners(finishedWork) {
13486 // If this boundary just timed out, then it will have a set of wakeables.
13487 // For each wakeable, attach a listener so that when it resolves, React
13488 // attempts to re-render the boundary in the primary (pre-timeout) state.
13489 var wakeables = finishedWork.updateQueue;
13490
13491 if (wakeables !== null) {
13492 finishedWork.updateQueue = null;
13493 var retryCache = finishedWork.stateNode;
13494
13495 if (retryCache === null) {
13496 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
13497 }
13498
13499 wakeables.forEach(function (wakeable) {
13500 // Memoize using the boundary fiber to prevent redundant listeners.
13501 var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable);
13502
13503 if (!retryCache.has(wakeable)) {
13504 retryCache.add(wakeable);
13505
13506 wakeable.then(retry, retry);
13507 }
13508 });
13509 }
13510 } // This function detects when a Suspense boundary goes from visible to hidden.
13511
13512 function commitResetTextContent(current) {
13513
13514 resetTextContent(current.stateNode);
13515 }
13516
13517 function commitMutationEffects(root, firstChild, committedLanes) {
13518 nextEffect = firstChild;
13519 commitMutationEffects_begin(root, committedLanes);
13520 }
13521
13522 function commitMutationEffects_begin(root, lanes) {
13523 while (nextEffect !== null) {
13524 var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization
13525
13526 var deletions = fiber.deletions;
13527
13528 if (deletions !== null) {
13529 for (var i = 0; i < deletions.length; i++) {
13530 var childToDelete = deletions[i];
13531
13532 try {
13533 commitDeletion(root, childToDelete, fiber);
13534 } catch (error) {
13535 reportUncaughtErrorInDEV(error);
13536 captureCommitPhaseError(childToDelete, fiber, error);
13537 }
13538 }
13539 }
13540
13541 var child = fiber.child;
13542
13543 if ((fiber.subtreeFlags & MutationMask) !== NoFlags && child !== null) {
13544 ensureCorrectReturnPointer(child, fiber);
13545 nextEffect = child;
13546 } else {
13547 commitMutationEffects_complete(root, lanes);
13548 }
13549 }
13550 }
13551
13552 function commitMutationEffects_complete(root, lanes) {
13553 while (nextEffect !== null) {
13554 var fiber = nextEffect;
13555 setCurrentFiber(fiber);
13556
13557 try {
13558 commitMutationEffectsOnFiber(fiber, root, lanes);
13559 } catch (error) {
13560 reportUncaughtErrorInDEV(error);
13561 captureCommitPhaseError(fiber, fiber.return, error);
13562 }
13563
13564 resetCurrentFiber();
13565 var sibling = fiber.sibling;
13566
13567 if (sibling !== null) {
13568 ensureCorrectReturnPointer(sibling, fiber.return);
13569 nextEffect = sibling;
13570 return;
13571 }
13572
13573 nextEffect = fiber.return;
13574 }
13575 }
13576
13577 function commitMutationEffectsOnFiber(finishedWork, root, lanes) {
13578 // TODO: The factoring of this phase could probably be improved. Consider
13579 // switching on the type of work before checking the flags. That's what
13580 // we do in all the other phases. I think this one is only different
13581 // because of the shared reconciliation logic below.
13582 var flags = finishedWork.flags;
13583
13584 if (flags & ContentReset) {
13585 commitResetTextContent(finishedWork);
13586 }
13587
13588 if (flags & Ref) {
13589 var current = finishedWork.alternate;
13590
13591 if (current !== null) {
13592 commitDetachRef(current);
13593 }
13594 }
13595
13596 if (flags & Visibility) {
13597 switch (finishedWork.tag) {
13598 case SuspenseComponent:
13599 {
13600 var newState = finishedWork.memoizedState;
13601 var isHidden = newState !== null;
13602
13603 if (isHidden) {
13604 var _current = finishedWork.alternate;
13605 var wasHidden = _current !== null && _current.memoizedState !== null;
13606
13607 if (!wasHidden) {
13608 // TODO: Move to passive phase
13609 markCommitTimeOfFallback();
13610 }
13611 }
13612
13613 break;
13614 }
13615
13616 case OffscreenComponent:
13617 {
13618 var _newState = finishedWork.memoizedState;
13619
13620 var _isHidden = _newState !== null;
13621
13622 var _current2 = finishedWork.alternate;
13623
13624 var _wasHidden = _current2 !== null && _current2.memoizedState !== null;
13625
13626 var offscreenBoundary = finishedWork;
13627
13628 {
13629 // TODO: This needs to run whenever there's an insertion or update
13630 // inside a hidden Offscreen tree.
13631 hideOrUnhideAllChildren(offscreenBoundary, _isHidden);
13632 }
13633 }
13634 }
13635 } // The following switch statement is only concerned about placement,
13636 // updates, and deletions. To avoid needing to add a case for every possible
13637 // bitmap value, we remove the secondary effects from the effect tag and
13638 // switch on that value.
13639
13640
13641 var primaryFlags = flags & (Placement | Update | Hydrating);
13642
13643 switch (primaryFlags) {
13644 case Placement:
13645 {
13646 commitPlacement(finishedWork); // Clear the "placement" from effect tag so that we know that this is
13647 // inserted, before any life-cycles like componentDidMount gets called.
13648 // TODO: findDOMNode doesn't rely on this any more but isMounted does
13649 // and isMounted is deprecated anyway so we should be able to kill this.
13650
13651 finishedWork.flags &= ~Placement;
13652 break;
13653 }
13654
13655 case PlacementAndUpdate:
13656 {
13657 // Placement
13658 commitPlacement(finishedWork); // Clear the "placement" from effect tag so that we know that this is
13659 // inserted, before any life-cycles like componentDidMount gets called.
13660
13661 finishedWork.flags &= ~Placement; // Update
13662
13663 var _current3 = finishedWork.alternate;
13664 commitWork(_current3, finishedWork);
13665 break;
13666 }
13667
13668 case Hydrating:
13669 {
13670 finishedWork.flags &= ~Hydrating;
13671 break;
13672 }
13673
13674 case HydratingAndUpdate:
13675 {
13676 finishedWork.flags &= ~Hydrating; // Update
13677
13678 var _current4 = finishedWork.alternate;
13679 commitWork(_current4, finishedWork);
13680 break;
13681 }
13682
13683 case Update:
13684 {
13685 var _current5 = finishedWork.alternate;
13686 commitWork(_current5, finishedWork);
13687 break;
13688 }
13689 }
13690 }
13691
13692 function commitLayoutEffects(finishedWork, root, committedLanes) {
13693 nextEffect = finishedWork;
13694 commitLayoutEffects_begin(finishedWork, root, committedLanes);
13695 }
13696
13697 function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) {
13698 // Suspense layout effects semantics don't change for legacy roots.
13699 var isModernRoot = (subtreeRoot.mode & ConcurrentMode) !== NoMode;
13700
13701 while (nextEffect !== null) {
13702 var fiber = nextEffect;
13703 var firstChild = fiber.child;
13704
13705 if ((fiber.subtreeFlags & LayoutMask) !== NoFlags && firstChild !== null) {
13706 ensureCorrectReturnPointer(firstChild, fiber);
13707 nextEffect = firstChild;
13708 } else {
13709 commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes);
13710 }
13711 }
13712 }
13713
13714 function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) {
13715 while (nextEffect !== null) {
13716 var fiber = nextEffect;
13717
13718 if ((fiber.flags & LayoutMask) !== NoFlags) {
13719 var current = fiber.alternate;
13720 setCurrentFiber(fiber);
13721
13722 try {
13723 commitLayoutEffectOnFiber(root, current, fiber, committedLanes);
13724 } catch (error) {
13725 reportUncaughtErrorInDEV(error);
13726 captureCommitPhaseError(fiber, fiber.return, error);
13727 }
13728
13729 resetCurrentFiber();
13730 }
13731
13732 if (fiber === subtreeRoot) {
13733 nextEffect = null;
13734 return;
13735 }
13736
13737 var sibling = fiber.sibling;
13738
13739 if (sibling !== null) {
13740 ensureCorrectReturnPointer(sibling, fiber.return);
13741 nextEffect = sibling;
13742 return;
13743 }
13744
13745 nextEffect = fiber.return;
13746 }
13747 }
13748
13749 function commitPassiveMountEffects(root, finishedWork) {
13750 nextEffect = finishedWork;
13751 commitPassiveMountEffects_begin(finishedWork, root);
13752 }
13753
13754 function commitPassiveMountEffects_begin(subtreeRoot, root) {
13755 while (nextEffect !== null) {
13756 var fiber = nextEffect;
13757 var firstChild = fiber.child;
13758
13759 if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) {
13760 ensureCorrectReturnPointer(firstChild, fiber);
13761 nextEffect = firstChild;
13762 } else {
13763 commitPassiveMountEffects_complete(subtreeRoot, root);
13764 }
13765 }
13766 }
13767
13768 function commitPassiveMountEffects_complete(subtreeRoot, root) {
13769 while (nextEffect !== null) {
13770 var fiber = nextEffect;
13771
13772 if ((fiber.flags & Passive) !== NoFlags) {
13773 setCurrentFiber(fiber);
13774
13775 try {
13776 commitPassiveMountOnFiber(root, fiber);
13777 } catch (error) {
13778 reportUncaughtErrorInDEV(error);
13779 captureCommitPhaseError(fiber, fiber.return, error);
13780 }
13781
13782 resetCurrentFiber();
13783 }
13784
13785 if (fiber === subtreeRoot) {
13786 nextEffect = null;
13787 return;
13788 }
13789
13790 var sibling = fiber.sibling;
13791
13792 if (sibling !== null) {
13793 ensureCorrectReturnPointer(sibling, fiber.return);
13794 nextEffect = sibling;
13795 return;
13796 }
13797
13798 nextEffect = fiber.return;
13799 }
13800 }
13801
13802 function commitPassiveMountOnFiber(finishedRoot, finishedWork) {
13803 switch (finishedWork.tag) {
13804 case FunctionComponent:
13805 case ForwardRef:
13806 case SimpleMemoComponent:
13807 {
13808 if ( finishedWork.mode & ProfileMode) {
13809 startPassiveEffectTimer();
13810
13811 try {
13812 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
13813 } finally {
13814 recordPassiveEffectDuration(finishedWork);
13815 }
13816 } else {
13817 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
13818 }
13819
13820 break;
13821 }
13822 }
13823 }
13824
13825 function commitPassiveUnmountEffects(firstChild) {
13826 nextEffect = firstChild;
13827 commitPassiveUnmountEffects_begin();
13828 }
13829
13830 function commitPassiveUnmountEffects_begin() {
13831 while (nextEffect !== null) {
13832 var fiber = nextEffect;
13833 var child = fiber.child;
13834
13835 if ((nextEffect.flags & ChildDeletion) !== NoFlags) {
13836 var deletions = fiber.deletions;
13837
13838 if (deletions !== null) {
13839 for (var i = 0; i < deletions.length; i++) {
13840 var fiberToDelete = deletions[i];
13841 nextEffect = fiberToDelete;
13842 commitPassiveUnmountEffectsInsideOfDeletedTree_begin(fiberToDelete, fiber);
13843 }
13844
13845 {
13846 // A fiber was deleted from this parent fiber, but it's still part of
13847 // the previous (alternate) parent fiber's list of children. Because
13848 // children are a linked list, an earlier sibling that's still alive
13849 // will be connected to the deleted fiber via its `alternate`:
13850 //
13851 // live fiber
13852 // --alternate--> previous live fiber
13853 // --sibling--> deleted fiber
13854 //
13855 // We can't disconnect `alternate` on nodes that haven't been deleted
13856 // yet, but we can disconnect the `sibling` and `child` pointers.
13857 var previousFiber = fiber.alternate;
13858
13859 if (previousFiber !== null) {
13860 var detachedChild = previousFiber.child;
13861
13862 if (detachedChild !== null) {
13863 previousFiber.child = null;
13864
13865 do {
13866 var detachedSibling = detachedChild.sibling;
13867 detachedChild.sibling = null;
13868 detachedChild = detachedSibling;
13869 } while (detachedChild !== null);
13870 }
13871 }
13872 }
13873
13874 nextEffect = fiber;
13875 }
13876 }
13877
13878 if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) {
13879 ensureCorrectReturnPointer(child, fiber);
13880 nextEffect = child;
13881 } else {
13882 commitPassiveUnmountEffects_complete();
13883 }
13884 }
13885 }
13886
13887 function commitPassiveUnmountEffects_complete() {
13888 while (nextEffect !== null) {
13889 var fiber = nextEffect;
13890
13891 if ((fiber.flags & Passive) !== NoFlags) {
13892 setCurrentFiber(fiber);
13893 commitPassiveUnmountOnFiber(fiber);
13894 resetCurrentFiber();
13895 }
13896
13897 var sibling = fiber.sibling;
13898
13899 if (sibling !== null) {
13900 ensureCorrectReturnPointer(sibling, fiber.return);
13901 nextEffect = sibling;
13902 return;
13903 }
13904
13905 nextEffect = fiber.return;
13906 }
13907 }
13908
13909 function commitPassiveUnmountOnFiber(finishedWork) {
13910 switch (finishedWork.tag) {
13911 case FunctionComponent:
13912 case ForwardRef:
13913 case SimpleMemoComponent:
13914 {
13915 if ( finishedWork.mode & ProfileMode) {
13916 startPassiveEffectTimer();
13917 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork, finishedWork.return);
13918 recordPassiveEffectDuration(finishedWork);
13919 } else {
13920 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork, finishedWork.return);
13921 }
13922
13923 break;
13924 }
13925 }
13926 }
13927
13928 function commitPassiveUnmountEffectsInsideOfDeletedTree_begin(deletedSubtreeRoot, nearestMountedAncestor) {
13929 while (nextEffect !== null) {
13930 var fiber = nextEffect; // Deletion effects fire in parent -> child order
13931 // TODO: Check if fiber has a PassiveStatic flag
13932
13933 setCurrentFiber(fiber);
13934 commitPassiveUnmountInsideDeletedTreeOnFiber(fiber, nearestMountedAncestor);
13935 resetCurrentFiber();
13936 var child = fiber.child; // TODO: Only traverse subtree if it has a PassiveStatic flag. (But, if we
13937 // do this, still need to handle `deletedTreeCleanUpLevel` correctly.)
13938
13939 if (child !== null) {
13940 ensureCorrectReturnPointer(child, fiber);
13941 nextEffect = child;
13942 } else {
13943 commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot);
13944 }
13945 }
13946 }
13947
13948 function commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot) {
13949 while (nextEffect !== null) {
13950 var fiber = nextEffect;
13951 var sibling = fiber.sibling;
13952 var returnFiber = fiber.return;
13953
13954 {
13955 // Recursively traverse the entire deleted tree and clean up fiber fields.
13956 // This is more aggressive than ideal, and the long term goal is to only
13957 // have to detach the deleted tree at the root.
13958 detachFiberAfterEffects(fiber);
13959
13960 if (fiber === deletedSubtreeRoot) {
13961 nextEffect = null;
13962 return;
13963 }
13964 }
13965
13966 if (sibling !== null) {
13967 ensureCorrectReturnPointer(sibling, returnFiber);
13968 nextEffect = sibling;
13969 return;
13970 }
13971
13972 nextEffect = returnFiber;
13973 }
13974 }
13975
13976 function commitPassiveUnmountInsideDeletedTreeOnFiber(current, nearestMountedAncestor) {
13977 switch (current.tag) {
13978 case FunctionComponent:
13979 case ForwardRef:
13980 case SimpleMemoComponent:
13981 {
13982 if ( current.mode & ProfileMode) {
13983 startPassiveEffectTimer();
13984 commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor);
13985 recordPassiveEffectDuration(current);
13986 } else {
13987 commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor);
13988 }
13989
13990 break;
13991 }
13992 }
13993 }
13994
13995 var didWarnWrongReturnPointer = false;
13996
13997 function ensureCorrectReturnPointer(fiber, expectedReturnFiber) {
13998 {
13999 if (!didWarnWrongReturnPointer && fiber.return !== expectedReturnFiber) {
14000 didWarnWrongReturnPointer = true;
14001
14002 error('Internal React error: Return pointer is inconsistent ' + 'with parent.');
14003 }
14004 } // TODO: Remove this assignment once we're confident that it won't break
14005 // anything, by checking the warning logs for the above invariant
14006
14007
14008 fiber.return = expectedReturnFiber;
14009 } // TODO: Reuse reappearLayoutEffects traversal here?
14010
14011 var COMPONENT_TYPE = 0;
14012 var HAS_PSEUDO_CLASS_TYPE = 1;
14013 var ROLE_TYPE = 2;
14014 var TEST_NAME_TYPE = 3;
14015 var TEXT_TYPE = 4;
14016
14017 if (typeof Symbol === 'function' && Symbol.for) {
14018 var symbolFor = Symbol.for;
14019 COMPONENT_TYPE = symbolFor('selector.component');
14020 HAS_PSEUDO_CLASS_TYPE = symbolFor('selector.has_pseudo_class');
14021 ROLE_TYPE = symbolFor('selector.role');
14022 TEST_NAME_TYPE = symbolFor('selector.test_id');
14023 TEXT_TYPE = symbolFor('selector.text');
14024 }
14025
14026 var ReactCurrentActQueue = ReactSharedInternals.ReactCurrentActQueue;
14027 function isLegacyActEnvironment(fiber) {
14028 {
14029 // Legacy mode. We preserve the behavior of React 17's act. It assumes an
14030 // act environment whenever `jest` is defined, but you can still turn off
14031 // spurious warnings by setting IS_REACT_ACT_ENVIRONMENT explicitly
14032 // to false.
14033 var isReactActEnvironmentGlobal = // $FlowExpectedError – Flow doesn't know about IS_REACT_ACT_ENVIRONMENT global
14034 typeof IS_REACT_ACT_ENVIRONMENT !== 'undefined' ? IS_REACT_ACT_ENVIRONMENT : undefined; // $FlowExpectedError - Flow doesn't know about jest
14035
14036 var jestIsDefined = typeof jest !== 'undefined';
14037 return jestIsDefined && isReactActEnvironmentGlobal !== false;
14038 }
14039 }
14040 function isConcurrentActEnvironment() {
14041 {
14042 var isReactActEnvironmentGlobal = // $FlowExpectedError – Flow doesn't know about IS_REACT_ACT_ENVIRONMENT global
14043 typeof IS_REACT_ACT_ENVIRONMENT !== 'undefined' ? IS_REACT_ACT_ENVIRONMENT : undefined;
14044
14045 if (!isReactActEnvironmentGlobal && ReactCurrentActQueue.current !== null) {
14046 // TODO: Include link to relevant documentation page.
14047 error('The current testing environment is not configured to support ' + 'act(...)');
14048 }
14049
14050 return isReactActEnvironmentGlobal;
14051 }
14052 }
14053
14054 var ceil = Math.ceil;
14055 var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher,
14056 ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner,
14057 ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig,
14058 ReactCurrentActQueue$1 = ReactSharedInternals.ReactCurrentActQueue;
14059 var NoContext =
14060 /* */
14061 0;
14062 var BatchedContext =
14063 /* */
14064 1;
14065 var RenderContext =
14066 /* */
14067 2;
14068 var CommitContext =
14069 /* */
14070 4;
14071 var RootInProgress = 0;
14072 var RootFatalErrored = 1;
14073 var RootErrored = 2;
14074 var RootSuspended = 3;
14075 var RootSuspendedWithDelay = 4;
14076 var RootCompleted = 5;
14077 var RootDidNotComplete = 6; // Describes where we are in the React execution stack
14078
14079 var executionContext = NoContext; // The root we're working on
14080
14081 var workInProgressRoot = null; // The fiber we're working on
14082
14083 var workInProgress = null; // The lanes we're rendering
14084
14085 var workInProgressRootRenderLanes = NoLanes; // Stack that allows components to change the render lanes for its subtree
14086 // This is a superset of the lanes we started working on at the root. The only
14087 // case where it's different from `workInProgressRootRenderLanes` is when we
14088 // enter a subtree that is hidden and needs to be unhidden: Suspense and
14089 // Offscreen component.
14090 //
14091 // Most things in the work loop should deal with workInProgressRootRenderLanes.
14092 // Most things in begin/complete phases should deal with subtreeRenderLanes.
14093
14094 var subtreeRenderLanes = NoLanes;
14095 var subtreeRenderLanesCursor = createCursor(NoLanes); // Whether to root completed, errored, suspended, etc.
14096
14097 var workInProgressRootExitStatus = RootInProgress; // A fatal error, if one is thrown
14098
14099 var workInProgressRootFatalError = null; // "Included" lanes refer to lanes that were worked on during this render. It's
14100 // slightly different than `renderLanes` because `renderLanes` can change as you
14101 // enter and exit an Offscreen tree. This value is the combination of all render
14102 // lanes for the entire render phase.
14103
14104 var workInProgressRootIncludedLanes = NoLanes; // The work left over by components that were visited during this render. Only
14105 // includes unprocessed updates, not work in bailed out children.
14106
14107 var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an interleaved event) during this render.
14108
14109 var workInProgressRootInterleavedUpdatedLanes = NoLanes; // Lanes that were updated during the render phase (*not* an interleaved event).
14110
14111 var workInProgressRootPingedLanes = NoLanes; // Errors that are thrown during the render phase.
14112
14113 var workInProgressRootConcurrentErrors = null; // These are errors that we recovered from without surfacing them to the UI.
14114 // We will log them once the tree commits.
14115
14116 var workInProgressRootRecoverableErrors = null; // The most recent time we committed a fallback. This lets us ensure a train
14117 // model where we don't commit new loading states in too quick succession.
14118
14119 var globalMostRecentFallbackTime = 0;
14120 var FALLBACK_THROTTLE_MS = 500; // The absolute time for when we should start giving up on rendering
14121 // more and prefer CPU suspense heuristics instead.
14122
14123 var workInProgressRootRenderTargetTime = Infinity; // How long a render is supposed to take before we start following CPU
14124 // suspense heuristics and opt out of rendering more content.
14125
14126 var RENDER_TIMEOUT_MS = 500;
14127
14128 function resetRenderTimer() {
14129 workInProgressRootRenderTargetTime = now() + RENDER_TIMEOUT_MS;
14130 }
14131
14132 function getRenderTargetTime() {
14133 return workInProgressRootRenderTargetTime;
14134 }
14135 var hasUncaughtError = false;
14136 var firstUncaughtError = null;
14137 var legacyErrorBoundariesThatAlreadyFailed = null; // Only used when enableProfilerNestedUpdateScheduledHook is true;
14138 var rootDoesHavePassiveEffects = false;
14139 var rootWithPendingPassiveEffects = null;
14140 var pendingPassiveEffectsLanes = NoLanes;
14141 var pendingPassiveProfilerEffects = [];
14142
14143 var NESTED_UPDATE_LIMIT = 50;
14144 var nestedUpdateCount = 0;
14145 var rootWithNestedUpdates = null;
14146 var NESTED_PASSIVE_UPDATE_LIMIT = 50;
14147 var nestedPassiveUpdateCount = 0; // If two updates are scheduled within the same event, we should treat their
14148 // event times as simultaneous, even if the actual clock time has advanced
14149 // between the first and second call.
14150
14151 var currentEventTime = NoTimestamp;
14152 var currentEventTransitionLane = NoLanes;
14153 function getWorkInProgressRoot() {
14154 return workInProgressRoot;
14155 }
14156 function requestEventTime() {
14157 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
14158 // We're inside React, so it's fine to read the actual time.
14159 return now();
14160 } // We're not inside React, so we may be in the middle of a browser event.
14161
14162
14163 if (currentEventTime !== NoTimestamp) {
14164 // Use the same start time for all updates until we enter React again.
14165 return currentEventTime;
14166 } // This is the first update since React yielded. Compute a new start time.
14167
14168
14169 currentEventTime = now();
14170 return currentEventTime;
14171 }
14172 function requestUpdateLane(fiber) {
14173 // Special cases
14174 var mode = fiber.mode;
14175
14176 if ((mode & ConcurrentMode) === NoMode) {
14177 return SyncLane;
14178 } else if ( (executionContext & RenderContext) !== NoContext && workInProgressRootRenderLanes !== NoLanes) {
14179 // This is a render phase update. These are not officially supported. The
14180 // old behavior is to give this the same "thread" (lanes) as
14181 // whatever is currently rendering. So if you call `setState` on a component
14182 // that happens later in the same render, it will flush. Ideally, we want to
14183 // remove the special case and treat them as if they came from an
14184 // interleaved event. Regardless, this pattern is not officially supported.
14185 // This behavior is only a fallback. The flag only exists until we can roll
14186 // out the setState warning, since existing code might accidentally rely on
14187 // the current behavior.
14188 return pickArbitraryLane(workInProgressRootRenderLanes);
14189 }
14190
14191 var isTransition = requestCurrentTransition() !== NoTransition;
14192
14193 if (isTransition) {
14194 if ( ReactCurrentBatchConfig$2.transition !== null) {
14195 var transition = ReactCurrentBatchConfig$2.transition;
14196
14197 if (!transition._updatedFibers) {
14198 transition._updatedFibers = new Set();
14199 }
14200
14201 transition._updatedFibers.add(fiber);
14202 } // The algorithm for assigning an update to a lane should be stable for all
14203 // updates at the same priority within the same event. To do this, the
14204 // inputs to the algorithm must be the same.
14205 //
14206 // The trick we use is to cache the first of each of these inputs within an
14207 // event. Then reset the cached values once we can be sure the event is
14208 // over. Our heuristic for that is whenever we enter a concurrent work loop.
14209
14210
14211 if (currentEventTransitionLane === NoLane) {
14212 // All transitions within the same event are assigned the same lane.
14213 currentEventTransitionLane = claimNextTransitionLane();
14214 }
14215
14216 return currentEventTransitionLane;
14217 } // Updates originating inside certain React methods, like flushSync, have
14218 // their priority set by tracking it with a context variable.
14219 //
14220 // The opaque type returned by the host config is internally a lane, so we can
14221 // use that directly.
14222 // TODO: Move this type conversion to the event priority module.
14223
14224
14225 var updateLane = getCurrentUpdatePriority();
14226
14227 if (updateLane !== NoLane) {
14228 return updateLane;
14229 } // This update originated outside React. Ask the host environment for an
14230 // appropriate priority, based on the type of event.
14231 //
14232 // The opaque type returned by the host config is internally a lane, so we can
14233 // use that directly.
14234 // TODO: Move this type conversion to the event priority module.
14235
14236
14237 var eventLane = getCurrentEventPriority();
14238 return eventLane;
14239 }
14240
14241 function requestRetryLane(fiber) {
14242 // This is a fork of `requestUpdateLane` designed specifically for Suspense
14243 // "retries" — a special update that attempts to flip a Suspense boundary
14244 // from its placeholder state to its primary/resolved state.
14245 // Special cases
14246 var mode = fiber.mode;
14247
14248 if ((mode & ConcurrentMode) === NoMode) {
14249 return SyncLane;
14250 }
14251
14252 return claimNextRetryLane();
14253 }
14254
14255 function scheduleUpdateOnFiber(fiber, lane, eventTime) {
14256 checkForNestedUpdates();
14257 var root = markUpdateLaneFromFiberToRoot(fiber, lane);
14258
14259 if (root === null) {
14260 return null;
14261 } // Mark that the root has a pending update.
14262
14263
14264 markRootUpdated(root, lane, eventTime);
14265
14266 if ((executionContext & RenderContext) !== NoLanes && root === workInProgressRoot) {
14267 // This update was dispatched during the render phase. This is a mistake
14268 // if the update originates from user space (with the exception of local
14269 // hook updates, which are handled differently and don't reach this
14270 // function), but there are some internal React features that use this as
14271 // an implementation detail, like selective hydration.
14272 warnAboutRenderPhaseUpdatesInDEV(fiber); // Track lanes that were updated during the render phase
14273 } else {
14274
14275 warnIfUpdatesNotWrappedWithActDEV(fiber);
14276
14277 if (root === workInProgressRoot) {
14278 // TODO: Consolidate with `isInterleavedUpdate` check
14279 // Received an update to a tree that's in the middle of rendering. Mark
14280 // that there was an interleaved update work on this root. Unless the
14281 // `deferRenderPhaseUpdateToNextBatch` flag is off and this is a render
14282 // phase update. In that case, we don't treat render phase updates as if
14283 // they were interleaved, for backwards compat reasons.
14284 if ( (executionContext & RenderContext) === NoContext) {
14285 workInProgressRootInterleavedUpdatedLanes = mergeLanes(workInProgressRootInterleavedUpdatedLanes, lane);
14286 }
14287
14288 if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
14289 // The root already suspended with a delay, which means this render
14290 // definitely won't finish. Since we have a new update, let's mark it as
14291 // suspended now, right before marking the incoming update. This has the
14292 // effect of interrupting the current render and switching to the update.
14293 // TODO: Make sure this doesn't override pings that happen while we've
14294 // already started rendering.
14295 markRootSuspended$1(root, workInProgressRootRenderLanes);
14296 }
14297 }
14298
14299 ensureRootIsScheduled(root, eventTime);
14300
14301 if (lane === SyncLane && executionContext === NoContext && (fiber.mode & ConcurrentMode) === NoMode && // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode.
14302 !( ReactCurrentActQueue$1.isBatchingLegacy)) {
14303 // Flush the synchronous work now, unless we're already working or inside
14304 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
14305 // scheduleCallbackForFiber to preserve the ability to schedule a callback
14306 // without immediately flushing it. We only do this for user-initiated
14307 // updates, to preserve historical behavior of legacy mode.
14308 resetRenderTimer();
14309 flushSyncCallbacksOnlyInLegacyMode();
14310 }
14311 }
14312
14313 return root;
14314 }
14315 // work without treating it as a typical update that originates from an event;
14316 // e.g. retrying a Suspense boundary isn't an update, but it does schedule work
14317 // on a fiber.
14318
14319 function markUpdateLaneFromFiberToRoot(sourceFiber, lane) {
14320 // Update the source fiber's lanes
14321 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, lane);
14322 var alternate = sourceFiber.alternate;
14323
14324 if (alternate !== null) {
14325 alternate.lanes = mergeLanes(alternate.lanes, lane);
14326 }
14327
14328 {
14329 if (alternate === null && (sourceFiber.flags & (Placement | Hydrating)) !== NoFlags) {
14330 warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);
14331 }
14332 } // Walk the parent path to the root and update the child lanes.
14333
14334
14335 var node = sourceFiber;
14336 var parent = sourceFiber.return;
14337
14338 while (parent !== null) {
14339 parent.childLanes = mergeLanes(parent.childLanes, lane);
14340 alternate = parent.alternate;
14341
14342 if (alternate !== null) {
14343 alternate.childLanes = mergeLanes(alternate.childLanes, lane);
14344 } else {
14345 {
14346 if ((parent.flags & (Placement | Hydrating)) !== NoFlags) {
14347 warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);
14348 }
14349 }
14350 }
14351
14352 node = parent;
14353 parent = parent.return;
14354 }
14355
14356 if (node.tag === HostRoot) {
14357 var root = node.stateNode;
14358 return root;
14359 } else {
14360 return null;
14361 }
14362 }
14363
14364 function isInterleavedUpdate(fiber, lane) {
14365 return (// TODO: Optimize slightly by comparing to root that fiber belongs to.
14366 // Requires some refactoring. Not a big deal though since it's rare for
14367 // concurrent apps to have more than a single root.
14368 workInProgressRoot !== null && (fiber.mode & ConcurrentMode) !== NoMode && ( // If this is a render phase update (i.e. UNSAFE_componentWillReceiveProps),
14369 // then don't treat this as an interleaved update. This pattern is
14370 // accompanied by a warning but we haven't fully deprecated it yet. We can
14371 // remove once the deferRenderPhaseUpdateToNextBatch flag is enabled.
14372 (executionContext & RenderContext) === NoContext)
14373 );
14374 } // Use this function to schedule a task for a root. There's only one task per
14375 // root; if a task was already scheduled, we'll check to make sure the priority
14376 // of the existing task is the same as the priority of the next level that the
14377 // root has work on. This function is called on every update, and right before
14378 // exiting a task.
14379
14380 function ensureRootIsScheduled(root, currentTime) {
14381 var existingCallbackNode = root.callbackNode; // Check if any lanes are being starved by other work. If so, mark them as
14382 // expired so we know to work on those next.
14383
14384 markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority.
14385
14386 var nextLanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
14387
14388 if (nextLanes === NoLanes) {
14389 // Special case: There's nothing to work on.
14390 if (existingCallbackNode !== null) {
14391 cancelCallback$1(existingCallbackNode);
14392 }
14393
14394 root.callbackNode = null;
14395 root.callbackPriority = NoLane;
14396 return;
14397 } // We use the highest priority lane to represent the priority of the callback.
14398
14399
14400 var newCallbackPriority = getHighestPriorityLane(nextLanes); // Check if there's an existing task. We may be able to reuse it.
14401
14402 var existingCallbackPriority = root.callbackPriority;
14403
14404 if (existingCallbackPriority === newCallbackPriority && // Special case related to `act`. If the currently scheduled task is a
14405 // Scheduler task, rather than an `act` task, cancel it and re-scheduled
14406 // on the `act` queue.
14407 !( ReactCurrentActQueue$1.current !== null && existingCallbackNode !== fakeActCallbackNode)) {
14408 {
14409 // If we're going to re-use an existing task, it needs to exist.
14410 // Assume that discrete update microtasks are non-cancellable and null.
14411 // TODO: Temporary until we confirm this warning is not fired.
14412 if (existingCallbackNode == null && existingCallbackPriority !== SyncLane) {
14413 error('Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue.');
14414 }
14415 } // The priority hasn't changed. We can reuse the existing task. Exit.
14416
14417
14418 return;
14419 }
14420
14421 if (existingCallbackNode != null) {
14422 // Cancel the existing callback. We'll schedule a new one below.
14423 cancelCallback$1(existingCallbackNode);
14424 } // Schedule a new callback.
14425
14426
14427 var newCallbackNode;
14428
14429 if (newCallbackPriority === SyncLane) {
14430 // Special case: Sync React callbacks are scheduled on a special
14431 // internal queue
14432 if (root.tag === LegacyRoot) {
14433 if ( ReactCurrentActQueue$1.isBatchingLegacy !== null) {
14434 ReactCurrentActQueue$1.didScheduleLegacyUpdate = true;
14435 }
14436
14437 scheduleLegacySyncCallback(performSyncWorkOnRoot.bind(null, root));
14438 } else {
14439 scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
14440 }
14441
14442 {
14443 // Flush the queue in an Immediate task.
14444 scheduleCallback$1(ImmediatePriority, flushSyncCallbacks);
14445 }
14446
14447 newCallbackNode = null;
14448 } else {
14449 var schedulerPriorityLevel;
14450
14451 switch (lanesToEventPriority(nextLanes)) {
14452 case DiscreteEventPriority:
14453 schedulerPriorityLevel = ImmediatePriority;
14454 break;
14455
14456 case ContinuousEventPriority:
14457 schedulerPriorityLevel = UserBlockingPriority;
14458 break;
14459
14460 case DefaultEventPriority:
14461 schedulerPriorityLevel = NormalPriority;
14462 break;
14463
14464 case IdleEventPriority:
14465 schedulerPriorityLevel = IdlePriority;
14466 break;
14467
14468 default:
14469 schedulerPriorityLevel = NormalPriority;
14470 break;
14471 }
14472
14473 newCallbackNode = scheduleCallback$1(schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root));
14474 }
14475
14476 root.callbackPriority = newCallbackPriority;
14477 root.callbackNode = newCallbackNode;
14478 } // This is the entry point for every concurrent task, i.e. anything that
14479 // goes through Scheduler.
14480
14481
14482 function performConcurrentWorkOnRoot(root, didTimeout) {
14483 {
14484 resetNestedUpdateFlag();
14485 } // Since we know we're in a React event, we can clear the current
14486 // event time. The next update will compute a new event time.
14487
14488
14489 currentEventTime = NoTimestamp;
14490 currentEventTransitionLane = NoLanes;
14491
14492 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
14493 throw new Error('Should not already be working.');
14494 } // Flush any pending passive effects before deciding which lanes to work on,
14495 // in case they schedule additional work.
14496
14497
14498 var originalCallbackNode = root.callbackNode;
14499 var didFlushPassiveEffects = flushPassiveEffects();
14500
14501 if (didFlushPassiveEffects) {
14502 // Something in the passive effect phase may have canceled the current task.
14503 // Check if the task node for this root was changed.
14504 if (root.callbackNode !== originalCallbackNode) {
14505 // The current task was canceled. Exit. We don't need to call
14506 // `ensureRootIsScheduled` because the check above implies either that
14507 // there's a new task, or that there's no remaining work on this root.
14508 return null;
14509 }
14510 } // Determine the next lanes to work on, using the fields stored
14511 // on the root.
14512
14513
14514 var lanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
14515
14516 if (lanes === NoLanes) {
14517 // Defensive coding. This is never expected to happen.
14518 return null;
14519 } // We disable time-slicing in some cases: if the work has been CPU-bound
14520 // for too long ("expired" work, to prevent starvation), or we're in
14521 // sync-updates-by-default mode.
14522 // TODO: We only check `didTimeout` defensively, to account for a Scheduler
14523 // bug we're still investigating. Once the bug in Scheduler is fixed,
14524 // we can remove this, since we track expiration ourselves.
14525
14526
14527 var shouldTimeSlice = !includesBlockingLane(root, lanes) && !includesExpiredLane(root, lanes) && ( !didTimeout);
14528 var exitStatus = shouldTimeSlice ? renderRootConcurrent(root, lanes) : renderRootSync(root, lanes);
14529
14530 if (exitStatus !== RootInProgress) {
14531 if (exitStatus === RootErrored) {
14532 // If something threw an error, try rendering one more time. We'll
14533 // render synchronously to block concurrent data mutations, and we'll
14534 // includes all pending updates are included. If it still fails after
14535 // the second attempt, we'll give up and commit the resulting tree.
14536 var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
14537
14538 if (errorRetryLanes !== NoLanes) {
14539 lanes = errorRetryLanes;
14540 exitStatus = recoverFromConcurrentError(root, errorRetryLanes);
14541 }
14542 }
14543
14544 if (exitStatus === RootFatalErrored) {
14545 var fatalError = workInProgressRootFatalError;
14546 prepareFreshStack(root, NoLanes);
14547 markRootSuspended$1(root, lanes);
14548 ensureRootIsScheduled(root, now());
14549 throw fatalError;
14550 }
14551
14552 if (exitStatus === RootDidNotComplete) {
14553 // The render unwound without completing the tree. This happens in special
14554 // cases where need to exit the current render without producing a
14555 // consistent tree or committing.
14556 //
14557 // This should only happen during a concurrent render, not a discrete or
14558 // synchronous update. We should have already checked for this when we
14559 // unwound the stack.
14560 markRootSuspended$1(root, lanes);
14561 } else {
14562 // The render completed.
14563 // Check if this render may have yielded to a concurrent event, and if so,
14564 // confirm that any newly rendered stores are consistent.
14565 // TODO: It's possible that even a concurrent render may never have yielded
14566 // to the main thread, if it was fast enough, or if it expired. We could
14567 // skip the consistency check in that case, too.
14568 var renderWasConcurrent = !includesBlockingLane(root, lanes);
14569 var finishedWork = root.current.alternate;
14570
14571 if (renderWasConcurrent && !isRenderConsistentWithExternalStores(finishedWork)) {
14572 // A store was mutated in an interleaved event. Render again,
14573 // synchronously, to block further mutations.
14574 exitStatus = renderRootSync(root, lanes); // We need to check again if something threw
14575
14576 if (exitStatus === RootErrored) {
14577 var _errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
14578
14579 if (_errorRetryLanes !== NoLanes) {
14580 lanes = _errorRetryLanes;
14581 exitStatus = recoverFromConcurrentError(root, _errorRetryLanes); // We assume the tree is now consistent because we didn't yield to any
14582 // concurrent events.
14583 }
14584 }
14585
14586 if (exitStatus === RootFatalErrored) {
14587 var _fatalError = workInProgressRootFatalError;
14588 prepareFreshStack(root, NoLanes);
14589 markRootSuspended$1(root, lanes);
14590 ensureRootIsScheduled(root, now());
14591 throw _fatalError;
14592 }
14593 } // We now have a consistent tree. The next step is either to commit it,
14594 // or, if something suspended, wait to commit it after a timeout.
14595
14596
14597 root.finishedWork = finishedWork;
14598 root.finishedLanes = lanes;
14599 finishConcurrentRender(root, exitStatus, lanes);
14600 }
14601 }
14602
14603 ensureRootIsScheduled(root, now());
14604
14605 if (root.callbackNode === originalCallbackNode) {
14606 // The task node scheduled for this root is the same one that's
14607 // currently executed. Need to return a continuation.
14608 return performConcurrentWorkOnRoot.bind(null, root);
14609 }
14610
14611 return null;
14612 }
14613
14614 function recoverFromConcurrentError(root, errorRetryLanes) {
14615 // If an error occurred during hydration, discard server response and fall
14616 // back to client side render.
14617 // Before rendering again, save the errors from the previous attempt.
14618 var errorsFromFirstAttempt = workInProgressRootConcurrentErrors;
14619
14620 if (isRootDehydrated(root)) {
14621 // The shell failed to hydrate. Set a flag to force a client rendering
14622 // during the next attempt. To do this, we call prepareFreshStack now
14623 // to create the root work-in-progress fiber. This is a bit weird in terms
14624 // of factoring, because it relies on renderRootSync not calling
14625 // prepareFreshStack again in the call below, which happens because the
14626 // root and lanes haven't changed.
14627 //
14628 // TODO: I think what we should do is set ForceClientRender inside
14629 // throwException, like we do for nested Suspense boundaries. The reason
14630 // it's here instead is so we can switch to the synchronous work loop, too.
14631 // Something to consider for a future refactor.
14632 var rootWorkInProgress = prepareFreshStack(root, errorRetryLanes);
14633 rootWorkInProgress.flags |= ForceClientRender;
14634
14635 {
14636 errorHydratingContainer(root.containerInfo);
14637 }
14638 }
14639
14640 var exitStatus = renderRootSync(root, errorRetryLanes);
14641
14642 if (exitStatus !== RootErrored) {
14643 // Successfully finished rendering on retry
14644 // The errors from the failed first attempt have been recovered. Add
14645 // them to the collection of recoverable errors. We'll log them in the
14646 // commit phase.
14647 var errorsFromSecondAttempt = workInProgressRootRecoverableErrors;
14648 workInProgressRootRecoverableErrors = errorsFromFirstAttempt; // The errors from the second attempt should be queued after the errors
14649 // from the first attempt, to preserve the causal sequence.
14650
14651 if (errorsFromSecondAttempt !== null) {
14652 queueRecoverableErrors(errorsFromSecondAttempt);
14653 }
14654 }
14655
14656 return exitStatus;
14657 }
14658
14659 function queueRecoverableErrors(errors) {
14660 if (workInProgressRootRecoverableErrors === null) {
14661 workInProgressRootRecoverableErrors = errors;
14662 } else {
14663 workInProgressRootRecoverableErrors.push.apply(workInProgressRootRecoverableErrors, errors);
14664 }
14665 }
14666
14667 function finishConcurrentRender(root, exitStatus, lanes) {
14668 switch (exitStatus) {
14669 case RootInProgress:
14670 case RootFatalErrored:
14671 {
14672 throw new Error('Root did not complete. This is a bug in React.');
14673 }
14674 // Flow knows about invariant, so it complains if I add a break
14675 // statement, but eslint doesn't know about invariant, so it complains
14676 // if I do. eslint-disable-next-line no-fallthrough
14677
14678 case RootErrored:
14679 {
14680 // We should have already attempted to retry this tree. If we reached
14681 // this point, it errored again. Commit it.
14682 commitRoot(root, workInProgressRootRecoverableErrors);
14683 break;
14684 }
14685
14686 case RootSuspended:
14687 {
14688 markRootSuspended$1(root, lanes); // We have an acceptable loading state. We need to figure out if we
14689 // should immediately commit it or wait a bit.
14690
14691 if (includesOnlyRetries(lanes) && // do not delay if we're inside an act() scope
14692 !shouldForceFlushFallbacksInDEV()) {
14693 // This render only included retries, no updates. Throttle committing
14694 // retries so that we don't show too many loading states too quickly.
14695 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.
14696
14697 if (msUntilTimeout > 10) {
14698 var nextLanes = getNextLanes(root, NoLanes);
14699
14700 if (nextLanes !== NoLanes) {
14701 // There's additional work on this root.
14702 break;
14703 }
14704
14705 var suspendedLanes = root.suspendedLanes;
14706
14707 if (!isSubsetOfLanes(suspendedLanes, lanes)) {
14708 // We should prefer to render the fallback of at the last
14709 // suspended level. Ping the last suspended level to try
14710 // rendering it again.
14711 // FIXME: What if the suspended lanes are Idle? Should not restart.
14712 var eventTime = requestEventTime();
14713 markRootPinged(root, suspendedLanes);
14714 break;
14715 } // The render is suspended, it hasn't timed out, and there's no
14716 // lower priority work to do. Instead of committing the fallback
14717 // immediately, wait for more data to arrive.
14718
14719
14720 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root, workInProgressRootRecoverableErrors), msUntilTimeout);
14721 break;
14722 }
14723 } // The work expired. Commit immediately.
14724
14725
14726 commitRoot(root, workInProgressRootRecoverableErrors);
14727 break;
14728 }
14729
14730 case RootSuspendedWithDelay:
14731 {
14732 markRootSuspended$1(root, lanes);
14733
14734 if (includesOnlyTransitions(lanes)) {
14735 // This is a transition, so we should exit without committing a
14736 // placeholder and without scheduling a timeout. Delay indefinitely
14737 // until we receive more data.
14738 break;
14739 }
14740
14741 if (!shouldForceFlushFallbacksInDEV()) {
14742 // This is not a transition, but we did trigger an avoided state.
14743 // Schedule a placeholder to display after a short delay, using the Just
14744 // Noticeable Difference.
14745 // TODO: Is the JND optimization worth the added complexity? If this is
14746 // the only reason we track the event time, then probably not.
14747 // Consider removing.
14748 var mostRecentEventTime = getMostRecentEventTime(root, lanes);
14749 var eventTimeMs = mostRecentEventTime;
14750 var timeElapsedMs = now() - eventTimeMs;
14751
14752 var _msUntilTimeout = jnd(timeElapsedMs) - timeElapsedMs; // Don't bother with a very short suspense time.
14753
14754
14755 if (_msUntilTimeout > 10) {
14756 // Instead of committing the fallback immediately, wait for more data
14757 // to arrive.
14758 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root, workInProgressRootRecoverableErrors), _msUntilTimeout);
14759 break;
14760 }
14761 } // Commit the placeholder.
14762
14763
14764 commitRoot(root, workInProgressRootRecoverableErrors);
14765 break;
14766 }
14767
14768 case RootCompleted:
14769 {
14770 // The work completed. Ready to commit.
14771 commitRoot(root, workInProgressRootRecoverableErrors);
14772 break;
14773 }
14774
14775 default:
14776 {
14777 throw new Error('Unknown root exit status.');
14778 }
14779 }
14780 }
14781
14782 function isRenderConsistentWithExternalStores(finishedWork) {
14783 // Search the rendered tree for external store reads, and check whether the
14784 // stores were mutated in a concurrent event. Intentionally using an iterative
14785 // loop instead of recursion so we can exit early.
14786 var node = finishedWork;
14787
14788 while (true) {
14789 if (node.flags & StoreConsistency) {
14790 var updateQueue = node.updateQueue;
14791
14792 if (updateQueue !== null) {
14793 var checks = updateQueue.stores;
14794
14795 if (checks !== null) {
14796 for (var i = 0; i < checks.length; i++) {
14797 var check = checks[i];
14798 var getSnapshot = check.getSnapshot;
14799 var renderedValue = check.value;
14800
14801 try {
14802 if (!objectIs(getSnapshot(), renderedValue)) {
14803 // Found an inconsistent store.
14804 return false;
14805 }
14806 } catch (error) {
14807 // If `getSnapshot` throws, return `false`. This will schedule
14808 // a re-render, and the error will be rethrown during render.
14809 return false;
14810 }
14811 }
14812 }
14813 }
14814 }
14815
14816 var child = node.child;
14817
14818 if (node.subtreeFlags & StoreConsistency && child !== null) {
14819 child.return = node;
14820 node = child;
14821 continue;
14822 }
14823
14824 if (node === finishedWork) {
14825 return true;
14826 }
14827
14828 while (node.sibling === null) {
14829 if (node.return === null || node.return === finishedWork) {
14830 return true;
14831 }
14832
14833 node = node.return;
14834 }
14835
14836 node.sibling.return = node.return;
14837 node = node.sibling;
14838 } // Flow doesn't know this is unreachable, but eslint does
14839 // eslint-disable-next-line no-unreachable
14840
14841
14842 return true;
14843 }
14844
14845 function markRootSuspended$1(root, suspendedLanes) {
14846 // When suspending, we should always exclude lanes that were pinged or (more
14847 // rarely, since we try to avoid it) updated during the render phase.
14848 // TODO: Lol maybe there's a better way to factor this besides this
14849 // obnoxiously named function :)
14850 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootPingedLanes);
14851 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootInterleavedUpdatedLanes);
14852 markRootSuspended(root, suspendedLanes);
14853 } // This is the entry point for synchronous tasks that don't go
14854 // through Scheduler
14855
14856
14857 function performSyncWorkOnRoot(root) {
14858 {
14859 syncNestedUpdateFlag();
14860 }
14861
14862 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
14863 throw new Error('Should not already be working.');
14864 }
14865
14866 flushPassiveEffects();
14867 var lanes = getNextLanes(root, NoLanes);
14868
14869 if (!includesSomeLane(lanes, SyncLane)) {
14870 // There's no remaining sync work left.
14871 ensureRootIsScheduled(root, now());
14872 return null;
14873 }
14874
14875 var exitStatus = renderRootSync(root, lanes);
14876
14877 if (root.tag !== LegacyRoot && exitStatus === RootErrored) {
14878 // If something threw an error, try rendering one more time. We'll render
14879 // synchronously to block concurrent data mutations, and we'll includes
14880 // all pending updates are included. If it still fails after the second
14881 // attempt, we'll give up and commit the resulting tree.
14882 var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
14883
14884 if (errorRetryLanes !== NoLanes) {
14885 lanes = errorRetryLanes;
14886 exitStatus = recoverFromConcurrentError(root, errorRetryLanes);
14887 }
14888 }
14889
14890 if (exitStatus === RootFatalErrored) {
14891 var fatalError = workInProgressRootFatalError;
14892 prepareFreshStack(root, NoLanes);
14893 markRootSuspended$1(root, lanes);
14894 ensureRootIsScheduled(root, now());
14895 throw fatalError;
14896 }
14897
14898 if (exitStatus === RootDidNotComplete) {
14899 throw new Error('Root did not complete. This is a bug in React.');
14900 } // We now have a consistent tree. Because this is a sync render, we
14901 // will commit it even if something suspended.
14902
14903
14904 var finishedWork = root.current.alternate;
14905 root.finishedWork = finishedWork;
14906 root.finishedLanes = lanes;
14907 commitRoot(root, workInProgressRootRecoverableErrors); // Before exiting, make sure there's a callback scheduled for the next
14908 // pending level.
14909
14910 ensureRootIsScheduled(root, now());
14911 return null;
14912 }
14913 function batchedUpdates(fn, a) {
14914 var prevExecutionContext = executionContext;
14915 executionContext |= BatchedContext;
14916
14917 try {
14918 return fn(a);
14919 } finally {
14920 executionContext = prevExecutionContext; // If there were legacy sync updates, flush them at the end of the outer
14921 // most batchedUpdates-like method.
14922
14923 if (executionContext === NoContext && // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode.
14924 !( ReactCurrentActQueue$1.isBatchingLegacy)) {
14925 resetRenderTimer();
14926 flushSyncCallbacksOnlyInLegacyMode();
14927 }
14928 }
14929 }
14930 // Warning, this opts-out of checking the function body.
14931
14932 // eslint-disable-next-line no-redeclare
14933 function flushSync(fn) {
14934 // In legacy mode, we flush pending passive effects at the beginning of the
14935 // next event, not at the end of the previous one.
14936 if (rootWithPendingPassiveEffects !== null && rootWithPendingPassiveEffects.tag === LegacyRoot && (executionContext & (RenderContext | CommitContext)) === NoContext) {
14937 flushPassiveEffects();
14938 }
14939
14940 var prevExecutionContext = executionContext;
14941 executionContext |= BatchedContext;
14942 var prevTransition = ReactCurrentBatchConfig$2.transition;
14943 var previousPriority = getCurrentUpdatePriority();
14944
14945 try {
14946 ReactCurrentBatchConfig$2.transition = null;
14947 setCurrentUpdatePriority(DiscreteEventPriority);
14948
14949 if (fn) {
14950 return fn();
14951 } else {
14952 return undefined;
14953 }
14954 } finally {
14955 setCurrentUpdatePriority(previousPriority);
14956 ReactCurrentBatchConfig$2.transition = prevTransition;
14957 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
14958 // Note that this will happen even if batchedUpdates is higher up
14959 // the stack.
14960
14961 if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
14962 flushSyncCallbacks();
14963 }
14964 }
14965 }
14966 function pushRenderLanes(fiber, lanes) {
14967 push(subtreeRenderLanesCursor, subtreeRenderLanes, fiber);
14968 subtreeRenderLanes = mergeLanes(subtreeRenderLanes, lanes);
14969 workInProgressRootIncludedLanes = mergeLanes(workInProgressRootIncludedLanes, lanes);
14970 }
14971 function popRenderLanes(fiber) {
14972 subtreeRenderLanes = subtreeRenderLanesCursor.current;
14973 pop(subtreeRenderLanesCursor, fiber);
14974 }
14975
14976 function prepareFreshStack(root, lanes) {
14977 root.finishedWork = null;
14978 root.finishedLanes = NoLanes;
14979 var timeoutHandle = root.timeoutHandle;
14980
14981 if (timeoutHandle !== noTimeout) {
14982 // The root previous suspended and scheduled a timeout to commit a fallback
14983 // state. Now that we have additional work, cancel the timeout.
14984 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
14985
14986 cancelTimeout(timeoutHandle);
14987 }
14988
14989 if (workInProgress !== null) {
14990 var interruptedWork = workInProgress.return;
14991
14992 while (interruptedWork !== null) {
14993 var current = interruptedWork.alternate;
14994 unwindInterruptedWork(current, interruptedWork);
14995 interruptedWork = interruptedWork.return;
14996 }
14997 }
14998
14999 workInProgressRoot = root;
15000 var rootWorkInProgress = createWorkInProgress(root.current, null);
15001 workInProgress = rootWorkInProgress;
15002 workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes;
15003 workInProgressRootExitStatus = RootInProgress;
15004 workInProgressRootFatalError = null;
15005 workInProgressRootSkippedLanes = NoLanes;
15006 workInProgressRootInterleavedUpdatedLanes = NoLanes;
15007 workInProgressRootPingedLanes = NoLanes;
15008 workInProgressRootConcurrentErrors = null;
15009 workInProgressRootRecoverableErrors = null;
15010 enqueueInterleavedUpdates();
15011
15012 {
15013 ReactStrictModeWarnings.discardPendingWarnings();
15014 }
15015
15016 return rootWorkInProgress;
15017 }
15018
15019 function handleError(root, thrownValue) {
15020 do {
15021 var erroredWork = workInProgress;
15022
15023 try {
15024 // Reset module-level state that was set during the render phase.
15025 resetContextDependencies();
15026 resetHooksAfterThrow();
15027 resetCurrentFiber(); // TODO: I found and added this missing line while investigating a
15028 // separate issue. Write a regression test using string refs.
15029
15030 ReactCurrentOwner$2.current = null;
15031
15032 if (erroredWork === null || erroredWork.return === null) {
15033 // Expected to be working on a non-root fiber. This is a fatal error
15034 // because there's no ancestor that can handle it; the root is
15035 // supposed to capture all errors that weren't caught by an error
15036 // boundary.
15037 workInProgressRootExitStatus = RootFatalErrored;
15038 workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next
15039 // sibling, or the parent if there are no siblings. But since the root
15040 // has no siblings nor a parent, we set it to null. Usually this is
15041 // handled by `completeUnitOfWork` or `unwindWork`, but since we're
15042 // intentionally not calling those, we need set it here.
15043 // TODO: Consider calling `unwindWork` to pop the contexts.
15044
15045 workInProgress = null;
15046 return;
15047 }
15048
15049 if (enableProfilerTimer && erroredWork.mode & ProfileMode) {
15050 // Record the time spent rendering before an error was thrown. This
15051 // avoids inaccurate Profiler durations in the case of a
15052 // suspended render.
15053 stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true);
15054 }
15055
15056 if (enableSchedulingProfiler) {
15057 markComponentRenderStopped();
15058
15059 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') {
15060 var wakeable = thrownValue;
15061 markComponentSuspended(erroredWork, wakeable, workInProgressRootRenderLanes);
15062 } else {
15063 markComponentErrored(erroredWork, thrownValue, workInProgressRootRenderLanes);
15064 }
15065 }
15066
15067 throwException(root, erroredWork.return, erroredWork, thrownValue, workInProgressRootRenderLanes);
15068 completeUnitOfWork(erroredWork);
15069 } catch (yetAnotherThrownValue) {
15070 // Something in the return path also threw.
15071 thrownValue = yetAnotherThrownValue;
15072
15073 if (workInProgress === erroredWork && erroredWork !== null) {
15074 // If this boundary has already errored, then we had trouble processing
15075 // the error. Bubble it to the next boundary.
15076 erroredWork = erroredWork.return;
15077 workInProgress = erroredWork;
15078 } else {
15079 erroredWork = workInProgress;
15080 }
15081
15082 continue;
15083 } // Return to the normal work loop.
15084
15085
15086 return;
15087 } while (true);
15088 }
15089
15090 function pushDispatcher() {
15091 var prevDispatcher = ReactCurrentDispatcher$2.current;
15092 ReactCurrentDispatcher$2.current = ContextOnlyDispatcher;
15093
15094 if (prevDispatcher === null) {
15095 // The React isomorphic package does not include a default dispatcher.
15096 // Instead the first renderer will lazily attach one, in order to give
15097 // nicer error messages.
15098 return ContextOnlyDispatcher;
15099 } else {
15100 return prevDispatcher;
15101 }
15102 }
15103
15104 function popDispatcher(prevDispatcher) {
15105 ReactCurrentDispatcher$2.current = prevDispatcher;
15106 }
15107
15108 function markCommitTimeOfFallback() {
15109 globalMostRecentFallbackTime = now();
15110 }
15111 function markSkippedUpdateLanes(lane) {
15112 workInProgressRootSkippedLanes = mergeLanes(lane, workInProgressRootSkippedLanes);
15113 }
15114 function renderDidSuspend() {
15115 if (workInProgressRootExitStatus === RootInProgress) {
15116 workInProgressRootExitStatus = RootSuspended;
15117 }
15118 }
15119 function renderDidSuspendDelayIfPossible() {
15120 if (workInProgressRootExitStatus === RootInProgress || workInProgressRootExitStatus === RootSuspended || workInProgressRootExitStatus === RootErrored) {
15121 workInProgressRootExitStatus = RootSuspendedWithDelay;
15122 } // Check if there are updates that we skipped tree that might have unblocked
15123 // this render.
15124
15125
15126 if (workInProgressRoot !== null && (includesNonIdleWork(workInProgressRootSkippedLanes) || includesNonIdleWork(workInProgressRootInterleavedUpdatedLanes))) {
15127 // Mark the current render as suspended so that we switch to working on
15128 // the updates that were skipped. Usually we only suspend at the end of
15129 // the render phase.
15130 // TODO: We should probably always mark the root as suspended immediately
15131 // (inside this function), since by suspending at the end of the render
15132 // phase introduces a potential mistake where we suspend lanes that were
15133 // pinged or updated while we were rendering.
15134 markRootSuspended$1(workInProgressRoot, workInProgressRootRenderLanes);
15135 }
15136 }
15137 function renderDidError(error) {
15138 if (workInProgressRootExitStatus !== RootSuspendedWithDelay) {
15139 workInProgressRootExitStatus = RootErrored;
15140 }
15141
15142 if (workInProgressRootConcurrentErrors === null) {
15143 workInProgressRootConcurrentErrors = [error];
15144 } else {
15145 workInProgressRootConcurrentErrors.push(error);
15146 }
15147 } // Called during render to determine if anything has suspended.
15148 // Returns false if we're not sure.
15149
15150 function renderHasNotSuspendedYet() {
15151 // If something errored or completed, we can't really be sure,
15152 // so those are false.
15153 return workInProgressRootExitStatus === RootInProgress;
15154 }
15155
15156 function renderRootSync(root, lanes) {
15157 var prevExecutionContext = executionContext;
15158 executionContext |= RenderContext;
15159 var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack
15160 // and prepare a fresh one. Otherwise we'll continue where we left off.
15161
15162 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {
15163 prepareFreshStack(root, lanes);
15164 }
15165
15166 do {
15167 try {
15168 workLoopSync();
15169 break;
15170 } catch (thrownValue) {
15171 handleError(root, thrownValue);
15172 }
15173 } while (true);
15174
15175 resetContextDependencies();
15176 executionContext = prevExecutionContext;
15177 popDispatcher(prevDispatcher);
15178
15179 if (workInProgress !== null) {
15180 // This is a sync render, so we should have finished the whole tree.
15181 throw new Error('Cannot commit an incomplete root. This error is likely caused by a ' + 'bug in React. Please file an issue.');
15182 }
15183
15184
15185 workInProgressRoot = null;
15186 workInProgressRootRenderLanes = NoLanes;
15187 return workInProgressRootExitStatus;
15188 } // The work loop is an extremely hot path. Tell Closure not to inline it.
15189
15190 /** @noinline */
15191
15192
15193 function workLoopSync() {
15194 // Already timed out, so perform work without checking if we need to yield.
15195 while (workInProgress !== null) {
15196 performUnitOfWork(workInProgress);
15197 }
15198 }
15199
15200 function renderRootConcurrent(root, lanes) {
15201 var prevExecutionContext = executionContext;
15202 executionContext |= RenderContext;
15203 var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack
15204 // and prepare a fresh one. Otherwise we'll continue where we left off.
15205
15206 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {
15207 resetRenderTimer();
15208 prepareFreshStack(root, lanes);
15209 }
15210
15211 do {
15212 try {
15213 workLoopConcurrent();
15214 break;
15215 } catch (thrownValue) {
15216 handleError(root, thrownValue);
15217 }
15218 } while (true);
15219
15220 resetContextDependencies();
15221 popDispatcher(prevDispatcher);
15222 executionContext = prevExecutionContext;
15223
15224
15225 if (workInProgress !== null) {
15226
15227 return RootInProgress;
15228 } else {
15229
15230
15231 workInProgressRoot = null;
15232 workInProgressRootRenderLanes = NoLanes; // Return the final exit status.
15233
15234 return workInProgressRootExitStatus;
15235 }
15236 }
15237 /** @noinline */
15238
15239
15240 function workLoopConcurrent() {
15241 // Perform work until Scheduler asks us to yield
15242 while (workInProgress !== null && !shouldYield()) {
15243 performUnitOfWork(workInProgress);
15244 }
15245 }
15246
15247 function performUnitOfWork(unitOfWork) {
15248 // The current, flushed, state of this fiber is the alternate. Ideally
15249 // nothing should rely on this, but relying on it here means that we don't
15250 // need an additional field on the work in progress.
15251 var current = unitOfWork.alternate;
15252 setCurrentFiber(unitOfWork);
15253 var next;
15254
15255 if ( (unitOfWork.mode & ProfileMode) !== NoMode) {
15256 startProfilerTimer(unitOfWork);
15257 next = beginWork$1(current, unitOfWork, subtreeRenderLanes);
15258 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
15259 } else {
15260 next = beginWork$1(current, unitOfWork, subtreeRenderLanes);
15261 }
15262
15263 resetCurrentFiber();
15264 unitOfWork.memoizedProps = unitOfWork.pendingProps;
15265
15266 if (next === null) {
15267 // If this doesn't spawn new work, complete the current work.
15268 completeUnitOfWork(unitOfWork);
15269 } else {
15270 workInProgress = next;
15271 }
15272
15273 ReactCurrentOwner$2.current = null;
15274 }
15275
15276 function completeUnitOfWork(unitOfWork) {
15277 // Attempt to complete the current unit of work, then move to the next
15278 // sibling. If there are no more siblings, return to the parent fiber.
15279 var completedWork = unitOfWork;
15280
15281 do {
15282 // The current, flushed, state of this fiber is the alternate. Ideally
15283 // nothing should rely on this, but relying on it here means that we don't
15284 // need an additional field on the work in progress.
15285 var current = completedWork.alternate;
15286 var returnFiber = completedWork.return; // Check if the work completed or if something threw.
15287
15288 if ((completedWork.flags & Incomplete) === NoFlags) {
15289 setCurrentFiber(completedWork);
15290 var next = void 0;
15291
15292 if ( (completedWork.mode & ProfileMode) === NoMode) {
15293 next = completeWork(current, completedWork, subtreeRenderLanes);
15294 } else {
15295 startProfilerTimer(completedWork);
15296 next = completeWork(current, completedWork, subtreeRenderLanes); // Update render duration assuming we didn't error.
15297
15298 stopProfilerTimerIfRunningAndRecordDelta(completedWork, false);
15299 }
15300
15301 resetCurrentFiber();
15302
15303 if (next !== null) {
15304 // Completing this fiber spawned new work. Work on that next.
15305 workInProgress = next;
15306 return;
15307 }
15308 } else {
15309 // This fiber did not complete because something threw. Pop values off
15310 // the stack without entering the complete phase. If this is a boundary,
15311 // capture values if possible.
15312 var _next = unwindWork(current, completedWork); // Because this fiber did not complete, don't reset its lanes.
15313
15314
15315 if (_next !== null) {
15316 // If completing this work spawned new work, do that next. We'll come
15317 // back here again.
15318 // Since we're restarting, remove anything that is not a host effect
15319 // from the effect tag.
15320 _next.flags &= HostEffectMask;
15321 workInProgress = _next;
15322 return;
15323 }
15324
15325 if ( (completedWork.mode & ProfileMode) !== NoMode) {
15326 // Record the render duration for the fiber that errored.
15327 stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); // Include the time spent working on failed children before continuing.
15328
15329 var actualDuration = completedWork.actualDuration;
15330 var child = completedWork.child;
15331
15332 while (child !== null) {
15333 actualDuration += child.actualDuration;
15334 child = child.sibling;
15335 }
15336
15337 completedWork.actualDuration = actualDuration;
15338 }
15339
15340 if (returnFiber !== null) {
15341 // Mark the parent fiber as incomplete and clear its subtree flags.
15342 returnFiber.flags |= Incomplete;
15343 returnFiber.subtreeFlags = NoFlags;
15344 returnFiber.deletions = null;
15345 } else {
15346 // We've unwound all the way to the root.
15347 workInProgressRootExitStatus = RootDidNotComplete;
15348 workInProgress = null;
15349 return;
15350 }
15351 }
15352
15353 var siblingFiber = completedWork.sibling;
15354
15355 if (siblingFiber !== null) {
15356 // If there is more work to do in this returnFiber, do that next.
15357 workInProgress = siblingFiber;
15358 return;
15359 } // Otherwise, return to the parent
15360
15361
15362 completedWork = returnFiber; // Update the next thing we're working on in case something throws.
15363
15364 workInProgress = completedWork;
15365 } while (completedWork !== null); // We've reached the root.
15366
15367
15368 if (workInProgressRootExitStatus === RootInProgress) {
15369 workInProgressRootExitStatus = RootCompleted;
15370 }
15371 }
15372
15373 function commitRoot(root, recoverableErrors) {
15374 // TODO: This no longer makes any sense. We already wrap the mutation and
15375 // layout phases. Should be able to remove.
15376 var previousUpdateLanePriority = getCurrentUpdatePriority();
15377 var prevTransition = ReactCurrentBatchConfig$2.transition;
15378
15379 try {
15380 ReactCurrentBatchConfig$2.transition = null;
15381 setCurrentUpdatePriority(DiscreteEventPriority);
15382 commitRootImpl(root, recoverableErrors, previousUpdateLanePriority);
15383 } finally {
15384 ReactCurrentBatchConfig$2.transition = prevTransition;
15385 setCurrentUpdatePriority(previousUpdateLanePriority);
15386 }
15387
15388 return null;
15389 }
15390
15391 function commitRootImpl(root, recoverableErrors, renderPriorityLevel) {
15392 do {
15393 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which
15394 // means `flushPassiveEffects` will sometimes result in additional
15395 // passive effects. So we need to keep flushing in a loop until there are
15396 // no more pending effects.
15397 // TODO: Might be better if `flushPassiveEffects` did not automatically
15398 // flush synchronous work at the end, to avoid factoring hazards like this.
15399 flushPassiveEffects();
15400 } while (rootWithPendingPassiveEffects !== null);
15401
15402 flushRenderPhaseStrictModeWarningsInDEV();
15403
15404 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
15405 throw new Error('Should not already be working.');
15406 }
15407
15408 var finishedWork = root.finishedWork;
15409 var lanes = root.finishedLanes;
15410
15411 if (finishedWork === null) {
15412
15413 return null;
15414 } else {
15415 {
15416 if (lanes === NoLanes) {
15417 error('root.finishedLanes should not be empty during a commit. This is a ' + 'bug in React.');
15418 }
15419 }
15420 }
15421
15422 root.finishedWork = null;
15423 root.finishedLanes = NoLanes;
15424
15425 if (finishedWork === root.current) {
15426 throw new Error('Cannot commit the same tree as before. This error is likely caused by ' + 'a bug in React. Please file an issue.');
15427 } // commitRoot never returns a continuation; it always finishes synchronously.
15428 // So we can clear these now to allow a new callback to be scheduled.
15429
15430
15431 root.callbackNode = null;
15432 root.callbackPriority = NoLane; // Update the first and last pending times on this root. The new first
15433 // pending time is whatever is left on the root fiber.
15434
15435 var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes);
15436 markRootFinished(root, remainingLanes);
15437
15438 if (root === workInProgressRoot) {
15439 // We can reset these now that they are finished.
15440 workInProgressRoot = null;
15441 workInProgress = null;
15442 workInProgressRootRenderLanes = NoLanes;
15443 } // If there are pending passive effects, schedule a callback to process them.
15444 // Do this as early as possible, so it is queued before anything else that
15445 // might get scheduled in the commit phase. (See #16714.)
15446 // TODO: Delete all other places that schedule the passive effect callback
15447 // They're redundant.
15448
15449
15450 if ((finishedWork.subtreeFlags & PassiveMask) !== NoFlags || (finishedWork.flags & PassiveMask) !== NoFlags) {
15451 if (!rootDoesHavePassiveEffects) {
15452 rootDoesHavePassiveEffects = true;
15453 scheduleCallback$1(NormalPriority, function () {
15454 flushPassiveEffects(); // This render triggered passive effects: release the root cache pool
15455 // *after* passive effects fire to avoid freeing a cache pool that may
15456 // be referenced by a node in the tree (HostRoot, Cache boundary etc)
15457
15458 return null;
15459 });
15460 }
15461 } // Check if there are any effects in the whole tree.
15462 // TODO: This is left over from the effect list implementation, where we had
15463 // to check for the existence of `firstEffect` to satisfy Flow. I think the
15464 // only other reason this optimization exists is because it affects profiling.
15465 // Reconsider whether this is necessary.
15466
15467
15468 var subtreeHasEffects = (finishedWork.subtreeFlags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags;
15469 var rootHasEffect = (finishedWork.flags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags;
15470
15471 if (subtreeHasEffects || rootHasEffect) {
15472 var prevTransition = ReactCurrentBatchConfig$2.transition;
15473 ReactCurrentBatchConfig$2.transition = null;
15474 var previousPriority = getCurrentUpdatePriority();
15475 setCurrentUpdatePriority(DiscreteEventPriority);
15476 var prevExecutionContext = executionContext;
15477 executionContext |= CommitContext; // Reset this to null before calling lifecycles
15478
15479 ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass
15480 // of the effect list for each phase: all mutation effects come before all
15481 // layout effects, and so on.
15482 // The first phase a "before mutation" phase. We use this phase to read the
15483 // state of the host tree right before we mutate it. This is where
15484 // getSnapshotBeforeUpdate is called.
15485
15486 var shouldFireAfterActiveInstanceBlur = commitBeforeMutationEffects(root, finishedWork);
15487
15488 {
15489 // Mark the current commit time to be shared by all Profilers in this
15490 // batch. This enables them to be grouped later.
15491 recordCommitTime();
15492 }
15493
15494
15495 commitMutationEffects(root, finishedWork, lanes);
15496
15497 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
15498 // the mutation phase, so that the previous tree is still current during
15499 // componentWillUnmount, but before the layout phase, so that the finished
15500 // work is current during componentDidMount/Update.
15501
15502 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
15503
15504 commitLayoutEffects(finishedWork, root, lanes);
15505 // opportunity to paint.
15506
15507
15508 requestPaint();
15509 executionContext = prevExecutionContext; // Reset the priority to the previous non-sync value.
15510
15511 setCurrentUpdatePriority(previousPriority);
15512 ReactCurrentBatchConfig$2.transition = prevTransition;
15513 } else {
15514 // No effects.
15515 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
15516 // no effects.
15517 // TODO: Maybe there's a better way to report this.
15518
15519 {
15520 recordCommitTime();
15521 }
15522 }
15523
15524 if (rootDoesHavePassiveEffects) {
15525 // This commit has passive effects. Stash a reference to them. But don't
15526 // schedule a callback until after flushing layout work.
15527 rootDoesHavePassiveEffects = false;
15528 rootWithPendingPassiveEffects = root;
15529 pendingPassiveEffectsLanes = lanes;
15530 } // Read this again, since an effect might have updated it
15531
15532
15533 remainingLanes = root.pendingLanes; // Check if there's remaining work on this root
15534 // TODO: This is part of the `componentDidCatch` implementation. Its purpose
15535 // is to detect whether something might have called setState inside
15536 // `componentDidCatch`. The mechanism is known to be flawed because `setState`
15537 // inside `componentDidCatch` is itself flawed — that's why we recommend
15538 // `getDerivedStateFromError` instead. However, it could be improved by
15539 // checking if remainingLanes includes Sync work, instead of whether there's
15540 // any work remaining at all (which would also include stuff like Suspense
15541 // retries or transitions). It's been like this for a while, though, so fixing
15542 // it probably isn't that urgent.
15543
15544 if (remainingLanes === NoLanes) {
15545 // If there's no remaining work, we can clear the set of already failed
15546 // error boundaries.
15547 legacyErrorBoundariesThatAlreadyFailed = null;
15548 }
15549
15550 onCommitRoot(finishedWork.stateNode, renderPriorityLevel);
15551 // additional work on this root is scheduled.
15552
15553
15554 ensureRootIsScheduled(root, now());
15555
15556 if (recoverableErrors !== null) {
15557 // There were errors during this render, but recovered from them without
15558 // needing to surface it to the UI. We log them here.
15559 var onRecoverableError = root.onRecoverableError;
15560
15561 for (var i = 0; i < recoverableErrors.length; i++) {
15562 var recoverableError = recoverableErrors[i];
15563 onRecoverableError(recoverableError);
15564 }
15565 }
15566
15567 if (hasUncaughtError) {
15568 hasUncaughtError = false;
15569 var error$1 = firstUncaughtError;
15570 firstUncaughtError = null;
15571 throw error$1;
15572 } // If the passive effects are the result of a discrete render, flush them
15573 // synchronously at the end of the current task so that the result is
15574 // immediately observable. Otherwise, we assume that they are not
15575 // order-dependent and do not need to be observed by external systems, so we
15576 // can wait until after paint.
15577 // TODO: We can optimize this by not scheduling the callback earlier. Since we
15578 // currently schedule the callback in multiple places, will wait until those
15579 // are consolidated.
15580
15581
15582 if (includesSomeLane(pendingPassiveEffectsLanes, SyncLane) && root.tag !== LegacyRoot) {
15583 flushPassiveEffects();
15584 } // Read this again, since a passive effect might have updated it
15585
15586
15587 remainingLanes = root.pendingLanes;
15588
15589 if (includesSomeLane(remainingLanes, SyncLane)) {
15590 {
15591 markNestedUpdateScheduled();
15592 } // Count the number of times the root synchronously re-renders without
15593 // finishing. If there are too many, it indicates an infinite update loop.
15594
15595
15596 if (root === rootWithNestedUpdates) {
15597 nestedUpdateCount++;
15598 } else {
15599 nestedUpdateCount = 0;
15600 rootWithNestedUpdates = root;
15601 }
15602 } else {
15603 nestedUpdateCount = 0;
15604 } // If layout work was scheduled, flush it now.
15605
15606
15607 flushSyncCallbacks();
15608
15609 return null;
15610 }
15611
15612 function flushPassiveEffects() {
15613 // Returns whether passive effects were flushed.
15614 // TODO: Combine this check with the one in flushPassiveEFfectsImpl. We should
15615 // probably just combine the two functions. I believe they were only separate
15616 // in the first place because we used to wrap it with
15617 // `Scheduler.runWithPriority`, which accepts a function. But now we track the
15618 // priority within React itself, so we can mutate the variable directly.
15619 if (rootWithPendingPassiveEffects !== null) {
15620 var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes);
15621 var priority = lowerEventPriority(DefaultEventPriority, renderPriority);
15622 var prevTransition = ReactCurrentBatchConfig$2.transition;
15623 var previousPriority = getCurrentUpdatePriority();
15624
15625 try {
15626 ReactCurrentBatchConfig$2.transition = null;
15627 setCurrentUpdatePriority(priority);
15628 return flushPassiveEffectsImpl();
15629 } finally {
15630 setCurrentUpdatePriority(previousPriority);
15631 ReactCurrentBatchConfig$2.transition = prevTransition; // Once passive effects have run for the tree - giving components a
15632 }
15633 }
15634
15635 return false;
15636 }
15637 function enqueuePendingPassiveProfilerEffect(fiber) {
15638 {
15639 pendingPassiveProfilerEffects.push(fiber);
15640
15641 if (!rootDoesHavePassiveEffects) {
15642 rootDoesHavePassiveEffects = true;
15643 scheduleCallback$1(NormalPriority, function () {
15644 flushPassiveEffects();
15645 return null;
15646 });
15647 }
15648 }
15649 }
15650
15651 function flushPassiveEffectsImpl() {
15652 if (rootWithPendingPassiveEffects === null) {
15653 return false;
15654 }
15655
15656 var root = rootWithPendingPassiveEffects;
15657 rootWithPendingPassiveEffects = null; // TODO: This is sometimes out of sync with rootWithPendingPassiveEffects.
15658 // Figure out why and fix it. It's not causing any known issues (probably
15659 // because it's only used for profiling), but it's a refactor hazard.
15660
15661 pendingPassiveEffectsLanes = NoLanes;
15662
15663 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
15664 throw new Error('Cannot flush passive effects while already rendering.');
15665 }
15666
15667 var prevExecutionContext = executionContext;
15668 executionContext |= CommitContext;
15669 commitPassiveUnmountEffects(root.current);
15670 commitPassiveMountEffects(root, root.current); // TODO: Move to commitPassiveMountEffects
15671
15672 {
15673 var profilerEffects = pendingPassiveProfilerEffects;
15674 pendingPassiveProfilerEffects = [];
15675
15676 for (var i = 0; i < profilerEffects.length; i++) {
15677 var _fiber = profilerEffects[i];
15678 commitPassiveEffectDurations(root, _fiber);
15679 }
15680 }
15681
15682 executionContext = prevExecutionContext;
15683 flushSyncCallbacks(); // If additional passive effects were scheduled, increment a counter. If this
15684 // exceeds the limit, we'll fire a warning.
15685
15686 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1; // TODO: Move to commitPassiveMountEffects
15687
15688 onPostCommitRoot(root);
15689
15690 {
15691 var stateNode = root.current.stateNode;
15692 stateNode.effectDuration = 0;
15693 stateNode.passiveEffectDuration = 0;
15694 }
15695
15696 return true;
15697 }
15698
15699 function isAlreadyFailedLegacyErrorBoundary(instance) {
15700 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
15701 }
15702 function markLegacyErrorBoundaryAsFailed(instance) {
15703 if (legacyErrorBoundariesThatAlreadyFailed === null) {
15704 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
15705 } else {
15706 legacyErrorBoundariesThatAlreadyFailed.add(instance);
15707 }
15708 }
15709
15710 function prepareToThrowUncaughtError(error) {
15711 if (!hasUncaughtError) {
15712 hasUncaughtError = true;
15713 firstUncaughtError = error;
15714 }
15715 }
15716
15717 var onUncaughtError = prepareToThrowUncaughtError;
15718
15719 function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
15720 var errorInfo = createCapturedValue(error, sourceFiber);
15721 var update = createRootErrorUpdate(rootFiber, errorInfo, SyncLane);
15722 enqueueUpdate(rootFiber, update);
15723 var eventTime = requestEventTime();
15724 var root = markUpdateLaneFromFiberToRoot(rootFiber, SyncLane);
15725
15726 if (root !== null) {
15727 markRootUpdated(root, SyncLane, eventTime);
15728 ensureRootIsScheduled(root, eventTime);
15729 }
15730 }
15731
15732 function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) {
15733 if (sourceFiber.tag === HostRoot) {
15734 // Error was thrown at the root. There is no parent, so the root
15735 // itself should capture it.
15736 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1);
15737 return;
15738 }
15739
15740 var fiber = null;
15741
15742 {
15743 fiber = sourceFiber.return;
15744 }
15745
15746 while (fiber !== null) {
15747 if (fiber.tag === HostRoot) {
15748 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1);
15749 return;
15750 } else if (fiber.tag === ClassComponent) {
15751 var ctor = fiber.type;
15752 var instance = fiber.stateNode;
15753
15754 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
15755 var errorInfo = createCapturedValue(error$1, sourceFiber);
15756 var update = createClassErrorUpdate(fiber, errorInfo, SyncLane);
15757 enqueueUpdate(fiber, update);
15758 var eventTime = requestEventTime();
15759 var root = markUpdateLaneFromFiberToRoot(fiber, SyncLane);
15760
15761 if (root !== null) {
15762 markRootUpdated(root, SyncLane, eventTime);
15763 ensureRootIsScheduled(root, eventTime);
15764 }
15765
15766 return;
15767 }
15768 }
15769
15770 fiber = fiber.return;
15771 }
15772
15773 {
15774 // TODO: Until we re-land skipUnmountedBoundaries (see #20147), this warning
15775 // will fire for errors that are thrown by destroy functions inside deleted
15776 // trees. What it should instead do is propagate the error to the parent of
15777 // the deleted tree. In the meantime, do not add this warning to the
15778 // allowlist; this is only for our internal use.
15779 error('Internal React error: Attempted to capture a commit phase error ' + 'inside a detached tree. This indicates a bug in React. Likely ' + 'causes include deleting the same fiber more than once, committing an ' + 'already-finished tree, or an inconsistent return pointer.\n\n' + 'Error message:\n\n%s', error$1);
15780 }
15781 }
15782 function pingSuspendedRoot(root, wakeable, pingedLanes) {
15783 var pingCache = root.pingCache;
15784
15785 if (pingCache !== null) {
15786 // The wakeable resolved, so we no longer need to memoize, because it will
15787 // never be thrown again.
15788 pingCache.delete(wakeable);
15789 }
15790
15791 var eventTime = requestEventTime();
15792 markRootPinged(root, pingedLanes);
15793 warnIfSuspenseResolutionNotWrappedWithActDEV(root);
15794
15795 if (workInProgressRoot === root && isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes)) {
15796 // Received a ping at the same priority level at which we're currently
15797 // rendering. We might want to restart this render. This should mirror
15798 // the logic of whether or not a root suspends once it completes.
15799 // TODO: If we're rendering sync either due to Sync, Batched or expired,
15800 // we should probably never restart.
15801 // If we're suspended with delay, or if it's a retry, we'll always suspend
15802 // so we can always restart.
15803 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && includesOnlyRetries(workInProgressRootRenderLanes) && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
15804 // Restart from the root.
15805 prepareFreshStack(root, NoLanes);
15806 } else {
15807 // Even though we can't restart right now, we might get an
15808 // opportunity later. So we mark this render as having a ping.
15809 workInProgressRootPingedLanes = mergeLanes(workInProgressRootPingedLanes, pingedLanes);
15810 }
15811 }
15812
15813 ensureRootIsScheduled(root, eventTime);
15814 }
15815
15816 function retryTimedOutBoundary(boundaryFiber, retryLane) {
15817 // The boundary fiber (a Suspense component or SuspenseList component)
15818 // previously was rendered in its fallback state. One of the promises that
15819 // suspended it has resolved, which means at least part of the tree was
15820 // likely unblocked. Try rendering again, at a new lanes.
15821 if (retryLane === NoLane) {
15822 // TODO: Assign this to `suspenseState.retryLane`? to avoid
15823 // unnecessary entanglement?
15824 retryLane = requestRetryLane(boundaryFiber);
15825 } // TODO: Special case idle priority?
15826
15827
15828 var eventTime = requestEventTime();
15829 var root = markUpdateLaneFromFiberToRoot(boundaryFiber, retryLane);
15830
15831 if (root !== null) {
15832 markRootUpdated(root, retryLane, eventTime);
15833 ensureRootIsScheduled(root, eventTime);
15834 }
15835 }
15836 function resolveRetryWakeable(boundaryFiber, wakeable) {
15837 var retryLane = NoLane; // Default
15838
15839 var retryCache;
15840
15841 {
15842 retryCache = boundaryFiber.stateNode;
15843 }
15844
15845 if (retryCache !== null) {
15846 // The wakeable resolved, so we no longer need to memoize, because it will
15847 // never be thrown again.
15848 retryCache.delete(wakeable);
15849 }
15850
15851 retryTimedOutBoundary(boundaryFiber, retryLane);
15852 } // Computes the next Just Noticeable Difference (JND) boundary.
15853 // The theory is that a person can't tell the difference between small differences in time.
15854 // Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
15855 // difference in the experience. However, waiting for longer might mean that we can avoid
15856 // showing an intermediate loading state. The longer we have already waited, the harder it
15857 // is to tell small differences in time. Therefore, the longer we've already waited,
15858 // the longer we can wait additionally. At some point we have to give up though.
15859 // We pick a train model where the next boundary commits at a consistent schedule.
15860 // These particular numbers are vague estimates. We expect to adjust them based on research.
15861
15862 function jnd(timeElapsed) {
15863 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
15864 }
15865
15866 function checkForNestedUpdates() {
15867 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
15868 nestedUpdateCount = 0;
15869 rootWithNestedUpdates = null;
15870 throw new Error('Maximum update depth exceeded. This can happen when a component ' + 'repeatedly calls setState inside componentWillUpdate or ' + 'componentDidUpdate. React limits the number of nested updates to ' + 'prevent infinite loops.');
15871 }
15872
15873 {
15874 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
15875 nestedPassiveUpdateCount = 0;
15876
15877 error('Maximum update depth exceeded. This can happen when a component ' + "calls setState inside useEffect, but useEffect either doesn't " + 'have a dependency array, or one of the dependencies changes on ' + 'every render.');
15878 }
15879 }
15880 }
15881
15882 function flushRenderPhaseStrictModeWarningsInDEV() {
15883 {
15884 ReactStrictModeWarnings.flushLegacyContextWarning();
15885
15886 {
15887 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
15888 }
15889 }
15890 }
15891
15892 var didWarnStateUpdateForNotYetMountedComponent = null;
15893
15894 function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) {
15895 {
15896 if ((executionContext & RenderContext) !== NoContext) {
15897 // We let the other warning about render phase updates deal with this one.
15898 return;
15899 }
15900
15901 if (!(fiber.mode & ConcurrentMode)) {
15902 return;
15903 }
15904
15905 var tag = fiber.tag;
15906
15907 if (tag !== IndeterminateComponent && tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent) {
15908 // Only warn for user-defined components, not internal ones like Suspense.
15909 return;
15910 } // We show the whole stack but dedupe on the top component's name because
15911 // the problematic code almost always lies inside that component.
15912
15913
15914 var componentName = getComponentNameFromFiber(fiber) || 'ReactComponent';
15915
15916 if (didWarnStateUpdateForNotYetMountedComponent !== null) {
15917 if (didWarnStateUpdateForNotYetMountedComponent.has(componentName)) {
15918 return;
15919 }
15920
15921 didWarnStateUpdateForNotYetMountedComponent.add(componentName);
15922 } else {
15923 didWarnStateUpdateForNotYetMountedComponent = new Set([componentName]);
15924 }
15925
15926 var previousFiber = current;
15927
15928 try {
15929 setCurrentFiber(fiber);
15930
15931 error("Can't perform a React state update on a component that hasn't mounted yet. " + 'This indicates that you have a side-effect in your render function that ' + 'asynchronously later calls tries to update the component. Move this work to ' + 'useEffect instead.');
15932 } finally {
15933 if (previousFiber) {
15934 setCurrentFiber(fiber);
15935 } else {
15936 resetCurrentFiber();
15937 }
15938 }
15939 }
15940 }
15941
15942 var beginWork$1;
15943
15944 {
15945 beginWork$1 = beginWork;
15946 }
15947
15948 var didWarnAboutUpdateInRender = false;
15949 var didWarnAboutUpdateInRenderForAnotherComponent;
15950
15951 {
15952 didWarnAboutUpdateInRenderForAnotherComponent = new Set();
15953 }
15954
15955 function warnAboutRenderPhaseUpdatesInDEV(fiber) {
15956 {
15957 if (isRendering && !getIsUpdatingOpaqueValueInRenderPhaseInDEV()) {
15958 switch (fiber.tag) {
15959 case FunctionComponent:
15960 case ForwardRef:
15961 case SimpleMemoComponent:
15962 {
15963 var renderingComponentName = workInProgress && getComponentNameFromFiber(workInProgress) || 'Unknown'; // Dedupe by the rendering component because it's the one that needs to be fixed.
15964
15965 var dedupeKey = renderingComponentName;
15966
15967 if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) {
15968 didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey);
15969 var setStateComponentName = getComponentNameFromFiber(fiber) || 'Unknown';
15970
15971 error('Cannot update a component (`%s`) while rendering a ' + 'different component (`%s`). To locate the bad setState() call inside `%s`, ' + 'follow the stack trace as described in https://reactjs.org/link/setstate-in-render', setStateComponentName, renderingComponentName, renderingComponentName);
15972 }
15973
15974 break;
15975 }
15976
15977 case ClassComponent:
15978 {
15979 if (!didWarnAboutUpdateInRender) {
15980 error('Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure ' + 'function of props and state.');
15981
15982 didWarnAboutUpdateInRender = true;
15983 }
15984
15985 break;
15986 }
15987 }
15988 }
15989 }
15990 }
15991 var fakeActCallbackNode = {};
15992
15993 function scheduleCallback$1(priorityLevel, callback) {
15994 {
15995 // If we're currently inside an `act` scope, bypass Scheduler and push to
15996 // the `act` queue instead.
15997 var actQueue = ReactCurrentActQueue$1.current;
15998
15999 if (actQueue !== null) {
16000 actQueue.push(callback);
16001 return fakeActCallbackNode;
16002 } else {
16003 return scheduleCallback(priorityLevel, callback);
16004 }
16005 }
16006 }
16007
16008 function cancelCallback$1(callbackNode) {
16009 if ( callbackNode === fakeActCallbackNode) {
16010 return;
16011 } // In production, always call Scheduler. This function will be stripped out.
16012
16013
16014 return cancelCallback(callbackNode);
16015 }
16016
16017 function shouldForceFlushFallbacksInDEV() {
16018 // Never force flush in production. This function should get stripped out.
16019 return ReactCurrentActQueue$1.current !== null;
16020 }
16021
16022 function warnIfUpdatesNotWrappedWithActDEV(fiber) {
16023 {
16024 if (fiber.mode & ConcurrentMode) {
16025 if (!isConcurrentActEnvironment()) {
16026 // Not in an act environment. No need to warn.
16027 return;
16028 }
16029 } else {
16030 // Legacy mode has additional cases where we suppress a warning.
16031 if (!isLegacyActEnvironment()) {
16032 // Not in an act environment. No need to warn.
16033 return;
16034 }
16035
16036 if (executionContext !== NoContext) {
16037 // Legacy mode doesn't warn if the update is batched, i.e.
16038 // batchedUpdates or flushSync.
16039 return;
16040 }
16041
16042 if (fiber.tag !== FunctionComponent && fiber.tag !== ForwardRef && fiber.tag !== SimpleMemoComponent) {
16043 // For backwards compatibility with pre-hooks code, legacy mode only
16044 // warns for updates that originate from a hook.
16045 return;
16046 }
16047 }
16048
16049 if (ReactCurrentActQueue$1.current === null) {
16050 var previousFiber = current;
16051
16052 try {
16053 setCurrentFiber(fiber);
16054
16055 error('An update to %s inside a test was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://reactjs.org/link/wrap-tests-with-act', getComponentNameFromFiber(fiber));
16056 } finally {
16057 if (previousFiber) {
16058 setCurrentFiber(fiber);
16059 } else {
16060 resetCurrentFiber();
16061 }
16062 }
16063 }
16064 }
16065 }
16066
16067 function warnIfSuspenseResolutionNotWrappedWithActDEV(root) {
16068 {
16069 if (root.tag !== LegacyRoot && isConcurrentActEnvironment() && ReactCurrentActQueue$1.current === null) {
16070 error('A suspended resource finished loading inside a test, but the event ' + 'was not wrapped in act(...).\n\n' + 'When testing, code that resolves suspended data should be wrapped ' + 'into act(...):\n\n' + 'act(() => {\n' + ' /* finish loading suspended data */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://reactjs.org/link/wrap-tests-with-act');
16071 }
16072 }
16073 }
16074
16075 /* eslint-disable react-internal/prod-error-codes */
16076 var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
16077
16078 var failedBoundaries = null;
16079 var setRefreshHandler = function (handler) {
16080 {
16081 resolveFamily = handler;
16082 }
16083 };
16084 function resolveFunctionForHotReloading(type) {
16085 {
16086 if (resolveFamily === null) {
16087 // Hot reloading is disabled.
16088 return type;
16089 }
16090
16091 var family = resolveFamily(type);
16092
16093 if (family === undefined) {
16094 return type;
16095 } // Use the latest known implementation.
16096
16097
16098 return family.current;
16099 }
16100 }
16101 function resolveClassForHotReloading(type) {
16102 // No implementation differences.
16103 return resolveFunctionForHotReloading(type);
16104 }
16105 function resolveForwardRefForHotReloading(type) {
16106 {
16107 if (resolveFamily === null) {
16108 // Hot reloading is disabled.
16109 return type;
16110 }
16111
16112 var family = resolveFamily(type);
16113
16114 if (family === undefined) {
16115 // Check if we're dealing with a real forwardRef. Don't want to crash early.
16116 if (type !== null && type !== undefined && typeof type.render === 'function') {
16117 // ForwardRef is special because its resolved .type is an object,
16118 // but it's possible that we only have its inner render function in the map.
16119 // If that inner render function is different, we'll build a new forwardRef type.
16120 var currentRender = resolveFunctionForHotReloading(type.render);
16121
16122 if (type.render !== currentRender) {
16123 var syntheticType = {
16124 $$typeof: REACT_FORWARD_REF_TYPE,
16125 render: currentRender
16126 };
16127
16128 if (type.displayName !== undefined) {
16129 syntheticType.displayName = type.displayName;
16130 }
16131
16132 return syntheticType;
16133 }
16134 }
16135
16136 return type;
16137 } // Use the latest known implementation.
16138
16139
16140 return family.current;
16141 }
16142 }
16143 function isCompatibleFamilyForHotReloading(fiber, element) {
16144 {
16145 if (resolveFamily === null) {
16146 // Hot reloading is disabled.
16147 return false;
16148 }
16149
16150 var prevType = fiber.elementType;
16151 var nextType = element.type; // If we got here, we know types aren't === equal.
16152
16153 var needsCompareFamilies = false;
16154 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
16155
16156 switch (fiber.tag) {
16157 case ClassComponent:
16158 {
16159 if (typeof nextType === 'function') {
16160 needsCompareFamilies = true;
16161 }
16162
16163 break;
16164 }
16165
16166 case FunctionComponent:
16167 {
16168 if (typeof nextType === 'function') {
16169 needsCompareFamilies = true;
16170 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
16171 // We don't know the inner type yet.
16172 // We're going to assume that the lazy inner type is stable,
16173 // and so it is sufficient to avoid reconciling it away.
16174 // We're not going to unwrap or actually use the new lazy type.
16175 needsCompareFamilies = true;
16176 }
16177
16178 break;
16179 }
16180
16181 case ForwardRef:
16182 {
16183 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
16184 needsCompareFamilies = true;
16185 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
16186 needsCompareFamilies = true;
16187 }
16188
16189 break;
16190 }
16191
16192 case MemoComponent:
16193 case SimpleMemoComponent:
16194 {
16195 if ($$typeofNextType === REACT_MEMO_TYPE) {
16196 // TODO: if it was but can no longer be simple,
16197 // we shouldn't set this.
16198 needsCompareFamilies = true;
16199 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
16200 needsCompareFamilies = true;
16201 }
16202
16203 break;
16204 }
16205
16206 default:
16207 return false;
16208 } // Check if both types have a family and it's the same one.
16209
16210
16211 if (needsCompareFamilies) {
16212 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
16213 // This means both of them need to be registered to preserve state.
16214 // If we unwrapped and compared the inner types for wrappers instead,
16215 // then we would risk falsely saying two separate memo(Foo)
16216 // calls are equivalent because they wrap the same Foo function.
16217 var prevFamily = resolveFamily(prevType);
16218
16219 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
16220 return true;
16221 }
16222 }
16223
16224 return false;
16225 }
16226 }
16227 function markFailedErrorBoundaryForHotReloading(fiber) {
16228 {
16229 if (resolveFamily === null) {
16230 // Hot reloading is disabled.
16231 return;
16232 }
16233
16234 if (typeof WeakSet !== 'function') {
16235 return;
16236 }
16237
16238 if (failedBoundaries === null) {
16239 failedBoundaries = new WeakSet();
16240 }
16241
16242 failedBoundaries.add(fiber);
16243 }
16244 }
16245 var scheduleRefresh = function (root, update) {
16246 {
16247 if (resolveFamily === null) {
16248 // Hot reloading is disabled.
16249 return;
16250 }
16251
16252 var staleFamilies = update.staleFamilies,
16253 updatedFamilies = update.updatedFamilies;
16254 flushPassiveEffects();
16255 flushSync(function () {
16256 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
16257 });
16258 }
16259 };
16260 var scheduleRoot = function (root, element) {
16261 {
16262 if (root.context !== emptyContextObject) {
16263 // Super edge case: root has a legacy _renderSubtree context
16264 // but we don't know the parentComponent so we can't pass it.
16265 // Just ignore. We'll delete this with _renderSubtree code path later.
16266 return;
16267 }
16268
16269 flushPassiveEffects();
16270 flushSync(function () {
16271 updateContainer(element, root, null, null);
16272 });
16273 }
16274 };
16275
16276 function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
16277 {
16278 var alternate = fiber.alternate,
16279 child = fiber.child,
16280 sibling = fiber.sibling,
16281 tag = fiber.tag,
16282 type = fiber.type;
16283 var candidateType = null;
16284
16285 switch (tag) {
16286 case FunctionComponent:
16287 case SimpleMemoComponent:
16288 case ClassComponent:
16289 candidateType = type;
16290 break;
16291
16292 case ForwardRef:
16293 candidateType = type.render;
16294 break;
16295 }
16296
16297 if (resolveFamily === null) {
16298 throw new Error('Expected resolveFamily to be set during hot reload.');
16299 }
16300
16301 var needsRender = false;
16302 var needsRemount = false;
16303
16304 if (candidateType !== null) {
16305 var family = resolveFamily(candidateType);
16306
16307 if (family !== undefined) {
16308 if (staleFamilies.has(family)) {
16309 needsRemount = true;
16310 } else if (updatedFamilies.has(family)) {
16311 if (tag === ClassComponent) {
16312 needsRemount = true;
16313 } else {
16314 needsRender = true;
16315 }
16316 }
16317 }
16318 }
16319
16320 if (failedBoundaries !== null) {
16321 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
16322 needsRemount = true;
16323 }
16324 }
16325
16326 if (needsRemount) {
16327 fiber._debugNeedsRemount = true;
16328 }
16329
16330 if (needsRemount || needsRender) {
16331 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
16332 }
16333
16334 if (child !== null && !needsRemount) {
16335 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
16336 }
16337
16338 if (sibling !== null) {
16339 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
16340 }
16341 }
16342 }
16343
16344 var findHostInstancesForRefresh = function (root, families) {
16345 {
16346 var hostInstances = new Set();
16347 var types = new Set(families.map(function (family) {
16348 return family.current;
16349 }));
16350 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
16351 return hostInstances;
16352 }
16353 };
16354
16355 function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
16356 {
16357 var child = fiber.child,
16358 sibling = fiber.sibling,
16359 tag = fiber.tag,
16360 type = fiber.type;
16361 var candidateType = null;
16362
16363 switch (tag) {
16364 case FunctionComponent:
16365 case SimpleMemoComponent:
16366 case ClassComponent:
16367 candidateType = type;
16368 break;
16369
16370 case ForwardRef:
16371 candidateType = type.render;
16372 break;
16373 }
16374
16375 var didMatch = false;
16376
16377 if (candidateType !== null) {
16378 if (types.has(candidateType)) {
16379 didMatch = true;
16380 }
16381 }
16382
16383 if (didMatch) {
16384 // We have a match. This only drills down to the closest host components.
16385 // There's no need to search deeper because for the purpose of giving
16386 // visual feedback, "flashing" outermost parent rectangles is sufficient.
16387 findHostInstancesForFiberShallowly(fiber, hostInstances);
16388 } else {
16389 // If there's no match, maybe there will be one further down in the child tree.
16390 if (child !== null) {
16391 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
16392 }
16393 }
16394
16395 if (sibling !== null) {
16396 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
16397 }
16398 }
16399 }
16400
16401 function findHostInstancesForFiberShallowly(fiber, hostInstances) {
16402 {
16403 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
16404
16405 if (foundHostInstances) {
16406 return;
16407 } // If we didn't find any host children, fallback to closest host parent.
16408
16409
16410 var node = fiber;
16411
16412 while (true) {
16413 switch (node.tag) {
16414 case HostComponent:
16415 hostInstances.add(node.stateNode);
16416 return;
16417
16418 case HostPortal:
16419 hostInstances.add(node.stateNode.containerInfo);
16420 return;
16421
16422 case HostRoot:
16423 hostInstances.add(node.stateNode.containerInfo);
16424 return;
16425 }
16426
16427 if (node.return === null) {
16428 throw new Error('Expected to reach root first.');
16429 }
16430
16431 node = node.return;
16432 }
16433 }
16434 }
16435
16436 function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
16437 {
16438 var node = fiber;
16439 var foundHostInstances = false;
16440
16441 while (true) {
16442 if (node.tag === HostComponent) {
16443 // We got a match.
16444 foundHostInstances = true;
16445 hostInstances.add(node.stateNode); // There may still be more, so keep searching.
16446 } else if (node.child !== null) {
16447 node.child.return = node;
16448 node = node.child;
16449 continue;
16450 }
16451
16452 if (node === fiber) {
16453 return foundHostInstances;
16454 }
16455
16456 while (node.sibling === null) {
16457 if (node.return === null || node.return === fiber) {
16458 return foundHostInstances;
16459 }
16460
16461 node = node.return;
16462 }
16463
16464 node.sibling.return = node.return;
16465 node = node.sibling;
16466 }
16467 }
16468
16469 return false;
16470 }
16471
16472 var hasBadMapPolyfill;
16473
16474 {
16475 hasBadMapPolyfill = false;
16476
16477 try {
16478 var nonExtensibleObject = Object.preventExtensions({});
16479 /* eslint-disable no-new */
16480
16481 new Map([[nonExtensibleObject, null]]);
16482 new Set([nonExtensibleObject]);
16483 /* eslint-enable no-new */
16484 } catch (e) {
16485 // TODO: Consider warning about bad polyfills
16486 hasBadMapPolyfill = true;
16487 }
16488 }
16489
16490 function FiberNode(tag, pendingProps, key, mode) {
16491 // Instance
16492 this.tag = tag;
16493 this.key = key;
16494 this.elementType = null;
16495 this.type = null;
16496 this.stateNode = null; // Fiber
16497
16498 this.return = null;
16499 this.child = null;
16500 this.sibling = null;
16501 this.index = 0;
16502 this.ref = null;
16503 this.pendingProps = pendingProps;
16504 this.memoizedProps = null;
16505 this.updateQueue = null;
16506 this.memoizedState = null;
16507 this.dependencies = null;
16508 this.mode = mode; // Effects
16509
16510 this.flags = NoFlags;
16511 this.subtreeFlags = NoFlags;
16512 this.deletions = null;
16513 this.lanes = NoLanes;
16514 this.childLanes = NoLanes;
16515 this.alternate = null;
16516
16517 {
16518 // Note: The following is done to avoid a v8 performance cliff.
16519 //
16520 // Initializing the fields below to smis and later updating them with
16521 // double values will cause Fibers to end up having separate shapes.
16522 // This behavior/bug has something to do with Object.preventExtension().
16523 // Fortunately this only impacts DEV builds.
16524 // Unfortunately it makes React unusably slow for some applications.
16525 // To work around this, initialize the fields below with doubles.
16526 //
16527 // Learn more about this here:
16528 // https://github.com/facebook/react/issues/14365
16529 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
16530 this.actualDuration = Number.NaN;
16531 this.actualStartTime = Number.NaN;
16532 this.selfBaseDuration = Number.NaN;
16533 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
16534 // This won't trigger the performance cliff mentioned above,
16535 // and it simplifies other profiler code (including DevTools).
16536
16537 this.actualDuration = 0;
16538 this.actualStartTime = -1;
16539 this.selfBaseDuration = 0;
16540 this.treeBaseDuration = 0;
16541 }
16542
16543 {
16544 // This isn't directly used but is handy for debugging internals:
16545 this._debugSource = null;
16546 this._debugOwner = null;
16547 this._debugNeedsRemount = false;
16548 this._debugHookTypes = null;
16549
16550 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
16551 Object.preventExtensions(this);
16552 }
16553 }
16554 } // This is a constructor function, rather than a POJO constructor, still
16555 // please ensure we do the following:
16556 // 1) Nobody should add any instance methods on this. Instance methods can be
16557 // more difficult to predict when they get optimized and they are almost
16558 // never inlined properly in static compilers.
16559 // 2) Nobody should rely on `instanceof Fiber` for type testing. We should
16560 // always know when it is a fiber.
16561 // 3) We might want to experiment with using numeric keys since they are easier
16562 // to optimize in a non-JIT environment.
16563 // 4) We can easily go from a constructor to a createFiber object literal if that
16564 // is faster.
16565 // 5) It should be easy to port this to a C struct and keep a C implementation
16566 // compatible.
16567
16568
16569 var createFiber = function (tag, pendingProps, key, mode) {
16570 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
16571 return new FiberNode(tag, pendingProps, key, mode);
16572 };
16573
16574 function shouldConstruct$1(Component) {
16575 var prototype = Component.prototype;
16576 return !!(prototype && prototype.isReactComponent);
16577 }
16578
16579 function isSimpleFunctionComponent(type) {
16580 return typeof type === 'function' && !shouldConstruct$1(type) && type.defaultProps === undefined;
16581 }
16582 function resolveLazyComponentTag(Component) {
16583 if (typeof Component === 'function') {
16584 return shouldConstruct$1(Component) ? ClassComponent : FunctionComponent;
16585 } else if (Component !== undefined && Component !== null) {
16586 var $$typeof = Component.$$typeof;
16587
16588 if ($$typeof === REACT_FORWARD_REF_TYPE) {
16589 return ForwardRef;
16590 }
16591
16592 if ($$typeof === REACT_MEMO_TYPE) {
16593 return MemoComponent;
16594 }
16595 }
16596
16597 return IndeterminateComponent;
16598 } // This is used to create an alternate fiber to do work on.
16599
16600 function createWorkInProgress(current, pendingProps) {
16601 var workInProgress = current.alternate;
16602
16603 if (workInProgress === null) {
16604 // We use a double buffering pooling technique because we know that we'll
16605 // only ever need at most two versions of a tree. We pool the "other" unused
16606 // node that we're free to reuse. This is lazily created to avoid allocating
16607 // extra objects for things that are never updated. It also allow us to
16608 // reclaim the extra memory if needed.
16609 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
16610 workInProgress.elementType = current.elementType;
16611 workInProgress.type = current.type;
16612 workInProgress.stateNode = current.stateNode;
16613
16614 {
16615 // DEV-only fields
16616 workInProgress._debugSource = current._debugSource;
16617 workInProgress._debugOwner = current._debugOwner;
16618 workInProgress._debugHookTypes = current._debugHookTypes;
16619 }
16620
16621 workInProgress.alternate = current;
16622 current.alternate = workInProgress;
16623 } else {
16624 workInProgress.pendingProps = pendingProps; // Needed because Blocks store data on type.
16625
16626 workInProgress.type = current.type; // We already have an alternate.
16627 // Reset the effect tag.
16628
16629 workInProgress.flags = NoFlags; // The effects are no longer valid.
16630
16631 workInProgress.subtreeFlags = NoFlags;
16632 workInProgress.deletions = null;
16633
16634 {
16635 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
16636 // This prevents time from endlessly accumulating in new commits.
16637 // This has the downside of resetting values for different priority renders,
16638 // But works for yielding (the common case) and should support resuming.
16639 workInProgress.actualDuration = 0;
16640 workInProgress.actualStartTime = -1;
16641 }
16642 } // Reset all effects except static ones.
16643 // Static effects are not specific to a render.
16644
16645
16646 workInProgress.flags = current.flags & StaticMask;
16647 workInProgress.childLanes = current.childLanes;
16648 workInProgress.lanes = current.lanes;
16649 workInProgress.child = current.child;
16650 workInProgress.memoizedProps = current.memoizedProps;
16651 workInProgress.memoizedState = current.memoizedState;
16652 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
16653 // it cannot be shared with the current fiber.
16654
16655 var currentDependencies = current.dependencies;
16656 workInProgress.dependencies = currentDependencies === null ? null : {
16657 lanes: currentDependencies.lanes,
16658 firstContext: currentDependencies.firstContext
16659 }; // These will be overridden during the parent's reconciliation
16660
16661 workInProgress.sibling = current.sibling;
16662 workInProgress.index = current.index;
16663 workInProgress.ref = current.ref;
16664
16665 {
16666 workInProgress.selfBaseDuration = current.selfBaseDuration;
16667 workInProgress.treeBaseDuration = current.treeBaseDuration;
16668 }
16669
16670 {
16671 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
16672
16673 switch (workInProgress.tag) {
16674 case IndeterminateComponent:
16675 case FunctionComponent:
16676 case SimpleMemoComponent:
16677 workInProgress.type = resolveFunctionForHotReloading(current.type);
16678 break;
16679
16680 case ClassComponent:
16681 workInProgress.type = resolveClassForHotReloading(current.type);
16682 break;
16683
16684 case ForwardRef:
16685 workInProgress.type = resolveForwardRefForHotReloading(current.type);
16686 break;
16687 }
16688 }
16689
16690 return workInProgress;
16691 } // Used to reuse a Fiber for a second pass.
16692
16693 function resetWorkInProgress(workInProgress, renderLanes) {
16694 // This resets the Fiber to what createFiber or createWorkInProgress would
16695 // have set the values to before during the first pass. Ideally this wouldn't
16696 // be necessary but unfortunately many code paths reads from the workInProgress
16697 // when they should be reading from current and writing to workInProgress.
16698 // We assume pendingProps, index, key, ref, return are still untouched to
16699 // avoid doing another reconciliation.
16700 // Reset the effect flags but keep any Placement tags, since that's something
16701 // that child fiber is setting, not the reconciliation.
16702 workInProgress.flags &= StaticMask | Placement; // The effects are no longer valid.
16703
16704 var current = workInProgress.alternate;
16705
16706 if (current === null) {
16707 // Reset to createFiber's initial values.
16708 workInProgress.childLanes = NoLanes;
16709 workInProgress.lanes = renderLanes;
16710 workInProgress.child = null;
16711 workInProgress.subtreeFlags = NoFlags;
16712 workInProgress.memoizedProps = null;
16713 workInProgress.memoizedState = null;
16714 workInProgress.updateQueue = null;
16715 workInProgress.dependencies = null;
16716 workInProgress.stateNode = null;
16717
16718 {
16719 // Note: We don't reset the actualTime counts. It's useful to accumulate
16720 // actual time across multiple render passes.
16721 workInProgress.selfBaseDuration = 0;
16722 workInProgress.treeBaseDuration = 0;
16723 }
16724 } else {
16725 // Reset to the cloned values that createWorkInProgress would've.
16726 workInProgress.childLanes = current.childLanes;
16727 workInProgress.lanes = current.lanes;
16728 workInProgress.child = current.child;
16729 workInProgress.subtreeFlags = NoFlags;
16730 workInProgress.deletions = null;
16731 workInProgress.memoizedProps = current.memoizedProps;
16732 workInProgress.memoizedState = current.memoizedState;
16733 workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type.
16734
16735 workInProgress.type = current.type; // Clone the dependencies object. This is mutated during the render phase, so
16736 // it cannot be shared with the current fiber.
16737
16738 var currentDependencies = current.dependencies;
16739 workInProgress.dependencies = currentDependencies === null ? null : {
16740 lanes: currentDependencies.lanes,
16741 firstContext: currentDependencies.firstContext
16742 };
16743
16744 {
16745 // Note: We don't reset the actualTime counts. It's useful to accumulate
16746 // actual time across multiple render passes.
16747 workInProgress.selfBaseDuration = current.selfBaseDuration;
16748 workInProgress.treeBaseDuration = current.treeBaseDuration;
16749 }
16750 }
16751
16752 return workInProgress;
16753 }
16754 function createHostRootFiber(tag, isStrictMode, concurrentUpdatesByDefaultOverride) {
16755 var mode;
16756
16757 if (tag === ConcurrentRoot) {
16758 mode = ConcurrentMode;
16759
16760 if (isStrictMode === true) {
16761 mode |= StrictLegacyMode;
16762 }
16763 } else {
16764 mode = NoMode;
16765 }
16766
16767 if ( isDevToolsPresent) {
16768 // Always collect profile timings when DevTools are present.
16769 // This enables DevTools to start capturing timing at any point–
16770 // Without some nodes in the tree having empty base times.
16771 mode |= ProfileMode;
16772 }
16773
16774 return createFiber(HostRoot, null, null, mode);
16775 }
16776 function createFiberFromTypeAndProps(type, // React$ElementType
16777 key, pendingProps, owner, mode, lanes) {
16778 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
16779
16780 var resolvedType = type;
16781
16782 if (typeof type === 'function') {
16783 if (shouldConstruct$1(type)) {
16784 fiberTag = ClassComponent;
16785
16786 {
16787 resolvedType = resolveClassForHotReloading(resolvedType);
16788 }
16789 } else {
16790 {
16791 resolvedType = resolveFunctionForHotReloading(resolvedType);
16792 }
16793 }
16794 } else if (typeof type === 'string') {
16795 fiberTag = HostComponent;
16796 } else {
16797 getTag: switch (type) {
16798 case REACT_FRAGMENT_TYPE:
16799 return createFiberFromFragment(pendingProps.children, mode, lanes, key);
16800
16801 case REACT_STRICT_MODE_TYPE:
16802 fiberTag = Mode;
16803 mode |= StrictLegacyMode;
16804
16805 break;
16806
16807 case REACT_PROFILER_TYPE:
16808 return createFiberFromProfiler(pendingProps, mode, lanes, key);
16809
16810 case REACT_SUSPENSE_TYPE:
16811 return createFiberFromSuspense(pendingProps, mode, lanes, key);
16812
16813 case REACT_SUSPENSE_LIST_TYPE:
16814 return createFiberFromSuspenseList(pendingProps, mode, lanes, key);
16815
16816 case REACT_OFFSCREEN_TYPE:
16817 return createFiberFromOffscreen(pendingProps, mode, lanes, key);
16818
16819 case REACT_LEGACY_HIDDEN_TYPE:
16820
16821 // eslint-disable-next-line no-fallthrough
16822
16823 case REACT_SCOPE_TYPE:
16824
16825 // eslint-disable-next-line no-fallthrough
16826
16827 case REACT_CACHE_TYPE:
16828
16829 // eslint-disable-next-line no-fallthrough
16830
16831 case REACT_TRACING_MARKER_TYPE:
16832
16833 // eslint-disable-next-line no-fallthrough
16834
16835 case REACT_DEBUG_TRACING_MODE_TYPE:
16836
16837 // eslint-disable-next-line no-fallthrough
16838
16839 default:
16840 {
16841 if (typeof type === 'object' && type !== null) {
16842 switch (type.$$typeof) {
16843 case REACT_PROVIDER_TYPE:
16844 fiberTag = ContextProvider;
16845 break getTag;
16846
16847 case REACT_CONTEXT_TYPE:
16848 // This is a consumer
16849 fiberTag = ContextConsumer;
16850 break getTag;
16851
16852 case REACT_FORWARD_REF_TYPE:
16853 fiberTag = ForwardRef;
16854
16855 {
16856 resolvedType = resolveForwardRefForHotReloading(resolvedType);
16857 }
16858
16859 break getTag;
16860
16861 case REACT_MEMO_TYPE:
16862 fiberTag = MemoComponent;
16863 break getTag;
16864
16865 case REACT_LAZY_TYPE:
16866 fiberTag = LazyComponent;
16867 resolvedType = null;
16868 break getTag;
16869 }
16870 }
16871
16872 var info = '';
16873
16874 {
16875 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
16876 info += ' You likely forgot to export your component from the file ' + "it's defined in, or you might have mixed up default and " + 'named imports.';
16877 }
16878
16879 var ownerName = owner ? getComponentNameFromFiber(owner) : null;
16880
16881 if (ownerName) {
16882 info += '\n\nCheck the render method of `' + ownerName + '`.';
16883 }
16884 }
16885
16886 throw new Error('Element type is invalid: expected a string (for built-in ' + 'components) or a class/function (for composite components) ' + ("but got: " + (type == null ? type : typeof type) + "." + info));
16887 }
16888 }
16889 }
16890
16891 var fiber = createFiber(fiberTag, pendingProps, key, mode);
16892 fiber.elementType = type;
16893 fiber.type = resolvedType;
16894 fiber.lanes = lanes;
16895
16896 {
16897 fiber._debugOwner = owner;
16898 }
16899
16900 return fiber;
16901 }
16902 function createFiberFromElement(element, mode, lanes) {
16903 var owner = null;
16904
16905 {
16906 owner = element._owner;
16907 }
16908
16909 var type = element.type;
16910 var key = element.key;
16911 var pendingProps = element.props;
16912 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, lanes);
16913
16914 {
16915 fiber._debugSource = element._source;
16916 fiber._debugOwner = element._owner;
16917 }
16918
16919 return fiber;
16920 }
16921 function createFiberFromFragment(elements, mode, lanes, key) {
16922 var fiber = createFiber(Fragment, elements, key, mode);
16923 fiber.lanes = lanes;
16924 return fiber;
16925 }
16926
16927 function createFiberFromProfiler(pendingProps, mode, lanes, key) {
16928 {
16929 if (typeof pendingProps.id !== 'string') {
16930 error('Profiler must specify an "id" of type `string` as a prop. Received the type `%s` instead.', typeof pendingProps.id);
16931 }
16932 }
16933
16934 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
16935 fiber.elementType = REACT_PROFILER_TYPE;
16936 fiber.lanes = lanes;
16937
16938 {
16939 fiber.stateNode = {
16940 effectDuration: 0,
16941 passiveEffectDuration: 0
16942 };
16943 }
16944
16945 return fiber;
16946 }
16947
16948 function createFiberFromSuspense(pendingProps, mode, lanes, key) {
16949 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
16950 fiber.elementType = REACT_SUSPENSE_TYPE;
16951 fiber.lanes = lanes;
16952 return fiber;
16953 }
16954 function createFiberFromSuspenseList(pendingProps, mode, lanes, key) {
16955 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
16956 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
16957 fiber.lanes = lanes;
16958 return fiber;
16959 }
16960 function createFiberFromOffscreen(pendingProps, mode, lanes, key) {
16961 var fiber = createFiber(OffscreenComponent, pendingProps, key, mode);
16962 fiber.elementType = REACT_OFFSCREEN_TYPE;
16963 fiber.lanes = lanes;
16964 var primaryChildInstance = {};
16965 fiber.stateNode = primaryChildInstance;
16966 return fiber;
16967 }
16968 function createFiberFromText(content, mode, lanes) {
16969 var fiber = createFiber(HostText, content, null, mode);
16970 fiber.lanes = lanes;
16971 return fiber;
16972 }
16973 function createFiberFromPortal(portal, mode, lanes) {
16974 var pendingProps = portal.children !== null ? portal.children : [];
16975 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
16976 fiber.lanes = lanes;
16977 fiber.stateNode = {
16978 containerInfo: portal.containerInfo,
16979 pendingChildren: null,
16980 // Used by persistent updates
16981 implementation: portal.implementation
16982 };
16983 return fiber;
16984 } // Used for stashing WIP properties to replay failed work in DEV.
16985
16986 function FiberRootNode(containerInfo, tag, hydrate, identifierPrefix, onRecoverableError) {
16987 this.tag = tag;
16988 this.containerInfo = containerInfo;
16989 this.pendingChildren = null;
16990 this.current = null;
16991 this.pingCache = null;
16992 this.finishedWork = null;
16993 this.timeoutHandle = noTimeout;
16994 this.context = null;
16995 this.pendingContext = null;
16996 this.callbackNode = null;
16997 this.callbackPriority = NoLane;
16998 this.eventTimes = createLaneMap(NoLanes);
16999 this.expirationTimes = createLaneMap(NoTimestamp);
17000 this.pendingLanes = NoLanes;
17001 this.suspendedLanes = NoLanes;
17002 this.pingedLanes = NoLanes;
17003 this.expiredLanes = NoLanes;
17004 this.mutableReadLanes = NoLanes;
17005 this.finishedLanes = NoLanes;
17006 this.entangledLanes = NoLanes;
17007 this.entanglements = createLaneMap(NoLanes);
17008 this.identifierPrefix = identifierPrefix;
17009 this.onRecoverableError = onRecoverableError;
17010
17011 {
17012 this.effectDuration = 0;
17013 this.passiveEffectDuration = 0;
17014 }
17015
17016 {
17017 switch (tag) {
17018 case ConcurrentRoot:
17019 this._debugRootType = hydrate ? 'hydrateRoot()' : 'createRoot()';
17020 break;
17021
17022 case LegacyRoot:
17023 this._debugRootType = hydrate ? 'hydrate()' : 'render()';
17024 break;
17025 }
17026 }
17027 }
17028
17029 function createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, // TODO: We have several of these arguments that are conceptually part of the
17030 // host config, but because they are passed in at runtime, we have to thread
17031 // them through the root constructor. Perhaps we should put them all into a
17032 // single type, like a DynamicHostConfig that is defined by the renderer.
17033 identifierPrefix, onRecoverableError, transitionCallbacks) {
17034 var root = new FiberRootNode(containerInfo, tag, hydrate, identifierPrefix, onRecoverableError);
17035 // stateNode is any.
17036
17037
17038 var uninitializedFiber = createHostRootFiber(tag, isStrictMode);
17039 root.current = uninitializedFiber;
17040 uninitializedFiber.stateNode = root;
17041
17042 {
17043 var _initialState = {
17044 element: initialChildren,
17045 isDehydrated: hydrate,
17046 cache: null,
17047 // not enabled yet
17048 transitions: null
17049 };
17050 uninitializedFiber.memoizedState = _initialState;
17051 }
17052
17053 initializeUpdateQueue(uninitializedFiber);
17054 return root;
17055 }
17056
17057 var ReactVersion = '18.0.0-fc46dba67-20220329';
17058
17059 var didWarnAboutNestedUpdates;
17060
17061 {
17062 didWarnAboutNestedUpdates = false;
17063 }
17064
17065 function getContextForSubtree(parentComponent) {
17066 if (!parentComponent) {
17067 return emptyContextObject;
17068 }
17069
17070 var fiber = get(parentComponent);
17071 var parentContext = findCurrentUnmaskedContext(fiber);
17072
17073 if (fiber.tag === ClassComponent) {
17074 var Component = fiber.type;
17075
17076 if (isContextProvider(Component)) {
17077 return processChildContext(fiber, Component, parentContext);
17078 }
17079 }
17080
17081 return parentContext;
17082 }
17083
17084 function createContainer(containerInfo, tag, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError, transitionCallbacks) {
17085 var hydrate = false;
17086 var initialChildren = null;
17087 return createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError);
17088 }
17089 function updateContainer(element, container, parentComponent, callback) {
17090 {
17091 onScheduleRoot(container, element);
17092 }
17093
17094 var current$1 = container.current;
17095 var eventTime = requestEventTime();
17096 var lane = requestUpdateLane(current$1);
17097
17098 var context = getContextForSubtree(parentComponent);
17099
17100 if (container.context === null) {
17101 container.context = context;
17102 } else {
17103 container.pendingContext = context;
17104 }
17105
17106 {
17107 if (isRendering && current !== null && !didWarnAboutNestedUpdates) {
17108 didWarnAboutNestedUpdates = true;
17109
17110 error('Render methods should be a pure function of props and state; ' + 'triggering nested component updates from render is not allowed. ' + 'If necessary, trigger nested updates in componentDidUpdate.\n\n' + 'Check the render method of %s.', getComponentNameFromFiber(current) || 'Unknown');
17111 }
17112 }
17113
17114 var update = createUpdate(eventTime, lane); // Caution: React DevTools currently depends on this property
17115 // being called "element".
17116
17117 update.payload = {
17118 element: element
17119 };
17120 callback = callback === undefined ? null : callback;
17121
17122 if (callback !== null) {
17123 {
17124 if (typeof callback !== 'function') {
17125 error('render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
17126 }
17127 }
17128
17129 update.callback = callback;
17130 }
17131
17132 enqueueUpdate(current$1, update);
17133 var root = scheduleUpdateOnFiber(current$1, lane, eventTime);
17134
17135 if (root !== null) {
17136 entangleTransitions(root, current$1, lane);
17137 }
17138
17139 return lane;
17140 }
17141 function getPublicRootInstance(container) {
17142 var containerFiber = container.current;
17143
17144 if (!containerFiber.child) {
17145 return null;
17146 }
17147
17148 switch (containerFiber.child.tag) {
17149 case HostComponent:
17150 return getPublicInstance(containerFiber.child.stateNode);
17151
17152 default:
17153 return containerFiber.child.stateNode;
17154 }
17155 }
17156
17157 var shouldErrorImpl = function (fiber) {
17158 return null;
17159 };
17160
17161 function shouldError(fiber) {
17162 return shouldErrorImpl(fiber);
17163 }
17164
17165 var shouldSuspendImpl = function (fiber) {
17166 return false;
17167 };
17168
17169 function shouldSuspend(fiber) {
17170 return shouldSuspendImpl(fiber);
17171 }
17172 var overrideHookState = null;
17173 var overrideHookStateDeletePath = null;
17174 var overrideHookStateRenamePath = null;
17175 var overrideProps = null;
17176 var overridePropsDeletePath = null;
17177 var overridePropsRenamePath = null;
17178 var scheduleUpdate = null;
17179 var setErrorHandler = null;
17180 var setSuspenseHandler = null;
17181
17182 {
17183 var copyWithDeleteImpl = function (obj, path, index) {
17184 var key = path[index];
17185 var updated = isArray(obj) ? obj.slice() : assign({}, obj);
17186
17187 if (index + 1 === path.length) {
17188 if (isArray(updated)) {
17189 updated.splice(key, 1);
17190 } else {
17191 delete updated[key];
17192 }
17193
17194 return updated;
17195 } // $FlowFixMe number or string is fine here
17196
17197
17198 updated[key] = copyWithDeleteImpl(obj[key], path, index + 1);
17199 return updated;
17200 };
17201
17202 var copyWithDelete = function (obj, path) {
17203 return copyWithDeleteImpl(obj, path, 0);
17204 };
17205
17206 var copyWithRenameImpl = function (obj, oldPath, newPath, index) {
17207 var oldKey = oldPath[index];
17208 var updated = isArray(obj) ? obj.slice() : assign({}, obj);
17209
17210 if (index + 1 === oldPath.length) {
17211 var newKey = newPath[index]; // $FlowFixMe number or string is fine here
17212
17213 updated[newKey] = updated[oldKey];
17214
17215 if (isArray(updated)) {
17216 updated.splice(oldKey, 1);
17217 } else {
17218 delete updated[oldKey];
17219 }
17220 } else {
17221 // $FlowFixMe number or string is fine here
17222 updated[oldKey] = copyWithRenameImpl( // $FlowFixMe number or string is fine here
17223 obj[oldKey], oldPath, newPath, index + 1);
17224 }
17225
17226 return updated;
17227 };
17228
17229 var copyWithRename = function (obj, oldPath, newPath) {
17230 if (oldPath.length !== newPath.length) {
17231 warn('copyWithRename() expects paths of the same length');
17232
17233 return;
17234 } else {
17235 for (var i = 0; i < newPath.length - 1; i++) {
17236 if (oldPath[i] !== newPath[i]) {
17237 warn('copyWithRename() expects paths to be the same except for the deepest key');
17238
17239 return;
17240 }
17241 }
17242 }
17243
17244 return copyWithRenameImpl(obj, oldPath, newPath, 0);
17245 };
17246
17247 var copyWithSetImpl = function (obj, path, index, value) {
17248 if (index >= path.length) {
17249 return value;
17250 }
17251
17252 var key = path[index];
17253 var updated = isArray(obj) ? obj.slice() : assign({}, obj); // $FlowFixMe number or string is fine here
17254
17255 updated[key] = copyWithSetImpl(obj[key], path, index + 1, value);
17256 return updated;
17257 };
17258
17259 var copyWithSet = function (obj, path, value) {
17260 return copyWithSetImpl(obj, path, 0, value);
17261 };
17262
17263 var findHook = function (fiber, id) {
17264 // For now, the "id" of stateful hooks is just the stateful hook index.
17265 // This may change in the future with e.g. nested hooks.
17266 var currentHook = fiber.memoizedState;
17267
17268 while (currentHook !== null && id > 0) {
17269 currentHook = currentHook.next;
17270 id--;
17271 }
17272
17273 return currentHook;
17274 }; // Support DevTools editable values for useState and useReducer.
17275
17276
17277 overrideHookState = function (fiber, id, path, value) {
17278 var hook = findHook(fiber, id);
17279
17280 if (hook !== null) {
17281 var newState = copyWithSet(hook.memoizedState, path, value);
17282 hook.memoizedState = newState;
17283 hook.baseState = newState; // We aren't actually adding an update to the queue,
17284 // because there is no update we can add for useReducer hooks that won't trigger an error.
17285 // (There's no appropriate action type for DevTools overrides.)
17286 // As a result though, React will see the scheduled update as a noop and bailout.
17287 // Shallow cloning props works as a workaround for now to bypass the bailout check.
17288
17289 fiber.memoizedProps = assign({}, fiber.memoizedProps);
17290 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
17291 }
17292 };
17293
17294 overrideHookStateDeletePath = function (fiber, id, path) {
17295 var hook = findHook(fiber, id);
17296
17297 if (hook !== null) {
17298 var newState = copyWithDelete(hook.memoizedState, path);
17299 hook.memoizedState = newState;
17300 hook.baseState = newState; // We aren't actually adding an update to the queue,
17301 // because there is no update we can add for useReducer hooks that won't trigger an error.
17302 // (There's no appropriate action type for DevTools overrides.)
17303 // As a result though, React will see the scheduled update as a noop and bailout.
17304 // Shallow cloning props works as a workaround for now to bypass the bailout check.
17305
17306 fiber.memoizedProps = assign({}, fiber.memoizedProps);
17307 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
17308 }
17309 };
17310
17311 overrideHookStateRenamePath = function (fiber, id, oldPath, newPath) {
17312 var hook = findHook(fiber, id);
17313
17314 if (hook !== null) {
17315 var newState = copyWithRename(hook.memoizedState, oldPath, newPath);
17316 hook.memoizedState = newState;
17317 hook.baseState = newState; // We aren't actually adding an update to the queue,
17318 // because there is no update we can add for useReducer hooks that won't trigger an error.
17319 // (There's no appropriate action type for DevTools overrides.)
17320 // As a result though, React will see the scheduled update as a noop and bailout.
17321 // Shallow cloning props works as a workaround for now to bypass the bailout check.
17322
17323 fiber.memoizedProps = assign({}, fiber.memoizedProps);
17324 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
17325 }
17326 }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
17327
17328
17329 overrideProps = function (fiber, path, value) {
17330 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
17331
17332 if (fiber.alternate) {
17333 fiber.alternate.pendingProps = fiber.pendingProps;
17334 }
17335
17336 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
17337 };
17338
17339 overridePropsDeletePath = function (fiber, path) {
17340 fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path);
17341
17342 if (fiber.alternate) {
17343 fiber.alternate.pendingProps = fiber.pendingProps;
17344 }
17345
17346 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
17347 };
17348
17349 overridePropsRenamePath = function (fiber, oldPath, newPath) {
17350 fiber.pendingProps = copyWithRename(fiber.memoizedProps, oldPath, newPath);
17351
17352 if (fiber.alternate) {
17353 fiber.alternate.pendingProps = fiber.pendingProps;
17354 }
17355
17356 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
17357 };
17358
17359 scheduleUpdate = function (fiber) {
17360 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
17361 };
17362
17363 setErrorHandler = function (newShouldErrorImpl) {
17364 shouldErrorImpl = newShouldErrorImpl;
17365 };
17366
17367 setSuspenseHandler = function (newShouldSuspendImpl) {
17368 shouldSuspendImpl = newShouldSuspendImpl;
17369 };
17370 }
17371
17372 function findHostInstanceByFiber(fiber) {
17373 var hostFiber = findCurrentHostFiber(fiber);
17374
17375 if (hostFiber === null) {
17376 return null;
17377 }
17378
17379 return hostFiber.stateNode;
17380 }
17381
17382 function emptyFindFiberByHostInstance(instance) {
17383 return null;
17384 }
17385
17386 function getCurrentFiberForDevTools() {
17387 return current;
17388 }
17389
17390 function injectIntoDevTools(devToolsConfig) {
17391 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
17392 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
17393 return injectInternals({
17394 bundleType: devToolsConfig.bundleType,
17395 version: devToolsConfig.version,
17396 rendererPackageName: devToolsConfig.rendererPackageName,
17397 rendererConfig: devToolsConfig.rendererConfig,
17398 overrideHookState: overrideHookState,
17399 overrideHookStateDeletePath: overrideHookStateDeletePath,
17400 overrideHookStateRenamePath: overrideHookStateRenamePath,
17401 overrideProps: overrideProps,
17402 overridePropsDeletePath: overridePropsDeletePath,
17403 overridePropsRenamePath: overridePropsRenamePath,
17404 setErrorHandler: setErrorHandler,
17405 setSuspenseHandler: setSuspenseHandler,
17406 scheduleUpdate: scheduleUpdate,
17407 currentDispatcherRef: ReactCurrentDispatcher,
17408 findHostInstanceByFiber: findHostInstanceByFiber,
17409 findFiberByHostInstance: findFiberByHostInstance || emptyFindFiberByHostInstance,
17410 // React Refresh
17411 findHostInstancesForRefresh: findHostInstancesForRefresh ,
17412 scheduleRefresh: scheduleRefresh ,
17413 scheduleRoot: scheduleRoot ,
17414 setRefreshHandler: setRefreshHandler ,
17415 // Enables DevTools to append owner stacks to error messages in DEV mode.
17416 getCurrentFiber: getCurrentFiberForDevTools ,
17417 // Enables DevTools to detect reconciler version rather than renderer version
17418 // which may not match for third party renderers.
17419 reconcilerVersion: ReactVersion
17420 });
17421 }
17422
17423 var act = React.unstable_act; // TODO: Remove from public bundle
17424
17425 var defaultTestOptions = {
17426 createNodeMock: function () {
17427 return null;
17428 }
17429 };
17430
17431 function toJSON(inst) {
17432 if (inst.isHidden) {
17433 // Omit timed out children from output entirely. This seems like the least
17434 // surprising behavior. We could perhaps add a separate API that includes
17435 // them, if it turns out people need it.
17436 return null;
17437 }
17438
17439 switch (inst.tag) {
17440 case 'TEXT':
17441 return inst.text;
17442
17443 case 'INSTANCE':
17444 {
17445 /* eslint-disable no-unused-vars */
17446 // We don't include the `children` prop in JSON.
17447 // Instead, we will include the actual rendered children.
17448 var _inst$props = inst.props,
17449 children = _inst$props.children,
17450 props = _objectWithoutPropertiesLoose(_inst$props, ["children"]);
17451 /* eslint-enable */
17452
17453
17454 var renderedChildren = null;
17455
17456 if (inst.children && inst.children.length) {
17457 for (var i = 0; i < inst.children.length; i++) {
17458 var renderedChild = toJSON(inst.children[i]);
17459
17460 if (renderedChild !== null) {
17461 if (renderedChildren === null) {
17462 renderedChildren = [renderedChild];
17463 } else {
17464 renderedChildren.push(renderedChild);
17465 }
17466 }
17467 }
17468 }
17469
17470 var json = {
17471 type: inst.type,
17472 props: props,
17473 children: renderedChildren
17474 };
17475 Object.defineProperty(json, '$$typeof', {
17476 value: Symbol.for('react.test.json')
17477 });
17478 return json;
17479 }
17480
17481 default:
17482 throw new Error("Unexpected node type in toJSON: " + inst.tag);
17483 }
17484 }
17485
17486 function childrenToTree(node) {
17487 if (!node) {
17488 return null;
17489 }
17490
17491 var children = nodeAndSiblingsArray(node);
17492
17493 if (children.length === 0) {
17494 return null;
17495 } else if (children.length === 1) {
17496 return toTree(children[0]);
17497 }
17498
17499 return flatten(children.map(toTree));
17500 }
17501
17502 function nodeAndSiblingsArray(nodeWithSibling) {
17503 var array = [];
17504 var node = nodeWithSibling;
17505
17506 while (node != null) {
17507 array.push(node);
17508 node = node.sibling;
17509 }
17510
17511 return array;
17512 }
17513
17514 function flatten(arr) {
17515 var result = [];
17516 var stack = [{
17517 i: 0,
17518 array: arr
17519 }];
17520
17521 while (stack.length) {
17522 var n = stack.pop();
17523
17524 while (n.i < n.array.length) {
17525 var el = n.array[n.i];
17526 n.i += 1;
17527
17528 if (isArray(el)) {
17529 stack.push(n);
17530 stack.push({
17531 i: 0,
17532 array: el
17533 });
17534 break;
17535 }
17536
17537 result.push(el);
17538 }
17539 }
17540
17541 return result;
17542 }
17543
17544 function toTree(node) {
17545 if (node == null) {
17546 return null;
17547 }
17548
17549 switch (node.tag) {
17550 case HostRoot:
17551 return childrenToTree(node.child);
17552
17553 case HostPortal:
17554 return childrenToTree(node.child);
17555
17556 case ClassComponent:
17557 return {
17558 nodeType: 'component',
17559 type: node.type,
17560 props: assign({}, node.memoizedProps),
17561 instance: node.stateNode,
17562 rendered: childrenToTree(node.child)
17563 };
17564
17565 case FunctionComponent:
17566 case SimpleMemoComponent:
17567 return {
17568 nodeType: 'component',
17569 type: node.type,
17570 props: assign({}, node.memoizedProps),
17571 instance: null,
17572 rendered: childrenToTree(node.child)
17573 };
17574
17575 case HostComponent:
17576 {
17577 return {
17578 nodeType: 'host',
17579 type: node.type,
17580 props: assign({}, node.memoizedProps),
17581 instance: null,
17582 // TODO: use createNodeMock here somehow?
17583 rendered: flatten(nodeAndSiblingsArray(node.child).map(toTree))
17584 };
17585 }
17586
17587 case HostText:
17588 return node.stateNode.text;
17589
17590 case Fragment:
17591 case ContextProvider:
17592 case ContextConsumer:
17593 case Mode:
17594 case Profiler:
17595 case ForwardRef:
17596 case MemoComponent:
17597 case IncompleteClassComponent:
17598 case ScopeComponent:
17599 return childrenToTree(node.child);
17600
17601 default:
17602 throw new Error("toTree() does not yet know how to handle nodes with tag=" + node.tag);
17603 }
17604 }
17605
17606 var validWrapperTypes = new Set([FunctionComponent, ClassComponent, HostComponent, ForwardRef, MemoComponent, SimpleMemoComponent, // Normally skipped, but used when there's more than one root child.
17607 HostRoot]);
17608
17609 function getChildren(parent) {
17610 var children = [];
17611 var startingNode = parent;
17612 var node = startingNode;
17613
17614 if (node.child === null) {
17615 return children;
17616 }
17617
17618 node.child.return = node;
17619 node = node.child;
17620
17621 outer: while (true) {
17622 var descend = false;
17623
17624 if (validWrapperTypes.has(node.tag)) {
17625 children.push(wrapFiber(node));
17626 } else if (node.tag === HostText) {
17627 {
17628 checkPropStringCoercion(node.memoizedProps, 'memoizedProps');
17629 }
17630
17631 children.push('' + node.memoizedProps);
17632 } else {
17633 descend = true;
17634 }
17635
17636 if (descend && node.child !== null) {
17637 node.child.return = node;
17638 node = node.child;
17639 continue;
17640 }
17641
17642 while (node.sibling === null) {
17643 if (node.return === startingNode) {
17644 break outer;
17645 }
17646
17647 node = node.return;
17648 }
17649
17650 node.sibling.return = node.return;
17651 node = node.sibling;
17652 }
17653
17654 return children;
17655 }
17656
17657 var ReactTestInstance = /*#__PURE__*/function () {
17658 var _proto = ReactTestInstance.prototype;
17659
17660 _proto._currentFiber = function _currentFiber() {
17661 // Throws if this component has been unmounted.
17662 var fiber = findCurrentFiberUsingSlowPath(this._fiber);
17663
17664 if (fiber === null) {
17665 throw new Error("Can't read from currently-mounting component. This error is likely " + 'caused by a bug in React. Please file an issue.');
17666 }
17667
17668 return fiber;
17669 };
17670
17671 function ReactTestInstance(fiber) {
17672 if (!validWrapperTypes.has(fiber.tag)) {
17673 throw new Error("Unexpected object passed to ReactTestInstance constructor (tag: " + fiber.tag + "). " + 'This is probably a bug in React.');
17674 }
17675
17676 this._fiber = fiber;
17677 }
17678
17679 // Custom search functions
17680 _proto.find = function find(predicate) {
17681 return expectOne(this.findAll(predicate, {
17682 deep: false
17683 }), "matching custom predicate: " + predicate.toString());
17684 };
17685
17686 _proto.findByType = function findByType(type) {
17687 return expectOne(this.findAllByType(type, {
17688 deep: false
17689 }), "with node type: \"" + (getComponentNameFromType(type) || 'Unknown') + "\"");
17690 };
17691
17692 _proto.findByProps = function findByProps(props) {
17693 return expectOne(this.findAllByProps(props, {
17694 deep: false
17695 }), "with props: " + JSON.stringify(props));
17696 };
17697
17698 _proto.findAll = function findAll(predicate) {
17699 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
17700 return _findAll(this, predicate, options);
17701 };
17702
17703 _proto.findAllByType = function findAllByType(type) {
17704 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
17705 return _findAll(this, function (node) {
17706 return node.type === type;
17707 }, options);
17708 };
17709
17710 _proto.findAllByProps = function findAllByProps(props) {
17711 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
17712 return _findAll(this, function (node) {
17713 return node.props && propsMatch(node.props, props);
17714 }, options);
17715 };
17716
17717 _createClass(ReactTestInstance, [{
17718 key: "instance",
17719 get: function () {
17720 if (this._fiber.tag === HostComponent) {
17721 return getPublicInstance(this._fiber.stateNode);
17722 } else {
17723 return this._fiber.stateNode;
17724 }
17725 }
17726 }, {
17727 key: "type",
17728 get: function () {
17729 return this._fiber.type;
17730 }
17731 }, {
17732 key: "props",
17733 get: function () {
17734 return this._currentFiber().memoizedProps;
17735 }
17736 }, {
17737 key: "parent",
17738 get: function () {
17739 var parent = this._fiber.return;
17740
17741 while (parent !== null) {
17742 if (validWrapperTypes.has(parent.tag)) {
17743 if (parent.tag === HostRoot) {
17744 // Special case: we only "materialize" instances for roots
17745 // if they have more than a single child. So we'll check that now.
17746 if (getChildren(parent).length < 2) {
17747 return null;
17748 }
17749 }
17750
17751 return wrapFiber(parent);
17752 }
17753
17754 parent = parent.return;
17755 }
17756
17757 return null;
17758 }
17759 }, {
17760 key: "children",
17761 get: function () {
17762 return getChildren(this._currentFiber());
17763 }
17764 }]);
17765
17766 return ReactTestInstance;
17767 }();
17768
17769 function _findAll(root, predicate, options) {
17770 var deep = options ? options.deep : true;
17771 var results = [];
17772
17773 if (predicate(root)) {
17774 results.push(root);
17775
17776 if (!deep) {
17777 return results;
17778 }
17779 }
17780
17781 root.children.forEach(function (child) {
17782 if (typeof child === 'string') {
17783 return;
17784 }
17785
17786 results.push.apply(results, _findAll(child, predicate, options));
17787 });
17788 return results;
17789 }
17790
17791 function expectOne(all, message) {
17792 if (all.length === 1) {
17793 return all[0];
17794 }
17795
17796 var prefix = all.length === 0 ? 'No instances found ' : "Expected 1 but found " + all.length + " instances ";
17797 throw new Error(prefix + message);
17798 }
17799
17800 function propsMatch(props, filter) {
17801 for (var key in filter) {
17802 if (props[key] !== filter[key]) {
17803 return false;
17804 }
17805 }
17806
17807 return true;
17808 }
17809
17810 function onRecoverableError(error$1) {
17811 // TODO: Expose onRecoverableError option to userspace
17812 // eslint-disable-next-line react-internal/no-production-logging, react-internal/warning-args
17813 error(error$1);
17814 }
17815
17816 function create(element, options) {
17817 var createNodeMock = defaultTestOptions.createNodeMock;
17818 var isConcurrent = false;
17819 var isStrictMode = false;
17820 var concurrentUpdatesByDefault = null;
17821
17822 if (typeof options === 'object' && options !== null) {
17823 if (typeof options.createNodeMock === 'function') {
17824 createNodeMock = options.createNodeMock;
17825 }
17826
17827 if (options.unstable_isConcurrent === true) {
17828 isConcurrent = true;
17829 }
17830
17831 if (options.unstable_strictMode === true) {
17832 isStrictMode = true;
17833 }
17834 }
17835
17836 var container = {
17837 children: [],
17838 createNodeMock: createNodeMock,
17839 tag: 'CONTAINER'
17840 };
17841 var root = createContainer(container, isConcurrent ? ConcurrentRoot : LegacyRoot, null, isStrictMode, concurrentUpdatesByDefault, '', onRecoverableError);
17842
17843 if (root == null) {
17844 throw new Error('something went wrong');
17845 }
17846
17847 updateContainer(element, root, null, null);
17848 var entry = {
17849 _Scheduler: Scheduler,
17850 root: undefined,
17851 // makes flow happy
17852 // we define a 'getter' for 'root' below using 'Object.defineProperty'
17853 toJSON: function () {
17854 if (root == null || root.current == null || container == null) {
17855 return null;
17856 }
17857
17858 if (container.children.length === 0) {
17859 return null;
17860 }
17861
17862 if (container.children.length === 1) {
17863 return toJSON(container.children[0]);
17864 }
17865
17866 if (container.children.length === 2 && container.children[0].isHidden === true && container.children[1].isHidden === false) {
17867 // Omit timed out children from output entirely, including the fact that we
17868 // temporarily wrap fallback and timed out children in an array.
17869 return toJSON(container.children[1]);
17870 }
17871
17872 var renderedChildren = null;
17873
17874 if (container.children && container.children.length) {
17875 for (var i = 0; i < container.children.length; i++) {
17876 var renderedChild = toJSON(container.children[i]);
17877
17878 if (renderedChild !== null) {
17879 if (renderedChildren === null) {
17880 renderedChildren = [renderedChild];
17881 } else {
17882 renderedChildren.push(renderedChild);
17883 }
17884 }
17885 }
17886 }
17887
17888 return renderedChildren;
17889 },
17890 toTree: function () {
17891 if (root == null || root.current == null) {
17892 return null;
17893 }
17894
17895 return toTree(root.current);
17896 },
17897 update: function (newElement) {
17898 if (root == null || root.current == null) {
17899 return;
17900 }
17901
17902 updateContainer(newElement, root, null, null);
17903 },
17904 unmount: function () {
17905 if (root == null || root.current == null) {
17906 return;
17907 }
17908
17909 updateContainer(null, root, null, null);
17910 container = null;
17911 root = null;
17912 },
17913 getInstance: function () {
17914 if (root == null || root.current == null) {
17915 return null;
17916 }
17917
17918 return getPublicRootInstance(root);
17919 },
17920 unstable_flushSync: flushSync
17921 };
17922 Object.defineProperty(entry, 'root', {
17923 configurable: true,
17924 enumerable: true,
17925 get: function () {
17926 if (root === null) {
17927 throw new Error("Can't access .root on unmounted test renderer");
17928 }
17929
17930 var children = getChildren(root.current);
17931
17932 if (children.length === 0) {
17933 throw new Error("Can't access .root on unmounted test renderer");
17934 } else if (children.length === 1) {
17935 // Normally, we skip the root and just give you the child.
17936 return children[0];
17937 } else {
17938 // However, we give you the root if there's more than one root child.
17939 // We could make this the behavior for all cases but it would be a breaking change.
17940 return wrapFiber(root.current);
17941 }
17942 }
17943 });
17944 return entry;
17945 }
17946
17947 var fiberToWrapper = new WeakMap();
17948
17949 function wrapFiber(fiber) {
17950 var wrapper = fiberToWrapper.get(fiber);
17951
17952 if (wrapper === undefined && fiber.alternate !== null) {
17953 wrapper = fiberToWrapper.get(fiber.alternate);
17954 }
17955
17956 if (wrapper === undefined) {
17957 wrapper = new ReactTestInstance(fiber);
17958 fiberToWrapper.set(fiber, wrapper);
17959 }
17960
17961 return wrapper;
17962 } // Enable ReactTestRenderer to be used to test DevTools integration.
17963
17964
17965 injectIntoDevTools({
17966 findFiberByHostInstance: function () {
17967 throw new Error('TestRenderer does not support findFiberByHostInstance()');
17968 },
17969 bundleType: 1 ,
17970 version: ReactVersion,
17971 rendererPackageName: 'react-test-renderer'
17972 });
17973
17974 exports._Scheduler = Scheduler;
17975 exports.act = act;
17976 exports.create = create;
17977 exports.unstable_batchedUpdates = batchedUpdates;
17978
17979})));