UNPKG

646 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
11'use strict';
12
13if (process.env.NODE_ENV !== "production") {
14 (function() {
15'use strict';
16
17var React = require('react');
18var Scheduler = require('scheduler/unstable_mock');
19var Scheduler$1 = require('scheduler');
20
21var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
22
23// by calls to these methods by a Babel plugin.
24//
25// In PROD (or in packages without access to React internals),
26// they are left as they are instead.
27
28function warn(format) {
29 {
30 {
31 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
32 args[_key - 1] = arguments[_key];
33 }
34
35 printWarning('warn', format, args);
36 }
37 }
38}
39function error(format) {
40 {
41 {
42 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
43 args[_key2 - 1] = arguments[_key2];
44 }
45
46 printWarning('error', format, args);
47 }
48 }
49}
50
51function printWarning(level, format, args) {
52 // When changing this logic, you might want to also
53 // update consoleWithStackDev.www.js as well.
54 {
55 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
56 var stack = ReactDebugCurrentFrame.getStackAddendum();
57
58 if (stack !== '') {
59 format += '%s';
60 args = args.concat([stack]);
61 } // eslint-disable-next-line react-internal/safe-string-coercion
62
63
64 var argsWithFormat = args.map(function (item) {
65 return String(item);
66 }); // Careful: RN currently depends on this prefix
67
68 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
69 // breaks IE9: https://github.com/facebook/react/issues/13610
70 // eslint-disable-next-line react-internal/no-production-logging
71
72 Function.prototype.apply.call(console[level], console, argsWithFormat);
73 }
74}
75
76function _defineProperties(target, props) {
77 for (var i = 0; i < props.length; i++) {
78 var descriptor = props[i];
79 descriptor.enumerable = descriptor.enumerable || false;
80 descriptor.configurable = true;
81 if ("value" in descriptor) descriptor.writable = true;
82 Object.defineProperty(target, descriptor.key, descriptor);
83 }
84}
85
86function _createClass(Constructor, protoProps, staticProps) {
87 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
88 if (staticProps) _defineProperties(Constructor, staticProps);
89 return Constructor;
90}
91
92function _objectWithoutPropertiesLoose(source, excluded) {
93 if (source == null) return {};
94 var target = {};
95 var sourceKeys = Object.keys(source);
96 var key, i;
97
98 for (i = 0; i < sourceKeys.length; i++) {
99 key = sourceKeys[i];
100 if (excluded.indexOf(key) >= 0) continue;
101 target[key] = source[key];
102 }
103
104 return target;
105}
106
107var assign = Object.assign;
108
109/**
110 * `ReactInstanceMap` maintains a mapping from a public facing stateful
111 * instance (key) and the internal representation (value). This allows public
112 * methods to accept the user facing instance as an argument and map them back
113 * to internal methods.
114 *
115 * Note that this module is currently shared and assumed to be stateless.
116 * If this becomes an actual Map, that will break.
117 */
118function get(key) {
119 return key._reactInternals;
120}
121function set(key, value) {
122 key._reactInternals = value;
123}
124
125var enableSchedulingProfiler = false;
126var enableProfilerTimer = true;
127var enableProfilerCommitHooks = true;
128var warnAboutStringRefs = false;
129var enableSuspenseAvoidThisFallback = false;
130var enableNewReconciler = false;
131var enableLazyContextPropagation = false;
132var enableLegacyHidden = false;
133
134var FunctionComponent = 0;
135var ClassComponent = 1;
136var IndeterminateComponent = 2; // Before we know whether it is function or class
137
138var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
139
140var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
141
142var HostComponent = 5;
143var HostText = 6;
144var Fragment = 7;
145var Mode = 8;
146var ContextConsumer = 9;
147var ContextProvider = 10;
148var ForwardRef = 11;
149var Profiler = 12;
150var SuspenseComponent = 13;
151var MemoComponent = 14;
152var SimpleMemoComponent = 15;
153var LazyComponent = 16;
154var IncompleteClassComponent = 17;
155var DehydratedFragment = 18;
156var SuspenseListComponent = 19;
157var ScopeComponent = 21;
158var OffscreenComponent = 22;
159var LegacyHiddenComponent = 23;
160var CacheComponent = 24;
161var TracingMarkerComponent = 25;
162
163// ATTENTION
164// When adding new symbols to this file,
165// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
166// The Symbol used to tag the ReactElement-like types.
167var REACT_ELEMENT_TYPE = Symbol.for('react.element');
168var REACT_PORTAL_TYPE = Symbol.for('react.portal');
169var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
170var REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode');
171var REACT_PROFILER_TYPE = Symbol.for('react.profiler');
172var REACT_PROVIDER_TYPE = Symbol.for('react.provider');
173var REACT_CONTEXT_TYPE = Symbol.for('react.context');
174var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
175var REACT_SUSPENSE_TYPE = Symbol.for('react.suspense');
176var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list');
177var REACT_MEMO_TYPE = Symbol.for('react.memo');
178var REACT_LAZY_TYPE = Symbol.for('react.lazy');
179var REACT_SCOPE_TYPE = Symbol.for('react.scope');
180var REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for('react.debug_trace_mode');
181var REACT_OFFSCREEN_TYPE = Symbol.for('react.offscreen');
182var REACT_LEGACY_HIDDEN_TYPE = Symbol.for('react.legacy_hidden');
183var REACT_CACHE_TYPE = Symbol.for('react.cache');
184var REACT_TRACING_MARKER_TYPE = Symbol.for('react.tracing_marker');
185var MAYBE_ITERATOR_SYMBOL = Symbol.iterator;
186var FAUX_ITERATOR_SYMBOL = '@@iterator';
187function getIteratorFn(maybeIterable) {
188 if (maybeIterable === null || typeof maybeIterable !== 'object') {
189 return null;
190 }
191
192 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
193
194 if (typeof maybeIterator === 'function') {
195 return maybeIterator;
196 }
197
198 return null;
199}
200
201function getWrappedName(outerType, innerType, wrapperName) {
202 var displayName = outerType.displayName;
203
204 if (displayName) {
205 return displayName;
206 }
207
208 var functionName = innerType.displayName || innerType.name || '';
209 return functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName;
210} // Keep in sync with react-reconciler/getComponentNameFromFiber
211
212
213function getContextName(type) {
214 return type.displayName || 'Context';
215} // Note that the reconciler package should generally prefer to use getComponentNameFromFiber() instead.
216
217
218function getComponentNameFromType(type) {
219 if (type == null) {
220 // Host root, text node or just invalid type.
221 return null;
222 }
223
224 {
225 if (typeof type.tag === 'number') {
226 error('Received an unexpected object in getComponentNameFromType(). ' + 'This is likely a bug in React. Please file an issue.');
227 }
228 }
229
230 if (typeof type === 'function') {
231 return type.displayName || type.name || null;
232 }
233
234 if (typeof type === 'string') {
235 return type;
236 }
237
238 switch (type) {
239 case REACT_FRAGMENT_TYPE:
240 return 'Fragment';
241
242 case REACT_PORTAL_TYPE:
243 return 'Portal';
244
245 case REACT_PROFILER_TYPE:
246 return 'Profiler';
247
248 case REACT_STRICT_MODE_TYPE:
249 return 'StrictMode';
250
251 case REACT_SUSPENSE_TYPE:
252 return 'Suspense';
253
254 case REACT_SUSPENSE_LIST_TYPE:
255 return 'SuspenseList';
256
257 }
258
259 if (typeof type === 'object') {
260 switch (type.$$typeof) {
261 case REACT_CONTEXT_TYPE:
262 var context = type;
263 return getContextName(context) + '.Consumer';
264
265 case REACT_PROVIDER_TYPE:
266 var provider = type;
267 return getContextName(provider._context) + '.Provider';
268
269 case REACT_FORWARD_REF_TYPE:
270 return getWrappedName(type, type.render, 'ForwardRef');
271
272 case REACT_MEMO_TYPE:
273 var outerName = type.displayName || null;
274
275 if (outerName !== null) {
276 return outerName;
277 }
278
279 return getComponentNameFromType(type.type) || 'Memo';
280
281 case REACT_LAZY_TYPE:
282 {
283 var lazyComponent = type;
284 var payload = lazyComponent._payload;
285 var init = lazyComponent._init;
286
287 try {
288 return getComponentNameFromType(init(payload));
289 } catch (x) {
290 return null;
291 }
292 }
293
294 // eslint-disable-next-line no-fallthrough
295 }
296 }
297
298 return null;
299}
300
301function getWrappedName$1(outerType, innerType, wrapperName) {
302 var functionName = innerType.displayName || innerType.name || '';
303 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
304} // Keep in sync with shared/getComponentNameFromType
305
306
307function getContextName$1(type) {
308 return type.displayName || 'Context';
309}
310
311function getComponentNameFromFiber(fiber) {
312 var tag = fiber.tag,
313 type = fiber.type;
314
315 switch (tag) {
316 case CacheComponent:
317 return 'Cache';
318
319 case ContextConsumer:
320 var context = type;
321 return getContextName$1(context) + '.Consumer';
322
323 case ContextProvider:
324 var provider = type;
325 return getContextName$1(provider._context) + '.Provider';
326
327 case DehydratedFragment:
328 return 'DehydratedFragment';
329
330 case ForwardRef:
331 return getWrappedName$1(type, type.render, 'ForwardRef');
332
333 case Fragment:
334 return 'Fragment';
335
336 case HostComponent:
337 // Host component type is the display name (e.g. "div", "View")
338 return type;
339
340 case HostPortal:
341 return 'Portal';
342
343 case HostRoot:
344 return 'Root';
345
346 case HostText:
347 return 'Text';
348
349 case LazyComponent:
350 // Name comes from the type in this case; we don't have a tag.
351 return getComponentNameFromType(type);
352
353 case Mode:
354 if (type === REACT_STRICT_MODE_TYPE) {
355 // Don't be less specific than shared/getComponentNameFromType
356 return 'StrictMode';
357 }
358
359 return 'Mode';
360
361 case OffscreenComponent:
362 return 'Offscreen';
363
364 case Profiler:
365 return 'Profiler';
366
367 case ScopeComponent:
368 return 'Scope';
369
370 case SuspenseComponent:
371 return 'Suspense';
372
373 case SuspenseListComponent:
374 return 'SuspenseList';
375
376 case TracingMarkerComponent:
377 return 'TracingMarker';
378 // The display name for this tags come from the user-provided type:
379
380 case ClassComponent:
381 case FunctionComponent:
382 case IncompleteClassComponent:
383 case IndeterminateComponent:
384 case MemoComponent:
385 case SimpleMemoComponent:
386 if (typeof type === 'function') {
387 return type.displayName || type.name || null;
388 }
389
390 if (typeof type === 'string') {
391 return type;
392 }
393
394 break;
395
396 }
397
398 return null;
399}
400
401// Don't change these two values. They're used by React Dev Tools.
402var NoFlags =
403/* */
4040;
405var PerformedWork =
406/* */
4071; // You can change the rest (and add more).
408
409var Placement =
410/* */
4112;
412var Update =
413/* */
4144;
415var ChildDeletion =
416/* */
41716;
418var ContentReset =
419/* */
42032;
421var Callback =
422/* */
42364;
424var DidCapture =
425/* */
426128;
427var ForceClientRender =
428/* */
429256;
430var Ref =
431/* */
432512;
433var Snapshot =
434/* */
4351024;
436var Passive =
437/* */
4382048;
439var Hydrating =
440/* */
4414096;
442var Visibility =
443/* */
4448192;
445var StoreConsistency =
446/* */
44716384;
448var LifecycleEffectMask = Passive | Update | Callback | Ref | Snapshot | StoreConsistency; // Union of all commit flags (flags with the lifetime of a particular commit)
449
450var HostEffectMask =
451/* */
45232767; // These are not really side effects, but we still reuse this field.
453
454var Incomplete =
455/* */
45632768;
457var ShouldCapture =
458/* */
45965536;
460var ForceUpdateForLegacySuspense =
461/* */
462131072;
463var Forked =
464/* */
4651048576; // Static tags describe aspects of a fiber that are not specific to a render,
466// e.g. a fiber uses a passive effect (even if there are no updates on this particular render).
467// This enables us to defer more work in the unmount case,
468// since we can defer traversing the tree during layout to look for Passive effects,
469// and instead rely on the static flag as a signal that there may be cleanup work.
470
471var RefStatic =
472/* */
4732097152;
474var LayoutStatic =
475/* */
4764194304;
477var PassiveStatic =
478/* */
4798388608; // These flags allow us to traverse to fibers that have effects on mount
480// don't contain effects, by checking subtreeFlags.
481
482var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visibility
483// flag logic (see #20043)
484Update | Snapshot | ( 0);
485var MutationMask = Placement | Update | ChildDeletion | ContentReset | Ref | Hydrating | Visibility;
486var LayoutMask = Update | Callback | Ref | Visibility; // TODO: Split into PassiveMountMask and PassiveUnmountMask
487
488var PassiveMask = Passive | ChildDeletion; // Union of tags that don't get reset on clones.
489// This allows certain concepts to persist without recalculating them,
490// e.g. whether a subtree contains passive effects or portals.
491
492var StaticMask = LayoutStatic | PassiveStatic | RefStatic;
493
494var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
495function getNearestMountedFiber(fiber) {
496 var node = fiber;
497 var nearestMounted = fiber;
498
499 if (!fiber.alternate) {
500 // If there is no alternate, this might be a new tree that isn't inserted
501 // yet. If it is, then it will have a pending insertion effect on it.
502 var nextNode = node;
503
504 do {
505 node = nextNode;
506
507 if ((node.flags & (Placement | Hydrating)) !== NoFlags) {
508 // This is an insertion or in-progress hydration. The nearest possible
509 // mounted fiber is the parent but we need to continue to figure out
510 // if that one is still mounted.
511 nearestMounted = node.return;
512 }
513
514 nextNode = node.return;
515 } while (nextNode);
516 } else {
517 while (node.return) {
518 node = node.return;
519 }
520 }
521
522 if (node.tag === HostRoot) {
523 // TODO: Check if this was a nested HostRoot when used with
524 // renderContainerIntoSubtree.
525 return nearestMounted;
526 } // If we didn't hit the root, that means that we're in an disconnected tree
527 // that has been unmounted.
528
529
530 return null;
531}
532function isFiberMounted(fiber) {
533 return getNearestMountedFiber(fiber) === fiber;
534}
535function isMounted(component) {
536 {
537 var owner = ReactCurrentOwner.current;
538
539 if (owner !== null && owner.tag === ClassComponent) {
540 var ownerFiber = owner;
541 var instance = ownerFiber.stateNode;
542
543 if (!instance._warnedAboutRefsInRender) {
544 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');
545 }
546
547 instance._warnedAboutRefsInRender = true;
548 }
549 }
550
551 var fiber = get(component);
552
553 if (!fiber) {
554 return false;
555 }
556
557 return getNearestMountedFiber(fiber) === fiber;
558}
559
560function assertIsMounted(fiber) {
561 if (getNearestMountedFiber(fiber) !== fiber) {
562 throw new Error('Unable to find node on an unmounted component.');
563 }
564}
565
566function findCurrentFiberUsingSlowPath(fiber) {
567 var alternate = fiber.alternate;
568
569 if (!alternate) {
570 // If there is no alternate, then we only need to check if it is mounted.
571 var nearestMounted = getNearestMountedFiber(fiber);
572
573 if (nearestMounted === null) {
574 throw new Error('Unable to find node on an unmounted component.');
575 }
576
577 if (nearestMounted !== fiber) {
578 return null;
579 }
580
581 return fiber;
582 } // If we have two possible branches, we'll walk backwards up to the root
583 // to see what path the root points to. On the way we may hit one of the
584 // special cases and we'll deal with them.
585
586
587 var a = fiber;
588 var b = alternate;
589
590 while (true) {
591 var parentA = a.return;
592
593 if (parentA === null) {
594 // We're at the root.
595 break;
596 }
597
598 var parentB = parentA.alternate;
599
600 if (parentB === null) {
601 // There is no alternate. This is an unusual case. Currently, it only
602 // happens when a Suspense component is hidden. An extra fragment fiber
603 // is inserted in between the Suspense fiber and its children. Skip
604 // over this extra fragment fiber and proceed to the next parent.
605 var nextParent = parentA.return;
606
607 if (nextParent !== null) {
608 a = b = nextParent;
609 continue;
610 } // If there's no parent, we're at the root.
611
612
613 break;
614 } // If both copies of the parent fiber point to the same child, we can
615 // assume that the child is current. This happens when we bailout on low
616 // priority: the bailed out fiber's child reuses the current child.
617
618
619 if (parentA.child === parentB.child) {
620 var child = parentA.child;
621
622 while (child) {
623 if (child === a) {
624 // We've determined that A is the current branch.
625 assertIsMounted(parentA);
626 return fiber;
627 }
628
629 if (child === b) {
630 // We've determined that B is the current branch.
631 assertIsMounted(parentA);
632 return alternate;
633 }
634
635 child = child.sibling;
636 } // We should never have an alternate for any mounting node. So the only
637 // way this could possibly happen is if this was unmounted, if at all.
638
639
640 throw new Error('Unable to find node on an unmounted component.');
641 }
642
643 if (a.return !== b.return) {
644 // The return pointer of A and the return pointer of B point to different
645 // fibers. We assume that return pointers never criss-cross, so A must
646 // belong to the child set of A.return, and B must belong to the child
647 // set of B.return.
648 a = parentA;
649 b = parentB;
650 } else {
651 // The return pointers point to the same fiber. We'll have to use the
652 // default, slow path: scan the child sets of each parent alternate to see
653 // which child belongs to which set.
654 //
655 // Search parent A's child set
656 var didFindChild = false;
657 var _child = parentA.child;
658
659 while (_child) {
660 if (_child === a) {
661 didFindChild = true;
662 a = parentA;
663 b = parentB;
664 break;
665 }
666
667 if (_child === b) {
668 didFindChild = true;
669 b = parentA;
670 a = parentB;
671 break;
672 }
673
674 _child = _child.sibling;
675 }
676
677 if (!didFindChild) {
678 // Search parent B's child set
679 _child = parentB.child;
680
681 while (_child) {
682 if (_child === a) {
683 didFindChild = true;
684 a = parentB;
685 b = parentA;
686 break;
687 }
688
689 if (_child === b) {
690 didFindChild = true;
691 b = parentB;
692 a = parentA;
693 break;
694 }
695
696 _child = _child.sibling;
697 }
698
699 if (!didFindChild) {
700 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.');
701 }
702 }
703 }
704
705 if (a.alternate !== b) {
706 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.');
707 }
708 } // If the root is not a host container, we're in a disconnected tree. I.e.
709 // unmounted.
710
711
712 if (a.tag !== HostRoot) {
713 throw new Error('Unable to find node on an unmounted component.');
714 }
715
716 if (a.stateNode.current === a) {
717 // We've determined that A is the current branch.
718 return fiber;
719 } // Otherwise B has to be current branch.
720
721
722 return alternate;
723}
724function findCurrentHostFiber(parent) {
725 var currentParent = findCurrentFiberUsingSlowPath(parent);
726 return currentParent !== null ? findCurrentHostFiberImpl(currentParent) : null;
727}
728
729function findCurrentHostFiberImpl(node) {
730 // Next we'll drill down this component to find the first HostComponent/Text.
731 if (node.tag === HostComponent || node.tag === HostText) {
732 return node;
733 }
734
735 var child = node.child;
736
737 while (child !== null) {
738 var match = findCurrentHostFiberImpl(child);
739
740 if (match !== null) {
741 return match;
742 }
743
744 child = child.sibling;
745 }
746
747 return null;
748}
749
750var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare
751
752function isArray(a) {
753 return isArrayImpl(a);
754}
755
756// This module only exists as an ESM wrapper around the external CommonJS
757var scheduleCallback = Scheduler$1.unstable_scheduleCallback;
758var cancelCallback = Scheduler$1.unstable_cancelCallback;
759var shouldYield = Scheduler$1.unstable_shouldYield;
760var requestPaint = Scheduler$1.unstable_requestPaint;
761var now = Scheduler$1.unstable_now;
762var ImmediatePriority = Scheduler$1.unstable_ImmediatePriority;
763var UserBlockingPriority = Scheduler$1.unstable_UserBlockingPriority;
764var NormalPriority = Scheduler$1.unstable_NormalPriority;
765var IdlePriority = Scheduler$1.unstable_IdlePriority;
766
767// Helpers to patch console.logs to avoid logging during side-effect free
768// replaying on render function. This currently only patches the object
769// lazily which won't cover if the log function was extracted eagerly.
770// We could also eagerly patch the method.
771var disabledDepth = 0;
772var prevLog;
773var prevInfo;
774var prevWarn;
775var prevError;
776var prevGroup;
777var prevGroupCollapsed;
778var prevGroupEnd;
779
780function disabledLog() {}
781
782disabledLog.__reactDisabledLog = true;
783function disableLogs() {
784 {
785 if (disabledDepth === 0) {
786 /* eslint-disable react-internal/no-production-logging */
787 prevLog = console.log;
788 prevInfo = console.info;
789 prevWarn = console.warn;
790 prevError = console.error;
791 prevGroup = console.group;
792 prevGroupCollapsed = console.groupCollapsed;
793 prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099
794
795 var props = {
796 configurable: true,
797 enumerable: true,
798 value: disabledLog,
799 writable: true
800 }; // $FlowFixMe Flow thinks console is immutable.
801
802 Object.defineProperties(console, {
803 info: props,
804 log: props,
805 warn: props,
806 error: props,
807 group: props,
808 groupCollapsed: props,
809 groupEnd: props
810 });
811 /* eslint-enable react-internal/no-production-logging */
812 }
813
814 disabledDepth++;
815 }
816}
817function reenableLogs() {
818 {
819 disabledDepth--;
820
821 if (disabledDepth === 0) {
822 /* eslint-disable react-internal/no-production-logging */
823 var props = {
824 configurable: true,
825 enumerable: true,
826 writable: true
827 }; // $FlowFixMe Flow thinks console is immutable.
828
829 Object.defineProperties(console, {
830 log: assign({}, props, {
831 value: prevLog
832 }),
833 info: assign({}, props, {
834 value: prevInfo
835 }),
836 warn: assign({}, props, {
837 value: prevWarn
838 }),
839 error: assign({}, props, {
840 value: prevError
841 }),
842 group: assign({}, props, {
843 value: prevGroup
844 }),
845 groupCollapsed: assign({}, props, {
846 value: prevGroupCollapsed
847 }),
848 groupEnd: assign({}, props, {
849 value: prevGroupEnd
850 })
851 });
852 /* eslint-enable react-internal/no-production-logging */
853 }
854
855 if (disabledDepth < 0) {
856 error('disabledDepth fell below zero. ' + 'This is a bug in React. Please file an issue.');
857 }
858 }
859}
860
861var rendererID = null;
862var injectedHook = null;
863var hasLoggedError = false;
864var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
865function injectInternals(internals) {
866 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
867 // No DevTools
868 return false;
869 }
870
871 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
872
873 if (hook.isDisabled) {
874 // This isn't a real property on the hook, but it can be set to opt out
875 // of DevTools integration and associated warnings and logs.
876 // https://github.com/facebook/react/issues/3877
877 return true;
878 }
879
880 if (!hook.supportsFiber) {
881 {
882 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');
883 } // DevTools exists, even though it doesn't support Fiber.
884
885
886 return true;
887 }
888
889 try {
890 if (enableSchedulingProfiler) {
891 // Conditionally inject these hooks only if Timeline profiler is supported by this build.
892 // This gives DevTools a way to feature detect that isn't tied to version number
893 // (since profiling and timeline are controlled by different feature flags).
894 internals = assign({}, internals, {
895 getLaneLabelMap: getLaneLabelMap,
896 injectProfilingHooks: injectProfilingHooks
897 });
898 }
899
900 rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
901
902 injectedHook = hook;
903 } catch (err) {
904 // Catch all errors because it is unsafe to throw during initialization.
905 {
906 error('React instrumentation encountered an error: %s.', err);
907 }
908 }
909
910 if (hook.checkDCE) {
911 // This is the real DevTools.
912 return true;
913 } else {
914 // This is likely a hook installed by Fast Refresh runtime.
915 return false;
916 }
917}
918function onScheduleRoot(root, children) {
919 {
920 if (injectedHook && typeof injectedHook.onScheduleFiberRoot === 'function') {
921 try {
922 injectedHook.onScheduleFiberRoot(rendererID, root, children);
923 } catch (err) {
924 if ( !hasLoggedError) {
925 hasLoggedError = true;
926
927 error('React instrumentation encountered an error: %s', err);
928 }
929 }
930 }
931 }
932}
933function onCommitRoot(root, eventPriority) {
934 if (injectedHook && typeof injectedHook.onCommitFiberRoot === 'function') {
935 try {
936 var didError = (root.current.flags & DidCapture) === DidCapture;
937
938 if (enableProfilerTimer) {
939 var schedulerPriority;
940
941 switch (eventPriority) {
942 case DiscreteEventPriority:
943 schedulerPriority = ImmediatePriority;
944 break;
945
946 case ContinuousEventPriority:
947 schedulerPriority = UserBlockingPriority;
948 break;
949
950 case DefaultEventPriority:
951 schedulerPriority = NormalPriority;
952 break;
953
954 case IdleEventPriority:
955 schedulerPriority = IdlePriority;
956 break;
957
958 default:
959 schedulerPriority = NormalPriority;
960 break;
961 }
962
963 injectedHook.onCommitFiberRoot(rendererID, root, schedulerPriority, didError);
964 } else {
965 injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError);
966 }
967 } catch (err) {
968 {
969 if (!hasLoggedError) {
970 hasLoggedError = true;
971
972 error('React instrumentation encountered an error: %s', err);
973 }
974 }
975 }
976 }
977}
978function onPostCommitRoot(root) {
979 if (injectedHook && typeof injectedHook.onPostCommitFiberRoot === 'function') {
980 try {
981 injectedHook.onPostCommitFiberRoot(rendererID, root);
982 } catch (err) {
983 {
984 if (!hasLoggedError) {
985 hasLoggedError = true;
986
987 error('React instrumentation encountered an error: %s', err);
988 }
989 }
990 }
991 }
992}
993function onCommitUnmount(fiber) {
994 if (injectedHook && typeof injectedHook.onCommitFiberUnmount === 'function') {
995 try {
996 injectedHook.onCommitFiberUnmount(rendererID, fiber);
997 } catch (err) {
998 {
999 if (!hasLoggedError) {
1000 hasLoggedError = true;
1001
1002 error('React instrumentation encountered an error: %s', err);
1003 }
1004 }
1005 }
1006 }
1007}
1008
1009function injectProfilingHooks(profilingHooks) {
1010}
1011
1012function getLaneLabelMap() {
1013 {
1014 return null;
1015 }
1016}
1017function markComponentRenderStopped() {
1018}
1019function markComponentErrored(fiber, thrownValue, lanes) {
1020}
1021function markComponentSuspended(fiber, wakeable, lanes) {
1022}
1023
1024var NoMode =
1025/* */
10260; // TODO: Remove ConcurrentMode by reading from the root tag instead
1027
1028var ConcurrentMode =
1029/* */
10301;
1031var ProfileMode =
1032/* */
10332;
1034var StrictLegacyMode =
1035/* */
10368;
1037
1038// TODO: This is pretty well supported by browsers. Maybe we can drop it.
1039var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros.
1040// Based on:
1041// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
1042
1043var log = Math.log;
1044var LN2 = Math.LN2;
1045
1046function clz32Fallback(x) {
1047 var asUint = x >>> 0;
1048
1049 if (asUint === 0) {
1050 return 32;
1051 }
1052
1053 return 31 - (log(asUint) / LN2 | 0) | 0;
1054}
1055
1056// If those values are changed that package should be rebuilt and redeployed.
1057
1058var TotalLanes = 31;
1059var NoLanes =
1060/* */
10610;
1062var NoLane =
1063/* */
10640;
1065var SyncLane =
1066/* */
10671;
1068var InputContinuousHydrationLane =
1069/* */
10702;
1071var InputContinuousLane =
1072/* */
10734;
1074var DefaultHydrationLane =
1075/* */
10768;
1077var DefaultLane =
1078/* */
107916;
1080var TransitionHydrationLane =
1081/* */
108232;
1083var TransitionLanes =
1084/* */
10854194240;
1086var TransitionLane1 =
1087/* */
108864;
1089var TransitionLane2 =
1090/* */
1091128;
1092var TransitionLane3 =
1093/* */
1094256;
1095var TransitionLane4 =
1096/* */
1097512;
1098var TransitionLane5 =
1099/* */
11001024;
1101var TransitionLane6 =
1102/* */
11032048;
1104var TransitionLane7 =
1105/* */
11064096;
1107var TransitionLane8 =
1108/* */
11098192;
1110var TransitionLane9 =
1111/* */
111216384;
1113var TransitionLane10 =
1114/* */
111532768;
1116var TransitionLane11 =
1117/* */
111865536;
1119var TransitionLane12 =
1120/* */
1121131072;
1122var TransitionLane13 =
1123/* */
1124262144;
1125var TransitionLane14 =
1126/* */
1127524288;
1128var TransitionLane15 =
1129/* */
11301048576;
1131var TransitionLane16 =
1132/* */
11332097152;
1134var RetryLanes =
1135/* */
1136130023424;
1137var RetryLane1 =
1138/* */
11394194304;
1140var RetryLane2 =
1141/* */
11428388608;
1143var RetryLane3 =
1144/* */
114516777216;
1146var RetryLane4 =
1147/* */
114833554432;
1149var RetryLane5 =
1150/* */
115167108864;
1152var SomeRetryLane = RetryLane1;
1153var SelectiveHydrationLane =
1154/* */
1155134217728;
1156var NonIdleLanes =
1157/* */
1158268435455;
1159var IdleHydrationLane =
1160/* */
1161268435456;
1162var IdleLane =
1163/* */
1164536870912;
1165var OffscreenLane =
1166/* */
11671073741824; // This function is used for the experimental timeline (react-devtools-timeline)
1168var NoTimestamp = -1;
1169var nextTransitionLane = TransitionLane1;
1170var nextRetryLane = RetryLane1;
1171
1172function getHighestPriorityLanes(lanes) {
1173 switch (getHighestPriorityLane(lanes)) {
1174 case SyncLane:
1175 return SyncLane;
1176
1177 case InputContinuousHydrationLane:
1178 return InputContinuousHydrationLane;
1179
1180 case InputContinuousLane:
1181 return InputContinuousLane;
1182
1183 case DefaultHydrationLane:
1184 return DefaultHydrationLane;
1185
1186 case DefaultLane:
1187 return DefaultLane;
1188
1189 case TransitionHydrationLane:
1190 return TransitionHydrationLane;
1191
1192 case TransitionLane1:
1193 case TransitionLane2:
1194 case TransitionLane3:
1195 case TransitionLane4:
1196 case TransitionLane5:
1197 case TransitionLane6:
1198 case TransitionLane7:
1199 case TransitionLane8:
1200 case TransitionLane9:
1201 case TransitionLane10:
1202 case TransitionLane11:
1203 case TransitionLane12:
1204 case TransitionLane13:
1205 case TransitionLane14:
1206 case TransitionLane15:
1207 case TransitionLane16:
1208 return lanes & TransitionLanes;
1209
1210 case RetryLane1:
1211 case RetryLane2:
1212 case RetryLane3:
1213 case RetryLane4:
1214 case RetryLane5:
1215 return lanes & RetryLanes;
1216
1217 case SelectiveHydrationLane:
1218 return SelectiveHydrationLane;
1219
1220 case IdleHydrationLane:
1221 return IdleHydrationLane;
1222
1223 case IdleLane:
1224 return IdleLane;
1225
1226 case OffscreenLane:
1227 return OffscreenLane;
1228
1229 default:
1230 {
1231 error('Should have found matching lanes. This is a bug in React.');
1232 } // This shouldn't be reachable, but as a fallback, return the entire bitmask.
1233
1234
1235 return lanes;
1236 }
1237}
1238
1239function getNextLanes(root, wipLanes) {
1240 // Early bailout if there's no pending work left.
1241 var pendingLanes = root.pendingLanes;
1242
1243 if (pendingLanes === NoLanes) {
1244 return NoLanes;
1245 }
1246
1247 var nextLanes = NoLanes;
1248 var suspendedLanes = root.suspendedLanes;
1249 var pingedLanes = root.pingedLanes; // Do not work on any idle work until all the non-idle work has finished,
1250 // even if the work is suspended.
1251
1252 var nonIdlePendingLanes = pendingLanes & NonIdleLanes;
1253
1254 if (nonIdlePendingLanes !== NoLanes) {
1255 var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes;
1256
1257 if (nonIdleUnblockedLanes !== NoLanes) {
1258 nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes);
1259 } else {
1260 var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes;
1261
1262 if (nonIdlePingedLanes !== NoLanes) {
1263 nextLanes = getHighestPriorityLanes(nonIdlePingedLanes);
1264 }
1265 }
1266 } else {
1267 // The only remaining work is Idle.
1268 var unblockedLanes = pendingLanes & ~suspendedLanes;
1269
1270 if (unblockedLanes !== NoLanes) {
1271 nextLanes = getHighestPriorityLanes(unblockedLanes);
1272 } else {
1273 if (pingedLanes !== NoLanes) {
1274 nextLanes = getHighestPriorityLanes(pingedLanes);
1275 }
1276 }
1277 }
1278
1279 if (nextLanes === NoLanes) {
1280 // This should only be reachable if we're suspended
1281 // TODO: Consider warning in this path if a fallback timer is not scheduled.
1282 return NoLanes;
1283 } // If we're already in the middle of a render, switching lanes will interrupt
1284 // it and we'll lose our progress. We should only do this if the new lanes are
1285 // higher priority.
1286
1287
1288 if (wipLanes !== NoLanes && wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't
1289 // bother waiting until the root is complete.
1290 (wipLanes & suspendedLanes) === NoLanes) {
1291 var nextLane = getHighestPriorityLane(nextLanes);
1292 var wipLane = getHighestPriorityLane(wipLanes);
1293
1294 if ( // Tests whether the next lane is equal or lower priority than the wip
1295 // one. This works because the bits decrease in priority as you go left.
1296 nextLane >= wipLane || // Default priority updates should not interrupt transition updates. The
1297 // only difference between default updates and transition updates is that
1298 // default updates do not support refresh transitions.
1299 nextLane === DefaultLane && (wipLane & TransitionLanes) !== NoLanes) {
1300 // Keep working on the existing in-progress tree. Do not interrupt.
1301 return wipLanes;
1302 }
1303 }
1304
1305 if ((nextLanes & InputContinuousLane) !== NoLanes) {
1306 // When updates are sync by default, we entangle continuous priority updates
1307 // and default updates, so they render in the same batch. The only reason
1308 // they use separate lanes is because continuous updates should interrupt
1309 // transitions, but default updates should not.
1310 nextLanes |= pendingLanes & DefaultLane;
1311 } // Check for entangled lanes and add them to the batch.
1312 //
1313 // A lane is said to be entangled with another when it's not allowed to render
1314 // in a batch that does not also include the other lane. Typically we do this
1315 // when multiple updates have the same source, and we only want to respond to
1316 // the most recent event from that source.
1317 //
1318 // Note that we apply entanglements *after* checking for partial work above.
1319 // This means that if a lane is entangled during an interleaved event while
1320 // it's already rendering, we won't interrupt it. This is intentional, since
1321 // entanglement is usually "best effort": we'll try our best to render the
1322 // lanes in the same batch, but it's not worth throwing out partially
1323 // completed work in order to do it.
1324 // TODO: Reconsider this. The counter-argument is that the partial work
1325 // represents an intermediate state, which we don't want to show to the user.
1326 // And by spending extra time finishing it, we're increasing the amount of
1327 // time it takes to show the final state, which is what they are actually
1328 // waiting for.
1329 //
1330 // For those exceptions where entanglement is semantically important, like
1331 // useMutableSource, we should ensure that there is no partial work at the
1332 // time we apply the entanglement.
1333
1334
1335 var entangledLanes = root.entangledLanes;
1336
1337 if (entangledLanes !== NoLanes) {
1338 var entanglements = root.entanglements;
1339 var lanes = nextLanes & entangledLanes;
1340
1341 while (lanes > 0) {
1342 var index = pickArbitraryLaneIndex(lanes);
1343 var lane = 1 << index;
1344 nextLanes |= entanglements[index];
1345 lanes &= ~lane;
1346 }
1347 }
1348
1349 return nextLanes;
1350}
1351function getMostRecentEventTime(root, lanes) {
1352 var eventTimes = root.eventTimes;
1353 var mostRecentEventTime = NoTimestamp;
1354
1355 while (lanes > 0) {
1356 var index = pickArbitraryLaneIndex(lanes);
1357 var lane = 1 << index;
1358 var eventTime = eventTimes[index];
1359
1360 if (eventTime > mostRecentEventTime) {
1361 mostRecentEventTime = eventTime;
1362 }
1363
1364 lanes &= ~lane;
1365 }
1366
1367 return mostRecentEventTime;
1368}
1369
1370function computeExpirationTime(lane, currentTime) {
1371 switch (lane) {
1372 case SyncLane:
1373 case InputContinuousHydrationLane:
1374 case InputContinuousLane:
1375 // User interactions should expire slightly more quickly.
1376 //
1377 // NOTE: This is set to the corresponding constant as in Scheduler.js.
1378 // When we made it larger, a product metric in www regressed, suggesting
1379 // there's a user interaction that's being starved by a series of
1380 // synchronous updates. If that theory is correct, the proper solution is
1381 // to fix the starvation. However, this scenario supports the idea that
1382 // expiration times are an important safeguard when starvation
1383 // does happen.
1384 return currentTime + 250;
1385
1386 case DefaultHydrationLane:
1387 case DefaultLane:
1388 case TransitionHydrationLane:
1389 case TransitionLane1:
1390 case TransitionLane2:
1391 case TransitionLane3:
1392 case TransitionLane4:
1393 case TransitionLane5:
1394 case TransitionLane6:
1395 case TransitionLane7:
1396 case TransitionLane8:
1397 case TransitionLane9:
1398 case TransitionLane10:
1399 case TransitionLane11:
1400 case TransitionLane12:
1401 case TransitionLane13:
1402 case TransitionLane14:
1403 case TransitionLane15:
1404 case TransitionLane16:
1405 return currentTime + 5000;
1406
1407 case RetryLane1:
1408 case RetryLane2:
1409 case RetryLane3:
1410 case RetryLane4:
1411 case RetryLane5:
1412 // TODO: Retries should be allowed to expire if they are CPU bound for
1413 // too long, but when I made this change it caused a spike in browser
1414 // crashes. There must be some other underlying bug; not super urgent but
1415 // ideally should figure out why and fix it. Unfortunately we don't have
1416 // a repro for the crashes, only detected via production metrics.
1417 return NoTimestamp;
1418
1419 case SelectiveHydrationLane:
1420 case IdleHydrationLane:
1421 case IdleLane:
1422 case OffscreenLane:
1423 // Anything idle priority or lower should never expire.
1424 return NoTimestamp;
1425
1426 default:
1427 {
1428 error('Should have found matching lanes. This is a bug in React.');
1429 }
1430
1431 return NoTimestamp;
1432 }
1433}
1434
1435function markStarvedLanesAsExpired(root, currentTime) {
1436 // TODO: This gets called every time we yield. We can optimize by storing
1437 // the earliest expiration time on the root. Then use that to quickly bail out
1438 // of this function.
1439 var pendingLanes = root.pendingLanes;
1440 var suspendedLanes = root.suspendedLanes;
1441 var pingedLanes = root.pingedLanes;
1442 var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their
1443 // expiration time. If so, we'll assume the update is being starved and mark
1444 // it as expired to force it to finish.
1445
1446 var lanes = pendingLanes;
1447
1448 while (lanes > 0) {
1449 var index = pickArbitraryLaneIndex(lanes);
1450 var lane = 1 << index;
1451 var expirationTime = expirationTimes[index];
1452
1453 if (expirationTime === NoTimestamp) {
1454 // Found a pending lane with no expiration time. If it's not suspended, or
1455 // if it's pinged, assume it's CPU-bound. Compute a new expiration time
1456 // using the current time.
1457 if ((lane & suspendedLanes) === NoLanes || (lane & pingedLanes) !== NoLanes) {
1458 // Assumes timestamps are monotonically increasing.
1459 expirationTimes[index] = computeExpirationTime(lane, currentTime);
1460 }
1461 } else if (expirationTime <= currentTime) {
1462 // This lane expired
1463 root.expiredLanes |= lane;
1464 }
1465
1466 lanes &= ~lane;
1467 }
1468} // This returns the highest priority pending lanes regardless of whether they
1469function getLanesToRetrySynchronouslyOnError(root) {
1470 var everythingButOffscreen = root.pendingLanes & ~OffscreenLane;
1471
1472 if (everythingButOffscreen !== NoLanes) {
1473 return everythingButOffscreen;
1474 }
1475
1476 if (everythingButOffscreen & OffscreenLane) {
1477 return OffscreenLane;
1478 }
1479
1480 return NoLanes;
1481}
1482function includesSyncLane(lanes) {
1483 return (lanes & SyncLane) !== NoLanes;
1484}
1485function includesNonIdleWork(lanes) {
1486 return (lanes & NonIdleLanes) !== NoLanes;
1487}
1488function includesOnlyRetries(lanes) {
1489 return (lanes & RetryLanes) === lanes;
1490}
1491function includesOnlyNonUrgentLanes(lanes) {
1492 var UrgentLanes = SyncLane | InputContinuousLane | DefaultLane;
1493 return (lanes & UrgentLanes) === NoLanes;
1494}
1495function includesOnlyTransitions(lanes) {
1496 return (lanes & TransitionLanes) === lanes;
1497}
1498function includesBlockingLane(root, lanes) {
1499
1500 var SyncDefaultLanes = InputContinuousHydrationLane | InputContinuousLane | DefaultHydrationLane | DefaultLane;
1501 return (lanes & SyncDefaultLanes) !== NoLanes;
1502}
1503function includesExpiredLane(root, lanes) {
1504 // This is a separate check from includesBlockingLane because a lane can
1505 // expire after a render has already started.
1506 return (lanes & root.expiredLanes) !== NoLanes;
1507}
1508function isTransitionLane(lane) {
1509 return (lane & TransitionLanes) !== NoLanes;
1510}
1511function claimNextTransitionLane() {
1512 // Cycle through the lanes, assigning each new transition to the next lane.
1513 // In most cases, this means every transition gets its own lane, until we
1514 // run out of lanes and cycle back to the beginning.
1515 var lane = nextTransitionLane;
1516 nextTransitionLane <<= 1;
1517
1518 if ((nextTransitionLane & TransitionLanes) === NoLanes) {
1519 nextTransitionLane = TransitionLane1;
1520 }
1521
1522 return lane;
1523}
1524function claimNextRetryLane() {
1525 var lane = nextRetryLane;
1526 nextRetryLane <<= 1;
1527
1528 if ((nextRetryLane & RetryLanes) === NoLanes) {
1529 nextRetryLane = RetryLane1;
1530 }
1531
1532 return lane;
1533}
1534function getHighestPriorityLane(lanes) {
1535 return lanes & -lanes;
1536}
1537function pickArbitraryLane(lanes) {
1538 // This wrapper function gets inlined. Only exists so to communicate that it
1539 // doesn't matter which bit is selected; you can pick any bit without
1540 // affecting the algorithms where its used. Here I'm using
1541 // getHighestPriorityLane because it requires the fewest operations.
1542 return getHighestPriorityLane(lanes);
1543}
1544
1545function pickArbitraryLaneIndex(lanes) {
1546 return 31 - clz32(lanes);
1547}
1548
1549function laneToIndex(lane) {
1550 return pickArbitraryLaneIndex(lane);
1551}
1552
1553function includesSomeLane(a, b) {
1554 return (a & b) !== NoLanes;
1555}
1556function isSubsetOfLanes(set, subset) {
1557 return (set & subset) === subset;
1558}
1559function mergeLanes(a, b) {
1560 return a | b;
1561}
1562function removeLanes(set, subset) {
1563 return set & ~subset;
1564}
1565function intersectLanes(a, b) {
1566 return a & b;
1567} // Seems redundant, but it changes the type from a single lane (used for
1568// updates) to a group of lanes (used for flushing work).
1569
1570function laneToLanes(lane) {
1571 return lane;
1572}
1573function createLaneMap(initial) {
1574 // Intentionally pushing one by one.
1575 // https://v8.dev/blog/elements-kinds#avoid-creating-holes
1576 var laneMap = [];
1577
1578 for (var i = 0; i < TotalLanes; i++) {
1579 laneMap.push(initial);
1580 }
1581
1582 return laneMap;
1583}
1584function markRootUpdated(root, updateLane, eventTime) {
1585 root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update
1586 // could unblock them. Clear the suspended lanes so that we can try rendering
1587 // them again.
1588 //
1589 // TODO: We really only need to unsuspend only lanes that are in the
1590 // `subtreeLanes` of the updated fiber, or the update lanes of the return
1591 // path. This would exclude suspended updates in an unrelated sibling tree,
1592 // since there's no way for this update to unblock it.
1593 //
1594 // We don't do this if the incoming update is idle, because we never process
1595 // idle updates until after all the regular updates have finished; there's no
1596 // way it could unblock a transition.
1597
1598 if (updateLane !== IdleLane) {
1599 root.suspendedLanes = NoLanes;
1600 root.pingedLanes = NoLanes;
1601 }
1602
1603 var eventTimes = root.eventTimes;
1604 var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most
1605 // recent event, and we assume time is monotonically increasing.
1606
1607 eventTimes[index] = eventTime;
1608}
1609function markRootSuspended(root, suspendedLanes) {
1610 root.suspendedLanes |= suspendedLanes;
1611 root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times.
1612
1613 var expirationTimes = root.expirationTimes;
1614 var lanes = suspendedLanes;
1615
1616 while (lanes > 0) {
1617 var index = pickArbitraryLaneIndex(lanes);
1618 var lane = 1 << index;
1619 expirationTimes[index] = NoTimestamp;
1620 lanes &= ~lane;
1621 }
1622}
1623function markRootPinged(root, pingedLanes, eventTime) {
1624 root.pingedLanes |= root.suspendedLanes & pingedLanes;
1625}
1626function markRootFinished(root, remainingLanes) {
1627 var noLongerPendingLanes = root.pendingLanes & ~remainingLanes;
1628 root.pendingLanes = remainingLanes; // Let's try everything again
1629
1630 root.suspendedLanes = NoLanes;
1631 root.pingedLanes = NoLanes;
1632 root.expiredLanes &= remainingLanes;
1633 root.mutableReadLanes &= remainingLanes;
1634 root.entangledLanes &= remainingLanes;
1635 var entanglements = root.entanglements;
1636 var eventTimes = root.eventTimes;
1637 var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work
1638
1639 var lanes = noLongerPendingLanes;
1640
1641 while (lanes > 0) {
1642 var index = pickArbitraryLaneIndex(lanes);
1643 var lane = 1 << index;
1644 entanglements[index] = NoLanes;
1645 eventTimes[index] = NoTimestamp;
1646 expirationTimes[index] = NoTimestamp;
1647 lanes &= ~lane;
1648 }
1649}
1650function markRootEntangled(root, entangledLanes) {
1651 // In addition to entangling each of the given lanes with each other, we also
1652 // have to consider _transitive_ entanglements. For each lane that is already
1653 // entangled with *any* of the given lanes, that lane is now transitively
1654 // entangled with *all* the given lanes.
1655 //
1656 // Translated: If C is entangled with A, then entangling A with B also
1657 // entangles C with B.
1658 //
1659 // If this is hard to grasp, it might help to intentionally break this
1660 // function and look at the tests that fail in ReactTransition-test.js. Try
1661 // commenting out one of the conditions below.
1662 var rootEntangledLanes = root.entangledLanes |= entangledLanes;
1663 var entanglements = root.entanglements;
1664 var lanes = rootEntangledLanes;
1665
1666 while (lanes) {
1667 var index = pickArbitraryLaneIndex(lanes);
1668 var lane = 1 << index;
1669
1670 if ( // Is this one of the newly entangled lanes?
1671 lane & entangledLanes | // Is this lane transitively entangled with the newly entangled lanes?
1672 entanglements[index] & entangledLanes) {
1673 entanglements[index] |= entangledLanes;
1674 }
1675
1676 lanes &= ~lane;
1677 }
1678}
1679function getBumpedLaneForHydration(root, renderLanes) {
1680 var renderLane = getHighestPriorityLane(renderLanes);
1681 var lane;
1682
1683 switch (renderLane) {
1684 case InputContinuousLane:
1685 lane = InputContinuousHydrationLane;
1686 break;
1687
1688 case DefaultLane:
1689 lane = DefaultHydrationLane;
1690 break;
1691
1692 case TransitionLane1:
1693 case TransitionLane2:
1694 case TransitionLane3:
1695 case TransitionLane4:
1696 case TransitionLane5:
1697 case TransitionLane6:
1698 case TransitionLane7:
1699 case TransitionLane8:
1700 case TransitionLane9:
1701 case TransitionLane10:
1702 case TransitionLane11:
1703 case TransitionLane12:
1704 case TransitionLane13:
1705 case TransitionLane14:
1706 case TransitionLane15:
1707 case TransitionLane16:
1708 case RetryLane1:
1709 case RetryLane2:
1710 case RetryLane3:
1711 case RetryLane4:
1712 case RetryLane5:
1713 lane = TransitionHydrationLane;
1714 break;
1715
1716 case IdleLane:
1717 lane = IdleHydrationLane;
1718 break;
1719
1720 default:
1721 // Everything else is already either a hydration lane, or shouldn't
1722 // be retried at a hydration lane.
1723 lane = NoLane;
1724 break;
1725 } // Check if the lane we chose is suspended. If so, that indicates that we
1726 // already attempted and failed to hydrate at that level. Also check if we're
1727 // already rendering that lane, which is rare but could happen.
1728
1729
1730 if ((lane & (root.suspendedLanes | renderLanes)) !== NoLane) {
1731 // Give up trying to hydrate and fall back to client render.
1732 return NoLane;
1733 }
1734
1735 return lane;
1736}
1737function getTransitionsForLanes(root, lanes) {
1738 {
1739 return null;
1740 }
1741}
1742
1743var DiscreteEventPriority = SyncLane;
1744var ContinuousEventPriority = InputContinuousLane;
1745var DefaultEventPriority = DefaultLane;
1746var IdleEventPriority = IdleLane;
1747var currentUpdatePriority = NoLane;
1748function getCurrentUpdatePriority() {
1749 return currentUpdatePriority;
1750}
1751function setCurrentUpdatePriority(newPriority) {
1752 currentUpdatePriority = newPriority;
1753}
1754function higherEventPriority(a, b) {
1755 return a !== 0 && a < b ? a : b;
1756}
1757function lowerEventPriority(a, b) {
1758 return a === 0 || a > b ? a : b;
1759}
1760function isHigherEventPriority(a, b) {
1761 return a !== 0 && a < b;
1762}
1763function lanesToEventPriority(lanes) {
1764 var lane = getHighestPriorityLane(lanes);
1765
1766 if (!isHigherEventPriority(DiscreteEventPriority, lane)) {
1767 return DiscreteEventPriority;
1768 }
1769
1770 if (!isHigherEventPriority(ContinuousEventPriority, lane)) {
1771 return ContinuousEventPriority;
1772 }
1773
1774 if (includesNonIdleWork(lane)) {
1775 return DefaultEventPriority;
1776 }
1777
1778 return IdleEventPriority;
1779}
1780
1781// Renderers that don't support hydration
1782// can re-export everything from this module.
1783function shim() {
1784 throw new Error('The current renderer does not support hydration. ' + 'This error is likely caused by a bug in React. ' + 'Please file an issue.');
1785} // Hydration (when unsupported)
1786var isSuspenseInstancePending = shim;
1787var isSuspenseInstanceFallback = shim;
1788var getSuspenseInstanceFallbackErrorDetails = shim;
1789var registerSuspenseInstanceRetry = shim;
1790var hydrateTextInstance = shim;
1791var clearSuspenseBoundary = shim;
1792var clearSuspenseBoundaryFromContainer = shim;
1793var errorHydratingContainer = shim;
1794
1795var NO_CONTEXT = {};
1796var UPDATE_SIGNAL = {};
1797var nodeToInstanceMap = new WeakMap();
1798
1799{
1800 Object.freeze(NO_CONTEXT);
1801 Object.freeze(UPDATE_SIGNAL);
1802}
1803
1804function getPublicInstance(inst) {
1805 switch (inst.tag) {
1806 case 'INSTANCE':
1807 var createNodeMock = inst.rootContainerInstance.createNodeMock;
1808 var mockNode = createNodeMock({
1809 type: inst.type,
1810 props: inst.props
1811 });
1812
1813 if (typeof mockNode === 'object' && mockNode !== null) {
1814 nodeToInstanceMap.set(mockNode, inst);
1815 }
1816
1817 return mockNode;
1818
1819 default:
1820 return inst;
1821 }
1822}
1823function appendChild(parentInstance, child) {
1824 {
1825 if (!isArray(parentInstance.children)) {
1826 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.');
1827 }
1828 }
1829
1830 var index = parentInstance.children.indexOf(child);
1831
1832 if (index !== -1) {
1833 parentInstance.children.splice(index, 1);
1834 }
1835
1836 parentInstance.children.push(child);
1837}
1838function insertBefore(parentInstance, child, beforeChild) {
1839 var index = parentInstance.children.indexOf(child);
1840
1841 if (index !== -1) {
1842 parentInstance.children.splice(index, 1);
1843 }
1844
1845 var beforeIndex = parentInstance.children.indexOf(beforeChild);
1846 parentInstance.children.splice(beforeIndex, 0, child);
1847}
1848function removeChild(parentInstance, child) {
1849 var index = parentInstance.children.indexOf(child);
1850 parentInstance.children.splice(index, 1);
1851}
1852function clearContainer(container) {
1853 container.children.splice(0);
1854}
1855function getRootHostContext(rootContainerInstance) {
1856 return NO_CONTEXT;
1857}
1858function getChildHostContext(parentHostContext, type, rootContainerInstance) {
1859 return NO_CONTEXT;
1860}
1861function prepareForCommit(containerInfo) {
1862 // noop
1863 return null;
1864}
1865function resetAfterCommit(containerInfo) {// noop
1866}
1867function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
1868 return {
1869 type: type,
1870 props: props,
1871 isHidden: false,
1872 children: [],
1873 internalInstanceHandle: internalInstanceHandle,
1874 rootContainerInstance: rootContainerInstance,
1875 tag: 'INSTANCE'
1876 };
1877}
1878function appendInitialChild(parentInstance, child) {
1879 var index = parentInstance.children.indexOf(child);
1880
1881 if (index !== -1) {
1882 parentInstance.children.splice(index, 1);
1883 }
1884
1885 parentInstance.children.push(child);
1886}
1887function prepareUpdate(testElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
1888 return UPDATE_SIGNAL;
1889}
1890function shouldSetTextContent(type, props) {
1891 return false;
1892}
1893function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
1894 return {
1895 text: text,
1896 isHidden: false,
1897 tag: 'TEXT'
1898 };
1899}
1900function getCurrentEventPriority() {
1901 return DefaultEventPriority;
1902}
1903var scheduleTimeout = setTimeout;
1904var cancelTimeout = clearTimeout;
1905var noTimeout = -1; // -------------------
1906function commitUpdate(instance, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
1907 instance.type = type;
1908 instance.props = newProps;
1909}
1910function commitTextUpdate(textInstance, oldText, newText) {
1911 textInstance.text = newText;
1912}
1913function resetTextContent(testElement) {// noop
1914}
1915var appendChildToContainer = appendChild;
1916var insertInContainerBefore = insertBefore;
1917var removeChildFromContainer = removeChild;
1918function hideInstance(instance) {
1919 instance.isHidden = true;
1920}
1921function hideTextInstance(textInstance) {
1922 textInstance.isHidden = true;
1923}
1924function unhideInstance(instance, props) {
1925 instance.isHidden = false;
1926}
1927function unhideTextInstance(textInstance, text) {
1928 textInstance.isHidden = false;
1929}
1930function preparePortalMount(portalInstance) {// noop
1931}
1932
1933var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
1934var prefix;
1935function describeBuiltInComponentFrame(name, source, ownerFn) {
1936 {
1937 if (prefix === undefined) {
1938 // Extract the VM specific prefix used by each line.
1939 try {
1940 throw Error();
1941 } catch (x) {
1942 var match = x.stack.trim().match(/\n( *(at )?)/);
1943 prefix = match && match[1] || '';
1944 }
1945 } // We use the prefix to ensure our stacks line up with native stack frames.
1946
1947
1948 return '\n' + prefix + name;
1949 }
1950}
1951var reentry = false;
1952var componentFrameCache;
1953
1954{
1955 var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
1956 componentFrameCache = new PossiblyWeakMap();
1957}
1958
1959function describeNativeComponentFrame(fn, construct) {
1960 // If something asked for a stack inside a fake render, it should get ignored.
1961 if ( !fn || reentry) {
1962 return '';
1963 }
1964
1965 {
1966 var frame = componentFrameCache.get(fn);
1967
1968 if (frame !== undefined) {
1969 return frame;
1970 }
1971 }
1972
1973 var control;
1974 reentry = true;
1975 var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe It does accept undefined.
1976
1977 Error.prepareStackTrace = undefined;
1978 var previousDispatcher;
1979
1980 {
1981 previousDispatcher = ReactCurrentDispatcher.current; // Set the dispatcher in DEV because this might be call in the render function
1982 // for warnings.
1983
1984 ReactCurrentDispatcher.current = null;
1985 disableLogs();
1986 }
1987
1988 try {
1989 // This should throw.
1990 if (construct) {
1991 // Something should be setting the props in the constructor.
1992 var Fake = function () {
1993 throw Error();
1994 }; // $FlowFixMe
1995
1996
1997 Object.defineProperty(Fake.prototype, 'props', {
1998 set: function () {
1999 // We use a throwing setter instead of frozen or non-writable props
2000 // because that won't throw in a non-strict mode function.
2001 throw Error();
2002 }
2003 });
2004
2005 if (typeof Reflect === 'object' && Reflect.construct) {
2006 // We construct a different control for this case to include any extra
2007 // frames added by the construct call.
2008 try {
2009 Reflect.construct(Fake, []);
2010 } catch (x) {
2011 control = x;
2012 }
2013
2014 Reflect.construct(fn, [], Fake);
2015 } else {
2016 try {
2017 Fake.call();
2018 } catch (x) {
2019 control = x;
2020 }
2021
2022 fn.call(Fake.prototype);
2023 }
2024 } else {
2025 try {
2026 throw Error();
2027 } catch (x) {
2028 control = x;
2029 }
2030
2031 fn();
2032 }
2033 } catch (sample) {
2034 // This is inlined manually because closure doesn't do it for us.
2035 if (sample && control && typeof sample.stack === 'string') {
2036 // This extracts the first frame from the sample that isn't also in the control.
2037 // Skipping one frame that we assume is the frame that calls the two.
2038 var sampleLines = sample.stack.split('\n');
2039 var controlLines = control.stack.split('\n');
2040 var s = sampleLines.length - 1;
2041 var c = controlLines.length - 1;
2042
2043 while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {
2044 // We expect at least one stack frame to be shared.
2045 // Typically this will be the root most one. However, stack frames may be
2046 // cut off due to maximum stack limits. In this case, one maybe cut off
2047 // earlier than the other. We assume that the sample is longer or the same
2048 // and there for cut off earlier. So we should find the root most frame in
2049 // the sample somewhere in the control.
2050 c--;
2051 }
2052
2053 for (; s >= 1 && c >= 0; s--, c--) {
2054 // Next we find the first one that isn't the same which should be the
2055 // frame that called our sample function and the control.
2056 if (sampleLines[s] !== controlLines[c]) {
2057 // In V8, the first line is describing the message but other VMs don't.
2058 // If we're about to return the first line, and the control is also on the same
2059 // line, that's a pretty good indicator that our sample threw at same line as
2060 // the control. I.e. before we entered the sample frame. So we ignore this result.
2061 // This can happen if you passed a class to function component, or non-function.
2062 if (s !== 1 || c !== 1) {
2063 do {
2064 s--;
2065 c--; // We may still have similar intermediate frames from the construct call.
2066 // The next one that isn't the same should be our match though.
2067
2068 if (c < 0 || sampleLines[s] !== controlLines[c]) {
2069 // V8 adds a "new" prefix for native classes. Let's remove it to make it prettier.
2070 var _frame = '\n' + sampleLines[s].replace(' at new ', ' at '); // If our component frame is labeled "<anonymous>"
2071 // but we have a user-provided "displayName"
2072 // splice it in to make the stack more readable.
2073
2074
2075 if (fn.displayName && _frame.includes('<anonymous>')) {
2076 _frame = _frame.replace('<anonymous>', fn.displayName);
2077 }
2078
2079 {
2080 if (typeof fn === 'function') {
2081 componentFrameCache.set(fn, _frame);
2082 }
2083 } // Return the line we found.
2084
2085
2086 return _frame;
2087 }
2088 } while (s >= 1 && c >= 0);
2089 }
2090
2091 break;
2092 }
2093 }
2094 }
2095 } finally {
2096 reentry = false;
2097
2098 {
2099 ReactCurrentDispatcher.current = previousDispatcher;
2100 reenableLogs();
2101 }
2102
2103 Error.prepareStackTrace = previousPrepareStackTrace;
2104 } // Fallback to just using the name if we couldn't make it throw.
2105
2106
2107 var name = fn ? fn.displayName || fn.name : '';
2108 var syntheticFrame = name ? describeBuiltInComponentFrame(name) : '';
2109
2110 {
2111 if (typeof fn === 'function') {
2112 componentFrameCache.set(fn, syntheticFrame);
2113 }
2114 }
2115
2116 return syntheticFrame;
2117}
2118
2119function describeClassComponentFrame(ctor, source, ownerFn) {
2120 {
2121 return describeNativeComponentFrame(ctor, true);
2122 }
2123}
2124function describeFunctionComponentFrame(fn, source, ownerFn) {
2125 {
2126 return describeNativeComponentFrame(fn, false);
2127 }
2128}
2129
2130function shouldConstruct(Component) {
2131 var prototype = Component.prototype;
2132 return !!(prototype && prototype.isReactComponent);
2133}
2134
2135function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) {
2136
2137 if (type == null) {
2138 return '';
2139 }
2140
2141 if (typeof type === 'function') {
2142 {
2143 return describeNativeComponentFrame(type, shouldConstruct(type));
2144 }
2145 }
2146
2147 if (typeof type === 'string') {
2148 return describeBuiltInComponentFrame(type);
2149 }
2150
2151 switch (type) {
2152 case REACT_SUSPENSE_TYPE:
2153 return describeBuiltInComponentFrame('Suspense');
2154
2155 case REACT_SUSPENSE_LIST_TYPE:
2156 return describeBuiltInComponentFrame('SuspenseList');
2157 }
2158
2159 if (typeof type === 'object') {
2160 switch (type.$$typeof) {
2161 case REACT_FORWARD_REF_TYPE:
2162 return describeFunctionComponentFrame(type.render);
2163
2164 case REACT_MEMO_TYPE:
2165 // Memo may contain any component type so we recursively resolve it.
2166 return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn);
2167
2168 case REACT_LAZY_TYPE:
2169 {
2170 var lazyComponent = type;
2171 var payload = lazyComponent._payload;
2172 var init = lazyComponent._init;
2173
2174 try {
2175 // Lazy may contain any component type so we recursively resolve it.
2176 return describeUnknownElementTypeFrameInDEV(init(payload), source, ownerFn);
2177 } catch (x) {}
2178 }
2179 }
2180 }
2181
2182 return '';
2183}
2184
2185var hasOwnProperty = Object.prototype.hasOwnProperty;
2186
2187var loggedTypeFailures = {};
2188var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
2189
2190function setCurrentlyValidatingElement(element) {
2191 {
2192 if (element) {
2193 var owner = element._owner;
2194 var stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null);
2195 ReactDebugCurrentFrame.setExtraStackFrame(stack);
2196 } else {
2197 ReactDebugCurrentFrame.setExtraStackFrame(null);
2198 }
2199 }
2200}
2201
2202function checkPropTypes(typeSpecs, values, location, componentName, element) {
2203 {
2204 // $FlowFixMe This is okay but Flow doesn't know it.
2205 var has = Function.call.bind(hasOwnProperty);
2206
2207 for (var typeSpecName in typeSpecs) {
2208 if (has(typeSpecs, typeSpecName)) {
2209 var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to
2210 // fail the render phase where it didn't fail before. So we log it.
2211 // After these have been cleaned up, we'll let them throw.
2212
2213 try {
2214 // This is intentionally an invariant that gets caught. It's the same
2215 // behavior as without this statement except with a better message.
2216 if (typeof typeSpecs[typeSpecName] !== 'function') {
2217 // eslint-disable-next-line react-internal/prod-error-codes
2218 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`.');
2219 err.name = 'Invariant Violation';
2220 throw err;
2221 }
2222
2223 error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
2224 } catch (ex) {
2225 error$1 = ex;
2226 }
2227
2228 if (error$1 && !(error$1 instanceof Error)) {
2229 setCurrentlyValidatingElement(element);
2230
2231 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);
2232
2233 setCurrentlyValidatingElement(null);
2234 }
2235
2236 if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) {
2237 // Only monitor this failure once because there tends to be a lot of the
2238 // same error.
2239 loggedTypeFailures[error$1.message] = true;
2240 setCurrentlyValidatingElement(element);
2241
2242 error('Failed %s type: %s', location, error$1.message);
2243
2244 setCurrentlyValidatingElement(null);
2245 }
2246 }
2247 }
2248 }
2249}
2250
2251var valueStack = [];
2252var fiberStack;
2253
2254{
2255 fiberStack = [];
2256}
2257
2258var index = -1;
2259
2260function createCursor(defaultValue) {
2261 return {
2262 current: defaultValue
2263 };
2264}
2265
2266function pop(cursor, fiber) {
2267 if (index < 0) {
2268 {
2269 error('Unexpected pop.');
2270 }
2271
2272 return;
2273 }
2274
2275 {
2276 if (fiber !== fiberStack[index]) {
2277 error('Unexpected Fiber popped.');
2278 }
2279 }
2280
2281 cursor.current = valueStack[index];
2282 valueStack[index] = null;
2283
2284 {
2285 fiberStack[index] = null;
2286 }
2287
2288 index--;
2289}
2290
2291function push(cursor, value, fiber) {
2292 index++;
2293 valueStack[index] = cursor.current;
2294
2295 {
2296 fiberStack[index] = fiber;
2297 }
2298
2299 cursor.current = value;
2300}
2301
2302var warnedAboutMissingGetChildContext;
2303
2304{
2305 warnedAboutMissingGetChildContext = {};
2306}
2307
2308var emptyContextObject = {};
2309
2310{
2311 Object.freeze(emptyContextObject);
2312} // A cursor to the current merged context object on the stack.
2313
2314
2315var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.
2316
2317var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.
2318// We use this to get access to the parent context after we have already
2319// pushed the next context provider, and now need to merge their contexts.
2320
2321var previousContext = emptyContextObject;
2322
2323function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
2324 {
2325 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
2326 // If the fiber is a context provider itself, when we read its context
2327 // we may have already pushed its own child context on the stack. A context
2328 // provider should not "see" its own child context. Therefore we read the
2329 // previous (parent) context instead for a context provider.
2330 return previousContext;
2331 }
2332
2333 return contextStackCursor.current;
2334 }
2335}
2336
2337function cacheContext(workInProgress, unmaskedContext, maskedContext) {
2338 {
2339 var instance = workInProgress.stateNode;
2340 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
2341 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
2342 }
2343}
2344
2345function getMaskedContext(workInProgress, unmaskedContext) {
2346 {
2347 var type = workInProgress.type;
2348 var contextTypes = type.contextTypes;
2349
2350 if (!contextTypes) {
2351 return emptyContextObject;
2352 } // Avoid recreating masked context unless unmasked context has changed.
2353 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
2354 // This may trigger infinite loops if componentWillReceiveProps calls setState.
2355
2356
2357 var instance = workInProgress.stateNode;
2358
2359 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
2360 return instance.__reactInternalMemoizedMaskedChildContext;
2361 }
2362
2363 var context = {};
2364
2365 for (var key in contextTypes) {
2366 context[key] = unmaskedContext[key];
2367 }
2368
2369 {
2370 var name = getComponentNameFromFiber(workInProgress) || 'Unknown';
2371 checkPropTypes(contextTypes, context, 'context', name);
2372 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
2373 // Context is created before the class component is instantiated so check for instance.
2374
2375
2376 if (instance) {
2377 cacheContext(workInProgress, unmaskedContext, context);
2378 }
2379
2380 return context;
2381 }
2382}
2383
2384function hasContextChanged() {
2385 {
2386 return didPerformWorkStackCursor.current;
2387 }
2388}
2389
2390function isContextProvider(type) {
2391 {
2392 var childContextTypes = type.childContextTypes;
2393 return childContextTypes !== null && childContextTypes !== undefined;
2394 }
2395}
2396
2397function popContext(fiber) {
2398 {
2399 pop(didPerformWorkStackCursor, fiber);
2400 pop(contextStackCursor, fiber);
2401 }
2402}
2403
2404function popTopLevelContextObject(fiber) {
2405 {
2406 pop(didPerformWorkStackCursor, fiber);
2407 pop(contextStackCursor, fiber);
2408 }
2409}
2410
2411function pushTopLevelContextObject(fiber, context, didChange) {
2412 {
2413 if (contextStackCursor.current !== emptyContextObject) {
2414 throw new Error('Unexpected context found on stack. ' + 'This error is likely caused by a bug in React. Please file an issue.');
2415 }
2416
2417 push(contextStackCursor, context, fiber);
2418 push(didPerformWorkStackCursor, didChange, fiber);
2419 }
2420}
2421
2422function processChildContext(fiber, type, parentContext) {
2423 {
2424 var instance = fiber.stateNode;
2425 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.
2426 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
2427
2428 if (typeof instance.getChildContext !== 'function') {
2429 {
2430 var componentName = getComponentNameFromFiber(fiber) || 'Unknown';
2431
2432 if (!warnedAboutMissingGetChildContext[componentName]) {
2433 warnedAboutMissingGetChildContext[componentName] = true;
2434
2435 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);
2436 }
2437 }
2438
2439 return parentContext;
2440 }
2441
2442 var childContext = instance.getChildContext();
2443
2444 for (var contextKey in childContext) {
2445 if (!(contextKey in childContextTypes)) {
2446 throw new Error((getComponentNameFromFiber(fiber) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes.");
2447 }
2448 }
2449
2450 {
2451 var name = getComponentNameFromFiber(fiber) || 'Unknown';
2452 checkPropTypes(childContextTypes, childContext, 'child context', name);
2453 }
2454
2455 return assign({}, parentContext, childContext);
2456 }
2457}
2458
2459function pushContextProvider(workInProgress) {
2460 {
2461 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.
2462 // If the instance does not exist yet, we will push null at first,
2463 // and replace it on the stack later when invalidating the context.
2464
2465 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.
2466 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
2467
2468 previousContext = contextStackCursor.current;
2469 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
2470 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
2471 return true;
2472 }
2473}
2474
2475function invalidateContextProvider(workInProgress, type, didChange) {
2476 {
2477 var instance = workInProgress.stateNode;
2478
2479 if (!instance) {
2480 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.');
2481 }
2482
2483 if (didChange) {
2484 // Merge parent and own context.
2485 // Skip this if we're not updating due to sCU.
2486 // This avoids unnecessarily recomputing memoized values.
2487 var mergedContext = processChildContext(workInProgress, type, previousContext);
2488 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.
2489 // It is important to unwind the context in the reverse order.
2490
2491 pop(didPerformWorkStackCursor, workInProgress);
2492 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.
2493
2494 push(contextStackCursor, mergedContext, workInProgress);
2495 push(didPerformWorkStackCursor, didChange, workInProgress);
2496 } else {
2497 pop(didPerformWorkStackCursor, workInProgress);
2498 push(didPerformWorkStackCursor, didChange, workInProgress);
2499 }
2500 }
2501}
2502
2503function findCurrentUnmaskedContext(fiber) {
2504 {
2505 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
2506 // makes sense elsewhere
2507 if (!isFiberMounted(fiber) || fiber.tag !== ClassComponent) {
2508 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.');
2509 }
2510
2511 var node = fiber;
2512
2513 do {
2514 switch (node.tag) {
2515 case HostRoot:
2516 return node.stateNode.context;
2517
2518 case ClassComponent:
2519 {
2520 var Component = node.type;
2521
2522 if (isContextProvider(Component)) {
2523 return node.stateNode.__reactInternalMemoizedMergedChildContext;
2524 }
2525
2526 break;
2527 }
2528 }
2529
2530 node = node.return;
2531 } while (node !== null);
2532
2533 throw new Error('Found unexpected detached subtree parent. ' + 'This error is likely caused by a bug in React. Please file an issue.');
2534 }
2535}
2536
2537var LegacyRoot = 0;
2538var ConcurrentRoot = 1;
2539
2540/**
2541 * inlined Object.is polyfill to avoid requiring consumers ship their own
2542 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
2543 */
2544function is(x, y) {
2545 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
2546 ;
2547}
2548
2549var objectIs = typeof Object.is === 'function' ? Object.is : is;
2550
2551var syncQueue = null;
2552var includesLegacySyncCallbacks = false;
2553var isFlushingSyncQueue = false;
2554function scheduleSyncCallback(callback) {
2555 // Push this callback into an internal queue. We'll flush these either in
2556 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
2557 if (syncQueue === null) {
2558 syncQueue = [callback];
2559 } else {
2560 // Push onto existing queue. Don't need to schedule a callback because
2561 // we already scheduled one when we created the queue.
2562 syncQueue.push(callback);
2563 }
2564}
2565function scheduleLegacySyncCallback(callback) {
2566 includesLegacySyncCallbacks = true;
2567 scheduleSyncCallback(callback);
2568}
2569function flushSyncCallbacksOnlyInLegacyMode() {
2570 // Only flushes the queue if there's a legacy sync callback scheduled.
2571 // TODO: There's only a single type of callback: performSyncOnWorkOnRoot. So
2572 // it might make more sense for the queue to be a list of roots instead of a
2573 // list of generic callbacks. Then we can have two: one for legacy roots, one
2574 // for concurrent roots. And this method would only flush the legacy ones.
2575 if (includesLegacySyncCallbacks) {
2576 flushSyncCallbacks();
2577 }
2578}
2579function flushSyncCallbacks() {
2580 if (!isFlushingSyncQueue && syncQueue !== null) {
2581 // Prevent re-entrance.
2582 isFlushingSyncQueue = true;
2583 var i = 0;
2584 var previousUpdatePriority = getCurrentUpdatePriority();
2585
2586 try {
2587 var isSync = true;
2588 var queue = syncQueue; // TODO: Is this necessary anymore? The only user code that runs in this
2589 // queue is in the render or commit phases.
2590
2591 setCurrentUpdatePriority(DiscreteEventPriority);
2592
2593 for (; i < queue.length; i++) {
2594 var callback = queue[i];
2595
2596 do {
2597 callback = callback(isSync);
2598 } while (callback !== null);
2599 }
2600
2601 syncQueue = null;
2602 includesLegacySyncCallbacks = false;
2603 } catch (error) {
2604 // If something throws, leave the remaining callbacks on the queue.
2605 if (syncQueue !== null) {
2606 syncQueue = syncQueue.slice(i + 1);
2607 } // Resume flushing in the next tick
2608
2609
2610 scheduleCallback(ImmediatePriority, flushSyncCallbacks);
2611 throw error;
2612 } finally {
2613 setCurrentUpdatePriority(previousUpdatePriority);
2614 isFlushingSyncQueue = false;
2615 }
2616 }
2617
2618 return null;
2619}
2620
2621// This is imported by the event replaying implementation in React DOM. It's
2622// in a separate file to break a circular dependency between the renderer and
2623// the reconciler.
2624function isRootDehydrated(root) {
2625 var currentState = root.current.memoizedState;
2626 return currentState.isDehydrated;
2627}
2628
2629// TODO: Use the unified fiber stack module instead of this local one?
2630// Intentionally not using it yet to derisk the initial implementation, because
2631// the way we push/pop these values is a bit unusual. If there's a mistake, I'd
2632// rather the ids be wrong than crash the whole reconciler.
2633var forkStack = [];
2634var forkStackIndex = 0;
2635var treeForkProvider = null;
2636var treeForkCount = 0;
2637var idStack = [];
2638var idStackIndex = 0;
2639var treeContextProvider = null;
2640var treeContextId = 1;
2641var treeContextOverflow = '';
2642
2643function popTreeContext(workInProgress) {
2644 // Restore the previous values.
2645 // This is a bit more complicated than other context-like modules in Fiber
2646 // because the same Fiber may appear on the stack multiple times and for
2647 // different reasons. We have to keep popping until the work-in-progress is
2648 // no longer at the top of the stack.
2649 while (workInProgress === treeForkProvider) {
2650 treeForkProvider = forkStack[--forkStackIndex];
2651 forkStack[forkStackIndex] = null;
2652 treeForkCount = forkStack[--forkStackIndex];
2653 forkStack[forkStackIndex] = null;
2654 }
2655
2656 while (workInProgress === treeContextProvider) {
2657 treeContextProvider = idStack[--idStackIndex];
2658 idStack[idStackIndex] = null;
2659 treeContextOverflow = idStack[--idStackIndex];
2660 idStack[idStackIndex] = null;
2661 treeContextId = idStack[--idStackIndex];
2662 idStack[idStackIndex] = null;
2663 }
2664}
2665
2666var isHydrating = false; // This flag allows for warning supression when we expect there to be mismatches
2667
2668var hydrationErrors = null;
2669
2670function reenterHydrationStateFromDehydratedSuspenseInstance(fiber, suspenseInstance, treeContext) {
2671 {
2672 return false;
2673 }
2674}
2675
2676function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
2677 {
2678 throw new Error('Expected prepareToHydrateHostInstance() to never be called. ' + 'This error is likely caused by a bug in React. Please file an issue.');
2679 }
2680}
2681
2682function prepareToHydrateHostTextInstance(fiber) {
2683 {
2684 throw new Error('Expected prepareToHydrateHostTextInstance() to never be called. ' + 'This error is likely caused by a bug in React. Please file an issue.');
2685 }
2686 var shouldUpdate = hydrateTextInstance();
2687}
2688
2689function prepareToHydrateHostSuspenseInstance(fiber) {
2690 {
2691 throw new Error('Expected prepareToHydrateHostSuspenseInstance() to never be called. ' + 'This error is likely caused by a bug in React. Please file an issue.');
2692 }
2693}
2694
2695function popHydrationState(fiber) {
2696 {
2697 return false;
2698 }
2699}
2700
2701function upgradeHydrationErrorsToRecoverable() {
2702 if (hydrationErrors !== null) {
2703 // Successfully completed a forced client render. The errors that occurred
2704 // during the hydration attempt are now recovered. We will log them in
2705 // commit phase, once the entire tree has finished.
2706 queueRecoverableErrors(hydrationErrors);
2707 hydrationErrors = null;
2708 }
2709}
2710
2711function getIsHydrating() {
2712 return isHydrating;
2713}
2714
2715function queueHydrationError(error) {
2716 if (hydrationErrors === null) {
2717 hydrationErrors = [error];
2718 } else {
2719 hydrationErrors.push(error);
2720 }
2721}
2722
2723var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
2724var NoTransition = null;
2725function requestCurrentTransition() {
2726 return ReactCurrentBatchConfig.transition;
2727}
2728
2729/**
2730 * Performs equality by iterating through keys on an object and returning false
2731 * when any key has values which are not strictly equal between the arguments.
2732 * Returns true when the values of all keys are strictly equal.
2733 */
2734
2735function shallowEqual(objA, objB) {
2736 if (objectIs(objA, objB)) {
2737 return true;
2738 }
2739
2740 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
2741 return false;
2742 }
2743
2744 var keysA = Object.keys(objA);
2745 var keysB = Object.keys(objB);
2746
2747 if (keysA.length !== keysB.length) {
2748 return false;
2749 } // Test for A's keys different from B.
2750
2751
2752 for (var i = 0; i < keysA.length; i++) {
2753 var currentKey = keysA[i];
2754
2755 if (!hasOwnProperty.call(objB, currentKey) || !objectIs(objA[currentKey], objB[currentKey])) {
2756 return false;
2757 }
2758 }
2759
2760 return true;
2761}
2762
2763function describeFiber(fiber) {
2764 var owner = fiber._debugOwner ? fiber._debugOwner.type : null ;
2765 var source = fiber._debugSource ;
2766
2767 switch (fiber.tag) {
2768 case HostComponent:
2769 return describeBuiltInComponentFrame(fiber.type);
2770
2771 case LazyComponent:
2772 return describeBuiltInComponentFrame('Lazy');
2773
2774 case SuspenseComponent:
2775 return describeBuiltInComponentFrame('Suspense');
2776
2777 case SuspenseListComponent:
2778 return describeBuiltInComponentFrame('SuspenseList');
2779
2780 case FunctionComponent:
2781 case IndeterminateComponent:
2782 case SimpleMemoComponent:
2783 return describeFunctionComponentFrame(fiber.type);
2784
2785 case ForwardRef:
2786 return describeFunctionComponentFrame(fiber.type.render);
2787
2788 case ClassComponent:
2789 return describeClassComponentFrame(fiber.type);
2790
2791 default:
2792 return '';
2793 }
2794}
2795
2796function getStackByFiberInDevAndProd(workInProgress) {
2797 try {
2798 var info = '';
2799 var node = workInProgress;
2800
2801 do {
2802 info += describeFiber(node);
2803 node = node.return;
2804 } while (node);
2805
2806 return info;
2807 } catch (x) {
2808 return '\nError generating stack: ' + x.message + '\n' + x.stack;
2809 }
2810}
2811
2812var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
2813var current = null;
2814var isRendering = false;
2815function getCurrentFiberOwnerNameInDevOrNull() {
2816 {
2817 if (current === null) {
2818 return null;
2819 }
2820
2821 var owner = current._debugOwner;
2822
2823 if (owner !== null && typeof owner !== 'undefined') {
2824 return getComponentNameFromFiber(owner);
2825 }
2826 }
2827
2828 return null;
2829}
2830
2831function getCurrentFiberStackInDev() {
2832 {
2833 if (current === null) {
2834 return '';
2835 } // Safe because if current fiber exists, we are reconciling,
2836 // and it is guaranteed to be the work-in-progress version.
2837
2838
2839 return getStackByFiberInDevAndProd(current);
2840 }
2841}
2842
2843function resetCurrentFiber() {
2844 {
2845 ReactDebugCurrentFrame$1.getCurrentStack = null;
2846 current = null;
2847 isRendering = false;
2848 }
2849}
2850function setCurrentFiber(fiber) {
2851 {
2852 ReactDebugCurrentFrame$1.getCurrentStack = fiber === null ? null : getCurrentFiberStackInDev;
2853 current = fiber;
2854 isRendering = false;
2855 }
2856}
2857function getCurrentFiber() {
2858 {
2859 return current;
2860 }
2861}
2862function setIsRendering(rendering) {
2863 {
2864 isRendering = rendering;
2865 }
2866}
2867
2868var ReactStrictModeWarnings = {
2869 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
2870 flushPendingUnsafeLifecycleWarnings: function () {},
2871 recordLegacyContextWarning: function (fiber, instance) {},
2872 flushLegacyContextWarning: function () {},
2873 discardPendingWarnings: function () {}
2874};
2875
2876{
2877 var findStrictRoot = function (fiber) {
2878 var maybeStrictRoot = null;
2879 var node = fiber;
2880
2881 while (node !== null) {
2882 if (node.mode & StrictLegacyMode) {
2883 maybeStrictRoot = node;
2884 }
2885
2886 node = node.return;
2887 }
2888
2889 return maybeStrictRoot;
2890 };
2891
2892 var setToSortedString = function (set) {
2893 var array = [];
2894 set.forEach(function (value) {
2895 array.push(value);
2896 });
2897 return array.sort().join(', ');
2898 };
2899
2900 var pendingComponentWillMountWarnings = [];
2901 var pendingUNSAFE_ComponentWillMountWarnings = [];
2902 var pendingComponentWillReceivePropsWarnings = [];
2903 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2904 var pendingComponentWillUpdateWarnings = [];
2905 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
2906
2907 var didWarnAboutUnsafeLifecycles = new Set();
2908
2909 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
2910 // Dedupe strategy: Warn once per component.
2911 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
2912 return;
2913 }
2914
2915 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.
2916 instance.componentWillMount.__suppressDeprecationWarning !== true) {
2917 pendingComponentWillMountWarnings.push(fiber);
2918 }
2919
2920 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillMount === 'function') {
2921 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
2922 }
2923
2924 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
2925 pendingComponentWillReceivePropsWarnings.push(fiber);
2926 }
2927
2928 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
2929 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
2930 }
2931
2932 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
2933 pendingComponentWillUpdateWarnings.push(fiber);
2934 }
2935
2936 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
2937 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
2938 }
2939 };
2940
2941 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
2942 // We do an initial pass to gather component names
2943 var componentWillMountUniqueNames = new Set();
2944
2945 if (pendingComponentWillMountWarnings.length > 0) {
2946 pendingComponentWillMountWarnings.forEach(function (fiber) {
2947 componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
2948 didWarnAboutUnsafeLifecycles.add(fiber.type);
2949 });
2950 pendingComponentWillMountWarnings = [];
2951 }
2952
2953 var UNSAFE_componentWillMountUniqueNames = new Set();
2954
2955 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
2956 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
2957 UNSAFE_componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
2958 didWarnAboutUnsafeLifecycles.add(fiber.type);
2959 });
2960 pendingUNSAFE_ComponentWillMountWarnings = [];
2961 }
2962
2963 var componentWillReceivePropsUniqueNames = new Set();
2964
2965 if (pendingComponentWillReceivePropsWarnings.length > 0) {
2966 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
2967 componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
2968 didWarnAboutUnsafeLifecycles.add(fiber.type);
2969 });
2970 pendingComponentWillReceivePropsWarnings = [];
2971 }
2972
2973 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
2974
2975 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
2976 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
2977 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
2978 didWarnAboutUnsafeLifecycles.add(fiber.type);
2979 });
2980 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2981 }
2982
2983 var componentWillUpdateUniqueNames = new Set();
2984
2985 if (pendingComponentWillUpdateWarnings.length > 0) {
2986 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
2987 componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
2988 didWarnAboutUnsafeLifecycles.add(fiber.type);
2989 });
2990 pendingComponentWillUpdateWarnings = [];
2991 }
2992
2993 var UNSAFE_componentWillUpdateUniqueNames = new Set();
2994
2995 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
2996 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
2997 UNSAFE_componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
2998 didWarnAboutUnsafeLifecycles.add(fiber.type);
2999 });
3000 pendingUNSAFE_ComponentWillUpdateWarnings = [];
3001 } // Finally, we flush all the warnings
3002 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
3003
3004
3005 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
3006 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
3007
3008 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);
3009 }
3010
3011 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
3012 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
3013
3014 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);
3015 }
3016
3017 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
3018 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
3019
3020 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);
3021 }
3022
3023 if (componentWillMountUniqueNames.size > 0) {
3024 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
3025
3026 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);
3027 }
3028
3029 if (componentWillReceivePropsUniqueNames.size > 0) {
3030 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
3031
3032 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);
3033 }
3034
3035 if (componentWillUpdateUniqueNames.size > 0) {
3036 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
3037
3038 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);
3039 }
3040 };
3041
3042 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
3043
3044 var didWarnAboutLegacyContext = new Set();
3045
3046 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
3047 var strictRoot = findStrictRoot(fiber);
3048
3049 if (strictRoot === null) {
3050 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.');
3051
3052 return;
3053 } // Dedup strategy: Warn once per component.
3054
3055
3056 if (didWarnAboutLegacyContext.has(fiber.type)) {
3057 return;
3058 }
3059
3060 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
3061
3062 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
3063 if (warningsForRoot === undefined) {
3064 warningsForRoot = [];
3065 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
3066 }
3067
3068 warningsForRoot.push(fiber);
3069 }
3070 };
3071
3072 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
3073 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
3074 if (fiberArray.length === 0) {
3075 return;
3076 }
3077
3078 var firstFiber = fiberArray[0];
3079 var uniqueNames = new Set();
3080 fiberArray.forEach(function (fiber) {
3081 uniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
3082 didWarnAboutLegacyContext.add(fiber.type);
3083 });
3084 var sortedNames = setToSortedString(uniqueNames);
3085
3086 try {
3087 setCurrentFiber(firstFiber);
3088
3089 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);
3090 } finally {
3091 resetCurrentFiber();
3092 }
3093 });
3094 };
3095
3096 ReactStrictModeWarnings.discardPendingWarnings = function () {
3097 pendingComponentWillMountWarnings = [];
3098 pendingUNSAFE_ComponentWillMountWarnings = [];
3099 pendingComponentWillReceivePropsWarnings = [];
3100 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
3101 pendingComponentWillUpdateWarnings = [];
3102 pendingUNSAFE_ComponentWillUpdateWarnings = [];
3103 pendingLegacyContextWarning = new Map();
3104 };
3105}
3106
3107/*
3108 * The `'' + value` pattern (used in in perf-sensitive code) throws for Symbol
3109 * and Temporal.* types. See https://github.com/facebook/react/pull/22064.
3110 *
3111 * The functions in this module will throw an easier-to-understand,
3112 * easier-to-debug exception with a clear errors message message explaining the
3113 * problem. (Instead of a confusing exception thrown inside the implementation
3114 * of the `value` object).
3115 */
3116// $FlowFixMe only called in DEV, so void return is not possible.
3117function typeName(value) {
3118 {
3119 // toStringTag is needed for namespaced types like Temporal.Instant
3120 var hasToStringTag = typeof Symbol === 'function' && Symbol.toStringTag;
3121 var type = hasToStringTag && value[Symbol.toStringTag] || value.constructor.name || 'Object';
3122 return type;
3123 }
3124} // $FlowFixMe only called in DEV, so void return is not possible.
3125
3126
3127function willCoercionThrow(value) {
3128 {
3129 try {
3130 testStringCoercion(value);
3131 return false;
3132 } catch (e) {
3133 return true;
3134 }
3135 }
3136}
3137
3138function testStringCoercion(value) {
3139 // If you ended up here by following an exception call stack, here's what's
3140 // happened: you supplied an object or symbol value to React (as a prop, key,
3141 // DOM attribute, CSS property, string ref, etc.) and when React tried to
3142 // coerce it to a string using `'' + value`, an exception was thrown.
3143 //
3144 // The most common types that will cause this exception are `Symbol` instances
3145 // and Temporal objects like `Temporal.Instant`. But any object that has a
3146 // `valueOf` or `[Symbol.toPrimitive]` method that throws will also cause this
3147 // exception. (Library authors do this to prevent users from using built-in
3148 // numeric operators like `+` or comparison operators like `>=` because custom
3149 // methods are needed to perform accurate arithmetic or comparison.)
3150 //
3151 // To fix the problem, coerce this object or symbol value to a string before
3152 // passing it to React. The most reliable way is usually `String(value)`.
3153 //
3154 // To find which value is throwing, check the browser or debugger console.
3155 // Before this exception was thrown, there should be `console.error` output
3156 // that shows the type (Symbol, Temporal.PlainDate, etc.) that caused the
3157 // problem and how that type was used: key, atrribute, input value prop, etc.
3158 // In most cases, this console output also shows the component and its
3159 // ancestor components where the exception happened.
3160 //
3161 // eslint-disable-next-line react-internal/safe-string-coercion
3162 return '' + value;
3163}
3164function checkPropStringCoercion(value, propName) {
3165 {
3166 if (willCoercionThrow(value)) {
3167 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));
3168
3169 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
3170 }
3171 }
3172}
3173
3174function resolveDefaultProps(Component, baseProps) {
3175 if (Component && Component.defaultProps) {
3176 // Resolve default props. Taken from ReactElement
3177 var props = assign({}, baseProps);
3178 var defaultProps = Component.defaultProps;
3179
3180 for (var propName in defaultProps) {
3181 if (props[propName] === undefined) {
3182 props[propName] = defaultProps[propName];
3183 }
3184 }
3185
3186 return props;
3187 }
3188
3189 return baseProps;
3190}
3191
3192var valueCursor = createCursor(null);
3193var rendererSigil;
3194
3195{
3196 // Use this to detect multiple renderers using the same context
3197 rendererSigil = {};
3198}
3199
3200var currentlyRenderingFiber = null;
3201var lastContextDependency = null;
3202var lastFullyObservedContext = null;
3203var isDisallowedContextReadInDEV = false;
3204function resetContextDependencies() {
3205 // This is called right before React yields execution, to ensure `readContext`
3206 // cannot be called outside the render phase.
3207 currentlyRenderingFiber = null;
3208 lastContextDependency = null;
3209 lastFullyObservedContext = null;
3210
3211 {
3212 isDisallowedContextReadInDEV = false;
3213 }
3214}
3215function enterDisallowedContextReadInDEV() {
3216 {
3217 isDisallowedContextReadInDEV = true;
3218 }
3219}
3220function exitDisallowedContextReadInDEV() {
3221 {
3222 isDisallowedContextReadInDEV = false;
3223 }
3224}
3225function pushProvider(providerFiber, context, nextValue) {
3226 {
3227 push(valueCursor, context._currentValue2, providerFiber);
3228 context._currentValue2 = nextValue;
3229
3230 {
3231 if (context._currentRenderer2 !== undefined && context._currentRenderer2 !== null && context._currentRenderer2 !== rendererSigil) {
3232 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.');
3233 }
3234
3235 context._currentRenderer2 = rendererSigil;
3236 }
3237 }
3238}
3239function popProvider(context, providerFiber) {
3240 var currentValue = valueCursor.current;
3241 pop(valueCursor, providerFiber);
3242
3243 {
3244 {
3245 context._currentValue2 = currentValue;
3246 }
3247 }
3248}
3249function scheduleContextWorkOnParentPath(parent, renderLanes, propagationRoot) {
3250 // Update the child lanes of all the ancestors, including the alternates.
3251 var node = parent;
3252
3253 while (node !== null) {
3254 var alternate = node.alternate;
3255
3256 if (!isSubsetOfLanes(node.childLanes, renderLanes)) {
3257 node.childLanes = mergeLanes(node.childLanes, renderLanes);
3258
3259 if (alternate !== null) {
3260 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
3261 }
3262 } else if (alternate !== null && !isSubsetOfLanes(alternate.childLanes, renderLanes)) {
3263 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
3264 }
3265
3266 if (node === propagationRoot) {
3267 break;
3268 }
3269
3270 node = node.return;
3271 }
3272
3273 {
3274 if (node !== propagationRoot) {
3275 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.');
3276 }
3277 }
3278}
3279function propagateContextChange(workInProgress, context, renderLanes) {
3280 {
3281 propagateContextChange_eager(workInProgress, context, renderLanes);
3282 }
3283}
3284
3285function propagateContextChange_eager(workInProgress, context, renderLanes) {
3286
3287 var fiber = workInProgress.child;
3288
3289 if (fiber !== null) {
3290 // Set the return pointer of the child to the work-in-progress fiber.
3291 fiber.return = workInProgress;
3292 }
3293
3294 while (fiber !== null) {
3295 var nextFiber = void 0; // Visit this fiber.
3296
3297 var list = fiber.dependencies;
3298
3299 if (list !== null) {
3300 nextFiber = fiber.child;
3301 var dependency = list.firstContext;
3302
3303 while (dependency !== null) {
3304 // Check if the context matches.
3305 if (dependency.context === context) {
3306 // Match! Schedule an update on this fiber.
3307 if (fiber.tag === ClassComponent) {
3308 // Schedule a force update on the work-in-progress.
3309 var lane = pickArbitraryLane(renderLanes);
3310 var update = createUpdate(NoTimestamp, lane);
3311 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
3312 // update to the current fiber, too, which means it will persist even if
3313 // this render is thrown away. Since it's a race condition, not sure it's
3314 // worth fixing.
3315 // Inlined `enqueueUpdate` to remove interleaved update check
3316
3317 var updateQueue = fiber.updateQueue;
3318
3319 if (updateQueue === null) ; else {
3320 var sharedQueue = updateQueue.shared;
3321 var pending = sharedQueue.pending;
3322
3323 if (pending === null) {
3324 // This is the first update. Create a circular list.
3325 update.next = update;
3326 } else {
3327 update.next = pending.next;
3328 pending.next = update;
3329 }
3330
3331 sharedQueue.pending = update;
3332 }
3333 }
3334
3335 fiber.lanes = mergeLanes(fiber.lanes, renderLanes);
3336 var alternate = fiber.alternate;
3337
3338 if (alternate !== null) {
3339 alternate.lanes = mergeLanes(alternate.lanes, renderLanes);
3340 }
3341
3342 scheduleContextWorkOnParentPath(fiber.return, renderLanes, workInProgress); // Mark the updated lanes on the list, too.
3343
3344 list.lanes = mergeLanes(list.lanes, renderLanes); // Since we already found a match, we can stop traversing the
3345 // dependency list.
3346
3347 break;
3348 }
3349
3350 dependency = dependency.next;
3351 }
3352 } else if (fiber.tag === ContextProvider) {
3353 // Don't scan deeper if this is a matching provider
3354 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
3355 } else if (fiber.tag === DehydratedFragment) {
3356 // If a dehydrated suspense boundary is in this subtree, we don't know
3357 // if it will have any context consumers in it. The best we can do is
3358 // mark it as having updates.
3359 var parentSuspense = fiber.return;
3360
3361 if (parentSuspense === null) {
3362 throw new Error('We just came from a parent so we must have had a parent. This is a bug in React.');
3363 }
3364
3365 parentSuspense.lanes = mergeLanes(parentSuspense.lanes, renderLanes);
3366 var _alternate = parentSuspense.alternate;
3367
3368 if (_alternate !== null) {
3369 _alternate.lanes = mergeLanes(_alternate.lanes, renderLanes);
3370 } // This is intentionally passing this fiber as the parent
3371 // because we want to schedule this fiber as having work
3372 // on its children. We'll use the childLanes on
3373 // this fiber to indicate that a context has changed.
3374
3375
3376 scheduleContextWorkOnParentPath(parentSuspense, renderLanes, workInProgress);
3377 nextFiber = fiber.sibling;
3378 } else {
3379 // Traverse down.
3380 nextFiber = fiber.child;
3381 }
3382
3383 if (nextFiber !== null) {
3384 // Set the return pointer of the child to the work-in-progress fiber.
3385 nextFiber.return = fiber;
3386 } else {
3387 // No child. Traverse to next sibling.
3388 nextFiber = fiber;
3389
3390 while (nextFiber !== null) {
3391 if (nextFiber === workInProgress) {
3392 // We're back to the root of this subtree. Exit.
3393 nextFiber = null;
3394 break;
3395 }
3396
3397 var sibling = nextFiber.sibling;
3398
3399 if (sibling !== null) {
3400 // Set the return pointer of the sibling to the work-in-progress fiber.
3401 sibling.return = nextFiber.return;
3402 nextFiber = sibling;
3403 break;
3404 } // No more siblings. Traverse up.
3405
3406
3407 nextFiber = nextFiber.return;
3408 }
3409 }
3410
3411 fiber = nextFiber;
3412 }
3413}
3414function prepareToReadContext(workInProgress, renderLanes) {
3415 currentlyRenderingFiber = workInProgress;
3416 lastContextDependency = null;
3417 lastFullyObservedContext = null;
3418 var dependencies = workInProgress.dependencies;
3419
3420 if (dependencies !== null) {
3421 {
3422 var firstContext = dependencies.firstContext;
3423
3424 if (firstContext !== null) {
3425 if (includesSomeLane(dependencies.lanes, renderLanes)) {
3426 // Context list has a pending update. Mark that this fiber performed work.
3427 markWorkInProgressReceivedUpdate();
3428 } // Reset the work-in-progress list
3429
3430
3431 dependencies.firstContext = null;
3432 }
3433 }
3434 }
3435}
3436function readContext(context) {
3437 {
3438 // This warning would fire if you read context inside a Hook like useMemo.
3439 // Unlike the class check below, it's not enforced in production for perf.
3440 if (isDisallowedContextReadInDEV) {
3441 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().');
3442 }
3443 }
3444
3445 var value = context._currentValue2;
3446
3447 if (lastFullyObservedContext === context) ; else {
3448 var contextItem = {
3449 context: context,
3450 memoizedValue: value,
3451 next: null
3452 };
3453
3454 if (lastContextDependency === null) {
3455 if (currentlyRenderingFiber === null) {
3456 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().');
3457 } // This is the first dependency for this component. Create a new list.
3458
3459
3460 lastContextDependency = contextItem;
3461 currentlyRenderingFiber.dependencies = {
3462 lanes: NoLanes,
3463 firstContext: contextItem
3464 };
3465 } else {
3466 // Append a new context item.
3467 lastContextDependency = lastContextDependency.next = contextItem;
3468 }
3469 }
3470
3471 return value;
3472}
3473
3474// render. When this render exits, either because it finishes or because it is
3475// interrupted, the interleaved updates will be transferred onto the main part
3476// of the queue.
3477
3478var concurrentQueues = null;
3479function pushConcurrentUpdateQueue(queue) {
3480 if (concurrentQueues === null) {
3481 concurrentQueues = [queue];
3482 } else {
3483 concurrentQueues.push(queue);
3484 }
3485}
3486function finishQueueingConcurrentUpdates() {
3487 // Transfer the interleaved updates onto the main queue. Each queue has a
3488 // `pending` field and an `interleaved` field. When they are not null, they
3489 // point to the last node in a circular linked list. We need to append the
3490 // interleaved list to the end of the pending list by joining them into a
3491 // single, circular list.
3492 if (concurrentQueues !== null) {
3493 for (var i = 0; i < concurrentQueues.length; i++) {
3494 var queue = concurrentQueues[i];
3495 var lastInterleavedUpdate = queue.interleaved;
3496
3497 if (lastInterleavedUpdate !== null) {
3498 queue.interleaved = null;
3499 var firstInterleavedUpdate = lastInterleavedUpdate.next;
3500 var lastPendingUpdate = queue.pending;
3501
3502 if (lastPendingUpdate !== null) {
3503 var firstPendingUpdate = lastPendingUpdate.next;
3504 lastPendingUpdate.next = firstInterleavedUpdate;
3505 lastInterleavedUpdate.next = firstPendingUpdate;
3506 }
3507
3508 queue.pending = lastInterleavedUpdate;
3509 }
3510 }
3511
3512 concurrentQueues = null;
3513 }
3514}
3515function enqueueConcurrentHookUpdate(fiber, queue, update, lane) {
3516 var interleaved = queue.interleaved;
3517
3518 if (interleaved === null) {
3519 // This is the first update. Create a circular list.
3520 update.next = update; // At the end of the current render, this queue's interleaved updates will
3521 // be transferred to the pending queue.
3522
3523 pushConcurrentUpdateQueue(queue);
3524 } else {
3525 update.next = interleaved.next;
3526 interleaved.next = update;
3527 }
3528
3529 queue.interleaved = update;
3530 return markUpdateLaneFromFiberToRoot(fiber, lane);
3531}
3532function enqueueConcurrentHookUpdateAndEagerlyBailout(fiber, queue, update, lane) {
3533 var interleaved = queue.interleaved;
3534
3535 if (interleaved === null) {
3536 // This is the first update. Create a circular list.
3537 update.next = update; // At the end of the current render, this queue's interleaved updates will
3538 // be transferred to the pending queue.
3539
3540 pushConcurrentUpdateQueue(queue);
3541 } else {
3542 update.next = interleaved.next;
3543 interleaved.next = update;
3544 }
3545
3546 queue.interleaved = update;
3547}
3548function enqueueConcurrentClassUpdate(fiber, queue, update, lane) {
3549 var interleaved = queue.interleaved;
3550
3551 if (interleaved === null) {
3552 // This is the first update. Create a circular list.
3553 update.next = update; // At the end of the current render, this queue's interleaved updates will
3554 // be transferred to the pending queue.
3555
3556 pushConcurrentUpdateQueue(queue);
3557 } else {
3558 update.next = interleaved.next;
3559 interleaved.next = update;
3560 }
3561
3562 queue.interleaved = update;
3563 return markUpdateLaneFromFiberToRoot(fiber, lane);
3564}
3565function enqueueConcurrentRenderForLane(fiber, lane) {
3566 return markUpdateLaneFromFiberToRoot(fiber, lane);
3567} // Calling this function outside this module should only be done for backwards
3568// compatibility and should always be accompanied by a warning.
3569
3570var unsafe_markUpdateLaneFromFiberToRoot = markUpdateLaneFromFiberToRoot;
3571
3572function markUpdateLaneFromFiberToRoot(sourceFiber, lane) {
3573 // Update the source fiber's lanes
3574 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, lane);
3575 var alternate = sourceFiber.alternate;
3576
3577 if (alternate !== null) {
3578 alternate.lanes = mergeLanes(alternate.lanes, lane);
3579 }
3580
3581 {
3582 if (alternate === null && (sourceFiber.flags & (Placement | Hydrating)) !== NoFlags) {
3583 warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);
3584 }
3585 } // Walk the parent path to the root and update the child lanes.
3586
3587
3588 var node = sourceFiber;
3589 var parent = sourceFiber.return;
3590
3591 while (parent !== null) {
3592 parent.childLanes = mergeLanes(parent.childLanes, lane);
3593 alternate = parent.alternate;
3594
3595 if (alternate !== null) {
3596 alternate.childLanes = mergeLanes(alternate.childLanes, lane);
3597 } else {
3598 {
3599 if ((parent.flags & (Placement | Hydrating)) !== NoFlags) {
3600 warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);
3601 }
3602 }
3603 }
3604
3605 node = parent;
3606 parent = parent.return;
3607 }
3608
3609 if (node.tag === HostRoot) {
3610 var root = node.stateNode;
3611 return root;
3612 } else {
3613 return null;
3614 }
3615}
3616
3617var UpdateState = 0;
3618var ReplaceState = 1;
3619var ForceUpdate = 2;
3620var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
3621// It should only be read right after calling `processUpdateQueue`, via
3622// `checkHasForceUpdateAfterProcessing`.
3623
3624var hasForceUpdate = false;
3625var didWarnUpdateInsideUpdate;
3626var currentlyProcessingQueue;
3627
3628{
3629 didWarnUpdateInsideUpdate = false;
3630 currentlyProcessingQueue = null;
3631}
3632
3633function initializeUpdateQueue(fiber) {
3634 var queue = {
3635 baseState: fiber.memoizedState,
3636 firstBaseUpdate: null,
3637 lastBaseUpdate: null,
3638 shared: {
3639 pending: null,
3640 interleaved: null,
3641 lanes: NoLanes
3642 },
3643 effects: null
3644 };
3645 fiber.updateQueue = queue;
3646}
3647function cloneUpdateQueue(current, workInProgress) {
3648 // Clone the update queue from current. Unless it's already a clone.
3649 var queue = workInProgress.updateQueue;
3650 var currentQueue = current.updateQueue;
3651
3652 if (queue === currentQueue) {
3653 var clone = {
3654 baseState: currentQueue.baseState,
3655 firstBaseUpdate: currentQueue.firstBaseUpdate,
3656 lastBaseUpdate: currentQueue.lastBaseUpdate,
3657 shared: currentQueue.shared,
3658 effects: currentQueue.effects
3659 };
3660 workInProgress.updateQueue = clone;
3661 }
3662}
3663function createUpdate(eventTime, lane) {
3664 var update = {
3665 eventTime: eventTime,
3666 lane: lane,
3667 tag: UpdateState,
3668 payload: null,
3669 callback: null,
3670 next: null
3671 };
3672 return update;
3673}
3674function enqueueUpdate(fiber, update, lane) {
3675 var updateQueue = fiber.updateQueue;
3676
3677 if (updateQueue === null) {
3678 // Only occurs if the fiber has been unmounted.
3679 return null;
3680 }
3681
3682 var sharedQueue = updateQueue.shared;
3683
3684 {
3685 if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) {
3686 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.');
3687
3688 didWarnUpdateInsideUpdate = true;
3689 }
3690 }
3691
3692 if (isUnsafeClassRenderPhaseUpdate()) {
3693 // This is an unsafe render phase update. Add directly to the update
3694 // queue so we can process it immediately during the current render.
3695 var pending = sharedQueue.pending;
3696
3697 if (pending === null) {
3698 // This is the first update. Create a circular list.
3699 update.next = update;
3700 } else {
3701 update.next = pending.next;
3702 pending.next = update;
3703 }
3704
3705 sharedQueue.pending = update; // Update the childLanes even though we're most likely already rendering
3706 // this fiber. This is for backwards compatibility in the case where you
3707 // update a different component during render phase than the one that is
3708 // currently renderings (a pattern that is accompanied by a warning).
3709
3710 return unsafe_markUpdateLaneFromFiberToRoot(fiber, lane);
3711 } else {
3712 return enqueueConcurrentClassUpdate(fiber, sharedQueue, update, lane);
3713 }
3714}
3715function entangleTransitions(root, fiber, lane) {
3716 var updateQueue = fiber.updateQueue;
3717
3718 if (updateQueue === null) {
3719 // Only occurs if the fiber has been unmounted.
3720 return;
3721 }
3722
3723 var sharedQueue = updateQueue.shared;
3724
3725 if (isTransitionLane(lane)) {
3726 var queueLanes = sharedQueue.lanes; // If any entangled lanes are no longer pending on the root, then they must
3727 // have finished. We can remove them from the shared queue, which represents
3728 // a superset of the actually pending lanes. In some cases we may entangle
3729 // more than we need to, but that's OK. In fact it's worse if we *don't*
3730 // entangle when we should.
3731
3732 queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes.
3733
3734 var newQueueLanes = mergeLanes(queueLanes, lane);
3735 sharedQueue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if
3736 // the lane finished since the last time we entangled it. So we need to
3737 // entangle it again, just to be sure.
3738
3739 markRootEntangled(root, newQueueLanes);
3740 }
3741}
3742function enqueueCapturedUpdate(workInProgress, capturedUpdate) {
3743 // Captured updates are updates that are thrown by a child during the render
3744 // phase. They should be discarded if the render is aborted. Therefore,
3745 // we should only put them on the work-in-progress queue, not the current one.
3746 var queue = workInProgress.updateQueue; // Check if the work-in-progress queue is a clone.
3747
3748 var current = workInProgress.alternate;
3749
3750 if (current !== null) {
3751 var currentQueue = current.updateQueue;
3752
3753 if (queue === currentQueue) {
3754 // The work-in-progress queue is the same as current. This happens when
3755 // we bail out on a parent fiber that then captures an error thrown by
3756 // a child. Since we want to append the update only to the work-in
3757 // -progress queue, we need to clone the updates. We usually clone during
3758 // processUpdateQueue, but that didn't happen in this case because we
3759 // skipped over the parent when we bailed out.
3760 var newFirst = null;
3761 var newLast = null;
3762 var firstBaseUpdate = queue.firstBaseUpdate;
3763
3764 if (firstBaseUpdate !== null) {
3765 // Loop through the updates and clone them.
3766 var update = firstBaseUpdate;
3767
3768 do {
3769 var clone = {
3770 eventTime: update.eventTime,
3771 lane: update.lane,
3772 tag: update.tag,
3773 payload: update.payload,
3774 callback: update.callback,
3775 next: null
3776 };
3777
3778 if (newLast === null) {
3779 newFirst = newLast = clone;
3780 } else {
3781 newLast.next = clone;
3782 newLast = clone;
3783 }
3784
3785 update = update.next;
3786 } while (update !== null); // Append the captured update the end of the cloned list.
3787
3788
3789 if (newLast === null) {
3790 newFirst = newLast = capturedUpdate;
3791 } else {
3792 newLast.next = capturedUpdate;
3793 newLast = capturedUpdate;
3794 }
3795 } else {
3796 // There are no base updates.
3797 newFirst = newLast = capturedUpdate;
3798 }
3799
3800 queue = {
3801 baseState: currentQueue.baseState,
3802 firstBaseUpdate: newFirst,
3803 lastBaseUpdate: newLast,
3804 shared: currentQueue.shared,
3805 effects: currentQueue.effects
3806 };
3807 workInProgress.updateQueue = queue;
3808 return;
3809 }
3810 } // Append the update to the end of the list.
3811
3812
3813 var lastBaseUpdate = queue.lastBaseUpdate;
3814
3815 if (lastBaseUpdate === null) {
3816 queue.firstBaseUpdate = capturedUpdate;
3817 } else {
3818 lastBaseUpdate.next = capturedUpdate;
3819 }
3820
3821 queue.lastBaseUpdate = capturedUpdate;
3822}
3823
3824function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
3825 switch (update.tag) {
3826 case ReplaceState:
3827 {
3828 var payload = update.payload;
3829
3830 if (typeof payload === 'function') {
3831 // Updater function
3832 {
3833 enterDisallowedContextReadInDEV();
3834 }
3835
3836 var nextState = payload.call(instance, prevState, nextProps);
3837
3838 {
3839
3840 exitDisallowedContextReadInDEV();
3841 }
3842
3843 return nextState;
3844 } // State object
3845
3846
3847 return payload;
3848 }
3849
3850 case CaptureUpdate:
3851 {
3852 workInProgress.flags = workInProgress.flags & ~ShouldCapture | DidCapture;
3853 }
3854 // Intentional fallthrough
3855
3856 case UpdateState:
3857 {
3858 var _payload = update.payload;
3859 var partialState;
3860
3861 if (typeof _payload === 'function') {
3862 // Updater function
3863 {
3864 enterDisallowedContextReadInDEV();
3865 }
3866
3867 partialState = _payload.call(instance, prevState, nextProps);
3868
3869 {
3870
3871 exitDisallowedContextReadInDEV();
3872 }
3873 } else {
3874 // Partial state object
3875 partialState = _payload;
3876 }
3877
3878 if (partialState === null || partialState === undefined) {
3879 // Null and undefined are treated as no-ops.
3880 return prevState;
3881 } // Merge the partial state and the previous state.
3882
3883
3884 return assign({}, prevState, partialState);
3885 }
3886
3887 case ForceUpdate:
3888 {
3889 hasForceUpdate = true;
3890 return prevState;
3891 }
3892 }
3893
3894 return prevState;
3895}
3896
3897function processUpdateQueue(workInProgress, props, instance, renderLanes) {
3898 // This is always non-null on a ClassComponent or HostRoot
3899 var queue = workInProgress.updateQueue;
3900 hasForceUpdate = false;
3901
3902 {
3903 currentlyProcessingQueue = queue.shared;
3904 }
3905
3906 var firstBaseUpdate = queue.firstBaseUpdate;
3907 var lastBaseUpdate = queue.lastBaseUpdate; // Check if there are pending updates. If so, transfer them to the base queue.
3908
3909 var pendingQueue = queue.shared.pending;
3910
3911 if (pendingQueue !== null) {
3912 queue.shared.pending = null; // The pending queue is circular. Disconnect the pointer between first
3913 // and last so that it's non-circular.
3914
3915 var lastPendingUpdate = pendingQueue;
3916 var firstPendingUpdate = lastPendingUpdate.next;
3917 lastPendingUpdate.next = null; // Append pending updates to base queue
3918
3919 if (lastBaseUpdate === null) {
3920 firstBaseUpdate = firstPendingUpdate;
3921 } else {
3922 lastBaseUpdate.next = firstPendingUpdate;
3923 }
3924
3925 lastBaseUpdate = lastPendingUpdate; // If there's a current queue, and it's different from the base queue, then
3926 // we need to transfer the updates to that queue, too. Because the base
3927 // queue is a singly-linked list with no cycles, we can append to both
3928 // lists and take advantage of structural sharing.
3929 // TODO: Pass `current` as argument
3930
3931 var current = workInProgress.alternate;
3932
3933 if (current !== null) {
3934 // This is always non-null on a ClassComponent or HostRoot
3935 var currentQueue = current.updateQueue;
3936 var currentLastBaseUpdate = currentQueue.lastBaseUpdate;
3937
3938 if (currentLastBaseUpdate !== lastBaseUpdate) {
3939 if (currentLastBaseUpdate === null) {
3940 currentQueue.firstBaseUpdate = firstPendingUpdate;
3941 } else {
3942 currentLastBaseUpdate.next = firstPendingUpdate;
3943 }
3944
3945 currentQueue.lastBaseUpdate = lastPendingUpdate;
3946 }
3947 }
3948 } // These values may change as we process the queue.
3949
3950
3951 if (firstBaseUpdate !== null) {
3952 // Iterate through the list of updates to compute the result.
3953 var newState = queue.baseState; // TODO: Don't need to accumulate this. Instead, we can remove renderLanes
3954 // from the original lanes.
3955
3956 var newLanes = NoLanes;
3957 var newBaseState = null;
3958 var newFirstBaseUpdate = null;
3959 var newLastBaseUpdate = null;
3960 var update = firstBaseUpdate;
3961
3962 do {
3963 var updateLane = update.lane;
3964 var updateEventTime = update.eventTime;
3965
3966 if (!isSubsetOfLanes(renderLanes, updateLane)) {
3967 // Priority is insufficient. Skip this update. If this is the first
3968 // skipped update, the previous update/state is the new base
3969 // update/state.
3970 var clone = {
3971 eventTime: updateEventTime,
3972 lane: updateLane,
3973 tag: update.tag,
3974 payload: update.payload,
3975 callback: update.callback,
3976 next: null
3977 };
3978
3979 if (newLastBaseUpdate === null) {
3980 newFirstBaseUpdate = newLastBaseUpdate = clone;
3981 newBaseState = newState;
3982 } else {
3983 newLastBaseUpdate = newLastBaseUpdate.next = clone;
3984 } // Update the remaining priority in the queue.
3985
3986
3987 newLanes = mergeLanes(newLanes, updateLane);
3988 } else {
3989 // This update does have sufficient priority.
3990 if (newLastBaseUpdate !== null) {
3991 var _clone = {
3992 eventTime: updateEventTime,
3993 // This update is going to be committed so we never want uncommit
3994 // it. Using NoLane works because 0 is a subset of all bitmasks, so
3995 // this will never be skipped by the check above.
3996 lane: NoLane,
3997 tag: update.tag,
3998 payload: update.payload,
3999 callback: update.callback,
4000 next: null
4001 };
4002 newLastBaseUpdate = newLastBaseUpdate.next = _clone;
4003 } // Process this update.
4004
4005
4006 newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance);
4007 var callback = update.callback;
4008
4009 if (callback !== null && // If the update was already committed, we should not queue its
4010 // callback again.
4011 update.lane !== NoLane) {
4012 workInProgress.flags |= Callback;
4013 var effects = queue.effects;
4014
4015 if (effects === null) {
4016 queue.effects = [update];
4017 } else {
4018 effects.push(update);
4019 }
4020 }
4021 }
4022
4023 update = update.next;
4024
4025 if (update === null) {
4026 pendingQueue = queue.shared.pending;
4027
4028 if (pendingQueue === null) {
4029 break;
4030 } else {
4031 // An update was scheduled from inside a reducer. Add the new
4032 // pending updates to the end of the list and keep processing.
4033 var _lastPendingUpdate = pendingQueue; // Intentionally unsound. Pending updates form a circular list, but we
4034 // unravel them when transferring them to the base queue.
4035
4036 var _firstPendingUpdate = _lastPendingUpdate.next;
4037 _lastPendingUpdate.next = null;
4038 update = _firstPendingUpdate;
4039 queue.lastBaseUpdate = _lastPendingUpdate;
4040 queue.shared.pending = null;
4041 }
4042 }
4043 } while (true);
4044
4045 if (newLastBaseUpdate === null) {
4046 newBaseState = newState;
4047 }
4048
4049 queue.baseState = newBaseState;
4050 queue.firstBaseUpdate = newFirstBaseUpdate;
4051 queue.lastBaseUpdate = newLastBaseUpdate; // Interleaved updates are stored on a separate queue. We aren't going to
4052 // process them during this render, but we do need to track which lanes
4053 // are remaining.
4054
4055 var lastInterleaved = queue.shared.interleaved;
4056
4057 if (lastInterleaved !== null) {
4058 var interleaved = lastInterleaved;
4059
4060 do {
4061 newLanes = mergeLanes(newLanes, interleaved.lane);
4062 interleaved = interleaved.next;
4063 } while (interleaved !== lastInterleaved);
4064 } else if (firstBaseUpdate === null) {
4065 // `queue.lanes` is used for entangling transitions. We can set it back to
4066 // zero once the queue is empty.
4067 queue.shared.lanes = NoLanes;
4068 } // Set the remaining expiration time to be whatever is remaining in the queue.
4069 // This should be fine because the only two other things that contribute to
4070 // expiration time are props and context. We're already in the middle of the
4071 // begin phase by the time we start processing the queue, so we've already
4072 // dealt with the props. Context in components that specify
4073 // shouldComponentUpdate is tricky; but we'll have to account for
4074 // that regardless.
4075
4076
4077 markSkippedUpdateLanes(newLanes);
4078 workInProgress.lanes = newLanes;
4079 workInProgress.memoizedState = newState;
4080 }
4081
4082 {
4083 currentlyProcessingQueue = null;
4084 }
4085}
4086
4087function callCallback(callback, context) {
4088 if (typeof callback !== 'function') {
4089 throw new Error('Invalid argument passed as callback. Expected a function. Instead ' + ("received: " + callback));
4090 }
4091
4092 callback.call(context);
4093}
4094
4095function resetHasForceUpdateBeforeProcessing() {
4096 hasForceUpdate = false;
4097}
4098function checkHasForceUpdateAfterProcessing() {
4099 return hasForceUpdate;
4100}
4101function commitUpdateQueue(finishedWork, finishedQueue, instance) {
4102 // Commit the effects
4103 var effects = finishedQueue.effects;
4104 finishedQueue.effects = null;
4105
4106 if (effects !== null) {
4107 for (var i = 0; i < effects.length; i++) {
4108 var effect = effects[i];
4109 var callback = effect.callback;
4110
4111 if (callback !== null) {
4112 effect.callback = null;
4113 callCallback(callback, instance);
4114 }
4115 }
4116 }
4117}
4118
4119var fakeInternalInstance = {}; // React.Component uses a shared frozen object by default.
4120// We'll use it to determine whether we need to initialize legacy refs.
4121
4122var emptyRefsObject = new React.Component().refs;
4123var didWarnAboutStateAssignmentForComponent;
4124var didWarnAboutUninitializedState;
4125var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
4126var didWarnAboutLegacyLifecyclesAndDerivedState;
4127var didWarnAboutUndefinedDerivedState;
4128var warnOnUndefinedDerivedState;
4129var warnOnInvalidCallback;
4130var didWarnAboutDirectlyAssigningPropsToState;
4131var didWarnAboutContextTypeAndContextTypes;
4132var didWarnAboutInvalidateContextType;
4133
4134{
4135 didWarnAboutStateAssignmentForComponent = new Set();
4136 didWarnAboutUninitializedState = new Set();
4137 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
4138 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
4139 didWarnAboutDirectlyAssigningPropsToState = new Set();
4140 didWarnAboutUndefinedDerivedState = new Set();
4141 didWarnAboutContextTypeAndContextTypes = new Set();
4142 didWarnAboutInvalidateContextType = new Set();
4143 var didWarnOnInvalidCallback = new Set();
4144
4145 warnOnInvalidCallback = function (callback, callerName) {
4146 if (callback === null || typeof callback === 'function') {
4147 return;
4148 }
4149
4150 var key = callerName + '_' + callback;
4151
4152 if (!didWarnOnInvalidCallback.has(key)) {
4153 didWarnOnInvalidCallback.add(key);
4154
4155 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
4156 }
4157 };
4158
4159 warnOnUndefinedDerivedState = function (type, partialState) {
4160 if (partialState === undefined) {
4161 var componentName = getComponentNameFromType(type) || 'Component';
4162
4163 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
4164 didWarnAboutUndefinedDerivedState.add(componentName);
4165
4166 error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
4167 }
4168 }
4169 }; // This is so gross but it's at least non-critical and can be removed if
4170 // it causes problems. This is meant to give a nicer error message for
4171 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
4172 // ...)) which otherwise throws a "_processChildContext is not a function"
4173 // exception.
4174
4175
4176 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
4177 enumerable: false,
4178 value: function () {
4179 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).');
4180 }
4181 });
4182 Object.freeze(fakeInternalInstance);
4183}
4184
4185function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
4186 var prevState = workInProgress.memoizedState;
4187 var partialState = getDerivedStateFromProps(nextProps, prevState);
4188
4189 {
4190
4191 warnOnUndefinedDerivedState(ctor, partialState);
4192 } // Merge the partial state and the previous state.
4193
4194
4195 var memoizedState = partialState === null || partialState === undefined ? prevState : assign({}, prevState, partialState);
4196 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
4197 // base state.
4198
4199 if (workInProgress.lanes === NoLanes) {
4200 // Queue is always non-null for classes
4201 var updateQueue = workInProgress.updateQueue;
4202 updateQueue.baseState = memoizedState;
4203 }
4204}
4205
4206var classComponentUpdater = {
4207 isMounted: isMounted,
4208 enqueueSetState: function (inst, payload, callback) {
4209 var fiber = get(inst);
4210 var eventTime = requestEventTime();
4211 var lane = requestUpdateLane(fiber);
4212 var update = createUpdate(eventTime, lane);
4213 update.payload = payload;
4214
4215 if (callback !== undefined && callback !== null) {
4216 {
4217 warnOnInvalidCallback(callback, 'setState');
4218 }
4219
4220 update.callback = callback;
4221 }
4222
4223 var root = enqueueUpdate(fiber, update, lane);
4224
4225 if (root !== null) {
4226 scheduleUpdateOnFiber(root, fiber, lane, eventTime);
4227 entangleTransitions(root, fiber, lane);
4228 }
4229 },
4230 enqueueReplaceState: function (inst, payload, callback) {
4231 var fiber = get(inst);
4232 var eventTime = requestEventTime();
4233 var lane = requestUpdateLane(fiber);
4234 var update = createUpdate(eventTime, lane);
4235 update.tag = ReplaceState;
4236 update.payload = payload;
4237
4238 if (callback !== undefined && callback !== null) {
4239 {
4240 warnOnInvalidCallback(callback, 'replaceState');
4241 }
4242
4243 update.callback = callback;
4244 }
4245
4246 var root = enqueueUpdate(fiber, update, lane);
4247
4248 if (root !== null) {
4249 scheduleUpdateOnFiber(root, fiber, lane, eventTime);
4250 entangleTransitions(root, fiber, lane);
4251 }
4252 },
4253 enqueueForceUpdate: function (inst, callback) {
4254 var fiber = get(inst);
4255 var eventTime = requestEventTime();
4256 var lane = requestUpdateLane(fiber);
4257 var update = createUpdate(eventTime, lane);
4258 update.tag = ForceUpdate;
4259
4260 if (callback !== undefined && callback !== null) {
4261 {
4262 warnOnInvalidCallback(callback, 'forceUpdate');
4263 }
4264
4265 update.callback = callback;
4266 }
4267
4268 var root = enqueueUpdate(fiber, update, lane);
4269
4270 if (root !== null) {
4271 scheduleUpdateOnFiber(root, fiber, lane, eventTime);
4272 entangleTransitions(root, fiber, lane);
4273 }
4274 }
4275};
4276
4277function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
4278 var instance = workInProgress.stateNode;
4279
4280 if (typeof instance.shouldComponentUpdate === 'function') {
4281 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
4282
4283 {
4284
4285 if (shouldUpdate === undefined) {
4286 error('%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentNameFromType(ctor) || 'Component');
4287 }
4288 }
4289
4290 return shouldUpdate;
4291 }
4292
4293 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
4294 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
4295 }
4296
4297 return true;
4298}
4299
4300function checkClassInstance(workInProgress, ctor, newProps) {
4301 var instance = workInProgress.stateNode;
4302
4303 {
4304 var name = getComponentNameFromType(ctor) || 'Component';
4305 var renderPresent = instance.render;
4306
4307 if (!renderPresent) {
4308 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
4309 error('%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
4310 } else {
4311 error('%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
4312 }
4313 }
4314
4315 if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) {
4316 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);
4317 }
4318
4319 if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) {
4320 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);
4321 }
4322
4323 if (instance.propTypes) {
4324 error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
4325 }
4326
4327 if (instance.contextType) {
4328 error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name);
4329 }
4330
4331 {
4332 if (instance.contextTypes) {
4333 error('contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
4334 }
4335
4336 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
4337 didWarnAboutContextTypeAndContextTypes.add(ctor);
4338
4339 error('%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
4340 }
4341 }
4342
4343 if (typeof instance.componentShouldUpdate === 'function') {
4344 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);
4345 }
4346
4347 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
4348 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');
4349 }
4350
4351 if (typeof instance.componentDidUnmount === 'function') {
4352 error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
4353 }
4354
4355 if (typeof instance.componentDidReceiveProps === 'function') {
4356 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);
4357 }
4358
4359 if (typeof instance.componentWillRecieveProps === 'function') {
4360 error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
4361 }
4362
4363 if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') {
4364 error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);
4365 }
4366
4367 var hasMutatedProps = instance.props !== newProps;
4368
4369 if (instance.props !== undefined && hasMutatedProps) {
4370 error('%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name);
4371 }
4372
4373 if (instance.defaultProps) {
4374 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);
4375 }
4376
4377 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
4378 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
4379
4380 error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentNameFromType(ctor));
4381 }
4382
4383 if (typeof instance.getDerivedStateFromProps === 'function') {
4384 error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
4385 }
4386
4387 if (typeof instance.getDerivedStateFromError === 'function') {
4388 error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
4389 }
4390
4391 if (typeof ctor.getSnapshotBeforeUpdate === 'function') {
4392 error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name);
4393 }
4394
4395 var _state = instance.state;
4396
4397 if (_state && (typeof _state !== 'object' || isArray(_state))) {
4398 error('%s.state: must be set to an object or null', name);
4399 }
4400
4401 if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') {
4402 error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name);
4403 }
4404 }
4405}
4406
4407function adoptClassInstance(workInProgress, instance) {
4408 instance.updater = classComponentUpdater;
4409 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
4410
4411 set(instance, workInProgress);
4412
4413 {
4414 instance._reactInternalInstance = fakeInternalInstance;
4415 }
4416}
4417
4418function constructClassInstance(workInProgress, ctor, props) {
4419 var isLegacyContextConsumer = false;
4420 var unmaskedContext = emptyContextObject;
4421 var context = emptyContextObject;
4422 var contextType = ctor.contextType;
4423
4424 {
4425 if ('contextType' in ctor) {
4426 var isValid = // Allow null for conditional declaration
4427 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
4428
4429 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
4430 didWarnAboutInvalidateContextType.add(ctor);
4431 var addendum = '';
4432
4433 if (contextType === undefined) {
4434 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.';
4435 } else if (typeof contextType !== 'object') {
4436 addendum = ' However, it is set to a ' + typeof contextType + '.';
4437 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
4438 addendum = ' Did you accidentally pass the Context.Provider instead?';
4439 } else if (contextType._context !== undefined) {
4440 // <Context.Consumer>
4441 addendum = ' Did you accidentally pass the Context.Consumer instead?';
4442 } else {
4443 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
4444 }
4445
4446 error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentNameFromType(ctor) || 'Component', addendum);
4447 }
4448 }
4449 }
4450
4451 if (typeof contextType === 'object' && contextType !== null) {
4452 context = readContext(contextType);
4453 } else {
4454 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4455 var contextTypes = ctor.contextTypes;
4456 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
4457 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
4458 }
4459
4460 var instance = new ctor(props, context); // Instantiate twice to help detect side-effects.
4461
4462 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
4463 adoptClassInstance(workInProgress, instance);
4464
4465 {
4466 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
4467 var componentName = getComponentNameFromType(ctor) || 'Component';
4468
4469 if (!didWarnAboutUninitializedState.has(componentName)) {
4470 didWarnAboutUninitializedState.add(componentName);
4471
4472 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);
4473 }
4474 } // If new component APIs are defined, "unsafe" lifecycles won't be called.
4475 // Warn about these lifecycles if they are present.
4476 // Don't warn about react-lifecycles-compat polyfilled methods though.
4477
4478
4479 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
4480 var foundWillMountName = null;
4481 var foundWillReceivePropsName = null;
4482 var foundWillUpdateName = null;
4483
4484 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
4485 foundWillMountName = 'componentWillMount';
4486 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
4487 foundWillMountName = 'UNSAFE_componentWillMount';
4488 }
4489
4490 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
4491 foundWillReceivePropsName = 'componentWillReceiveProps';
4492 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4493 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
4494 }
4495
4496 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
4497 foundWillUpdateName = 'componentWillUpdate';
4498 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4499 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
4500 }
4501
4502 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
4503 var _componentName = getComponentNameFromType(ctor) || 'Component';
4504
4505 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
4506
4507 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
4508 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
4509
4510 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 : '');
4511 }
4512 }
4513 }
4514 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
4515 // ReactFiberContext usually updates this cache but can't for newly-created instances.
4516
4517
4518 if (isLegacyContextConsumer) {
4519 cacheContext(workInProgress, unmaskedContext, context);
4520 }
4521
4522 return instance;
4523}
4524
4525function callComponentWillMount(workInProgress, instance) {
4526 var oldState = instance.state;
4527
4528 if (typeof instance.componentWillMount === 'function') {
4529 instance.componentWillMount();
4530 }
4531
4532 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4533 instance.UNSAFE_componentWillMount();
4534 }
4535
4536 if (oldState !== instance.state) {
4537 {
4538 error('%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentNameFromFiber(workInProgress) || 'Component');
4539 }
4540
4541 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4542 }
4543}
4544
4545function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
4546 var oldState = instance.state;
4547
4548 if (typeof instance.componentWillReceiveProps === 'function') {
4549 instance.componentWillReceiveProps(newProps, nextContext);
4550 }
4551
4552 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4553 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
4554 }
4555
4556 if (instance.state !== oldState) {
4557 {
4558 var componentName = getComponentNameFromFiber(workInProgress) || 'Component';
4559
4560 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
4561 didWarnAboutStateAssignmentForComponent.add(componentName);
4562
4563 error('%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
4564 }
4565 }
4566
4567 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4568 }
4569} // Invokes the mount life-cycles on a previously never rendered instance.
4570
4571
4572function mountClassInstance(workInProgress, ctor, newProps, renderLanes) {
4573 {
4574 checkClassInstance(workInProgress, ctor, newProps);
4575 }
4576
4577 var instance = workInProgress.stateNode;
4578 instance.props = newProps;
4579 instance.state = workInProgress.memoizedState;
4580 instance.refs = emptyRefsObject;
4581 initializeUpdateQueue(workInProgress);
4582 var contextType = ctor.contextType;
4583
4584 if (typeof contextType === 'object' && contextType !== null) {
4585 instance.context = readContext(contextType);
4586 } else {
4587 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4588 instance.context = getMaskedContext(workInProgress, unmaskedContext);
4589 }
4590
4591 {
4592 if (instance.state === newProps) {
4593 var componentName = getComponentNameFromType(ctor) || 'Component';
4594
4595 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
4596 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
4597
4598 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);
4599 }
4600 }
4601
4602 if (workInProgress.mode & StrictLegacyMode) {
4603 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
4604 }
4605
4606 {
4607 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
4608 }
4609 }
4610
4611 instance.state = workInProgress.memoizedState;
4612 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4613
4614 if (typeof getDerivedStateFromProps === 'function') {
4615 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4616 instance.state = workInProgress.memoizedState;
4617 } // In order to support react-lifecycles-compat polyfilled components,
4618 // Unsafe lifecycles should not be invoked for components using the new APIs.
4619
4620
4621 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4622 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
4623 // process them now.
4624
4625 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
4626 instance.state = workInProgress.memoizedState;
4627 }
4628
4629 if (typeof instance.componentDidMount === 'function') {
4630 var fiberFlags = Update;
4631
4632 workInProgress.flags |= fiberFlags;
4633 }
4634}
4635
4636function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) {
4637 var instance = workInProgress.stateNode;
4638 var oldProps = workInProgress.memoizedProps;
4639 instance.props = oldProps;
4640 var oldContext = instance.context;
4641 var contextType = ctor.contextType;
4642 var nextContext = emptyContextObject;
4643
4644 if (typeof contextType === 'object' && contextType !== null) {
4645 nextContext = readContext(contextType);
4646 } else {
4647 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4648 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
4649 }
4650
4651 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4652 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
4653 // ever the previously attempted to render - not the "current". However,
4654 // during componentDidUpdate we pass the "current" props.
4655 // In order to support react-lifecycles-compat polyfilled components,
4656 // Unsafe lifecycles should not be invoked for components using the new APIs.
4657
4658 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4659 if (oldProps !== newProps || oldContext !== nextContext) {
4660 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4661 }
4662 }
4663
4664 resetHasForceUpdateBeforeProcessing();
4665 var oldState = workInProgress.memoizedState;
4666 var newState = instance.state = oldState;
4667 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
4668 newState = workInProgress.memoizedState;
4669
4670 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4671 // If an update was already in progress, we should schedule an Update
4672 // effect even though we're bailing out, so that cWU/cDU are called.
4673 if (typeof instance.componentDidMount === 'function') {
4674 var fiberFlags = Update;
4675
4676 workInProgress.flags |= fiberFlags;
4677 }
4678
4679 return false;
4680 }
4681
4682 if (typeof getDerivedStateFromProps === 'function') {
4683 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4684 newState = workInProgress.memoizedState;
4685 }
4686
4687 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4688
4689 if (shouldUpdate) {
4690 // In order to support react-lifecycles-compat polyfilled components,
4691 // Unsafe lifecycles should not be invoked for components using the new APIs.
4692 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4693 if (typeof instance.componentWillMount === 'function') {
4694 instance.componentWillMount();
4695 }
4696
4697 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4698 instance.UNSAFE_componentWillMount();
4699 }
4700 }
4701
4702 if (typeof instance.componentDidMount === 'function') {
4703 var _fiberFlags = Update;
4704
4705 workInProgress.flags |= _fiberFlags;
4706 }
4707 } else {
4708 // If an update was already in progress, we should schedule an Update
4709 // effect even though we're bailing out, so that cWU/cDU are called.
4710 if (typeof instance.componentDidMount === 'function') {
4711 var _fiberFlags2 = Update;
4712
4713 workInProgress.flags |= _fiberFlags2;
4714 } // If shouldComponentUpdate returned false, we should still update the
4715 // memoized state to indicate that this work can be reused.
4716
4717
4718 workInProgress.memoizedProps = newProps;
4719 workInProgress.memoizedState = newState;
4720 } // Update the existing instance's state, props, and context pointers even
4721 // if shouldComponentUpdate returns false.
4722
4723
4724 instance.props = newProps;
4725 instance.state = newState;
4726 instance.context = nextContext;
4727 return shouldUpdate;
4728} // Invokes the update life-cycles and returns false if it shouldn't rerender.
4729
4730
4731function updateClassInstance(current, workInProgress, ctor, newProps, renderLanes) {
4732 var instance = workInProgress.stateNode;
4733 cloneUpdateQueue(current, workInProgress);
4734 var unresolvedOldProps = workInProgress.memoizedProps;
4735 var oldProps = workInProgress.type === workInProgress.elementType ? unresolvedOldProps : resolveDefaultProps(workInProgress.type, unresolvedOldProps);
4736 instance.props = oldProps;
4737 var unresolvedNewProps = workInProgress.pendingProps;
4738 var oldContext = instance.context;
4739 var contextType = ctor.contextType;
4740 var nextContext = emptyContextObject;
4741
4742 if (typeof contextType === 'object' && contextType !== null) {
4743 nextContext = readContext(contextType);
4744 } else {
4745 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4746 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
4747 }
4748
4749 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4750 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
4751 // ever the previously attempted to render - not the "current". However,
4752 // during componentDidUpdate we pass the "current" props.
4753 // In order to support react-lifecycles-compat polyfilled components,
4754 // Unsafe lifecycles should not be invoked for components using the new APIs.
4755
4756 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4757 if (unresolvedOldProps !== unresolvedNewProps || oldContext !== nextContext) {
4758 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4759 }
4760 }
4761
4762 resetHasForceUpdateBeforeProcessing();
4763 var oldState = workInProgress.memoizedState;
4764 var newState = instance.state = oldState;
4765 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
4766 newState = workInProgress.memoizedState;
4767
4768 if (unresolvedOldProps === unresolvedNewProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing() && !(enableLazyContextPropagation )) {
4769 // If an update was already in progress, we should schedule an Update
4770 // effect even though we're bailing out, so that cWU/cDU are called.
4771 if (typeof instance.componentDidUpdate === 'function') {
4772 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4773 workInProgress.flags |= Update;
4774 }
4775 }
4776
4777 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4778 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4779 workInProgress.flags |= Snapshot;
4780 }
4781 }
4782
4783 return false;
4784 }
4785
4786 if (typeof getDerivedStateFromProps === 'function') {
4787 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4788 newState = workInProgress.memoizedState;
4789 }
4790
4791 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,
4792 // both before and after `shouldComponentUpdate` has been called. Not ideal,
4793 // but I'm loath to refactor this function. This only happens for memoized
4794 // components so it's not that common.
4795 enableLazyContextPropagation ;
4796
4797 if (shouldUpdate) {
4798 // In order to support react-lifecycles-compat polyfilled components,
4799 // Unsafe lifecycles should not be invoked for components using the new APIs.
4800 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
4801 if (typeof instance.componentWillUpdate === 'function') {
4802 instance.componentWillUpdate(newProps, newState, nextContext);
4803 }
4804
4805 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4806 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
4807 }
4808 }
4809
4810 if (typeof instance.componentDidUpdate === 'function') {
4811 workInProgress.flags |= Update;
4812 }
4813
4814 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4815 workInProgress.flags |= Snapshot;
4816 }
4817 } else {
4818 // If an update was already in progress, we should schedule an Update
4819 // effect even though we're bailing out, so that cWU/cDU are called.
4820 if (typeof instance.componentDidUpdate === 'function') {
4821 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4822 workInProgress.flags |= Update;
4823 }
4824 }
4825
4826 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4827 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4828 workInProgress.flags |= Snapshot;
4829 }
4830 } // If shouldComponentUpdate returned false, we should still update the
4831 // memoized props/state to indicate that this work can be reused.
4832
4833
4834 workInProgress.memoizedProps = newProps;
4835 workInProgress.memoizedState = newState;
4836 } // Update the existing instance's state, props, and context pointers even
4837 // if shouldComponentUpdate returns false.
4838
4839
4840 instance.props = newProps;
4841 instance.state = newState;
4842 instance.context = nextContext;
4843 return shouldUpdate;
4844}
4845
4846var didWarnAboutMaps;
4847var didWarnAboutGenerators;
4848var didWarnAboutStringRefs;
4849var ownerHasKeyUseWarning;
4850var ownerHasFunctionTypeWarning;
4851
4852var warnForMissingKey = function (child, returnFiber) {};
4853
4854{
4855 didWarnAboutMaps = false;
4856 didWarnAboutGenerators = false;
4857 didWarnAboutStringRefs = {};
4858 /**
4859 * Warn if there's no key explicitly set on dynamic arrays of children or
4860 * object keys are not valid. This allows us to keep track of children between
4861 * updates.
4862 */
4863
4864 ownerHasKeyUseWarning = {};
4865 ownerHasFunctionTypeWarning = {};
4866
4867 warnForMissingKey = function (child, returnFiber) {
4868 if (child === null || typeof child !== 'object') {
4869 return;
4870 }
4871
4872 if (!child._store || child._store.validated || child.key != null) {
4873 return;
4874 }
4875
4876 if (typeof child._store !== 'object') {
4877 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.');
4878 }
4879
4880 child._store.validated = true;
4881 var componentName = getComponentNameFromFiber(returnFiber) || 'Component';
4882
4883 if (ownerHasKeyUseWarning[componentName]) {
4884 return;
4885 }
4886
4887 ownerHasKeyUseWarning[componentName] = true;
4888
4889 error('Each child in a list should have a unique ' + '"key" prop. See https://reactjs.org/link/warning-keys for ' + 'more information.');
4890 };
4891}
4892
4893function coerceRef(returnFiber, current, element) {
4894 var mixedRef = element.ref;
4895
4896 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
4897 {
4898 // TODO: Clean this up once we turn on the string ref warning for
4899 // everyone, because the strict mode case will no longer be relevant
4900 if ((returnFiber.mode & StrictLegacyMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs
4901 // because these cannot be automatically converted to an arrow function
4902 // using a codemod. Therefore, we don't have to warn about string refs again.
4903 !(element._owner && element._self && element._owner.stateNode !== element._self)) {
4904 var componentName = getComponentNameFromFiber(returnFiber) || 'Component';
4905
4906 if (!didWarnAboutStringRefs[componentName]) {
4907 {
4908 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);
4909 }
4910
4911 didWarnAboutStringRefs[componentName] = true;
4912 }
4913 }
4914 }
4915
4916 if (element._owner) {
4917 var owner = element._owner;
4918 var inst;
4919
4920 if (owner) {
4921 var ownerFiber = owner;
4922
4923 if (ownerFiber.tag !== ClassComponent) {
4924 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');
4925 }
4926
4927 inst = ownerFiber.stateNode;
4928 }
4929
4930 if (!inst) {
4931 throw new Error("Missing owner for string ref " + mixedRef + ". This error is likely caused by a " + 'bug in React. Please file an issue.');
4932 } // Assigning this to a const so Flow knows it won't change in the closure
4933
4934
4935 var resolvedInst = inst;
4936
4937 {
4938 checkPropStringCoercion(mixedRef, 'ref');
4939 }
4940
4941 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref
4942
4943 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
4944 return current.ref;
4945 }
4946
4947 var ref = function (value) {
4948 var refs = resolvedInst.refs;
4949
4950 if (refs === emptyRefsObject) {
4951 // This is a lazy pooled frozen object, so we need to initialize.
4952 refs = resolvedInst.refs = {};
4953 }
4954
4955 if (value === null) {
4956 delete refs[stringRef];
4957 } else {
4958 refs[stringRef] = value;
4959 }
4960 };
4961
4962 ref._stringRef = stringRef;
4963 return ref;
4964 } else {
4965 if (typeof mixedRef !== 'string') {
4966 throw new Error('Expected ref to be a function, a string, an object returned by React.createRef(), or null.');
4967 }
4968
4969 if (!element._owner) {
4970 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.');
4971 }
4972 }
4973 }
4974
4975 return mixedRef;
4976}
4977
4978function throwOnInvalidObjectType(returnFiber, newChild) {
4979 var childString = Object.prototype.toString.call(newChild);
4980 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.');
4981}
4982
4983function warnOnFunctionType(returnFiber) {
4984 {
4985 var componentName = getComponentNameFromFiber(returnFiber) || 'Component';
4986
4987 if (ownerHasFunctionTypeWarning[componentName]) {
4988 return;
4989 }
4990
4991 ownerHasFunctionTypeWarning[componentName] = true;
4992
4993 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.');
4994 }
4995}
4996
4997function resolveLazy(lazyType) {
4998 var payload = lazyType._payload;
4999 var init = lazyType._init;
5000 return init(payload);
5001} // This wrapper function exists because I expect to clone the code in each path
5002// to be able to optimize each path individually by branching early. This needs
5003// a compiler or we can do it manually. Helpers that don't need this branching
5004// live outside of this function.
5005
5006
5007function ChildReconciler(shouldTrackSideEffects) {
5008 function deleteChild(returnFiber, childToDelete) {
5009 if (!shouldTrackSideEffects) {
5010 // Noop.
5011 return;
5012 }
5013
5014 var deletions = returnFiber.deletions;
5015
5016 if (deletions === null) {
5017 returnFiber.deletions = [childToDelete];
5018 returnFiber.flags |= ChildDeletion;
5019 } else {
5020 deletions.push(childToDelete);
5021 }
5022 }
5023
5024 function deleteRemainingChildren(returnFiber, currentFirstChild) {
5025 if (!shouldTrackSideEffects) {
5026 // Noop.
5027 return null;
5028 } // TODO: For the shouldClone case, this could be micro-optimized a bit by
5029 // assuming that after the first child we've already added everything.
5030
5031
5032 var childToDelete = currentFirstChild;
5033
5034 while (childToDelete !== null) {
5035 deleteChild(returnFiber, childToDelete);
5036 childToDelete = childToDelete.sibling;
5037 }
5038
5039 return null;
5040 }
5041
5042 function mapRemainingChildren(returnFiber, currentFirstChild) {
5043 // Add the remaining children to a temporary map so that we can find them by
5044 // keys quickly. Implicit (null) keys get added to this set with their index
5045 // instead.
5046 var existingChildren = new Map();
5047 var existingChild = currentFirstChild;
5048
5049 while (existingChild !== null) {
5050 if (existingChild.key !== null) {
5051 existingChildren.set(existingChild.key, existingChild);
5052 } else {
5053 existingChildren.set(existingChild.index, existingChild);
5054 }
5055
5056 existingChild = existingChild.sibling;
5057 }
5058
5059 return existingChildren;
5060 }
5061
5062 function useFiber(fiber, pendingProps) {
5063 // We currently set sibling to null and index to 0 here because it is easy
5064 // to forget to do before returning it. E.g. for the single child case.
5065 var clone = createWorkInProgress(fiber, pendingProps);
5066 clone.index = 0;
5067 clone.sibling = null;
5068 return clone;
5069 }
5070
5071 function placeChild(newFiber, lastPlacedIndex, newIndex) {
5072 newFiber.index = newIndex;
5073
5074 if (!shouldTrackSideEffects) {
5075 // During hydration, the useId algorithm needs to know which fibers are
5076 // part of a list of children (arrays, iterators).
5077 newFiber.flags |= Forked;
5078 return lastPlacedIndex;
5079 }
5080
5081 var current = newFiber.alternate;
5082
5083 if (current !== null) {
5084 var oldIndex = current.index;
5085
5086 if (oldIndex < lastPlacedIndex) {
5087 // This is a move.
5088 newFiber.flags |= Placement;
5089 return lastPlacedIndex;
5090 } else {
5091 // This item can stay in place.
5092 return oldIndex;
5093 }
5094 } else {
5095 // This is an insertion.
5096 newFiber.flags |= Placement;
5097 return lastPlacedIndex;
5098 }
5099 }
5100
5101 function placeSingleChild(newFiber) {
5102 // This is simpler for the single child case. We only need to do a
5103 // placement for inserting new children.
5104 if (shouldTrackSideEffects && newFiber.alternate === null) {
5105 newFiber.flags |= Placement;
5106 }
5107
5108 return newFiber;
5109 }
5110
5111 function updateTextNode(returnFiber, current, textContent, lanes) {
5112 if (current === null || current.tag !== HostText) {
5113 // Insert
5114 var created = createFiberFromText(textContent, returnFiber.mode, lanes);
5115 created.return = returnFiber;
5116 return created;
5117 } else {
5118 // Update
5119 var existing = useFiber(current, textContent);
5120 existing.return = returnFiber;
5121 return existing;
5122 }
5123 }
5124
5125 function updateElement(returnFiber, current, element, lanes) {
5126 var elementType = element.type;
5127
5128 if (elementType === REACT_FRAGMENT_TYPE) {
5129 return updateFragment(returnFiber, current, element.props.children, lanes, element.key);
5130 }
5131
5132 if (current !== null) {
5133 if (current.elementType === elementType || ( // Keep this check inline so it only runs on the false path:
5134 isCompatibleFamilyForHotReloading(current, element) ) || // Lazy types should reconcile their resolved type.
5135 // We need to do this after the Hot Reloading check above,
5136 // because hot reloading has different semantics than prod because
5137 // it doesn't resuspend. So we can't let the call below suspend.
5138 typeof elementType === 'object' && elementType !== null && elementType.$$typeof === REACT_LAZY_TYPE && resolveLazy(elementType) === current.type) {
5139 // Move based on index
5140 var existing = useFiber(current, element.props);
5141 existing.ref = coerceRef(returnFiber, current, element);
5142 existing.return = returnFiber;
5143
5144 {
5145 existing._debugSource = element._source;
5146 existing._debugOwner = element._owner;
5147 }
5148
5149 return existing;
5150 }
5151 } // Insert
5152
5153
5154 var created = createFiberFromElement(element, returnFiber.mode, lanes);
5155 created.ref = coerceRef(returnFiber, current, element);
5156 created.return = returnFiber;
5157 return created;
5158 }
5159
5160 function updatePortal(returnFiber, current, portal, lanes) {
5161 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
5162 // Insert
5163 var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
5164 created.return = returnFiber;
5165 return created;
5166 } else {
5167 // Update
5168 var existing = useFiber(current, portal.children || []);
5169 existing.return = returnFiber;
5170 return existing;
5171 }
5172 }
5173
5174 function updateFragment(returnFiber, current, fragment, lanes, key) {
5175 if (current === null || current.tag !== Fragment) {
5176 // Insert
5177 var created = createFiberFromFragment(fragment, returnFiber.mode, lanes, key);
5178 created.return = returnFiber;
5179 return created;
5180 } else {
5181 // Update
5182 var existing = useFiber(current, fragment);
5183 existing.return = returnFiber;
5184 return existing;
5185 }
5186 }
5187
5188 function createChild(returnFiber, newChild, lanes) {
5189 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
5190 // Text nodes don't have keys. If the previous node is implicitly keyed
5191 // we can continue to replace it without aborting even if it is not a text
5192 // node.
5193 var created = createFiberFromText('' + newChild, returnFiber.mode, lanes);
5194 created.return = returnFiber;
5195 return created;
5196 }
5197
5198 if (typeof newChild === 'object' && newChild !== null) {
5199 switch (newChild.$$typeof) {
5200 case REACT_ELEMENT_TYPE:
5201 {
5202 var _created = createFiberFromElement(newChild, returnFiber.mode, lanes);
5203
5204 _created.ref = coerceRef(returnFiber, null, newChild);
5205 _created.return = returnFiber;
5206 return _created;
5207 }
5208
5209 case REACT_PORTAL_TYPE:
5210 {
5211 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, lanes);
5212
5213 _created2.return = returnFiber;
5214 return _created2;
5215 }
5216
5217 case REACT_LAZY_TYPE:
5218 {
5219 var payload = newChild._payload;
5220 var init = newChild._init;
5221 return createChild(returnFiber, init(payload), lanes);
5222 }
5223 }
5224
5225 if (isArray(newChild) || getIteratorFn(newChild)) {
5226 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, lanes, null);
5227
5228 _created3.return = returnFiber;
5229 return _created3;
5230 }
5231
5232 throwOnInvalidObjectType(returnFiber, newChild);
5233 }
5234
5235 {
5236 if (typeof newChild === 'function') {
5237 warnOnFunctionType(returnFiber);
5238 }
5239 }
5240
5241 return null;
5242 }
5243
5244 function updateSlot(returnFiber, oldFiber, newChild, lanes) {
5245 // Update the fiber if the keys match, otherwise return null.
5246 var key = oldFiber !== null ? oldFiber.key : null;
5247
5248 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
5249 // Text nodes don't have keys. If the previous node is implicitly keyed
5250 // we can continue to replace it without aborting even if it is not a text
5251 // node.
5252 if (key !== null) {
5253 return null;
5254 }
5255
5256 return updateTextNode(returnFiber, oldFiber, '' + newChild, lanes);
5257 }
5258
5259 if (typeof newChild === 'object' && newChild !== null) {
5260 switch (newChild.$$typeof) {
5261 case REACT_ELEMENT_TYPE:
5262 {
5263 if (newChild.key === key) {
5264 return updateElement(returnFiber, oldFiber, newChild, lanes);
5265 } else {
5266 return null;
5267 }
5268 }
5269
5270 case REACT_PORTAL_TYPE:
5271 {
5272 if (newChild.key === key) {
5273 return updatePortal(returnFiber, oldFiber, newChild, lanes);
5274 } else {
5275 return null;
5276 }
5277 }
5278
5279 case REACT_LAZY_TYPE:
5280 {
5281 var payload = newChild._payload;
5282 var init = newChild._init;
5283 return updateSlot(returnFiber, oldFiber, init(payload), lanes);
5284 }
5285 }
5286
5287 if (isArray(newChild) || getIteratorFn(newChild)) {
5288 if (key !== null) {
5289 return null;
5290 }
5291
5292 return updateFragment(returnFiber, oldFiber, newChild, lanes, null);
5293 }
5294
5295 throwOnInvalidObjectType(returnFiber, newChild);
5296 }
5297
5298 {
5299 if (typeof newChild === 'function') {
5300 warnOnFunctionType(returnFiber);
5301 }
5302 }
5303
5304 return null;
5305 }
5306
5307 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, lanes) {
5308 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
5309 // Text nodes don't have keys, so we neither have to check the old nor
5310 // new node for the key. If both are text nodes, they match.
5311 var matchedFiber = existingChildren.get(newIdx) || null;
5312 return updateTextNode(returnFiber, matchedFiber, '' + newChild, lanes);
5313 }
5314
5315 if (typeof newChild === 'object' && newChild !== null) {
5316 switch (newChild.$$typeof) {
5317 case REACT_ELEMENT_TYPE:
5318 {
5319 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
5320
5321 return updateElement(returnFiber, _matchedFiber, newChild, lanes);
5322 }
5323
5324 case REACT_PORTAL_TYPE:
5325 {
5326 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
5327
5328 return updatePortal(returnFiber, _matchedFiber2, newChild, lanes);
5329 }
5330
5331 case REACT_LAZY_TYPE:
5332 var payload = newChild._payload;
5333 var init = newChild._init;
5334 return updateFromMap(existingChildren, returnFiber, newIdx, init(payload), lanes);
5335 }
5336
5337 if (isArray(newChild) || getIteratorFn(newChild)) {
5338 var _matchedFiber3 = existingChildren.get(newIdx) || null;
5339
5340 return updateFragment(returnFiber, _matchedFiber3, newChild, lanes, null);
5341 }
5342
5343 throwOnInvalidObjectType(returnFiber, newChild);
5344 }
5345
5346 {
5347 if (typeof newChild === 'function') {
5348 warnOnFunctionType(returnFiber);
5349 }
5350 }
5351
5352 return null;
5353 }
5354 /**
5355 * Warns if there is a duplicate or missing key
5356 */
5357
5358
5359 function warnOnInvalidKey(child, knownKeys, returnFiber) {
5360 {
5361 if (typeof child !== 'object' || child === null) {
5362 return knownKeys;
5363 }
5364
5365 switch (child.$$typeof) {
5366 case REACT_ELEMENT_TYPE:
5367 case REACT_PORTAL_TYPE:
5368 warnForMissingKey(child, returnFiber);
5369 var key = child.key;
5370
5371 if (typeof key !== 'string') {
5372 break;
5373 }
5374
5375 if (knownKeys === null) {
5376 knownKeys = new Set();
5377 knownKeys.add(key);
5378 break;
5379 }
5380
5381 if (!knownKeys.has(key)) {
5382 knownKeys.add(key);
5383 break;
5384 }
5385
5386 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);
5387
5388 break;
5389
5390 case REACT_LAZY_TYPE:
5391 var payload = child._payload;
5392 var init = child._init;
5393 warnOnInvalidKey(init(payload), knownKeys, returnFiber);
5394 break;
5395 }
5396 }
5397
5398 return knownKeys;
5399 }
5400
5401 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, lanes) {
5402 // This algorithm can't optimize by searching from both ends since we
5403 // don't have backpointers on fibers. I'm trying to see how far we can get
5404 // with that model. If it ends up not being worth the tradeoffs, we can
5405 // add it later.
5406 // Even with a two ended optimization, we'd want to optimize for the case
5407 // where there are few changes and brute force the comparison instead of
5408 // going for the Map. It'd like to explore hitting that path first in
5409 // forward-only mode and only go for the Map once we notice that we need
5410 // lots of look ahead. This doesn't handle reversal as well as two ended
5411 // search but that's unusual. Besides, for the two ended optimization to
5412 // work on Iterables, we'd need to copy the whole set.
5413 // In this first iteration, we'll just live with hitting the bad case
5414 // (adding everything to a Map) in for every insert/move.
5415 // If you change this code, also update reconcileChildrenIterator() which
5416 // uses the same algorithm.
5417 {
5418 // First, validate keys.
5419 var knownKeys = null;
5420
5421 for (var i = 0; i < newChildren.length; i++) {
5422 var child = newChildren[i];
5423 knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber);
5424 }
5425 }
5426
5427 var resultingFirstChild = null;
5428 var previousNewFiber = null;
5429 var oldFiber = currentFirstChild;
5430 var lastPlacedIndex = 0;
5431 var newIdx = 0;
5432 var nextOldFiber = null;
5433
5434 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
5435 if (oldFiber.index > newIdx) {
5436 nextOldFiber = oldFiber;
5437 oldFiber = null;
5438 } else {
5439 nextOldFiber = oldFiber.sibling;
5440 }
5441
5442 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], lanes);
5443
5444 if (newFiber === null) {
5445 // TODO: This breaks on empty slots like null children. That's
5446 // unfortunate because it triggers the slow path all the time. We need
5447 // a better way to communicate whether this was a miss or null,
5448 // boolean, undefined, etc.
5449 if (oldFiber === null) {
5450 oldFiber = nextOldFiber;
5451 }
5452
5453 break;
5454 }
5455
5456 if (shouldTrackSideEffects) {
5457 if (oldFiber && newFiber.alternate === null) {
5458 // We matched the slot, but we didn't reuse the existing fiber, so we
5459 // need to delete the existing child.
5460 deleteChild(returnFiber, oldFiber);
5461 }
5462 }
5463
5464 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
5465
5466 if (previousNewFiber === null) {
5467 // TODO: Move out of the loop. This only happens for the first run.
5468 resultingFirstChild = newFiber;
5469 } else {
5470 // TODO: Defer siblings if we're not at the right index for this slot.
5471 // I.e. if we had null values before, then we want to defer this
5472 // for each null value. However, we also don't want to call updateSlot
5473 // with the previous one.
5474 previousNewFiber.sibling = newFiber;
5475 }
5476
5477 previousNewFiber = newFiber;
5478 oldFiber = nextOldFiber;
5479 }
5480
5481 if (newIdx === newChildren.length) {
5482 // We've reached the end of the new children. We can delete the rest.
5483 deleteRemainingChildren(returnFiber, oldFiber);
5484
5485 return resultingFirstChild;
5486 }
5487
5488 if (oldFiber === null) {
5489 // If we don't have any more existing children we can choose a fast path
5490 // since the rest will all be insertions.
5491 for (; newIdx < newChildren.length; newIdx++) {
5492 var _newFiber = createChild(returnFiber, newChildren[newIdx], lanes);
5493
5494 if (_newFiber === null) {
5495 continue;
5496 }
5497
5498 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
5499
5500 if (previousNewFiber === null) {
5501 // TODO: Move out of the loop. This only happens for the first run.
5502 resultingFirstChild = _newFiber;
5503 } else {
5504 previousNewFiber.sibling = _newFiber;
5505 }
5506
5507 previousNewFiber = _newFiber;
5508 }
5509
5510 return resultingFirstChild;
5511 } // Add all children to a key map for quick lookups.
5512
5513
5514 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
5515
5516 for (; newIdx < newChildren.length; newIdx++) {
5517 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], lanes);
5518
5519 if (_newFiber2 !== null) {
5520 if (shouldTrackSideEffects) {
5521 if (_newFiber2.alternate !== null) {
5522 // The new fiber is a work in progress, but if there exists a
5523 // current, that means that we reused the fiber. We need to delete
5524 // it from the child list so that we don't add it to the deletion
5525 // list.
5526 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
5527 }
5528 }
5529
5530 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
5531
5532 if (previousNewFiber === null) {
5533 resultingFirstChild = _newFiber2;
5534 } else {
5535 previousNewFiber.sibling = _newFiber2;
5536 }
5537
5538 previousNewFiber = _newFiber2;
5539 }
5540 }
5541
5542 if (shouldTrackSideEffects) {
5543 // Any existing children that weren't consumed above were deleted. We need
5544 // to add them to the deletion list.
5545 existingChildren.forEach(function (child) {
5546 return deleteChild(returnFiber, child);
5547 });
5548 }
5549
5550 return resultingFirstChild;
5551 }
5552
5553 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, lanes) {
5554 // This is the same implementation as reconcileChildrenArray(),
5555 // but using the iterator instead.
5556 var iteratorFn = getIteratorFn(newChildrenIterable);
5557
5558 if (typeof iteratorFn !== 'function') {
5559 throw new Error('An object is not an iterable. This error is likely caused by a bug in ' + 'React. Please file an issue.');
5560 }
5561
5562 {
5563 // We don't support rendering Generators because it's a mutation.
5564 // See https://github.com/facebook/react/issues/12995
5565 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag
5566 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
5567 if (!didWarnAboutGenerators) {
5568 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.');
5569 }
5570
5571 didWarnAboutGenerators = true;
5572 } // Warn about using Maps as children
5573
5574
5575 if (newChildrenIterable.entries === iteratorFn) {
5576 if (!didWarnAboutMaps) {
5577 error('Using Maps as children is not supported. ' + 'Use an array of keyed ReactElements instead.');
5578 }
5579
5580 didWarnAboutMaps = true;
5581 } // First, validate keys.
5582 // We'll get a different iterator later for the main pass.
5583
5584
5585 var _newChildren = iteratorFn.call(newChildrenIterable);
5586
5587 if (_newChildren) {
5588 var knownKeys = null;
5589
5590 var _step = _newChildren.next();
5591
5592 for (; !_step.done; _step = _newChildren.next()) {
5593 var child = _step.value;
5594 knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber);
5595 }
5596 }
5597 }
5598
5599 var newChildren = iteratorFn.call(newChildrenIterable);
5600
5601 if (newChildren == null) {
5602 throw new Error('An iterable object provided no iterator.');
5603 }
5604
5605 var resultingFirstChild = null;
5606 var previousNewFiber = null;
5607 var oldFiber = currentFirstChild;
5608 var lastPlacedIndex = 0;
5609 var newIdx = 0;
5610 var nextOldFiber = null;
5611 var step = newChildren.next();
5612
5613 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
5614 if (oldFiber.index > newIdx) {
5615 nextOldFiber = oldFiber;
5616 oldFiber = null;
5617 } else {
5618 nextOldFiber = oldFiber.sibling;
5619 }
5620
5621 var newFiber = updateSlot(returnFiber, oldFiber, step.value, lanes);
5622
5623 if (newFiber === null) {
5624 // TODO: This breaks on empty slots like null children. That's
5625 // unfortunate because it triggers the slow path all the time. We need
5626 // a better way to communicate whether this was a miss or null,
5627 // boolean, undefined, etc.
5628 if (oldFiber === null) {
5629 oldFiber = nextOldFiber;
5630 }
5631
5632 break;
5633 }
5634
5635 if (shouldTrackSideEffects) {
5636 if (oldFiber && newFiber.alternate === null) {
5637 // We matched the slot, but we didn't reuse the existing fiber, so we
5638 // need to delete the existing child.
5639 deleteChild(returnFiber, oldFiber);
5640 }
5641 }
5642
5643 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
5644
5645 if (previousNewFiber === null) {
5646 // TODO: Move out of the loop. This only happens for the first run.
5647 resultingFirstChild = newFiber;
5648 } else {
5649 // TODO: Defer siblings if we're not at the right index for this slot.
5650 // I.e. if we had null values before, then we want to defer this
5651 // for each null value. However, we also don't want to call updateSlot
5652 // with the previous one.
5653 previousNewFiber.sibling = newFiber;
5654 }
5655
5656 previousNewFiber = newFiber;
5657 oldFiber = nextOldFiber;
5658 }
5659
5660 if (step.done) {
5661 // We've reached the end of the new children. We can delete the rest.
5662 deleteRemainingChildren(returnFiber, oldFiber);
5663
5664 return resultingFirstChild;
5665 }
5666
5667 if (oldFiber === null) {
5668 // If we don't have any more existing children we can choose a fast path
5669 // since the rest will all be insertions.
5670 for (; !step.done; newIdx++, step = newChildren.next()) {
5671 var _newFiber3 = createChild(returnFiber, step.value, lanes);
5672
5673 if (_newFiber3 === null) {
5674 continue;
5675 }
5676
5677 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
5678
5679 if (previousNewFiber === null) {
5680 // TODO: Move out of the loop. This only happens for the first run.
5681 resultingFirstChild = _newFiber3;
5682 } else {
5683 previousNewFiber.sibling = _newFiber3;
5684 }
5685
5686 previousNewFiber = _newFiber3;
5687 }
5688
5689 return resultingFirstChild;
5690 } // Add all children to a key map for quick lookups.
5691
5692
5693 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
5694
5695 for (; !step.done; newIdx++, step = newChildren.next()) {
5696 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, lanes);
5697
5698 if (_newFiber4 !== null) {
5699 if (shouldTrackSideEffects) {
5700 if (_newFiber4.alternate !== null) {
5701 // The new fiber is a work in progress, but if there exists a
5702 // current, that means that we reused the fiber. We need to delete
5703 // it from the child list so that we don't add it to the deletion
5704 // list.
5705 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
5706 }
5707 }
5708
5709 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
5710
5711 if (previousNewFiber === null) {
5712 resultingFirstChild = _newFiber4;
5713 } else {
5714 previousNewFiber.sibling = _newFiber4;
5715 }
5716
5717 previousNewFiber = _newFiber4;
5718 }
5719 }
5720
5721 if (shouldTrackSideEffects) {
5722 // Any existing children that weren't consumed above were deleted. We need
5723 // to add them to the deletion list.
5724 existingChildren.forEach(function (child) {
5725 return deleteChild(returnFiber, child);
5726 });
5727 }
5728
5729 return resultingFirstChild;
5730 }
5731
5732 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, lanes) {
5733 // There's no need to check for keys on text nodes since we don't have a
5734 // way to define them.
5735 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
5736 // We already have an existing node so let's just update it and delete
5737 // the rest.
5738 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
5739 var existing = useFiber(currentFirstChild, textContent);
5740 existing.return = returnFiber;
5741 return existing;
5742 } // The existing first child is not a text node so we need to create one
5743 // and delete the existing ones.
5744
5745
5746 deleteRemainingChildren(returnFiber, currentFirstChild);
5747 var created = createFiberFromText(textContent, returnFiber.mode, lanes);
5748 created.return = returnFiber;
5749 return created;
5750 }
5751
5752 function reconcileSingleElement(returnFiber, currentFirstChild, element, lanes) {
5753 var key = element.key;
5754 var child = currentFirstChild;
5755
5756 while (child !== null) {
5757 // TODO: If key === null and child.key === null, then this only applies to
5758 // the first item in the list.
5759 if (child.key === key) {
5760 var elementType = element.type;
5761
5762 if (elementType === REACT_FRAGMENT_TYPE) {
5763 if (child.tag === Fragment) {
5764 deleteRemainingChildren(returnFiber, child.sibling);
5765 var existing = useFiber(child, element.props.children);
5766 existing.return = returnFiber;
5767
5768 {
5769 existing._debugSource = element._source;
5770 existing._debugOwner = element._owner;
5771 }
5772
5773 return existing;
5774 }
5775 } else {
5776 if (child.elementType === elementType || ( // Keep this check inline so it only runs on the false path:
5777 isCompatibleFamilyForHotReloading(child, element) ) || // Lazy types should reconcile their resolved type.
5778 // We need to do this after the Hot Reloading check above,
5779 // because hot reloading has different semantics than prod because
5780 // it doesn't resuspend. So we can't let the call below suspend.
5781 typeof elementType === 'object' && elementType !== null && elementType.$$typeof === REACT_LAZY_TYPE && resolveLazy(elementType) === child.type) {
5782 deleteRemainingChildren(returnFiber, child.sibling);
5783
5784 var _existing = useFiber(child, element.props);
5785
5786 _existing.ref = coerceRef(returnFiber, child, element);
5787 _existing.return = returnFiber;
5788
5789 {
5790 _existing._debugSource = element._source;
5791 _existing._debugOwner = element._owner;
5792 }
5793
5794 return _existing;
5795 }
5796 } // Didn't match.
5797
5798
5799 deleteRemainingChildren(returnFiber, child);
5800 break;
5801 } else {
5802 deleteChild(returnFiber, child);
5803 }
5804
5805 child = child.sibling;
5806 }
5807
5808 if (element.type === REACT_FRAGMENT_TYPE) {
5809 var created = createFiberFromFragment(element.props.children, returnFiber.mode, lanes, element.key);
5810 created.return = returnFiber;
5811 return created;
5812 } else {
5813 var _created4 = createFiberFromElement(element, returnFiber.mode, lanes);
5814
5815 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
5816 _created4.return = returnFiber;
5817 return _created4;
5818 }
5819 }
5820
5821 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, lanes) {
5822 var key = portal.key;
5823 var child = currentFirstChild;
5824
5825 while (child !== null) {
5826 // TODO: If key === null and child.key === null, then this only applies to
5827 // the first item in the list.
5828 if (child.key === key) {
5829 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
5830 deleteRemainingChildren(returnFiber, child.sibling);
5831 var existing = useFiber(child, portal.children || []);
5832 existing.return = returnFiber;
5833 return existing;
5834 } else {
5835 deleteRemainingChildren(returnFiber, child);
5836 break;
5837 }
5838 } else {
5839 deleteChild(returnFiber, child);
5840 }
5841
5842 child = child.sibling;
5843 }
5844
5845 var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
5846 created.return = returnFiber;
5847 return created;
5848 } // This API will tag the children with the side-effect of the reconciliation
5849 // itself. They will be added to the side-effect list as we pass through the
5850 // children and the parent.
5851
5852
5853 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, lanes) {
5854 // This function is not recursive.
5855 // If the top level item is an array, we treat it as a set of children,
5856 // not as a fragment. Nested arrays on the other hand will be treated as
5857 // fragment nodes. Recursion happens at the normal flow.
5858 // Handle top level unkeyed fragments as if they were arrays.
5859 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
5860 // We treat the ambiguous cases above the same.
5861 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
5862
5863 if (isUnkeyedTopLevelFragment) {
5864 newChild = newChild.props.children;
5865 } // Handle object types
5866
5867
5868 if (typeof newChild === 'object' && newChild !== null) {
5869 switch (newChild.$$typeof) {
5870 case REACT_ELEMENT_TYPE:
5871 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, lanes));
5872
5873 case REACT_PORTAL_TYPE:
5874 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, lanes));
5875
5876 case REACT_LAZY_TYPE:
5877 var payload = newChild._payload;
5878 var init = newChild._init; // TODO: This function is supposed to be non-recursive.
5879
5880 return reconcileChildFibers(returnFiber, currentFirstChild, init(payload), lanes);
5881 }
5882
5883 if (isArray(newChild)) {
5884 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, lanes);
5885 }
5886
5887 if (getIteratorFn(newChild)) {
5888 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, lanes);
5889 }
5890
5891 throwOnInvalidObjectType(returnFiber, newChild);
5892 }
5893
5894 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
5895 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, lanes));
5896 }
5897
5898 {
5899 if (typeof newChild === 'function') {
5900 warnOnFunctionType(returnFiber);
5901 }
5902 } // Remaining cases are all treated as empty.
5903
5904
5905 return deleteRemainingChildren(returnFiber, currentFirstChild);
5906 }
5907
5908 return reconcileChildFibers;
5909}
5910
5911var reconcileChildFibers = ChildReconciler(true);
5912var mountChildFibers = ChildReconciler(false);
5913function cloneChildFibers(current, workInProgress) {
5914 if (current !== null && workInProgress.child !== current.child) {
5915 throw new Error('Resuming work not yet implemented.');
5916 }
5917
5918 if (workInProgress.child === null) {
5919 return;
5920 }
5921
5922 var currentChild = workInProgress.child;
5923 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps);
5924 workInProgress.child = newChild;
5925 newChild.return = workInProgress;
5926
5927 while (currentChild.sibling !== null) {
5928 currentChild = currentChild.sibling;
5929 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps);
5930 newChild.return = workInProgress;
5931 }
5932
5933 newChild.sibling = null;
5934} // Reset a workInProgress child set to prepare it for a second pass.
5935
5936function resetChildFibers(workInProgress, lanes) {
5937 var child = workInProgress.child;
5938
5939 while (child !== null) {
5940 resetWorkInProgress(child, lanes);
5941 child = child.sibling;
5942 }
5943}
5944
5945var NO_CONTEXT$1 = {};
5946var contextStackCursor$1 = createCursor(NO_CONTEXT$1);
5947var contextFiberStackCursor = createCursor(NO_CONTEXT$1);
5948var rootInstanceStackCursor = createCursor(NO_CONTEXT$1);
5949
5950function requiredContext(c) {
5951 if (c === NO_CONTEXT$1) {
5952 throw new Error('Expected host context to exist. This error is likely caused by a bug ' + 'in React. Please file an issue.');
5953 }
5954
5955 return c;
5956}
5957
5958function getRootHostContainer() {
5959 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5960 return rootInstance;
5961}
5962
5963function pushHostContainer(fiber, nextRootInstance) {
5964 // Push current root instance onto the stack;
5965 // This allows us to reset root when portals are popped.
5966 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
5967 // This enables us to pop only Fibers that provide unique contexts.
5968
5969 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
5970 // However, we can't just call getRootHostContext() and push it because
5971 // we'd have a different number of entries on the stack depending on
5972 // whether getRootHostContext() throws somewhere in renderer code or not.
5973 // So we push an empty value first. This lets us safely unwind on errors.
5974
5975 push(contextStackCursor$1, NO_CONTEXT$1, fiber);
5976 var nextRootContext = getRootHostContext(); // Now that we know this function doesn't throw, replace it.
5977
5978 pop(contextStackCursor$1, fiber);
5979 push(contextStackCursor$1, nextRootContext, fiber);
5980}
5981
5982function popHostContainer(fiber) {
5983 pop(contextStackCursor$1, fiber);
5984 pop(contextFiberStackCursor, fiber);
5985 pop(rootInstanceStackCursor, fiber);
5986}
5987
5988function getHostContext() {
5989 var context = requiredContext(contextStackCursor$1.current);
5990 return context;
5991}
5992
5993function pushHostContext(fiber) {
5994 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5995 var context = requiredContext(contextStackCursor$1.current);
5996 var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique.
5997
5998 if (context === nextContext) {
5999 return;
6000 } // Track the context and the Fiber that provided it.
6001 // This enables us to pop only Fibers that provide unique contexts.
6002
6003
6004 push(contextFiberStackCursor, fiber, fiber);
6005 push(contextStackCursor$1, nextContext, fiber);
6006}
6007
6008function popHostContext(fiber) {
6009 // Do not pop unless this Fiber provided the current context.
6010 // pushHostContext() only pushes Fibers that provide unique contexts.
6011 if (contextFiberStackCursor.current !== fiber) {
6012 return;
6013 }
6014
6015 pop(contextStackCursor$1, fiber);
6016 pop(contextFiberStackCursor, fiber);
6017}
6018
6019var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is
6020// inherited deeply down the subtree. The upper bits only affect
6021// this immediate suspense boundary and gets reset each new
6022// boundary or suspense list.
6023
6024var SubtreeSuspenseContextMask = 1; // Subtree Flags:
6025// InvisibleParentSuspenseContext indicates that one of our parent Suspense
6026// boundaries is not currently showing visible main content.
6027// Either because it is already showing a fallback or is not mounted at all.
6028// We can use this to determine if it is desirable to trigger a fallback at
6029// the parent. If not, then we might need to trigger undesirable boundaries
6030// and/or suspend the commit to avoid hiding the parent content.
6031
6032var InvisibleParentSuspenseContext = 1; // Shallow Flags:
6033// ForceSuspenseFallback can be used by SuspenseList to force newly added
6034// items into their fallback state during one of the render passes.
6035
6036var ForceSuspenseFallback = 2;
6037var suspenseStackCursor = createCursor(DefaultSuspenseContext);
6038function hasSuspenseContext(parentContext, flag) {
6039 return (parentContext & flag) !== 0;
6040}
6041function setDefaultShallowSuspenseContext(parentContext) {
6042 return parentContext & SubtreeSuspenseContextMask;
6043}
6044function setShallowSuspenseContext(parentContext, shallowContext) {
6045 return parentContext & SubtreeSuspenseContextMask | shallowContext;
6046}
6047function addSubtreeSuspenseContext(parentContext, subtreeContext) {
6048 return parentContext | subtreeContext;
6049}
6050function pushSuspenseContext(fiber, newContext) {
6051 push(suspenseStackCursor, newContext, fiber);
6052}
6053function popSuspenseContext(fiber) {
6054 pop(suspenseStackCursor, fiber);
6055}
6056
6057function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
6058 // If it was the primary children that just suspended, capture and render the
6059 // fallback. Otherwise, don't capture and bubble to the next boundary.
6060 var nextState = workInProgress.memoizedState;
6061
6062 if (nextState !== null) {
6063 if (nextState.dehydrated !== null) {
6064 // A dehydrated boundary always captures.
6065 return true;
6066 }
6067
6068 return false;
6069 }
6070
6071 var props = workInProgress.memoizedProps; // Regular boundaries always capture.
6072
6073 {
6074 return true;
6075 } // If it's a boundary we should avoid, then we prefer to bubble up to the
6076}
6077function findFirstSuspended(row) {
6078 var node = row;
6079
6080 while (node !== null) {
6081 if (node.tag === SuspenseComponent) {
6082 var state = node.memoizedState;
6083
6084 if (state !== null) {
6085 var dehydrated = state.dehydrated;
6086
6087 if (dehydrated === null || isSuspenseInstancePending() || isSuspenseInstanceFallback()) {
6088 return node;
6089 }
6090 }
6091 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
6092 // keep track of whether it suspended or not.
6093 node.memoizedProps.revealOrder !== undefined) {
6094 var didSuspend = (node.flags & DidCapture) !== NoFlags;
6095
6096 if (didSuspend) {
6097 return node;
6098 }
6099 } else if (node.child !== null) {
6100 node.child.return = node;
6101 node = node.child;
6102 continue;
6103 }
6104
6105 if (node === row) {
6106 return null;
6107 }
6108
6109 while (node.sibling === null) {
6110 if (node.return === null || node.return === row) {
6111 return null;
6112 }
6113
6114 node = node.return;
6115 }
6116
6117 node.sibling.return = node.return;
6118 node = node.sibling;
6119 }
6120
6121 return null;
6122}
6123
6124var NoFlags$1 =
6125/* */
61260; // Represents whether effect should fire.
6127
6128var HasEffect =
6129/* */
61301; // Represents the phase in which the effect (not the clean-up) fires.
6131
6132var Insertion =
6133/* */
61342;
6135var Layout =
6136/* */
61374;
6138var Passive$1 =
6139/* */
61408;
6141
6142// and should be reset before starting a new render.
6143// This tracks which mutable sources need to be reset after a render.
6144
6145var workInProgressSources = [];
6146function resetWorkInProgressVersions() {
6147 for (var i = 0; i < workInProgressSources.length; i++) {
6148 var mutableSource = workInProgressSources[i];
6149
6150 {
6151 mutableSource._workInProgressVersionSecondary = null;
6152 }
6153 }
6154
6155 workInProgressSources.length = 0;
6156}
6157
6158var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher,
6159 ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig;
6160var didWarnAboutMismatchedHooksForComponent;
6161var didWarnUncachedGetSnapshot;
6162
6163{
6164 didWarnAboutMismatchedHooksForComponent = new Set();
6165}
6166
6167// These are set right before calling the component.
6168var renderLanes = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from
6169// the work-in-progress hook.
6170
6171var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
6172// current hook list is the list that belongs to the current fiber. The
6173// work-in-progress hook list is a new list that will be added to the
6174// work-in-progress fiber.
6175
6176var currentHook = null;
6177var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This
6178// does not get reset if we do another render pass; only when we're completely
6179// finished evaluating this component. This is an optimization so we know
6180// whether we need to clear render phase updates after a throw.
6181
6182var didScheduleRenderPhaseUpdate = false; // Where an update was scheduled only during the current render pass. This
6183// gets reset after each attempt.
6184// TODO: Maybe there's some way to consolidate this with
6185// `didScheduleRenderPhaseUpdate`. Or with `numberOfReRenders`.
6186
6187var didScheduleRenderPhaseUpdateDuringThisPass = false; // Counts the number of useId hooks in this component.
6188// hydration). This counter is global, so client ids are not stable across
6189// render attempts.
6190
6191var globalClientIdCounter = 0;
6192var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
6193
6194var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
6195// The list stores the order of hooks used during the initial render (mount).
6196// Subsequent renders (updates) reference this list.
6197
6198var hookTypesDev = null;
6199var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
6200// the dependencies for Hooks that need them (e.g. useEffect or useMemo).
6201// When true, such Hooks will always be "remounted". Only used during hot reload.
6202
6203var ignorePreviousDependencies = false;
6204
6205function mountHookTypesDev() {
6206 {
6207 var hookName = currentHookNameInDev;
6208
6209 if (hookTypesDev === null) {
6210 hookTypesDev = [hookName];
6211 } else {
6212 hookTypesDev.push(hookName);
6213 }
6214 }
6215}
6216
6217function updateHookTypesDev() {
6218 {
6219 var hookName = currentHookNameInDev;
6220
6221 if (hookTypesDev !== null) {
6222 hookTypesUpdateIndexDev++;
6223
6224 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
6225 warnOnHookMismatchInDev(hookName);
6226 }
6227 }
6228 }
6229}
6230
6231function checkDepsAreArrayDev(deps) {
6232 {
6233 if (deps !== undefined && deps !== null && !isArray(deps)) {
6234 // Verify deps, but only on mount to avoid extra checks.
6235 // It's unlikely their type would change as usually you define them inline.
6236 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);
6237 }
6238 }
6239}
6240
6241function warnOnHookMismatchInDev(currentHookName) {
6242 {
6243 var componentName = getComponentNameFromFiber(currentlyRenderingFiber$1);
6244
6245 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
6246 didWarnAboutMismatchedHooksForComponent.add(componentName);
6247
6248 if (hookTypesDev !== null) {
6249 var table = '';
6250 var secondColumnStart = 30;
6251
6252 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
6253 var oldHookName = hookTypesDev[i];
6254 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
6255 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
6256 // lol @ IE not supporting String#repeat
6257
6258 while (row.length < secondColumnStart) {
6259 row += ' ';
6260 }
6261
6262 row += newHookName + '\n';
6263 table += row;
6264 }
6265
6266 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);
6267 }
6268 }
6269 }
6270}
6271
6272function throwInvalidHookError() {
6273 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.');
6274}
6275
6276function areHookInputsEqual(nextDeps, prevDeps) {
6277 {
6278 if (ignorePreviousDependencies) {
6279 // Only true when this component is being hot reloaded.
6280 return false;
6281 }
6282 }
6283
6284 if (prevDeps === null) {
6285 {
6286 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);
6287 }
6288
6289 return false;
6290 }
6291
6292 {
6293 // Don't bother comparing lengths in prod because these arrays should be
6294 // passed inline.
6295 if (nextDeps.length !== prevDeps.length) {
6296 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(', ') + "]");
6297 }
6298 }
6299
6300 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
6301 if (objectIs(nextDeps[i], prevDeps[i])) {
6302 continue;
6303 }
6304
6305 return false;
6306 }
6307
6308 return true;
6309}
6310
6311function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderLanes) {
6312 renderLanes = nextRenderLanes;
6313 currentlyRenderingFiber$1 = workInProgress;
6314
6315 {
6316 hookTypesDev = current !== null ? current._debugHookTypes : null;
6317 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
6318
6319 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
6320 }
6321
6322 workInProgress.memoizedState = null;
6323 workInProgress.updateQueue = null;
6324 workInProgress.lanes = NoLanes; // The following should have already been reset
6325 // currentHook = null;
6326 // workInProgressHook = null;
6327 // didScheduleRenderPhaseUpdate = false;
6328 // localIdCounter = 0;
6329 // TODO Warn if no hooks are used at all during mount, then some are used during update.
6330 // Currently we will identify the update render as a mount because memoizedState === null.
6331 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
6332 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.
6333 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
6334 // so memoizedState would be null during updates and mounts.
6335
6336 {
6337 if (current !== null && current.memoizedState !== null) {
6338 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
6339 } else if (hookTypesDev !== null) {
6340 // This dispatcher handles an edge case where a component is updating,
6341 // but no stateful hooks have been used.
6342 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
6343 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
6344 // This dispatcher does that.
6345 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
6346 } else {
6347 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
6348 }
6349 }
6350
6351 var children = Component(props, secondArg); // Check if there was a render phase update
6352
6353 if (didScheduleRenderPhaseUpdateDuringThisPass) {
6354 // Keep rendering in a loop for as long as render phase updates continue to
6355 // be scheduled. Use a counter to prevent infinite loops.
6356 var numberOfReRenders = 0;
6357
6358 do {
6359 didScheduleRenderPhaseUpdateDuringThisPass = false;
6360
6361 if (numberOfReRenders >= RE_RENDER_LIMIT) {
6362 throw new Error('Too many re-renders. React limits the number of renders to prevent ' + 'an infinite loop.');
6363 }
6364
6365 numberOfReRenders += 1;
6366
6367 {
6368 // Even when hot reloading, allow dependencies to stabilize
6369 // after first render to prevent infinite render phase updates.
6370 ignorePreviousDependencies = false;
6371 } // Start over from the beginning of the list
6372
6373
6374 currentHook = null;
6375 workInProgressHook = null;
6376 workInProgress.updateQueue = null;
6377
6378 {
6379 // Also validate hook order for cascading updates.
6380 hookTypesUpdateIndexDev = -1;
6381 }
6382
6383 ReactCurrentDispatcher$1.current = HooksDispatcherOnRerenderInDEV ;
6384 children = Component(props, secondArg);
6385 } while (didScheduleRenderPhaseUpdateDuringThisPass);
6386 } // We can assume the previous dispatcher is always this one, since we set it
6387 // at the beginning of the render phase and there's no re-entrance.
6388
6389
6390 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
6391
6392 {
6393 workInProgress._debugHookTypes = hookTypesDev;
6394 } // This check uses currentHook so that it works the same in DEV and prod bundles.
6395 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
6396
6397
6398 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
6399 renderLanes = NoLanes;
6400 currentlyRenderingFiber$1 = null;
6401 currentHook = null;
6402 workInProgressHook = null;
6403
6404 {
6405 currentHookNameInDev = null;
6406 hookTypesDev = null;
6407 hookTypesUpdateIndexDev = -1; // Confirm that a static flag was not added or removed since the last
6408 // render. If this fires, it suggests that we incorrectly reset the static
6409 // flags in some other part of the codebase. This has happened before, for
6410 // example, in the SuspenseList implementation.
6411
6412 if (current !== null && (current.flags & StaticMask) !== (workInProgress.flags & StaticMask) && // Disable this warning in legacy mode, because legacy Suspense is weird
6413 // and creates false positives. To make this work in legacy mode, we'd
6414 // need to mark fibers that commit in an incomplete state, somehow. For
6415 // now I'll disable the warning that most of the bugs that would trigger
6416 // it are either exclusive to concurrent mode or exist in both.
6417 (current.mode & ConcurrentMode) !== NoMode) {
6418 error('Internal React error: Expected static flag was missing. Please ' + 'notify the React team.');
6419 }
6420 }
6421
6422 didScheduleRenderPhaseUpdate = false; // This is reset by checkDidRenderIdHook
6423 // localIdCounter = 0;
6424
6425 if (didRenderTooFewHooks) {
6426 throw new Error('Rendered fewer hooks than expected. This may be caused by an accidental ' + 'early return statement.');
6427 }
6428
6429 return children;
6430}
6431function bailoutHooks(current, workInProgress, lanes) {
6432 workInProgress.updateQueue = current.updateQueue; // TODO: Don't need to reset the flags here, because they're reset in the
6433 // complete phase (bubbleProperties).
6434
6435 {
6436 workInProgress.flags &= ~(Passive | Update);
6437 }
6438
6439 current.lanes = removeLanes(current.lanes, lanes);
6440}
6441function resetHooksAfterThrow() {
6442 // We can assume the previous dispatcher is always this one, since we set it
6443 // at the beginning of the render phase and there's no re-entrance.
6444 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
6445
6446 if (didScheduleRenderPhaseUpdate) {
6447 // There were render phase updates. These are only valid for this render
6448 // phase, which we are now aborting. Remove the updates from the queues so
6449 // they do not persist to the next render. Do not remove updates from hooks
6450 // that weren't processed.
6451 //
6452 // Only reset the updates from the queue if it has a clone. If it does
6453 // not have a clone, that means it wasn't processed, and the updates were
6454 // scheduled before we entered the render phase.
6455 var hook = currentlyRenderingFiber$1.memoizedState;
6456
6457 while (hook !== null) {
6458 var queue = hook.queue;
6459
6460 if (queue !== null) {
6461 queue.pending = null;
6462 }
6463
6464 hook = hook.next;
6465 }
6466
6467 didScheduleRenderPhaseUpdate = false;
6468 }
6469
6470 renderLanes = NoLanes;
6471 currentlyRenderingFiber$1 = null;
6472 currentHook = null;
6473 workInProgressHook = null;
6474
6475 {
6476 hookTypesDev = null;
6477 hookTypesUpdateIndexDev = -1;
6478 currentHookNameInDev = null;
6479 isUpdatingOpaqueValueInRenderPhase = false;
6480 }
6481
6482 didScheduleRenderPhaseUpdateDuringThisPass = false;
6483}
6484
6485function mountWorkInProgressHook() {
6486 var hook = {
6487 memoizedState: null,
6488 baseState: null,
6489 baseQueue: null,
6490 queue: null,
6491 next: null
6492 };
6493
6494 if (workInProgressHook === null) {
6495 // This is the first hook in the list
6496 currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;
6497 } else {
6498 // Append to the end of the list
6499 workInProgressHook = workInProgressHook.next = hook;
6500 }
6501
6502 return workInProgressHook;
6503}
6504
6505function updateWorkInProgressHook() {
6506 // This function is used both for updates and for re-renders triggered by a
6507 // render phase update. It assumes there is either a current hook we can
6508 // clone, or a work-in-progress hook from a previous render pass that we can
6509 // use as a base. When we reach the end of the base list, we must switch to
6510 // the dispatcher used for mounts.
6511 var nextCurrentHook;
6512
6513 if (currentHook === null) {
6514 var current = currentlyRenderingFiber$1.alternate;
6515
6516 if (current !== null) {
6517 nextCurrentHook = current.memoizedState;
6518 } else {
6519 nextCurrentHook = null;
6520 }
6521 } else {
6522 nextCurrentHook = currentHook.next;
6523 }
6524
6525 var nextWorkInProgressHook;
6526
6527 if (workInProgressHook === null) {
6528 nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;
6529 } else {
6530 nextWorkInProgressHook = workInProgressHook.next;
6531 }
6532
6533 if (nextWorkInProgressHook !== null) {
6534 // There's already a work-in-progress. Reuse it.
6535 workInProgressHook = nextWorkInProgressHook;
6536 nextWorkInProgressHook = workInProgressHook.next;
6537 currentHook = nextCurrentHook;
6538 } else {
6539 // Clone from the current hook.
6540 if (nextCurrentHook === null) {
6541 throw new Error('Rendered more hooks than during the previous render.');
6542 }
6543
6544 currentHook = nextCurrentHook;
6545 var newHook = {
6546 memoizedState: currentHook.memoizedState,
6547 baseState: currentHook.baseState,
6548 baseQueue: currentHook.baseQueue,
6549 queue: currentHook.queue,
6550 next: null
6551 };
6552
6553 if (workInProgressHook === null) {
6554 // This is the first hook in the list.
6555 currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;
6556 } else {
6557 // Append to the end of the list.
6558 workInProgressHook = workInProgressHook.next = newHook;
6559 }
6560 }
6561
6562 return workInProgressHook;
6563}
6564
6565function createFunctionComponentUpdateQueue() {
6566 return {
6567 lastEffect: null,
6568 stores: null
6569 };
6570}
6571
6572function basicStateReducer(state, action) {
6573 // $FlowFixMe: Flow doesn't like mixed types
6574 return typeof action === 'function' ? action(state) : action;
6575}
6576
6577function mountReducer(reducer, initialArg, init) {
6578 var hook = mountWorkInProgressHook();
6579 var initialState;
6580
6581 if (init !== undefined) {
6582 initialState = init(initialArg);
6583 } else {
6584 initialState = initialArg;
6585 }
6586
6587 hook.memoizedState = hook.baseState = initialState;
6588 var queue = {
6589 pending: null,
6590 interleaved: null,
6591 lanes: NoLanes,
6592 dispatch: null,
6593 lastRenderedReducer: reducer,
6594 lastRenderedState: initialState
6595 };
6596 hook.queue = queue;
6597 var dispatch = queue.dispatch = dispatchReducerAction.bind(null, currentlyRenderingFiber$1, queue);
6598 return [hook.memoizedState, dispatch];
6599}
6600
6601function updateReducer(reducer, initialArg, init) {
6602 var hook = updateWorkInProgressHook();
6603 var queue = hook.queue;
6604
6605 if (queue === null) {
6606 throw new Error('Should have a queue. This is likely a bug in React. Please file an issue.');
6607 }
6608
6609 queue.lastRenderedReducer = reducer;
6610 var current = currentHook; // The last rebase update that is NOT part of the base state.
6611
6612 var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet.
6613
6614 var pendingQueue = queue.pending;
6615
6616 if (pendingQueue !== null) {
6617 // We have new updates that haven't been processed yet.
6618 // We'll add them to the base queue.
6619 if (baseQueue !== null) {
6620 // Merge the pending queue and the base queue.
6621 var baseFirst = baseQueue.next;
6622 var pendingFirst = pendingQueue.next;
6623 baseQueue.next = pendingFirst;
6624 pendingQueue.next = baseFirst;
6625 }
6626
6627 {
6628 if (current.baseQueue !== baseQueue) {
6629 // Internal invariant that should never happen, but feasibly could in
6630 // the future if we implement resuming, or some form of that.
6631 error('Internal error: Expected work-in-progress queue to be a clone. ' + 'This is a bug in React.');
6632 }
6633 }
6634
6635 current.baseQueue = baseQueue = pendingQueue;
6636 queue.pending = null;
6637 }
6638
6639 if (baseQueue !== null) {
6640 // We have a queue to process.
6641 var first = baseQueue.next;
6642 var newState = current.baseState;
6643 var newBaseState = null;
6644 var newBaseQueueFirst = null;
6645 var newBaseQueueLast = null;
6646 var update = first;
6647
6648 do {
6649 var updateLane = update.lane;
6650
6651 if (!isSubsetOfLanes(renderLanes, updateLane)) {
6652 // Priority is insufficient. Skip this update. If this is the first
6653 // skipped update, the previous update/state is the new base
6654 // update/state.
6655 var clone = {
6656 lane: updateLane,
6657 action: update.action,
6658 hasEagerState: update.hasEagerState,
6659 eagerState: update.eagerState,
6660 next: null
6661 };
6662
6663 if (newBaseQueueLast === null) {
6664 newBaseQueueFirst = newBaseQueueLast = clone;
6665 newBaseState = newState;
6666 } else {
6667 newBaseQueueLast = newBaseQueueLast.next = clone;
6668 } // Update the remaining priority in the queue.
6669 // TODO: Don't need to accumulate this. Instead, we can remove
6670 // renderLanes from the original lanes.
6671
6672
6673 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, updateLane);
6674 markSkippedUpdateLanes(updateLane);
6675 } else {
6676 // This update does have sufficient priority.
6677 if (newBaseQueueLast !== null) {
6678 var _clone = {
6679 // This update is going to be committed so we never want uncommit
6680 // it. Using NoLane works because 0 is a subset of all bitmasks, so
6681 // this will never be skipped by the check above.
6682 lane: NoLane,
6683 action: update.action,
6684 hasEagerState: update.hasEagerState,
6685 eagerState: update.eagerState,
6686 next: null
6687 };
6688 newBaseQueueLast = newBaseQueueLast.next = _clone;
6689 } // Process this update.
6690
6691
6692 if (update.hasEagerState) {
6693 // If this update is a state update (not a reducer) and was processed eagerly,
6694 // we can use the eagerly computed state
6695 newState = update.eagerState;
6696 } else {
6697 var action = update.action;
6698 newState = reducer(newState, action);
6699 }
6700 }
6701
6702 update = update.next;
6703 } while (update !== null && update !== first);
6704
6705 if (newBaseQueueLast === null) {
6706 newBaseState = newState;
6707 } else {
6708 newBaseQueueLast.next = newBaseQueueFirst;
6709 } // Mark that the fiber performed work, but only if the new state is
6710 // different from the current state.
6711
6712
6713 if (!objectIs(newState, hook.memoizedState)) {
6714 markWorkInProgressReceivedUpdate();
6715 }
6716
6717 hook.memoizedState = newState;
6718 hook.baseState = newBaseState;
6719 hook.baseQueue = newBaseQueueLast;
6720 queue.lastRenderedState = newState;
6721 } // Interleaved updates are stored on a separate queue. We aren't going to
6722 // process them during this render, but we do need to track which lanes
6723 // are remaining.
6724
6725
6726 var lastInterleaved = queue.interleaved;
6727
6728 if (lastInterleaved !== null) {
6729 var interleaved = lastInterleaved;
6730
6731 do {
6732 var interleavedLane = interleaved.lane;
6733 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, interleavedLane);
6734 markSkippedUpdateLanes(interleavedLane);
6735 interleaved = interleaved.next;
6736 } while (interleaved !== lastInterleaved);
6737 } else if (baseQueue === null) {
6738 // `queue.lanes` is used for entangling transitions. We can set it back to
6739 // zero once the queue is empty.
6740 queue.lanes = NoLanes;
6741 }
6742
6743 var dispatch = queue.dispatch;
6744 return [hook.memoizedState, dispatch];
6745}
6746
6747function rerenderReducer(reducer, initialArg, init) {
6748 var hook = updateWorkInProgressHook();
6749 var queue = hook.queue;
6750
6751 if (queue === null) {
6752 throw new Error('Should have a queue. This is likely a bug in React. Please file an issue.');
6753 }
6754
6755 queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous
6756 // work-in-progress hook.
6757
6758 var dispatch = queue.dispatch;
6759 var lastRenderPhaseUpdate = queue.pending;
6760 var newState = hook.memoizedState;
6761
6762 if (lastRenderPhaseUpdate !== null) {
6763 // The queue doesn't persist past this render pass.
6764 queue.pending = null;
6765 var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;
6766 var update = firstRenderPhaseUpdate;
6767
6768 do {
6769 // Process this render phase update. We don't have to check the
6770 // priority because it will always be the same as the current
6771 // render's.
6772 var action = update.action;
6773 newState = reducer(newState, action);
6774 update = update.next;
6775 } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is
6776 // different from the current state.
6777
6778
6779 if (!objectIs(newState, hook.memoizedState)) {
6780 markWorkInProgressReceivedUpdate();
6781 }
6782
6783 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
6784 // the base state unless the queue is empty.
6785 // TODO: Not sure if this is the desired semantics, but it's what we
6786 // do for gDSFP. I can't remember why.
6787
6788 if (hook.baseQueue === null) {
6789 hook.baseState = newState;
6790 }
6791
6792 queue.lastRenderedState = newState;
6793 }
6794
6795 return [newState, dispatch];
6796}
6797
6798function mountMutableSource(source, getSnapshot, subscribe) {
6799 {
6800 return undefined;
6801 }
6802}
6803
6804function updateMutableSource(source, getSnapshot, subscribe) {
6805 {
6806 return undefined;
6807 }
6808}
6809
6810function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
6811 var fiber = currentlyRenderingFiber$1;
6812 var hook = mountWorkInProgressHook();
6813 var nextSnapshot;
6814
6815 {
6816 nextSnapshot = getSnapshot();
6817
6818 {
6819 if (!didWarnUncachedGetSnapshot) {
6820 var cachedSnapshot = getSnapshot();
6821
6822 if (!objectIs(nextSnapshot, cachedSnapshot)) {
6823 error('The result of getSnapshot should be cached to avoid an infinite loop');
6824
6825 didWarnUncachedGetSnapshot = true;
6826 }
6827 }
6828 } // Unless we're rendering a blocking lane, schedule a consistency check.
6829 // Right before committing, we will walk the tree and check if any of the
6830 // stores were mutated.
6831 //
6832 // We won't do this if we're hydrating server-rendered content, because if
6833 // the content is stale, it's already visible anyway. Instead we'll patch
6834 // it up in a passive effect.
6835
6836
6837 var root = getWorkInProgressRoot();
6838
6839 if (root === null) {
6840 throw new Error('Expected a work-in-progress root. This is a bug in React. Please file an issue.');
6841 }
6842
6843 if (!includesBlockingLane(root, renderLanes)) {
6844 pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
6845 }
6846 } // Read the current snapshot from the store on every render. This breaks the
6847 // normal rules of React, and only works because store updates are
6848 // always synchronous.
6849
6850
6851 hook.memoizedState = nextSnapshot;
6852 var inst = {
6853 value: nextSnapshot,
6854 getSnapshot: getSnapshot
6855 };
6856 hook.queue = inst; // Schedule an effect to subscribe to the store.
6857
6858 mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]); // Schedule an effect to update the mutable instance fields. We will update
6859 // this whenever subscribe, getSnapshot, or value changes. Because there's no
6860 // clean-up function, and we track the deps correctly, we can call pushEffect
6861 // directly, without storing any additional state. For the same reason, we
6862 // don't need to set a static flag, either.
6863 // TODO: We can move this to the passive phase once we add a pre-commit
6864 // consistency check. See the next comment.
6865
6866 fiber.flags |= Passive;
6867 pushEffect(HasEffect | Passive$1, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), undefined, null);
6868 return nextSnapshot;
6869}
6870
6871function updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
6872 var fiber = currentlyRenderingFiber$1;
6873 var hook = updateWorkInProgressHook(); // Read the current snapshot from the store on every render. This breaks the
6874 // normal rules of React, and only works because store updates are
6875 // always synchronous.
6876
6877 var nextSnapshot = getSnapshot();
6878
6879 {
6880 if (!didWarnUncachedGetSnapshot) {
6881 var cachedSnapshot = getSnapshot();
6882
6883 if (!objectIs(nextSnapshot, cachedSnapshot)) {
6884 error('The result of getSnapshot should be cached to avoid an infinite loop');
6885
6886 didWarnUncachedGetSnapshot = true;
6887 }
6888 }
6889 }
6890
6891 var prevSnapshot = hook.memoizedState;
6892 var snapshotChanged = !objectIs(prevSnapshot, nextSnapshot);
6893
6894 if (snapshotChanged) {
6895 hook.memoizedState = nextSnapshot;
6896 markWorkInProgressReceivedUpdate();
6897 }
6898
6899 var inst = hook.queue;
6900 updateEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]); // Whenever getSnapshot or subscribe changes, we need to check in the
6901 // commit phase if there was an interleaved mutation. In concurrent mode
6902 // this can happen all the time, but even in synchronous mode, an earlier
6903 // effect may have mutated the store.
6904
6905 if (inst.getSnapshot !== getSnapshot || snapshotChanged || // Check if the susbcribe function changed. We can save some memory by
6906 // checking whether we scheduled a subscription effect above.
6907 workInProgressHook !== null && workInProgressHook.memoizedState.tag & HasEffect) {
6908 fiber.flags |= Passive;
6909 pushEffect(HasEffect | Passive$1, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), undefined, null); // Unless we're rendering a blocking lane, schedule a consistency check.
6910 // Right before committing, we will walk the tree and check if any of the
6911 // stores were mutated.
6912
6913 var root = getWorkInProgressRoot();
6914
6915 if (root === null) {
6916 throw new Error('Expected a work-in-progress root. This is a bug in React. Please file an issue.');
6917 }
6918
6919 if (!includesBlockingLane(root, renderLanes)) {
6920 pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
6921 }
6922 }
6923
6924 return nextSnapshot;
6925}
6926
6927function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) {
6928 fiber.flags |= StoreConsistency;
6929 var check = {
6930 getSnapshot: getSnapshot,
6931 value: renderedSnapshot
6932 };
6933 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
6934
6935 if (componentUpdateQueue === null) {
6936 componentUpdateQueue = createFunctionComponentUpdateQueue();
6937 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
6938 componentUpdateQueue.stores = [check];
6939 } else {
6940 var stores = componentUpdateQueue.stores;
6941
6942 if (stores === null) {
6943 componentUpdateQueue.stores = [check];
6944 } else {
6945 stores.push(check);
6946 }
6947 }
6948}
6949
6950function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) {
6951 // These are updated in the passive phase
6952 inst.value = nextSnapshot;
6953 inst.getSnapshot = getSnapshot; // Something may have been mutated in between render and commit. This could
6954 // have been in an event that fired before the passive effects, or it could
6955 // have been in a layout effect. In that case, we would have used the old
6956 // snapsho and getSnapshot values to bail out. We need to check one more time.
6957
6958 if (checkIfSnapshotChanged(inst)) {
6959 // Force a re-render.
6960 forceStoreRerender(fiber);
6961 }
6962}
6963
6964function subscribeToStore(fiber, inst, subscribe) {
6965 var handleStoreChange = function () {
6966 // The store changed. Check if the snapshot changed since the last time we
6967 // read from the store.
6968 if (checkIfSnapshotChanged(inst)) {
6969 // Force a re-render.
6970 forceStoreRerender(fiber);
6971 }
6972 }; // Subscribe to the store and return a clean-up function.
6973
6974
6975 return subscribe(handleStoreChange);
6976}
6977
6978function checkIfSnapshotChanged(inst) {
6979 var latestGetSnapshot = inst.getSnapshot;
6980 var prevValue = inst.value;
6981
6982 try {
6983 var nextValue = latestGetSnapshot();
6984 return !objectIs(prevValue, nextValue);
6985 } catch (error) {
6986 return true;
6987 }
6988}
6989
6990function forceStoreRerender(fiber) {
6991 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
6992
6993 if (root !== null) {
6994 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
6995 }
6996}
6997
6998function mountState(initialState) {
6999 var hook = mountWorkInProgressHook();
7000
7001 if (typeof initialState === 'function') {
7002 // $FlowFixMe: Flow doesn't like mixed types
7003 initialState = initialState();
7004 }
7005
7006 hook.memoizedState = hook.baseState = initialState;
7007 var queue = {
7008 pending: null,
7009 interleaved: null,
7010 lanes: NoLanes,
7011 dispatch: null,
7012 lastRenderedReducer: basicStateReducer,
7013 lastRenderedState: initialState
7014 };
7015 hook.queue = queue;
7016 var dispatch = queue.dispatch = dispatchSetState.bind(null, currentlyRenderingFiber$1, queue);
7017 return [hook.memoizedState, dispatch];
7018}
7019
7020function updateState(initialState) {
7021 return updateReducer(basicStateReducer);
7022}
7023
7024function rerenderState(initialState) {
7025 return rerenderReducer(basicStateReducer);
7026}
7027
7028function pushEffect(tag, create, destroy, deps) {
7029 var effect = {
7030 tag: tag,
7031 create: create,
7032 destroy: destroy,
7033 deps: deps,
7034 // Circular
7035 next: null
7036 };
7037 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
7038
7039 if (componentUpdateQueue === null) {
7040 componentUpdateQueue = createFunctionComponentUpdateQueue();
7041 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
7042 componentUpdateQueue.lastEffect = effect.next = effect;
7043 } else {
7044 var lastEffect = componentUpdateQueue.lastEffect;
7045
7046 if (lastEffect === null) {
7047 componentUpdateQueue.lastEffect = effect.next = effect;
7048 } else {
7049 var firstEffect = lastEffect.next;
7050 lastEffect.next = effect;
7051 effect.next = firstEffect;
7052 componentUpdateQueue.lastEffect = effect;
7053 }
7054 }
7055
7056 return effect;
7057}
7058
7059function mountRef(initialValue) {
7060 var hook = mountWorkInProgressHook();
7061
7062 {
7063 var _ref2 = {
7064 current: initialValue
7065 };
7066 hook.memoizedState = _ref2;
7067 return _ref2;
7068 }
7069}
7070
7071function updateRef(initialValue) {
7072 var hook = updateWorkInProgressHook();
7073 return hook.memoizedState;
7074}
7075
7076function mountEffectImpl(fiberFlags, hookFlags, create, deps) {
7077 var hook = mountWorkInProgressHook();
7078 var nextDeps = deps === undefined ? null : deps;
7079 currentlyRenderingFiber$1.flags |= fiberFlags;
7080 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, undefined, nextDeps);
7081}
7082
7083function updateEffectImpl(fiberFlags, hookFlags, create, deps) {
7084 var hook = updateWorkInProgressHook();
7085 var nextDeps = deps === undefined ? null : deps;
7086 var destroy = undefined;
7087
7088 if (currentHook !== null) {
7089 var prevEffect = currentHook.memoizedState;
7090 destroy = prevEffect.destroy;
7091
7092 if (nextDeps !== null) {
7093 var prevDeps = prevEffect.deps;
7094
7095 if (areHookInputsEqual(nextDeps, prevDeps)) {
7096 hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps);
7097 return;
7098 }
7099 }
7100 }
7101
7102 currentlyRenderingFiber$1.flags |= fiberFlags;
7103 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, destroy, nextDeps);
7104}
7105
7106function mountEffect(create, deps) {
7107 {
7108 return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps);
7109 }
7110}
7111
7112function updateEffect(create, deps) {
7113 return updateEffectImpl(Passive, Passive$1, create, deps);
7114}
7115
7116function mountInsertionEffect(create, deps) {
7117 return mountEffectImpl(Update, Insertion, create, deps);
7118}
7119
7120function updateInsertionEffect(create, deps) {
7121 return updateEffectImpl(Update, Insertion, create, deps);
7122}
7123
7124function mountLayoutEffect(create, deps) {
7125 var fiberFlags = Update;
7126
7127 return mountEffectImpl(fiberFlags, Layout, create, deps);
7128}
7129
7130function updateLayoutEffect(create, deps) {
7131 return updateEffectImpl(Update, Layout, create, deps);
7132}
7133
7134function imperativeHandleEffect(create, ref) {
7135 if (typeof ref === 'function') {
7136 var refCallback = ref;
7137
7138 var _inst = create();
7139
7140 refCallback(_inst);
7141 return function () {
7142 refCallback(null);
7143 };
7144 } else if (ref !== null && ref !== undefined) {
7145 var refObject = ref;
7146
7147 {
7148 if (!refObject.hasOwnProperty('current')) {
7149 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(', ') + '}');
7150 }
7151 }
7152
7153 var _inst2 = create();
7154
7155 refObject.current = _inst2;
7156 return function () {
7157 refObject.current = null;
7158 };
7159 }
7160}
7161
7162function mountImperativeHandle(ref, create, deps) {
7163 {
7164 if (typeof create !== 'function') {
7165 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
7166 }
7167 } // TODO: If deps are provided, should we skip comparing the ref itself?
7168
7169
7170 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
7171 var fiberFlags = Update;
7172
7173 return mountEffectImpl(fiberFlags, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
7174}
7175
7176function updateImperativeHandle(ref, create, deps) {
7177 {
7178 if (typeof create !== 'function') {
7179 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
7180 }
7181 } // TODO: If deps are provided, should we skip comparing the ref itself?
7182
7183
7184 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
7185 return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
7186}
7187
7188function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.
7189 // The react-debug-hooks package injects its own implementation
7190 // so that e.g. DevTools can display custom hook values.
7191}
7192
7193var updateDebugValue = mountDebugValue;
7194
7195function mountCallback(callback, deps) {
7196 var hook = mountWorkInProgressHook();
7197 var nextDeps = deps === undefined ? null : deps;
7198 hook.memoizedState = [callback, nextDeps];
7199 return callback;
7200}
7201
7202function updateCallback(callback, deps) {
7203 var hook = updateWorkInProgressHook();
7204 var nextDeps = deps === undefined ? null : deps;
7205 var prevState = hook.memoizedState;
7206
7207 if (prevState !== null) {
7208 if (nextDeps !== null) {
7209 var prevDeps = prevState[1];
7210
7211 if (areHookInputsEqual(nextDeps, prevDeps)) {
7212 return prevState[0];
7213 }
7214 }
7215 }
7216
7217 hook.memoizedState = [callback, nextDeps];
7218 return callback;
7219}
7220
7221function mountMemo(nextCreate, deps) {
7222 var hook = mountWorkInProgressHook();
7223 var nextDeps = deps === undefined ? null : deps;
7224 var nextValue = nextCreate();
7225 hook.memoizedState = [nextValue, nextDeps];
7226 return nextValue;
7227}
7228
7229function updateMemo(nextCreate, deps) {
7230 var hook = updateWorkInProgressHook();
7231 var nextDeps = deps === undefined ? null : deps;
7232 var prevState = hook.memoizedState;
7233
7234 if (prevState !== null) {
7235 // Assume these are defined. If they're not, areHookInputsEqual will warn.
7236 if (nextDeps !== null) {
7237 var prevDeps = prevState[1];
7238
7239 if (areHookInputsEqual(nextDeps, prevDeps)) {
7240 return prevState[0];
7241 }
7242 }
7243 }
7244
7245 var nextValue = nextCreate();
7246 hook.memoizedState = [nextValue, nextDeps];
7247 return nextValue;
7248}
7249
7250function mountDeferredValue(value) {
7251 var hook = mountWorkInProgressHook();
7252 hook.memoizedState = value;
7253 return value;
7254}
7255
7256function updateDeferredValue(value) {
7257 var hook = updateWorkInProgressHook();
7258 var resolvedCurrentHook = currentHook;
7259 var prevValue = resolvedCurrentHook.memoizedState;
7260 return updateDeferredValueImpl(hook, prevValue, value);
7261}
7262
7263function rerenderDeferredValue(value) {
7264 var hook = updateWorkInProgressHook();
7265
7266 if (currentHook === null) {
7267 // This is a rerender during a mount.
7268 hook.memoizedState = value;
7269 return value;
7270 } else {
7271 // This is a rerender during an update.
7272 var prevValue = currentHook.memoizedState;
7273 return updateDeferredValueImpl(hook, prevValue, value);
7274 }
7275}
7276
7277function updateDeferredValueImpl(hook, prevValue, value) {
7278 var shouldDeferValue = !includesOnlyNonUrgentLanes(renderLanes);
7279
7280 if (shouldDeferValue) {
7281 // This is an urgent update. If the value has changed, keep using the
7282 // previous value and spawn a deferred render to update it later.
7283 if (!objectIs(value, prevValue)) {
7284 // Schedule a deferred render
7285 var deferredLane = claimNextTransitionLane();
7286 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, deferredLane);
7287 markSkippedUpdateLanes(deferredLane); // Set this to true to indicate that the rendered value is inconsistent
7288 // from the latest value. The name "baseState" doesn't really match how we
7289 // use it because we're reusing a state hook field instead of creating a
7290 // new one.
7291
7292 hook.baseState = true;
7293 } // Reuse the previous value
7294
7295
7296 return prevValue;
7297 } else {
7298 // This is not an urgent update, so we can use the latest value regardless
7299 // of what it is. No need to defer it.
7300 // However, if we're currently inside a spawned render, then we need to mark
7301 // this as an update to prevent the fiber from bailing out.
7302 //
7303 // `baseState` is true when the current value is different from the rendered
7304 // value. The name doesn't really match how we use it because we're reusing
7305 // a state hook field instead of creating a new one.
7306 if (hook.baseState) {
7307 // Flip this back to false.
7308 hook.baseState = false;
7309 markWorkInProgressReceivedUpdate();
7310 }
7311
7312 hook.memoizedState = value;
7313 return value;
7314 }
7315}
7316
7317function startTransition(setPending, callback, options) {
7318 var previousPriority = getCurrentUpdatePriority();
7319 setCurrentUpdatePriority(higherEventPriority(previousPriority, ContinuousEventPriority));
7320 setPending(true);
7321 var prevTransition = ReactCurrentBatchConfig$1.transition;
7322 ReactCurrentBatchConfig$1.transition = {};
7323 var currentTransition = ReactCurrentBatchConfig$1.transition;
7324
7325 {
7326 ReactCurrentBatchConfig$1.transition._updatedFibers = new Set();
7327 }
7328
7329 try {
7330 setPending(false);
7331 callback();
7332 } finally {
7333 setCurrentUpdatePriority(previousPriority);
7334 ReactCurrentBatchConfig$1.transition = prevTransition;
7335
7336 {
7337 if (prevTransition === null && currentTransition._updatedFibers) {
7338 var updatedFibersCount = currentTransition._updatedFibers.size;
7339
7340 if (updatedFibersCount > 10) {
7341 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.');
7342 }
7343
7344 currentTransition._updatedFibers.clear();
7345 }
7346 }
7347 }
7348}
7349
7350function mountTransition() {
7351 var _mountState = mountState(false),
7352 isPending = _mountState[0],
7353 setPending = _mountState[1]; // The `start` method never changes.
7354
7355
7356 var start = startTransition.bind(null, setPending);
7357 var hook = mountWorkInProgressHook();
7358 hook.memoizedState = start;
7359 return [isPending, start];
7360}
7361
7362function updateTransition() {
7363 var _updateState = updateState(),
7364 isPending = _updateState[0];
7365
7366 var hook = updateWorkInProgressHook();
7367 var start = hook.memoizedState;
7368 return [isPending, start];
7369}
7370
7371function rerenderTransition() {
7372 var _rerenderState = rerenderState(),
7373 isPending = _rerenderState[0];
7374
7375 var hook = updateWorkInProgressHook();
7376 var start = hook.memoizedState;
7377 return [isPending, start];
7378}
7379
7380var isUpdatingOpaqueValueInRenderPhase = false;
7381function getIsUpdatingOpaqueValueInRenderPhaseInDEV() {
7382 {
7383 return isUpdatingOpaqueValueInRenderPhase;
7384 }
7385}
7386
7387function mountId() {
7388 var hook = mountWorkInProgressHook();
7389 var root = getWorkInProgressRoot(); // TODO: In Fizz, id generation is specific to each server config. Maybe we
7390 // should do this in Fiber, too? Deferring this decision for now because
7391 // there's no other place to store the prefix except for an internal field on
7392 // the public createRoot object, which the fiber tree does not currently have
7393 // a reference to.
7394
7395 var identifierPrefix = root.identifierPrefix;
7396 var id;
7397
7398 {
7399 // Use a lowercase r prefix for client-generated ids.
7400 var globalClientId = globalClientIdCounter++;
7401 id = ':' + identifierPrefix + 'r' + globalClientId.toString(32) + ':';
7402 }
7403
7404 hook.memoizedState = id;
7405 return id;
7406}
7407
7408function updateId() {
7409 var hook = updateWorkInProgressHook();
7410 var id = hook.memoizedState;
7411 return id;
7412}
7413
7414function dispatchReducerAction(fiber, queue, action) {
7415 {
7416 if (typeof arguments[3] === 'function') {
7417 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().');
7418 }
7419 }
7420
7421 var lane = requestUpdateLane(fiber);
7422 var update = {
7423 lane: lane,
7424 action: action,
7425 hasEagerState: false,
7426 eagerState: null,
7427 next: null
7428 };
7429
7430 if (isRenderPhaseUpdate(fiber)) {
7431 enqueueRenderPhaseUpdate(queue, update);
7432 } else {
7433 var root = enqueueConcurrentHookUpdate(fiber, queue, update, lane);
7434
7435 if (root !== null) {
7436 var eventTime = requestEventTime();
7437 scheduleUpdateOnFiber(root, fiber, lane, eventTime);
7438 entangleTransitionUpdate(root, queue, lane);
7439 }
7440 }
7441}
7442
7443function dispatchSetState(fiber, queue, action) {
7444 {
7445 if (typeof arguments[3] === 'function') {
7446 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().');
7447 }
7448 }
7449
7450 var lane = requestUpdateLane(fiber);
7451 var update = {
7452 lane: lane,
7453 action: action,
7454 hasEagerState: false,
7455 eagerState: null,
7456 next: null
7457 };
7458
7459 if (isRenderPhaseUpdate(fiber)) {
7460 enqueueRenderPhaseUpdate(queue, update);
7461 } else {
7462 var alternate = fiber.alternate;
7463
7464 if (fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes)) {
7465 // The queue is currently empty, which means we can eagerly compute the
7466 // next state before entering the render phase. If the new state is the
7467 // same as the current state, we may be able to bail out entirely.
7468 var lastRenderedReducer = queue.lastRenderedReducer;
7469
7470 if (lastRenderedReducer !== null) {
7471 var prevDispatcher;
7472
7473 {
7474 prevDispatcher = ReactCurrentDispatcher$1.current;
7475 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7476 }
7477
7478 try {
7479 var currentState = queue.lastRenderedState;
7480 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
7481 // it, on the update object. If the reducer hasn't changed by the
7482 // time we enter the render phase, then the eager state can be used
7483 // without calling the reducer again.
7484
7485 update.hasEagerState = true;
7486 update.eagerState = eagerState;
7487
7488 if (objectIs(eagerState, currentState)) {
7489 // Fast path. We can bail out without scheduling React to re-render.
7490 // It's still possible that we'll need to rebase this update later,
7491 // if the component re-renders for a different reason and by that
7492 // time the reducer has changed.
7493 // TODO: Do we still need to entangle transitions in this case?
7494 enqueueConcurrentHookUpdateAndEagerlyBailout(fiber, queue, update, lane);
7495 return;
7496 }
7497 } catch (error) {// Suppress the error. It will throw again in the render phase.
7498 } finally {
7499 {
7500 ReactCurrentDispatcher$1.current = prevDispatcher;
7501 }
7502 }
7503 }
7504 }
7505
7506 var root = enqueueConcurrentHookUpdate(fiber, queue, update, lane);
7507
7508 if (root !== null) {
7509 var eventTime = requestEventTime();
7510 scheduleUpdateOnFiber(root, fiber, lane, eventTime);
7511 entangleTransitionUpdate(root, queue, lane);
7512 }
7513 }
7514}
7515
7516function isRenderPhaseUpdate(fiber) {
7517 var alternate = fiber.alternate;
7518 return fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1;
7519}
7520
7521function enqueueRenderPhaseUpdate(queue, update) {
7522 // This is a render phase update. Stash it in a lazily-created map of
7523 // queue -> linked list of updates. After this render pass, we'll restart
7524 // and apply the stashed updates on top of the work-in-progress hook.
7525 didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true;
7526 var pending = queue.pending;
7527
7528 if (pending === null) {
7529 // This is the first update. Create a circular list.
7530 update.next = update;
7531 } else {
7532 update.next = pending.next;
7533 pending.next = update;
7534 }
7535
7536 queue.pending = update;
7537} // TODO: Move to ReactFiberConcurrentUpdates?
7538
7539
7540function entangleTransitionUpdate(root, queue, lane) {
7541 if (isTransitionLane(lane)) {
7542 var queueLanes = queue.lanes; // If any entangled lanes are no longer pending on the root, then they
7543 // must have finished. We can remove them from the shared queue, which
7544 // represents a superset of the actually pending lanes. In some cases we
7545 // may entangle more than we need to, but that's OK. In fact it's worse if
7546 // we *don't* entangle when we should.
7547
7548 queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes.
7549
7550 var newQueueLanes = mergeLanes(queueLanes, lane);
7551 queue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if
7552 // the lane finished since the last time we entangled it. So we need to
7553 // entangle it again, just to be sure.
7554
7555 markRootEntangled(root, newQueueLanes);
7556 }
7557}
7558
7559var ContextOnlyDispatcher = {
7560 readContext: readContext,
7561 useCallback: throwInvalidHookError,
7562 useContext: throwInvalidHookError,
7563 useEffect: throwInvalidHookError,
7564 useImperativeHandle: throwInvalidHookError,
7565 useInsertionEffect: throwInvalidHookError,
7566 useLayoutEffect: throwInvalidHookError,
7567 useMemo: throwInvalidHookError,
7568 useReducer: throwInvalidHookError,
7569 useRef: throwInvalidHookError,
7570 useState: throwInvalidHookError,
7571 useDebugValue: throwInvalidHookError,
7572 useDeferredValue: throwInvalidHookError,
7573 useTransition: throwInvalidHookError,
7574 useMutableSource: throwInvalidHookError,
7575 useSyncExternalStore: throwInvalidHookError,
7576 useId: throwInvalidHookError,
7577 unstable_isNewReconciler: enableNewReconciler
7578};
7579
7580var HooksDispatcherOnMountInDEV = null;
7581var HooksDispatcherOnMountWithHookTypesInDEV = null;
7582var HooksDispatcherOnUpdateInDEV = null;
7583var HooksDispatcherOnRerenderInDEV = null;
7584var InvalidNestedHooksDispatcherOnMountInDEV = null;
7585var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
7586var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
7587
7588{
7589 var warnInvalidContextAccess = function () {
7590 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().');
7591 };
7592
7593 var warnInvalidHookAccess = function () {
7594 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');
7595 };
7596
7597 HooksDispatcherOnMountInDEV = {
7598 readContext: function (context) {
7599 return readContext(context);
7600 },
7601 useCallback: function (callback, deps) {
7602 currentHookNameInDev = 'useCallback';
7603 mountHookTypesDev();
7604 checkDepsAreArrayDev(deps);
7605 return mountCallback(callback, deps);
7606 },
7607 useContext: function (context) {
7608 currentHookNameInDev = 'useContext';
7609 mountHookTypesDev();
7610 return readContext(context);
7611 },
7612 useEffect: function (create, deps) {
7613 currentHookNameInDev = 'useEffect';
7614 mountHookTypesDev();
7615 checkDepsAreArrayDev(deps);
7616 return mountEffect(create, deps);
7617 },
7618 useImperativeHandle: function (ref, create, deps) {
7619 currentHookNameInDev = 'useImperativeHandle';
7620 mountHookTypesDev();
7621 checkDepsAreArrayDev(deps);
7622 return mountImperativeHandle(ref, create, deps);
7623 },
7624 useInsertionEffect: function (create, deps) {
7625 currentHookNameInDev = 'useInsertionEffect';
7626 mountHookTypesDev();
7627 checkDepsAreArrayDev(deps);
7628 return mountInsertionEffect(create, deps);
7629 },
7630 useLayoutEffect: function (create, deps) {
7631 currentHookNameInDev = 'useLayoutEffect';
7632 mountHookTypesDev();
7633 checkDepsAreArrayDev(deps);
7634 return mountLayoutEffect(create, deps);
7635 },
7636 useMemo: function (create, deps) {
7637 currentHookNameInDev = 'useMemo';
7638 mountHookTypesDev();
7639 checkDepsAreArrayDev(deps);
7640 var prevDispatcher = ReactCurrentDispatcher$1.current;
7641 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7642
7643 try {
7644 return mountMemo(create, deps);
7645 } finally {
7646 ReactCurrentDispatcher$1.current = prevDispatcher;
7647 }
7648 },
7649 useReducer: function (reducer, initialArg, init) {
7650 currentHookNameInDev = 'useReducer';
7651 mountHookTypesDev();
7652 var prevDispatcher = ReactCurrentDispatcher$1.current;
7653 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7654
7655 try {
7656 return mountReducer(reducer, initialArg, init);
7657 } finally {
7658 ReactCurrentDispatcher$1.current = prevDispatcher;
7659 }
7660 },
7661 useRef: function (initialValue) {
7662 currentHookNameInDev = 'useRef';
7663 mountHookTypesDev();
7664 return mountRef(initialValue);
7665 },
7666 useState: function (initialState) {
7667 currentHookNameInDev = 'useState';
7668 mountHookTypesDev();
7669 var prevDispatcher = ReactCurrentDispatcher$1.current;
7670 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7671
7672 try {
7673 return mountState(initialState);
7674 } finally {
7675 ReactCurrentDispatcher$1.current = prevDispatcher;
7676 }
7677 },
7678 useDebugValue: function (value, formatterFn) {
7679 currentHookNameInDev = 'useDebugValue';
7680 mountHookTypesDev();
7681 return mountDebugValue();
7682 },
7683 useDeferredValue: function (value) {
7684 currentHookNameInDev = 'useDeferredValue';
7685 mountHookTypesDev();
7686 return mountDeferredValue(value);
7687 },
7688 useTransition: function () {
7689 currentHookNameInDev = 'useTransition';
7690 mountHookTypesDev();
7691 return mountTransition();
7692 },
7693 useMutableSource: function (source, getSnapshot, subscribe) {
7694 currentHookNameInDev = 'useMutableSource';
7695 mountHookTypesDev();
7696 return mountMutableSource();
7697 },
7698 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
7699 currentHookNameInDev = 'useSyncExternalStore';
7700 mountHookTypesDev();
7701 return mountSyncExternalStore(subscribe, getSnapshot);
7702 },
7703 useId: function () {
7704 currentHookNameInDev = 'useId';
7705 mountHookTypesDev();
7706 return mountId();
7707 },
7708 unstable_isNewReconciler: enableNewReconciler
7709 };
7710
7711 HooksDispatcherOnMountWithHookTypesInDEV = {
7712 readContext: function (context) {
7713 return readContext(context);
7714 },
7715 useCallback: function (callback, deps) {
7716 currentHookNameInDev = 'useCallback';
7717 updateHookTypesDev();
7718 return mountCallback(callback, deps);
7719 },
7720 useContext: function (context) {
7721 currentHookNameInDev = 'useContext';
7722 updateHookTypesDev();
7723 return readContext(context);
7724 },
7725 useEffect: function (create, deps) {
7726 currentHookNameInDev = 'useEffect';
7727 updateHookTypesDev();
7728 return mountEffect(create, deps);
7729 },
7730 useImperativeHandle: function (ref, create, deps) {
7731 currentHookNameInDev = 'useImperativeHandle';
7732 updateHookTypesDev();
7733 return mountImperativeHandle(ref, create, deps);
7734 },
7735 useInsertionEffect: function (create, deps) {
7736 currentHookNameInDev = 'useInsertionEffect';
7737 updateHookTypesDev();
7738 return mountInsertionEffect(create, deps);
7739 },
7740 useLayoutEffect: function (create, deps) {
7741 currentHookNameInDev = 'useLayoutEffect';
7742 updateHookTypesDev();
7743 return mountLayoutEffect(create, deps);
7744 },
7745 useMemo: function (create, deps) {
7746 currentHookNameInDev = 'useMemo';
7747 updateHookTypesDev();
7748 var prevDispatcher = ReactCurrentDispatcher$1.current;
7749 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7750
7751 try {
7752 return mountMemo(create, deps);
7753 } finally {
7754 ReactCurrentDispatcher$1.current = prevDispatcher;
7755 }
7756 },
7757 useReducer: function (reducer, initialArg, init) {
7758 currentHookNameInDev = 'useReducer';
7759 updateHookTypesDev();
7760 var prevDispatcher = ReactCurrentDispatcher$1.current;
7761 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7762
7763 try {
7764 return mountReducer(reducer, initialArg, init);
7765 } finally {
7766 ReactCurrentDispatcher$1.current = prevDispatcher;
7767 }
7768 },
7769 useRef: function (initialValue) {
7770 currentHookNameInDev = 'useRef';
7771 updateHookTypesDev();
7772 return mountRef(initialValue);
7773 },
7774 useState: function (initialState) {
7775 currentHookNameInDev = 'useState';
7776 updateHookTypesDev();
7777 var prevDispatcher = ReactCurrentDispatcher$1.current;
7778 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7779
7780 try {
7781 return mountState(initialState);
7782 } finally {
7783 ReactCurrentDispatcher$1.current = prevDispatcher;
7784 }
7785 },
7786 useDebugValue: function (value, formatterFn) {
7787 currentHookNameInDev = 'useDebugValue';
7788 updateHookTypesDev();
7789 return mountDebugValue();
7790 },
7791 useDeferredValue: function (value) {
7792 currentHookNameInDev = 'useDeferredValue';
7793 updateHookTypesDev();
7794 return mountDeferredValue(value);
7795 },
7796 useTransition: function () {
7797 currentHookNameInDev = 'useTransition';
7798 updateHookTypesDev();
7799 return mountTransition();
7800 },
7801 useMutableSource: function (source, getSnapshot, subscribe) {
7802 currentHookNameInDev = 'useMutableSource';
7803 updateHookTypesDev();
7804 return mountMutableSource();
7805 },
7806 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
7807 currentHookNameInDev = 'useSyncExternalStore';
7808 updateHookTypesDev();
7809 return mountSyncExternalStore(subscribe, getSnapshot);
7810 },
7811 useId: function () {
7812 currentHookNameInDev = 'useId';
7813 updateHookTypesDev();
7814 return mountId();
7815 },
7816 unstable_isNewReconciler: enableNewReconciler
7817 };
7818
7819 HooksDispatcherOnUpdateInDEV = {
7820 readContext: function (context) {
7821 return readContext(context);
7822 },
7823 useCallback: function (callback, deps) {
7824 currentHookNameInDev = 'useCallback';
7825 updateHookTypesDev();
7826 return updateCallback(callback, deps);
7827 },
7828 useContext: function (context) {
7829 currentHookNameInDev = 'useContext';
7830 updateHookTypesDev();
7831 return readContext(context);
7832 },
7833 useEffect: function (create, deps) {
7834 currentHookNameInDev = 'useEffect';
7835 updateHookTypesDev();
7836 return updateEffect(create, deps);
7837 },
7838 useImperativeHandle: function (ref, create, deps) {
7839 currentHookNameInDev = 'useImperativeHandle';
7840 updateHookTypesDev();
7841 return updateImperativeHandle(ref, create, deps);
7842 },
7843 useInsertionEffect: function (create, deps) {
7844 currentHookNameInDev = 'useInsertionEffect';
7845 updateHookTypesDev();
7846 return updateInsertionEffect(create, deps);
7847 },
7848 useLayoutEffect: function (create, deps) {
7849 currentHookNameInDev = 'useLayoutEffect';
7850 updateHookTypesDev();
7851 return updateLayoutEffect(create, deps);
7852 },
7853 useMemo: function (create, deps) {
7854 currentHookNameInDev = 'useMemo';
7855 updateHookTypesDev();
7856 var prevDispatcher = ReactCurrentDispatcher$1.current;
7857 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7858
7859 try {
7860 return updateMemo(create, deps);
7861 } finally {
7862 ReactCurrentDispatcher$1.current = prevDispatcher;
7863 }
7864 },
7865 useReducer: function (reducer, initialArg, init) {
7866 currentHookNameInDev = 'useReducer';
7867 updateHookTypesDev();
7868 var prevDispatcher = ReactCurrentDispatcher$1.current;
7869 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7870
7871 try {
7872 return updateReducer(reducer, initialArg, init);
7873 } finally {
7874 ReactCurrentDispatcher$1.current = prevDispatcher;
7875 }
7876 },
7877 useRef: function (initialValue) {
7878 currentHookNameInDev = 'useRef';
7879 updateHookTypesDev();
7880 return updateRef();
7881 },
7882 useState: function (initialState) {
7883 currentHookNameInDev = 'useState';
7884 updateHookTypesDev();
7885 var prevDispatcher = ReactCurrentDispatcher$1.current;
7886 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7887
7888 try {
7889 return updateState(initialState);
7890 } finally {
7891 ReactCurrentDispatcher$1.current = prevDispatcher;
7892 }
7893 },
7894 useDebugValue: function (value, formatterFn) {
7895 currentHookNameInDev = 'useDebugValue';
7896 updateHookTypesDev();
7897 return updateDebugValue();
7898 },
7899 useDeferredValue: function (value) {
7900 currentHookNameInDev = 'useDeferredValue';
7901 updateHookTypesDev();
7902 return updateDeferredValue(value);
7903 },
7904 useTransition: function () {
7905 currentHookNameInDev = 'useTransition';
7906 updateHookTypesDev();
7907 return updateTransition();
7908 },
7909 useMutableSource: function (source, getSnapshot, subscribe) {
7910 currentHookNameInDev = 'useMutableSource';
7911 updateHookTypesDev();
7912 return updateMutableSource();
7913 },
7914 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
7915 currentHookNameInDev = 'useSyncExternalStore';
7916 updateHookTypesDev();
7917 return updateSyncExternalStore(subscribe, getSnapshot);
7918 },
7919 useId: function () {
7920 currentHookNameInDev = 'useId';
7921 updateHookTypesDev();
7922 return updateId();
7923 },
7924 unstable_isNewReconciler: enableNewReconciler
7925 };
7926
7927 HooksDispatcherOnRerenderInDEV = {
7928 readContext: function (context) {
7929 return readContext(context);
7930 },
7931 useCallback: function (callback, deps) {
7932 currentHookNameInDev = 'useCallback';
7933 updateHookTypesDev();
7934 return updateCallback(callback, deps);
7935 },
7936 useContext: function (context) {
7937 currentHookNameInDev = 'useContext';
7938 updateHookTypesDev();
7939 return readContext(context);
7940 },
7941 useEffect: function (create, deps) {
7942 currentHookNameInDev = 'useEffect';
7943 updateHookTypesDev();
7944 return updateEffect(create, deps);
7945 },
7946 useImperativeHandle: function (ref, create, deps) {
7947 currentHookNameInDev = 'useImperativeHandle';
7948 updateHookTypesDev();
7949 return updateImperativeHandle(ref, create, deps);
7950 },
7951 useInsertionEffect: function (create, deps) {
7952 currentHookNameInDev = 'useInsertionEffect';
7953 updateHookTypesDev();
7954 return updateInsertionEffect(create, deps);
7955 },
7956 useLayoutEffect: function (create, deps) {
7957 currentHookNameInDev = 'useLayoutEffect';
7958 updateHookTypesDev();
7959 return updateLayoutEffect(create, deps);
7960 },
7961 useMemo: function (create, deps) {
7962 currentHookNameInDev = 'useMemo';
7963 updateHookTypesDev();
7964 var prevDispatcher = ReactCurrentDispatcher$1.current;
7965 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
7966
7967 try {
7968 return updateMemo(create, deps);
7969 } finally {
7970 ReactCurrentDispatcher$1.current = prevDispatcher;
7971 }
7972 },
7973 useReducer: function (reducer, initialArg, init) {
7974 currentHookNameInDev = 'useReducer';
7975 updateHookTypesDev();
7976 var prevDispatcher = ReactCurrentDispatcher$1.current;
7977 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
7978
7979 try {
7980 return rerenderReducer(reducer, initialArg, init);
7981 } finally {
7982 ReactCurrentDispatcher$1.current = prevDispatcher;
7983 }
7984 },
7985 useRef: function (initialValue) {
7986 currentHookNameInDev = 'useRef';
7987 updateHookTypesDev();
7988 return updateRef();
7989 },
7990 useState: function (initialState) {
7991 currentHookNameInDev = 'useState';
7992 updateHookTypesDev();
7993 var prevDispatcher = ReactCurrentDispatcher$1.current;
7994 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
7995
7996 try {
7997 return rerenderState(initialState);
7998 } finally {
7999 ReactCurrentDispatcher$1.current = prevDispatcher;
8000 }
8001 },
8002 useDebugValue: function (value, formatterFn) {
8003 currentHookNameInDev = 'useDebugValue';
8004 updateHookTypesDev();
8005 return updateDebugValue();
8006 },
8007 useDeferredValue: function (value) {
8008 currentHookNameInDev = 'useDeferredValue';
8009 updateHookTypesDev();
8010 return rerenderDeferredValue(value);
8011 },
8012 useTransition: function () {
8013 currentHookNameInDev = 'useTransition';
8014 updateHookTypesDev();
8015 return rerenderTransition();
8016 },
8017 useMutableSource: function (source, getSnapshot, subscribe) {
8018 currentHookNameInDev = 'useMutableSource';
8019 updateHookTypesDev();
8020 return updateMutableSource();
8021 },
8022 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
8023 currentHookNameInDev = 'useSyncExternalStore';
8024 updateHookTypesDev();
8025 return updateSyncExternalStore(subscribe, getSnapshot);
8026 },
8027 useId: function () {
8028 currentHookNameInDev = 'useId';
8029 updateHookTypesDev();
8030 return updateId();
8031 },
8032 unstable_isNewReconciler: enableNewReconciler
8033 };
8034
8035 InvalidNestedHooksDispatcherOnMountInDEV = {
8036 readContext: function (context) {
8037 warnInvalidContextAccess();
8038 return readContext(context);
8039 },
8040 useCallback: function (callback, deps) {
8041 currentHookNameInDev = 'useCallback';
8042 warnInvalidHookAccess();
8043 mountHookTypesDev();
8044 return mountCallback(callback, deps);
8045 },
8046 useContext: function (context) {
8047 currentHookNameInDev = 'useContext';
8048 warnInvalidHookAccess();
8049 mountHookTypesDev();
8050 return readContext(context);
8051 },
8052 useEffect: function (create, deps) {
8053 currentHookNameInDev = 'useEffect';
8054 warnInvalidHookAccess();
8055 mountHookTypesDev();
8056 return mountEffect(create, deps);
8057 },
8058 useImperativeHandle: function (ref, create, deps) {
8059 currentHookNameInDev = 'useImperativeHandle';
8060 warnInvalidHookAccess();
8061 mountHookTypesDev();
8062 return mountImperativeHandle(ref, create, deps);
8063 },
8064 useInsertionEffect: function (create, deps) {
8065 currentHookNameInDev = 'useInsertionEffect';
8066 warnInvalidHookAccess();
8067 mountHookTypesDev();
8068 return mountInsertionEffect(create, deps);
8069 },
8070 useLayoutEffect: function (create, deps) {
8071 currentHookNameInDev = 'useLayoutEffect';
8072 warnInvalidHookAccess();
8073 mountHookTypesDev();
8074 return mountLayoutEffect(create, deps);
8075 },
8076 useMemo: function (create, deps) {
8077 currentHookNameInDev = 'useMemo';
8078 warnInvalidHookAccess();
8079 mountHookTypesDev();
8080 var prevDispatcher = ReactCurrentDispatcher$1.current;
8081 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
8082
8083 try {
8084 return mountMemo(create, deps);
8085 } finally {
8086 ReactCurrentDispatcher$1.current = prevDispatcher;
8087 }
8088 },
8089 useReducer: function (reducer, initialArg, init) {
8090 currentHookNameInDev = 'useReducer';
8091 warnInvalidHookAccess();
8092 mountHookTypesDev();
8093 var prevDispatcher = ReactCurrentDispatcher$1.current;
8094 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
8095
8096 try {
8097 return mountReducer(reducer, initialArg, init);
8098 } finally {
8099 ReactCurrentDispatcher$1.current = prevDispatcher;
8100 }
8101 },
8102 useRef: function (initialValue) {
8103 currentHookNameInDev = 'useRef';
8104 warnInvalidHookAccess();
8105 mountHookTypesDev();
8106 return mountRef(initialValue);
8107 },
8108 useState: function (initialState) {
8109 currentHookNameInDev = 'useState';
8110 warnInvalidHookAccess();
8111 mountHookTypesDev();
8112 var prevDispatcher = ReactCurrentDispatcher$1.current;
8113 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
8114
8115 try {
8116 return mountState(initialState);
8117 } finally {
8118 ReactCurrentDispatcher$1.current = prevDispatcher;
8119 }
8120 },
8121 useDebugValue: function (value, formatterFn) {
8122 currentHookNameInDev = 'useDebugValue';
8123 warnInvalidHookAccess();
8124 mountHookTypesDev();
8125 return mountDebugValue();
8126 },
8127 useDeferredValue: function (value) {
8128 currentHookNameInDev = 'useDeferredValue';
8129 warnInvalidHookAccess();
8130 mountHookTypesDev();
8131 return mountDeferredValue(value);
8132 },
8133 useTransition: function () {
8134 currentHookNameInDev = 'useTransition';
8135 warnInvalidHookAccess();
8136 mountHookTypesDev();
8137 return mountTransition();
8138 },
8139 useMutableSource: function (source, getSnapshot, subscribe) {
8140 currentHookNameInDev = 'useMutableSource';
8141 warnInvalidHookAccess();
8142 mountHookTypesDev();
8143 return mountMutableSource();
8144 },
8145 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
8146 currentHookNameInDev = 'useSyncExternalStore';
8147 warnInvalidHookAccess();
8148 mountHookTypesDev();
8149 return mountSyncExternalStore(subscribe, getSnapshot);
8150 },
8151 useId: function () {
8152 currentHookNameInDev = 'useId';
8153 warnInvalidHookAccess();
8154 mountHookTypesDev();
8155 return mountId();
8156 },
8157 unstable_isNewReconciler: enableNewReconciler
8158 };
8159
8160 InvalidNestedHooksDispatcherOnUpdateInDEV = {
8161 readContext: function (context) {
8162 warnInvalidContextAccess();
8163 return readContext(context);
8164 },
8165 useCallback: function (callback, deps) {
8166 currentHookNameInDev = 'useCallback';
8167 warnInvalidHookAccess();
8168 updateHookTypesDev();
8169 return updateCallback(callback, deps);
8170 },
8171 useContext: function (context) {
8172 currentHookNameInDev = 'useContext';
8173 warnInvalidHookAccess();
8174 updateHookTypesDev();
8175 return readContext(context);
8176 },
8177 useEffect: function (create, deps) {
8178 currentHookNameInDev = 'useEffect';
8179 warnInvalidHookAccess();
8180 updateHookTypesDev();
8181 return updateEffect(create, deps);
8182 },
8183 useImperativeHandle: function (ref, create, deps) {
8184 currentHookNameInDev = 'useImperativeHandle';
8185 warnInvalidHookAccess();
8186 updateHookTypesDev();
8187 return updateImperativeHandle(ref, create, deps);
8188 },
8189 useInsertionEffect: function (create, deps) {
8190 currentHookNameInDev = 'useInsertionEffect';
8191 warnInvalidHookAccess();
8192 updateHookTypesDev();
8193 return updateInsertionEffect(create, deps);
8194 },
8195 useLayoutEffect: function (create, deps) {
8196 currentHookNameInDev = 'useLayoutEffect';
8197 warnInvalidHookAccess();
8198 updateHookTypesDev();
8199 return updateLayoutEffect(create, deps);
8200 },
8201 useMemo: function (create, deps) {
8202 currentHookNameInDev = 'useMemo';
8203 warnInvalidHookAccess();
8204 updateHookTypesDev();
8205 var prevDispatcher = ReactCurrentDispatcher$1.current;
8206 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
8207
8208 try {
8209 return updateMemo(create, deps);
8210 } finally {
8211 ReactCurrentDispatcher$1.current = prevDispatcher;
8212 }
8213 },
8214 useReducer: function (reducer, initialArg, init) {
8215 currentHookNameInDev = 'useReducer';
8216 warnInvalidHookAccess();
8217 updateHookTypesDev();
8218 var prevDispatcher = ReactCurrentDispatcher$1.current;
8219 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
8220
8221 try {
8222 return updateReducer(reducer, initialArg, init);
8223 } finally {
8224 ReactCurrentDispatcher$1.current = prevDispatcher;
8225 }
8226 },
8227 useRef: function (initialValue) {
8228 currentHookNameInDev = 'useRef';
8229 warnInvalidHookAccess();
8230 updateHookTypesDev();
8231 return updateRef();
8232 },
8233 useState: function (initialState) {
8234 currentHookNameInDev = 'useState';
8235 warnInvalidHookAccess();
8236 updateHookTypesDev();
8237 var prevDispatcher = ReactCurrentDispatcher$1.current;
8238 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
8239
8240 try {
8241 return updateState(initialState);
8242 } finally {
8243 ReactCurrentDispatcher$1.current = prevDispatcher;
8244 }
8245 },
8246 useDebugValue: function (value, formatterFn) {
8247 currentHookNameInDev = 'useDebugValue';
8248 warnInvalidHookAccess();
8249 updateHookTypesDev();
8250 return updateDebugValue();
8251 },
8252 useDeferredValue: function (value) {
8253 currentHookNameInDev = 'useDeferredValue';
8254 warnInvalidHookAccess();
8255 updateHookTypesDev();
8256 return updateDeferredValue(value);
8257 },
8258 useTransition: function () {
8259 currentHookNameInDev = 'useTransition';
8260 warnInvalidHookAccess();
8261 updateHookTypesDev();
8262 return updateTransition();
8263 },
8264 useMutableSource: function (source, getSnapshot, subscribe) {
8265 currentHookNameInDev = 'useMutableSource';
8266 warnInvalidHookAccess();
8267 updateHookTypesDev();
8268 return updateMutableSource();
8269 },
8270 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
8271 currentHookNameInDev = 'useSyncExternalStore';
8272 warnInvalidHookAccess();
8273 updateHookTypesDev();
8274 return updateSyncExternalStore(subscribe, getSnapshot);
8275 },
8276 useId: function () {
8277 currentHookNameInDev = 'useId';
8278 warnInvalidHookAccess();
8279 updateHookTypesDev();
8280 return updateId();
8281 },
8282 unstable_isNewReconciler: enableNewReconciler
8283 };
8284
8285 InvalidNestedHooksDispatcherOnRerenderInDEV = {
8286 readContext: function (context) {
8287 warnInvalidContextAccess();
8288 return readContext(context);
8289 },
8290 useCallback: function (callback, deps) {
8291 currentHookNameInDev = 'useCallback';
8292 warnInvalidHookAccess();
8293 updateHookTypesDev();
8294 return updateCallback(callback, deps);
8295 },
8296 useContext: function (context) {
8297 currentHookNameInDev = 'useContext';
8298 warnInvalidHookAccess();
8299 updateHookTypesDev();
8300 return readContext(context);
8301 },
8302 useEffect: function (create, deps) {
8303 currentHookNameInDev = 'useEffect';
8304 warnInvalidHookAccess();
8305 updateHookTypesDev();
8306 return updateEffect(create, deps);
8307 },
8308 useImperativeHandle: function (ref, create, deps) {
8309 currentHookNameInDev = 'useImperativeHandle';
8310 warnInvalidHookAccess();
8311 updateHookTypesDev();
8312 return updateImperativeHandle(ref, create, deps);
8313 },
8314 useInsertionEffect: function (create, deps) {
8315 currentHookNameInDev = 'useInsertionEffect';
8316 warnInvalidHookAccess();
8317 updateHookTypesDev();
8318 return updateInsertionEffect(create, deps);
8319 },
8320 useLayoutEffect: function (create, deps) {
8321 currentHookNameInDev = 'useLayoutEffect';
8322 warnInvalidHookAccess();
8323 updateHookTypesDev();
8324 return updateLayoutEffect(create, deps);
8325 },
8326 useMemo: function (create, deps) {
8327 currentHookNameInDev = 'useMemo';
8328 warnInvalidHookAccess();
8329 updateHookTypesDev();
8330 var prevDispatcher = ReactCurrentDispatcher$1.current;
8331 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
8332
8333 try {
8334 return updateMemo(create, deps);
8335 } finally {
8336 ReactCurrentDispatcher$1.current = prevDispatcher;
8337 }
8338 },
8339 useReducer: function (reducer, initialArg, init) {
8340 currentHookNameInDev = 'useReducer';
8341 warnInvalidHookAccess();
8342 updateHookTypesDev();
8343 var prevDispatcher = ReactCurrentDispatcher$1.current;
8344 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
8345
8346 try {
8347 return rerenderReducer(reducer, initialArg, init);
8348 } finally {
8349 ReactCurrentDispatcher$1.current = prevDispatcher;
8350 }
8351 },
8352 useRef: function (initialValue) {
8353 currentHookNameInDev = 'useRef';
8354 warnInvalidHookAccess();
8355 updateHookTypesDev();
8356 return updateRef();
8357 },
8358 useState: function (initialState) {
8359 currentHookNameInDev = 'useState';
8360 warnInvalidHookAccess();
8361 updateHookTypesDev();
8362 var prevDispatcher = ReactCurrentDispatcher$1.current;
8363 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
8364
8365 try {
8366 return rerenderState(initialState);
8367 } finally {
8368 ReactCurrentDispatcher$1.current = prevDispatcher;
8369 }
8370 },
8371 useDebugValue: function (value, formatterFn) {
8372 currentHookNameInDev = 'useDebugValue';
8373 warnInvalidHookAccess();
8374 updateHookTypesDev();
8375 return updateDebugValue();
8376 },
8377 useDeferredValue: function (value) {
8378 currentHookNameInDev = 'useDeferredValue';
8379 warnInvalidHookAccess();
8380 updateHookTypesDev();
8381 return rerenderDeferredValue(value);
8382 },
8383 useTransition: function () {
8384 currentHookNameInDev = 'useTransition';
8385 warnInvalidHookAccess();
8386 updateHookTypesDev();
8387 return rerenderTransition();
8388 },
8389 useMutableSource: function (source, getSnapshot, subscribe) {
8390 currentHookNameInDev = 'useMutableSource';
8391 warnInvalidHookAccess();
8392 updateHookTypesDev();
8393 return updateMutableSource();
8394 },
8395 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
8396 currentHookNameInDev = 'useSyncExternalStore';
8397 warnInvalidHookAccess();
8398 updateHookTypesDev();
8399 return updateSyncExternalStore(subscribe, getSnapshot);
8400 },
8401 useId: function () {
8402 currentHookNameInDev = 'useId';
8403 warnInvalidHookAccess();
8404 updateHookTypesDev();
8405 return updateId();
8406 },
8407 unstable_isNewReconciler: enableNewReconciler
8408 };
8409}
8410
8411var now$1 = Scheduler$1.unstable_now;
8412var commitTime = 0;
8413var layoutEffectStartTime = -1;
8414var profilerStartTime = -1;
8415var passiveEffectStartTime = -1;
8416/**
8417 * Tracks whether the current update was a nested/cascading update (scheduled from a layout effect).
8418 *
8419 * The overall sequence is:
8420 * 1. render
8421 * 2. commit (and call `onRender`, `onCommit`)
8422 * 3. check for nested updates
8423 * 4. flush passive effects (and call `onPostCommit`)
8424 *
8425 * Nested updates are identified in step 3 above,
8426 * but step 4 still applies to the work that was just committed.
8427 * We use two flags to track nested updates then:
8428 * one tracks whether the upcoming update is a nested update,
8429 * and the other tracks whether the current update was a nested update.
8430 * The first value gets synced to the second at the start of the render phase.
8431 */
8432
8433var currentUpdateIsNested = false;
8434var nestedUpdateScheduled = false;
8435
8436function isCurrentUpdateNested() {
8437 return currentUpdateIsNested;
8438}
8439
8440function markNestedUpdateScheduled() {
8441 {
8442 nestedUpdateScheduled = true;
8443 }
8444}
8445
8446function resetNestedUpdateFlag() {
8447 {
8448 currentUpdateIsNested = false;
8449 nestedUpdateScheduled = false;
8450 }
8451}
8452
8453function syncNestedUpdateFlag() {
8454 {
8455 currentUpdateIsNested = nestedUpdateScheduled;
8456 nestedUpdateScheduled = false;
8457 }
8458}
8459
8460function getCommitTime() {
8461 return commitTime;
8462}
8463
8464function recordCommitTime() {
8465
8466 commitTime = now$1();
8467}
8468
8469function startProfilerTimer(fiber) {
8470
8471 profilerStartTime = now$1();
8472
8473 if (fiber.actualStartTime < 0) {
8474 fiber.actualStartTime = now$1();
8475 }
8476}
8477
8478function stopProfilerTimerIfRunning(fiber) {
8479
8480 profilerStartTime = -1;
8481}
8482
8483function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
8484
8485 if (profilerStartTime >= 0) {
8486 var elapsedTime = now$1() - profilerStartTime;
8487 fiber.actualDuration += elapsedTime;
8488
8489 if (overrideBaseTime) {
8490 fiber.selfBaseDuration = elapsedTime;
8491 }
8492
8493 profilerStartTime = -1;
8494 }
8495}
8496
8497function recordLayoutEffectDuration(fiber) {
8498
8499 if (layoutEffectStartTime >= 0) {
8500 var elapsedTime = now$1() - layoutEffectStartTime;
8501 layoutEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor
8502 // Or the root (for the DevTools Profiler to read)
8503
8504 var parentFiber = fiber.return;
8505
8506 while (parentFiber !== null) {
8507 switch (parentFiber.tag) {
8508 case HostRoot:
8509 var root = parentFiber.stateNode;
8510 root.effectDuration += elapsedTime;
8511 return;
8512
8513 case Profiler:
8514 var parentStateNode = parentFiber.stateNode;
8515 parentStateNode.effectDuration += elapsedTime;
8516 return;
8517 }
8518
8519 parentFiber = parentFiber.return;
8520 }
8521 }
8522}
8523
8524function recordPassiveEffectDuration(fiber) {
8525
8526 if (passiveEffectStartTime >= 0) {
8527 var elapsedTime = now$1() - passiveEffectStartTime;
8528 passiveEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor
8529 // Or the root (for the DevTools Profiler to read)
8530
8531 var parentFiber = fiber.return;
8532
8533 while (parentFiber !== null) {
8534 switch (parentFiber.tag) {
8535 case HostRoot:
8536 var root = parentFiber.stateNode;
8537
8538 if (root !== null) {
8539 root.passiveEffectDuration += elapsedTime;
8540 }
8541
8542 return;
8543
8544 case Profiler:
8545 var parentStateNode = parentFiber.stateNode;
8546
8547 if (parentStateNode !== null) {
8548 // Detached fibers have their state node cleared out.
8549 // In this case, the return pointer is also cleared out,
8550 // so we won't be able to report the time spent in this Profiler's subtree.
8551 parentStateNode.passiveEffectDuration += elapsedTime;
8552 }
8553
8554 return;
8555 }
8556
8557 parentFiber = parentFiber.return;
8558 }
8559 }
8560}
8561
8562function startLayoutEffectTimer() {
8563
8564 layoutEffectStartTime = now$1();
8565}
8566
8567function startPassiveEffectTimer() {
8568
8569 passiveEffectStartTime = now$1();
8570}
8571
8572function transferActualDuration(fiber) {
8573 // Transfer time spent rendering these children so we don't lose it
8574 // after we rerender. This is used as a helper in special cases
8575 // where we should count the work of multiple passes.
8576 var child = fiber.child;
8577
8578 while (child) {
8579 fiber.actualDuration += child.actualDuration;
8580 child = child.sibling;
8581 }
8582}
8583
8584function createCapturedValueAtFiber(value, source) {
8585 // If the value is an error, call this function immediately after it is thrown
8586 // so the stack is accurate.
8587 return {
8588 value: value,
8589 source: source,
8590 stack: getStackByFiberInDevAndProd(source),
8591 digest: null
8592 };
8593}
8594function createCapturedValue(value, digest, stack) {
8595 return {
8596 value: value,
8597 source: null,
8598 stack: stack != null ? stack : null,
8599 digest: digest != null ? digest : null
8600 };
8601}
8602
8603// This module is forked in different environments.
8604// By default, return `true` to log errors to the console.
8605// Forks can return `false` if this isn't desirable.
8606function showErrorDialog(boundary, errorInfo) {
8607 return true;
8608}
8609
8610function logCapturedError(boundary, errorInfo) {
8611 try {
8612 var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging.
8613 // This enables renderers like ReactNative to better manage redbox behavior.
8614
8615 if (logError === false) {
8616 return;
8617 }
8618
8619 var error = errorInfo.value;
8620
8621 if (true) {
8622 var source = errorInfo.source;
8623 var stack = errorInfo.stack;
8624 var componentStack = stack !== null ? stack : ''; // Browsers support silencing uncaught errors by calling
8625 // `preventDefault()` in window `error` handler.
8626 // We record this information as an expando on the error.
8627
8628 if (error != null && error._suppressLogging) {
8629 if (boundary.tag === ClassComponent) {
8630 // The error is recoverable and was silenced.
8631 // Ignore it and don't print the stack addendum.
8632 // This is handy for testing error boundaries without noise.
8633 return;
8634 } // The error is fatal. Since the silencing might have
8635 // been accidental, we'll surface it anyway.
8636 // However, the browser would have silenced the original error
8637 // so we'll print it first, and then print the stack addendum.
8638
8639
8640 console['error'](error); // Don't transform to our wrapper
8641 // For a more detailed description of this block, see:
8642 // https://github.com/facebook/react/pull/13384
8643 }
8644
8645 var componentName = source ? getComponentNameFromFiber(source) : null;
8646 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:';
8647 var errorBoundaryMessage;
8648
8649 if (boundary.tag === HostRoot) {
8650 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.';
8651 } else {
8652 var errorBoundaryName = getComponentNameFromFiber(boundary) || 'Anonymous';
8653 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
8654 }
8655
8656 var combinedMessage = componentNameMessage + "\n" + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.
8657 // We don't include the original error message and JS stack because the browser
8658 // has already printed it. Even if the application swallows the error, it is still
8659 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
8660
8661 console['error'](combinedMessage); // Don't transform to our wrapper
8662 } else {
8663 // In production, we print the error directly.
8664 // This will include the message, the JS stack, and anything the browser wants to show.
8665 // We pass the error object instead of custom message so that the browser displays the error natively.
8666 console['error'](error); // Don't transform to our wrapper
8667 }
8668 } catch (e) {
8669 // This method must not throw, or React internal state will get messed up.
8670 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
8671 // we want to report this error outside of the normal stack as a last resort.
8672 // https://github.com/facebook/react/issues/13188
8673 setTimeout(function () {
8674 throw e;
8675 });
8676 }
8677}
8678
8679var PossiblyWeakMap$1 = typeof WeakMap === 'function' ? WeakMap : Map;
8680
8681function createRootErrorUpdate(fiber, errorInfo, lane) {
8682 var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null.
8683
8684 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
8685 // being called "element".
8686
8687 update.payload = {
8688 element: null
8689 };
8690 var error = errorInfo.value;
8691
8692 update.callback = function () {
8693 onUncaughtError(error);
8694 logCapturedError(fiber, errorInfo);
8695 };
8696
8697 return update;
8698}
8699
8700function createClassErrorUpdate(fiber, errorInfo, lane) {
8701 var update = createUpdate(NoTimestamp, lane);
8702 update.tag = CaptureUpdate;
8703 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
8704
8705 if (typeof getDerivedStateFromError === 'function') {
8706 var error$1 = errorInfo.value;
8707
8708 update.payload = function () {
8709 return getDerivedStateFromError(error$1);
8710 };
8711
8712 update.callback = function () {
8713 {
8714 markFailedErrorBoundaryForHotReloading(fiber);
8715 }
8716
8717 logCapturedError(fiber, errorInfo);
8718 };
8719 }
8720
8721 var inst = fiber.stateNode;
8722
8723 if (inst !== null && typeof inst.componentDidCatch === 'function') {
8724 update.callback = function callback() {
8725 {
8726 markFailedErrorBoundaryForHotReloading(fiber);
8727 }
8728
8729 logCapturedError(fiber, errorInfo);
8730
8731 if (typeof getDerivedStateFromError !== 'function') {
8732 // To preserve the preexisting retry behavior of error boundaries,
8733 // we keep track of which ones already failed during this batch.
8734 // This gets reset before we yield back to the browser.
8735 // TODO: Warn in strict mode if getDerivedStateFromError is
8736 // not defined.
8737 markLegacyErrorBoundaryAsFailed(this);
8738 }
8739
8740 var error$1 = errorInfo.value;
8741 var stack = errorInfo.stack;
8742 this.componentDidCatch(error$1, {
8743 componentStack: stack !== null ? stack : ''
8744 });
8745
8746 {
8747 if (typeof getDerivedStateFromError !== 'function') {
8748 // If componentDidCatch is the only error boundary method defined,
8749 // then it needs to call setState to recover from errors.
8750 // If no state update is scheduled then the boundary will swallow the error.
8751 if (!includesSomeLane(fiber.lanes, SyncLane)) {
8752 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');
8753 }
8754 }
8755 }
8756 };
8757 }
8758
8759 return update;
8760}
8761
8762function attachPingListener(root, wakeable, lanes) {
8763 // Attach a ping listener
8764 //
8765 // The data might resolve before we have a chance to commit the fallback. Or,
8766 // in the case of a refresh, we'll never commit a fallback. So we need to
8767 // attach a listener now. When it resolves ("pings"), we can decide whether to
8768 // try rendering the tree again.
8769 //
8770 // Only attach a listener if one does not already exist for the lanes
8771 // we're currently rendering (which acts like a "thread ID" here).
8772 //
8773 // We only need to do this in concurrent mode. Legacy Suspense always
8774 // commits fallbacks synchronously, so there are no pings.
8775 var pingCache = root.pingCache;
8776 var threadIDs;
8777
8778 if (pingCache === null) {
8779 pingCache = root.pingCache = new PossiblyWeakMap$1();
8780 threadIDs = new Set();
8781 pingCache.set(wakeable, threadIDs);
8782 } else {
8783 threadIDs = pingCache.get(wakeable);
8784
8785 if (threadIDs === undefined) {
8786 threadIDs = new Set();
8787 pingCache.set(wakeable, threadIDs);
8788 }
8789 }
8790
8791 if (!threadIDs.has(lanes)) {
8792 // Memoize using the thread ID to prevent redundant listeners.
8793 threadIDs.add(lanes);
8794 var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes);
8795
8796 wakeable.then(ping, ping);
8797 }
8798}
8799
8800function attachRetryListener(suspenseBoundary, root, wakeable, lanes) {
8801 // Retry listener
8802 //
8803 // If the fallback does commit, we need to attach a different type of
8804 // listener. This one schedules an update on the Suspense boundary to turn
8805 // the fallback state off.
8806 //
8807 // Stash the wakeable on the boundary fiber so we can access it in the
8808 // commit phase.
8809 //
8810 // When the wakeable resolves, we'll attempt to render the boundary
8811 // again ("retry").
8812 var wakeables = suspenseBoundary.updateQueue;
8813
8814 if (wakeables === null) {
8815 var updateQueue = new Set();
8816 updateQueue.add(wakeable);
8817 suspenseBoundary.updateQueue = updateQueue;
8818 } else {
8819 wakeables.add(wakeable);
8820 }
8821}
8822
8823function resetSuspendedComponent(sourceFiber, rootRenderLanes) {
8824 // A legacy mode Suspense quirk, only relevant to hook components.
8825
8826
8827 var tag = sourceFiber.tag;
8828
8829 if ((sourceFiber.mode & ConcurrentMode) === NoMode && (tag === FunctionComponent || tag === ForwardRef || tag === SimpleMemoComponent)) {
8830 var currentSource = sourceFiber.alternate;
8831
8832 if (currentSource) {
8833 sourceFiber.updateQueue = currentSource.updateQueue;
8834 sourceFiber.memoizedState = currentSource.memoizedState;
8835 sourceFiber.lanes = currentSource.lanes;
8836 } else {
8837 sourceFiber.updateQueue = null;
8838 sourceFiber.memoizedState = null;
8839 }
8840 }
8841}
8842
8843function getNearestSuspenseBoundaryToCapture(returnFiber) {
8844 var node = returnFiber;
8845
8846 do {
8847 if (node.tag === SuspenseComponent && shouldCaptureSuspense(node)) {
8848 return node;
8849 } // This boundary already captured during this render. Continue to the next
8850 // boundary.
8851
8852
8853 node = node.return;
8854 } while (node !== null);
8855
8856 return null;
8857}
8858
8859function markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes) {
8860 // This marks a Suspense boundary so that when we're unwinding the stack,
8861 // it captures the suspended "exception" and does a second (fallback) pass.
8862 if ((suspenseBoundary.mode & ConcurrentMode) === NoMode) {
8863 // Legacy Mode Suspense
8864 //
8865 // If the boundary is in legacy mode, we should *not*
8866 // suspend the commit. Pretend as if the suspended component rendered
8867 // null and keep rendering. When the Suspense boundary completes,
8868 // we'll do a second pass to render the fallback.
8869 if (suspenseBoundary === returnFiber) {
8870 // Special case where we suspended while reconciling the children of
8871 // a Suspense boundary's inner Offscreen wrapper fiber. This happens
8872 // when a React.lazy component is a direct child of a
8873 // Suspense boundary.
8874 //
8875 // Suspense boundaries are implemented as multiple fibers, but they
8876 // are a single conceptual unit. The legacy mode behavior where we
8877 // pretend the suspended fiber committed as `null` won't work,
8878 // because in this case the "suspended" fiber is the inner
8879 // Offscreen wrapper.
8880 //
8881 // Because the contents of the boundary haven't started rendering
8882 // yet (i.e. nothing in the tree has partially rendered) we can
8883 // switch to the regular, concurrent mode behavior: mark the
8884 // boundary with ShouldCapture and enter the unwind phase.
8885 suspenseBoundary.flags |= ShouldCapture;
8886 } else {
8887 suspenseBoundary.flags |= DidCapture;
8888 sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete.
8889 // But we shouldn't call any lifecycle methods or callbacks. Remove
8890 // all lifecycle effect tags.
8891
8892 sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete);
8893
8894 if (sourceFiber.tag === ClassComponent) {
8895 var currentSourceFiber = sourceFiber.alternate;
8896
8897 if (currentSourceFiber === null) {
8898 // This is a new mount. Change the tag so it's not mistaken for a
8899 // completed class component. For example, we should not call
8900 // componentWillUnmount if it is deleted.
8901 sourceFiber.tag = IncompleteClassComponent;
8902 } else {
8903 // When we try rendering again, we should not reuse the current fiber,
8904 // since it's known to be in an inconsistent state. Use a force update to
8905 // prevent a bail out.
8906 var update = createUpdate(NoTimestamp, SyncLane);
8907 update.tag = ForceUpdate;
8908 enqueueUpdate(sourceFiber, update, SyncLane);
8909 }
8910 } // The source fiber did not complete. Mark it with Sync priority to
8911 // indicate that it still has pending work.
8912
8913
8914 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane);
8915 }
8916
8917 return suspenseBoundary;
8918 } // Confirmed that the boundary is in a concurrent mode tree. Continue
8919 // with the normal suspend path.
8920 //
8921 // After this we'll use a set of heuristics to determine whether this
8922 // render pass will run to completion or restart or "suspend" the commit.
8923 // The actual logic for this is spread out in different places.
8924 //
8925 // This first principle is that if we're going to suspend when we complete
8926 // a root, then we should also restart if we get an update or ping that
8927 // might unsuspend it, and vice versa. The only reason to suspend is
8928 // because you think you might want to restart before committing. However,
8929 // it doesn't make sense to restart only while in the period we're suspended.
8930 //
8931 // Restarting too aggressively is also not good because it starves out any
8932 // intermediate loading state. So we use heuristics to determine when.
8933 // Suspense Heuristics
8934 //
8935 // If nothing threw a Promise or all the same fallbacks are already showing,
8936 // then don't suspend/restart.
8937 //
8938 // If this is an initial render of a new tree of Suspense boundaries and
8939 // those trigger a fallback, then don't suspend/restart. We want to ensure
8940 // that we can show the initial loading state as quickly as possible.
8941 //
8942 // If we hit a "Delayed" case, such as when we'd switch from content back into
8943 // a fallback, then we should always suspend/restart. Transitions apply
8944 // to this case. If none is defined, JND is used instead.
8945 //
8946 // If we're already showing a fallback and it gets "retried", allowing us to show
8947 // another level, but there's still an inner boundary that would show a fallback,
8948 // then we suspend/restart for 500ms since the last time we showed a fallback
8949 // anywhere in the tree. This effectively throttles progressive loading into a
8950 // consistent train of commits. This also gives us an opportunity to restart to
8951 // get to the completed state slightly earlier.
8952 //
8953 // If there's ambiguity due to batching it's resolved in preference of:
8954 // 1) "delayed", 2) "initial render", 3) "retry".
8955 //
8956 // We want to ensure that a "busy" state doesn't get force committed. We want to
8957 // ensure that new initial loading states can commit as soon as possible.
8958
8959
8960 suspenseBoundary.flags |= ShouldCapture; // TODO: I think we can remove this, since we now use `DidCapture` in
8961 // the begin phase to prevent an early bailout.
8962
8963 suspenseBoundary.lanes = rootRenderLanes;
8964 return suspenseBoundary;
8965}
8966
8967function throwException(root, returnFiber, sourceFiber, value, rootRenderLanes) {
8968 // The source fiber did not complete.
8969 sourceFiber.flags |= Incomplete;
8970
8971 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
8972 // This is a wakeable. The component suspended.
8973 var wakeable = value;
8974 resetSuspendedComponent(sourceFiber);
8975
8976
8977 var suspenseBoundary = getNearestSuspenseBoundaryToCapture(returnFiber);
8978
8979 if (suspenseBoundary !== null) {
8980 suspenseBoundary.flags &= ~ForceClientRender;
8981 markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes); // We only attach ping listeners in concurrent mode. Legacy Suspense always
8982 // commits fallbacks synchronously, so there are no pings.
8983
8984 if (suspenseBoundary.mode & ConcurrentMode) {
8985 attachPingListener(root, wakeable, rootRenderLanes);
8986 }
8987
8988 attachRetryListener(suspenseBoundary, root, wakeable);
8989 return;
8990 } else {
8991 // No boundary was found. Unless this is a sync update, this is OK.
8992 // We can suspend and wait for more data to arrive.
8993 if (!includesSyncLane(rootRenderLanes)) {
8994 // This is not a sync update. Suspend. Since we're not activating a
8995 // Suspense boundary, this will unwind all the way to the root without
8996 // performing a second pass to render a fallback. (This is arguably how
8997 // refresh transitions should work, too, since we're not going to commit
8998 // the fallbacks anyway.)
8999 //
9000 // This case also applies to initial hydration.
9001 attachPingListener(root, wakeable, rootRenderLanes);
9002 renderDidSuspendDelayIfPossible();
9003 return;
9004 } // This is a sync/discrete update. We treat this case like an error
9005 // because discrete renders are expected to produce a complete tree
9006 // synchronously to maintain consistency with external state.
9007
9008
9009 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.
9010 // The error will be caught by the nearest suspense boundary.
9011
9012 value = uncaughtSuspenseError;
9013 }
9014 }
9015
9016 value = createCapturedValueAtFiber(value, sourceFiber);
9017 renderDidError(value); // We didn't find a boundary that could handle this type of exception. Start
9018 // over and traverse parent path again, this time treating the exception
9019 // as an error.
9020
9021 var workInProgress = returnFiber;
9022
9023 do {
9024 switch (workInProgress.tag) {
9025 case HostRoot:
9026 {
9027 var _errorInfo = value;
9028 workInProgress.flags |= ShouldCapture;
9029 var lane = pickArbitraryLane(rootRenderLanes);
9030 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);
9031 var update = createRootErrorUpdate(workInProgress, _errorInfo, lane);
9032 enqueueCapturedUpdate(workInProgress, update);
9033 return;
9034 }
9035
9036 case ClassComponent:
9037 // Capture and retry
9038 var errorInfo = value;
9039 var ctor = workInProgress.type;
9040 var instance = workInProgress.stateNode;
9041
9042 if ((workInProgress.flags & DidCapture) === NoFlags && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
9043 workInProgress.flags |= ShouldCapture;
9044
9045 var _lane = pickArbitraryLane(rootRenderLanes);
9046
9047 workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state
9048
9049 var _update = createClassErrorUpdate(workInProgress, errorInfo, _lane);
9050
9051 enqueueCapturedUpdate(workInProgress, _update);
9052 return;
9053 }
9054
9055 break;
9056 }
9057
9058 workInProgress = workInProgress.return;
9059 } while (workInProgress !== null);
9060}
9061
9062function getSuspendedCache() {
9063 {
9064 return null;
9065 } // This function is called when a Suspense boundary suspends. It returns the
9066}
9067
9068var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
9069var didReceiveUpdate = false;
9070var didWarnAboutBadClass;
9071var didWarnAboutModulePatternComponent;
9072var didWarnAboutContextTypeOnFunctionComponent;
9073var didWarnAboutGetDerivedStateOnFunctionComponent;
9074var didWarnAboutFunctionRefs;
9075var didWarnAboutReassigningProps;
9076var didWarnAboutRevealOrder;
9077var didWarnAboutTailOptions;
9078
9079{
9080 didWarnAboutBadClass = {};
9081 didWarnAboutModulePatternComponent = {};
9082 didWarnAboutContextTypeOnFunctionComponent = {};
9083 didWarnAboutGetDerivedStateOnFunctionComponent = {};
9084 didWarnAboutFunctionRefs = {};
9085 didWarnAboutReassigningProps = false;
9086 didWarnAboutRevealOrder = {};
9087 didWarnAboutTailOptions = {};
9088}
9089
9090function reconcileChildren(current, workInProgress, nextChildren, renderLanes) {
9091 if (current === null) {
9092 // If this is a fresh new component that hasn't been rendered yet, we
9093 // won't update its child set by applying minimal side-effects. Instead,
9094 // we will add them all to the child before it gets rendered. That means
9095 // we can optimize this reconciliation pass by not tracking side-effects.
9096 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderLanes);
9097 } else {
9098 // If the current child is the same as the work in progress, it means that
9099 // we haven't yet started any work on these children. Therefore, we use
9100 // the clone algorithm to create a copy of all the current children.
9101 // If we had any progressed work already, that is invalid at this point so
9102 // let's throw it out.
9103 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderLanes);
9104 }
9105}
9106
9107function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes) {
9108 // This function is fork of reconcileChildren. It's used in cases where we
9109 // want to reconcile without matching against the existing set. This has the
9110 // effect of all current children being unmounted; even if the type and key
9111 // are the same, the old child is unmounted and a new child is created.
9112 //
9113 // To do this, we're going to go through the reconcile algorithm twice. In
9114 // the first pass, we schedule a deletion for all the current children by
9115 // passing null.
9116 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderLanes); // In the second pass, we mount the new children. The trick here is that we
9117 // pass null in place of where we usually pass the current child set. This has
9118 // the effect of remounting all children regardless of whether their
9119 // identities match.
9120
9121 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes);
9122}
9123
9124function updateForwardRef(current, workInProgress, Component, nextProps, renderLanes) {
9125 // TODO: current can be non-null here even if the component
9126 // hasn't yet mounted. This happens after the first render suspends.
9127 // We'll need to figure out if this is fine or can cause issues.
9128 {
9129 if (workInProgress.type !== workInProgress.elementType) {
9130 // Lazy component props can't be validated in createElement
9131 // because they're only guaranteed to be resolved here.
9132 var innerPropTypes = Component.propTypes;
9133
9134 if (innerPropTypes) {
9135 checkPropTypes(innerPropTypes, nextProps, // Resolved props
9136 'prop', getComponentNameFromType(Component));
9137 }
9138 }
9139 }
9140
9141 var render = Component.render;
9142 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent
9143
9144 var nextChildren;
9145 prepareToReadContext(workInProgress, renderLanes);
9146
9147 {
9148 ReactCurrentOwner$1.current = workInProgress;
9149 setIsRendering(true);
9150 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes);
9151
9152 setIsRendering(false);
9153 }
9154
9155 if (current !== null && !didReceiveUpdate) {
9156 bailoutHooks(current, workInProgress, renderLanes);
9157 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
9158 }
9159
9160
9161 workInProgress.flags |= PerformedWork;
9162 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
9163 return workInProgress.child;
9164}
9165
9166function updateMemoComponent(current, workInProgress, Component, nextProps, renderLanes) {
9167 if (current === null) {
9168 var type = Component.type;
9169
9170 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.
9171 Component.defaultProps === undefined) {
9172 var resolvedType = type;
9173
9174 {
9175 resolvedType = resolveFunctionForHotReloading(type);
9176 } // If this is a plain function component without default props,
9177 // and with only the default shallow comparison, we upgrade it
9178 // to a SimpleMemoComponent to allow fast path updates.
9179
9180
9181 workInProgress.tag = SimpleMemoComponent;
9182 workInProgress.type = resolvedType;
9183
9184 {
9185 validateFunctionComponentInDev(workInProgress, type);
9186 }
9187
9188 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, renderLanes);
9189 }
9190
9191 {
9192 var innerPropTypes = type.propTypes;
9193
9194 if (innerPropTypes) {
9195 // Inner memo component props aren't currently validated in createElement.
9196 // We could move it there, but we'd still need this for lazy code path.
9197 checkPropTypes(innerPropTypes, nextProps, // Resolved props
9198 'prop', getComponentNameFromType(type));
9199 }
9200 }
9201
9202 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, workInProgress, workInProgress.mode, renderLanes);
9203 child.ref = workInProgress.ref;
9204 child.return = workInProgress;
9205 workInProgress.child = child;
9206 return child;
9207 }
9208
9209 {
9210 var _type = Component.type;
9211 var _innerPropTypes = _type.propTypes;
9212
9213 if (_innerPropTypes) {
9214 // Inner memo component props aren't currently validated in createElement.
9215 // We could move it there, but we'd still need this for lazy code path.
9216 checkPropTypes(_innerPropTypes, nextProps, // Resolved props
9217 'prop', getComponentNameFromType(_type));
9218 }
9219 }
9220
9221 var currentChild = current.child; // This is always exactly one child
9222
9223 var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current, renderLanes);
9224
9225 if (!hasScheduledUpdateOrContext) {
9226 // This will be the props with resolved defaultProps,
9227 // unlike current.memoizedProps which will be the unresolved ones.
9228 var prevProps = currentChild.memoizedProps; // Default to shallow comparison
9229
9230 var compare = Component.compare;
9231 compare = compare !== null ? compare : shallowEqual;
9232
9233 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
9234 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
9235 }
9236 } // React DevTools reads this flag.
9237
9238
9239 workInProgress.flags |= PerformedWork;
9240 var newChild = createWorkInProgress(currentChild, nextProps);
9241 newChild.ref = workInProgress.ref;
9242 newChild.return = workInProgress;
9243 workInProgress.child = newChild;
9244 return newChild;
9245}
9246
9247function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, renderLanes) {
9248 // TODO: current can be non-null here even if the component
9249 // hasn't yet mounted. This happens when the inner render suspends.
9250 // We'll need to figure out if this is fine or can cause issues.
9251 {
9252 if (workInProgress.type !== workInProgress.elementType) {
9253 // Lazy component props can't be validated in createElement
9254 // because they're only guaranteed to be resolved here.
9255 var outerMemoType = workInProgress.elementType;
9256
9257 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
9258 // We warn when you define propTypes on lazy()
9259 // so let's just skip over it to find memo() outer wrapper.
9260 // Inner props for memo are validated later.
9261 var lazyComponent = outerMemoType;
9262 var payload = lazyComponent._payload;
9263 var init = lazyComponent._init;
9264
9265 try {
9266 outerMemoType = init(payload);
9267 } catch (x) {
9268 outerMemoType = null;
9269 } // Inner propTypes will be validated in the function component path.
9270
9271
9272 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
9273
9274 if (outerPropTypes) {
9275 checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
9276 'prop', getComponentNameFromType(outerMemoType));
9277 }
9278 }
9279 }
9280 }
9281
9282 if (current !== null) {
9283 var prevProps = current.memoizedProps;
9284
9285 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload.
9286 workInProgress.type === current.type )) {
9287 didReceiveUpdate = false; // The props are shallowly equal. Reuse the previous props object, like we
9288 // would during a normal fiber bailout.
9289 //
9290 // We don't have strong guarantees that the props object is referentially
9291 // equal during updates where we can't bail out anyway — like if the props
9292 // are shallowly equal, but there's a local state or context update in the
9293 // same batch.
9294 //
9295 // However, as a principle, we should aim to make the behavior consistent
9296 // across different ways of memoizing a component. For example, React.memo
9297 // has a different internal Fiber layout if you pass a normal function
9298 // component (SimpleMemoComponent) versus if you pass a different type
9299 // like forwardRef (MemoComponent). But this is an implementation detail.
9300 // Wrapping a component in forwardRef (or React.lazy, etc) shouldn't
9301 // affect whether the props object is reused during a bailout.
9302
9303 workInProgress.pendingProps = nextProps = prevProps;
9304
9305 if (!checkScheduledUpdateOrContext(current, renderLanes)) {
9306 // The pending lanes were cleared at the beginning of beginWork. We're
9307 // about to bail out, but there might be other lanes that weren't
9308 // included in the current render. Usually, the priority level of the
9309 // remaining updates is accumulated during the evaluation of the
9310 // component (i.e. when processing the update queue). But since since
9311 // we're bailing out early *without* evaluating the component, we need
9312 // to account for it here, too. Reset to the value of the current fiber.
9313 // NOTE: This only applies to SimpleMemoComponent, not MemoComponent,
9314 // because a MemoComponent fiber does not have hooks or an update queue;
9315 // rather, it wraps around an inner component, which may or may not
9316 // contains hooks.
9317 // TODO: Move the reset at in beginWork out of the common path so that
9318 // this is no longer necessary.
9319 workInProgress.lanes = current.lanes;
9320 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
9321 } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) {
9322 // This is a special case that only exists for legacy mode.
9323 // See https://github.com/facebook/react/pull/19216.
9324 didReceiveUpdate = true;
9325 }
9326 }
9327 }
9328
9329 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes);
9330}
9331
9332function updateOffscreenComponent(current, workInProgress, renderLanes) {
9333 var nextProps = workInProgress.pendingProps;
9334 var nextChildren = nextProps.children;
9335 var prevState = current !== null ? current.memoizedState : null;
9336
9337 if (nextProps.mode === 'hidden' || enableLegacyHidden ) {
9338 // Rendering a hidden tree.
9339 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
9340 // In legacy sync mode, don't defer the subtree. Render it now.
9341 // TODO: Consider how Offscreen should work with transitions in the future
9342 var nextState = {
9343 baseLanes: NoLanes,
9344 cachePool: null,
9345 transitions: null
9346 };
9347 workInProgress.memoizedState = nextState;
9348
9349 pushRenderLanes(workInProgress, renderLanes);
9350 } else if (!includesSomeLane(renderLanes, OffscreenLane)) {
9351 var spawnedCachePool = null; // We're hidden, and we're not rendering at Offscreen. We will bail out
9352 // and resume this tree later.
9353
9354 var nextBaseLanes;
9355
9356 if (prevState !== null) {
9357 var prevBaseLanes = prevState.baseLanes;
9358 nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes);
9359 } else {
9360 nextBaseLanes = renderLanes;
9361 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
9362
9363
9364 workInProgress.lanes = workInProgress.childLanes = laneToLanes(OffscreenLane);
9365 var _nextState = {
9366 baseLanes: nextBaseLanes,
9367 cachePool: spawnedCachePool,
9368 transitions: null
9369 };
9370 workInProgress.memoizedState = _nextState;
9371 workInProgress.updateQueue = null;
9372 // to avoid a push/pop misalignment.
9373
9374
9375 pushRenderLanes(workInProgress, nextBaseLanes);
9376
9377 return null;
9378 } else {
9379 // This is the second render. The surrounding visible content has already
9380 // committed. Now we resume rendering the hidden tree.
9381 // Rendering at offscreen, so we can clear the base lanes.
9382 var _nextState2 = {
9383 baseLanes: NoLanes,
9384 cachePool: null,
9385 transitions: null
9386 };
9387 workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out.
9388
9389 var subtreeRenderLanes = prevState !== null ? prevState.baseLanes : renderLanes;
9390
9391 pushRenderLanes(workInProgress, subtreeRenderLanes);
9392 }
9393 } else {
9394 // Rendering a visible tree.
9395 var _subtreeRenderLanes;
9396
9397 if (prevState !== null) {
9398 // We're going from hidden -> visible.
9399 _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes);
9400
9401 workInProgress.memoizedState = null;
9402 } else {
9403 // We weren't previously hidden, and we still aren't, so there's nothing
9404 // special to do. Need to push to the stack regardless, though, to avoid
9405 // a push/pop misalignment.
9406 _subtreeRenderLanes = renderLanes;
9407 }
9408
9409 pushRenderLanes(workInProgress, _subtreeRenderLanes);
9410 }
9411
9412 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
9413 return workInProgress.child;
9414} // Note: These happen to have identical begin phases, for now. We shouldn't hold
9415
9416function updateFragment(current, workInProgress, renderLanes) {
9417 var nextChildren = workInProgress.pendingProps;
9418 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
9419 return workInProgress.child;
9420}
9421
9422function updateMode(current, workInProgress, renderLanes) {
9423 var nextChildren = workInProgress.pendingProps.children;
9424 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
9425 return workInProgress.child;
9426}
9427
9428function updateProfiler(current, workInProgress, renderLanes) {
9429 {
9430 workInProgress.flags |= Update;
9431
9432 {
9433 // Reset effect durations for the next eventual effect phase.
9434 // These are reset during render to allow the DevTools commit hook a chance to read them,
9435 var stateNode = workInProgress.stateNode;
9436 stateNode.effectDuration = 0;
9437 stateNode.passiveEffectDuration = 0;
9438 }
9439 }
9440
9441 var nextProps = workInProgress.pendingProps;
9442 var nextChildren = nextProps.children;
9443 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
9444 return workInProgress.child;
9445}
9446
9447function markRef(current, workInProgress) {
9448 var ref = workInProgress.ref;
9449
9450 if (current === null && ref !== null || current !== null && current.ref !== ref) {
9451 // Schedule a Ref effect
9452 workInProgress.flags |= Ref;
9453 }
9454}
9455
9456function updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes) {
9457 {
9458 if (workInProgress.type !== workInProgress.elementType) {
9459 // Lazy component props can't be validated in createElement
9460 // because they're only guaranteed to be resolved here.
9461 var innerPropTypes = Component.propTypes;
9462
9463 if (innerPropTypes) {
9464 checkPropTypes(innerPropTypes, nextProps, // Resolved props
9465 'prop', getComponentNameFromType(Component));
9466 }
9467 }
9468 }
9469
9470 var context;
9471
9472 {
9473 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
9474 context = getMaskedContext(workInProgress, unmaskedContext);
9475 }
9476
9477 var nextChildren;
9478 prepareToReadContext(workInProgress, renderLanes);
9479
9480 {
9481 ReactCurrentOwner$1.current = workInProgress;
9482 setIsRendering(true);
9483 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes);
9484
9485 setIsRendering(false);
9486 }
9487
9488 if (current !== null && !didReceiveUpdate) {
9489 bailoutHooks(current, workInProgress, renderLanes);
9490 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
9491 }
9492
9493
9494 workInProgress.flags |= PerformedWork;
9495 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
9496 return workInProgress.child;
9497}
9498
9499function updateClassComponent(current, workInProgress, Component, nextProps, renderLanes) {
9500 {
9501 // This is used by DevTools to force a boundary to error.
9502 switch (shouldError(workInProgress)) {
9503 case false:
9504 {
9505 var _instance = workInProgress.stateNode;
9506 var ctor = workInProgress.type; // TODO This way of resetting the error boundary state is a hack.
9507 // Is there a better way to do this?
9508
9509 var tempInstance = new ctor(workInProgress.memoizedProps, _instance.context);
9510 var state = tempInstance.state;
9511
9512 _instance.updater.enqueueSetState(_instance, state, null);
9513
9514 break;
9515 }
9516
9517 case true:
9518 {
9519 workInProgress.flags |= DidCapture;
9520 workInProgress.flags |= ShouldCapture; // eslint-disable-next-line react-internal/prod-error-codes
9521
9522 var error$1 = new Error('Simulated error coming from DevTools');
9523 var lane = pickArbitraryLane(renderLanes);
9524 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); // Schedule the error boundary to re-render using updated state
9525
9526 var update = createClassErrorUpdate(workInProgress, createCapturedValueAtFiber(error$1, workInProgress), lane);
9527 enqueueCapturedUpdate(workInProgress, update);
9528 break;
9529 }
9530 }
9531
9532 if (workInProgress.type !== workInProgress.elementType) {
9533 // Lazy component props can't be validated in createElement
9534 // because they're only guaranteed to be resolved here.
9535 var innerPropTypes = Component.propTypes;
9536
9537 if (innerPropTypes) {
9538 checkPropTypes(innerPropTypes, nextProps, // Resolved props
9539 'prop', getComponentNameFromType(Component));
9540 }
9541 }
9542 } // Push context providers early to prevent context stack mismatches.
9543 // During mounting we don't know the child context yet as the instance doesn't exist.
9544 // We will invalidate the child context in finishClassComponent() right after rendering.
9545
9546
9547 var hasContext;
9548
9549 if (isContextProvider(Component)) {
9550 hasContext = true;
9551 pushContextProvider(workInProgress);
9552 } else {
9553 hasContext = false;
9554 }
9555
9556 prepareToReadContext(workInProgress, renderLanes);
9557 var instance = workInProgress.stateNode;
9558 var shouldUpdate;
9559
9560 if (instance === null) {
9561 resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); // In the initial pass we might need to construct the instance.
9562
9563 constructClassInstance(workInProgress, Component, nextProps);
9564 mountClassInstance(workInProgress, Component, nextProps, renderLanes);
9565 shouldUpdate = true;
9566 } else if (current === null) {
9567 // In a resume, we'll already have an instance we can reuse.
9568 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderLanes);
9569 } else {
9570 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderLanes);
9571 }
9572
9573 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes);
9574
9575 {
9576 var inst = workInProgress.stateNode;
9577
9578 if (shouldUpdate && inst.props !== nextProps) {
9579 if (!didWarnAboutReassigningProps) {
9580 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');
9581 }
9582
9583 didWarnAboutReassigningProps = true;
9584 }
9585 }
9586
9587 return nextUnitOfWork;
9588}
9589
9590function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes) {
9591 // Refs should update even if shouldComponentUpdate returns false
9592 markRef(current, workInProgress);
9593 var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags;
9594
9595 if (!shouldUpdate && !didCaptureError) {
9596 // Context providers should defer to sCU for rendering
9597 if (hasContext) {
9598 invalidateContextProvider(workInProgress, Component, false);
9599 }
9600
9601 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
9602 }
9603
9604 var instance = workInProgress.stateNode; // Rerender
9605
9606 ReactCurrentOwner$1.current = workInProgress;
9607 var nextChildren;
9608
9609 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
9610 // If we captured an error, but getDerivedStateFromError is not defined,
9611 // unmount all the children. componentDidCatch will schedule an update to
9612 // re-render a fallback. This is temporary until we migrate everyone to
9613 // the new API.
9614 // TODO: Warn in a future release.
9615 nextChildren = null;
9616
9617 {
9618 stopProfilerTimerIfRunning();
9619 }
9620 } else {
9621
9622 {
9623 setIsRendering(true);
9624 nextChildren = instance.render();
9625
9626 setIsRendering(false);
9627 }
9628 } // React DevTools reads this flag.
9629
9630
9631 workInProgress.flags |= PerformedWork;
9632
9633 if (current !== null && didCaptureError) {
9634 // If we're recovering from an error, reconcile without reusing any of
9635 // the existing children. Conceptually, the normal children and the children
9636 // that are shown on error are two different sets, so we shouldn't reuse
9637 // normal children even if their identities match.
9638 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes);
9639 } else {
9640 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
9641 } // Memoize state using the values we just used to render.
9642 // TODO: Restructure so we never read values from the instance.
9643
9644
9645 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
9646
9647 if (hasContext) {
9648 invalidateContextProvider(workInProgress, Component, true);
9649 }
9650
9651 return workInProgress.child;
9652}
9653
9654function pushHostRootContext(workInProgress) {
9655 var root = workInProgress.stateNode;
9656
9657 if (root.pendingContext) {
9658 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
9659 } else if (root.context) {
9660 // Should always be set
9661 pushTopLevelContextObject(workInProgress, root.context, false);
9662 }
9663
9664 pushHostContainer(workInProgress, root.containerInfo);
9665}
9666
9667function updateHostRoot(current, workInProgress, renderLanes) {
9668 pushHostRootContext(workInProgress);
9669
9670 if (current === null) {
9671 throw new Error('Should have a current fiber. This is a bug in React.');
9672 }
9673
9674 var nextProps = workInProgress.pendingProps;
9675 var prevState = workInProgress.memoizedState;
9676 var prevChildren = prevState.element;
9677 cloneUpdateQueue(current, workInProgress);
9678 processUpdateQueue(workInProgress, nextProps, null, renderLanes);
9679 var nextState = workInProgress.memoizedState;
9680 var root = workInProgress.stateNode;
9681 // being called "element".
9682
9683
9684 var nextChildren = nextState.element;
9685
9686 {
9687
9688 if (nextChildren === prevChildren) {
9689 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
9690 }
9691
9692 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
9693 }
9694
9695 return workInProgress.child;
9696}
9697
9698function updateHostComponent(current, workInProgress, renderLanes) {
9699 pushHostContext(workInProgress);
9700
9701 var type = workInProgress.type;
9702 var nextProps = workInProgress.pendingProps;
9703 var prevProps = current !== null ? current.memoizedProps : null;
9704 var nextChildren = nextProps.children;
9705
9706 if (prevProps !== null && shouldSetTextContent()) {
9707 // If we're switching from a direct text child to a normal child, or to
9708 // empty, we need to schedule the text content to be reset.
9709 workInProgress.flags |= ContentReset;
9710 }
9711
9712 markRef(current, workInProgress);
9713 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
9714 return workInProgress.child;
9715}
9716
9717function updateHostText(current, workInProgress) {
9718 // immediately after.
9719
9720
9721 return null;
9722}
9723
9724function mountLazyComponent(_current, workInProgress, elementType, renderLanes) {
9725 resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress);
9726 var props = workInProgress.pendingProps;
9727 var lazyComponent = elementType;
9728 var payload = lazyComponent._payload;
9729 var init = lazyComponent._init;
9730 var Component = init(payload); // Store the unwrapped component in the type.
9731
9732 workInProgress.type = Component;
9733 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
9734 var resolvedProps = resolveDefaultProps(Component, props);
9735 var child;
9736
9737 switch (resolvedTag) {
9738 case FunctionComponent:
9739 {
9740 {
9741 validateFunctionComponentInDev(workInProgress, Component);
9742 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
9743 }
9744
9745 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderLanes);
9746 return child;
9747 }
9748
9749 case ClassComponent:
9750 {
9751 {
9752 workInProgress.type = Component = resolveClassForHotReloading(Component);
9753 }
9754
9755 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderLanes);
9756 return child;
9757 }
9758
9759 case ForwardRef:
9760 {
9761 {
9762 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
9763 }
9764
9765 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderLanes);
9766 return child;
9767 }
9768
9769 case MemoComponent:
9770 {
9771 {
9772 if (workInProgress.type !== workInProgress.elementType) {
9773 var outerPropTypes = Component.propTypes;
9774
9775 if (outerPropTypes) {
9776 checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only
9777 'prop', getComponentNameFromType(Component));
9778 }
9779 }
9780 }
9781
9782 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
9783 renderLanes);
9784 return child;
9785 }
9786 }
9787
9788 var hint = '';
9789
9790 {
9791 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
9792 hint = ' Did you wrap a component in React.lazy() more than once?';
9793 }
9794 } // This message intentionally doesn't mention ForwardRef or MemoComponent
9795 // because the fact that it's a separate type of work is an
9796 // implementation detail.
9797
9798
9799 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));
9800}
9801
9802function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderLanes) {
9803 resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); // Promote the fiber to a class and try rendering again.
9804
9805 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`
9806 // Push context providers early to prevent context stack mismatches.
9807 // During mounting we don't know the child context yet as the instance doesn't exist.
9808 // We will invalidate the child context in finishClassComponent() right after rendering.
9809
9810 var hasContext;
9811
9812 if (isContextProvider(Component)) {
9813 hasContext = true;
9814 pushContextProvider(workInProgress);
9815 } else {
9816 hasContext = false;
9817 }
9818
9819 prepareToReadContext(workInProgress, renderLanes);
9820 constructClassInstance(workInProgress, Component, nextProps);
9821 mountClassInstance(workInProgress, Component, nextProps, renderLanes);
9822 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes);
9823}
9824
9825function mountIndeterminateComponent(_current, workInProgress, Component, renderLanes) {
9826 resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress);
9827 var props = workInProgress.pendingProps;
9828 var context;
9829
9830 {
9831 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
9832 context = getMaskedContext(workInProgress, unmaskedContext);
9833 }
9834
9835 prepareToReadContext(workInProgress, renderLanes);
9836 var value;
9837
9838 {
9839 if (Component.prototype && typeof Component.prototype.render === 'function') {
9840 var componentName = getComponentNameFromType(Component) || 'Unknown';
9841
9842 if (!didWarnAboutBadClass[componentName]) {
9843 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);
9844
9845 didWarnAboutBadClass[componentName] = true;
9846 }
9847 }
9848
9849 if (workInProgress.mode & StrictLegacyMode) {
9850 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
9851 }
9852
9853 setIsRendering(true);
9854 ReactCurrentOwner$1.current = workInProgress;
9855 value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes);
9856 setIsRendering(false);
9857 }
9858
9859
9860 workInProgress.flags |= PerformedWork;
9861
9862 {
9863 // Support for module components is deprecated and is removed behind a flag.
9864 // Whether or not it would crash later, we want to show a good message in DEV first.
9865 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
9866 var _componentName = getComponentNameFromType(Component) || 'Unknown';
9867
9868 if (!didWarnAboutModulePatternComponent[_componentName]) {
9869 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);
9870
9871 didWarnAboutModulePatternComponent[_componentName] = true;
9872 }
9873 }
9874 }
9875
9876 if ( // Run these checks in production only if the flag is off.
9877 // Eventually we'll delete this branch altogether.
9878 typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
9879 {
9880 var _componentName2 = getComponentNameFromType(Component) || 'Unknown';
9881
9882 if (!didWarnAboutModulePatternComponent[_componentName2]) {
9883 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);
9884
9885 didWarnAboutModulePatternComponent[_componentName2] = true;
9886 }
9887 } // Proceed under the assumption that this is a class instance
9888
9889
9890 workInProgress.tag = ClassComponent; // Throw out any hooks that were used.
9891
9892 workInProgress.memoizedState = null;
9893 workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches.
9894 // During mounting we don't know the child context yet as the instance doesn't exist.
9895 // We will invalidate the child context in finishClassComponent() right after rendering.
9896
9897 var hasContext = false;
9898
9899 if (isContextProvider(Component)) {
9900 hasContext = true;
9901 pushContextProvider(workInProgress);
9902 } else {
9903 hasContext = false;
9904 }
9905
9906 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
9907 initializeUpdateQueue(workInProgress);
9908 adoptClassInstance(workInProgress, value);
9909 mountClassInstance(workInProgress, Component, props, renderLanes);
9910 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes);
9911 } else {
9912 // Proceed under the assumption that this is a function component
9913 workInProgress.tag = FunctionComponent;
9914
9915 reconcileChildren(null, workInProgress, value, renderLanes);
9916
9917 {
9918 validateFunctionComponentInDev(workInProgress, Component);
9919 }
9920
9921 return workInProgress.child;
9922 }
9923}
9924
9925function validateFunctionComponentInDev(workInProgress, Component) {
9926 {
9927 if (Component) {
9928 if (Component.childContextTypes) {
9929 error('%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component');
9930 }
9931 }
9932
9933 if (workInProgress.ref !== null) {
9934 var info = '';
9935 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
9936
9937 if (ownerName) {
9938 info += '\n\nCheck the render method of `' + ownerName + '`.';
9939 }
9940
9941 var warningKey = ownerName || '';
9942 var debugSource = workInProgress._debugSource;
9943
9944 if (debugSource) {
9945 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
9946 }
9947
9948 if (!didWarnAboutFunctionRefs[warningKey]) {
9949 didWarnAboutFunctionRefs[warningKey] = true;
9950
9951 error('Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
9952 }
9953 }
9954
9955 if (typeof Component.getDerivedStateFromProps === 'function') {
9956 var _componentName3 = getComponentNameFromType(Component) || 'Unknown';
9957
9958 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) {
9959 error('%s: Function components do not support getDerivedStateFromProps.', _componentName3);
9960
9961 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true;
9962 }
9963 }
9964
9965 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
9966 var _componentName4 = getComponentNameFromType(Component) || 'Unknown';
9967
9968 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) {
9969 error('%s: Function components do not support contextType.', _componentName4);
9970
9971 didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true;
9972 }
9973 }
9974 }
9975}
9976
9977var SUSPENDED_MARKER = {
9978 dehydrated: null,
9979 treeContext: null,
9980 retryLane: NoLane
9981};
9982
9983function mountSuspenseOffscreenState(renderLanes) {
9984 return {
9985 baseLanes: renderLanes,
9986 cachePool: getSuspendedCache(),
9987 transitions: null
9988 };
9989}
9990
9991function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) {
9992 var cachePool = null;
9993
9994 return {
9995 baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes),
9996 cachePool: cachePool,
9997 transitions: prevOffscreenState.transitions
9998 };
9999} // TODO: Probably should inline this back
10000
10001
10002function shouldRemainOnFallback(suspenseContext, current, workInProgress, renderLanes) {
10003 // If we're already showing a fallback, there are cases where we need to
10004 // remain on that fallback regardless of whether the content has resolved.
10005 // For example, SuspenseList coordinates when nested content appears.
10006 if (current !== null) {
10007 var suspenseState = current.memoizedState;
10008
10009 if (suspenseState === null) {
10010 // Currently showing content. Don't hide it, even if ForceSuspenseFallback
10011 // is true. More precise name might be "ForceRemainSuspenseFallback".
10012 // Note: This is a factoring smell. Can't remain on a fallback if there's
10013 // no fallback to remain on.
10014 return false;
10015 }
10016 } // Not currently showing content. Consult the Suspense context.
10017
10018
10019 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
10020}
10021
10022function getRemainingWorkInPrimaryTree(current, renderLanes) {
10023 // TODO: Should not remove render lanes that were pinged during this render
10024 return removeLanes(current.childLanes, renderLanes);
10025}
10026
10027function updateSuspenseComponent(current, workInProgress, renderLanes) {
10028 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
10029
10030 {
10031 if (shouldSuspend(workInProgress)) {
10032 workInProgress.flags |= DidCapture;
10033 }
10034 }
10035
10036 var suspenseContext = suspenseStackCursor.current;
10037 var showFallback = false;
10038 var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags;
10039
10040 if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) {
10041 // Something in this boundary's subtree already suspended. Switch to
10042 // rendering the fallback children.
10043 showFallback = true;
10044 workInProgress.flags &= ~DidCapture;
10045 } else {
10046 // Attempting the main content
10047 if (current === null || current.memoizedState !== null) {
10048 // This is a new mount or this boundary is already showing a fallback state.
10049 // Mark this subtree context as having at least one invisible parent that could
10050 // handle the fallback state.
10051 // Avoided boundaries are not considered since they cannot handle preferred fallback states.
10052 {
10053 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
10054 }
10055 }
10056 }
10057
10058 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
10059 pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense
10060 // boundary's children. This involves some custom reconciliation logic. Two
10061 // main reasons this is so complicated.
10062 //
10063 // First, Legacy Mode has different semantics for backwards compatibility. The
10064 // primary tree will commit in an inconsistent state, so when we do the
10065 // second pass to render the fallback, we do some exceedingly, uh, clever
10066 // hacks to make that not totally break. Like transferring effects and
10067 // deletions from hidden tree. In Concurrent Mode, it's much simpler,
10068 // because we bailout on the primary tree completely and leave it in its old
10069 // state, no effects. Same as what we do for Offscreen (except that
10070 // Offscreen doesn't have the first render pass).
10071 //
10072 // Second is hydration. During hydration, the Suspense fiber has a slightly
10073 // different layout, where the child points to a dehydrated fragment, which
10074 // contains the DOM rendered by the server.
10075 //
10076 // Third, even if you set all that aside, Suspense is like error boundaries in
10077 // that we first we try to render one tree, and if that fails, we render again
10078 // and switch to a different tree. Like a try/catch block. So we have to track
10079 // which branch we're currently rendering. Ideally we would model this using
10080 // a stack.
10081
10082 if (current === null) {
10083
10084 var suspenseState = workInProgress.memoizedState;
10085
10086 if (suspenseState !== null) {
10087 var dehydrated = suspenseState.dehydrated;
10088
10089 if (dehydrated !== null) {
10090 return mountDehydratedSuspenseComponent(workInProgress);
10091 }
10092 }
10093
10094 var nextPrimaryChildren = nextProps.children;
10095 var nextFallbackChildren = nextProps.fallback;
10096
10097 if (showFallback) {
10098 var fallbackFragment = mountSuspenseFallbackChildren(workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes);
10099 var primaryChildFragment = workInProgress.child;
10100 primaryChildFragment.memoizedState = mountSuspenseOffscreenState(renderLanes);
10101 workInProgress.memoizedState = SUSPENDED_MARKER;
10102
10103 return fallbackFragment;
10104 } else {
10105 return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren);
10106 }
10107 } else {
10108 // This is an update.
10109 // Special path for hydration
10110 var prevState = current.memoizedState;
10111
10112 if (prevState !== null) {
10113 var _dehydrated = prevState.dehydrated;
10114
10115 if (_dehydrated !== null) {
10116 return updateDehydratedSuspenseComponent(current, workInProgress, didSuspend, nextProps, _dehydrated, prevState, renderLanes);
10117 }
10118 }
10119
10120 if (showFallback) {
10121 var _nextFallbackChildren = nextProps.fallback;
10122 var _nextPrimaryChildren = nextProps.children;
10123 var fallbackChildFragment = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren, _nextFallbackChildren, renderLanes);
10124 var _primaryChildFragment2 = workInProgress.child;
10125 var prevOffscreenState = current.child.memoizedState;
10126 _primaryChildFragment2.memoizedState = prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(prevOffscreenState, renderLanes);
10127
10128 _primaryChildFragment2.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes);
10129 workInProgress.memoizedState = SUSPENDED_MARKER;
10130 return fallbackChildFragment;
10131 } else {
10132 var _nextPrimaryChildren2 = nextProps.children;
10133
10134 var _primaryChildFragment3 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren2, renderLanes);
10135
10136 workInProgress.memoizedState = null;
10137 return _primaryChildFragment3;
10138 }
10139 }
10140}
10141
10142function mountSuspensePrimaryChildren(workInProgress, primaryChildren, renderLanes) {
10143 var mode = workInProgress.mode;
10144 var primaryChildProps = {
10145 mode: 'visible',
10146 children: primaryChildren
10147 };
10148 var primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode);
10149 primaryChildFragment.return = workInProgress;
10150 workInProgress.child = primaryChildFragment;
10151 return primaryChildFragment;
10152}
10153
10154function mountSuspenseFallbackChildren(workInProgress, primaryChildren, fallbackChildren, renderLanes) {
10155 var mode = workInProgress.mode;
10156 var progressedPrimaryFragment = workInProgress.child;
10157 var primaryChildProps = {
10158 mode: 'hidden',
10159 children: primaryChildren
10160 };
10161 var primaryChildFragment;
10162 var fallbackChildFragment;
10163
10164 if ((mode & ConcurrentMode) === NoMode && progressedPrimaryFragment !== null) {
10165 // In legacy mode, we commit the primary tree as if it successfully
10166 // completed, even though it's in an inconsistent state.
10167 primaryChildFragment = progressedPrimaryFragment;
10168 primaryChildFragment.childLanes = NoLanes;
10169 primaryChildFragment.pendingProps = primaryChildProps;
10170
10171 if ( workInProgress.mode & ProfileMode) {
10172 // Reset the durations from the first pass so they aren't included in the
10173 // final amounts. This seems counterintuitive, since we're intentionally
10174 // not measuring part of the render phase, but this makes it match what we
10175 // do in Concurrent Mode.
10176 primaryChildFragment.actualDuration = 0;
10177 primaryChildFragment.actualStartTime = -1;
10178 primaryChildFragment.selfBaseDuration = 0;
10179 primaryChildFragment.treeBaseDuration = 0;
10180 }
10181
10182 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null);
10183 } else {
10184 primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode);
10185 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null);
10186 }
10187
10188 primaryChildFragment.return = workInProgress;
10189 fallbackChildFragment.return = workInProgress;
10190 primaryChildFragment.sibling = fallbackChildFragment;
10191 workInProgress.child = primaryChildFragment;
10192 return fallbackChildFragment;
10193}
10194
10195function mountWorkInProgressOffscreenFiber(offscreenProps, mode, renderLanes) {
10196 // The props argument to `createFiberFromOffscreen` is `any` typed, so we use
10197 // this wrapper function to constrain it.
10198 return createFiberFromOffscreen(offscreenProps, mode, NoLanes, null);
10199}
10200
10201function updateWorkInProgressOffscreenFiber(current, offscreenProps) {
10202 // The props argument to `createWorkInProgress` is `any` typed, so we use this
10203 // wrapper function to constrain it.
10204 return createWorkInProgress(current, offscreenProps);
10205}
10206
10207function updateSuspensePrimaryChildren(current, workInProgress, primaryChildren, renderLanes) {
10208 var currentPrimaryChildFragment = current.child;
10209 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
10210 var primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, {
10211 mode: 'visible',
10212 children: primaryChildren
10213 });
10214
10215 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
10216 primaryChildFragment.lanes = renderLanes;
10217 }
10218
10219 primaryChildFragment.return = workInProgress;
10220 primaryChildFragment.sibling = null;
10221
10222 if (currentFallbackChildFragment !== null) {
10223 // Delete the fallback child fragment
10224 var deletions = workInProgress.deletions;
10225
10226 if (deletions === null) {
10227 workInProgress.deletions = [currentFallbackChildFragment];
10228 workInProgress.flags |= ChildDeletion;
10229 } else {
10230 deletions.push(currentFallbackChildFragment);
10231 }
10232 }
10233
10234 workInProgress.child = primaryChildFragment;
10235 return primaryChildFragment;
10236}
10237
10238function updateSuspenseFallbackChildren(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) {
10239 var mode = workInProgress.mode;
10240 var currentPrimaryChildFragment = current.child;
10241 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
10242 var primaryChildProps = {
10243 mode: 'hidden',
10244 children: primaryChildren
10245 };
10246 var primaryChildFragment;
10247
10248 if ( // In legacy mode, we commit the primary tree as if it successfully
10249 // completed, even though it's in an inconsistent state.
10250 (mode & ConcurrentMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was
10251 // already cloned. In legacy mode, the only case where this isn't true is
10252 // when DevTools forces us to display a fallback; we skip the first render
10253 // pass entirely and go straight to rendering the fallback. (In Concurrent
10254 // Mode, SuspenseList can also trigger this scenario, but this is a legacy-
10255 // only codepath.)
10256 workInProgress.child !== currentPrimaryChildFragment) {
10257 var progressedPrimaryFragment = workInProgress.child;
10258 primaryChildFragment = progressedPrimaryFragment;
10259 primaryChildFragment.childLanes = NoLanes;
10260 primaryChildFragment.pendingProps = primaryChildProps;
10261
10262 if ( workInProgress.mode & ProfileMode) {
10263 // Reset the durations from the first pass so they aren't included in the
10264 // final amounts. This seems counterintuitive, since we're intentionally
10265 // not measuring part of the render phase, but this makes it match what we
10266 // do in Concurrent Mode.
10267 primaryChildFragment.actualDuration = 0;
10268 primaryChildFragment.actualStartTime = -1;
10269 primaryChildFragment.selfBaseDuration = currentPrimaryChildFragment.selfBaseDuration;
10270 primaryChildFragment.treeBaseDuration = currentPrimaryChildFragment.treeBaseDuration;
10271 } // The fallback fiber was added as a deletion during the first pass.
10272 // However, since we're going to remain on the fallback, we no longer want
10273 // to delete it.
10274
10275
10276 workInProgress.deletions = null;
10277 } else {
10278 primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, primaryChildProps); // Since we're reusing a current tree, we need to reuse the flags, too.
10279 // (We don't do this in legacy mode, because in legacy mode we don't re-use
10280 // the current tree; see previous branch.)
10281
10282 primaryChildFragment.subtreeFlags = currentPrimaryChildFragment.subtreeFlags & StaticMask;
10283 }
10284
10285 var fallbackChildFragment;
10286
10287 if (currentFallbackChildFragment !== null) {
10288 fallbackChildFragment = createWorkInProgress(currentFallbackChildFragment, fallbackChildren);
10289 } else {
10290 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null); // Needs a placement effect because the parent (the Suspense boundary) already
10291 // mounted but this is a new fiber.
10292
10293 fallbackChildFragment.flags |= Placement;
10294 }
10295
10296 fallbackChildFragment.return = workInProgress;
10297 primaryChildFragment.return = workInProgress;
10298 primaryChildFragment.sibling = fallbackChildFragment;
10299 workInProgress.child = primaryChildFragment;
10300 return fallbackChildFragment;
10301}
10302
10303function retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, recoverableError) {
10304 // Falling back to client rendering. Because this has performance
10305 // implications, it's considered a recoverable error, even though the user
10306 // likely won't observe anything wrong with the UI.
10307 //
10308 // The error is passed in as an argument to enforce that every caller provide
10309 // a custom message, or explicitly opt out (currently the only path that opts
10310 // out is legacy mode; every concurrent path provides an error).
10311 if (recoverableError !== null) {
10312 queueHydrationError(recoverableError);
10313 } // This will add the old fiber to the deletion list
10314
10315
10316 reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated.
10317
10318 var nextProps = workInProgress.pendingProps;
10319 var primaryChildren = nextProps.children;
10320 var primaryChildFragment = mountSuspensePrimaryChildren(workInProgress, primaryChildren); // Needs a placement effect because the parent (the Suspense boundary) already
10321 // mounted but this is a new fiber.
10322
10323 primaryChildFragment.flags |= Placement;
10324 workInProgress.memoizedState = null;
10325 return primaryChildFragment;
10326}
10327
10328function mountSuspenseFallbackAfterRetryWithoutHydrating(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) {
10329 var fiberMode = workInProgress.mode;
10330 var primaryChildProps = {
10331 mode: 'visible',
10332 children: primaryChildren
10333 };
10334 var primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, fiberMode);
10335 var fallbackChildFragment = createFiberFromFragment(fallbackChildren, fiberMode, renderLanes, null); // Needs a placement effect because the parent (the Suspense
10336 // boundary) already mounted but this is a new fiber.
10337
10338 fallbackChildFragment.flags |= Placement;
10339 primaryChildFragment.return = workInProgress;
10340 fallbackChildFragment.return = workInProgress;
10341 primaryChildFragment.sibling = fallbackChildFragment;
10342 workInProgress.child = primaryChildFragment;
10343
10344 if ((workInProgress.mode & ConcurrentMode) !== NoMode) {
10345 // We will have dropped the effect list which contains the
10346 // deletion. We need to reconcile to delete the current child.
10347 reconcileChildFibers(workInProgress, current.child, null, renderLanes);
10348 }
10349
10350 return fallbackChildFragment;
10351}
10352
10353function mountDehydratedSuspenseComponent(workInProgress, suspenseInstance, renderLanes) {
10354 // During the first pass, we'll bail out and not drill into the children.
10355 // Instead, we'll leave the content in place and try to hydrate it later.
10356 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
10357 {
10358 error('Cannot hydrate Suspense in legacy mode. Switch from ' + 'ReactDOM.hydrate(element, container) to ' + 'ReactDOMClient.hydrateRoot(container, <App />)' + '.render(element) or remove the Suspense components from ' + 'the server rendered components.');
10359 }
10360
10361 workInProgress.lanes = laneToLanes(SyncLane);
10362 } else if (isSuspenseInstanceFallback()) {
10363 // This is a client-only boundary. Since we won't get any content from the server
10364 // for this, we need to schedule that at a higher priority based on when it would
10365 // have timed out. In theory we could render it in this pass but it would have the
10366 // wrong priority associated with it and will prevent hydration of parent path.
10367 // Instead, we'll leave work left on it to render it in a separate commit.
10368 // TODO This time should be the time at which the server rendered response that is
10369 // a parent to this boundary was displayed. However, since we currently don't have
10370 // a protocol to transfer that time, we'll just estimate it by using the current
10371 // time. This will mean that Suspense timeouts are slightly shifted to later than
10372 // they should be.
10373 // Schedule a normal pri update to render this content.
10374 workInProgress.lanes = laneToLanes(DefaultHydrationLane);
10375 } else {
10376 // We'll continue hydrating the rest at offscreen priority since we'll already
10377 // be showing the right content coming from the server, it is no rush.
10378 workInProgress.lanes = laneToLanes(OffscreenLane);
10379 }
10380
10381 return null;
10382}
10383
10384function updateDehydratedSuspenseComponent(current, workInProgress, didSuspend, nextProps, suspenseInstance, suspenseState, renderLanes) {
10385 if (!didSuspend) {
10386
10387 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
10388 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, // TODO: When we delete legacy mode, we should make this error argument
10389 // required — every concurrent mode path that causes hydration to
10390 // de-opt to client rendering should have an error message.
10391 null);
10392 }
10393
10394 if (isSuspenseInstanceFallback()) {
10395 // This boundary is in a permanent fallback state. In this case, we'll never
10396 // get an update and we'll never be able to hydrate the final content. Let's just try the
10397 // client side render instead.
10398 var digest, message, stack;
10399
10400 {
10401 var _getSuspenseInstanceF = getSuspenseInstanceFallbackErrorDetails();
10402
10403 digest = _getSuspenseInstanceF.digest;
10404 message = _getSuspenseInstanceF.message;
10405 stack = _getSuspenseInstanceF.stack;
10406 }
10407
10408 var error;
10409
10410 if (message) {
10411 // eslint-disable-next-line react-internal/prod-error-codes
10412 error = new Error(message);
10413 } else {
10414 error = new Error('The server could not finish this Suspense boundary, likely ' + 'due to an error during server rendering. Switched to ' + 'client rendering.');
10415 }
10416
10417 var capturedValue = createCapturedValue(error, digest, stack);
10418 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, capturedValue);
10419 }
10420 // any context has changed, we need to treat is as if the input might have changed.
10421
10422
10423 var hasContextChanged = includesSomeLane(renderLanes, current.childLanes);
10424
10425 if (didReceiveUpdate || hasContextChanged) {
10426 // This boundary has changed since the first render. This means that we are now unable to
10427 // hydrate it. We might still be able to hydrate it using a higher priority lane.
10428 var root = getWorkInProgressRoot();
10429
10430 if (root !== null) {
10431 var attemptHydrationAtLane = getBumpedLaneForHydration(root, renderLanes);
10432
10433 if (attemptHydrationAtLane !== NoLane && attemptHydrationAtLane !== suspenseState.retryLane) {
10434 // Intentionally mutating since this render will get interrupted. This
10435 // is one of the very rare times where we mutate the current tree
10436 // during the render phase.
10437 suspenseState.retryLane = attemptHydrationAtLane; // TODO: Ideally this would inherit the event time of the current render
10438
10439 var eventTime = NoTimestamp;
10440 enqueueConcurrentRenderForLane(current, attemptHydrationAtLane);
10441 scheduleUpdateOnFiber(root, current, attemptHydrationAtLane, eventTime);
10442 }
10443 } // If we have scheduled higher pri work above, this will probably just abort the render
10444 // since we now have higher priority work, but in case it doesn't, we need to prepare to
10445 // render something, if we time out. Even if that requires us to delete everything and
10446 // skip hydration.
10447 // Delay having to do this as long as the suspense timeout allows us.
10448
10449
10450 renderDidSuspendDelayIfPossible();
10451
10452 var _capturedValue = createCapturedValue(new Error('This Suspense boundary received an update before it finished ' + 'hydrating. This caused the boundary to switch to client rendering. ' + 'The usual way to fix this is to wrap the original update ' + 'in startTransition.'));
10453
10454 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, _capturedValue);
10455 } else if (isSuspenseInstancePending()) {
10456 // This component is still pending more data from the server, so we can't hydrate its
10457 // content. We treat it as if this component suspended itself. It might seem as if
10458 // we could just try to render it client-side instead. However, this will perform a
10459 // lot of unnecessary work and is unlikely to complete since it often will suspend
10460 // on missing data anyway. Additionally, the server might be able to render more
10461 // than we can on the client yet. In that case we'd end up with more fallback states
10462 // on the client than if we just leave it alone. If the server times out or errors
10463 // these should update this boundary to the permanent Fallback state instead.
10464 // Mark it as having captured (i.e. suspended).
10465 workInProgress.flags |= DidCapture; // Leave the child in place. I.e. the dehydrated fragment.
10466
10467 workInProgress.child = current.child; // Register a callback to retry this boundary once the server has sent the result.
10468
10469 var retry = retryDehydratedSuspenseBoundary.bind(null, current);
10470 registerSuspenseInstanceRetry();
10471 return null;
10472 } else {
10473 // This is the first attempt.
10474 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress, suspenseInstance, suspenseState.treeContext);
10475 var primaryChildren = nextProps.children;
10476 var primaryChildFragment = mountSuspensePrimaryChildren(workInProgress, primaryChildren); // Mark the children as hydrating. This is a fast path to know whether this
10477 // tree is part of a hydrating tree. This is used to determine if a child
10478 // node has fully mounted yet, and for scheduling event replaying.
10479 // Conceptually this is similar to Placement in that a new subtree is
10480 // inserted into the React tree here. It just happens to not need DOM
10481 // mutations because it already exists.
10482
10483 primaryChildFragment.flags |= Hydrating;
10484 return primaryChildFragment;
10485 }
10486 } else {
10487 // This is the second render pass. We already attempted to hydrated, but
10488 // something either suspended or errored.
10489 if (workInProgress.flags & ForceClientRender) {
10490 // Something errored during hydration. Try again without hydrating.
10491 workInProgress.flags &= ~ForceClientRender;
10492
10493 var _capturedValue2 = createCapturedValue(new Error('There was an error while hydrating this Suspense boundary. ' + 'Switched to client rendering.'));
10494
10495 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, _capturedValue2);
10496 } else if (workInProgress.memoizedState !== null) {
10497 // Something suspended and we should still be in dehydrated mode.
10498 // Leave the existing child in place.
10499 workInProgress.child = current.child; // The dehydrated completion pass expects this flag to be there
10500 // but the normal suspense pass doesn't.
10501
10502 workInProgress.flags |= DidCapture;
10503 return null;
10504 } else {
10505 // Suspended but we should no longer be in dehydrated mode.
10506 // Therefore we now have to render the fallback.
10507 var nextPrimaryChildren = nextProps.children;
10508 var nextFallbackChildren = nextProps.fallback;
10509 var fallbackChildFragment = mountSuspenseFallbackAfterRetryWithoutHydrating(current, workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes);
10510 var _primaryChildFragment4 = workInProgress.child;
10511 _primaryChildFragment4.memoizedState = mountSuspenseOffscreenState(renderLanes);
10512 workInProgress.memoizedState = SUSPENDED_MARKER;
10513 return fallbackChildFragment;
10514 }
10515 }
10516}
10517
10518function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) {
10519 fiber.lanes = mergeLanes(fiber.lanes, renderLanes);
10520 var alternate = fiber.alternate;
10521
10522 if (alternate !== null) {
10523 alternate.lanes = mergeLanes(alternate.lanes, renderLanes);
10524 }
10525
10526 scheduleContextWorkOnParentPath(fiber.return, renderLanes, propagationRoot);
10527}
10528
10529function propagateSuspenseContextChange(workInProgress, firstChild, renderLanes) {
10530 // Mark any Suspense boundaries with fallbacks as having work to do.
10531 // If they were previously forced into fallbacks, they may now be able
10532 // to unblock.
10533 var node = firstChild;
10534
10535 while (node !== null) {
10536 if (node.tag === SuspenseComponent) {
10537 var state = node.memoizedState;
10538
10539 if (state !== null) {
10540 scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress);
10541 }
10542 } else if (node.tag === SuspenseListComponent) {
10543 // If the tail is hidden there might not be an Suspense boundaries
10544 // to schedule work on. In this case we have to schedule it on the
10545 // list itself.
10546 // We don't have to traverse to the children of the list since
10547 // the list will propagate the change when it rerenders.
10548 scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress);
10549 } else if (node.child !== null) {
10550 node.child.return = node;
10551 node = node.child;
10552 continue;
10553 }
10554
10555 if (node === workInProgress) {
10556 return;
10557 }
10558
10559 while (node.sibling === null) {
10560 if (node.return === null || node.return === workInProgress) {
10561 return;
10562 }
10563
10564 node = node.return;
10565 }
10566
10567 node.sibling.return = node.return;
10568 node = node.sibling;
10569 }
10570}
10571
10572function findLastContentRow(firstChild) {
10573 // This is going to find the last row among these children that is already
10574 // showing content on the screen, as opposed to being in fallback state or
10575 // new. If a row has multiple Suspense boundaries, any of them being in the
10576 // fallback state, counts as the whole row being in a fallback state.
10577 // Note that the "rows" will be workInProgress, but any nested children
10578 // will still be current since we haven't rendered them yet. The mounted
10579 // order may not be the same as the new order. We use the new order.
10580 var row = firstChild;
10581 var lastContentRow = null;
10582
10583 while (row !== null) {
10584 var currentRow = row.alternate; // New rows can't be content rows.
10585
10586 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
10587 lastContentRow = row;
10588 }
10589
10590 row = row.sibling;
10591 }
10592
10593 return lastContentRow;
10594}
10595
10596function validateRevealOrder(revealOrder) {
10597 {
10598 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
10599 didWarnAboutRevealOrder[revealOrder] = true;
10600
10601 if (typeof revealOrder === 'string') {
10602 switch (revealOrder.toLowerCase()) {
10603 case 'together':
10604 case 'forwards':
10605 case 'backwards':
10606 {
10607 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
10608
10609 break;
10610 }
10611
10612 case 'forward':
10613 case 'backward':
10614 {
10615 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());
10616
10617 break;
10618 }
10619
10620 default:
10621 error('"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
10622
10623 break;
10624 }
10625 } else {
10626 error('%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
10627 }
10628 }
10629 }
10630}
10631
10632function validateTailOptions(tailMode, revealOrder) {
10633 {
10634 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
10635 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
10636 didWarnAboutTailOptions[tailMode] = true;
10637
10638 error('"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
10639 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
10640 didWarnAboutTailOptions[tailMode] = true;
10641
10642 error('<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
10643 }
10644 }
10645 }
10646}
10647
10648function validateSuspenseListNestedChild(childSlot, index) {
10649 {
10650 var isAnArray = isArray(childSlot);
10651 var isIterable = !isAnArray && typeof getIteratorFn(childSlot) === 'function';
10652
10653 if (isAnArray || isIterable) {
10654 var type = isAnArray ? 'array' : 'iterable';
10655
10656 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);
10657
10658 return false;
10659 }
10660 }
10661
10662 return true;
10663}
10664
10665function validateSuspenseListChildren(children, revealOrder) {
10666 {
10667 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
10668 if (isArray(children)) {
10669 for (var i = 0; i < children.length; i++) {
10670 if (!validateSuspenseListNestedChild(children[i], i)) {
10671 return;
10672 }
10673 }
10674 } else {
10675 var iteratorFn = getIteratorFn(children);
10676
10677 if (typeof iteratorFn === 'function') {
10678 var childrenIterator = iteratorFn.call(children);
10679
10680 if (childrenIterator) {
10681 var step = childrenIterator.next();
10682 var _i = 0;
10683
10684 for (; !step.done; step = childrenIterator.next()) {
10685 if (!validateSuspenseListNestedChild(step.value, _i)) {
10686 return;
10687 }
10688
10689 _i++;
10690 }
10691 }
10692 } else {
10693 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);
10694 }
10695 }
10696 }
10697 }
10698}
10699
10700function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode) {
10701 var renderState = workInProgress.memoizedState;
10702
10703 if (renderState === null) {
10704 workInProgress.memoizedState = {
10705 isBackwards: isBackwards,
10706 rendering: null,
10707 renderingStartTime: 0,
10708 last: lastContentRow,
10709 tail: tail,
10710 tailMode: tailMode
10711 };
10712 } else {
10713 // We can reuse the existing object from previous renders.
10714 renderState.isBackwards = isBackwards;
10715 renderState.rendering = null;
10716 renderState.renderingStartTime = 0;
10717 renderState.last = lastContentRow;
10718 renderState.tail = tail;
10719 renderState.tailMode = tailMode;
10720 }
10721} // This can end up rendering this component multiple passes.
10722// The first pass splits the children fibers into two sets. A head and tail.
10723// We first render the head. If anything is in fallback state, we do another
10724// pass through beginWork to rerender all children (including the tail) with
10725// the force suspend context. If the first render didn't have anything in
10726// in fallback state. Then we render each row in the tail one-by-one.
10727// That happens in the completeWork phase without going back to beginWork.
10728
10729
10730function updateSuspenseListComponent(current, workInProgress, renderLanes) {
10731 var nextProps = workInProgress.pendingProps;
10732 var revealOrder = nextProps.revealOrder;
10733 var tailMode = nextProps.tail;
10734 var newChildren = nextProps.children;
10735 validateRevealOrder(revealOrder);
10736 validateTailOptions(tailMode, revealOrder);
10737 validateSuspenseListChildren(newChildren, revealOrder);
10738 reconcileChildren(current, workInProgress, newChildren, renderLanes);
10739 var suspenseContext = suspenseStackCursor.current;
10740 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
10741
10742 if (shouldForceFallback) {
10743 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
10744 workInProgress.flags |= DidCapture;
10745 } else {
10746 var didSuspendBefore = current !== null && (current.flags & DidCapture) !== NoFlags;
10747
10748 if (didSuspendBefore) {
10749 // If we previously forced a fallback, we need to schedule work
10750 // on any nested boundaries to let them know to try to render
10751 // again. This is the same as context updating.
10752 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderLanes);
10753 }
10754
10755 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
10756 }
10757
10758 pushSuspenseContext(workInProgress, suspenseContext);
10759
10760 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
10761 // In legacy mode, SuspenseList doesn't work so we just
10762 // use make it a noop by treating it as the default revealOrder.
10763 workInProgress.memoizedState = null;
10764 } else {
10765 switch (revealOrder) {
10766 case 'forwards':
10767 {
10768 var lastContentRow = findLastContentRow(workInProgress.child);
10769 var tail;
10770
10771 if (lastContentRow === null) {
10772 // The whole list is part of the tail.
10773 // TODO: We could fast path by just rendering the tail now.
10774 tail = workInProgress.child;
10775 workInProgress.child = null;
10776 } else {
10777 // Disconnect the tail rows after the content row.
10778 // We're going to render them separately later.
10779 tail = lastContentRow.sibling;
10780 lastContentRow.sibling = null;
10781 }
10782
10783 initSuspenseListRenderState(workInProgress, false, // isBackwards
10784 tail, lastContentRow, tailMode);
10785 break;
10786 }
10787
10788 case 'backwards':
10789 {
10790 // We're going to find the first row that has existing content.
10791 // At the same time we're going to reverse the list of everything
10792 // we pass in the meantime. That's going to be our tail in reverse
10793 // order.
10794 var _tail = null;
10795 var row = workInProgress.child;
10796 workInProgress.child = null;
10797
10798 while (row !== null) {
10799 var currentRow = row.alternate; // New rows can't be content rows.
10800
10801 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
10802 // This is the beginning of the main content.
10803 workInProgress.child = row;
10804 break;
10805 }
10806
10807 var nextRow = row.sibling;
10808 row.sibling = _tail;
10809 _tail = row;
10810 row = nextRow;
10811 } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
10812
10813
10814 initSuspenseListRenderState(workInProgress, true, // isBackwards
10815 _tail, null, // last
10816 tailMode);
10817 break;
10818 }
10819
10820 case 'together':
10821 {
10822 initSuspenseListRenderState(workInProgress, false, // isBackwards
10823 null, // tail
10824 null, // last
10825 undefined);
10826 break;
10827 }
10828
10829 default:
10830 {
10831 // The default reveal order is the same as not having
10832 // a boundary.
10833 workInProgress.memoizedState = null;
10834 }
10835 }
10836 }
10837
10838 return workInProgress.child;
10839}
10840
10841function updatePortalComponent(current, workInProgress, renderLanes) {
10842 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
10843 var nextChildren = workInProgress.pendingProps;
10844
10845 if (current === null) {
10846 // Portals are special because we don't append the children during mount
10847 // but at commit. Therefore we need to track insertions which the normal
10848 // flow doesn't do during mount. This doesn't happen at the root because
10849 // the root always starts with a "current" with a null child.
10850 // TODO: Consider unifying this with how the root works.
10851 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes);
10852 } else {
10853 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
10854 }
10855
10856 return workInProgress.child;
10857}
10858
10859var hasWarnedAboutUsingNoValuePropOnContextProvider = false;
10860
10861function updateContextProvider(current, workInProgress, renderLanes) {
10862 var providerType = workInProgress.type;
10863 var context = providerType._context;
10864 var newProps = workInProgress.pendingProps;
10865 var oldProps = workInProgress.memoizedProps;
10866 var newValue = newProps.value;
10867
10868 {
10869 if (!('value' in newProps)) {
10870 if (!hasWarnedAboutUsingNoValuePropOnContextProvider) {
10871 hasWarnedAboutUsingNoValuePropOnContextProvider = true;
10872
10873 error('The `value` prop is required for the `<Context.Provider>`. Did you misspell it or forget to pass it?');
10874 }
10875 }
10876
10877 var providerPropTypes = workInProgress.type.propTypes;
10878
10879 if (providerPropTypes) {
10880 checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider');
10881 }
10882 }
10883
10884 pushProvider(workInProgress, context, newValue);
10885
10886 {
10887 if (oldProps !== null) {
10888 var oldValue = oldProps.value;
10889
10890 if (objectIs(oldValue, newValue)) {
10891 // No change. Bailout early if children are the same.
10892 if (oldProps.children === newProps.children && !hasContextChanged()) {
10893 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
10894 }
10895 } else {
10896 // The context value changed. Search for matching consumers and schedule
10897 // them to update.
10898 propagateContextChange(workInProgress, context, renderLanes);
10899 }
10900 }
10901 }
10902
10903 var newChildren = newProps.children;
10904 reconcileChildren(current, workInProgress, newChildren, renderLanes);
10905 return workInProgress.child;
10906}
10907
10908var hasWarnedAboutUsingContextAsConsumer = false;
10909
10910function updateContextConsumer(current, workInProgress, renderLanes) {
10911 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In
10912 // DEV mode, we create a separate object for Context.Consumer that acts
10913 // like a proxy to Context. This proxy object adds unnecessary code in PROD
10914 // so we use the old behaviour (Context.Consumer references Context) to
10915 // reduce size and overhead. The separate object references context via
10916 // a property called "_context", which also gives us the ability to check
10917 // in DEV mode if this property exists or not and warn if it does not.
10918
10919 {
10920 if (context._context === undefined) {
10921 // This may be because it's a Context (rather than a Consumer).
10922 // Or it may be because it's older React where they're the same thing.
10923 // We only want to warn if we're sure it's a new React.
10924 if (context !== context.Consumer) {
10925 if (!hasWarnedAboutUsingContextAsConsumer) {
10926 hasWarnedAboutUsingContextAsConsumer = true;
10927
10928 error('Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
10929 }
10930 }
10931 } else {
10932 context = context._context;
10933 }
10934 }
10935
10936 var newProps = workInProgress.pendingProps;
10937 var render = newProps.children;
10938
10939 {
10940 if (typeof render !== 'function') {
10941 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.');
10942 }
10943 }
10944
10945 prepareToReadContext(workInProgress, renderLanes);
10946 var newValue = readContext(context);
10947
10948 var newChildren;
10949
10950 {
10951 ReactCurrentOwner$1.current = workInProgress;
10952 setIsRendering(true);
10953 newChildren = render(newValue);
10954 setIsRendering(false);
10955 }
10956
10957
10958 workInProgress.flags |= PerformedWork;
10959 reconcileChildren(current, workInProgress, newChildren, renderLanes);
10960 return workInProgress.child;
10961}
10962
10963function markWorkInProgressReceivedUpdate() {
10964 didReceiveUpdate = true;
10965}
10966
10967function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) {
10968 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
10969 if (current !== null) {
10970 // A lazy component only mounts if it suspended inside a non-
10971 // concurrent tree, in an inconsistent state. We want to treat it like
10972 // a new mount, even though an empty version of it already committed.
10973 // Disconnect the alternate pointers.
10974 current.alternate = null;
10975 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
10976
10977 workInProgress.flags |= Placement;
10978 }
10979 }
10980}
10981
10982function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) {
10983 if (current !== null) {
10984 // Reuse previous dependencies
10985 workInProgress.dependencies = current.dependencies;
10986 }
10987
10988 {
10989 // Don't update "base" render times for bailouts.
10990 stopProfilerTimerIfRunning();
10991 }
10992
10993 markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work.
10994
10995 if (!includesSomeLane(renderLanes, workInProgress.childLanes)) {
10996 // The children don't have any work either. We can skip them.
10997 // TODO: Once we add back resuming, we should check if the children are
10998 // a work-in-progress set. If so, we need to transfer their effects.
10999 {
11000 return null;
11001 }
11002 } // This fiber doesn't have work, but its subtree does. Clone the child
11003 // fibers and continue.
11004
11005
11006 cloneChildFibers(current, workInProgress);
11007 return workInProgress.child;
11008}
11009
11010function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
11011 {
11012 var returnFiber = oldWorkInProgress.return;
11013
11014 if (returnFiber === null) {
11015 // eslint-disable-next-line react-internal/prod-error-codes
11016 throw new Error('Cannot swap the root fiber.');
11017 } // Disconnect from the old current.
11018 // It will get deleted.
11019
11020
11021 current.alternate = null;
11022 oldWorkInProgress.alternate = null; // Connect to the new tree.
11023
11024 newWorkInProgress.index = oldWorkInProgress.index;
11025 newWorkInProgress.sibling = oldWorkInProgress.sibling;
11026 newWorkInProgress.return = oldWorkInProgress.return;
11027 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.
11028
11029 if (oldWorkInProgress === returnFiber.child) {
11030 returnFiber.child = newWorkInProgress;
11031 } else {
11032 var prevSibling = returnFiber.child;
11033
11034 if (prevSibling === null) {
11035 // eslint-disable-next-line react-internal/prod-error-codes
11036 throw new Error('Expected parent to have a child.');
11037 }
11038
11039 while (prevSibling.sibling !== oldWorkInProgress) {
11040 prevSibling = prevSibling.sibling;
11041
11042 if (prevSibling === null) {
11043 // eslint-disable-next-line react-internal/prod-error-codes
11044 throw new Error('Expected to find the previous sibling.');
11045 }
11046 }
11047
11048 prevSibling.sibling = newWorkInProgress;
11049 } // Delete the old fiber and place the new one.
11050 // Since the old fiber is disconnected, we have to schedule it manually.
11051
11052
11053 var deletions = returnFiber.deletions;
11054
11055 if (deletions === null) {
11056 returnFiber.deletions = [current];
11057 returnFiber.flags |= ChildDeletion;
11058 } else {
11059 deletions.push(current);
11060 }
11061
11062 newWorkInProgress.flags |= Placement; // Restart work from the new fiber.
11063
11064 return newWorkInProgress;
11065 }
11066}
11067
11068function checkScheduledUpdateOrContext(current, renderLanes) {
11069 // Before performing an early bailout, we must check if there are pending
11070 // updates or context.
11071 var updateLanes = current.lanes;
11072
11073 if (includesSomeLane(updateLanes, renderLanes)) {
11074 return true;
11075 } // No pending update, but because context is propagated lazily, we need
11076
11077 return false;
11078}
11079
11080function attemptEarlyBailoutIfNoScheduledUpdate(current, workInProgress, renderLanes) {
11081 // This fiber does not have any pending work. Bailout without entering
11082 // the begin phase. There's still some bookkeeping we that needs to be done
11083 // in this optimized path, mostly pushing stuff onto the stack.
11084 switch (workInProgress.tag) {
11085 case HostRoot:
11086 pushHostRootContext(workInProgress);
11087 var root = workInProgress.stateNode;
11088 break;
11089
11090 case HostComponent:
11091 pushHostContext(workInProgress);
11092 break;
11093
11094 case ClassComponent:
11095 {
11096 var Component = workInProgress.type;
11097
11098 if (isContextProvider(Component)) {
11099 pushContextProvider(workInProgress);
11100 }
11101
11102 break;
11103 }
11104
11105 case HostPortal:
11106 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
11107 break;
11108
11109 case ContextProvider:
11110 {
11111 var newValue = workInProgress.memoizedProps.value;
11112 var context = workInProgress.type._context;
11113 pushProvider(workInProgress, context, newValue);
11114 break;
11115 }
11116
11117 case Profiler:
11118 {
11119 // Profiler should only call onRender when one of its descendants actually rendered.
11120 var hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes);
11121
11122 if (hasChildWork) {
11123 workInProgress.flags |= Update;
11124 }
11125
11126 {
11127 // Reset effect durations for the next eventual effect phase.
11128 // These are reset during render to allow the DevTools commit hook a chance to read them,
11129 var stateNode = workInProgress.stateNode;
11130 stateNode.effectDuration = 0;
11131 stateNode.passiveEffectDuration = 0;
11132 }
11133 }
11134
11135 break;
11136
11137 case SuspenseComponent:
11138 {
11139 var state = workInProgress.memoizedState;
11140
11141 if (state !== null) {
11142 if (state.dehydrated !== null) {
11143 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // We know that this component will suspend again because if it has
11144 // been unsuspended it has committed as a resolved Suspense component.
11145 // If it needs to be retried, it should have work scheduled on it.
11146
11147 workInProgress.flags |= DidCapture; // We should never render the children of a dehydrated boundary until we
11148 // upgrade it. We return null instead of bailoutOnAlreadyFinishedWork.
11149
11150 return null;
11151 } // If this boundary is currently timed out, we need to decide
11152 // whether to retry the primary children, or to skip over it and
11153 // go straight to the fallback. Check the priority of the primary
11154 // child fragment.
11155
11156
11157 var primaryChildFragment = workInProgress.child;
11158 var primaryChildLanes = primaryChildFragment.childLanes;
11159
11160 if (includesSomeLane(renderLanes, primaryChildLanes)) {
11161 // The primary children have pending work. Use the normal path
11162 // to attempt to render the primary children again.
11163 return updateSuspenseComponent(current, workInProgress, renderLanes);
11164 } else {
11165 // The primary child fragment does not have pending work marked
11166 // on it
11167 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient
11168 // priority. Bailout.
11169
11170 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
11171
11172 if (child !== null) {
11173 // The fallback children have pending work. Skip over the
11174 // primary children and work on the fallback.
11175 return child.sibling;
11176 } else {
11177 // Note: We can return `null` here because we already checked
11178 // whether there were nested context consumers, via the call to
11179 // `bailoutOnAlreadyFinishedWork` above.
11180 return null;
11181 }
11182 }
11183 } else {
11184 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
11185 }
11186
11187 break;
11188 }
11189
11190 case SuspenseListComponent:
11191 {
11192 var didSuspendBefore = (current.flags & DidCapture) !== NoFlags;
11193
11194 var _hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes);
11195
11196 if (didSuspendBefore) {
11197 if (_hasChildWork) {
11198 // If something was in fallback state last time, and we have all the
11199 // same children then we're still in progressive loading state.
11200 // Something might get unblocked by state updates or retries in the
11201 // tree which will affect the tail. So we need to use the normal
11202 // path to compute the correct tail.
11203 return updateSuspenseListComponent(current, workInProgress, renderLanes);
11204 } // If none of the children had any work, that means that none of
11205 // them got retried so they'll still be blocked in the same way
11206 // as before. We can fast bail out.
11207
11208
11209 workInProgress.flags |= DidCapture;
11210 } // If nothing suspended before and we're rendering the same children,
11211 // then the tail doesn't matter. Anything new that suspends will work
11212 // in the "together" mode, so we can continue from the state we had.
11213
11214
11215 var renderState = workInProgress.memoizedState;
11216
11217 if (renderState !== null) {
11218 // Reset to the "together" mode in case we've started a different
11219 // update in the past but didn't complete it.
11220 renderState.rendering = null;
11221 renderState.tail = null;
11222 renderState.lastEffect = null;
11223 }
11224
11225 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
11226
11227 if (_hasChildWork) {
11228 break;
11229 } else {
11230 // If none of the children had any work, that means that none of
11231 // them got retried so they'll still be blocked in the same way
11232 // as before. We can fast bail out.
11233 return null;
11234 }
11235 }
11236
11237 case OffscreenComponent:
11238 case LegacyHiddenComponent:
11239 {
11240 // Need to check if the tree still needs to be deferred. This is
11241 // almost identical to the logic used in the normal update path,
11242 // so we'll just enter that. The only difference is we'll bail out
11243 // at the next level instead of this one, because the child props
11244 // have not changed. Which is fine.
11245 // TODO: Probably should refactor `beginWork` to split the bailout
11246 // path from the normal path. I'm tempted to do a labeled break here
11247 // but I won't :)
11248 workInProgress.lanes = NoLanes;
11249 return updateOffscreenComponent(current, workInProgress, renderLanes);
11250 }
11251 }
11252
11253 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
11254}
11255
11256function beginWork(current, workInProgress, renderLanes) {
11257 {
11258 if (workInProgress._debugNeedsRemount && current !== null) {
11259 // This will restart the begin phase with a new fiber.
11260 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.lanes));
11261 }
11262 }
11263
11264 if (current !== null) {
11265 var oldProps = current.memoizedProps;
11266 var newProps = workInProgress.pendingProps;
11267
11268 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
11269 workInProgress.type !== current.type )) {
11270 // If props or context changed, mark the fiber as having performed work.
11271 // This may be unset if the props are determined to be equal later (memo).
11272 didReceiveUpdate = true;
11273 } else {
11274 // Neither props nor legacy context changes. Check if there's a pending
11275 // update or context change.
11276 var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current, renderLanes);
11277
11278 if (!hasScheduledUpdateOrContext && // If this is the second pass of an error or suspense boundary, there
11279 // may not be work scheduled on `current`, so we check for this flag.
11280 (workInProgress.flags & DidCapture) === NoFlags) {
11281 // No pending updates or context. Bail out now.
11282 didReceiveUpdate = false;
11283 return attemptEarlyBailoutIfNoScheduledUpdate(current, workInProgress, renderLanes);
11284 }
11285
11286 if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) {
11287 // This is a special case that only exists for legacy mode.
11288 // See https://github.com/facebook/react/pull/19216.
11289 didReceiveUpdate = true;
11290 } else {
11291 // An update was scheduled on this fiber, but there are no new props
11292 // nor legacy context. Set this to false. If an update queue or context
11293 // consumer produces a changed value, it will set this to true. Otherwise,
11294 // the component will assume the children have not changed and bail out.
11295 didReceiveUpdate = false;
11296 }
11297 }
11298 } else {
11299 didReceiveUpdate = false;
11300 } // Before entering the begin phase, clear pending update priority.
11301 // TODO: This assumes that we're about to evaluate the component and process
11302 // the update queue. However, there's an exception: SimpleMemoComponent
11303 // sometimes bails out later in the begin phase. This indicates that we should
11304 // move this assignment out of the common path and into each branch.
11305
11306
11307 workInProgress.lanes = NoLanes;
11308
11309 switch (workInProgress.tag) {
11310 case IndeterminateComponent:
11311 {
11312 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderLanes);
11313 }
11314
11315 case LazyComponent:
11316 {
11317 var elementType = workInProgress.elementType;
11318 return mountLazyComponent(current, workInProgress, elementType, renderLanes);
11319 }
11320
11321 case FunctionComponent:
11322 {
11323 var Component = workInProgress.type;
11324 var unresolvedProps = workInProgress.pendingProps;
11325 var resolvedProps = workInProgress.elementType === Component ? unresolvedProps : resolveDefaultProps(Component, unresolvedProps);
11326 return updateFunctionComponent(current, workInProgress, Component, resolvedProps, renderLanes);
11327 }
11328
11329 case ClassComponent:
11330 {
11331 var _Component = workInProgress.type;
11332 var _unresolvedProps = workInProgress.pendingProps;
11333
11334 var _resolvedProps = workInProgress.elementType === _Component ? _unresolvedProps : resolveDefaultProps(_Component, _unresolvedProps);
11335
11336 return updateClassComponent(current, workInProgress, _Component, _resolvedProps, renderLanes);
11337 }
11338
11339 case HostRoot:
11340 return updateHostRoot(current, workInProgress, renderLanes);
11341
11342 case HostComponent:
11343 return updateHostComponent(current, workInProgress, renderLanes);
11344
11345 case HostText:
11346 return updateHostText();
11347
11348 case SuspenseComponent:
11349 return updateSuspenseComponent(current, workInProgress, renderLanes);
11350
11351 case HostPortal:
11352 return updatePortalComponent(current, workInProgress, renderLanes);
11353
11354 case ForwardRef:
11355 {
11356 var type = workInProgress.type;
11357 var _unresolvedProps2 = workInProgress.pendingProps;
11358
11359 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
11360
11361 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderLanes);
11362 }
11363
11364 case Fragment:
11365 return updateFragment(current, workInProgress, renderLanes);
11366
11367 case Mode:
11368 return updateMode(current, workInProgress, renderLanes);
11369
11370 case Profiler:
11371 return updateProfiler(current, workInProgress, renderLanes);
11372
11373 case ContextProvider:
11374 return updateContextProvider(current, workInProgress, renderLanes);
11375
11376 case ContextConsumer:
11377 return updateContextConsumer(current, workInProgress, renderLanes);
11378
11379 case MemoComponent:
11380 {
11381 var _type2 = workInProgress.type;
11382 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
11383
11384 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
11385
11386 {
11387 if (workInProgress.type !== workInProgress.elementType) {
11388 var outerPropTypes = _type2.propTypes;
11389
11390 if (outerPropTypes) {
11391 checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only
11392 'prop', getComponentNameFromType(_type2));
11393 }
11394 }
11395 }
11396
11397 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
11398 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, renderLanes);
11399 }
11400
11401 case SimpleMemoComponent:
11402 {
11403 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, renderLanes);
11404 }
11405
11406 case IncompleteClassComponent:
11407 {
11408 var _Component2 = workInProgress.type;
11409 var _unresolvedProps4 = workInProgress.pendingProps;
11410
11411 var _resolvedProps4 = workInProgress.elementType === _Component2 ? _unresolvedProps4 : resolveDefaultProps(_Component2, _unresolvedProps4);
11412
11413 return mountIncompleteClassComponent(current, workInProgress, _Component2, _resolvedProps4, renderLanes);
11414 }
11415
11416 case SuspenseListComponent:
11417 {
11418 return updateSuspenseListComponent(current, workInProgress, renderLanes);
11419 }
11420
11421 case ScopeComponent:
11422 {
11423
11424 break;
11425 }
11426
11427 case OffscreenComponent:
11428 {
11429 return updateOffscreenComponent(current, workInProgress, renderLanes);
11430 }
11431 }
11432
11433 throw new Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in " + 'React. Please file an issue.');
11434}
11435
11436function markUpdate(workInProgress) {
11437 // Tag the fiber with an update effect. This turns a Placement into
11438 // a PlacementAndUpdate.
11439 workInProgress.flags |= Update;
11440}
11441
11442function markRef$1(workInProgress) {
11443 workInProgress.flags |= Ref;
11444}
11445
11446var appendAllChildren;
11447var updateHostContainer;
11448var updateHostComponent$1;
11449var updateHostText$1;
11450
11451{
11452 // Mutation mode
11453 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
11454 // We only have the top Fiber that was created but we need recurse down its
11455 // children to find all the terminal nodes.
11456 var node = workInProgress.child;
11457
11458 while (node !== null) {
11459 if (node.tag === HostComponent || node.tag === HostText) {
11460 appendInitialChild(parent, node.stateNode);
11461 } else if (node.tag === HostPortal) ; else if (node.child !== null) {
11462 node.child.return = node;
11463 node = node.child;
11464 continue;
11465 }
11466
11467 if (node === workInProgress) {
11468 return;
11469 }
11470
11471 while (node.sibling === null) {
11472 if (node.return === null || node.return === workInProgress) {
11473 return;
11474 }
11475
11476 node = node.return;
11477 }
11478
11479 node.sibling.return = node.return;
11480 node = node.sibling;
11481 }
11482 };
11483
11484 updateHostContainer = function (current, workInProgress) {// Noop
11485 };
11486
11487 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
11488 // If we have an alternate, that means this is an update and we need to
11489 // schedule a side-effect to do the updates.
11490 var oldProps = current.memoizedProps;
11491
11492 if (oldProps === newProps) {
11493 // In mutation mode, this is sufficient for a bailout because
11494 // we won't touch this node even if children changed.
11495 return;
11496 } // If we get updated because one of our children updated, we don't
11497 // have newProps so we'll have to reuse them.
11498 // TODO: Split the update API as separate for the props vs. children.
11499 // Even better would be if children weren't special cased at all tho.
11500
11501
11502 var instance = workInProgress.stateNode;
11503 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host
11504 // component is hitting the resume path. Figure out why. Possibly
11505 // related to `hidden`.
11506
11507 var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component.
11508
11509 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
11510 // is a new ref we mark this as an update. All the work is done in commitWork.
11511
11512 if (updatePayload) {
11513 markUpdate(workInProgress);
11514 }
11515 };
11516
11517 updateHostText$1 = function (current, workInProgress, oldText, newText) {
11518 // If the text differs, mark it as an update. All the work in done in commitWork.
11519 if (oldText !== newText) {
11520 markUpdate(workInProgress);
11521 }
11522 };
11523}
11524
11525function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
11526
11527 switch (renderState.tailMode) {
11528 case 'hidden':
11529 {
11530 // Any insertions at the end of the tail list after this point
11531 // should be invisible. If there are already mounted boundaries
11532 // anything before them are not considered for collapsing.
11533 // Therefore we need to go through the whole tail to find if
11534 // there are any.
11535 var tailNode = renderState.tail;
11536 var lastTailNode = null;
11537
11538 while (tailNode !== null) {
11539 if (tailNode.alternate !== null) {
11540 lastTailNode = tailNode;
11541 }
11542
11543 tailNode = tailNode.sibling;
11544 } // Next we're simply going to delete all insertions after the
11545 // last rendered item.
11546
11547
11548 if (lastTailNode === null) {
11549 // All remaining items in the tail are insertions.
11550 renderState.tail = null;
11551 } else {
11552 // Detach the insertion after the last node that was already
11553 // inserted.
11554 lastTailNode.sibling = null;
11555 }
11556
11557 break;
11558 }
11559
11560 case 'collapsed':
11561 {
11562 // Any insertions at the end of the tail list after this point
11563 // should be invisible. If there are already mounted boundaries
11564 // anything before them are not considered for collapsing.
11565 // Therefore we need to go through the whole tail to find if
11566 // there are any.
11567 var _tailNode = renderState.tail;
11568 var _lastTailNode = null;
11569
11570 while (_tailNode !== null) {
11571 if (_tailNode.alternate !== null) {
11572 _lastTailNode = _tailNode;
11573 }
11574
11575 _tailNode = _tailNode.sibling;
11576 } // Next we're simply going to delete all insertions after the
11577 // last rendered item.
11578
11579
11580 if (_lastTailNode === null) {
11581 // All remaining items in the tail are insertions.
11582 if (!hasRenderedATailFallback && renderState.tail !== null) {
11583 // We suspended during the head. We want to show at least one
11584 // row at the tail. So we'll keep on and cut off the rest.
11585 renderState.tail.sibling = null;
11586 } else {
11587 renderState.tail = null;
11588 }
11589 } else {
11590 // Detach the insertion after the last node that was already
11591 // inserted.
11592 _lastTailNode.sibling = null;
11593 }
11594
11595 break;
11596 }
11597 }
11598}
11599
11600function bubbleProperties(completedWork) {
11601 var didBailout = completedWork.alternate !== null && completedWork.alternate.child === completedWork.child;
11602 var newChildLanes = NoLanes;
11603 var subtreeFlags = NoFlags;
11604
11605 if (!didBailout) {
11606 // Bubble up the earliest expiration time.
11607 if ( (completedWork.mode & ProfileMode) !== NoMode) {
11608 // In profiling mode, resetChildExpirationTime is also used to reset
11609 // profiler durations.
11610 var actualDuration = completedWork.actualDuration;
11611 var treeBaseDuration = completedWork.selfBaseDuration;
11612 var child = completedWork.child;
11613
11614 while (child !== null) {
11615 newChildLanes = mergeLanes(newChildLanes, mergeLanes(child.lanes, child.childLanes));
11616 subtreeFlags |= child.subtreeFlags;
11617 subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will
11618 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
11619 // When work is done, it should bubble to the parent's actualDuration. If
11620 // the fiber has not been cloned though, (meaning no work was done), then
11621 // this value will reflect the amount of time spent working on a previous
11622 // render. In that case it should not bubble. We determine whether it was
11623 // cloned by comparing the child pointer.
11624
11625 actualDuration += child.actualDuration;
11626 treeBaseDuration += child.treeBaseDuration;
11627 child = child.sibling;
11628 }
11629
11630 completedWork.actualDuration = actualDuration;
11631 completedWork.treeBaseDuration = treeBaseDuration;
11632 } else {
11633 var _child = completedWork.child;
11634
11635 while (_child !== null) {
11636 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child.lanes, _child.childLanes));
11637 subtreeFlags |= _child.subtreeFlags;
11638 subtreeFlags |= _child.flags; // Update the return pointer so the tree is consistent. This is a code
11639 // smell because it assumes the commit phase is never concurrent with
11640 // the render phase. Will address during refactor to alternate model.
11641
11642 _child.return = completedWork;
11643 _child = _child.sibling;
11644 }
11645 }
11646
11647 completedWork.subtreeFlags |= subtreeFlags;
11648 } else {
11649 // Bubble up the earliest expiration time.
11650 if ( (completedWork.mode & ProfileMode) !== NoMode) {
11651 // In profiling mode, resetChildExpirationTime is also used to reset
11652 // profiler durations.
11653 var _treeBaseDuration = completedWork.selfBaseDuration;
11654 var _child2 = completedWork.child;
11655
11656 while (_child2 !== null) {
11657 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child2.lanes, _child2.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to,
11658 // so we should bubble those up even during a bailout. All the other
11659 // flags have a lifetime only of a single render + commit, so we should
11660 // ignore them.
11661
11662 subtreeFlags |= _child2.subtreeFlags & StaticMask;
11663 subtreeFlags |= _child2.flags & StaticMask;
11664 _treeBaseDuration += _child2.treeBaseDuration;
11665 _child2 = _child2.sibling;
11666 }
11667
11668 completedWork.treeBaseDuration = _treeBaseDuration;
11669 } else {
11670 var _child3 = completedWork.child;
11671
11672 while (_child3 !== null) {
11673 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child3.lanes, _child3.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to,
11674 // so we should bubble those up even during a bailout. All the other
11675 // flags have a lifetime only of a single render + commit, so we should
11676 // ignore them.
11677
11678 subtreeFlags |= _child3.subtreeFlags & StaticMask;
11679 subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code
11680 // smell because it assumes the commit phase is never concurrent with
11681 // the render phase. Will address during refactor to alternate model.
11682
11683 _child3.return = completedWork;
11684 _child3 = _child3.sibling;
11685 }
11686 }
11687
11688 completedWork.subtreeFlags |= subtreeFlags;
11689 }
11690
11691 completedWork.childLanes = newChildLanes;
11692 return didBailout;
11693}
11694
11695function completeDehydratedSuspenseBoundary(current, workInProgress, nextState) {
11696
11697 var wasHydrated = popHydrationState();
11698
11699 if (nextState !== null && nextState.dehydrated !== null) {
11700 // We might be inside a hydration state the first time we're picking up this
11701 // Suspense boundary, and also after we've reentered it for further hydration.
11702 if (current === null) {
11703 if (!wasHydrated) {
11704 throw new Error('A dehydrated suspense component was completed without a hydrated node. ' + 'This is probably a bug in React.');
11705 }
11706
11707 prepareToHydrateHostSuspenseInstance();
11708 bubbleProperties(workInProgress);
11709
11710 {
11711 if ((workInProgress.mode & ProfileMode) !== NoMode) {
11712 var isTimedOutSuspense = nextState !== null;
11713
11714 if (isTimedOutSuspense) {
11715 // Don't count time spent in a timed out Suspense subtree as part of the base duration.
11716 var primaryChildFragment = workInProgress.child;
11717
11718 if (primaryChildFragment !== null) {
11719 // $FlowFixMe Flow doesn't support type casting in combination with the -= operator
11720 workInProgress.treeBaseDuration -= primaryChildFragment.treeBaseDuration;
11721 }
11722 }
11723 }
11724 }
11725
11726 return false;
11727 } else {
11728
11729 if ((workInProgress.flags & DidCapture) === NoFlags) {
11730 // This boundary did not suspend so it's now hydrated and unsuspended.
11731 workInProgress.memoizedState = null;
11732 } // If nothing suspended, we need to schedule an effect to mark this boundary
11733 // as having hydrated so events know that they're free to be invoked.
11734 // It's also a signal to replay events and the suspense callback.
11735 // If something suspended, schedule an effect to attach retry listeners.
11736 // So we might as well always mark this.
11737
11738
11739 workInProgress.flags |= Update;
11740 bubbleProperties(workInProgress);
11741
11742 {
11743 if ((workInProgress.mode & ProfileMode) !== NoMode) {
11744 var _isTimedOutSuspense = nextState !== null;
11745
11746 if (_isTimedOutSuspense) {
11747 // Don't count time spent in a timed out Suspense subtree as part of the base duration.
11748 var _primaryChildFragment = workInProgress.child;
11749
11750 if (_primaryChildFragment !== null) {
11751 // $FlowFixMe Flow doesn't support type casting in combination with the -= operator
11752 workInProgress.treeBaseDuration -= _primaryChildFragment.treeBaseDuration;
11753 }
11754 }
11755 }
11756 }
11757
11758 return false;
11759 }
11760 } else {
11761 // Successfully completed this tree. If this was a forced client render,
11762 // there may have been recoverable errors during first hydration
11763 // attempt. If so, add them to a queue so we can log them in the
11764 // commit phase.
11765 upgradeHydrationErrorsToRecoverable(); // Fall through to normal Suspense path
11766
11767 return true;
11768 }
11769}
11770
11771function completeWork(current, workInProgress, renderLanes) {
11772 var newProps = workInProgress.pendingProps; // Note: This intentionally doesn't check if we're hydrating because comparing
11773 // to the current tree provider fiber is just as fast and less error-prone.
11774 // Ideally we would have a special version of the work loop only
11775 // for hydration.
11776
11777 popTreeContext(workInProgress);
11778
11779 switch (workInProgress.tag) {
11780 case IndeterminateComponent:
11781 case LazyComponent:
11782 case SimpleMemoComponent:
11783 case FunctionComponent:
11784 case ForwardRef:
11785 case Fragment:
11786 case Mode:
11787 case Profiler:
11788 case ContextConsumer:
11789 case MemoComponent:
11790 bubbleProperties(workInProgress);
11791 return null;
11792
11793 case ClassComponent:
11794 {
11795 var Component = workInProgress.type;
11796
11797 if (isContextProvider(Component)) {
11798 popContext(workInProgress);
11799 }
11800
11801 bubbleProperties(workInProgress);
11802 return null;
11803 }
11804
11805 case HostRoot:
11806 {
11807 var fiberRoot = workInProgress.stateNode;
11808 popHostContainer(workInProgress);
11809 popTopLevelContextObject(workInProgress);
11810 resetWorkInProgressVersions();
11811
11812 if (fiberRoot.pendingContext) {
11813 fiberRoot.context = fiberRoot.pendingContext;
11814 fiberRoot.pendingContext = null;
11815 }
11816
11817 if (current === null || current.child === null) {
11818 // If we hydrated, pop so that we can delete any remaining children
11819 // that weren't hydrated.
11820 var wasHydrated = popHydrationState();
11821
11822 if (wasHydrated) {
11823 // If we hydrated, then we'll need to schedule an update for
11824 // the commit side-effects on the root.
11825 markUpdate(workInProgress);
11826 } else {
11827 if (current !== null) {
11828 var prevState = current.memoizedState;
11829
11830 if ( // Check if this is a client root
11831 !prevState.isDehydrated || // Check if we reverted to client rendering (e.g. due to an error)
11832 (workInProgress.flags & ForceClientRender) !== NoFlags) {
11833 // Schedule an effect to clear this container at the start of the
11834 // next commit. This handles the case of React rendering into a
11835 // container with previous children. It's also safe to do for
11836 // updates too, because current.child would only be null if the
11837 // previous render was null (so the container would already
11838 // be empty).
11839 workInProgress.flags |= Snapshot; // If this was a forced client render, there may have been
11840 // recoverable errors during first hydration attempt. If so, add
11841 // them to a queue so we can log them in the commit phase.
11842
11843 upgradeHydrationErrorsToRecoverable();
11844 }
11845 }
11846 }
11847 }
11848
11849 updateHostContainer(current, workInProgress);
11850 bubbleProperties(workInProgress);
11851
11852 return null;
11853 }
11854
11855 case HostComponent:
11856 {
11857 popHostContext(workInProgress);
11858 var rootContainerInstance = getRootHostContainer();
11859 var type = workInProgress.type;
11860
11861 if (current !== null && workInProgress.stateNode != null) {
11862 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
11863
11864 if (current.ref !== workInProgress.ref) {
11865 markRef$1(workInProgress);
11866 }
11867 } else {
11868 if (!newProps) {
11869 if (workInProgress.stateNode === null) {
11870 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.');
11871 } // This can happen when we abort work.
11872
11873
11874 bubbleProperties(workInProgress);
11875 return null;
11876 }
11877
11878 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
11879 // "stack" as the parent. Then append children as we go in beginWork
11880 // or completeWork depending on whether we want to add them top->down or
11881 // bottom->up. Top->down is faster in IE11.
11882
11883 var _wasHydrated = popHydrationState();
11884
11885 if (_wasHydrated) {
11886 // TODO: Move this and createInstance step into the beginPhase
11887 // to consolidate.
11888 if (prepareToHydrateHostInstance()) {
11889 // If changes to the hydrated node need to be applied at the
11890 // commit-phase we mark this as such.
11891 markUpdate(workInProgress);
11892 }
11893 } else {
11894 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
11895 appendAllChildren(instance, workInProgress, false, false);
11896 workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount.
11897 }
11898
11899 if (workInProgress.ref !== null) {
11900 // If there is a ref on a host node we need to schedule a callback
11901 markRef$1(workInProgress);
11902 }
11903 }
11904
11905 bubbleProperties(workInProgress);
11906 return null;
11907 }
11908
11909 case HostText:
11910 {
11911 var newText = newProps;
11912
11913 if (current && workInProgress.stateNode != null) {
11914 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
11915 // to schedule a side-effect to do the updates.
11916
11917 updateHostText$1(current, workInProgress, oldText, newText);
11918 } else {
11919 if (typeof newText !== 'string') {
11920 if (workInProgress.stateNode === null) {
11921 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.');
11922 } // This can happen when we abort work.
11923
11924 }
11925
11926 var _rootContainerInstance = getRootHostContainer();
11927
11928 var _currentHostContext = getHostContext();
11929
11930 var _wasHydrated2 = popHydrationState();
11931
11932 if (_wasHydrated2) {
11933 if (prepareToHydrateHostTextInstance()) {
11934 markUpdate(workInProgress);
11935 }
11936 } else {
11937 workInProgress.stateNode = createTextInstance(newText);
11938 }
11939 }
11940
11941 bubbleProperties(workInProgress);
11942 return null;
11943 }
11944
11945 case SuspenseComponent:
11946 {
11947 popSuspenseContext(workInProgress);
11948 var nextState = workInProgress.memoizedState; // Special path for dehydrated boundaries. We may eventually move this
11949 // to its own fiber type so that we can add other kinds of hydration
11950 // boundaries that aren't associated with a Suspense tree. In anticipation
11951 // of such a refactor, all the hydration logic is contained in
11952 // this branch.
11953
11954 if (current === null || current.memoizedState !== null && current.memoizedState.dehydrated !== null) {
11955 var fallthroughToNormalSuspensePath = completeDehydratedSuspenseBoundary(current, workInProgress, nextState);
11956
11957 if (!fallthroughToNormalSuspensePath) {
11958 if (workInProgress.flags & ShouldCapture) {
11959 // Special case. There were remaining unhydrated nodes. We treat
11960 // this as a mismatch. Revert to client rendering.
11961 return workInProgress;
11962 } else {
11963 // Did not finish hydrating, either because this is the initial
11964 // render or because something suspended.
11965 return null;
11966 }
11967 } // Continue with the normal Suspense path.
11968
11969 }
11970
11971 if ((workInProgress.flags & DidCapture) !== NoFlags) {
11972 // Something suspended. Re-render with the fallback children.
11973 workInProgress.lanes = renderLanes; // Do not reset the effect list.
11974
11975 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
11976 transferActualDuration(workInProgress);
11977 } // Don't bubble properties in this case.
11978
11979
11980 return workInProgress;
11981 }
11982
11983 var nextDidTimeout = nextState !== null;
11984 var prevDidTimeout = current !== null && current.memoizedState !== null;
11985 // a passive effect, which is when we process the transitions
11986
11987
11988 if (nextDidTimeout !== prevDidTimeout) {
11989 // an effect to toggle the subtree's visibility. When we switch from
11990 // fallback -> primary, the inner Offscreen fiber schedules this effect
11991 // as part of its normal complete phase. But when we switch from
11992 // primary -> fallback, the inner Offscreen fiber does not have a complete
11993 // phase. So we need to schedule its effect here.
11994 //
11995 // We also use this flag to connect/disconnect the effects, but the same
11996 // logic applies: when re-connecting, the Offscreen fiber's complete
11997 // phase will handle scheduling the effect. It's only when the fallback
11998 // is active that we have to do anything special.
11999
12000
12001 if (nextDidTimeout) {
12002 var _offscreenFiber2 = workInProgress.child;
12003 _offscreenFiber2.flags |= Visibility; // TODO: This will still suspend a synchronous tree if anything
12004 // in the concurrent tree already suspended during this render.
12005 // This is a known bug.
12006
12007 if ((workInProgress.mode & ConcurrentMode) !== NoMode) {
12008 // TODO: Move this back to throwException because this is too late
12009 // if this is a large tree which is common for initial loads. We
12010 // don't know if we should restart a render or not until we get
12011 // this marker, and this is too late.
12012 // If this render already had a ping or lower pri updates,
12013 // and this is the first time we know we're going to suspend we
12014 // should be able to immediately restart from within throwException.
12015 var hasInvisibleChildContext = current === null && (workInProgress.memoizedProps.unstable_avoidThisFallback !== true || !enableSuspenseAvoidThisFallback);
12016
12017 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
12018 // If this was in an invisible tree or a new render, then showing
12019 // this boundary is ok.
12020 renderDidSuspend();
12021 } else {
12022 // Otherwise, we're going to have to hide content so we should
12023 // suspend for longer if possible.
12024 renderDidSuspendDelayIfPossible();
12025 }
12026 }
12027 }
12028 }
12029
12030 var wakeables = workInProgress.updateQueue;
12031
12032 if (wakeables !== null) {
12033 // Schedule an effect to attach a retry listener to the promise.
12034 // TODO: Move to passive phase
12035 workInProgress.flags |= Update;
12036 }
12037
12038 bubbleProperties(workInProgress);
12039
12040 {
12041 if ((workInProgress.mode & ProfileMode) !== NoMode) {
12042 if (nextDidTimeout) {
12043 // Don't count time spent in a timed out Suspense subtree as part of the base duration.
12044 var primaryChildFragment = workInProgress.child;
12045
12046 if (primaryChildFragment !== null) {
12047 // $FlowFixMe Flow doesn't support type casting in combination with the -= operator
12048 workInProgress.treeBaseDuration -= primaryChildFragment.treeBaseDuration;
12049 }
12050 }
12051 }
12052 }
12053
12054 return null;
12055 }
12056
12057 case HostPortal:
12058 popHostContainer(workInProgress);
12059 updateHostContainer(current, workInProgress);
12060
12061 if (current === null) {
12062 preparePortalMount(workInProgress.stateNode.containerInfo);
12063 }
12064
12065 bubbleProperties(workInProgress);
12066 return null;
12067
12068 case ContextProvider:
12069 // Pop provider fiber
12070 var context = workInProgress.type._context;
12071 popProvider(context, workInProgress);
12072 bubbleProperties(workInProgress);
12073 return null;
12074
12075 case IncompleteClassComponent:
12076 {
12077 // Same as class component case. I put it down here so that the tags are
12078 // sequential to ensure this switch is compiled to a jump table.
12079 var _Component = workInProgress.type;
12080
12081 if (isContextProvider(_Component)) {
12082 popContext(workInProgress);
12083 }
12084
12085 bubbleProperties(workInProgress);
12086 return null;
12087 }
12088
12089 case SuspenseListComponent:
12090 {
12091 popSuspenseContext(workInProgress);
12092 var renderState = workInProgress.memoizedState;
12093
12094 if (renderState === null) {
12095 // We're running in the default, "independent" mode.
12096 // We don't do anything in this mode.
12097 bubbleProperties(workInProgress);
12098 return null;
12099 }
12100
12101 var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags;
12102 var renderedTail = renderState.rendering;
12103
12104 if (renderedTail === null) {
12105 // We just rendered the head.
12106 if (!didSuspendAlready) {
12107 // This is the first pass. We need to figure out if anything is still
12108 // suspended in the rendered set.
12109 // If new content unsuspended, but there's still some content that
12110 // didn't. Then we need to do a second pass that forces everything
12111 // to keep showing their fallbacks.
12112 // We might be suspended if something in this render pass suspended, or
12113 // something in the previous committed pass suspended. Otherwise,
12114 // there's no chance so we can skip the expensive call to
12115 // findFirstSuspended.
12116 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.flags & DidCapture) === NoFlags);
12117
12118 if (!cannotBeSuspended) {
12119 var row = workInProgress.child;
12120
12121 while (row !== null) {
12122 var suspended = findFirstSuspended(row);
12123
12124 if (suspended !== null) {
12125 didSuspendAlready = true;
12126 workInProgress.flags |= DidCapture;
12127 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
12128 // part of the second pass. In that case nothing will subscribe to
12129 // its thenables. Instead, we'll transfer its thenables to the
12130 // SuspenseList so that it can retry if they resolve.
12131 // There might be multiple of these in the list but since we're
12132 // going to wait for all of them anyway, it doesn't really matter
12133 // which ones gets to ping. In theory we could get clever and keep
12134 // track of how many dependencies remain but it gets tricky because
12135 // in the meantime, we can add/remove/change items and dependencies.
12136 // We might bail out of the loop before finding any but that
12137 // doesn't matter since that means that the other boundaries that
12138 // we did find already has their listeners attached.
12139
12140 var newThenables = suspended.updateQueue;
12141
12142 if (newThenables !== null) {
12143 workInProgress.updateQueue = newThenables;
12144 workInProgress.flags |= Update;
12145 } // Rerender the whole list, but this time, we'll force fallbacks
12146 // to stay in place.
12147 // Reset the effect flags before doing the second pass since that's now invalid.
12148 // Reset the child fibers to their original state.
12149
12150
12151 workInProgress.subtreeFlags = NoFlags;
12152 resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately
12153 // rerender the children.
12154
12155 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback)); // Don't bubble properties in this case.
12156
12157 return workInProgress.child;
12158 }
12159
12160 row = row.sibling;
12161 }
12162 }
12163
12164 if (renderState.tail !== null && now() > getRenderTargetTime()) {
12165 // We have already passed our CPU deadline but we still have rows
12166 // left in the tail. We'll just give up further attempts to render
12167 // the main content and only render fallbacks.
12168 workInProgress.flags |= DidCapture;
12169 didSuspendAlready = true;
12170 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
12171 // to get it started back up to attempt the next item. While in terms
12172 // of priority this work has the same priority as this current render,
12173 // it's not part of the same transition once the transition has
12174 // committed. If it's sync, we still want to yield so that it can be
12175 // painted. Conceptually, this is really the same as pinging.
12176 // We can use any RetryLane even if it's the one currently rendering
12177 // since we're leaving it behind on this node.
12178
12179 workInProgress.lanes = SomeRetryLane;
12180 }
12181 } else {
12182 cutOffTailIfNeeded(renderState, false);
12183 } // Next we're going to render the tail.
12184
12185 } else {
12186 // Append the rendered row to the child list.
12187 if (!didSuspendAlready) {
12188 var _suspended = findFirstSuspended(renderedTail);
12189
12190 if (_suspended !== null) {
12191 workInProgress.flags |= DidCapture;
12192 didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't
12193 // get lost if this row ends up dropped during a second pass.
12194
12195 var _newThenables = _suspended.updateQueue;
12196
12197 if (_newThenables !== null) {
12198 workInProgress.updateQueue = _newThenables;
12199 workInProgress.flags |= Update;
12200 }
12201
12202 cutOffTailIfNeeded(renderState, true); // This might have been modified.
12203
12204 if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate && !getIsHydrating() // We don't cut it if we're hydrating.
12205 ) {
12206 // We're done.
12207 bubbleProperties(workInProgress);
12208 return null;
12209 }
12210 } else if ( // The time it took to render last row is greater than the remaining
12211 // time we have to render. So rendering one more row would likely
12212 // exceed it.
12213 now() * 2 - renderState.renderingStartTime > getRenderTargetTime() && renderLanes !== OffscreenLane) {
12214 // We have now passed our CPU deadline and we'll just give up further
12215 // attempts to render the main content and only render fallbacks.
12216 // The assumption is that this is usually faster.
12217 workInProgress.flags |= DidCapture;
12218 didSuspendAlready = true;
12219 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
12220 // to get it started back up to attempt the next item. While in terms
12221 // of priority this work has the same priority as this current render,
12222 // it's not part of the same transition once the transition has
12223 // committed. If it's sync, we still want to yield so that it can be
12224 // painted. Conceptually, this is really the same as pinging.
12225 // We can use any RetryLane even if it's the one currently rendering
12226 // since we're leaving it behind on this node.
12227
12228 workInProgress.lanes = SomeRetryLane;
12229 }
12230 }
12231
12232 if (renderState.isBackwards) {
12233 // The effect list of the backwards tail will have been added
12234 // to the end. This breaks the guarantee that life-cycles fire in
12235 // sibling order but that isn't a strong guarantee promised by React.
12236 // Especially since these might also just pop in during future commits.
12237 // Append to the beginning of the list.
12238 renderedTail.sibling = workInProgress.child;
12239 workInProgress.child = renderedTail;
12240 } else {
12241 var previousSibling = renderState.last;
12242
12243 if (previousSibling !== null) {
12244 previousSibling.sibling = renderedTail;
12245 } else {
12246 workInProgress.child = renderedTail;
12247 }
12248
12249 renderState.last = renderedTail;
12250 }
12251 }
12252
12253 if (renderState.tail !== null) {
12254 // We still have tail rows to render.
12255 // Pop a row.
12256 var next = renderState.tail;
12257 renderState.rendering = next;
12258 renderState.tail = next.sibling;
12259 renderState.renderingStartTime = now();
12260 next.sibling = null; // Restore the context.
12261 // TODO: We can probably just avoid popping it instead and only
12262 // setting it the first time we go from not suspended to suspended.
12263
12264 var suspenseContext = suspenseStackCursor.current;
12265
12266 if (didSuspendAlready) {
12267 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
12268 } else {
12269 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
12270 }
12271
12272 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
12273 // Don't bubble properties in this case.
12274
12275 return next;
12276 }
12277
12278 bubbleProperties(workInProgress);
12279 return null;
12280 }
12281
12282 case ScopeComponent:
12283 {
12284
12285 break;
12286 }
12287
12288 case OffscreenComponent:
12289 case LegacyHiddenComponent:
12290 {
12291 popRenderLanes(workInProgress);
12292 var _nextState = workInProgress.memoizedState;
12293 var nextIsHidden = _nextState !== null;
12294
12295 if (current !== null) {
12296 var _prevState = current.memoizedState;
12297 var prevIsHidden = _prevState !== null;
12298
12299 if (prevIsHidden !== nextIsHidden && ( // LegacyHidden doesn't do any hiding — it only pre-renders.
12300 !enableLegacyHidden )) {
12301 workInProgress.flags |= Visibility;
12302 }
12303 }
12304
12305 if (!nextIsHidden || (workInProgress.mode & ConcurrentMode) === NoMode) {
12306 bubbleProperties(workInProgress);
12307 } else {
12308 // Don't bubble properties for hidden children unless we're rendering
12309 // at offscreen priority.
12310 if (includesSomeLane(subtreeRenderLanes, OffscreenLane)) {
12311 bubbleProperties(workInProgress);
12312
12313 {
12314 // Check if there was an insertion or update in the hidden subtree.
12315 // If so, we need to hide those nodes in the commit phase, so
12316 // schedule a visibility effect.
12317 if ( workInProgress.subtreeFlags & (Placement | Update)) {
12318 workInProgress.flags |= Visibility;
12319 }
12320 }
12321 }
12322 }
12323 return null;
12324 }
12325
12326 case CacheComponent:
12327 {
12328
12329 return null;
12330 }
12331
12332 case TracingMarkerComponent:
12333 {
12334
12335 return null;
12336 }
12337 }
12338
12339 throw new Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in " + 'React. Please file an issue.');
12340}
12341
12342function unwindWork(current, workInProgress, renderLanes) {
12343 // Note: This intentionally doesn't check if we're hydrating because comparing
12344 // to the current tree provider fiber is just as fast and less error-prone.
12345 // Ideally we would have a special version of the work loop only
12346 // for hydration.
12347 popTreeContext(workInProgress);
12348
12349 switch (workInProgress.tag) {
12350 case ClassComponent:
12351 {
12352 var Component = workInProgress.type;
12353
12354 if (isContextProvider(Component)) {
12355 popContext(workInProgress);
12356 }
12357
12358 var flags = workInProgress.flags;
12359
12360 if (flags & ShouldCapture) {
12361 workInProgress.flags = flags & ~ShouldCapture | DidCapture;
12362
12363 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
12364 transferActualDuration(workInProgress);
12365 }
12366
12367 return workInProgress;
12368 }
12369
12370 return null;
12371 }
12372
12373 case HostRoot:
12374 {
12375 var root = workInProgress.stateNode;
12376 popHostContainer(workInProgress);
12377 popTopLevelContextObject(workInProgress);
12378 resetWorkInProgressVersions();
12379 var _flags = workInProgress.flags;
12380
12381 if ((_flags & ShouldCapture) !== NoFlags && (_flags & DidCapture) === NoFlags) {
12382 // There was an error during render that wasn't captured by a suspense
12383 // boundary. Do a second pass on the root to unmount the children.
12384 workInProgress.flags = _flags & ~ShouldCapture | DidCapture;
12385 return workInProgress;
12386 } // We unwound to the root without completing it. Exit.
12387
12388
12389 return null;
12390 }
12391
12392 case HostComponent:
12393 {
12394 // TODO: popHydrationState
12395 popHostContext(workInProgress);
12396 return null;
12397 }
12398
12399 case SuspenseComponent:
12400 {
12401 popSuspenseContext(workInProgress);
12402 var suspenseState = workInProgress.memoizedState;
12403
12404 if (suspenseState !== null && suspenseState.dehydrated !== null) {
12405 if (workInProgress.alternate === null) {
12406 throw new Error('Threw in newly mounted dehydrated component. This is likely a bug in ' + 'React. Please file an issue.');
12407 }
12408 }
12409
12410 var _flags2 = workInProgress.flags;
12411
12412 if (_flags2 & ShouldCapture) {
12413 workInProgress.flags = _flags2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
12414
12415 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
12416 transferActualDuration(workInProgress);
12417 }
12418
12419 return workInProgress;
12420 }
12421
12422 return null;
12423 }
12424
12425 case SuspenseListComponent:
12426 {
12427 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
12428 // caught by a nested boundary. If not, it should bubble through.
12429
12430 return null;
12431 }
12432
12433 case HostPortal:
12434 popHostContainer(workInProgress);
12435 return null;
12436
12437 case ContextProvider:
12438 var context = workInProgress.type._context;
12439 popProvider(context, workInProgress);
12440 return null;
12441
12442 case OffscreenComponent:
12443 case LegacyHiddenComponent:
12444 popRenderLanes(workInProgress);
12445 return null;
12446
12447 case CacheComponent:
12448
12449 return null;
12450
12451 default:
12452 return null;
12453 }
12454}
12455
12456function unwindInterruptedWork(current, interruptedWork, renderLanes) {
12457 // Note: This intentionally doesn't check if we're hydrating because comparing
12458 // to the current tree provider fiber is just as fast and less error-prone.
12459 // Ideally we would have a special version of the work loop only
12460 // for hydration.
12461 popTreeContext(interruptedWork);
12462
12463 switch (interruptedWork.tag) {
12464 case ClassComponent:
12465 {
12466 var childContextTypes = interruptedWork.type.childContextTypes;
12467
12468 if (childContextTypes !== null && childContextTypes !== undefined) {
12469 popContext(interruptedWork);
12470 }
12471
12472 break;
12473 }
12474
12475 case HostRoot:
12476 {
12477 var root = interruptedWork.stateNode;
12478 popHostContainer(interruptedWork);
12479 popTopLevelContextObject(interruptedWork);
12480 resetWorkInProgressVersions();
12481 break;
12482 }
12483
12484 case HostComponent:
12485 {
12486 popHostContext(interruptedWork);
12487 break;
12488 }
12489
12490 case HostPortal:
12491 popHostContainer(interruptedWork);
12492 break;
12493
12494 case SuspenseComponent:
12495 popSuspenseContext(interruptedWork);
12496 break;
12497
12498 case SuspenseListComponent:
12499 popSuspenseContext(interruptedWork);
12500 break;
12501
12502 case ContextProvider:
12503 var context = interruptedWork.type._context;
12504 popProvider(context, interruptedWork);
12505 break;
12506
12507 case OffscreenComponent:
12508 case LegacyHiddenComponent:
12509 popRenderLanes(interruptedWork);
12510 break;
12511 }
12512}
12513
12514function invokeGuardedCallbackProd(name, func, context, a, b, c, d, e, f) {
12515 var funcArgs = Array.prototype.slice.call(arguments, 3);
12516
12517 try {
12518 func.apply(context, funcArgs);
12519 } catch (error) {
12520 this.onError(error);
12521 }
12522}
12523
12524var invokeGuardedCallbackImpl = invokeGuardedCallbackProd;
12525
12526{
12527 // In DEV mode, we swap out invokeGuardedCallback for a special version
12528 // that plays more nicely with the browser's DevTools. The idea is to preserve
12529 // "Pause on exceptions" behavior. Because React wraps all user-provided
12530 // functions in invokeGuardedCallback, and the production version of
12531 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
12532 // like caught exceptions, and the DevTools won't pause unless the developer
12533 // takes the extra step of enabling pause on caught exceptions. This is
12534 // unintuitive, though, because even though React has caught the error, from
12535 // the developer's perspective, the error is uncaught.
12536 //
12537 // To preserve the expected "Pause on exceptions" behavior, we don't use a
12538 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
12539 // DOM node, and call the user-provided callback from inside an event handler
12540 // for that fake event. If the callback throws, the error is "captured" using
12541 // a global event handler. But because the error happens in a different
12542 // event loop context, it does not interrupt the normal program flow.
12543 // Effectively, this gives us try-catch behavior without actually using
12544 // try-catch. Neat!
12545 // Check that the browser supports the APIs we need to implement our special
12546 // DEV version of invokeGuardedCallback
12547 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
12548 var fakeNode = document.createElement('react');
12549
12550 invokeGuardedCallbackImpl = function invokeGuardedCallbackDev(name, func, context, a, b, c, d, e, f) {
12551 // If document doesn't exist we know for sure we will crash in this method
12552 // when we call document.createEvent(). However this can cause confusing
12553 // errors: https://github.com/facebook/create-react-app/issues/3482
12554 // So we preemptively throw with a better message instead.
12555 if (typeof document === 'undefined' || document === null) {
12556 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.');
12557 }
12558
12559 var evt = document.createEvent('Event');
12560 var didCall = false; // Keeps track of whether the user-provided callback threw an error. We
12561 // set this to true at the beginning, then set it to false right after
12562 // calling the function. If the function errors, `didError` will never be
12563 // set to false. This strategy works even if the browser is flaky and
12564 // fails to call our global error handler, because it doesn't rely on
12565 // the error event at all.
12566
12567 var didError = true; // Keeps track of the value of window.event so that we can reset it
12568 // during the callback to let user code access window.event in the
12569 // browsers that support it.
12570
12571 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event
12572 // dispatching: https://github.com/facebook/react/issues/13688
12573
12574 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
12575
12576 function restoreAfterDispatch() {
12577 // We immediately remove the callback from event listeners so that
12578 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
12579 // nested call would trigger the fake event handlers of any call higher
12580 // in the stack.
12581 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the
12582 // window.event assignment in both IE <= 10 as they throw an error
12583 // "Member not found" in strict mode, and in Firefox which does not
12584 // support window.event.
12585
12586 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
12587 window.event = windowEvent;
12588 }
12589 } // Create an event handler for our fake event. We will synchronously
12590 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
12591 // call the user-provided callback.
12592
12593
12594 var funcArgs = Array.prototype.slice.call(arguments, 3);
12595
12596 function callCallback() {
12597 didCall = true;
12598 restoreAfterDispatch();
12599 func.apply(context, funcArgs);
12600 didError = false;
12601 } // Create a global error event handler. We use this to capture the value
12602 // that was thrown. It's possible that this error handler will fire more
12603 // than once; for example, if non-React code also calls `dispatchEvent`
12604 // and a handler for that event throws. We should be resilient to most of
12605 // those cases. Even if our error event handler fires more than once, the
12606 // last error event is always used. If the callback actually does error,
12607 // we know that the last error event is the correct one, because it's not
12608 // possible for anything else to have happened in between our callback
12609 // erroring and the code that follows the `dispatchEvent` call below. If
12610 // the callback doesn't error, but the error event was fired, we know to
12611 // ignore it because `didError` will be false, as described above.
12612
12613
12614 var error; // Use this to track whether the error event is ever called.
12615
12616 var didSetError = false;
12617 var isCrossOriginError = false;
12618
12619 function handleWindowError(event) {
12620 error = event.error;
12621 didSetError = true;
12622
12623 if (error === null && event.colno === 0 && event.lineno === 0) {
12624 isCrossOriginError = true;
12625 }
12626
12627 if (event.defaultPrevented) {
12628 // Some other error handler has prevented default.
12629 // Browsers silence the error report if this happens.
12630 // We'll remember this to later decide whether to log it or not.
12631 if (error != null && typeof error === 'object') {
12632 try {
12633 error._suppressLogging = true;
12634 } catch (inner) {// Ignore.
12635 }
12636 }
12637 }
12638 } // Create a fake event type.
12639
12640
12641 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers
12642
12643 window.addEventListener('error', handleWindowError);
12644 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function
12645 // errors, it will trigger our global error handler.
12646
12647 evt.initEvent(evtType, false, false);
12648 fakeNode.dispatchEvent(evt);
12649
12650 if (windowEventDescriptor) {
12651 Object.defineProperty(window, 'event', windowEventDescriptor);
12652 }
12653
12654 if (didCall && didError) {
12655 if (!didSetError) {
12656 // The callback errored, but the error event never fired.
12657 // eslint-disable-next-line react-internal/prod-error-codes
12658 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.');
12659 } else if (isCrossOriginError) {
12660 // eslint-disable-next-line react-internal/prod-error-codes
12661 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.');
12662 }
12663
12664 this.onError(error);
12665 } // Remove our event listeners
12666
12667
12668 window.removeEventListener('error', handleWindowError);
12669
12670 if (!didCall) {
12671 // Something went really wrong, and our event was not dispatched.
12672 // https://github.com/facebook/react/issues/16734
12673 // https://github.com/facebook/react/issues/16585
12674 // Fall back to the production implementation.
12675 restoreAfterDispatch();
12676 return invokeGuardedCallbackProd.apply(this, arguments);
12677 }
12678 };
12679 }
12680}
12681
12682var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
12683
12684var hasError = false;
12685var caughtError = null; // Used by event system to capture/rethrow the first error.
12686var reporter = {
12687 onError: function (error) {
12688 hasError = true;
12689 caughtError = error;
12690 }
12691};
12692/**
12693 * Call a function while guarding against errors that happens within it.
12694 * Returns an error if it throws, otherwise null.
12695 *
12696 * In production, this is implemented using a try-catch. The reason we don't
12697 * use a try-catch directly is so that we can swap out a different
12698 * implementation in DEV mode.
12699 *
12700 * @param {String} name of the guard to use for logging or debugging
12701 * @param {Function} func The function to invoke
12702 * @param {*} context The context to use when calling the function
12703 * @param {...*} args Arguments for function
12704 */
12705
12706function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
12707 hasError = false;
12708 caughtError = null;
12709 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
12710}
12711function clearCaughtError() {
12712 if (hasError) {
12713 var error = caughtError;
12714 hasError = false;
12715 caughtError = null;
12716 return error;
12717 } else {
12718 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.');
12719 }
12720}
12721
12722var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
12723
12724{
12725 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
12726} // Used during the commit phase to track the state of the Offscreen component stack.
12727var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
12728var nextEffect = null; // Used for Profiling builds to track updaters.
12729function reportUncaughtErrorInDEV(error) {
12730 // Wrapping each small part of the commit phase into a guarded
12731 // callback is a bit too slow (https://github.com/facebook/react/pull/21666).
12732 // But we rely on it to surface errors to DEV tools like overlays
12733 // (https://github.com/facebook/react/issues/21712).
12734 // As a compromise, rethrow only caught errors in a guard.
12735 {
12736 invokeGuardedCallback(null, function () {
12737 throw error;
12738 });
12739 clearCaughtError();
12740 }
12741}
12742
12743var callComponentWillUnmountWithTimer = function (current, instance) {
12744 instance.props = current.memoizedProps;
12745 instance.state = current.memoizedState;
12746
12747 if ( current.mode & ProfileMode) {
12748 try {
12749 startLayoutEffectTimer();
12750 instance.componentWillUnmount();
12751 } finally {
12752 recordLayoutEffectDuration(current);
12753 }
12754 } else {
12755 instance.componentWillUnmount();
12756 }
12757}; // Capture errors so they don't interrupt mounting.
12758
12759
12760function safelyCallComponentWillUnmount(current, nearestMountedAncestor, instance) {
12761 try {
12762 callComponentWillUnmountWithTimer(current, instance);
12763 } catch (error) {
12764 captureCommitPhaseError(current, nearestMountedAncestor, error);
12765 }
12766} // Capture errors so they don't interrupt mounting.
12767
12768function safelyDetachRef(current, nearestMountedAncestor) {
12769 var ref = current.ref;
12770
12771 if (ref !== null) {
12772 if (typeof ref === 'function') {
12773 var retVal;
12774
12775 try {
12776 if (enableProfilerTimer && enableProfilerCommitHooks && current.mode & ProfileMode) {
12777 try {
12778 startLayoutEffectTimer();
12779 retVal = ref(null);
12780 } finally {
12781 recordLayoutEffectDuration(current);
12782 }
12783 } else {
12784 retVal = ref(null);
12785 }
12786 } catch (error) {
12787 captureCommitPhaseError(current, nearestMountedAncestor, error);
12788 }
12789
12790 {
12791 if (typeof retVal === 'function') {
12792 error('Unexpected return value from a callback ref in %s. ' + 'A callback ref should not return a function.', getComponentNameFromFiber(current));
12793 }
12794 }
12795 } else {
12796 ref.current = null;
12797 }
12798 }
12799}
12800
12801function safelyCallDestroy(current, nearestMountedAncestor, destroy) {
12802 try {
12803 destroy();
12804 } catch (error) {
12805 captureCommitPhaseError(current, nearestMountedAncestor, error);
12806 }
12807}
12808
12809var focusedInstanceHandle = null;
12810var shouldFireAfterActiveInstanceBlur = false;
12811function commitBeforeMutationEffects(root, firstChild) {
12812 focusedInstanceHandle = prepareForCommit(root.containerInfo);
12813 nextEffect = firstChild;
12814 commitBeforeMutationEffects_begin(); // We no longer need to track the active instance fiber
12815
12816 var shouldFire = shouldFireAfterActiveInstanceBlur;
12817 shouldFireAfterActiveInstanceBlur = false;
12818 focusedInstanceHandle = null;
12819 return shouldFire;
12820}
12821
12822function commitBeforeMutationEffects_begin() {
12823 while (nextEffect !== null) {
12824 var fiber = nextEffect; // This phase is only used for beforeActiveInstanceBlur.
12825
12826 var child = fiber.child;
12827
12828 if ((fiber.subtreeFlags & BeforeMutationMask) !== NoFlags && child !== null) {
12829 child.return = fiber;
12830 nextEffect = child;
12831 } else {
12832 commitBeforeMutationEffects_complete();
12833 }
12834 }
12835}
12836
12837function commitBeforeMutationEffects_complete() {
12838 while (nextEffect !== null) {
12839 var fiber = nextEffect;
12840 setCurrentFiber(fiber);
12841
12842 try {
12843 commitBeforeMutationEffectsOnFiber(fiber);
12844 } catch (error) {
12845 captureCommitPhaseError(fiber, fiber.return, error);
12846 }
12847
12848 resetCurrentFiber();
12849 var sibling = fiber.sibling;
12850
12851 if (sibling !== null) {
12852 sibling.return = fiber.return;
12853 nextEffect = sibling;
12854 return;
12855 }
12856
12857 nextEffect = fiber.return;
12858 }
12859}
12860
12861function commitBeforeMutationEffectsOnFiber(finishedWork) {
12862 var current = finishedWork.alternate;
12863 var flags = finishedWork.flags;
12864
12865 if ((flags & Snapshot) !== NoFlags) {
12866 setCurrentFiber(finishedWork);
12867
12868 switch (finishedWork.tag) {
12869 case FunctionComponent:
12870 case ForwardRef:
12871 case SimpleMemoComponent:
12872 {
12873 break;
12874 }
12875
12876 case ClassComponent:
12877 {
12878 if (current !== null) {
12879 var prevProps = current.memoizedProps;
12880 var prevState = current.memoizedState;
12881 var instance = finishedWork.stateNode; // We could update instance props and state here,
12882 // but instead we rely on them being set during last render.
12883 // TODO: revisit this when we implement resuming.
12884
12885 {
12886 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
12887 if (instance.props !== finishedWork.memoizedProps) {
12888 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');
12889 }
12890
12891 if (instance.state !== finishedWork.memoizedState) {
12892 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');
12893 }
12894 }
12895 }
12896
12897 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
12898
12899 {
12900 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
12901
12902 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
12903 didWarnSet.add(finishedWork.type);
12904
12905 error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentNameFromFiber(finishedWork));
12906 }
12907 }
12908
12909 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
12910 }
12911
12912 break;
12913 }
12914
12915 case HostRoot:
12916 {
12917 {
12918 var root = finishedWork.stateNode;
12919 clearContainer(root.containerInfo);
12920 }
12921
12922 break;
12923 }
12924
12925 case HostComponent:
12926 case HostText:
12927 case HostPortal:
12928 case IncompleteClassComponent:
12929 // Nothing to do for these component types
12930 break;
12931
12932 default:
12933 {
12934 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.');
12935 }
12936 }
12937
12938 resetCurrentFiber();
12939 }
12940}
12941
12942function commitHookEffectListUnmount(flags, finishedWork, nearestMountedAncestor) {
12943 var updateQueue = finishedWork.updateQueue;
12944 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
12945
12946 if (lastEffect !== null) {
12947 var firstEffect = lastEffect.next;
12948 var effect = firstEffect;
12949
12950 do {
12951 if ((effect.tag & flags) === flags) {
12952 // Unmount
12953 var destroy = effect.destroy;
12954 effect.destroy = undefined;
12955
12956 if (destroy !== undefined) {
12957
12958 {
12959 if ((flags & Insertion) !== NoFlags$1) {
12960 setIsRunningInsertionEffect(true);
12961 }
12962 }
12963
12964 safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy);
12965
12966 {
12967 if ((flags & Insertion) !== NoFlags$1) {
12968 setIsRunningInsertionEffect(false);
12969 }
12970 }
12971 }
12972 }
12973
12974 effect = effect.next;
12975 } while (effect !== firstEffect);
12976 }
12977}
12978
12979function commitHookEffectListMount(flags, finishedWork) {
12980 var updateQueue = finishedWork.updateQueue;
12981 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
12982
12983 if (lastEffect !== null) {
12984 var firstEffect = lastEffect.next;
12985 var effect = firstEffect;
12986
12987 do {
12988 if ((effect.tag & flags) === flags) {
12989
12990
12991 var create = effect.create;
12992
12993 {
12994 if ((flags & Insertion) !== NoFlags$1) {
12995 setIsRunningInsertionEffect(true);
12996 }
12997 }
12998
12999 effect.destroy = create();
13000
13001 {
13002 if ((flags & Insertion) !== NoFlags$1) {
13003 setIsRunningInsertionEffect(false);
13004 }
13005 }
13006
13007 {
13008 var destroy = effect.destroy;
13009
13010 if (destroy !== undefined && typeof destroy !== 'function') {
13011 var hookName = void 0;
13012
13013 if ((effect.tag & Layout) !== NoFlags) {
13014 hookName = 'useLayoutEffect';
13015 } else if ((effect.tag & Insertion) !== NoFlags) {
13016 hookName = 'useInsertionEffect';
13017 } else {
13018 hookName = 'useEffect';
13019 }
13020
13021 var addendum = void 0;
13022
13023 if (destroy === null) {
13024 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
13025 } else if (typeof destroy.then === 'function') {
13026 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';
13027 } else {
13028 addendum = ' You returned: ' + destroy;
13029 }
13030
13031 error('%s must not return anything besides a function, ' + 'which is used for clean-up.%s', hookName, addendum);
13032 }
13033 }
13034 }
13035
13036 effect = effect.next;
13037 } while (effect !== firstEffect);
13038 }
13039}
13040
13041function commitPassiveEffectDurations(finishedRoot, finishedWork) {
13042 {
13043 // Only Profilers with work in their subtree will have an Update effect scheduled.
13044 if ((finishedWork.flags & Update) !== NoFlags) {
13045 switch (finishedWork.tag) {
13046 case Profiler:
13047 {
13048 var passiveEffectDuration = finishedWork.stateNode.passiveEffectDuration;
13049 var _finishedWork$memoize = finishedWork.memoizedProps,
13050 id = _finishedWork$memoize.id,
13051 onPostCommit = _finishedWork$memoize.onPostCommit; // This value will still reflect the previous commit phase.
13052 // It does not get reset until the start of the next commit phase.
13053
13054 var commitTime = getCommitTime();
13055 var phase = finishedWork.alternate === null ? 'mount' : 'update';
13056
13057 {
13058 if (isCurrentUpdateNested()) {
13059 phase = 'nested-update';
13060 }
13061 }
13062
13063 if (typeof onPostCommit === 'function') {
13064 onPostCommit(id, phase, passiveEffectDuration, commitTime);
13065 } // Bubble times to the next nearest ancestor Profiler.
13066 // After we process that Profiler, we'll bubble further up.
13067
13068
13069 var parentFiber = finishedWork.return;
13070
13071 outer: while (parentFiber !== null) {
13072 switch (parentFiber.tag) {
13073 case HostRoot:
13074 var root = parentFiber.stateNode;
13075 root.passiveEffectDuration += passiveEffectDuration;
13076 break outer;
13077
13078 case Profiler:
13079 var parentStateNode = parentFiber.stateNode;
13080 parentStateNode.passiveEffectDuration += passiveEffectDuration;
13081 break outer;
13082 }
13083
13084 parentFiber = parentFiber.return;
13085 }
13086
13087 break;
13088 }
13089 }
13090 }
13091 }
13092}
13093
13094function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork, committedLanes) {
13095 if ((finishedWork.flags & LayoutMask) !== NoFlags) {
13096 switch (finishedWork.tag) {
13097 case FunctionComponent:
13098 case ForwardRef:
13099 case SimpleMemoComponent:
13100 {
13101 {
13102 // At this point layout effects have already been destroyed (during mutation phase).
13103 // This is done to prevent sibling component effects from interfering with each other,
13104 // e.g. a destroy function in one component should never override a ref set
13105 // by a create function in another component during the same commit.
13106 if ( finishedWork.mode & ProfileMode) {
13107 try {
13108 startLayoutEffectTimer();
13109 commitHookEffectListMount(Layout | HasEffect, finishedWork);
13110 } finally {
13111 recordLayoutEffectDuration(finishedWork);
13112 }
13113 } else {
13114 commitHookEffectListMount(Layout | HasEffect, finishedWork);
13115 }
13116 }
13117
13118 break;
13119 }
13120
13121 case ClassComponent:
13122 {
13123 var instance = finishedWork.stateNode;
13124
13125 if (finishedWork.flags & Update) {
13126 {
13127 if (current === null) {
13128 // We could update instance props and state here,
13129 // but instead we rely on them being set during last render.
13130 // TODO: revisit this when we implement resuming.
13131 {
13132 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
13133 if (instance.props !== finishedWork.memoizedProps) {
13134 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');
13135 }
13136
13137 if (instance.state !== finishedWork.memoizedState) {
13138 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');
13139 }
13140 }
13141 }
13142
13143 if ( finishedWork.mode & ProfileMode) {
13144 try {
13145 startLayoutEffectTimer();
13146 instance.componentDidMount();
13147 } finally {
13148 recordLayoutEffectDuration(finishedWork);
13149 }
13150 } else {
13151 instance.componentDidMount();
13152 }
13153 } else {
13154 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
13155 var prevState = current.memoizedState; // We could update instance props and state here,
13156 // but instead we rely on them being set during last render.
13157 // TODO: revisit this when we implement resuming.
13158
13159 {
13160 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
13161 if (instance.props !== finishedWork.memoizedProps) {
13162 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');
13163 }
13164
13165 if (instance.state !== finishedWork.memoizedState) {
13166 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');
13167 }
13168 }
13169 }
13170
13171 if ( finishedWork.mode & ProfileMode) {
13172 try {
13173 startLayoutEffectTimer();
13174 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
13175 } finally {
13176 recordLayoutEffectDuration(finishedWork);
13177 }
13178 } else {
13179 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
13180 }
13181 }
13182 }
13183 } // TODO: I think this is now always non-null by the time it reaches the
13184 // commit phase. Consider removing the type check.
13185
13186
13187 var updateQueue = finishedWork.updateQueue;
13188
13189 if (updateQueue !== null) {
13190 {
13191 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
13192 if (instance.props !== finishedWork.memoizedProps) {
13193 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');
13194 }
13195
13196 if (instance.state !== finishedWork.memoizedState) {
13197 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');
13198 }
13199 }
13200 } // We could update instance props and state here,
13201 // but instead we rely on them being set during last render.
13202 // TODO: revisit this when we implement resuming.
13203
13204
13205 commitUpdateQueue(finishedWork, updateQueue, instance);
13206 }
13207
13208 break;
13209 }
13210
13211 case HostRoot:
13212 {
13213 // TODO: I think this is now always non-null by the time it reaches the
13214 // commit phase. Consider removing the type check.
13215 var _updateQueue = finishedWork.updateQueue;
13216
13217 if (_updateQueue !== null) {
13218 var _instance = null;
13219
13220 if (finishedWork.child !== null) {
13221 switch (finishedWork.child.tag) {
13222 case HostComponent:
13223 _instance = getPublicInstance(finishedWork.child.stateNode);
13224 break;
13225
13226 case ClassComponent:
13227 _instance = finishedWork.child.stateNode;
13228 break;
13229 }
13230 }
13231
13232 commitUpdateQueue(finishedWork, _updateQueue, _instance);
13233 }
13234
13235 break;
13236 }
13237
13238 case HostComponent:
13239 {
13240 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted
13241 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
13242 // These effects should only be committed when components are first mounted,
13243 // aka when there is no current/alternate.
13244
13245 if (current === null && finishedWork.flags & Update) {
13246 var type = finishedWork.type;
13247 var props = finishedWork.memoizedProps;
13248 }
13249
13250 break;
13251 }
13252
13253 case HostText:
13254 {
13255 // We have no life-cycles associated with text.
13256 break;
13257 }
13258
13259 case HostPortal:
13260 {
13261 // We have no life-cycles associated with portals.
13262 break;
13263 }
13264
13265 case Profiler:
13266 {
13267 {
13268 var _finishedWork$memoize2 = finishedWork.memoizedProps,
13269 onCommit = _finishedWork$memoize2.onCommit,
13270 onRender = _finishedWork$memoize2.onRender;
13271 var effectDuration = finishedWork.stateNode.effectDuration;
13272 var commitTime = getCommitTime();
13273 var phase = current === null ? 'mount' : 'update';
13274
13275 {
13276 if (isCurrentUpdateNested()) {
13277 phase = 'nested-update';
13278 }
13279 }
13280
13281 if (typeof onRender === 'function') {
13282 onRender(finishedWork.memoizedProps.id, phase, finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, commitTime);
13283 }
13284
13285 {
13286 if (typeof onCommit === 'function') {
13287 onCommit(finishedWork.memoizedProps.id, phase, effectDuration, commitTime);
13288 } // Schedule a passive effect for this Profiler to call onPostCommit hooks.
13289 // This effect should be scheduled even if there is no onPostCommit callback for this Profiler,
13290 // because the effect is also where times bubble to parent Profilers.
13291
13292
13293 enqueuePendingPassiveProfilerEffect(finishedWork); // Propagate layout effect durations to the next nearest Profiler ancestor.
13294 // Do not reset these values until the next render so DevTools has a chance to read them first.
13295
13296 var parentFiber = finishedWork.return;
13297
13298 outer: while (parentFiber !== null) {
13299 switch (parentFiber.tag) {
13300 case HostRoot:
13301 var root = parentFiber.stateNode;
13302 root.effectDuration += effectDuration;
13303 break outer;
13304
13305 case Profiler:
13306 var parentStateNode = parentFiber.stateNode;
13307 parentStateNode.effectDuration += effectDuration;
13308 break outer;
13309 }
13310
13311 parentFiber = parentFiber.return;
13312 }
13313 }
13314 }
13315
13316 break;
13317 }
13318
13319 case SuspenseComponent:
13320 {
13321 break;
13322 }
13323
13324 case SuspenseListComponent:
13325 case IncompleteClassComponent:
13326 case ScopeComponent:
13327 case OffscreenComponent:
13328 case LegacyHiddenComponent:
13329 case TracingMarkerComponent:
13330 {
13331 break;
13332 }
13333
13334 default:
13335 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.');
13336 }
13337 }
13338
13339 {
13340 {
13341 if (finishedWork.flags & Ref) {
13342 commitAttachRef(finishedWork);
13343 }
13344 }
13345 }
13346}
13347
13348function hideOrUnhideAllChildren(finishedWork, isHidden) {
13349 // Only hide or unhide the top-most host nodes.
13350 var hostSubtreeRoot = null;
13351
13352 {
13353 // We only have the top Fiber that was inserted but we need to recurse down its
13354 // children to find all the terminal nodes.
13355 var node = finishedWork;
13356
13357 while (true) {
13358 if (node.tag === HostComponent) {
13359 if (hostSubtreeRoot === null) {
13360 hostSubtreeRoot = node;
13361
13362 try {
13363 var instance = node.stateNode;
13364
13365 if (isHidden) {
13366 hideInstance(instance);
13367 } else {
13368 unhideInstance(node.stateNode, node.memoizedProps);
13369 }
13370 } catch (error) {
13371 captureCommitPhaseError(finishedWork, finishedWork.return, error);
13372 }
13373 }
13374 } else if (node.tag === HostText) {
13375 if (hostSubtreeRoot === null) {
13376 try {
13377 var _instance3 = node.stateNode;
13378
13379 if (isHidden) {
13380 hideTextInstance(_instance3);
13381 } else {
13382 unhideTextInstance(_instance3, node.memoizedProps);
13383 }
13384 } catch (error) {
13385 captureCommitPhaseError(finishedWork, finishedWork.return, error);
13386 }
13387 }
13388 } else if ((node.tag === OffscreenComponent || node.tag === LegacyHiddenComponent) && node.memoizedState !== null && node !== finishedWork) ; else if (node.child !== null) {
13389 node.child.return = node;
13390 node = node.child;
13391 continue;
13392 }
13393
13394 if (node === finishedWork) {
13395 return;
13396 }
13397
13398 while (node.sibling === null) {
13399 if (node.return === null || node.return === finishedWork) {
13400 return;
13401 }
13402
13403 if (hostSubtreeRoot === node) {
13404 hostSubtreeRoot = null;
13405 }
13406
13407 node = node.return;
13408 }
13409
13410 if (hostSubtreeRoot === node) {
13411 hostSubtreeRoot = null;
13412 }
13413
13414 node.sibling.return = node.return;
13415 node = node.sibling;
13416 }
13417 }
13418}
13419
13420function commitAttachRef(finishedWork) {
13421 var ref = finishedWork.ref;
13422
13423 if (ref !== null) {
13424 var instance = finishedWork.stateNode;
13425 var instanceToUse;
13426
13427 switch (finishedWork.tag) {
13428 case HostComponent:
13429 instanceToUse = getPublicInstance(instance);
13430 break;
13431
13432 default:
13433 instanceToUse = instance;
13434 } // Moved outside to ensure DCE works with this flag
13435
13436 if (typeof ref === 'function') {
13437 var retVal;
13438
13439 if ( finishedWork.mode & ProfileMode) {
13440 try {
13441 startLayoutEffectTimer();
13442 retVal = ref(instanceToUse);
13443 } finally {
13444 recordLayoutEffectDuration(finishedWork);
13445 }
13446 } else {
13447 retVal = ref(instanceToUse);
13448 }
13449
13450 {
13451 if (typeof retVal === 'function') {
13452 error('Unexpected return value from a callback ref in %s. ' + 'A callback ref should not return a function.', getComponentNameFromFiber(finishedWork));
13453 }
13454 }
13455 } else {
13456 {
13457 if (!ref.hasOwnProperty('current')) {
13458 error('Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().', getComponentNameFromFiber(finishedWork));
13459 }
13460 }
13461
13462 ref.current = instanceToUse;
13463 }
13464 }
13465}
13466
13467function detachFiberMutation(fiber) {
13468 // Cut off the return pointer to disconnect it from the tree.
13469 // This enables us to detect and warn against state updates on an unmounted component.
13470 // It also prevents events from bubbling from within disconnected components.
13471 //
13472 // Ideally, we should also clear the child pointer of the parent alternate to let this
13473 // get GC:ed but we don't know which for sure which parent is the current
13474 // one so we'll settle for GC:ing the subtree of this child.
13475 // This child itself will be GC:ed when the parent updates the next time.
13476 //
13477 // Note that we can't clear child or sibling pointers yet.
13478 // They're needed for passive effects and for findDOMNode.
13479 // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects).
13480 //
13481 // Don't reset the alternate yet, either. We need that so we can detach the
13482 // alternate's fields in the passive phase. Clearing the return pointer is
13483 // sufficient for findDOMNode semantics.
13484 var alternate = fiber.alternate;
13485
13486 if (alternate !== null) {
13487 alternate.return = null;
13488 }
13489
13490 fiber.return = null;
13491}
13492
13493function detachFiberAfterEffects(fiber) {
13494 var alternate = fiber.alternate;
13495
13496 if (alternate !== null) {
13497 fiber.alternate = null;
13498 detachFiberAfterEffects(alternate);
13499 } // Note: Defensively using negation instead of < in case
13500 // `deletedTreeCleanUpLevel` is undefined.
13501
13502
13503 {
13504 // Clear cyclical Fiber fields. This level alone is designed to roughly
13505 // approximate the planned Fiber refactor. In that world, `setState` will be
13506 // bound to a special "instance" object instead of a Fiber. The Instance
13507 // object will not have any of these fields. It will only be connected to
13508 // the fiber tree via a single link at the root. So if this level alone is
13509 // sufficient to fix memory issues, that bodes well for our plans.
13510 fiber.child = null;
13511 fiber.deletions = null;
13512 fiber.sibling = null; // The `stateNode` is cyclical because on host nodes it points to the host
13513 // tree, which has its own pointers to children, parents, and siblings.
13514 // The other host nodes also point back to fibers, so we should detach that
13515 // one, too.
13516
13517 if (fiber.tag === HostComponent) {
13518 var hostInstance = fiber.stateNode;
13519 }
13520
13521 fiber.stateNode = null; // I'm intentionally not clearing the `return` field in this level. We
13522 // already disconnect the `return` pointer at the root of the deleted
13523 // subtree (in `detachFiberMutation`). Besides, `return` by itself is not
13524 // cyclical — it's only cyclical when combined with `child`, `sibling`, and
13525 // `alternate`. But we'll clear it in the next level anyway, just in case.
13526
13527 {
13528 fiber._debugOwner = null;
13529 }
13530
13531 {
13532 // Theoretically, nothing in here should be necessary, because we already
13533 // disconnected the fiber from the tree. So even if something leaks this
13534 // particular fiber, it won't leak anything else
13535 //
13536 // The purpose of this branch is to be super aggressive so we can measure
13537 // if there's any difference in memory impact. If there is, that could
13538 // indicate a React leak we don't know about.
13539 fiber.return = null;
13540 fiber.dependencies = null;
13541 fiber.memoizedProps = null;
13542 fiber.memoizedState = null;
13543 fiber.pendingProps = null;
13544 fiber.stateNode = null; // TODO: Move to `commitPassiveUnmountInsideDeletedTreeOnFiber` instead.
13545
13546 fiber.updateQueue = null;
13547 }
13548 }
13549}
13550
13551function getHostParentFiber(fiber) {
13552 var parent = fiber.return;
13553
13554 while (parent !== null) {
13555 if (isHostParent(parent)) {
13556 return parent;
13557 }
13558
13559 parent = parent.return;
13560 }
13561
13562 throw new Error('Expected to find a host parent. This error is likely caused by a bug ' + 'in React. Please file an issue.');
13563}
13564
13565function isHostParent(fiber) {
13566 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
13567}
13568
13569function getHostSibling(fiber) {
13570 // We're going to search forward into the tree until we find a sibling host
13571 // node. Unfortunately, if multiple insertions are done in a row we have to
13572 // search past them. This leads to exponential search for the next sibling.
13573 // TODO: Find a more efficient way to do this.
13574 var node = fiber;
13575
13576 siblings: while (true) {
13577 // If we didn't find anything, let's try the next sibling.
13578 while (node.sibling === null) {
13579 if (node.return === null || isHostParent(node.return)) {
13580 // If we pop out of the root or hit the parent the fiber we are the
13581 // last sibling.
13582 return null;
13583 }
13584
13585 node = node.return;
13586 }
13587
13588 node.sibling.return = node.return;
13589 node = node.sibling;
13590
13591 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {
13592 // If it is not host node and, we might have a host node inside it.
13593 // Try to search down until we find one.
13594 if (node.flags & Placement) {
13595 // If we don't have a child, try the siblings instead.
13596 continue siblings;
13597 } // If we don't have a child, try the siblings instead.
13598 // We also skip portals because they are not part of this host tree.
13599
13600
13601 if (node.child === null || node.tag === HostPortal) {
13602 continue siblings;
13603 } else {
13604 node.child.return = node;
13605 node = node.child;
13606 }
13607 } // Check if this host node is stable or about to be placed.
13608
13609
13610 if (!(node.flags & Placement)) {
13611 // Found it!
13612 return node.stateNode;
13613 }
13614 }
13615}
13616
13617function commitPlacement(finishedWork) {
13618
13619
13620 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.
13621
13622 switch (parentFiber.tag) {
13623 case HostComponent:
13624 {
13625 var parent = parentFiber.stateNode;
13626
13627 if (parentFiber.flags & ContentReset) {
13628
13629 parentFiber.flags &= ~ContentReset;
13630 }
13631
13632 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
13633 // children to find all the terminal nodes.
13634
13635 insertOrAppendPlacementNode(finishedWork, before, parent);
13636 break;
13637 }
13638
13639 case HostRoot:
13640 case HostPortal:
13641 {
13642 var _parent = parentFiber.stateNode.containerInfo;
13643
13644 var _before = getHostSibling(finishedWork);
13645
13646 insertOrAppendPlacementNodeIntoContainer(finishedWork, _before, _parent);
13647 break;
13648 }
13649 // eslint-disable-next-line-no-fallthrough
13650
13651 default:
13652 throw new Error('Invalid host parent fiber. This error is likely caused by a bug ' + 'in React. Please file an issue.');
13653 }
13654}
13655
13656function insertOrAppendPlacementNodeIntoContainer(node, before, parent) {
13657 var tag = node.tag;
13658 var isHost = tag === HostComponent || tag === HostText;
13659
13660 if (isHost) {
13661 var stateNode = node.stateNode;
13662
13663 if (before) {
13664 insertInContainerBefore(parent, stateNode, before);
13665 } else {
13666 appendChildToContainer(parent, stateNode);
13667 }
13668 } else if (tag === HostPortal) ; else {
13669 var child = node.child;
13670
13671 if (child !== null) {
13672 insertOrAppendPlacementNodeIntoContainer(child, before, parent);
13673 var sibling = child.sibling;
13674
13675 while (sibling !== null) {
13676 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);
13677 sibling = sibling.sibling;
13678 }
13679 }
13680 }
13681}
13682
13683function insertOrAppendPlacementNode(node, before, parent) {
13684 var tag = node.tag;
13685 var isHost = tag === HostComponent || tag === HostText;
13686
13687 if (isHost) {
13688 var stateNode = node.stateNode;
13689
13690 if (before) {
13691 insertBefore(parent, stateNode, before);
13692 } else {
13693 appendChild(parent, stateNode);
13694 }
13695 } else if (tag === HostPortal) ; else {
13696 var child = node.child;
13697
13698 if (child !== null) {
13699 insertOrAppendPlacementNode(child, before, parent);
13700 var sibling = child.sibling;
13701
13702 while (sibling !== null) {
13703 insertOrAppendPlacementNode(sibling, before, parent);
13704 sibling = sibling.sibling;
13705 }
13706 }
13707 }
13708} // These are tracked on the stack as we recursively traverse a
13709// deleted subtree.
13710// TODO: Update these during the whole mutation phase, not just during
13711// a deletion.
13712
13713
13714var hostParent = null;
13715var hostParentIsContainer = false;
13716
13717function commitDeletionEffects(root, returnFiber, deletedFiber) {
13718 {
13719 // We only have the top Fiber that was deleted but we need to recurse down its
13720 // children to find all the terminal nodes.
13721 // Recursively delete all host nodes from the parent, detach refs, clean
13722 // up mounted layout effects, and call componentWillUnmount.
13723 // We only need to remove the topmost host child in each branch. But then we
13724 // still need to keep traversing to unmount effects, refs, and cWU. TODO: We
13725 // could split this into two separate traversals functions, where the second
13726 // one doesn't include any removeChild logic. This is maybe the same
13727 // function as "disappearLayoutEffects" (or whatever that turns into after
13728 // the layout phase is refactored to use recursion).
13729 // Before starting, find the nearest host parent on the stack so we know
13730 // which instance/container to remove the children from.
13731 // TODO: Instead of searching up the fiber return path on every deletion, we
13732 // can track the nearest host component on the JS stack as we traverse the
13733 // tree during the commit phase. This would make insertions faster, too.
13734 var parent = returnFiber;
13735
13736 findParent: while (parent !== null) {
13737 switch (parent.tag) {
13738 case HostComponent:
13739 {
13740 hostParent = parent.stateNode;
13741 hostParentIsContainer = false;
13742 break findParent;
13743 }
13744
13745 case HostRoot:
13746 {
13747 hostParent = parent.stateNode.containerInfo;
13748 hostParentIsContainer = true;
13749 break findParent;
13750 }
13751
13752 case HostPortal:
13753 {
13754 hostParent = parent.stateNode.containerInfo;
13755 hostParentIsContainer = true;
13756 break findParent;
13757 }
13758 }
13759
13760 parent = parent.return;
13761 }
13762
13763 if (hostParent === null) {
13764 throw new Error('Expected to find a host parent. This error is likely caused by ' + 'a bug in React. Please file an issue.');
13765 }
13766
13767 commitDeletionEffectsOnFiber(root, returnFiber, deletedFiber);
13768 hostParent = null;
13769 hostParentIsContainer = false;
13770 }
13771
13772 detachFiberMutation(deletedFiber);
13773}
13774
13775function recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, parent) {
13776 // TODO: Use a static flag to skip trees that don't have unmount effects
13777 var child = parent.child;
13778
13779 while (child !== null) {
13780 commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, child);
13781 child = child.sibling;
13782 }
13783}
13784
13785function commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, deletedFiber) {
13786 onCommitUnmount(deletedFiber); // The cases in this outer switch modify the stack before they traverse
13787 // into their subtree. There are simpler cases in the inner switch
13788 // that don't modify the stack.
13789
13790 switch (deletedFiber.tag) {
13791 case HostComponent:
13792 {
13793 {
13794 safelyDetachRef(deletedFiber, nearestMountedAncestor);
13795 } // Intentional fallthrough to next branch
13796
13797 }
13798 // eslint-disable-next-line-no-fallthrough
13799
13800 case HostText:
13801 {
13802 // We only need to remove the nearest host child. Set the host parent
13803 // to `null` on the stack to indicate that nested children don't
13804 // need to be removed.
13805 {
13806 var prevHostParent = hostParent;
13807 var prevHostParentIsContainer = hostParentIsContainer;
13808 hostParent = null;
13809 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
13810 hostParent = prevHostParent;
13811 hostParentIsContainer = prevHostParentIsContainer;
13812
13813 if (hostParent !== null) {
13814 // Now that all the child effects have unmounted, we can remove the
13815 // node from the tree.
13816 if (hostParentIsContainer) {
13817 removeChildFromContainer(hostParent, deletedFiber.stateNode);
13818 } else {
13819 removeChild(hostParent, deletedFiber.stateNode);
13820 }
13821 }
13822 }
13823
13824 return;
13825 }
13826
13827 case DehydratedFragment:
13828 {
13829 // Delete the dehydrated suspense boundary and all of its content.
13830
13831
13832 {
13833 if (hostParent !== null) {
13834 if (hostParentIsContainer) {
13835 clearSuspenseBoundaryFromContainer(hostParent, deletedFiber.stateNode);
13836 } else {
13837 clearSuspenseBoundary(hostParent, deletedFiber.stateNode);
13838 }
13839 }
13840 }
13841
13842 return;
13843 }
13844
13845 case HostPortal:
13846 {
13847 {
13848 // When we go into a portal, it becomes the parent to remove from.
13849 var _prevHostParent = hostParent;
13850 var _prevHostParentIsContainer = hostParentIsContainer;
13851 hostParent = deletedFiber.stateNode.containerInfo;
13852 hostParentIsContainer = true;
13853 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
13854 hostParent = _prevHostParent;
13855 hostParentIsContainer = _prevHostParentIsContainer;
13856 }
13857
13858 return;
13859 }
13860
13861 case FunctionComponent:
13862 case ForwardRef:
13863 case MemoComponent:
13864 case SimpleMemoComponent:
13865 {
13866 {
13867 var updateQueue = deletedFiber.updateQueue;
13868
13869 if (updateQueue !== null) {
13870 var lastEffect = updateQueue.lastEffect;
13871
13872 if (lastEffect !== null) {
13873 var firstEffect = lastEffect.next;
13874 var effect = firstEffect;
13875
13876 do {
13877 var _effect = effect,
13878 destroy = _effect.destroy,
13879 tag = _effect.tag;
13880
13881 if (destroy !== undefined) {
13882 if ((tag & Insertion) !== NoFlags$1) {
13883 safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy);
13884 } else if ((tag & Layout) !== NoFlags$1) {
13885
13886 if ( deletedFiber.mode & ProfileMode) {
13887 startLayoutEffectTimer();
13888 safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy);
13889 recordLayoutEffectDuration(deletedFiber);
13890 } else {
13891 safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy);
13892 }
13893 }
13894 }
13895
13896 effect = effect.next;
13897 } while (effect !== firstEffect);
13898 }
13899 }
13900 }
13901
13902 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
13903 return;
13904 }
13905
13906 case ClassComponent:
13907 {
13908 {
13909 safelyDetachRef(deletedFiber, nearestMountedAncestor);
13910 var instance = deletedFiber.stateNode;
13911
13912 if (typeof instance.componentWillUnmount === 'function') {
13913 safelyCallComponentWillUnmount(deletedFiber, nearestMountedAncestor, instance);
13914 }
13915 }
13916
13917 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
13918 return;
13919 }
13920
13921 case ScopeComponent:
13922 {
13923
13924 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
13925 return;
13926 }
13927
13928 case OffscreenComponent:
13929 {
13930 {
13931 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
13932 }
13933
13934 break;
13935 }
13936
13937 default:
13938 {
13939 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
13940 return;
13941 }
13942 }
13943}
13944
13945function commitSuspenseCallback(finishedWork) {
13946 // TODO: Move this to passive phase
13947 var newState = finishedWork.memoizedState;
13948}
13949
13950function attachSuspenseRetryListeners(finishedWork) {
13951 // If this boundary just timed out, then it will have a set of wakeables.
13952 // For each wakeable, attach a listener so that when it resolves, React
13953 // attempts to re-render the boundary in the primary (pre-timeout) state.
13954 var wakeables = finishedWork.updateQueue;
13955
13956 if (wakeables !== null) {
13957 finishedWork.updateQueue = null;
13958 var retryCache = finishedWork.stateNode;
13959
13960 if (retryCache === null) {
13961 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
13962 }
13963
13964 wakeables.forEach(function (wakeable) {
13965 // Memoize using the boundary fiber to prevent redundant listeners.
13966 var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable);
13967
13968 if (!retryCache.has(wakeable)) {
13969 retryCache.add(wakeable);
13970
13971 wakeable.then(retry, retry);
13972 }
13973 });
13974 }
13975} // This function detects when a Suspense boundary goes from visible to hidden.
13976function commitMutationEffects(root, finishedWork, committedLanes) {
13977 setCurrentFiber(finishedWork);
13978 commitMutationEffectsOnFiber(finishedWork, root);
13979 setCurrentFiber(finishedWork);
13980}
13981
13982function recursivelyTraverseMutationEffects(root, parentFiber, lanes) {
13983 // Deletions effects can be scheduled on any fiber type. They need to happen
13984 // before the children effects hae fired.
13985 var deletions = parentFiber.deletions;
13986
13987 if (deletions !== null) {
13988 for (var i = 0; i < deletions.length; i++) {
13989 var childToDelete = deletions[i];
13990
13991 try {
13992 commitDeletionEffects(root, parentFiber, childToDelete);
13993 } catch (error) {
13994 captureCommitPhaseError(childToDelete, parentFiber, error);
13995 }
13996 }
13997 }
13998
13999 var prevDebugFiber = getCurrentFiber();
14000
14001 if (parentFiber.subtreeFlags & MutationMask) {
14002 var child = parentFiber.child;
14003
14004 while (child !== null) {
14005 setCurrentFiber(child);
14006 commitMutationEffectsOnFiber(child, root);
14007 child = child.sibling;
14008 }
14009 }
14010
14011 setCurrentFiber(prevDebugFiber);
14012}
14013
14014function commitMutationEffectsOnFiber(finishedWork, root, lanes) {
14015 var current = finishedWork.alternate;
14016 var flags = finishedWork.flags; // The effect flag should be checked *after* we refine the type of fiber,
14017 // because the fiber tag is more specific. An exception is any flag related
14018 // to reconcilation, because those can be set on all fiber types.
14019
14020 switch (finishedWork.tag) {
14021 case FunctionComponent:
14022 case ForwardRef:
14023 case MemoComponent:
14024 case SimpleMemoComponent:
14025 {
14026 recursivelyTraverseMutationEffects(root, finishedWork);
14027 commitReconciliationEffects(finishedWork);
14028
14029 if (flags & Update) {
14030 try {
14031 commitHookEffectListUnmount(Insertion | HasEffect, finishedWork, finishedWork.return);
14032 commitHookEffectListMount(Insertion | HasEffect, finishedWork);
14033 } catch (error) {
14034 captureCommitPhaseError(finishedWork, finishedWork.return, error);
14035 } // Layout effects are destroyed during the mutation phase so that all
14036 // destroy functions for all fibers are called before any create functions.
14037 // This prevents sibling component effects from interfering with each other,
14038 // e.g. a destroy function in one component should never override a ref set
14039 // by a create function in another component during the same commit.
14040
14041
14042 if ( finishedWork.mode & ProfileMode) {
14043 try {
14044 startLayoutEffectTimer();
14045 commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return);
14046 } catch (error) {
14047 captureCommitPhaseError(finishedWork, finishedWork.return, error);
14048 }
14049
14050 recordLayoutEffectDuration(finishedWork);
14051 } else {
14052 try {
14053 commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return);
14054 } catch (error) {
14055 captureCommitPhaseError(finishedWork, finishedWork.return, error);
14056 }
14057 }
14058 }
14059
14060 return;
14061 }
14062
14063 case ClassComponent:
14064 {
14065 recursivelyTraverseMutationEffects(root, finishedWork);
14066 commitReconciliationEffects(finishedWork);
14067
14068 if (flags & Ref) {
14069 if (current !== null) {
14070 safelyDetachRef(current, current.return);
14071 }
14072 }
14073
14074 return;
14075 }
14076
14077 case HostComponent:
14078 {
14079 recursivelyTraverseMutationEffects(root, finishedWork);
14080 commitReconciliationEffects(finishedWork);
14081
14082 if (flags & Ref) {
14083 if (current !== null) {
14084 safelyDetachRef(current, current.return);
14085 }
14086 }
14087
14088 {
14089 // TODO: ContentReset gets cleared by the children during the commit
14090 // phase. This is a refactor hazard because it means we must read
14091 // flags the flags after `commitReconciliationEffects` has already run;
14092 // the order matters. We should refactor so that ContentReset does not
14093 // rely on mutating the flag during commit. Like by setting a flag
14094 // during the render phase instead.
14095 if (finishedWork.flags & ContentReset) {
14096 var instance = finishedWork.stateNode;
14097
14098 try {
14099 resetTextContent(instance);
14100 } catch (error) {
14101 captureCommitPhaseError(finishedWork, finishedWork.return, error);
14102 }
14103 }
14104
14105 if (flags & Update) {
14106 var _instance4 = finishedWork.stateNode;
14107
14108 if (_instance4 != null) {
14109 // Commit the work prepared earlier.
14110 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
14111 // as the newProps. The updatePayload will contain the real change in
14112 // this case.
14113
14114 var oldProps = current !== null ? current.memoizedProps : newProps;
14115 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.
14116
14117 var updatePayload = finishedWork.updateQueue;
14118 finishedWork.updateQueue = null;
14119
14120 if (updatePayload !== null) {
14121 try {
14122 commitUpdate(_instance4, updatePayload, type, oldProps, newProps, finishedWork);
14123 } catch (error) {
14124 captureCommitPhaseError(finishedWork, finishedWork.return, error);
14125 }
14126 }
14127 }
14128 }
14129 }
14130
14131 return;
14132 }
14133
14134 case HostText:
14135 {
14136 recursivelyTraverseMutationEffects(root, finishedWork);
14137 commitReconciliationEffects(finishedWork);
14138
14139 if (flags & Update) {
14140 {
14141 if (finishedWork.stateNode === null) {
14142 throw new Error('This should have a text node initialized. This error is likely ' + 'caused by a bug in React. Please file an issue.');
14143 }
14144
14145 var textInstance = finishedWork.stateNode;
14146 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
14147 // as the newProps. The updatePayload will contain the real change in
14148 // this case.
14149
14150 var oldText = current !== null ? current.memoizedProps : newText;
14151
14152 try {
14153 commitTextUpdate(textInstance, oldText, newText);
14154 } catch (error) {
14155 captureCommitPhaseError(finishedWork, finishedWork.return, error);
14156 }
14157 }
14158 }
14159
14160 return;
14161 }
14162
14163 case HostRoot:
14164 {
14165 recursivelyTraverseMutationEffects(root, finishedWork);
14166 commitReconciliationEffects(finishedWork);
14167
14168 return;
14169 }
14170
14171 case HostPortal:
14172 {
14173 recursivelyTraverseMutationEffects(root, finishedWork);
14174 commitReconciliationEffects(finishedWork);
14175
14176 return;
14177 }
14178
14179 case SuspenseComponent:
14180 {
14181 recursivelyTraverseMutationEffects(root, finishedWork);
14182 commitReconciliationEffects(finishedWork);
14183 var offscreenFiber = finishedWork.child;
14184
14185 if (offscreenFiber.flags & Visibility) {
14186 var offscreenInstance = offscreenFiber.stateNode;
14187 var newState = offscreenFiber.memoizedState;
14188 var isHidden = newState !== null; // Track the current state on the Offscreen instance so we can
14189 // read it during an event
14190
14191 offscreenInstance.isHidden = isHidden;
14192
14193 if (isHidden) {
14194 var wasHidden = offscreenFiber.alternate !== null && offscreenFiber.alternate.memoizedState !== null;
14195
14196 if (!wasHidden) {
14197 // TODO: Move to passive phase
14198 markCommitTimeOfFallback();
14199 }
14200 }
14201 }
14202
14203 if (flags & Update) {
14204 try {
14205 commitSuspenseCallback(finishedWork);
14206 } catch (error) {
14207 captureCommitPhaseError(finishedWork, finishedWork.return, error);
14208 }
14209
14210 attachSuspenseRetryListeners(finishedWork);
14211 }
14212
14213 return;
14214 }
14215
14216 case OffscreenComponent:
14217 {
14218 var _wasHidden = current !== null && current.memoizedState !== null;
14219
14220 {
14221 recursivelyTraverseMutationEffects(root, finishedWork);
14222 }
14223
14224 commitReconciliationEffects(finishedWork);
14225
14226 if (flags & Visibility) {
14227 var _offscreenInstance = finishedWork.stateNode;
14228 var _newState = finishedWork.memoizedState;
14229
14230 var _isHidden = _newState !== null;
14231
14232 var offscreenBoundary = finishedWork; // Track the current state on the Offscreen instance so we can
14233 // read it during an event
14234
14235 _offscreenInstance.isHidden = _isHidden;
14236
14237 {
14238 // TODO: This needs to run whenever there's an insertion or update
14239 // inside a hidden Offscreen tree.
14240 hideOrUnhideAllChildren(offscreenBoundary, _isHidden);
14241 }
14242 }
14243
14244 return;
14245 }
14246
14247 case SuspenseListComponent:
14248 {
14249 recursivelyTraverseMutationEffects(root, finishedWork);
14250 commitReconciliationEffects(finishedWork);
14251
14252 if (flags & Update) {
14253 attachSuspenseRetryListeners(finishedWork);
14254 }
14255
14256 return;
14257 }
14258
14259 case ScopeComponent:
14260 {
14261
14262 return;
14263 }
14264
14265 default:
14266 {
14267 recursivelyTraverseMutationEffects(root, finishedWork);
14268 commitReconciliationEffects(finishedWork);
14269 return;
14270 }
14271 }
14272}
14273
14274function commitReconciliationEffects(finishedWork) {
14275 // Placement effects (insertions, reorders) can be scheduled on any fiber
14276 // type. They needs to happen after the children effects have fired, but
14277 // before the effects on this fiber have fired.
14278 var flags = finishedWork.flags;
14279
14280 if (flags & Placement) {
14281 try {
14282 commitPlacement(finishedWork);
14283 } catch (error) {
14284 captureCommitPhaseError(finishedWork, finishedWork.return, error);
14285 } // Clear the "placement" from effect tag so that we know that this is
14286 // inserted, before any life-cycles like componentDidMount gets called.
14287 // TODO: findDOMNode doesn't rely on this any more but isMounted does
14288 // and isMounted is deprecated anyway so we should be able to kill this.
14289
14290
14291 finishedWork.flags &= ~Placement;
14292 }
14293
14294 if (flags & Hydrating) {
14295 finishedWork.flags &= ~Hydrating;
14296 }
14297}
14298
14299function commitLayoutEffects(finishedWork, root, committedLanes) {
14300 nextEffect = finishedWork;
14301 commitLayoutEffects_begin(finishedWork, root, committedLanes);
14302}
14303
14304function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) {
14305 // Suspense layout effects semantics don't change for legacy roots.
14306 var isModernRoot = (subtreeRoot.mode & ConcurrentMode) !== NoMode;
14307
14308 while (nextEffect !== null) {
14309 var fiber = nextEffect;
14310 var firstChild = fiber.child;
14311
14312 if ((fiber.subtreeFlags & LayoutMask) !== NoFlags && firstChild !== null) {
14313 firstChild.return = fiber;
14314 nextEffect = firstChild;
14315 } else {
14316 commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes);
14317 }
14318 }
14319}
14320
14321function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) {
14322 while (nextEffect !== null) {
14323 var fiber = nextEffect;
14324
14325 if ((fiber.flags & LayoutMask) !== NoFlags) {
14326 var current = fiber.alternate;
14327 setCurrentFiber(fiber);
14328
14329 try {
14330 commitLayoutEffectOnFiber(root, current, fiber, committedLanes);
14331 } catch (error) {
14332 captureCommitPhaseError(fiber, fiber.return, error);
14333 }
14334
14335 resetCurrentFiber();
14336 }
14337
14338 if (fiber === subtreeRoot) {
14339 nextEffect = null;
14340 return;
14341 }
14342
14343 var sibling = fiber.sibling;
14344
14345 if (sibling !== null) {
14346 sibling.return = fiber.return;
14347 nextEffect = sibling;
14348 return;
14349 }
14350
14351 nextEffect = fiber.return;
14352 }
14353}
14354
14355function commitPassiveMountEffects(root, finishedWork, committedLanes, committedTransitions) {
14356 nextEffect = finishedWork;
14357 commitPassiveMountEffects_begin(finishedWork, root, committedLanes, committedTransitions);
14358}
14359
14360function commitPassiveMountEffects_begin(subtreeRoot, root, committedLanes, committedTransitions) {
14361 while (nextEffect !== null) {
14362 var fiber = nextEffect;
14363 var firstChild = fiber.child;
14364
14365 if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) {
14366 firstChild.return = fiber;
14367 nextEffect = firstChild;
14368 } else {
14369 commitPassiveMountEffects_complete(subtreeRoot, root, committedLanes, committedTransitions);
14370 }
14371 }
14372}
14373
14374function commitPassiveMountEffects_complete(subtreeRoot, root, committedLanes, committedTransitions) {
14375 while (nextEffect !== null) {
14376 var fiber = nextEffect;
14377
14378 if ((fiber.flags & Passive) !== NoFlags) {
14379 setCurrentFiber(fiber);
14380
14381 try {
14382 commitPassiveMountOnFiber(root, fiber, committedLanes, committedTransitions);
14383 } catch (error) {
14384 captureCommitPhaseError(fiber, fiber.return, error);
14385 }
14386
14387 resetCurrentFiber();
14388 }
14389
14390 if (fiber === subtreeRoot) {
14391 nextEffect = null;
14392 return;
14393 }
14394
14395 var sibling = fiber.sibling;
14396
14397 if (sibling !== null) {
14398 sibling.return = fiber.return;
14399 nextEffect = sibling;
14400 return;
14401 }
14402
14403 nextEffect = fiber.return;
14404 }
14405}
14406
14407function commitPassiveMountOnFiber(finishedRoot, finishedWork, committedLanes, committedTransitions) {
14408 switch (finishedWork.tag) {
14409 case FunctionComponent:
14410 case ForwardRef:
14411 case SimpleMemoComponent:
14412 {
14413 if ( finishedWork.mode & ProfileMode) {
14414 startPassiveEffectTimer();
14415
14416 try {
14417 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
14418 } finally {
14419 recordPassiveEffectDuration(finishedWork);
14420 }
14421 } else {
14422 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
14423 }
14424
14425 break;
14426 }
14427 }
14428}
14429
14430function commitPassiveUnmountEffects(firstChild) {
14431 nextEffect = firstChild;
14432 commitPassiveUnmountEffects_begin();
14433}
14434
14435function commitPassiveUnmountEffects_begin() {
14436 while (nextEffect !== null) {
14437 var fiber = nextEffect;
14438 var child = fiber.child;
14439
14440 if ((nextEffect.flags & ChildDeletion) !== NoFlags) {
14441 var deletions = fiber.deletions;
14442
14443 if (deletions !== null) {
14444 for (var i = 0; i < deletions.length; i++) {
14445 var fiberToDelete = deletions[i];
14446 nextEffect = fiberToDelete;
14447 commitPassiveUnmountEffectsInsideOfDeletedTree_begin(fiberToDelete, fiber);
14448 }
14449
14450 {
14451 // A fiber was deleted from this parent fiber, but it's still part of
14452 // the previous (alternate) parent fiber's list of children. Because
14453 // children are a linked list, an earlier sibling that's still alive
14454 // will be connected to the deleted fiber via its `alternate`:
14455 //
14456 // live fiber
14457 // --alternate--> previous live fiber
14458 // --sibling--> deleted fiber
14459 //
14460 // We can't disconnect `alternate` on nodes that haven't been deleted
14461 // yet, but we can disconnect the `sibling` and `child` pointers.
14462 var previousFiber = fiber.alternate;
14463
14464 if (previousFiber !== null) {
14465 var detachedChild = previousFiber.child;
14466
14467 if (detachedChild !== null) {
14468 previousFiber.child = null;
14469
14470 do {
14471 var detachedSibling = detachedChild.sibling;
14472 detachedChild.sibling = null;
14473 detachedChild = detachedSibling;
14474 } while (detachedChild !== null);
14475 }
14476 }
14477 }
14478
14479 nextEffect = fiber;
14480 }
14481 }
14482
14483 if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) {
14484 child.return = fiber;
14485 nextEffect = child;
14486 } else {
14487 commitPassiveUnmountEffects_complete();
14488 }
14489 }
14490}
14491
14492function commitPassiveUnmountEffects_complete() {
14493 while (nextEffect !== null) {
14494 var fiber = nextEffect;
14495
14496 if ((fiber.flags & Passive) !== NoFlags) {
14497 setCurrentFiber(fiber);
14498 commitPassiveUnmountOnFiber(fiber);
14499 resetCurrentFiber();
14500 }
14501
14502 var sibling = fiber.sibling;
14503
14504 if (sibling !== null) {
14505 sibling.return = fiber.return;
14506 nextEffect = sibling;
14507 return;
14508 }
14509
14510 nextEffect = fiber.return;
14511 }
14512}
14513
14514function commitPassiveUnmountOnFiber(finishedWork) {
14515 switch (finishedWork.tag) {
14516 case FunctionComponent:
14517 case ForwardRef:
14518 case SimpleMemoComponent:
14519 {
14520 if ( finishedWork.mode & ProfileMode) {
14521 startPassiveEffectTimer();
14522 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork, finishedWork.return);
14523 recordPassiveEffectDuration(finishedWork);
14524 } else {
14525 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork, finishedWork.return);
14526 }
14527
14528 break;
14529 }
14530 }
14531}
14532
14533function commitPassiveUnmountEffectsInsideOfDeletedTree_begin(deletedSubtreeRoot, nearestMountedAncestor) {
14534 while (nextEffect !== null) {
14535 var fiber = nextEffect; // Deletion effects fire in parent -> child order
14536 // TODO: Check if fiber has a PassiveStatic flag
14537
14538 setCurrentFiber(fiber);
14539 commitPassiveUnmountInsideDeletedTreeOnFiber(fiber, nearestMountedAncestor);
14540 resetCurrentFiber();
14541 var child = fiber.child; // TODO: Only traverse subtree if it has a PassiveStatic flag. (But, if we
14542 // do this, still need to handle `deletedTreeCleanUpLevel` correctly.)
14543
14544 if (child !== null) {
14545 child.return = fiber;
14546 nextEffect = child;
14547 } else {
14548 commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot);
14549 }
14550 }
14551}
14552
14553function commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot) {
14554 while (nextEffect !== null) {
14555 var fiber = nextEffect;
14556 var sibling = fiber.sibling;
14557 var returnFiber = fiber.return;
14558
14559 {
14560 // Recursively traverse the entire deleted tree and clean up fiber fields.
14561 // This is more aggressive than ideal, and the long term goal is to only
14562 // have to detach the deleted tree at the root.
14563 detachFiberAfterEffects(fiber);
14564
14565 if (fiber === deletedSubtreeRoot) {
14566 nextEffect = null;
14567 return;
14568 }
14569 }
14570
14571 if (sibling !== null) {
14572 sibling.return = returnFiber;
14573 nextEffect = sibling;
14574 return;
14575 }
14576
14577 nextEffect = returnFiber;
14578 }
14579}
14580
14581function commitPassiveUnmountInsideDeletedTreeOnFiber(current, nearestMountedAncestor) {
14582 switch (current.tag) {
14583 case FunctionComponent:
14584 case ForwardRef:
14585 case SimpleMemoComponent:
14586 {
14587 if ( current.mode & ProfileMode) {
14588 startPassiveEffectTimer();
14589 commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor);
14590 recordPassiveEffectDuration(current);
14591 } else {
14592 commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor);
14593 }
14594
14595 break;
14596 }
14597 }
14598} // TODO: Reuse reappearLayoutEffects traversal here?
14599
14600var COMPONENT_TYPE = 0;
14601var HAS_PSEUDO_CLASS_TYPE = 1;
14602var ROLE_TYPE = 2;
14603var TEST_NAME_TYPE = 3;
14604var TEXT_TYPE = 4;
14605
14606if (typeof Symbol === 'function' && Symbol.for) {
14607 var symbolFor = Symbol.for;
14608 COMPONENT_TYPE = symbolFor('selector.component');
14609 HAS_PSEUDO_CLASS_TYPE = symbolFor('selector.has_pseudo_class');
14610 ROLE_TYPE = symbolFor('selector.role');
14611 TEST_NAME_TYPE = symbolFor('selector.test_id');
14612 TEXT_TYPE = symbolFor('selector.text');
14613}
14614
14615var ReactCurrentActQueue = ReactSharedInternals.ReactCurrentActQueue;
14616function isLegacyActEnvironment(fiber) {
14617 {
14618 // Legacy mode. We preserve the behavior of React 17's act. It assumes an
14619 // act environment whenever `jest` is defined, but you can still turn off
14620 // spurious warnings by setting IS_REACT_ACT_ENVIRONMENT explicitly
14621 // to false.
14622 var isReactActEnvironmentGlobal = // $FlowExpectedError – Flow doesn't know about IS_REACT_ACT_ENVIRONMENT global
14623 typeof IS_REACT_ACT_ENVIRONMENT !== 'undefined' ? IS_REACT_ACT_ENVIRONMENT : undefined; // $FlowExpectedError - Flow doesn't know about jest
14624
14625 var jestIsDefined = typeof jest !== 'undefined';
14626 return jestIsDefined && isReactActEnvironmentGlobal !== false;
14627 }
14628}
14629function isConcurrentActEnvironment() {
14630 {
14631 var isReactActEnvironmentGlobal = // $FlowExpectedError – Flow doesn't know about IS_REACT_ACT_ENVIRONMENT global
14632 typeof IS_REACT_ACT_ENVIRONMENT !== 'undefined' ? IS_REACT_ACT_ENVIRONMENT : undefined;
14633
14634 if (!isReactActEnvironmentGlobal && ReactCurrentActQueue.current !== null) {
14635 // TODO: Include link to relevant documentation page.
14636 error('The current testing environment is not configured to support ' + 'act(...)');
14637 }
14638
14639 return isReactActEnvironmentGlobal;
14640 }
14641}
14642
14643var ceil = Math.ceil;
14644var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher,
14645 ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner,
14646 ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig,
14647 ReactCurrentActQueue$1 = ReactSharedInternals.ReactCurrentActQueue;
14648var NoContext =
14649/* */
146500;
14651var BatchedContext =
14652/* */
146531;
14654var RenderContext =
14655/* */
146562;
14657var CommitContext =
14658/* */
146594;
14660var RootInProgress = 0;
14661var RootFatalErrored = 1;
14662var RootErrored = 2;
14663var RootSuspended = 3;
14664var RootSuspendedWithDelay = 4;
14665var RootCompleted = 5;
14666var RootDidNotComplete = 6; // Describes where we are in the React execution stack
14667
14668var executionContext = NoContext; // The root we're working on
14669
14670var workInProgressRoot = null; // The fiber we're working on
14671
14672var workInProgress = null; // The lanes we're rendering
14673
14674var workInProgressRootRenderLanes = NoLanes; // Stack that allows components to change the render lanes for its subtree
14675// This is a superset of the lanes we started working on at the root. The only
14676// case where it's different from `workInProgressRootRenderLanes` is when we
14677// enter a subtree that is hidden and needs to be unhidden: Suspense and
14678// Offscreen component.
14679//
14680// Most things in the work loop should deal with workInProgressRootRenderLanes.
14681// Most things in begin/complete phases should deal with subtreeRenderLanes.
14682
14683var subtreeRenderLanes = NoLanes;
14684var subtreeRenderLanesCursor = createCursor(NoLanes); // Whether to root completed, errored, suspended, etc.
14685
14686var workInProgressRootExitStatus = RootInProgress; // A fatal error, if one is thrown
14687
14688var workInProgressRootFatalError = null; // "Included" lanes refer to lanes that were worked on during this render. It's
14689// slightly different than `renderLanes` because `renderLanes` can change as you
14690// enter and exit an Offscreen tree. This value is the combination of all render
14691// lanes for the entire render phase.
14692
14693var workInProgressRootIncludedLanes = NoLanes; // The work left over by components that were visited during this render. Only
14694// includes unprocessed updates, not work in bailed out children.
14695
14696var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an interleaved event) during this render.
14697
14698var workInProgressRootInterleavedUpdatedLanes = NoLanes; // Lanes that were updated during the render phase (*not* an interleaved event).
14699
14700var workInProgressRootPingedLanes = NoLanes; // Errors that are thrown during the render phase.
14701
14702var workInProgressRootConcurrentErrors = null; // These are errors that we recovered from without surfacing them to the UI.
14703// We will log them once the tree commits.
14704
14705var workInProgressRootRecoverableErrors = null; // The most recent time we committed a fallback. This lets us ensure a train
14706// model where we don't commit new loading states in too quick succession.
14707
14708var globalMostRecentFallbackTime = 0;
14709var FALLBACK_THROTTLE_MS = 500; // The absolute time for when we should start giving up on rendering
14710// more and prefer CPU suspense heuristics instead.
14711
14712var workInProgressRootRenderTargetTime = Infinity; // How long a render is supposed to take before we start following CPU
14713// suspense heuristics and opt out of rendering more content.
14714
14715var RENDER_TIMEOUT_MS = 500;
14716var workInProgressTransitions = null;
14717
14718function resetRenderTimer() {
14719 workInProgressRootRenderTargetTime = now() + RENDER_TIMEOUT_MS;
14720}
14721
14722function getRenderTargetTime() {
14723 return workInProgressRootRenderTargetTime;
14724}
14725var hasUncaughtError = false;
14726var firstUncaughtError = null;
14727var legacyErrorBoundariesThatAlreadyFailed = null; // Only used when enableProfilerNestedUpdateScheduledHook is true;
14728var rootDoesHavePassiveEffects = false;
14729var rootWithPendingPassiveEffects = null;
14730var pendingPassiveEffectsLanes = NoLanes;
14731var pendingPassiveProfilerEffects = [];
14732var pendingPassiveTransitions = null; // Use these to prevent an infinite loop of nested updates
14733
14734var NESTED_UPDATE_LIMIT = 50;
14735var nestedUpdateCount = 0;
14736var rootWithNestedUpdates = null;
14737var isFlushingPassiveEffects = false;
14738var didScheduleUpdateDuringPassiveEffects = false;
14739var NESTED_PASSIVE_UPDATE_LIMIT = 50;
14740var nestedPassiveUpdateCount = 0;
14741var rootWithPassiveNestedUpdates = null; // If two updates are scheduled within the same event, we should treat their
14742// event times as simultaneous, even if the actual clock time has advanced
14743// between the first and second call.
14744
14745var currentEventTime = NoTimestamp;
14746var currentEventTransitionLane = NoLanes;
14747var isRunningInsertionEffect = false;
14748function getWorkInProgressRoot() {
14749 return workInProgressRoot;
14750}
14751function requestEventTime() {
14752 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
14753 // We're inside React, so it's fine to read the actual time.
14754 return now();
14755 } // We're not inside React, so we may be in the middle of a browser event.
14756
14757
14758 if (currentEventTime !== NoTimestamp) {
14759 // Use the same start time for all updates until we enter React again.
14760 return currentEventTime;
14761 } // This is the first update since React yielded. Compute a new start time.
14762
14763
14764 currentEventTime = now();
14765 return currentEventTime;
14766}
14767function requestUpdateLane(fiber) {
14768 // Special cases
14769 var mode = fiber.mode;
14770
14771 if ((mode & ConcurrentMode) === NoMode) {
14772 return SyncLane;
14773 } else if ( (executionContext & RenderContext) !== NoContext && workInProgressRootRenderLanes !== NoLanes) {
14774 // This is a render phase update. These are not officially supported. The
14775 // old behavior is to give this the same "thread" (lanes) as
14776 // whatever is currently rendering. So if you call `setState` on a component
14777 // that happens later in the same render, it will flush. Ideally, we want to
14778 // remove the special case and treat them as if they came from an
14779 // interleaved event. Regardless, this pattern is not officially supported.
14780 // This behavior is only a fallback. The flag only exists until we can roll
14781 // out the setState warning, since existing code might accidentally rely on
14782 // the current behavior.
14783 return pickArbitraryLane(workInProgressRootRenderLanes);
14784 }
14785
14786 var isTransition = requestCurrentTransition() !== NoTransition;
14787
14788 if (isTransition) {
14789 if ( ReactCurrentBatchConfig$2.transition !== null) {
14790 var transition = ReactCurrentBatchConfig$2.transition;
14791
14792 if (!transition._updatedFibers) {
14793 transition._updatedFibers = new Set();
14794 }
14795
14796 transition._updatedFibers.add(fiber);
14797 } // The algorithm for assigning an update to a lane should be stable for all
14798 // updates at the same priority within the same event. To do this, the
14799 // inputs to the algorithm must be the same.
14800 //
14801 // The trick we use is to cache the first of each of these inputs within an
14802 // event. Then reset the cached values once we can be sure the event is
14803 // over. Our heuristic for that is whenever we enter a concurrent work loop.
14804
14805
14806 if (currentEventTransitionLane === NoLane) {
14807 // All transitions within the same event are assigned the same lane.
14808 currentEventTransitionLane = claimNextTransitionLane();
14809 }
14810
14811 return currentEventTransitionLane;
14812 } // Updates originating inside certain React methods, like flushSync, have
14813 // their priority set by tracking it with a context variable.
14814 //
14815 // The opaque type returned by the host config is internally a lane, so we can
14816 // use that directly.
14817 // TODO: Move this type conversion to the event priority module.
14818
14819
14820 var updateLane = getCurrentUpdatePriority();
14821
14822 if (updateLane !== NoLane) {
14823 return updateLane;
14824 } // This update originated outside React. Ask the host environment for an
14825 // appropriate priority, based on the type of event.
14826 //
14827 // The opaque type returned by the host config is internally a lane, so we can
14828 // use that directly.
14829 // TODO: Move this type conversion to the event priority module.
14830
14831
14832 var eventLane = getCurrentEventPriority();
14833 return eventLane;
14834}
14835
14836function requestRetryLane(fiber) {
14837 // This is a fork of `requestUpdateLane` designed specifically for Suspense
14838 // "retries" — a special update that attempts to flip a Suspense boundary
14839 // from its placeholder state to its primary/resolved state.
14840 // Special cases
14841 var mode = fiber.mode;
14842
14843 if ((mode & ConcurrentMode) === NoMode) {
14844 return SyncLane;
14845 }
14846
14847 return claimNextRetryLane();
14848}
14849
14850function scheduleUpdateOnFiber(root, fiber, lane, eventTime) {
14851 checkForNestedUpdates();
14852
14853 {
14854 if (isRunningInsertionEffect) {
14855 error('useInsertionEffect must not schedule updates.');
14856 }
14857 }
14858
14859 {
14860 if (isFlushingPassiveEffects) {
14861 didScheduleUpdateDuringPassiveEffects = true;
14862 }
14863 } // Mark that the root has a pending update.
14864
14865
14866 markRootUpdated(root, lane, eventTime);
14867
14868 if ((executionContext & RenderContext) !== NoLanes && root === workInProgressRoot) {
14869 // This update was dispatched during the render phase. This is a mistake
14870 // if the update originates from user space (with the exception of local
14871 // hook updates, which are handled differently and don't reach this
14872 // function), but there are some internal React features that use this as
14873 // an implementation detail, like selective hydration.
14874 warnAboutRenderPhaseUpdatesInDEV(fiber); // Track lanes that were updated during the render phase
14875 } else {
14876
14877 warnIfUpdatesNotWrappedWithActDEV(fiber);
14878
14879 if (root === workInProgressRoot) {
14880 // Received an update to a tree that's in the middle of rendering. Mark
14881 // that there was an interleaved update work on this root. Unless the
14882 // `deferRenderPhaseUpdateToNextBatch` flag is off and this is a render
14883 // phase update. In that case, we don't treat render phase updates as if
14884 // they were interleaved, for backwards compat reasons.
14885 if ( (executionContext & RenderContext) === NoContext) {
14886 workInProgressRootInterleavedUpdatedLanes = mergeLanes(workInProgressRootInterleavedUpdatedLanes, lane);
14887 }
14888
14889 if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
14890 // The root already suspended with a delay, which means this render
14891 // definitely won't finish. Since we have a new update, let's mark it as
14892 // suspended now, right before marking the incoming update. This has the
14893 // effect of interrupting the current render and switching to the update.
14894 // TODO: Make sure this doesn't override pings that happen while we've
14895 // already started rendering.
14896 markRootSuspended$1(root, workInProgressRootRenderLanes);
14897 }
14898 }
14899
14900 ensureRootIsScheduled(root, eventTime);
14901
14902 if (lane === SyncLane && executionContext === NoContext && (fiber.mode & ConcurrentMode) === NoMode && // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode.
14903 !( ReactCurrentActQueue$1.isBatchingLegacy)) {
14904 // Flush the synchronous work now, unless we're already working or inside
14905 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
14906 // scheduleCallbackForFiber to preserve the ability to schedule a callback
14907 // without immediately flushing it. We only do this for user-initiated
14908 // updates, to preserve historical behavior of legacy mode.
14909 resetRenderTimer();
14910 flushSyncCallbacksOnlyInLegacyMode();
14911 }
14912 }
14913}
14914function isUnsafeClassRenderPhaseUpdate(fiber) {
14915 // Check if this is a render phase update. Only called by class components,
14916 // which special (deprecated) behavior for UNSAFE_componentWillReceive props.
14917 return (// TODO: Remove outdated deferRenderPhaseUpdateToNextBatch experiment. We
14918 // decided not to enable it.
14919 (executionContext & RenderContext) !== NoContext
14920 );
14921} // Use this function to schedule a task for a root. There's only one task per
14922// root; if a task was already scheduled, we'll check to make sure the priority
14923// of the existing task is the same as the priority of the next level that the
14924// root has work on. This function is called on every update, and right before
14925// exiting a task.
14926
14927function ensureRootIsScheduled(root, currentTime) {
14928 var existingCallbackNode = root.callbackNode; // Check if any lanes are being starved by other work. If so, mark them as
14929 // expired so we know to work on those next.
14930
14931 markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority.
14932
14933 var nextLanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
14934
14935 if (nextLanes === NoLanes) {
14936 // Special case: There's nothing to work on.
14937 if (existingCallbackNode !== null) {
14938 cancelCallback$1(existingCallbackNode);
14939 }
14940
14941 root.callbackNode = null;
14942 root.callbackPriority = NoLane;
14943 return;
14944 } // We use the highest priority lane to represent the priority of the callback.
14945
14946
14947 var newCallbackPriority = getHighestPriorityLane(nextLanes); // Check if there's an existing task. We may be able to reuse it.
14948
14949 var existingCallbackPriority = root.callbackPriority;
14950
14951 if (existingCallbackPriority === newCallbackPriority && // Special case related to `act`. If the currently scheduled task is a
14952 // Scheduler task, rather than an `act` task, cancel it and re-scheduled
14953 // on the `act` queue.
14954 !( ReactCurrentActQueue$1.current !== null && existingCallbackNode !== fakeActCallbackNode)) {
14955 {
14956 // If we're going to re-use an existing task, it needs to exist.
14957 // Assume that discrete update microtasks are non-cancellable and null.
14958 // TODO: Temporary until we confirm this warning is not fired.
14959 if (existingCallbackNode == null && existingCallbackPriority !== SyncLane) {
14960 error('Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue.');
14961 }
14962 } // The priority hasn't changed. We can reuse the existing task. Exit.
14963
14964
14965 return;
14966 }
14967
14968 if (existingCallbackNode != null) {
14969 // Cancel the existing callback. We'll schedule a new one below.
14970 cancelCallback$1(existingCallbackNode);
14971 } // Schedule a new callback.
14972
14973
14974 var newCallbackNode;
14975
14976 if (newCallbackPriority === SyncLane) {
14977 // Special case: Sync React callbacks are scheduled on a special
14978 // internal queue
14979 if (root.tag === LegacyRoot) {
14980 if ( ReactCurrentActQueue$1.isBatchingLegacy !== null) {
14981 ReactCurrentActQueue$1.didScheduleLegacyUpdate = true;
14982 }
14983
14984 scheduleLegacySyncCallback(performSyncWorkOnRoot.bind(null, root));
14985 } else {
14986 scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
14987 }
14988
14989 {
14990 // Flush the queue in an Immediate task.
14991 scheduleCallback$1(ImmediatePriority, flushSyncCallbacks);
14992 }
14993
14994 newCallbackNode = null;
14995 } else {
14996 var schedulerPriorityLevel;
14997
14998 switch (lanesToEventPriority(nextLanes)) {
14999 case DiscreteEventPriority:
15000 schedulerPriorityLevel = ImmediatePriority;
15001 break;
15002
15003 case ContinuousEventPriority:
15004 schedulerPriorityLevel = UserBlockingPriority;
15005 break;
15006
15007 case DefaultEventPriority:
15008 schedulerPriorityLevel = NormalPriority;
15009 break;
15010
15011 case IdleEventPriority:
15012 schedulerPriorityLevel = IdlePriority;
15013 break;
15014
15015 default:
15016 schedulerPriorityLevel = NormalPriority;
15017 break;
15018 }
15019
15020 newCallbackNode = scheduleCallback$1(schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root));
15021 }
15022
15023 root.callbackPriority = newCallbackPriority;
15024 root.callbackNode = newCallbackNode;
15025} // This is the entry point for every concurrent task, i.e. anything that
15026// goes through Scheduler.
15027
15028
15029function performConcurrentWorkOnRoot(root, didTimeout) {
15030 {
15031 resetNestedUpdateFlag();
15032 } // Since we know we're in a React event, we can clear the current
15033 // event time. The next update will compute a new event time.
15034
15035
15036 currentEventTime = NoTimestamp;
15037 currentEventTransitionLane = NoLanes;
15038
15039 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
15040 throw new Error('Should not already be working.');
15041 } // Flush any pending passive effects before deciding which lanes to work on,
15042 // in case they schedule additional work.
15043
15044
15045 var originalCallbackNode = root.callbackNode;
15046 var didFlushPassiveEffects = flushPassiveEffects();
15047
15048 if (didFlushPassiveEffects) {
15049 // Something in the passive effect phase may have canceled the current task.
15050 // Check if the task node for this root was changed.
15051 if (root.callbackNode !== originalCallbackNode) {
15052 // The current task was canceled. Exit. We don't need to call
15053 // `ensureRootIsScheduled` because the check above implies either that
15054 // there's a new task, or that there's no remaining work on this root.
15055 return null;
15056 }
15057 } // Determine the next lanes to work on, using the fields stored
15058 // on the root.
15059
15060
15061 var lanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
15062
15063 if (lanes === NoLanes) {
15064 // Defensive coding. This is never expected to happen.
15065 return null;
15066 } // We disable time-slicing in some cases: if the work has been CPU-bound
15067 // for too long ("expired" work, to prevent starvation), or we're in
15068 // sync-updates-by-default mode.
15069 // TODO: We only check `didTimeout` defensively, to account for a Scheduler
15070 // bug we're still investigating. Once the bug in Scheduler is fixed,
15071 // we can remove this, since we track expiration ourselves.
15072
15073
15074 var shouldTimeSlice = !includesBlockingLane(root, lanes) && !includesExpiredLane(root, lanes) && ( !didTimeout);
15075 var exitStatus = shouldTimeSlice ? renderRootConcurrent(root, lanes) : renderRootSync(root, lanes);
15076
15077 if (exitStatus !== RootInProgress) {
15078 if (exitStatus === RootErrored) {
15079 // If something threw an error, try rendering one more time. We'll
15080 // render synchronously to block concurrent data mutations, and we'll
15081 // includes all pending updates are included. If it still fails after
15082 // the second attempt, we'll give up and commit the resulting tree.
15083 var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
15084
15085 if (errorRetryLanes !== NoLanes) {
15086 lanes = errorRetryLanes;
15087 exitStatus = recoverFromConcurrentError(root, errorRetryLanes);
15088 }
15089 }
15090
15091 if (exitStatus === RootFatalErrored) {
15092 var fatalError = workInProgressRootFatalError;
15093 prepareFreshStack(root, NoLanes);
15094 markRootSuspended$1(root, lanes);
15095 ensureRootIsScheduled(root, now());
15096 throw fatalError;
15097 }
15098
15099 if (exitStatus === RootDidNotComplete) {
15100 // The render unwound without completing the tree. This happens in special
15101 // cases where need to exit the current render without producing a
15102 // consistent tree or committing.
15103 //
15104 // This should only happen during a concurrent render, not a discrete or
15105 // synchronous update. We should have already checked for this when we
15106 // unwound the stack.
15107 markRootSuspended$1(root, lanes);
15108 } else {
15109 // The render completed.
15110 // Check if this render may have yielded to a concurrent event, and if so,
15111 // confirm that any newly rendered stores are consistent.
15112 // TODO: It's possible that even a concurrent render may never have yielded
15113 // to the main thread, if it was fast enough, or if it expired. We could
15114 // skip the consistency check in that case, too.
15115 var renderWasConcurrent = !includesBlockingLane(root, lanes);
15116 var finishedWork = root.current.alternate;
15117
15118 if (renderWasConcurrent && !isRenderConsistentWithExternalStores(finishedWork)) {
15119 // A store was mutated in an interleaved event. Render again,
15120 // synchronously, to block further mutations.
15121 exitStatus = renderRootSync(root, lanes); // We need to check again if something threw
15122
15123 if (exitStatus === RootErrored) {
15124 var _errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
15125
15126 if (_errorRetryLanes !== NoLanes) {
15127 lanes = _errorRetryLanes;
15128 exitStatus = recoverFromConcurrentError(root, _errorRetryLanes); // We assume the tree is now consistent because we didn't yield to any
15129 // concurrent events.
15130 }
15131 }
15132
15133 if (exitStatus === RootFatalErrored) {
15134 var _fatalError = workInProgressRootFatalError;
15135 prepareFreshStack(root, NoLanes);
15136 markRootSuspended$1(root, lanes);
15137 ensureRootIsScheduled(root, now());
15138 throw _fatalError;
15139 }
15140 } // We now have a consistent tree. The next step is either to commit it,
15141 // or, if something suspended, wait to commit it after a timeout.
15142
15143
15144 root.finishedWork = finishedWork;
15145 root.finishedLanes = lanes;
15146 finishConcurrentRender(root, exitStatus, lanes);
15147 }
15148 }
15149
15150 ensureRootIsScheduled(root, now());
15151
15152 if (root.callbackNode === originalCallbackNode) {
15153 // The task node scheduled for this root is the same one that's
15154 // currently executed. Need to return a continuation.
15155 return performConcurrentWorkOnRoot.bind(null, root);
15156 }
15157
15158 return null;
15159}
15160
15161function recoverFromConcurrentError(root, errorRetryLanes) {
15162 // If an error occurred during hydration, discard server response and fall
15163 // back to client side render.
15164 // Before rendering again, save the errors from the previous attempt.
15165 var errorsFromFirstAttempt = workInProgressRootConcurrentErrors;
15166
15167 if (isRootDehydrated(root)) {
15168 // The shell failed to hydrate. Set a flag to force a client rendering
15169 // during the next attempt. To do this, we call prepareFreshStack now
15170 // to create the root work-in-progress fiber. This is a bit weird in terms
15171 // of factoring, because it relies on renderRootSync not calling
15172 // prepareFreshStack again in the call below, which happens because the
15173 // root and lanes haven't changed.
15174 //
15175 // TODO: I think what we should do is set ForceClientRender inside
15176 // throwException, like we do for nested Suspense boundaries. The reason
15177 // it's here instead is so we can switch to the synchronous work loop, too.
15178 // Something to consider for a future refactor.
15179 var rootWorkInProgress = prepareFreshStack(root, errorRetryLanes);
15180 rootWorkInProgress.flags |= ForceClientRender;
15181
15182 {
15183 errorHydratingContainer(root.containerInfo);
15184 }
15185 }
15186
15187 var exitStatus = renderRootSync(root, errorRetryLanes);
15188
15189 if (exitStatus !== RootErrored) {
15190 // Successfully finished rendering on retry
15191 // The errors from the failed first attempt have been recovered. Add
15192 // them to the collection of recoverable errors. We'll log them in the
15193 // commit phase.
15194 var errorsFromSecondAttempt = workInProgressRootRecoverableErrors;
15195 workInProgressRootRecoverableErrors = errorsFromFirstAttempt; // The errors from the second attempt should be queued after the errors
15196 // from the first attempt, to preserve the causal sequence.
15197
15198 if (errorsFromSecondAttempt !== null) {
15199 queueRecoverableErrors(errorsFromSecondAttempt);
15200 }
15201 }
15202
15203 return exitStatus;
15204}
15205
15206function queueRecoverableErrors(errors) {
15207 if (workInProgressRootRecoverableErrors === null) {
15208 workInProgressRootRecoverableErrors = errors;
15209 } else {
15210 workInProgressRootRecoverableErrors.push.apply(workInProgressRootRecoverableErrors, errors);
15211 }
15212}
15213
15214function finishConcurrentRender(root, exitStatus, lanes) {
15215 switch (exitStatus) {
15216 case RootInProgress:
15217 case RootFatalErrored:
15218 {
15219 throw new Error('Root did not complete. This is a bug in React.');
15220 }
15221 // Flow knows about invariant, so it complains if I add a break
15222 // statement, but eslint doesn't know about invariant, so it complains
15223 // if I do. eslint-disable-next-line no-fallthrough
15224
15225 case RootErrored:
15226 {
15227 // We should have already attempted to retry this tree. If we reached
15228 // this point, it errored again. Commit it.
15229 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions);
15230 break;
15231 }
15232
15233 case RootSuspended:
15234 {
15235 markRootSuspended$1(root, lanes); // We have an acceptable loading state. We need to figure out if we
15236 // should immediately commit it or wait a bit.
15237
15238 if (includesOnlyRetries(lanes) && // do not delay if we're inside an act() scope
15239 !shouldForceFlushFallbacksInDEV()) {
15240 // This render only included retries, no updates. Throttle committing
15241 // retries so that we don't show too many loading states too quickly.
15242 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.
15243
15244 if (msUntilTimeout > 10) {
15245 var nextLanes = getNextLanes(root, NoLanes);
15246
15247 if (nextLanes !== NoLanes) {
15248 // There's additional work on this root.
15249 break;
15250 }
15251
15252 var suspendedLanes = root.suspendedLanes;
15253
15254 if (!isSubsetOfLanes(suspendedLanes, lanes)) {
15255 // We should prefer to render the fallback of at the last
15256 // suspended level. Ping the last suspended level to try
15257 // rendering it again.
15258 // FIXME: What if the suspended lanes are Idle? Should not restart.
15259 var eventTime = requestEventTime();
15260 markRootPinged(root, suspendedLanes);
15261 break;
15262 } // The render is suspended, it hasn't timed out, and there's no
15263 // lower priority work to do. Instead of committing the fallback
15264 // immediately, wait for more data to arrive.
15265
15266
15267 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root, workInProgressRootRecoverableErrors, workInProgressTransitions), msUntilTimeout);
15268 break;
15269 }
15270 } // The work expired. Commit immediately.
15271
15272
15273 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions);
15274 break;
15275 }
15276
15277 case RootSuspendedWithDelay:
15278 {
15279 markRootSuspended$1(root, lanes);
15280
15281 if (includesOnlyTransitions(lanes)) {
15282 // This is a transition, so we should exit without committing a
15283 // placeholder and without scheduling a timeout. Delay indefinitely
15284 // until we receive more data.
15285 break;
15286 }
15287
15288 if (!shouldForceFlushFallbacksInDEV()) {
15289 // This is not a transition, but we did trigger an avoided state.
15290 // Schedule a placeholder to display after a short delay, using the Just
15291 // Noticeable Difference.
15292 // TODO: Is the JND optimization worth the added complexity? If this is
15293 // the only reason we track the event time, then probably not.
15294 // Consider removing.
15295 var mostRecentEventTime = getMostRecentEventTime(root, lanes);
15296 var eventTimeMs = mostRecentEventTime;
15297 var timeElapsedMs = now() - eventTimeMs;
15298
15299 var _msUntilTimeout = jnd(timeElapsedMs) - timeElapsedMs; // Don't bother with a very short suspense time.
15300
15301
15302 if (_msUntilTimeout > 10) {
15303 // Instead of committing the fallback immediately, wait for more data
15304 // to arrive.
15305 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root, workInProgressRootRecoverableErrors, workInProgressTransitions), _msUntilTimeout);
15306 break;
15307 }
15308 } // Commit the placeholder.
15309
15310
15311 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions);
15312 break;
15313 }
15314
15315 case RootCompleted:
15316 {
15317 // The work completed. Ready to commit.
15318 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions);
15319 break;
15320 }
15321
15322 default:
15323 {
15324 throw new Error('Unknown root exit status.');
15325 }
15326 }
15327}
15328
15329function isRenderConsistentWithExternalStores(finishedWork) {
15330 // Search the rendered tree for external store reads, and check whether the
15331 // stores were mutated in a concurrent event. Intentionally using an iterative
15332 // loop instead of recursion so we can exit early.
15333 var node = finishedWork;
15334
15335 while (true) {
15336 if (node.flags & StoreConsistency) {
15337 var updateQueue = node.updateQueue;
15338
15339 if (updateQueue !== null) {
15340 var checks = updateQueue.stores;
15341
15342 if (checks !== null) {
15343 for (var i = 0; i < checks.length; i++) {
15344 var check = checks[i];
15345 var getSnapshot = check.getSnapshot;
15346 var renderedValue = check.value;
15347
15348 try {
15349 if (!objectIs(getSnapshot(), renderedValue)) {
15350 // Found an inconsistent store.
15351 return false;
15352 }
15353 } catch (error) {
15354 // If `getSnapshot` throws, return `false`. This will schedule
15355 // a re-render, and the error will be rethrown during render.
15356 return false;
15357 }
15358 }
15359 }
15360 }
15361 }
15362
15363 var child = node.child;
15364
15365 if (node.subtreeFlags & StoreConsistency && child !== null) {
15366 child.return = node;
15367 node = child;
15368 continue;
15369 }
15370
15371 if (node === finishedWork) {
15372 return true;
15373 }
15374
15375 while (node.sibling === null) {
15376 if (node.return === null || node.return === finishedWork) {
15377 return true;
15378 }
15379
15380 node = node.return;
15381 }
15382
15383 node.sibling.return = node.return;
15384 node = node.sibling;
15385 } // Flow doesn't know this is unreachable, but eslint does
15386 // eslint-disable-next-line no-unreachable
15387
15388
15389 return true;
15390}
15391
15392function markRootSuspended$1(root, suspendedLanes) {
15393 // When suspending, we should always exclude lanes that were pinged or (more
15394 // rarely, since we try to avoid it) updated during the render phase.
15395 // TODO: Lol maybe there's a better way to factor this besides this
15396 // obnoxiously named function :)
15397 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootPingedLanes);
15398 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootInterleavedUpdatedLanes);
15399 markRootSuspended(root, suspendedLanes);
15400} // This is the entry point for synchronous tasks that don't go
15401// through Scheduler
15402
15403
15404function performSyncWorkOnRoot(root) {
15405 {
15406 syncNestedUpdateFlag();
15407 }
15408
15409 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
15410 throw new Error('Should not already be working.');
15411 }
15412
15413 flushPassiveEffects();
15414 var lanes = getNextLanes(root, NoLanes);
15415
15416 if (!includesSomeLane(lanes, SyncLane)) {
15417 // There's no remaining sync work left.
15418 ensureRootIsScheduled(root, now());
15419 return null;
15420 }
15421
15422 var exitStatus = renderRootSync(root, lanes);
15423
15424 if (root.tag !== LegacyRoot && exitStatus === RootErrored) {
15425 // If something threw an error, try rendering one more time. We'll render
15426 // synchronously to block concurrent data mutations, and we'll includes
15427 // all pending updates are included. If it still fails after the second
15428 // attempt, we'll give up and commit the resulting tree.
15429 var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
15430
15431 if (errorRetryLanes !== NoLanes) {
15432 lanes = errorRetryLanes;
15433 exitStatus = recoverFromConcurrentError(root, errorRetryLanes);
15434 }
15435 }
15436
15437 if (exitStatus === RootFatalErrored) {
15438 var fatalError = workInProgressRootFatalError;
15439 prepareFreshStack(root, NoLanes);
15440 markRootSuspended$1(root, lanes);
15441 ensureRootIsScheduled(root, now());
15442 throw fatalError;
15443 }
15444
15445 if (exitStatus === RootDidNotComplete) {
15446 throw new Error('Root did not complete. This is a bug in React.');
15447 } // We now have a consistent tree. Because this is a sync render, we
15448 // will commit it even if something suspended.
15449
15450
15451 var finishedWork = root.current.alternate;
15452 root.finishedWork = finishedWork;
15453 root.finishedLanes = lanes;
15454 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions); // Before exiting, make sure there's a callback scheduled for the next
15455 // pending level.
15456
15457 ensureRootIsScheduled(root, now());
15458 return null;
15459}
15460function batchedUpdates(fn, a) {
15461 var prevExecutionContext = executionContext;
15462 executionContext |= BatchedContext;
15463
15464 try {
15465 return fn(a);
15466 } finally {
15467 executionContext = prevExecutionContext; // If there were legacy sync updates, flush them at the end of the outer
15468 // most batchedUpdates-like method.
15469
15470 if (executionContext === NoContext && // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode.
15471 !( ReactCurrentActQueue$1.isBatchingLegacy)) {
15472 resetRenderTimer();
15473 flushSyncCallbacksOnlyInLegacyMode();
15474 }
15475 }
15476}
15477// Warning, this opts-out of checking the function body.
15478
15479// eslint-disable-next-line no-redeclare
15480function flushSync(fn) {
15481 // In legacy mode, we flush pending passive effects at the beginning of the
15482 // next event, not at the end of the previous one.
15483 if (rootWithPendingPassiveEffects !== null && rootWithPendingPassiveEffects.tag === LegacyRoot && (executionContext & (RenderContext | CommitContext)) === NoContext) {
15484 flushPassiveEffects();
15485 }
15486
15487 var prevExecutionContext = executionContext;
15488 executionContext |= BatchedContext;
15489 var prevTransition = ReactCurrentBatchConfig$2.transition;
15490 var previousPriority = getCurrentUpdatePriority();
15491
15492 try {
15493 ReactCurrentBatchConfig$2.transition = null;
15494 setCurrentUpdatePriority(DiscreteEventPriority);
15495
15496 if (fn) {
15497 return fn();
15498 } else {
15499 return undefined;
15500 }
15501 } finally {
15502 setCurrentUpdatePriority(previousPriority);
15503 ReactCurrentBatchConfig$2.transition = prevTransition;
15504 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
15505 // Note that this will happen even if batchedUpdates is higher up
15506 // the stack.
15507
15508 if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
15509 flushSyncCallbacks();
15510 }
15511 }
15512}
15513function pushRenderLanes(fiber, lanes) {
15514 push(subtreeRenderLanesCursor, subtreeRenderLanes, fiber);
15515 subtreeRenderLanes = mergeLanes(subtreeRenderLanes, lanes);
15516 workInProgressRootIncludedLanes = mergeLanes(workInProgressRootIncludedLanes, lanes);
15517}
15518function popRenderLanes(fiber) {
15519 subtreeRenderLanes = subtreeRenderLanesCursor.current;
15520 pop(subtreeRenderLanesCursor, fiber);
15521}
15522
15523function prepareFreshStack(root, lanes) {
15524 root.finishedWork = null;
15525 root.finishedLanes = NoLanes;
15526 var timeoutHandle = root.timeoutHandle;
15527
15528 if (timeoutHandle !== noTimeout) {
15529 // The root previous suspended and scheduled a timeout to commit a fallback
15530 // state. Now that we have additional work, cancel the timeout.
15531 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
15532
15533 cancelTimeout(timeoutHandle);
15534 }
15535
15536 if (workInProgress !== null) {
15537 var interruptedWork = workInProgress.return;
15538
15539 while (interruptedWork !== null) {
15540 var current = interruptedWork.alternate;
15541 unwindInterruptedWork(current, interruptedWork);
15542 interruptedWork = interruptedWork.return;
15543 }
15544 }
15545
15546 workInProgressRoot = root;
15547 var rootWorkInProgress = createWorkInProgress(root.current, null);
15548 workInProgress = rootWorkInProgress;
15549 workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes;
15550 workInProgressRootExitStatus = RootInProgress;
15551 workInProgressRootFatalError = null;
15552 workInProgressRootSkippedLanes = NoLanes;
15553 workInProgressRootInterleavedUpdatedLanes = NoLanes;
15554 workInProgressRootPingedLanes = NoLanes;
15555 workInProgressRootConcurrentErrors = null;
15556 workInProgressRootRecoverableErrors = null;
15557 finishQueueingConcurrentUpdates();
15558
15559 {
15560 ReactStrictModeWarnings.discardPendingWarnings();
15561 }
15562
15563 return rootWorkInProgress;
15564}
15565
15566function handleError(root, thrownValue) {
15567 do {
15568 var erroredWork = workInProgress;
15569
15570 try {
15571 // Reset module-level state that was set during the render phase.
15572 resetContextDependencies();
15573 resetHooksAfterThrow();
15574 resetCurrentFiber(); // TODO: I found and added this missing line while investigating a
15575 // separate issue. Write a regression test using string refs.
15576
15577 ReactCurrentOwner$2.current = null;
15578
15579 if (erroredWork === null || erroredWork.return === null) {
15580 // Expected to be working on a non-root fiber. This is a fatal error
15581 // because there's no ancestor that can handle it; the root is
15582 // supposed to capture all errors that weren't caught by an error
15583 // boundary.
15584 workInProgressRootExitStatus = RootFatalErrored;
15585 workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next
15586 // sibling, or the parent if there are no siblings. But since the root
15587 // has no siblings nor a parent, we set it to null. Usually this is
15588 // handled by `completeUnitOfWork` or `unwindWork`, but since we're
15589 // intentionally not calling those, we need set it here.
15590 // TODO: Consider calling `unwindWork` to pop the contexts.
15591
15592 workInProgress = null;
15593 return;
15594 }
15595
15596 if (enableProfilerTimer && erroredWork.mode & ProfileMode) {
15597 // Record the time spent rendering before an error was thrown. This
15598 // avoids inaccurate Profiler durations in the case of a
15599 // suspended render.
15600 stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true);
15601 }
15602
15603 if (enableSchedulingProfiler) {
15604 markComponentRenderStopped();
15605
15606 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') {
15607 var wakeable = thrownValue;
15608 markComponentSuspended(erroredWork, wakeable, workInProgressRootRenderLanes);
15609 } else {
15610 markComponentErrored(erroredWork, thrownValue, workInProgressRootRenderLanes);
15611 }
15612 }
15613
15614 throwException(root, erroredWork.return, erroredWork, thrownValue, workInProgressRootRenderLanes);
15615 completeUnitOfWork(erroredWork);
15616 } catch (yetAnotherThrownValue) {
15617 // Something in the return path also threw.
15618 thrownValue = yetAnotherThrownValue;
15619
15620 if (workInProgress === erroredWork && erroredWork !== null) {
15621 // If this boundary has already errored, then we had trouble processing
15622 // the error. Bubble it to the next boundary.
15623 erroredWork = erroredWork.return;
15624 workInProgress = erroredWork;
15625 } else {
15626 erroredWork = workInProgress;
15627 }
15628
15629 continue;
15630 } // Return to the normal work loop.
15631
15632
15633 return;
15634 } while (true);
15635}
15636
15637function pushDispatcher() {
15638 var prevDispatcher = ReactCurrentDispatcher$2.current;
15639 ReactCurrentDispatcher$2.current = ContextOnlyDispatcher;
15640
15641 if (prevDispatcher === null) {
15642 // The React isomorphic package does not include a default dispatcher.
15643 // Instead the first renderer will lazily attach one, in order to give
15644 // nicer error messages.
15645 return ContextOnlyDispatcher;
15646 } else {
15647 return prevDispatcher;
15648 }
15649}
15650
15651function popDispatcher(prevDispatcher) {
15652 ReactCurrentDispatcher$2.current = prevDispatcher;
15653}
15654
15655function markCommitTimeOfFallback() {
15656 globalMostRecentFallbackTime = now();
15657}
15658function markSkippedUpdateLanes(lane) {
15659 workInProgressRootSkippedLanes = mergeLanes(lane, workInProgressRootSkippedLanes);
15660}
15661function renderDidSuspend() {
15662 if (workInProgressRootExitStatus === RootInProgress) {
15663 workInProgressRootExitStatus = RootSuspended;
15664 }
15665}
15666function renderDidSuspendDelayIfPossible() {
15667 if (workInProgressRootExitStatus === RootInProgress || workInProgressRootExitStatus === RootSuspended || workInProgressRootExitStatus === RootErrored) {
15668 workInProgressRootExitStatus = RootSuspendedWithDelay;
15669 } // Check if there are updates that we skipped tree that might have unblocked
15670 // this render.
15671
15672
15673 if (workInProgressRoot !== null && (includesNonIdleWork(workInProgressRootSkippedLanes) || includesNonIdleWork(workInProgressRootInterleavedUpdatedLanes))) {
15674 // Mark the current render as suspended so that we switch to working on
15675 // the updates that were skipped. Usually we only suspend at the end of
15676 // the render phase.
15677 // TODO: We should probably always mark the root as suspended immediately
15678 // (inside this function), since by suspending at the end of the render
15679 // phase introduces a potential mistake where we suspend lanes that were
15680 // pinged or updated while we were rendering.
15681 markRootSuspended$1(workInProgressRoot, workInProgressRootRenderLanes);
15682 }
15683}
15684function renderDidError(error) {
15685 if (workInProgressRootExitStatus !== RootSuspendedWithDelay) {
15686 workInProgressRootExitStatus = RootErrored;
15687 }
15688
15689 if (workInProgressRootConcurrentErrors === null) {
15690 workInProgressRootConcurrentErrors = [error];
15691 } else {
15692 workInProgressRootConcurrentErrors.push(error);
15693 }
15694} // Called during render to determine if anything has suspended.
15695// Returns false if we're not sure.
15696
15697function renderHasNotSuspendedYet() {
15698 // If something errored or completed, we can't really be sure,
15699 // so those are false.
15700 return workInProgressRootExitStatus === RootInProgress;
15701}
15702
15703function renderRootSync(root, lanes) {
15704 var prevExecutionContext = executionContext;
15705 executionContext |= RenderContext;
15706 var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack
15707 // and prepare a fresh one. Otherwise we'll continue where we left off.
15708
15709 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {
15710
15711 workInProgressTransitions = getTransitionsForLanes();
15712 prepareFreshStack(root, lanes);
15713 }
15714
15715 do {
15716 try {
15717 workLoopSync();
15718 break;
15719 } catch (thrownValue) {
15720 handleError(root, thrownValue);
15721 }
15722 } while (true);
15723
15724 resetContextDependencies();
15725 executionContext = prevExecutionContext;
15726 popDispatcher(prevDispatcher);
15727
15728 if (workInProgress !== null) {
15729 // This is a sync render, so we should have finished the whole tree.
15730 throw new Error('Cannot commit an incomplete root. This error is likely caused by a ' + 'bug in React. Please file an issue.');
15731 }
15732
15733
15734 workInProgressRoot = null;
15735 workInProgressRootRenderLanes = NoLanes;
15736 return workInProgressRootExitStatus;
15737} // The work loop is an extremely hot path. Tell Closure not to inline it.
15738
15739/** @noinline */
15740
15741
15742function workLoopSync() {
15743 // Already timed out, so perform work without checking if we need to yield.
15744 while (workInProgress !== null) {
15745 performUnitOfWork(workInProgress);
15746 }
15747}
15748
15749function renderRootConcurrent(root, lanes) {
15750 var prevExecutionContext = executionContext;
15751 executionContext |= RenderContext;
15752 var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack
15753 // and prepare a fresh one. Otherwise we'll continue where we left off.
15754
15755 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {
15756
15757 workInProgressTransitions = getTransitionsForLanes();
15758 resetRenderTimer();
15759 prepareFreshStack(root, lanes);
15760 }
15761
15762 do {
15763 try {
15764 workLoopConcurrent();
15765 break;
15766 } catch (thrownValue) {
15767 handleError(root, thrownValue);
15768 }
15769 } while (true);
15770
15771 resetContextDependencies();
15772 popDispatcher(prevDispatcher);
15773 executionContext = prevExecutionContext;
15774
15775
15776 if (workInProgress !== null) {
15777
15778 return RootInProgress;
15779 } else {
15780
15781
15782 workInProgressRoot = null;
15783 workInProgressRootRenderLanes = NoLanes; // Return the final exit status.
15784
15785 return workInProgressRootExitStatus;
15786 }
15787}
15788/** @noinline */
15789
15790
15791function workLoopConcurrent() {
15792 // Perform work until Scheduler asks us to yield
15793 while (workInProgress !== null && !shouldYield()) {
15794 performUnitOfWork(workInProgress);
15795 }
15796}
15797
15798function performUnitOfWork(unitOfWork) {
15799 // The current, flushed, state of this fiber is the alternate. Ideally
15800 // nothing should rely on this, but relying on it here means that we don't
15801 // need an additional field on the work in progress.
15802 var current = unitOfWork.alternate;
15803 setCurrentFiber(unitOfWork);
15804 var next;
15805
15806 if ( (unitOfWork.mode & ProfileMode) !== NoMode) {
15807 startProfilerTimer(unitOfWork);
15808 next = beginWork$1(current, unitOfWork, subtreeRenderLanes);
15809 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
15810 } else {
15811 next = beginWork$1(current, unitOfWork, subtreeRenderLanes);
15812 }
15813
15814 resetCurrentFiber();
15815 unitOfWork.memoizedProps = unitOfWork.pendingProps;
15816
15817 if (next === null) {
15818 // If this doesn't spawn new work, complete the current work.
15819 completeUnitOfWork(unitOfWork);
15820 } else {
15821 workInProgress = next;
15822 }
15823
15824 ReactCurrentOwner$2.current = null;
15825}
15826
15827function completeUnitOfWork(unitOfWork) {
15828 // Attempt to complete the current unit of work, then move to the next
15829 // sibling. If there are no more siblings, return to the parent fiber.
15830 var completedWork = unitOfWork;
15831
15832 do {
15833 // The current, flushed, state of this fiber is the alternate. Ideally
15834 // nothing should rely on this, but relying on it here means that we don't
15835 // need an additional field on the work in progress.
15836 var current = completedWork.alternate;
15837 var returnFiber = completedWork.return; // Check if the work completed or if something threw.
15838
15839 if ((completedWork.flags & Incomplete) === NoFlags) {
15840 setCurrentFiber(completedWork);
15841 var next = void 0;
15842
15843 if ( (completedWork.mode & ProfileMode) === NoMode) {
15844 next = completeWork(current, completedWork, subtreeRenderLanes);
15845 } else {
15846 startProfilerTimer(completedWork);
15847 next = completeWork(current, completedWork, subtreeRenderLanes); // Update render duration assuming we didn't error.
15848
15849 stopProfilerTimerIfRunningAndRecordDelta(completedWork, false);
15850 }
15851
15852 resetCurrentFiber();
15853
15854 if (next !== null) {
15855 // Completing this fiber spawned new work. Work on that next.
15856 workInProgress = next;
15857 return;
15858 }
15859 } else {
15860 // This fiber did not complete because something threw. Pop values off
15861 // the stack without entering the complete phase. If this is a boundary,
15862 // capture values if possible.
15863 var _next = unwindWork(current, completedWork); // Because this fiber did not complete, don't reset its lanes.
15864
15865
15866 if (_next !== null) {
15867 // If completing this work spawned new work, do that next. We'll come
15868 // back here again.
15869 // Since we're restarting, remove anything that is not a host effect
15870 // from the effect tag.
15871 _next.flags &= HostEffectMask;
15872 workInProgress = _next;
15873 return;
15874 }
15875
15876 if ( (completedWork.mode & ProfileMode) !== NoMode) {
15877 // Record the render duration for the fiber that errored.
15878 stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); // Include the time spent working on failed children before continuing.
15879
15880 var actualDuration = completedWork.actualDuration;
15881 var child = completedWork.child;
15882
15883 while (child !== null) {
15884 actualDuration += child.actualDuration;
15885 child = child.sibling;
15886 }
15887
15888 completedWork.actualDuration = actualDuration;
15889 }
15890
15891 if (returnFiber !== null) {
15892 // Mark the parent fiber as incomplete and clear its subtree flags.
15893 returnFiber.flags |= Incomplete;
15894 returnFiber.subtreeFlags = NoFlags;
15895 returnFiber.deletions = null;
15896 } else {
15897 // We've unwound all the way to the root.
15898 workInProgressRootExitStatus = RootDidNotComplete;
15899 workInProgress = null;
15900 return;
15901 }
15902 }
15903
15904 var siblingFiber = completedWork.sibling;
15905
15906 if (siblingFiber !== null) {
15907 // If there is more work to do in this returnFiber, do that next.
15908 workInProgress = siblingFiber;
15909 return;
15910 } // Otherwise, return to the parent
15911
15912
15913 completedWork = returnFiber; // Update the next thing we're working on in case something throws.
15914
15915 workInProgress = completedWork;
15916 } while (completedWork !== null); // We've reached the root.
15917
15918
15919 if (workInProgressRootExitStatus === RootInProgress) {
15920 workInProgressRootExitStatus = RootCompleted;
15921 }
15922}
15923
15924function commitRoot(root, recoverableErrors, transitions) {
15925 // TODO: This no longer makes any sense. We already wrap the mutation and
15926 // layout phases. Should be able to remove.
15927 var previousUpdateLanePriority = getCurrentUpdatePriority();
15928 var prevTransition = ReactCurrentBatchConfig$2.transition;
15929
15930 try {
15931 ReactCurrentBatchConfig$2.transition = null;
15932 setCurrentUpdatePriority(DiscreteEventPriority);
15933 commitRootImpl(root, recoverableErrors, transitions, previousUpdateLanePriority);
15934 } finally {
15935 ReactCurrentBatchConfig$2.transition = prevTransition;
15936 setCurrentUpdatePriority(previousUpdateLanePriority);
15937 }
15938
15939 return null;
15940}
15941
15942function commitRootImpl(root, recoverableErrors, transitions, renderPriorityLevel) {
15943 do {
15944 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which
15945 // means `flushPassiveEffects` will sometimes result in additional
15946 // passive effects. So we need to keep flushing in a loop until there are
15947 // no more pending effects.
15948 // TODO: Might be better if `flushPassiveEffects` did not automatically
15949 // flush synchronous work at the end, to avoid factoring hazards like this.
15950 flushPassiveEffects();
15951 } while (rootWithPendingPassiveEffects !== null);
15952
15953 flushRenderPhaseStrictModeWarningsInDEV();
15954
15955 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
15956 throw new Error('Should not already be working.');
15957 }
15958
15959 var finishedWork = root.finishedWork;
15960 var lanes = root.finishedLanes;
15961
15962 if (finishedWork === null) {
15963
15964 return null;
15965 } else {
15966 {
15967 if (lanes === NoLanes) {
15968 error('root.finishedLanes should not be empty during a commit. This is a ' + 'bug in React.');
15969 }
15970 }
15971 }
15972
15973 root.finishedWork = null;
15974 root.finishedLanes = NoLanes;
15975
15976 if (finishedWork === root.current) {
15977 throw new Error('Cannot commit the same tree as before. This error is likely caused by ' + 'a bug in React. Please file an issue.');
15978 } // commitRoot never returns a continuation; it always finishes synchronously.
15979 // So we can clear these now to allow a new callback to be scheduled.
15980
15981
15982 root.callbackNode = null;
15983 root.callbackPriority = NoLane; // Update the first and last pending times on this root. The new first
15984 // pending time is whatever is left on the root fiber.
15985
15986 var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes);
15987 markRootFinished(root, remainingLanes);
15988
15989 if (root === workInProgressRoot) {
15990 // We can reset these now that they are finished.
15991 workInProgressRoot = null;
15992 workInProgress = null;
15993 workInProgressRootRenderLanes = NoLanes;
15994 } // If there are pending passive effects, schedule a callback to process them.
15995 // Do this as early as possible, so it is queued before anything else that
15996 // might get scheduled in the commit phase. (See #16714.)
15997 // TODO: Delete all other places that schedule the passive effect callback
15998 // They're redundant.
15999
16000
16001 if ((finishedWork.subtreeFlags & PassiveMask) !== NoFlags || (finishedWork.flags & PassiveMask) !== NoFlags) {
16002 if (!rootDoesHavePassiveEffects) {
16003 rootDoesHavePassiveEffects = true;
16004 // to store it in pendingPassiveTransitions until they get processed
16005 // We need to pass this through as an argument to commitRoot
16006 // because workInProgressTransitions might have changed between
16007 // the previous render and commit if we throttle the commit
16008 // with setTimeout
16009
16010 pendingPassiveTransitions = transitions;
16011 scheduleCallback$1(NormalPriority, function () {
16012 flushPassiveEffects(); // This render triggered passive effects: release the root cache pool
16013 // *after* passive effects fire to avoid freeing a cache pool that may
16014 // be referenced by a node in the tree (HostRoot, Cache boundary etc)
16015
16016 return null;
16017 });
16018 }
16019 } // Check if there are any effects in the whole tree.
16020 // TODO: This is left over from the effect list implementation, where we had
16021 // to check for the existence of `firstEffect` to satisfy Flow. I think the
16022 // only other reason this optimization exists is because it affects profiling.
16023 // Reconsider whether this is necessary.
16024
16025
16026 var subtreeHasEffects = (finishedWork.subtreeFlags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags;
16027 var rootHasEffect = (finishedWork.flags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags;
16028
16029 if (subtreeHasEffects || rootHasEffect) {
16030 var prevTransition = ReactCurrentBatchConfig$2.transition;
16031 ReactCurrentBatchConfig$2.transition = null;
16032 var previousPriority = getCurrentUpdatePriority();
16033 setCurrentUpdatePriority(DiscreteEventPriority);
16034 var prevExecutionContext = executionContext;
16035 executionContext |= CommitContext; // Reset this to null before calling lifecycles
16036
16037 ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass
16038 // of the effect list for each phase: all mutation effects come before all
16039 // layout effects, and so on.
16040 // The first phase a "before mutation" phase. We use this phase to read the
16041 // state of the host tree right before we mutate it. This is where
16042 // getSnapshotBeforeUpdate is called.
16043
16044 var shouldFireAfterActiveInstanceBlur = commitBeforeMutationEffects(root, finishedWork);
16045
16046 {
16047 // Mark the current commit time to be shared by all Profilers in this
16048 // batch. This enables them to be grouped later.
16049 recordCommitTime();
16050 }
16051
16052
16053 commitMutationEffects(root, finishedWork);
16054
16055 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
16056 // the mutation phase, so that the previous tree is still current during
16057 // componentWillUnmount, but before the layout phase, so that the finished
16058 // work is current during componentDidMount/Update.
16059
16060 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
16061
16062 commitLayoutEffects(finishedWork, root, lanes);
16063 // opportunity to paint.
16064
16065
16066 requestPaint();
16067 executionContext = prevExecutionContext; // Reset the priority to the previous non-sync value.
16068
16069 setCurrentUpdatePriority(previousPriority);
16070 ReactCurrentBatchConfig$2.transition = prevTransition;
16071 } else {
16072 // No effects.
16073 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
16074 // no effects.
16075 // TODO: Maybe there's a better way to report this.
16076
16077 {
16078 recordCommitTime();
16079 }
16080 }
16081
16082 if (rootDoesHavePassiveEffects) {
16083 // This commit has passive effects. Stash a reference to them. But don't
16084 // schedule a callback until after flushing layout work.
16085 rootDoesHavePassiveEffects = false;
16086 rootWithPendingPassiveEffects = root;
16087 pendingPassiveEffectsLanes = lanes;
16088 } else {
16089
16090 {
16091 nestedPassiveUpdateCount = 0;
16092 rootWithPassiveNestedUpdates = null;
16093 }
16094 } // Read this again, since an effect might have updated it
16095
16096
16097 remainingLanes = root.pendingLanes; // Check if there's remaining work on this root
16098 // TODO: This is part of the `componentDidCatch` implementation. Its purpose
16099 // is to detect whether something might have called setState inside
16100 // `componentDidCatch`. The mechanism is known to be flawed because `setState`
16101 // inside `componentDidCatch` is itself flawed — that's why we recommend
16102 // `getDerivedStateFromError` instead. However, it could be improved by
16103 // checking if remainingLanes includes Sync work, instead of whether there's
16104 // any work remaining at all (which would also include stuff like Suspense
16105 // retries or transitions). It's been like this for a while, though, so fixing
16106 // it probably isn't that urgent.
16107
16108 if (remainingLanes === NoLanes) {
16109 // If there's no remaining work, we can clear the set of already failed
16110 // error boundaries.
16111 legacyErrorBoundariesThatAlreadyFailed = null;
16112 }
16113
16114 onCommitRoot(finishedWork.stateNode, renderPriorityLevel);
16115 // additional work on this root is scheduled.
16116
16117
16118 ensureRootIsScheduled(root, now());
16119
16120 if (recoverableErrors !== null) {
16121 // There were errors during this render, but recovered from them without
16122 // needing to surface it to the UI. We log them here.
16123 var onRecoverableError = root.onRecoverableError;
16124
16125 for (var i = 0; i < recoverableErrors.length; i++) {
16126 var recoverableError = recoverableErrors[i];
16127 var componentStack = recoverableError.stack;
16128 var digest = recoverableError.digest;
16129 onRecoverableError(recoverableError.value, {
16130 componentStack: componentStack,
16131 digest: digest
16132 });
16133 }
16134 }
16135
16136 if (hasUncaughtError) {
16137 hasUncaughtError = false;
16138 var error$1 = firstUncaughtError;
16139 firstUncaughtError = null;
16140 throw error$1;
16141 } // If the passive effects are the result of a discrete render, flush them
16142 // synchronously at the end of the current task so that the result is
16143 // immediately observable. Otherwise, we assume that they are not
16144 // order-dependent and do not need to be observed by external systems, so we
16145 // can wait until after paint.
16146 // TODO: We can optimize this by not scheduling the callback earlier. Since we
16147 // currently schedule the callback in multiple places, will wait until those
16148 // are consolidated.
16149
16150
16151 if (includesSomeLane(pendingPassiveEffectsLanes, SyncLane) && root.tag !== LegacyRoot) {
16152 flushPassiveEffects();
16153 } // Read this again, since a passive effect might have updated it
16154
16155
16156 remainingLanes = root.pendingLanes;
16157
16158 if (includesSomeLane(remainingLanes, SyncLane)) {
16159 {
16160 markNestedUpdateScheduled();
16161 } // Count the number of times the root synchronously re-renders without
16162 // finishing. If there are too many, it indicates an infinite update loop.
16163
16164
16165 if (root === rootWithNestedUpdates) {
16166 nestedUpdateCount++;
16167 } else {
16168 nestedUpdateCount = 0;
16169 rootWithNestedUpdates = root;
16170 }
16171 } else {
16172 nestedUpdateCount = 0;
16173 } // If layout work was scheduled, flush it now.
16174
16175
16176 flushSyncCallbacks();
16177
16178 return null;
16179}
16180
16181function flushPassiveEffects() {
16182 // Returns whether passive effects were flushed.
16183 // TODO: Combine this check with the one in flushPassiveEFfectsImpl. We should
16184 // probably just combine the two functions. I believe they were only separate
16185 // in the first place because we used to wrap it with
16186 // `Scheduler.runWithPriority`, which accepts a function. But now we track the
16187 // priority within React itself, so we can mutate the variable directly.
16188 if (rootWithPendingPassiveEffects !== null) {
16189 var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes);
16190 var priority = lowerEventPriority(DefaultEventPriority, renderPriority);
16191 var prevTransition = ReactCurrentBatchConfig$2.transition;
16192 var previousPriority = getCurrentUpdatePriority();
16193
16194 try {
16195 ReactCurrentBatchConfig$2.transition = null;
16196 setCurrentUpdatePriority(priority);
16197 return flushPassiveEffectsImpl();
16198 } finally {
16199 setCurrentUpdatePriority(previousPriority);
16200 ReactCurrentBatchConfig$2.transition = prevTransition; // Once passive effects have run for the tree - giving components a
16201 }
16202 }
16203
16204 return false;
16205}
16206function enqueuePendingPassiveProfilerEffect(fiber) {
16207 {
16208 pendingPassiveProfilerEffects.push(fiber);
16209
16210 if (!rootDoesHavePassiveEffects) {
16211 rootDoesHavePassiveEffects = true;
16212 scheduleCallback$1(NormalPriority, function () {
16213 flushPassiveEffects();
16214 return null;
16215 });
16216 }
16217 }
16218}
16219
16220function flushPassiveEffectsImpl() {
16221 if (rootWithPendingPassiveEffects === null) {
16222 return false;
16223 } // Cache and clear the transitions flag
16224
16225
16226 var transitions = pendingPassiveTransitions;
16227 pendingPassiveTransitions = null;
16228 var root = rootWithPendingPassiveEffects;
16229 var lanes = pendingPassiveEffectsLanes;
16230 rootWithPendingPassiveEffects = null; // TODO: This is sometimes out of sync with rootWithPendingPassiveEffects.
16231 // Figure out why and fix it. It's not causing any known issues (probably
16232 // because it's only used for profiling), but it's a refactor hazard.
16233
16234 pendingPassiveEffectsLanes = NoLanes;
16235
16236 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
16237 throw new Error('Cannot flush passive effects while already rendering.');
16238 }
16239
16240 {
16241 isFlushingPassiveEffects = true;
16242 didScheduleUpdateDuringPassiveEffects = false;
16243 }
16244
16245 var prevExecutionContext = executionContext;
16246 executionContext |= CommitContext;
16247 commitPassiveUnmountEffects(root.current);
16248 commitPassiveMountEffects(root, root.current, lanes, transitions); // TODO: Move to commitPassiveMountEffects
16249
16250 {
16251 var profilerEffects = pendingPassiveProfilerEffects;
16252 pendingPassiveProfilerEffects = [];
16253
16254 for (var i = 0; i < profilerEffects.length; i++) {
16255 var _fiber = profilerEffects[i];
16256 commitPassiveEffectDurations(root, _fiber);
16257 }
16258 }
16259
16260 executionContext = prevExecutionContext;
16261 flushSyncCallbacks();
16262
16263 {
16264 // If additional passive effects were scheduled, increment a counter. If this
16265 // exceeds the limit, we'll fire a warning.
16266 if (didScheduleUpdateDuringPassiveEffects) {
16267 if (root === rootWithPassiveNestedUpdates) {
16268 nestedPassiveUpdateCount++;
16269 } else {
16270 nestedPassiveUpdateCount = 0;
16271 rootWithPassiveNestedUpdates = root;
16272 }
16273 } else {
16274 nestedPassiveUpdateCount = 0;
16275 }
16276
16277 isFlushingPassiveEffects = false;
16278 didScheduleUpdateDuringPassiveEffects = false;
16279 } // TODO: Move to commitPassiveMountEffects
16280
16281
16282 onPostCommitRoot(root);
16283
16284 {
16285 var stateNode = root.current.stateNode;
16286 stateNode.effectDuration = 0;
16287 stateNode.passiveEffectDuration = 0;
16288 }
16289
16290 return true;
16291}
16292
16293function isAlreadyFailedLegacyErrorBoundary(instance) {
16294 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
16295}
16296function markLegacyErrorBoundaryAsFailed(instance) {
16297 if (legacyErrorBoundariesThatAlreadyFailed === null) {
16298 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
16299 } else {
16300 legacyErrorBoundariesThatAlreadyFailed.add(instance);
16301 }
16302}
16303
16304function prepareToThrowUncaughtError(error) {
16305 if (!hasUncaughtError) {
16306 hasUncaughtError = true;
16307 firstUncaughtError = error;
16308 }
16309}
16310
16311var onUncaughtError = prepareToThrowUncaughtError;
16312
16313function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
16314 var errorInfo = createCapturedValueAtFiber(error, sourceFiber);
16315 var update = createRootErrorUpdate(rootFiber, errorInfo, SyncLane);
16316 var root = enqueueUpdate(rootFiber, update, SyncLane);
16317 var eventTime = requestEventTime();
16318
16319 if (root !== null) {
16320 markRootUpdated(root, SyncLane, eventTime);
16321 ensureRootIsScheduled(root, eventTime);
16322 }
16323}
16324
16325function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) {
16326 {
16327 reportUncaughtErrorInDEV(error$1);
16328 setIsRunningInsertionEffect(false);
16329 }
16330
16331 if (sourceFiber.tag === HostRoot) {
16332 // Error was thrown at the root. There is no parent, so the root
16333 // itself should capture it.
16334 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1);
16335 return;
16336 }
16337
16338 var fiber = null;
16339
16340 {
16341 fiber = sourceFiber.return;
16342 }
16343
16344 while (fiber !== null) {
16345 if (fiber.tag === HostRoot) {
16346 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1);
16347 return;
16348 } else if (fiber.tag === ClassComponent) {
16349 var ctor = fiber.type;
16350 var instance = fiber.stateNode;
16351
16352 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
16353 var errorInfo = createCapturedValueAtFiber(error$1, sourceFiber);
16354 var update = createClassErrorUpdate(fiber, errorInfo, SyncLane);
16355 var root = enqueueUpdate(fiber, update, SyncLane);
16356 var eventTime = requestEventTime();
16357
16358 if (root !== null) {
16359 markRootUpdated(root, SyncLane, eventTime);
16360 ensureRootIsScheduled(root, eventTime);
16361 }
16362
16363 return;
16364 }
16365 }
16366
16367 fiber = fiber.return;
16368 }
16369
16370 {
16371 // TODO: Until we re-land skipUnmountedBoundaries (see #20147), this warning
16372 // will fire for errors that are thrown by destroy functions inside deleted
16373 // trees. What it should instead do is propagate the error to the parent of
16374 // the deleted tree. In the meantime, do not add this warning to the
16375 // allowlist; this is only for our internal use.
16376 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);
16377 }
16378}
16379function pingSuspendedRoot(root, wakeable, pingedLanes) {
16380 var pingCache = root.pingCache;
16381
16382 if (pingCache !== null) {
16383 // The wakeable resolved, so we no longer need to memoize, because it will
16384 // never be thrown again.
16385 pingCache.delete(wakeable);
16386 }
16387
16388 var eventTime = requestEventTime();
16389 markRootPinged(root, pingedLanes);
16390 warnIfSuspenseResolutionNotWrappedWithActDEV(root);
16391
16392 if (workInProgressRoot === root && isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes)) {
16393 // Received a ping at the same priority level at which we're currently
16394 // rendering. We might want to restart this render. This should mirror
16395 // the logic of whether or not a root suspends once it completes.
16396 // TODO: If we're rendering sync either due to Sync, Batched or expired,
16397 // we should probably never restart.
16398 // If we're suspended with delay, or if it's a retry, we'll always suspend
16399 // so we can always restart.
16400 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && includesOnlyRetries(workInProgressRootRenderLanes) && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
16401 // Restart from the root.
16402 prepareFreshStack(root, NoLanes);
16403 } else {
16404 // Even though we can't restart right now, we might get an
16405 // opportunity later. So we mark this render as having a ping.
16406 workInProgressRootPingedLanes = mergeLanes(workInProgressRootPingedLanes, pingedLanes);
16407 }
16408 }
16409
16410 ensureRootIsScheduled(root, eventTime);
16411}
16412
16413function retryTimedOutBoundary(boundaryFiber, retryLane) {
16414 // The boundary fiber (a Suspense component or SuspenseList component)
16415 // previously was rendered in its fallback state. One of the promises that
16416 // suspended it has resolved, which means at least part of the tree was
16417 // likely unblocked. Try rendering again, at a new lanes.
16418 if (retryLane === NoLane) {
16419 // TODO: Assign this to `suspenseState.retryLane`? to avoid
16420 // unnecessary entanglement?
16421 retryLane = requestRetryLane(boundaryFiber);
16422 } // TODO: Special case idle priority?
16423
16424
16425 var eventTime = requestEventTime();
16426 var root = enqueueConcurrentRenderForLane(boundaryFiber, retryLane);
16427
16428 if (root !== null) {
16429 markRootUpdated(root, retryLane, eventTime);
16430 ensureRootIsScheduled(root, eventTime);
16431 }
16432}
16433
16434function retryDehydratedSuspenseBoundary(boundaryFiber) {
16435 var suspenseState = boundaryFiber.memoizedState;
16436 var retryLane = NoLane;
16437
16438 if (suspenseState !== null) {
16439 retryLane = suspenseState.retryLane;
16440 }
16441
16442 retryTimedOutBoundary(boundaryFiber, retryLane);
16443}
16444function resolveRetryWakeable(boundaryFiber, wakeable) {
16445 var retryLane = NoLane; // Default
16446
16447 var retryCache;
16448
16449 switch (boundaryFiber.tag) {
16450 case SuspenseComponent:
16451 retryCache = boundaryFiber.stateNode;
16452 var suspenseState = boundaryFiber.memoizedState;
16453
16454 if (suspenseState !== null) {
16455 retryLane = suspenseState.retryLane;
16456 }
16457
16458 break;
16459
16460 case SuspenseListComponent:
16461 retryCache = boundaryFiber.stateNode;
16462 break;
16463
16464 default:
16465 throw new Error('Pinged unknown suspense boundary type. ' + 'This is probably a bug in React.');
16466 }
16467
16468 if (retryCache !== null) {
16469 // The wakeable resolved, so we no longer need to memoize, because it will
16470 // never be thrown again.
16471 retryCache.delete(wakeable);
16472 }
16473
16474 retryTimedOutBoundary(boundaryFiber, retryLane);
16475} // Computes the next Just Noticeable Difference (JND) boundary.
16476// The theory is that a person can't tell the difference between small differences in time.
16477// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
16478// difference in the experience. However, waiting for longer might mean that we can avoid
16479// showing an intermediate loading state. The longer we have already waited, the harder it
16480// is to tell small differences in time. Therefore, the longer we've already waited,
16481// the longer we can wait additionally. At some point we have to give up though.
16482// We pick a train model where the next boundary commits at a consistent schedule.
16483// These particular numbers are vague estimates. We expect to adjust them based on research.
16484
16485function jnd(timeElapsed) {
16486 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
16487}
16488
16489function checkForNestedUpdates() {
16490 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
16491 nestedUpdateCount = 0;
16492 rootWithNestedUpdates = null;
16493 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.');
16494 }
16495
16496 {
16497 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
16498 nestedPassiveUpdateCount = 0;
16499 rootWithPassiveNestedUpdates = null;
16500
16501 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.');
16502 }
16503 }
16504}
16505
16506function flushRenderPhaseStrictModeWarningsInDEV() {
16507 {
16508 ReactStrictModeWarnings.flushLegacyContextWarning();
16509
16510 {
16511 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
16512 }
16513 }
16514}
16515
16516var didWarnStateUpdateForNotYetMountedComponent = null;
16517function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) {
16518 {
16519 if ((executionContext & RenderContext) !== NoContext) {
16520 // We let the other warning about render phase updates deal with this one.
16521 return;
16522 }
16523
16524 if (!(fiber.mode & ConcurrentMode)) {
16525 return;
16526 }
16527
16528 var tag = fiber.tag;
16529
16530 if (tag !== IndeterminateComponent && tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent) {
16531 // Only warn for user-defined components, not internal ones like Suspense.
16532 return;
16533 } // We show the whole stack but dedupe on the top component's name because
16534 // the problematic code almost always lies inside that component.
16535
16536
16537 var componentName = getComponentNameFromFiber(fiber) || 'ReactComponent';
16538
16539 if (didWarnStateUpdateForNotYetMountedComponent !== null) {
16540 if (didWarnStateUpdateForNotYetMountedComponent.has(componentName)) {
16541 return;
16542 }
16543
16544 didWarnStateUpdateForNotYetMountedComponent.add(componentName);
16545 } else {
16546 didWarnStateUpdateForNotYetMountedComponent = new Set([componentName]);
16547 }
16548
16549 var previousFiber = current;
16550
16551 try {
16552 setCurrentFiber(fiber);
16553
16554 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.');
16555 } finally {
16556 if (previousFiber) {
16557 setCurrentFiber(fiber);
16558 } else {
16559 resetCurrentFiber();
16560 }
16561 }
16562 }
16563}
16564var beginWork$1;
16565
16566{
16567 beginWork$1 = beginWork;
16568}
16569
16570var didWarnAboutUpdateInRender = false;
16571var didWarnAboutUpdateInRenderForAnotherComponent;
16572
16573{
16574 didWarnAboutUpdateInRenderForAnotherComponent = new Set();
16575}
16576
16577function warnAboutRenderPhaseUpdatesInDEV(fiber) {
16578 {
16579 if (isRendering && !getIsUpdatingOpaqueValueInRenderPhaseInDEV()) {
16580 switch (fiber.tag) {
16581 case FunctionComponent:
16582 case ForwardRef:
16583 case SimpleMemoComponent:
16584 {
16585 var renderingComponentName = workInProgress && getComponentNameFromFiber(workInProgress) || 'Unknown'; // Dedupe by the rendering component because it's the one that needs to be fixed.
16586
16587 var dedupeKey = renderingComponentName;
16588
16589 if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) {
16590 didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey);
16591 var setStateComponentName = getComponentNameFromFiber(fiber) || 'Unknown';
16592
16593 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);
16594 }
16595
16596 break;
16597 }
16598
16599 case ClassComponent:
16600 {
16601 if (!didWarnAboutUpdateInRender) {
16602 error('Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure ' + 'function of props and state.');
16603
16604 didWarnAboutUpdateInRender = true;
16605 }
16606
16607 break;
16608 }
16609 }
16610 }
16611 }
16612}
16613var fakeActCallbackNode = {};
16614
16615function scheduleCallback$1(priorityLevel, callback) {
16616 {
16617 // If we're currently inside an `act` scope, bypass Scheduler and push to
16618 // the `act` queue instead.
16619 var actQueue = ReactCurrentActQueue$1.current;
16620
16621 if (actQueue !== null) {
16622 actQueue.push(callback);
16623 return fakeActCallbackNode;
16624 } else {
16625 return scheduleCallback(priorityLevel, callback);
16626 }
16627 }
16628}
16629
16630function cancelCallback$1(callbackNode) {
16631 if ( callbackNode === fakeActCallbackNode) {
16632 return;
16633 } // In production, always call Scheduler. This function will be stripped out.
16634
16635
16636 return cancelCallback(callbackNode);
16637}
16638
16639function shouldForceFlushFallbacksInDEV() {
16640 // Never force flush in production. This function should get stripped out.
16641 return ReactCurrentActQueue$1.current !== null;
16642}
16643
16644function warnIfUpdatesNotWrappedWithActDEV(fiber) {
16645 {
16646 if (fiber.mode & ConcurrentMode) {
16647 if (!isConcurrentActEnvironment()) {
16648 // Not in an act environment. No need to warn.
16649 return;
16650 }
16651 } else {
16652 // Legacy mode has additional cases where we suppress a warning.
16653 if (!isLegacyActEnvironment()) {
16654 // Not in an act environment. No need to warn.
16655 return;
16656 }
16657
16658 if (executionContext !== NoContext) {
16659 // Legacy mode doesn't warn if the update is batched, i.e.
16660 // batchedUpdates or flushSync.
16661 return;
16662 }
16663
16664 if (fiber.tag !== FunctionComponent && fiber.tag !== ForwardRef && fiber.tag !== SimpleMemoComponent) {
16665 // For backwards compatibility with pre-hooks code, legacy mode only
16666 // warns for updates that originate from a hook.
16667 return;
16668 }
16669 }
16670
16671 if (ReactCurrentActQueue$1.current === null) {
16672 var previousFiber = current;
16673
16674 try {
16675 setCurrentFiber(fiber);
16676
16677 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));
16678 } finally {
16679 if (previousFiber) {
16680 setCurrentFiber(fiber);
16681 } else {
16682 resetCurrentFiber();
16683 }
16684 }
16685 }
16686 }
16687}
16688
16689function warnIfSuspenseResolutionNotWrappedWithActDEV(root) {
16690 {
16691 if (root.tag !== LegacyRoot && isConcurrentActEnvironment() && ReactCurrentActQueue$1.current === null) {
16692 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');
16693 }
16694 }
16695}
16696
16697function setIsRunningInsertionEffect(isRunning) {
16698 {
16699 isRunningInsertionEffect = isRunning;
16700 }
16701}
16702
16703/* eslint-disable react-internal/prod-error-codes */
16704var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
16705
16706var failedBoundaries = null;
16707var setRefreshHandler = function (handler) {
16708 {
16709 resolveFamily = handler;
16710 }
16711};
16712function resolveFunctionForHotReloading(type) {
16713 {
16714 if (resolveFamily === null) {
16715 // Hot reloading is disabled.
16716 return type;
16717 }
16718
16719 var family = resolveFamily(type);
16720
16721 if (family === undefined) {
16722 return type;
16723 } // Use the latest known implementation.
16724
16725
16726 return family.current;
16727 }
16728}
16729function resolveClassForHotReloading(type) {
16730 // No implementation differences.
16731 return resolveFunctionForHotReloading(type);
16732}
16733function resolveForwardRefForHotReloading(type) {
16734 {
16735 if (resolveFamily === null) {
16736 // Hot reloading is disabled.
16737 return type;
16738 }
16739
16740 var family = resolveFamily(type);
16741
16742 if (family === undefined) {
16743 // Check if we're dealing with a real forwardRef. Don't want to crash early.
16744 if (type !== null && type !== undefined && typeof type.render === 'function') {
16745 // ForwardRef is special because its resolved .type is an object,
16746 // but it's possible that we only have its inner render function in the map.
16747 // If that inner render function is different, we'll build a new forwardRef type.
16748 var currentRender = resolveFunctionForHotReloading(type.render);
16749
16750 if (type.render !== currentRender) {
16751 var syntheticType = {
16752 $$typeof: REACT_FORWARD_REF_TYPE,
16753 render: currentRender
16754 };
16755
16756 if (type.displayName !== undefined) {
16757 syntheticType.displayName = type.displayName;
16758 }
16759
16760 return syntheticType;
16761 }
16762 }
16763
16764 return type;
16765 } // Use the latest known implementation.
16766
16767
16768 return family.current;
16769 }
16770}
16771function isCompatibleFamilyForHotReloading(fiber, element) {
16772 {
16773 if (resolveFamily === null) {
16774 // Hot reloading is disabled.
16775 return false;
16776 }
16777
16778 var prevType = fiber.elementType;
16779 var nextType = element.type; // If we got here, we know types aren't === equal.
16780
16781 var needsCompareFamilies = false;
16782 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
16783
16784 switch (fiber.tag) {
16785 case ClassComponent:
16786 {
16787 if (typeof nextType === 'function') {
16788 needsCompareFamilies = true;
16789 }
16790
16791 break;
16792 }
16793
16794 case FunctionComponent:
16795 {
16796 if (typeof nextType === 'function') {
16797 needsCompareFamilies = true;
16798 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
16799 // We don't know the inner type yet.
16800 // We're going to assume that the lazy inner type is stable,
16801 // and so it is sufficient to avoid reconciling it away.
16802 // We're not going to unwrap or actually use the new lazy type.
16803 needsCompareFamilies = true;
16804 }
16805
16806 break;
16807 }
16808
16809 case ForwardRef:
16810 {
16811 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
16812 needsCompareFamilies = true;
16813 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
16814 needsCompareFamilies = true;
16815 }
16816
16817 break;
16818 }
16819
16820 case MemoComponent:
16821 case SimpleMemoComponent:
16822 {
16823 if ($$typeofNextType === REACT_MEMO_TYPE) {
16824 // TODO: if it was but can no longer be simple,
16825 // we shouldn't set this.
16826 needsCompareFamilies = true;
16827 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
16828 needsCompareFamilies = true;
16829 }
16830
16831 break;
16832 }
16833
16834 default:
16835 return false;
16836 } // Check if both types have a family and it's the same one.
16837
16838
16839 if (needsCompareFamilies) {
16840 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
16841 // This means both of them need to be registered to preserve state.
16842 // If we unwrapped and compared the inner types for wrappers instead,
16843 // then we would risk falsely saying two separate memo(Foo)
16844 // calls are equivalent because they wrap the same Foo function.
16845 var prevFamily = resolveFamily(prevType);
16846
16847 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
16848 return true;
16849 }
16850 }
16851
16852 return false;
16853 }
16854}
16855function markFailedErrorBoundaryForHotReloading(fiber) {
16856 {
16857 if (resolveFamily === null) {
16858 // Hot reloading is disabled.
16859 return;
16860 }
16861
16862 if (typeof WeakSet !== 'function') {
16863 return;
16864 }
16865
16866 if (failedBoundaries === null) {
16867 failedBoundaries = new WeakSet();
16868 }
16869
16870 failedBoundaries.add(fiber);
16871 }
16872}
16873var scheduleRefresh = function (root, update) {
16874 {
16875 if (resolveFamily === null) {
16876 // Hot reloading is disabled.
16877 return;
16878 }
16879
16880 var staleFamilies = update.staleFamilies,
16881 updatedFamilies = update.updatedFamilies;
16882 flushPassiveEffects();
16883 flushSync(function () {
16884 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
16885 });
16886 }
16887};
16888var scheduleRoot = function (root, element) {
16889 {
16890 if (root.context !== emptyContextObject) {
16891 // Super edge case: root has a legacy _renderSubtree context
16892 // but we don't know the parentComponent so we can't pass it.
16893 // Just ignore. We'll delete this with _renderSubtree code path later.
16894 return;
16895 }
16896
16897 flushPassiveEffects();
16898 flushSync(function () {
16899 updateContainer(element, root, null, null);
16900 });
16901 }
16902};
16903
16904function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
16905 {
16906 var alternate = fiber.alternate,
16907 child = fiber.child,
16908 sibling = fiber.sibling,
16909 tag = fiber.tag,
16910 type = fiber.type;
16911 var candidateType = null;
16912
16913 switch (tag) {
16914 case FunctionComponent:
16915 case SimpleMemoComponent:
16916 case ClassComponent:
16917 candidateType = type;
16918 break;
16919
16920 case ForwardRef:
16921 candidateType = type.render;
16922 break;
16923 }
16924
16925 if (resolveFamily === null) {
16926 throw new Error('Expected resolveFamily to be set during hot reload.');
16927 }
16928
16929 var needsRender = false;
16930 var needsRemount = false;
16931
16932 if (candidateType !== null) {
16933 var family = resolveFamily(candidateType);
16934
16935 if (family !== undefined) {
16936 if (staleFamilies.has(family)) {
16937 needsRemount = true;
16938 } else if (updatedFamilies.has(family)) {
16939 if (tag === ClassComponent) {
16940 needsRemount = true;
16941 } else {
16942 needsRender = true;
16943 }
16944 }
16945 }
16946 }
16947
16948 if (failedBoundaries !== null) {
16949 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
16950 needsRemount = true;
16951 }
16952 }
16953
16954 if (needsRemount) {
16955 fiber._debugNeedsRemount = true;
16956 }
16957
16958 if (needsRemount || needsRender) {
16959 var _root = enqueueConcurrentRenderForLane(fiber, SyncLane);
16960
16961 if (_root !== null) {
16962 scheduleUpdateOnFiber(_root, fiber, SyncLane, NoTimestamp);
16963 }
16964 }
16965
16966 if (child !== null && !needsRemount) {
16967 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
16968 }
16969
16970 if (sibling !== null) {
16971 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
16972 }
16973 }
16974}
16975
16976var findHostInstancesForRefresh = function (root, families) {
16977 {
16978 var hostInstances = new Set();
16979 var types = new Set(families.map(function (family) {
16980 return family.current;
16981 }));
16982 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
16983 return hostInstances;
16984 }
16985};
16986
16987function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
16988 {
16989 var child = fiber.child,
16990 sibling = fiber.sibling,
16991 tag = fiber.tag,
16992 type = fiber.type;
16993 var candidateType = null;
16994
16995 switch (tag) {
16996 case FunctionComponent:
16997 case SimpleMemoComponent:
16998 case ClassComponent:
16999 candidateType = type;
17000 break;
17001
17002 case ForwardRef:
17003 candidateType = type.render;
17004 break;
17005 }
17006
17007 var didMatch = false;
17008
17009 if (candidateType !== null) {
17010 if (types.has(candidateType)) {
17011 didMatch = true;
17012 }
17013 }
17014
17015 if (didMatch) {
17016 // We have a match. This only drills down to the closest host components.
17017 // There's no need to search deeper because for the purpose of giving
17018 // visual feedback, "flashing" outermost parent rectangles is sufficient.
17019 findHostInstancesForFiberShallowly(fiber, hostInstances);
17020 } else {
17021 // If there's no match, maybe there will be one further down in the child tree.
17022 if (child !== null) {
17023 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
17024 }
17025 }
17026
17027 if (sibling !== null) {
17028 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
17029 }
17030 }
17031}
17032
17033function findHostInstancesForFiberShallowly(fiber, hostInstances) {
17034 {
17035 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
17036
17037 if (foundHostInstances) {
17038 return;
17039 } // If we didn't find any host children, fallback to closest host parent.
17040
17041
17042 var node = fiber;
17043
17044 while (true) {
17045 switch (node.tag) {
17046 case HostComponent:
17047 hostInstances.add(node.stateNode);
17048 return;
17049
17050 case HostPortal:
17051 hostInstances.add(node.stateNode.containerInfo);
17052 return;
17053
17054 case HostRoot:
17055 hostInstances.add(node.stateNode.containerInfo);
17056 return;
17057 }
17058
17059 if (node.return === null) {
17060 throw new Error('Expected to reach root first.');
17061 }
17062
17063 node = node.return;
17064 }
17065 }
17066}
17067
17068function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
17069 {
17070 var node = fiber;
17071 var foundHostInstances = false;
17072
17073 while (true) {
17074 if (node.tag === HostComponent) {
17075 // We got a match.
17076 foundHostInstances = true;
17077 hostInstances.add(node.stateNode); // There may still be more, so keep searching.
17078 } else if (node.child !== null) {
17079 node.child.return = node;
17080 node = node.child;
17081 continue;
17082 }
17083
17084 if (node === fiber) {
17085 return foundHostInstances;
17086 }
17087
17088 while (node.sibling === null) {
17089 if (node.return === null || node.return === fiber) {
17090 return foundHostInstances;
17091 }
17092
17093 node = node.return;
17094 }
17095
17096 node.sibling.return = node.return;
17097 node = node.sibling;
17098 }
17099 }
17100
17101 return false;
17102}
17103
17104var hasBadMapPolyfill;
17105
17106{
17107 hasBadMapPolyfill = false;
17108
17109 try {
17110 var nonExtensibleObject = Object.preventExtensions({});
17111 /* eslint-disable no-new */
17112
17113 new Map([[nonExtensibleObject, null]]);
17114 new Set([nonExtensibleObject]);
17115 /* eslint-enable no-new */
17116 } catch (e) {
17117 // TODO: Consider warning about bad polyfills
17118 hasBadMapPolyfill = true;
17119 }
17120}
17121
17122function FiberNode(tag, pendingProps, key, mode) {
17123 // Instance
17124 this.tag = tag;
17125 this.key = key;
17126 this.elementType = null;
17127 this.type = null;
17128 this.stateNode = null; // Fiber
17129
17130 this.return = null;
17131 this.child = null;
17132 this.sibling = null;
17133 this.index = 0;
17134 this.ref = null;
17135 this.pendingProps = pendingProps;
17136 this.memoizedProps = null;
17137 this.updateQueue = null;
17138 this.memoizedState = null;
17139 this.dependencies = null;
17140 this.mode = mode; // Effects
17141
17142 this.flags = NoFlags;
17143 this.subtreeFlags = NoFlags;
17144 this.deletions = null;
17145 this.lanes = NoLanes;
17146 this.childLanes = NoLanes;
17147 this.alternate = null;
17148
17149 {
17150 // Note: The following is done to avoid a v8 performance cliff.
17151 //
17152 // Initializing the fields below to smis and later updating them with
17153 // double values will cause Fibers to end up having separate shapes.
17154 // This behavior/bug has something to do with Object.preventExtension().
17155 // Fortunately this only impacts DEV builds.
17156 // Unfortunately it makes React unusably slow for some applications.
17157 // To work around this, initialize the fields below with doubles.
17158 //
17159 // Learn more about this here:
17160 // https://github.com/facebook/react/issues/14365
17161 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
17162 this.actualDuration = Number.NaN;
17163 this.actualStartTime = Number.NaN;
17164 this.selfBaseDuration = Number.NaN;
17165 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
17166 // This won't trigger the performance cliff mentioned above,
17167 // and it simplifies other profiler code (including DevTools).
17168
17169 this.actualDuration = 0;
17170 this.actualStartTime = -1;
17171 this.selfBaseDuration = 0;
17172 this.treeBaseDuration = 0;
17173 }
17174
17175 {
17176 // This isn't directly used but is handy for debugging internals:
17177 this._debugSource = null;
17178 this._debugOwner = null;
17179 this._debugNeedsRemount = false;
17180 this._debugHookTypes = null;
17181
17182 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
17183 Object.preventExtensions(this);
17184 }
17185 }
17186} // This is a constructor function, rather than a POJO constructor, still
17187// please ensure we do the following:
17188// 1) Nobody should add any instance methods on this. Instance methods can be
17189// more difficult to predict when they get optimized and they are almost
17190// never inlined properly in static compilers.
17191// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
17192// always know when it is a fiber.
17193// 3) We might want to experiment with using numeric keys since they are easier
17194// to optimize in a non-JIT environment.
17195// 4) We can easily go from a constructor to a createFiber object literal if that
17196// is faster.
17197// 5) It should be easy to port this to a C struct and keep a C implementation
17198// compatible.
17199
17200
17201var createFiber = function (tag, pendingProps, key, mode) {
17202 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
17203 return new FiberNode(tag, pendingProps, key, mode);
17204};
17205
17206function shouldConstruct$1(Component) {
17207 var prototype = Component.prototype;
17208 return !!(prototype && prototype.isReactComponent);
17209}
17210
17211function isSimpleFunctionComponent(type) {
17212 return typeof type === 'function' && !shouldConstruct$1(type) && type.defaultProps === undefined;
17213}
17214function resolveLazyComponentTag(Component) {
17215 if (typeof Component === 'function') {
17216 return shouldConstruct$1(Component) ? ClassComponent : FunctionComponent;
17217 } else if (Component !== undefined && Component !== null) {
17218 var $$typeof = Component.$$typeof;
17219
17220 if ($$typeof === REACT_FORWARD_REF_TYPE) {
17221 return ForwardRef;
17222 }
17223
17224 if ($$typeof === REACT_MEMO_TYPE) {
17225 return MemoComponent;
17226 }
17227 }
17228
17229 return IndeterminateComponent;
17230} // This is used to create an alternate fiber to do work on.
17231
17232function createWorkInProgress(current, pendingProps) {
17233 var workInProgress = current.alternate;
17234
17235 if (workInProgress === null) {
17236 // We use a double buffering pooling technique because we know that we'll
17237 // only ever need at most two versions of a tree. We pool the "other" unused
17238 // node that we're free to reuse. This is lazily created to avoid allocating
17239 // extra objects for things that are never updated. It also allow us to
17240 // reclaim the extra memory if needed.
17241 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
17242 workInProgress.elementType = current.elementType;
17243 workInProgress.type = current.type;
17244 workInProgress.stateNode = current.stateNode;
17245
17246 {
17247 // DEV-only fields
17248 workInProgress._debugSource = current._debugSource;
17249 workInProgress._debugOwner = current._debugOwner;
17250 workInProgress._debugHookTypes = current._debugHookTypes;
17251 }
17252
17253 workInProgress.alternate = current;
17254 current.alternate = workInProgress;
17255 } else {
17256 workInProgress.pendingProps = pendingProps; // Needed because Blocks store data on type.
17257
17258 workInProgress.type = current.type; // We already have an alternate.
17259 // Reset the effect tag.
17260
17261 workInProgress.flags = NoFlags; // The effects are no longer valid.
17262
17263 workInProgress.subtreeFlags = NoFlags;
17264 workInProgress.deletions = null;
17265
17266 {
17267 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
17268 // This prevents time from endlessly accumulating in new commits.
17269 // This has the downside of resetting values for different priority renders,
17270 // But works for yielding (the common case) and should support resuming.
17271 workInProgress.actualDuration = 0;
17272 workInProgress.actualStartTime = -1;
17273 }
17274 } // Reset all effects except static ones.
17275 // Static effects are not specific to a render.
17276
17277
17278 workInProgress.flags = current.flags & StaticMask;
17279 workInProgress.childLanes = current.childLanes;
17280 workInProgress.lanes = current.lanes;
17281 workInProgress.child = current.child;
17282 workInProgress.memoizedProps = current.memoizedProps;
17283 workInProgress.memoizedState = current.memoizedState;
17284 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
17285 // it cannot be shared with the current fiber.
17286
17287 var currentDependencies = current.dependencies;
17288 workInProgress.dependencies = currentDependencies === null ? null : {
17289 lanes: currentDependencies.lanes,
17290 firstContext: currentDependencies.firstContext
17291 }; // These will be overridden during the parent's reconciliation
17292
17293 workInProgress.sibling = current.sibling;
17294 workInProgress.index = current.index;
17295 workInProgress.ref = current.ref;
17296
17297 {
17298 workInProgress.selfBaseDuration = current.selfBaseDuration;
17299 workInProgress.treeBaseDuration = current.treeBaseDuration;
17300 }
17301
17302 {
17303 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
17304
17305 switch (workInProgress.tag) {
17306 case IndeterminateComponent:
17307 case FunctionComponent:
17308 case SimpleMemoComponent:
17309 workInProgress.type = resolveFunctionForHotReloading(current.type);
17310 break;
17311
17312 case ClassComponent:
17313 workInProgress.type = resolveClassForHotReloading(current.type);
17314 break;
17315
17316 case ForwardRef:
17317 workInProgress.type = resolveForwardRefForHotReloading(current.type);
17318 break;
17319 }
17320 }
17321
17322 return workInProgress;
17323} // Used to reuse a Fiber for a second pass.
17324
17325function resetWorkInProgress(workInProgress, renderLanes) {
17326 // This resets the Fiber to what createFiber or createWorkInProgress would
17327 // have set the values to before during the first pass. Ideally this wouldn't
17328 // be necessary but unfortunately many code paths reads from the workInProgress
17329 // when they should be reading from current and writing to workInProgress.
17330 // We assume pendingProps, index, key, ref, return are still untouched to
17331 // avoid doing another reconciliation.
17332 // Reset the effect flags but keep any Placement tags, since that's something
17333 // that child fiber is setting, not the reconciliation.
17334 workInProgress.flags &= StaticMask | Placement; // The effects are no longer valid.
17335
17336 var current = workInProgress.alternate;
17337
17338 if (current === null) {
17339 // Reset to createFiber's initial values.
17340 workInProgress.childLanes = NoLanes;
17341 workInProgress.lanes = renderLanes;
17342 workInProgress.child = null;
17343 workInProgress.subtreeFlags = NoFlags;
17344 workInProgress.memoizedProps = null;
17345 workInProgress.memoizedState = null;
17346 workInProgress.updateQueue = null;
17347 workInProgress.dependencies = null;
17348 workInProgress.stateNode = null;
17349
17350 {
17351 // Note: We don't reset the actualTime counts. It's useful to accumulate
17352 // actual time across multiple render passes.
17353 workInProgress.selfBaseDuration = 0;
17354 workInProgress.treeBaseDuration = 0;
17355 }
17356 } else {
17357 // Reset to the cloned values that createWorkInProgress would've.
17358 workInProgress.childLanes = current.childLanes;
17359 workInProgress.lanes = current.lanes;
17360 workInProgress.child = current.child;
17361 workInProgress.subtreeFlags = NoFlags;
17362 workInProgress.deletions = null;
17363 workInProgress.memoizedProps = current.memoizedProps;
17364 workInProgress.memoizedState = current.memoizedState;
17365 workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type.
17366
17367 workInProgress.type = current.type; // Clone the dependencies object. This is mutated during the render phase, so
17368 // it cannot be shared with the current fiber.
17369
17370 var currentDependencies = current.dependencies;
17371 workInProgress.dependencies = currentDependencies === null ? null : {
17372 lanes: currentDependencies.lanes,
17373 firstContext: currentDependencies.firstContext
17374 };
17375
17376 {
17377 // Note: We don't reset the actualTime counts. It's useful to accumulate
17378 // actual time across multiple render passes.
17379 workInProgress.selfBaseDuration = current.selfBaseDuration;
17380 workInProgress.treeBaseDuration = current.treeBaseDuration;
17381 }
17382 }
17383
17384 return workInProgress;
17385}
17386function createHostRootFiber(tag, isStrictMode, concurrentUpdatesByDefaultOverride) {
17387 var mode;
17388
17389 if (tag === ConcurrentRoot) {
17390 mode = ConcurrentMode;
17391
17392 if (isStrictMode === true) {
17393 mode |= StrictLegacyMode;
17394 }
17395 } else {
17396 mode = NoMode;
17397 }
17398
17399 if ( isDevToolsPresent) {
17400 // Always collect profile timings when DevTools are present.
17401 // This enables DevTools to start capturing timing at any point–
17402 // Without some nodes in the tree having empty base times.
17403 mode |= ProfileMode;
17404 }
17405
17406 return createFiber(HostRoot, null, null, mode);
17407}
17408function createFiberFromTypeAndProps(type, // React$ElementType
17409key, pendingProps, owner, mode, lanes) {
17410 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
17411
17412 var resolvedType = type;
17413
17414 if (typeof type === 'function') {
17415 if (shouldConstruct$1(type)) {
17416 fiberTag = ClassComponent;
17417
17418 {
17419 resolvedType = resolveClassForHotReloading(resolvedType);
17420 }
17421 } else {
17422 {
17423 resolvedType = resolveFunctionForHotReloading(resolvedType);
17424 }
17425 }
17426 } else if (typeof type === 'string') {
17427 fiberTag = HostComponent;
17428 } else {
17429 getTag: switch (type) {
17430 case REACT_FRAGMENT_TYPE:
17431 return createFiberFromFragment(pendingProps.children, mode, lanes, key);
17432
17433 case REACT_STRICT_MODE_TYPE:
17434 fiberTag = Mode;
17435 mode |= StrictLegacyMode;
17436
17437 break;
17438
17439 case REACT_PROFILER_TYPE:
17440 return createFiberFromProfiler(pendingProps, mode, lanes, key);
17441
17442 case REACT_SUSPENSE_TYPE:
17443 return createFiberFromSuspense(pendingProps, mode, lanes, key);
17444
17445 case REACT_SUSPENSE_LIST_TYPE:
17446 return createFiberFromSuspenseList(pendingProps, mode, lanes, key);
17447
17448 case REACT_OFFSCREEN_TYPE:
17449 return createFiberFromOffscreen(pendingProps, mode, lanes, key);
17450
17451 case REACT_LEGACY_HIDDEN_TYPE:
17452
17453 // eslint-disable-next-line no-fallthrough
17454
17455 case REACT_SCOPE_TYPE:
17456
17457 // eslint-disable-next-line no-fallthrough
17458
17459 case REACT_CACHE_TYPE:
17460
17461 // eslint-disable-next-line no-fallthrough
17462
17463 case REACT_TRACING_MARKER_TYPE:
17464
17465 // eslint-disable-next-line no-fallthrough
17466
17467 case REACT_DEBUG_TRACING_MODE_TYPE:
17468
17469 // eslint-disable-next-line no-fallthrough
17470
17471 default:
17472 {
17473 if (typeof type === 'object' && type !== null) {
17474 switch (type.$$typeof) {
17475 case REACT_PROVIDER_TYPE:
17476 fiberTag = ContextProvider;
17477 break getTag;
17478
17479 case REACT_CONTEXT_TYPE:
17480 // This is a consumer
17481 fiberTag = ContextConsumer;
17482 break getTag;
17483
17484 case REACT_FORWARD_REF_TYPE:
17485 fiberTag = ForwardRef;
17486
17487 {
17488 resolvedType = resolveForwardRefForHotReloading(resolvedType);
17489 }
17490
17491 break getTag;
17492
17493 case REACT_MEMO_TYPE:
17494 fiberTag = MemoComponent;
17495 break getTag;
17496
17497 case REACT_LAZY_TYPE:
17498 fiberTag = LazyComponent;
17499 resolvedType = null;
17500 break getTag;
17501 }
17502 }
17503
17504 var info = '';
17505
17506 {
17507 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
17508 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.';
17509 }
17510
17511 var ownerName = owner ? getComponentNameFromFiber(owner) : null;
17512
17513 if (ownerName) {
17514 info += '\n\nCheck the render method of `' + ownerName + '`.';
17515 }
17516 }
17517
17518 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));
17519 }
17520 }
17521 }
17522
17523 var fiber = createFiber(fiberTag, pendingProps, key, mode);
17524 fiber.elementType = type;
17525 fiber.type = resolvedType;
17526 fiber.lanes = lanes;
17527
17528 {
17529 fiber._debugOwner = owner;
17530 }
17531
17532 return fiber;
17533}
17534function createFiberFromElement(element, mode, lanes) {
17535 var owner = null;
17536
17537 {
17538 owner = element._owner;
17539 }
17540
17541 var type = element.type;
17542 var key = element.key;
17543 var pendingProps = element.props;
17544 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, lanes);
17545
17546 {
17547 fiber._debugSource = element._source;
17548 fiber._debugOwner = element._owner;
17549 }
17550
17551 return fiber;
17552}
17553function createFiberFromFragment(elements, mode, lanes, key) {
17554 var fiber = createFiber(Fragment, elements, key, mode);
17555 fiber.lanes = lanes;
17556 return fiber;
17557}
17558
17559function createFiberFromProfiler(pendingProps, mode, lanes, key) {
17560 {
17561 if (typeof pendingProps.id !== 'string') {
17562 error('Profiler must specify an "id" of type `string` as a prop. Received the type `%s` instead.', typeof pendingProps.id);
17563 }
17564 }
17565
17566 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
17567 fiber.elementType = REACT_PROFILER_TYPE;
17568 fiber.lanes = lanes;
17569
17570 {
17571 fiber.stateNode = {
17572 effectDuration: 0,
17573 passiveEffectDuration: 0
17574 };
17575 }
17576
17577 return fiber;
17578}
17579
17580function createFiberFromSuspense(pendingProps, mode, lanes, key) {
17581 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
17582 fiber.elementType = REACT_SUSPENSE_TYPE;
17583 fiber.lanes = lanes;
17584 return fiber;
17585}
17586function createFiberFromSuspenseList(pendingProps, mode, lanes, key) {
17587 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
17588 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
17589 fiber.lanes = lanes;
17590 return fiber;
17591}
17592function createFiberFromOffscreen(pendingProps, mode, lanes, key) {
17593 var fiber = createFiber(OffscreenComponent, pendingProps, key, mode);
17594 fiber.elementType = REACT_OFFSCREEN_TYPE;
17595 fiber.lanes = lanes;
17596 var primaryChildInstance = {
17597 isHidden: false
17598 };
17599 fiber.stateNode = primaryChildInstance;
17600 return fiber;
17601}
17602function createFiberFromText(content, mode, lanes) {
17603 var fiber = createFiber(HostText, content, null, mode);
17604 fiber.lanes = lanes;
17605 return fiber;
17606}
17607function createFiberFromPortal(portal, mode, lanes) {
17608 var pendingProps = portal.children !== null ? portal.children : [];
17609 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
17610 fiber.lanes = lanes;
17611 fiber.stateNode = {
17612 containerInfo: portal.containerInfo,
17613 pendingChildren: null,
17614 // Used by persistent updates
17615 implementation: portal.implementation
17616 };
17617 return fiber;
17618} // Used for stashing WIP properties to replay failed work in DEV.
17619
17620function FiberRootNode(containerInfo, tag, hydrate, identifierPrefix, onRecoverableError) {
17621 this.tag = tag;
17622 this.containerInfo = containerInfo;
17623 this.pendingChildren = null;
17624 this.current = null;
17625 this.pingCache = null;
17626 this.finishedWork = null;
17627 this.timeoutHandle = noTimeout;
17628 this.context = null;
17629 this.pendingContext = null;
17630 this.callbackNode = null;
17631 this.callbackPriority = NoLane;
17632 this.eventTimes = createLaneMap(NoLanes);
17633 this.expirationTimes = createLaneMap(NoTimestamp);
17634 this.pendingLanes = NoLanes;
17635 this.suspendedLanes = NoLanes;
17636 this.pingedLanes = NoLanes;
17637 this.expiredLanes = NoLanes;
17638 this.mutableReadLanes = NoLanes;
17639 this.finishedLanes = NoLanes;
17640 this.entangledLanes = NoLanes;
17641 this.entanglements = createLaneMap(NoLanes);
17642 this.identifierPrefix = identifierPrefix;
17643 this.onRecoverableError = onRecoverableError;
17644
17645 {
17646 this.effectDuration = 0;
17647 this.passiveEffectDuration = 0;
17648 }
17649
17650 {
17651 switch (tag) {
17652 case ConcurrentRoot:
17653 this._debugRootType = hydrate ? 'hydrateRoot()' : 'createRoot()';
17654 break;
17655
17656 case LegacyRoot:
17657 this._debugRootType = hydrate ? 'hydrate()' : 'render()';
17658 break;
17659 }
17660 }
17661}
17662
17663function createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, // TODO: We have several of these arguments that are conceptually part of the
17664// host config, but because they are passed in at runtime, we have to thread
17665// them through the root constructor. Perhaps we should put them all into a
17666// single type, like a DynamicHostConfig that is defined by the renderer.
17667identifierPrefix, onRecoverableError, transitionCallbacks) {
17668 var root = new FiberRootNode(containerInfo, tag, hydrate, identifierPrefix, onRecoverableError);
17669 // stateNode is any.
17670
17671
17672 var uninitializedFiber = createHostRootFiber(tag, isStrictMode);
17673 root.current = uninitializedFiber;
17674 uninitializedFiber.stateNode = root;
17675
17676 {
17677 var _initialState = {
17678 element: initialChildren,
17679 isDehydrated: hydrate,
17680 cache: null,
17681 // not enabled yet
17682 transitions: null,
17683 pendingSuspenseBoundaries: null
17684 };
17685 uninitializedFiber.memoizedState = _initialState;
17686 }
17687
17688 initializeUpdateQueue(uninitializedFiber);
17689 return root;
17690}
17691
17692var ReactVersion = '18.2.0';
17693
17694var didWarnAboutNestedUpdates;
17695
17696{
17697 didWarnAboutNestedUpdates = false;
17698}
17699
17700function getContextForSubtree(parentComponent) {
17701 if (!parentComponent) {
17702 return emptyContextObject;
17703 }
17704
17705 var fiber = get(parentComponent);
17706 var parentContext = findCurrentUnmaskedContext(fiber);
17707
17708 if (fiber.tag === ClassComponent) {
17709 var Component = fiber.type;
17710
17711 if (isContextProvider(Component)) {
17712 return processChildContext(fiber, Component, parentContext);
17713 }
17714 }
17715
17716 return parentContext;
17717}
17718
17719function createContainer(containerInfo, tag, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError, transitionCallbacks) {
17720 var hydrate = false;
17721 var initialChildren = null;
17722 return createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError);
17723}
17724function updateContainer(element, container, parentComponent, callback) {
17725 {
17726 onScheduleRoot(container, element);
17727 }
17728
17729 var current$1 = container.current;
17730 var eventTime = requestEventTime();
17731 var lane = requestUpdateLane(current$1);
17732
17733 var context = getContextForSubtree(parentComponent);
17734
17735 if (container.context === null) {
17736 container.context = context;
17737 } else {
17738 container.pendingContext = context;
17739 }
17740
17741 {
17742 if (isRendering && current !== null && !didWarnAboutNestedUpdates) {
17743 didWarnAboutNestedUpdates = true;
17744
17745 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');
17746 }
17747 }
17748
17749 var update = createUpdate(eventTime, lane); // Caution: React DevTools currently depends on this property
17750 // being called "element".
17751
17752 update.payload = {
17753 element: element
17754 };
17755 callback = callback === undefined ? null : callback;
17756
17757 if (callback !== null) {
17758 {
17759 if (typeof callback !== 'function') {
17760 error('render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
17761 }
17762 }
17763
17764 update.callback = callback;
17765 }
17766
17767 var root = enqueueUpdate(current$1, update, lane);
17768
17769 if (root !== null) {
17770 scheduleUpdateOnFiber(root, current$1, lane, eventTime);
17771 entangleTransitions(root, current$1, lane);
17772 }
17773
17774 return lane;
17775}
17776function getPublicRootInstance(container) {
17777 var containerFiber = container.current;
17778
17779 if (!containerFiber.child) {
17780 return null;
17781 }
17782
17783 switch (containerFiber.child.tag) {
17784 case HostComponent:
17785 return getPublicInstance(containerFiber.child.stateNode);
17786
17787 default:
17788 return containerFiber.child.stateNode;
17789 }
17790}
17791
17792var shouldErrorImpl = function (fiber) {
17793 return null;
17794};
17795
17796function shouldError(fiber) {
17797 return shouldErrorImpl(fiber);
17798}
17799
17800var shouldSuspendImpl = function (fiber) {
17801 return false;
17802};
17803
17804function shouldSuspend(fiber) {
17805 return shouldSuspendImpl(fiber);
17806}
17807var overrideHookState = null;
17808var overrideHookStateDeletePath = null;
17809var overrideHookStateRenamePath = null;
17810var overrideProps = null;
17811var overridePropsDeletePath = null;
17812var overridePropsRenamePath = null;
17813var scheduleUpdate = null;
17814var setErrorHandler = null;
17815var setSuspenseHandler = null;
17816
17817{
17818 var copyWithDeleteImpl = function (obj, path, index) {
17819 var key = path[index];
17820 var updated = isArray(obj) ? obj.slice() : assign({}, obj);
17821
17822 if (index + 1 === path.length) {
17823 if (isArray(updated)) {
17824 updated.splice(key, 1);
17825 } else {
17826 delete updated[key];
17827 }
17828
17829 return updated;
17830 } // $FlowFixMe number or string is fine here
17831
17832
17833 updated[key] = copyWithDeleteImpl(obj[key], path, index + 1);
17834 return updated;
17835 };
17836
17837 var copyWithDelete = function (obj, path) {
17838 return copyWithDeleteImpl(obj, path, 0);
17839 };
17840
17841 var copyWithRenameImpl = function (obj, oldPath, newPath, index) {
17842 var oldKey = oldPath[index];
17843 var updated = isArray(obj) ? obj.slice() : assign({}, obj);
17844
17845 if (index + 1 === oldPath.length) {
17846 var newKey = newPath[index]; // $FlowFixMe number or string is fine here
17847
17848 updated[newKey] = updated[oldKey];
17849
17850 if (isArray(updated)) {
17851 updated.splice(oldKey, 1);
17852 } else {
17853 delete updated[oldKey];
17854 }
17855 } else {
17856 // $FlowFixMe number or string is fine here
17857 updated[oldKey] = copyWithRenameImpl( // $FlowFixMe number or string is fine here
17858 obj[oldKey], oldPath, newPath, index + 1);
17859 }
17860
17861 return updated;
17862 };
17863
17864 var copyWithRename = function (obj, oldPath, newPath) {
17865 if (oldPath.length !== newPath.length) {
17866 warn('copyWithRename() expects paths of the same length');
17867
17868 return;
17869 } else {
17870 for (var i = 0; i < newPath.length - 1; i++) {
17871 if (oldPath[i] !== newPath[i]) {
17872 warn('copyWithRename() expects paths to be the same except for the deepest key');
17873
17874 return;
17875 }
17876 }
17877 }
17878
17879 return copyWithRenameImpl(obj, oldPath, newPath, 0);
17880 };
17881
17882 var copyWithSetImpl = function (obj, path, index, value) {
17883 if (index >= path.length) {
17884 return value;
17885 }
17886
17887 var key = path[index];
17888 var updated = isArray(obj) ? obj.slice() : assign({}, obj); // $FlowFixMe number or string is fine here
17889
17890 updated[key] = copyWithSetImpl(obj[key], path, index + 1, value);
17891 return updated;
17892 };
17893
17894 var copyWithSet = function (obj, path, value) {
17895 return copyWithSetImpl(obj, path, 0, value);
17896 };
17897
17898 var findHook = function (fiber, id) {
17899 // For now, the "id" of stateful hooks is just the stateful hook index.
17900 // This may change in the future with e.g. nested hooks.
17901 var currentHook = fiber.memoizedState;
17902
17903 while (currentHook !== null && id > 0) {
17904 currentHook = currentHook.next;
17905 id--;
17906 }
17907
17908 return currentHook;
17909 }; // Support DevTools editable values for useState and useReducer.
17910
17911
17912 overrideHookState = function (fiber, id, path, value) {
17913 var hook = findHook(fiber, id);
17914
17915 if (hook !== null) {
17916 var newState = copyWithSet(hook.memoizedState, path, value);
17917 hook.memoizedState = newState;
17918 hook.baseState = newState; // We aren't actually adding an update to the queue,
17919 // because there is no update we can add for useReducer hooks that won't trigger an error.
17920 // (There's no appropriate action type for DevTools overrides.)
17921 // As a result though, React will see the scheduled update as a noop and bailout.
17922 // Shallow cloning props works as a workaround for now to bypass the bailout check.
17923
17924 fiber.memoizedProps = assign({}, fiber.memoizedProps);
17925 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
17926
17927 if (root !== null) {
17928 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
17929 }
17930 }
17931 };
17932
17933 overrideHookStateDeletePath = function (fiber, id, path) {
17934 var hook = findHook(fiber, id);
17935
17936 if (hook !== null) {
17937 var newState = copyWithDelete(hook.memoizedState, path);
17938 hook.memoizedState = newState;
17939 hook.baseState = newState; // We aren't actually adding an update to the queue,
17940 // because there is no update we can add for useReducer hooks that won't trigger an error.
17941 // (There's no appropriate action type for DevTools overrides.)
17942 // As a result though, React will see the scheduled update as a noop and bailout.
17943 // Shallow cloning props works as a workaround for now to bypass the bailout check.
17944
17945 fiber.memoizedProps = assign({}, fiber.memoizedProps);
17946 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
17947
17948 if (root !== null) {
17949 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
17950 }
17951 }
17952 };
17953
17954 overrideHookStateRenamePath = function (fiber, id, oldPath, newPath) {
17955 var hook = findHook(fiber, id);
17956
17957 if (hook !== null) {
17958 var newState = copyWithRename(hook.memoizedState, oldPath, newPath);
17959 hook.memoizedState = newState;
17960 hook.baseState = newState; // We aren't actually adding an update to the queue,
17961 // because there is no update we can add for useReducer hooks that won't trigger an error.
17962 // (There's no appropriate action type for DevTools overrides.)
17963 // As a result though, React will see the scheduled update as a noop and bailout.
17964 // Shallow cloning props works as a workaround for now to bypass the bailout check.
17965
17966 fiber.memoizedProps = assign({}, fiber.memoizedProps);
17967 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
17968
17969 if (root !== null) {
17970 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
17971 }
17972 }
17973 }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
17974
17975
17976 overrideProps = function (fiber, path, value) {
17977 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
17978
17979 if (fiber.alternate) {
17980 fiber.alternate.pendingProps = fiber.pendingProps;
17981 }
17982
17983 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
17984
17985 if (root !== null) {
17986 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
17987 }
17988 };
17989
17990 overridePropsDeletePath = function (fiber, path) {
17991 fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path);
17992
17993 if (fiber.alternate) {
17994 fiber.alternate.pendingProps = fiber.pendingProps;
17995 }
17996
17997 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
17998
17999 if (root !== null) {
18000 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
18001 }
18002 };
18003
18004 overridePropsRenamePath = function (fiber, oldPath, newPath) {
18005 fiber.pendingProps = copyWithRename(fiber.memoizedProps, oldPath, newPath);
18006
18007 if (fiber.alternate) {
18008 fiber.alternate.pendingProps = fiber.pendingProps;
18009 }
18010
18011 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
18012
18013 if (root !== null) {
18014 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
18015 }
18016 };
18017
18018 scheduleUpdate = function (fiber) {
18019 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
18020
18021 if (root !== null) {
18022 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
18023 }
18024 };
18025
18026 setErrorHandler = function (newShouldErrorImpl) {
18027 shouldErrorImpl = newShouldErrorImpl;
18028 };
18029
18030 setSuspenseHandler = function (newShouldSuspendImpl) {
18031 shouldSuspendImpl = newShouldSuspendImpl;
18032 };
18033}
18034
18035function findHostInstanceByFiber(fiber) {
18036 var hostFiber = findCurrentHostFiber(fiber);
18037
18038 if (hostFiber === null) {
18039 return null;
18040 }
18041
18042 return hostFiber.stateNode;
18043}
18044
18045function emptyFindFiberByHostInstance(instance) {
18046 return null;
18047}
18048
18049function getCurrentFiberForDevTools() {
18050 return current;
18051}
18052
18053function injectIntoDevTools(devToolsConfig) {
18054 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
18055 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
18056 return injectInternals({
18057 bundleType: devToolsConfig.bundleType,
18058 version: devToolsConfig.version,
18059 rendererPackageName: devToolsConfig.rendererPackageName,
18060 rendererConfig: devToolsConfig.rendererConfig,
18061 overrideHookState: overrideHookState,
18062 overrideHookStateDeletePath: overrideHookStateDeletePath,
18063 overrideHookStateRenamePath: overrideHookStateRenamePath,
18064 overrideProps: overrideProps,
18065 overridePropsDeletePath: overridePropsDeletePath,
18066 overridePropsRenamePath: overridePropsRenamePath,
18067 setErrorHandler: setErrorHandler,
18068 setSuspenseHandler: setSuspenseHandler,
18069 scheduleUpdate: scheduleUpdate,
18070 currentDispatcherRef: ReactCurrentDispatcher,
18071 findHostInstanceByFiber: findHostInstanceByFiber,
18072 findFiberByHostInstance: findFiberByHostInstance || emptyFindFiberByHostInstance,
18073 // React Refresh
18074 findHostInstancesForRefresh: findHostInstancesForRefresh ,
18075 scheduleRefresh: scheduleRefresh ,
18076 scheduleRoot: scheduleRoot ,
18077 setRefreshHandler: setRefreshHandler ,
18078 // Enables DevTools to append owner stacks to error messages in DEV mode.
18079 getCurrentFiber: getCurrentFiberForDevTools ,
18080 // Enables DevTools to detect reconciler version rather than renderer version
18081 // which may not match for third party renderers.
18082 reconcilerVersion: ReactVersion
18083 });
18084}
18085
18086var act = React.unstable_act; // TODO: Remove from public bundle
18087
18088var defaultTestOptions = {
18089 createNodeMock: function () {
18090 return null;
18091 }
18092};
18093
18094function toJSON(inst) {
18095 if (inst.isHidden) {
18096 // Omit timed out children from output entirely. This seems like the least
18097 // surprising behavior. We could perhaps add a separate API that includes
18098 // them, if it turns out people need it.
18099 return null;
18100 }
18101
18102 switch (inst.tag) {
18103 case 'TEXT':
18104 return inst.text;
18105
18106 case 'INSTANCE':
18107 {
18108 /* eslint-disable no-unused-vars */
18109 // We don't include the `children` prop in JSON.
18110 // Instead, we will include the actual rendered children.
18111 var _inst$props = inst.props,
18112 children = _inst$props.children,
18113 props = _objectWithoutPropertiesLoose(_inst$props, ["children"]);
18114 /* eslint-enable */
18115
18116
18117 var renderedChildren = null;
18118
18119 if (inst.children && inst.children.length) {
18120 for (var i = 0; i < inst.children.length; i++) {
18121 var renderedChild = toJSON(inst.children[i]);
18122
18123 if (renderedChild !== null) {
18124 if (renderedChildren === null) {
18125 renderedChildren = [renderedChild];
18126 } else {
18127 renderedChildren.push(renderedChild);
18128 }
18129 }
18130 }
18131 }
18132
18133 var json = {
18134 type: inst.type,
18135 props: props,
18136 children: renderedChildren
18137 };
18138 Object.defineProperty(json, '$$typeof', {
18139 value: Symbol.for('react.test.json')
18140 });
18141 return json;
18142 }
18143
18144 default:
18145 throw new Error("Unexpected node type in toJSON: " + inst.tag);
18146 }
18147}
18148
18149function childrenToTree(node) {
18150 if (!node) {
18151 return null;
18152 }
18153
18154 var children = nodeAndSiblingsArray(node);
18155
18156 if (children.length === 0) {
18157 return null;
18158 } else if (children.length === 1) {
18159 return toTree(children[0]);
18160 }
18161
18162 return flatten(children.map(toTree));
18163}
18164
18165function nodeAndSiblingsArray(nodeWithSibling) {
18166 var array = [];
18167 var node = nodeWithSibling;
18168
18169 while (node != null) {
18170 array.push(node);
18171 node = node.sibling;
18172 }
18173
18174 return array;
18175}
18176
18177function flatten(arr) {
18178 var result = [];
18179 var stack = [{
18180 i: 0,
18181 array: arr
18182 }];
18183
18184 while (stack.length) {
18185 var n = stack.pop();
18186
18187 while (n.i < n.array.length) {
18188 var el = n.array[n.i];
18189 n.i += 1;
18190
18191 if (isArray(el)) {
18192 stack.push(n);
18193 stack.push({
18194 i: 0,
18195 array: el
18196 });
18197 break;
18198 }
18199
18200 result.push(el);
18201 }
18202 }
18203
18204 return result;
18205}
18206
18207function toTree(node) {
18208 if (node == null) {
18209 return null;
18210 }
18211
18212 switch (node.tag) {
18213 case HostRoot:
18214 return childrenToTree(node.child);
18215
18216 case HostPortal:
18217 return childrenToTree(node.child);
18218
18219 case ClassComponent:
18220 return {
18221 nodeType: 'component',
18222 type: node.type,
18223 props: assign({}, node.memoizedProps),
18224 instance: node.stateNode,
18225 rendered: childrenToTree(node.child)
18226 };
18227
18228 case FunctionComponent:
18229 case SimpleMemoComponent:
18230 return {
18231 nodeType: 'component',
18232 type: node.type,
18233 props: assign({}, node.memoizedProps),
18234 instance: null,
18235 rendered: childrenToTree(node.child)
18236 };
18237
18238 case HostComponent:
18239 {
18240 return {
18241 nodeType: 'host',
18242 type: node.type,
18243 props: assign({}, node.memoizedProps),
18244 instance: null,
18245 // TODO: use createNodeMock here somehow?
18246 rendered: flatten(nodeAndSiblingsArray(node.child).map(toTree))
18247 };
18248 }
18249
18250 case HostText:
18251 return node.stateNode.text;
18252
18253 case Fragment:
18254 case ContextProvider:
18255 case ContextConsumer:
18256 case Mode:
18257 case Profiler:
18258 case ForwardRef:
18259 case MemoComponent:
18260 case IncompleteClassComponent:
18261 case ScopeComponent:
18262 return childrenToTree(node.child);
18263
18264 default:
18265 throw new Error("toTree() does not yet know how to handle nodes with tag=" + node.tag);
18266 }
18267}
18268
18269var validWrapperTypes = new Set([FunctionComponent, ClassComponent, HostComponent, ForwardRef, MemoComponent, SimpleMemoComponent, // Normally skipped, but used when there's more than one root child.
18270HostRoot]);
18271
18272function getChildren(parent) {
18273 var children = [];
18274 var startingNode = parent;
18275 var node = startingNode;
18276
18277 if (node.child === null) {
18278 return children;
18279 }
18280
18281 node.child.return = node;
18282 node = node.child;
18283
18284 outer: while (true) {
18285 var descend = false;
18286
18287 if (validWrapperTypes.has(node.tag)) {
18288 children.push(wrapFiber(node));
18289 } else if (node.tag === HostText) {
18290 {
18291 checkPropStringCoercion(node.memoizedProps, 'memoizedProps');
18292 }
18293
18294 children.push('' + node.memoizedProps);
18295 } else {
18296 descend = true;
18297 }
18298
18299 if (descend && node.child !== null) {
18300 node.child.return = node;
18301 node = node.child;
18302 continue;
18303 }
18304
18305 while (node.sibling === null) {
18306 if (node.return === startingNode) {
18307 break outer;
18308 }
18309
18310 node = node.return;
18311 }
18312
18313 node.sibling.return = node.return;
18314 node = node.sibling;
18315 }
18316
18317 return children;
18318}
18319
18320var ReactTestInstance = /*#__PURE__*/function () {
18321 var _proto = ReactTestInstance.prototype;
18322
18323 _proto._currentFiber = function _currentFiber() {
18324 // Throws if this component has been unmounted.
18325 var fiber = findCurrentFiberUsingSlowPath(this._fiber);
18326
18327 if (fiber === null) {
18328 throw new Error("Can't read from currently-mounting component. This error is likely " + 'caused by a bug in React. Please file an issue.');
18329 }
18330
18331 return fiber;
18332 };
18333
18334 function ReactTestInstance(fiber) {
18335 if (!validWrapperTypes.has(fiber.tag)) {
18336 throw new Error("Unexpected object passed to ReactTestInstance constructor (tag: " + fiber.tag + "). " + 'This is probably a bug in React.');
18337 }
18338
18339 this._fiber = fiber;
18340 }
18341
18342 // Custom search functions
18343 _proto.find = function find(predicate) {
18344 return expectOne(this.findAll(predicate, {
18345 deep: false
18346 }), "matching custom predicate: " + predicate.toString());
18347 };
18348
18349 _proto.findByType = function findByType(type) {
18350 return expectOne(this.findAllByType(type, {
18351 deep: false
18352 }), "with node type: \"" + (getComponentNameFromType(type) || 'Unknown') + "\"");
18353 };
18354
18355 _proto.findByProps = function findByProps(props) {
18356 return expectOne(this.findAllByProps(props, {
18357 deep: false
18358 }), "with props: " + JSON.stringify(props));
18359 };
18360
18361 _proto.findAll = function findAll(predicate) {
18362 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
18363 return _findAll(this, predicate, options);
18364 };
18365
18366 _proto.findAllByType = function findAllByType(type) {
18367 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
18368 return _findAll(this, function (node) {
18369 return node.type === type;
18370 }, options);
18371 };
18372
18373 _proto.findAllByProps = function findAllByProps(props) {
18374 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
18375 return _findAll(this, function (node) {
18376 return node.props && propsMatch(node.props, props);
18377 }, options);
18378 };
18379
18380 _createClass(ReactTestInstance, [{
18381 key: "instance",
18382 get: function () {
18383 if (this._fiber.tag === HostComponent) {
18384 return getPublicInstance(this._fiber.stateNode);
18385 } else {
18386 return this._fiber.stateNode;
18387 }
18388 }
18389 }, {
18390 key: "type",
18391 get: function () {
18392 return this._fiber.type;
18393 }
18394 }, {
18395 key: "props",
18396 get: function () {
18397 return this._currentFiber().memoizedProps;
18398 }
18399 }, {
18400 key: "parent",
18401 get: function () {
18402 var parent = this._fiber.return;
18403
18404 while (parent !== null) {
18405 if (validWrapperTypes.has(parent.tag)) {
18406 if (parent.tag === HostRoot) {
18407 // Special case: we only "materialize" instances for roots
18408 // if they have more than a single child. So we'll check that now.
18409 if (getChildren(parent).length < 2) {
18410 return null;
18411 }
18412 }
18413
18414 return wrapFiber(parent);
18415 }
18416
18417 parent = parent.return;
18418 }
18419
18420 return null;
18421 }
18422 }, {
18423 key: "children",
18424 get: function () {
18425 return getChildren(this._currentFiber());
18426 }
18427 }]);
18428
18429 return ReactTestInstance;
18430}();
18431
18432function _findAll(root, predicate, options) {
18433 var deep = options ? options.deep : true;
18434 var results = [];
18435
18436 if (predicate(root)) {
18437 results.push(root);
18438
18439 if (!deep) {
18440 return results;
18441 }
18442 }
18443
18444 root.children.forEach(function (child) {
18445 if (typeof child === 'string') {
18446 return;
18447 }
18448
18449 results.push.apply(results, _findAll(child, predicate, options));
18450 });
18451 return results;
18452}
18453
18454function expectOne(all, message) {
18455 if (all.length === 1) {
18456 return all[0];
18457 }
18458
18459 var prefix = all.length === 0 ? 'No instances found ' : "Expected 1 but found " + all.length + " instances ";
18460 throw new Error(prefix + message);
18461}
18462
18463function propsMatch(props, filter) {
18464 for (var key in filter) {
18465 if (props[key] !== filter[key]) {
18466 return false;
18467 }
18468 }
18469
18470 return true;
18471}
18472
18473function onRecoverableError(error$1) {
18474 // TODO: Expose onRecoverableError option to userspace
18475 // eslint-disable-next-line react-internal/no-production-logging, react-internal/warning-args
18476 error(error$1);
18477}
18478
18479function create(element, options) {
18480 var createNodeMock = defaultTestOptions.createNodeMock;
18481 var isConcurrent = false;
18482 var isStrictMode = false;
18483 var concurrentUpdatesByDefault = null;
18484
18485 if (typeof options === 'object' && options !== null) {
18486 if (typeof options.createNodeMock === 'function') {
18487 createNodeMock = options.createNodeMock;
18488 }
18489
18490 if (options.unstable_isConcurrent === true) {
18491 isConcurrent = true;
18492 }
18493
18494 if (options.unstable_strictMode === true) {
18495 isStrictMode = true;
18496 }
18497 }
18498
18499 var container = {
18500 children: [],
18501 createNodeMock: createNodeMock,
18502 tag: 'CONTAINER'
18503 };
18504 var root = createContainer(container, isConcurrent ? ConcurrentRoot : LegacyRoot, null, isStrictMode, concurrentUpdatesByDefault, '', onRecoverableError);
18505
18506 if (root == null) {
18507 throw new Error('something went wrong');
18508 }
18509
18510 updateContainer(element, root, null, null);
18511 var entry = {
18512 _Scheduler: Scheduler,
18513 root: undefined,
18514 // makes flow happy
18515 // we define a 'getter' for 'root' below using 'Object.defineProperty'
18516 toJSON: function () {
18517 if (root == null || root.current == null || container == null) {
18518 return null;
18519 }
18520
18521 if (container.children.length === 0) {
18522 return null;
18523 }
18524
18525 if (container.children.length === 1) {
18526 return toJSON(container.children[0]);
18527 }
18528
18529 if (container.children.length === 2 && container.children[0].isHidden === true && container.children[1].isHidden === false) {
18530 // Omit timed out children from output entirely, including the fact that we
18531 // temporarily wrap fallback and timed out children in an array.
18532 return toJSON(container.children[1]);
18533 }
18534
18535 var renderedChildren = null;
18536
18537 if (container.children && container.children.length) {
18538 for (var i = 0; i < container.children.length; i++) {
18539 var renderedChild = toJSON(container.children[i]);
18540
18541 if (renderedChild !== null) {
18542 if (renderedChildren === null) {
18543 renderedChildren = [renderedChild];
18544 } else {
18545 renderedChildren.push(renderedChild);
18546 }
18547 }
18548 }
18549 }
18550
18551 return renderedChildren;
18552 },
18553 toTree: function () {
18554 if (root == null || root.current == null) {
18555 return null;
18556 }
18557
18558 return toTree(root.current);
18559 },
18560 update: function (newElement) {
18561 if (root == null || root.current == null) {
18562 return;
18563 }
18564
18565 updateContainer(newElement, root, null, null);
18566 },
18567 unmount: function () {
18568 if (root == null || root.current == null) {
18569 return;
18570 }
18571
18572 updateContainer(null, root, null, null);
18573 container = null;
18574 root = null;
18575 },
18576 getInstance: function () {
18577 if (root == null || root.current == null) {
18578 return null;
18579 }
18580
18581 return getPublicRootInstance(root);
18582 },
18583 unstable_flushSync: flushSync
18584 };
18585 Object.defineProperty(entry, 'root', {
18586 configurable: true,
18587 enumerable: true,
18588 get: function () {
18589 if (root === null) {
18590 throw new Error("Can't access .root on unmounted test renderer");
18591 }
18592
18593 var children = getChildren(root.current);
18594
18595 if (children.length === 0) {
18596 throw new Error("Can't access .root on unmounted test renderer");
18597 } else if (children.length === 1) {
18598 // Normally, we skip the root and just give you the child.
18599 return children[0];
18600 } else {
18601 // However, we give you the root if there's more than one root child.
18602 // We could make this the behavior for all cases but it would be a breaking change.
18603 return wrapFiber(root.current);
18604 }
18605 }
18606 });
18607 return entry;
18608}
18609
18610var fiberToWrapper = new WeakMap();
18611
18612function wrapFiber(fiber) {
18613 var wrapper = fiberToWrapper.get(fiber);
18614
18615 if (wrapper === undefined && fiber.alternate !== null) {
18616 wrapper = fiberToWrapper.get(fiber.alternate);
18617 }
18618
18619 if (wrapper === undefined) {
18620 wrapper = new ReactTestInstance(fiber);
18621 fiberToWrapper.set(fiber, wrapper);
18622 }
18623
18624 return wrapper;
18625} // Enable ReactTestRenderer to be used to test DevTools integration.
18626
18627
18628injectIntoDevTools({
18629 findFiberByHostInstance: function () {
18630 throw new Error('TestRenderer does not support findFiberByHostInstance()');
18631 },
18632 bundleType: 1 ,
18633 version: ReactVersion,
18634 rendererPackageName: 'react-test-renderer'
18635});
18636
18637exports._Scheduler = Scheduler;
18638exports.act = act;
18639exports.create = create;
18640exports.unstable_batchedUpdates = batchedUpdates;
18641 })();
18642}