UNPKG

538 kBJavaScriptView Raw
1/** @license React v16.13.1
2 * react-test-renderer.development.js
3 *
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10'use strict';
11
12
13
14if (process.env.NODE_ENV !== "production") {
15 (function() {
16'use strict';
17
18var _assign = require('object-assign');
19var Scheduler = require('scheduler/unstable_mock');
20var React = require('react');
21var checkPropTypes = require('prop-types/checkPropTypes');
22var Scheduler$1 = require('scheduler');
23var tracing = require('scheduler/tracing');
24
25function _defineProperties(target, props) {
26 for (var i = 0; i < props.length; i++) {
27 var descriptor = props[i];
28 descriptor.enumerable = descriptor.enumerable || false;
29 descriptor.configurable = true;
30 if ("value" in descriptor) descriptor.writable = true;
31 Object.defineProperty(target, descriptor.key, descriptor);
32 }
33}
34
35function _createClass(Constructor, protoProps, staticProps) {
36 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
37 if (staticProps) _defineProperties(Constructor, staticProps);
38 return Constructor;
39}
40
41function _objectWithoutPropertiesLoose(source, excluded) {
42 if (source == null) return {};
43 var target = {};
44 var sourceKeys = Object.keys(source);
45 var key, i;
46
47 for (i = 0; i < sourceKeys.length; i++) {
48 key = sourceKeys[i];
49 if (excluded.indexOf(key) >= 0) continue;
50 target[key] = source[key];
51 }
52
53 return target;
54}
55
56var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions.
57// Current owner and dispatcher used to share the same ref,
58// but PR #14548 split them out to better support the react-debug-tools package.
59
60if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
61 ReactSharedInternals.ReactCurrentDispatcher = {
62 current: null
63 };
64}
65
66if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {
67 ReactSharedInternals.ReactCurrentBatchConfig = {
68 suspense: null
69 };
70}
71
72// by calls to these methods by a Babel plugin.
73//
74// In PROD (or in packages without access to React internals),
75// they are left as they are instead.
76
77function warn(format) {
78 {
79 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
80 args[_key - 1] = arguments[_key];
81 }
82
83 printWarning('warn', format, args);
84 }
85}
86function error(format) {
87 {
88 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
89 args[_key2 - 1] = arguments[_key2];
90 }
91
92 printWarning('error', format, args);
93 }
94}
95
96function printWarning(level, format, args) {
97 // When changing this logic, you might want to also
98 // update consoleWithStackDev.www.js as well.
99 {
100 var hasExistingStack = args.length > 0 && typeof args[args.length - 1] === 'string' && args[args.length - 1].indexOf('\n in') === 0;
101
102 if (!hasExistingStack) {
103 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
104 var stack = ReactDebugCurrentFrame.getStackAddendum();
105
106 if (stack !== '') {
107 format += '%s';
108 args = args.concat([stack]);
109 }
110 }
111
112 var argsWithFormat = args.map(function (item) {
113 return '' + item;
114 }); // Careful: RN currently depends on this prefix
115
116 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
117 // breaks IE9: https://github.com/facebook/react/issues/13610
118 // eslint-disable-next-line react-internal/no-production-logging
119
120 Function.prototype.apply.call(console[level], console, argsWithFormat);
121
122 try {
123 // --- Welcome to debugging React ---
124 // This error was thrown as a convenience so that you can use this stack
125 // to find the callsite that caused this warning to fire.
126 var argIndex = 0;
127 var message = 'Warning: ' + format.replace(/%s/g, function () {
128 return args[argIndex++];
129 });
130 throw new Error(message);
131 } catch (x) {}
132 }
133}
134
135var FunctionComponent = 0;
136var ClassComponent = 1;
137var IndeterminateComponent = 2; // Before we know whether it is function or class
138
139var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
140
141var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
142
143var HostComponent = 5;
144var HostText = 6;
145var Fragment = 7;
146var Mode = 8;
147var ContextConsumer = 9;
148var ContextProvider = 10;
149var ForwardRef = 11;
150var Profiler = 12;
151var SuspenseComponent = 13;
152var MemoComponent = 14;
153var SimpleMemoComponent = 15;
154var LazyComponent = 16;
155var IncompleteClassComponent = 17;
156var DehydratedFragment = 18;
157var SuspenseListComponent = 19;
158var FundamentalComponent = 20;
159var ScopeComponent = 21;
160var Block = 22;
161
162/**
163 * `ReactInstanceMap` maintains a mapping from a public facing stateful
164 * instance (key) and the internal representation (value). This allows public
165 * methods to accept the user facing instance as an argument and map them back
166 * to internal methods.
167 *
168 * Note that this module is currently shared and assumed to be stateless.
169 * If this becomes an actual Map, that will break.
170 */
171function get(key) {
172 return key._reactInternalFiber;
173}
174function set(key, value) {
175 key._reactInternalFiber = value;
176}
177
178// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
179// nor polyfill, then a plain number is used for performance.
180var hasSymbol = typeof Symbol === 'function' && Symbol.for;
181var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
182var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
183var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
184var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
185var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
186var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
187var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
188var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
189var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
190var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
191var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
192var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
193var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
194var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for('react.block') : 0xead9;
195var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
196var FAUX_ITERATOR_SYMBOL = '@@iterator';
197function getIteratorFn(maybeIterable) {
198 if (maybeIterable === null || typeof maybeIterable !== 'object') {
199 return null;
200 }
201
202 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
203
204 if (typeof maybeIterator === 'function') {
205 return maybeIterator;
206 }
207
208 return null;
209}
210
211var Uninitialized = -1;
212var Pending = 0;
213var Resolved = 1;
214var Rejected = 2;
215function refineResolvedLazyComponent(lazyComponent) {
216 return lazyComponent._status === Resolved ? lazyComponent._result : null;
217}
218function initializeLazyComponentType(lazyComponent) {
219 if (lazyComponent._status === Uninitialized) {
220 lazyComponent._status = Pending;
221 var ctor = lazyComponent._ctor;
222 var thenable = ctor();
223 lazyComponent._result = thenable;
224 thenable.then(function (moduleObject) {
225 if (lazyComponent._status === Pending) {
226 var defaultExport = moduleObject.default;
227
228 {
229 if (defaultExport === undefined) {
230 error('lazy: Expected the result of a dynamic import() call. ' + 'Instead received: %s\n\nYour code should look like: \n ' + "const MyComponent = lazy(() => import('./MyComponent'))", moduleObject);
231 }
232 }
233
234 lazyComponent._status = Resolved;
235 lazyComponent._result = defaultExport;
236 }
237 }, function (error) {
238 if (lazyComponent._status === Pending) {
239 lazyComponent._status = Rejected;
240 lazyComponent._result = error;
241 }
242 });
243 }
244}
245
246function getWrappedName(outerType, innerType, wrapperName) {
247 var functionName = innerType.displayName || innerType.name || '';
248 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
249}
250
251function getComponentName(type) {
252 if (type == null) {
253 // Host root, text node or just invalid type.
254 return null;
255 }
256
257 {
258 if (typeof type.tag === 'number') {
259 error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
260 }
261 }
262
263 if (typeof type === 'function') {
264 return type.displayName || type.name || null;
265 }
266
267 if (typeof type === 'string') {
268 return type;
269 }
270
271 switch (type) {
272 case REACT_FRAGMENT_TYPE:
273 return 'Fragment';
274
275 case REACT_PORTAL_TYPE:
276 return 'Portal';
277
278 case REACT_PROFILER_TYPE:
279 return "Profiler";
280
281 case REACT_STRICT_MODE_TYPE:
282 return 'StrictMode';
283
284 case REACT_SUSPENSE_TYPE:
285 return 'Suspense';
286
287 case REACT_SUSPENSE_LIST_TYPE:
288 return 'SuspenseList';
289 }
290
291 if (typeof type === 'object') {
292 switch (type.$$typeof) {
293 case REACT_CONTEXT_TYPE:
294 return 'Context.Consumer';
295
296 case REACT_PROVIDER_TYPE:
297 return 'Context.Provider';
298
299 case REACT_FORWARD_REF_TYPE:
300 return getWrappedName(type, type.render, 'ForwardRef');
301
302 case REACT_MEMO_TYPE:
303 return getComponentName(type.type);
304
305 case REACT_BLOCK_TYPE:
306 return getComponentName(type.render);
307
308 case REACT_LAZY_TYPE:
309 {
310 var thenable = type;
311 var resolvedThenable = refineResolvedLazyComponent(thenable);
312
313 if (resolvedThenable) {
314 return getComponentName(resolvedThenable);
315 }
316
317 break;
318 }
319 }
320 }
321
322 return null;
323}
324
325// Don't change these two values. They're used by React Dev Tools.
326var NoEffect =
327/* */
3280;
329var PerformedWork =
330/* */
3311; // You can change the rest (and add more).
332
333var Placement =
334/* */
3352;
336var Update =
337/* */
3384;
339var PlacementAndUpdate =
340/* */
3416;
342var Deletion =
343/* */
3448;
345var ContentReset =
346/* */
34716;
348var Callback =
349/* */
35032;
351var DidCapture =
352/* */
35364;
354var Ref =
355/* */
356128;
357var Snapshot =
358/* */
359256;
360var Passive =
361/* */
362512;
363var Hydrating =
364/* */
3651024;
366var HydratingAndUpdate =
367/* */
3681028; // Passive & Update & Callback & Ref & Snapshot
369
370var LifecycleEffectMask =
371/* */
372932; // Union of all host effects
373
374var HostEffectMask =
375/* */
3762047;
377var Incomplete =
378/* */
3792048;
380var ShouldCapture =
381/* */
3824096;
383
384var enableProfilerTimer = true;
385var enableFundamentalAPI = false;
386var warnAboutStringRefs = false;
387
388var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
389function getNearestMountedFiber(fiber) {
390 var node = fiber;
391 var nearestMounted = fiber;
392
393 if (!fiber.alternate) {
394 // If there is no alternate, this might be a new tree that isn't inserted
395 // yet. If it is, then it will have a pending insertion effect on it.
396 var nextNode = node;
397
398 do {
399 node = nextNode;
400
401 if ((node.effectTag & (Placement | Hydrating)) !== NoEffect) {
402 // This is an insertion or in-progress hydration. The nearest possible
403 // mounted fiber is the parent but we need to continue to figure out
404 // if that one is still mounted.
405 nearestMounted = node.return;
406 }
407
408 nextNode = node.return;
409 } while (nextNode);
410 } else {
411 while (node.return) {
412 node = node.return;
413 }
414 }
415
416 if (node.tag === HostRoot) {
417 // TODO: Check if this was a nested HostRoot when used with
418 // renderContainerIntoSubtree.
419 return nearestMounted;
420 } // If we didn't hit the root, that means that we're in an disconnected tree
421 // that has been unmounted.
422
423
424 return null;
425}
426function isFiberMounted(fiber) {
427 return getNearestMountedFiber(fiber) === fiber;
428}
429function isMounted(component) {
430 {
431 var owner = ReactCurrentOwner.current;
432
433 if (owner !== null && owner.tag === ClassComponent) {
434 var ownerFiber = owner;
435 var instance = ownerFiber.stateNode;
436
437 if (!instance._warnedAboutRefsInRender) {
438 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.', getComponentName(ownerFiber.type) || 'A component');
439 }
440
441 instance._warnedAboutRefsInRender = true;
442 }
443 }
444
445 var fiber = get(component);
446
447 if (!fiber) {
448 return false;
449 }
450
451 return getNearestMountedFiber(fiber) === fiber;
452}
453
454function assertIsMounted(fiber) {
455 if (!(getNearestMountedFiber(fiber) === fiber)) {
456 {
457 throw Error( "Unable to find node on an unmounted component." );
458 }
459 }
460}
461
462function findCurrentFiberUsingSlowPath(fiber) {
463 var alternate = fiber.alternate;
464
465 if (!alternate) {
466 // If there is no alternate, then we only need to check if it is mounted.
467 var nearestMounted = getNearestMountedFiber(fiber);
468
469 if (!(nearestMounted !== null)) {
470 {
471 throw Error( "Unable to find node on an unmounted component." );
472 }
473 }
474
475 if (nearestMounted !== fiber) {
476 return null;
477 }
478
479 return fiber;
480 } // If we have two possible branches, we'll walk backwards up to the root
481 // to see what path the root points to. On the way we may hit one of the
482 // special cases and we'll deal with them.
483
484
485 var a = fiber;
486 var b = alternate;
487
488 while (true) {
489 var parentA = a.return;
490
491 if (parentA === null) {
492 // We're at the root.
493 break;
494 }
495
496 var parentB = parentA.alternate;
497
498 if (parentB === null) {
499 // There is no alternate. This is an unusual case. Currently, it only
500 // happens when a Suspense component is hidden. An extra fragment fiber
501 // is inserted in between the Suspense fiber and its children. Skip
502 // over this extra fragment fiber and proceed to the next parent.
503 var nextParent = parentA.return;
504
505 if (nextParent !== null) {
506 a = b = nextParent;
507 continue;
508 } // If there's no parent, we're at the root.
509
510
511 break;
512 } // If both copies of the parent fiber point to the same child, we can
513 // assume that the child is current. This happens when we bailout on low
514 // priority: the bailed out fiber's child reuses the current child.
515
516
517 if (parentA.child === parentB.child) {
518 var child = parentA.child;
519
520 while (child) {
521 if (child === a) {
522 // We've determined that A is the current branch.
523 assertIsMounted(parentA);
524 return fiber;
525 }
526
527 if (child === b) {
528 // We've determined that B is the current branch.
529 assertIsMounted(parentA);
530 return alternate;
531 }
532
533 child = child.sibling;
534 } // We should never have an alternate for any mounting node. So the only
535 // way this could possibly happen is if this was unmounted, if at all.
536
537
538 {
539 {
540 throw Error( "Unable to find node on an unmounted component." );
541 }
542 }
543 }
544
545 if (a.return !== b.return) {
546 // The return pointer of A and the return pointer of B point to different
547 // fibers. We assume that return pointers never criss-cross, so A must
548 // belong to the child set of A.return, and B must belong to the child
549 // set of B.return.
550 a = parentA;
551 b = parentB;
552 } else {
553 // The return pointers point to the same fiber. We'll have to use the
554 // default, slow path: scan the child sets of each parent alternate to see
555 // which child belongs to which set.
556 //
557 // Search parent A's child set
558 var didFindChild = false;
559 var _child = parentA.child;
560
561 while (_child) {
562 if (_child === a) {
563 didFindChild = true;
564 a = parentA;
565 b = parentB;
566 break;
567 }
568
569 if (_child === b) {
570 didFindChild = true;
571 b = parentA;
572 a = parentB;
573 break;
574 }
575
576 _child = _child.sibling;
577 }
578
579 if (!didFindChild) {
580 // Search parent B's child set
581 _child = parentB.child;
582
583 while (_child) {
584 if (_child === a) {
585 didFindChild = true;
586 a = parentB;
587 b = parentA;
588 break;
589 }
590
591 if (_child === b) {
592 didFindChild = true;
593 b = parentB;
594 a = parentA;
595 break;
596 }
597
598 _child = _child.sibling;
599 }
600
601 if (!didFindChild) {
602 {
603 throw Error( "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." );
604 }
605 }
606 }
607 }
608
609 if (!(a.alternate === b)) {
610 {
611 throw Error( "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." );
612 }
613 }
614 } // If the root is not a host container, we're in a disconnected tree. I.e.
615 // unmounted.
616
617
618 if (!(a.tag === HostRoot)) {
619 {
620 throw Error( "Unable to find node on an unmounted component." );
621 }
622 }
623
624 if (a.stateNode.current === a) {
625 // We've determined that A is the current branch.
626 return fiber;
627 } // Otherwise B has to be current branch.
628
629
630 return alternate;
631}
632function findCurrentHostFiber(parent) {
633 var currentParent = findCurrentFiberUsingSlowPath(parent);
634
635 if (!currentParent) {
636 return null;
637 } // Next we'll drill down this component to find the first HostComponent/Text.
638
639
640 var node = currentParent;
641
642 while (true) {
643 if (node.tag === HostComponent || node.tag === HostText) {
644 return node;
645 } else if (node.child) {
646 node.child.return = node;
647 node = node.child;
648 continue;
649 }
650
651 if (node === currentParent) {
652 return null;
653 }
654
655 while (!node.sibling) {
656 if (!node.return || node.return === currentParent) {
657 return null;
658 }
659
660 node = node.return;
661 }
662
663 node.sibling.return = node.return;
664 node = node.sibling;
665 } // Flow needs the return null here, but ESLint complains about it.
666 // eslint-disable-next-line no-unreachable
667
668
669 return null;
670}
671
672// can re-export everything from this module.
673
674function shim() {
675 {
676 {
677 throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." );
678 }
679 }
680} // Hydration (when unsupported)
681var isSuspenseInstancePending = shim;
682var isSuspenseInstanceFallback = shim;
683var hydrateTextInstance = shim;
684
685var NO_CONTEXT = {};
686var UPDATE_SIGNAL = {};
687var nodeToInstanceMap = new WeakMap();
688
689{
690 Object.freeze(NO_CONTEXT);
691 Object.freeze(UPDATE_SIGNAL);
692}
693
694function getPublicInstance(inst) {
695 switch (inst.tag) {
696 case 'INSTANCE':
697 var createNodeMock = inst.rootContainerInstance.createNodeMock;
698 var mockNode = createNodeMock({
699 type: inst.type,
700 props: inst.props
701 });
702
703 if (typeof mockNode === 'object' && mockNode !== null) {
704 nodeToInstanceMap.set(mockNode, inst);
705 }
706
707 return mockNode;
708
709 default:
710 return inst;
711 }
712}
713function appendChild(parentInstance, child) {
714 {
715 if (!Array.isArray(parentInstance.children)) {
716 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.');
717 }
718 }
719
720 var index = parentInstance.children.indexOf(child);
721
722 if (index !== -1) {
723 parentInstance.children.splice(index, 1);
724 }
725
726 parentInstance.children.push(child);
727}
728function insertBefore(parentInstance, child, beforeChild) {
729 var index = parentInstance.children.indexOf(child);
730
731 if (index !== -1) {
732 parentInstance.children.splice(index, 1);
733 }
734
735 var beforeIndex = parentInstance.children.indexOf(beforeChild);
736 parentInstance.children.splice(beforeIndex, 0, child);
737}
738function removeChild(parentInstance, child) {
739 var index = parentInstance.children.indexOf(child);
740 parentInstance.children.splice(index, 1);
741}
742function getRootHostContext(rootContainerInstance) {
743 return NO_CONTEXT;
744}
745function getChildHostContext(parentHostContext, type, rootContainerInstance) {
746 return NO_CONTEXT;
747}
748function prepareForCommit(containerInfo) {// noop
749}
750function resetAfterCommit(containerInfo) {// noop
751}
752function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
753 var propsToUse = props;
754
755 return {
756 type: type,
757 props: propsToUse,
758 isHidden: false,
759 children: [],
760 internalInstanceHandle: internalInstanceHandle,
761 rootContainerInstance: rootContainerInstance,
762 tag: 'INSTANCE'
763 };
764}
765function appendInitialChild(parentInstance, child) {
766 var index = parentInstance.children.indexOf(child);
767
768 if (index !== -1) {
769 parentInstance.children.splice(index, 1);
770 }
771
772 parentInstance.children.push(child);
773}
774function prepareUpdate(testElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
775 return UPDATE_SIGNAL;
776}
777function shouldSetTextContent(type, props) {
778 return false;
779}
780function shouldDeprioritizeSubtree(type, props) {
781 return false;
782}
783function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
784
785 return {
786 text: text,
787 isHidden: false,
788 tag: 'TEXT'
789 };
790}
791var scheduleTimeout = setTimeout;
792var cancelTimeout = clearTimeout;
793var noTimeout = -1; // -------------------
794function commitUpdate(instance, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
795 instance.type = type;
796 instance.props = newProps;
797}
798function commitTextUpdate(textInstance, oldText, newText) {
799 textInstance.text = newText;
800}
801function resetTextContent(testElement) {// noop
802}
803var appendChildToContainer = appendChild;
804var insertInContainerBefore = insertBefore;
805var removeChildFromContainer = removeChild;
806function hideInstance(instance) {
807 instance.isHidden = true;
808}
809function hideTextInstance(textInstance) {
810 textInstance.isHidden = true;
811}
812function unhideInstance(instance, props) {
813 instance.isHidden = false;
814}
815function unhideTextInstance(textInstance, text) {
816 textInstance.isHidden = false;
817}
818
819var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
820function describeComponentFrame (name, source, ownerName) {
821 var sourceInfo = '';
822
823 if (source) {
824 var path = source.fileName;
825 var fileName = path.replace(BEFORE_SLASH_RE, '');
826
827 {
828 // In DEV, include code for a common special case:
829 // prefer "folder/index.js" instead of just "index.js".
830 if (/^index\./.test(fileName)) {
831 var match = path.match(BEFORE_SLASH_RE);
832
833 if (match) {
834 var pathBeforeSlash = match[1];
835
836 if (pathBeforeSlash) {
837 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
838 fileName = folderName + '/' + fileName;
839 }
840 }
841 }
842 }
843
844 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
845 } else if (ownerName) {
846 sourceInfo = ' (created by ' + ownerName + ')';
847 }
848
849 return '\n in ' + (name || 'Unknown') + sourceInfo;
850}
851
852var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
853
854function describeFiber(fiber) {
855 switch (fiber.tag) {
856 case HostRoot:
857 case HostPortal:
858 case HostText:
859 case Fragment:
860 case ContextProvider:
861 case ContextConsumer:
862 return '';
863
864 default:
865 var owner = fiber._debugOwner;
866 var source = fiber._debugSource;
867 var name = getComponentName(fiber.type);
868 var ownerName = null;
869
870 if (owner) {
871 ownerName = getComponentName(owner.type);
872 }
873
874 return describeComponentFrame(name, source, ownerName);
875 }
876}
877
878function getStackByFiberInDevAndProd(workInProgress) {
879 var info = '';
880 var node = workInProgress;
881
882 do {
883 info += describeFiber(node);
884 node = node.return;
885 } while (node);
886
887 return info;
888}
889var current = null;
890var isRendering = false;
891function getCurrentFiberOwnerNameInDevOrNull() {
892 {
893 if (current === null) {
894 return null;
895 }
896
897 var owner = current._debugOwner;
898
899 if (owner !== null && typeof owner !== 'undefined') {
900 return getComponentName(owner.type);
901 }
902 }
903
904 return null;
905}
906function getCurrentFiberStackInDev() {
907 {
908 if (current === null) {
909 return '';
910 } // Safe because if current fiber exists, we are reconciling,
911 // and it is guaranteed to be the work-in-progress version.
912
913
914 return getStackByFiberInDevAndProd(current);
915 }
916}
917function resetCurrentFiber() {
918 {
919 ReactDebugCurrentFrame.getCurrentStack = null;
920 current = null;
921 isRendering = false;
922 }
923}
924function setCurrentFiber(fiber) {
925 {
926 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
927 current = fiber;
928 isRendering = false;
929 }
930}
931function setIsRendering(rendering) {
932 {
933 isRendering = rendering;
934 }
935}
936
937// Prefix measurements so that it's possible to filter them.
938// Longer prefixes are hard to read in DevTools.
939var reactEmoji = "\u269B";
940var warningEmoji = "\u26D4";
941var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function'; // Keep track of current fiber so that we know the path to unwind on pause.
942// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
943
944var currentFiber = null; // If we're in the middle of user code, which fiber and method is it?
945// Reusing `currentFiber` would be confusing for this because user code fiber
946// can change during commit phase too, but we don't need to unwind it (since
947// lifecycles in the commit phase don't resemble a tree).
948
949var currentPhase = null;
950var currentPhaseFiber = null; // Did lifecycle hook schedule an update? This is often a performance problem,
951// so we will keep track of it, and include it in the report.
952// Track commits caused by cascading updates.
953
954var isCommitting = false;
955var hasScheduledUpdateInCurrentCommit = false;
956var hasScheduledUpdateInCurrentPhase = false;
957var commitCountInCurrentWorkLoop = 0;
958var effectCountInCurrentCommit = 0;
959// to avoid stretch the commit phase with measurement overhead.
960
961var labelsInCurrentCommit = new Set();
962
963var formatMarkName = function (markName) {
964 return reactEmoji + " " + markName;
965};
966
967var formatLabel = function (label, warning) {
968 var prefix = warning ? warningEmoji + " " : reactEmoji + " ";
969 var suffix = warning ? " Warning: " + warning : '';
970 return "" + prefix + label + suffix;
971};
972
973var beginMark = function (markName) {
974 performance.mark(formatMarkName(markName));
975};
976
977var clearMark = function (markName) {
978 performance.clearMarks(formatMarkName(markName));
979};
980
981var endMark = function (label, markName, warning) {
982 var formattedMarkName = formatMarkName(markName);
983 var formattedLabel = formatLabel(label, warning);
984
985 try {
986 performance.measure(formattedLabel, formattedMarkName);
987 } catch (err) {} // If previous mark was missing for some reason, this will throw.
988 // This could only happen if React crashed in an unexpected place earlier.
989 // Don't pile on with more errors.
990 // Clear marks immediately to avoid growing buffer.
991
992
993 performance.clearMarks(formattedMarkName);
994 performance.clearMeasures(formattedLabel);
995};
996
997var getFiberMarkName = function (label, debugID) {
998 return label + " (#" + debugID + ")";
999};
1000
1001var getFiberLabel = function (componentName, isMounted, phase) {
1002 if (phase === null) {
1003 // These are composite component total time measurements.
1004 return componentName + " [" + (isMounted ? 'update' : 'mount') + "]";
1005 } else {
1006 // Composite component methods.
1007 return componentName + "." + phase;
1008 }
1009};
1010
1011var beginFiberMark = function (fiber, phase) {
1012 var componentName = getComponentName(fiber.type) || 'Unknown';
1013 var debugID = fiber._debugID;
1014 var isMounted = fiber.alternate !== null;
1015 var label = getFiberLabel(componentName, isMounted, phase);
1016
1017 if (isCommitting && labelsInCurrentCommit.has(label)) {
1018 // During the commit phase, we don't show duplicate labels because
1019 // there is a fixed overhead for every measurement, and we don't
1020 // want to stretch the commit phase beyond necessary.
1021 return false;
1022 }
1023
1024 labelsInCurrentCommit.add(label);
1025 var markName = getFiberMarkName(label, debugID);
1026 beginMark(markName);
1027 return true;
1028};
1029
1030var clearFiberMark = function (fiber, phase) {
1031 var componentName = getComponentName(fiber.type) || 'Unknown';
1032 var debugID = fiber._debugID;
1033 var isMounted = fiber.alternate !== null;
1034 var label = getFiberLabel(componentName, isMounted, phase);
1035 var markName = getFiberMarkName(label, debugID);
1036 clearMark(markName);
1037};
1038
1039var endFiberMark = function (fiber, phase, warning) {
1040 var componentName = getComponentName(fiber.type) || 'Unknown';
1041 var debugID = fiber._debugID;
1042 var isMounted = fiber.alternate !== null;
1043 var label = getFiberLabel(componentName, isMounted, phase);
1044 var markName = getFiberMarkName(label, debugID);
1045 endMark(label, markName, warning);
1046};
1047
1048var shouldIgnoreFiber = function (fiber) {
1049 // Host components should be skipped in the timeline.
1050 // We could check typeof fiber.type, but does this work with RN?
1051 switch (fiber.tag) {
1052 case HostRoot:
1053 case HostComponent:
1054 case HostText:
1055 case HostPortal:
1056 case Fragment:
1057 case ContextProvider:
1058 case ContextConsumer:
1059 case Mode:
1060 return true;
1061
1062 default:
1063 return false;
1064 }
1065};
1066
1067var clearPendingPhaseMeasurement = function () {
1068 if (currentPhase !== null && currentPhaseFiber !== null) {
1069 clearFiberMark(currentPhaseFiber, currentPhase);
1070 }
1071
1072 currentPhaseFiber = null;
1073 currentPhase = null;
1074 hasScheduledUpdateInCurrentPhase = false;
1075};
1076
1077var pauseTimers = function () {
1078 // Stops all currently active measurements so that they can be resumed
1079 // if we continue in a later deferred loop from the same unit of work.
1080 var fiber = currentFiber;
1081
1082 while (fiber) {
1083 if (fiber._debugIsCurrentlyTiming) {
1084 endFiberMark(fiber, null, null);
1085 }
1086
1087 fiber = fiber.return;
1088 }
1089};
1090
1091var resumeTimersRecursively = function (fiber) {
1092 if (fiber.return !== null) {
1093 resumeTimersRecursively(fiber.return);
1094 }
1095
1096 if (fiber._debugIsCurrentlyTiming) {
1097 beginFiberMark(fiber, null);
1098 }
1099};
1100
1101var resumeTimers = function () {
1102 // Resumes all measurements that were active during the last deferred loop.
1103 if (currentFiber !== null) {
1104 resumeTimersRecursively(currentFiber);
1105 }
1106};
1107
1108function recordEffect() {
1109 {
1110 effectCountInCurrentCommit++;
1111 }
1112}
1113function recordScheduleUpdate() {
1114 {
1115 if (isCommitting) {
1116 hasScheduledUpdateInCurrentCommit = true;
1117 }
1118
1119 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
1120 hasScheduledUpdateInCurrentPhase = true;
1121 }
1122 }
1123}
1124function startWorkTimer(fiber) {
1125 {
1126 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1127 return;
1128 } // If we pause, this is the fiber to unwind from.
1129
1130
1131 currentFiber = fiber;
1132
1133 if (!beginFiberMark(fiber, null)) {
1134 return;
1135 }
1136
1137 fiber._debugIsCurrentlyTiming = true;
1138 }
1139}
1140function cancelWorkTimer(fiber) {
1141 {
1142 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1143 return;
1144 } // Remember we shouldn't complete measurement for this fiber.
1145 // Otherwise flamechart will be deep even for small updates.
1146
1147
1148 fiber._debugIsCurrentlyTiming = false;
1149 clearFiberMark(fiber, null);
1150 }
1151}
1152function stopWorkTimer(fiber) {
1153 {
1154 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1155 return;
1156 } // If we pause, its parent is the fiber to unwind from.
1157
1158
1159 currentFiber = fiber.return;
1160
1161 if (!fiber._debugIsCurrentlyTiming) {
1162 return;
1163 }
1164
1165 fiber._debugIsCurrentlyTiming = false;
1166 endFiberMark(fiber, null, null);
1167 }
1168}
1169function stopFailedWorkTimer(fiber) {
1170 {
1171 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1172 return;
1173 } // If we pause, its parent is the fiber to unwind from.
1174
1175
1176 currentFiber = fiber.return;
1177
1178 if (!fiber._debugIsCurrentlyTiming) {
1179 return;
1180 }
1181
1182 fiber._debugIsCurrentlyTiming = false;
1183 var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
1184 endFiberMark(fiber, null, warning);
1185 }
1186}
1187function startPhaseTimer(fiber, phase) {
1188 {
1189 if (!supportsUserTiming) {
1190 return;
1191 }
1192
1193 clearPendingPhaseMeasurement();
1194
1195 if (!beginFiberMark(fiber, phase)) {
1196 return;
1197 }
1198
1199 currentPhaseFiber = fiber;
1200 currentPhase = phase;
1201 }
1202}
1203function stopPhaseTimer() {
1204 {
1205 if (!supportsUserTiming) {
1206 return;
1207 }
1208
1209 if (currentPhase !== null && currentPhaseFiber !== null) {
1210 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
1211 endFiberMark(currentPhaseFiber, currentPhase, warning);
1212 }
1213
1214 currentPhase = null;
1215 currentPhaseFiber = null;
1216 }
1217}
1218function startWorkLoopTimer(nextUnitOfWork) {
1219 {
1220 currentFiber = nextUnitOfWork;
1221
1222 if (!supportsUserTiming) {
1223 return;
1224 }
1225
1226 commitCountInCurrentWorkLoop = 0; // This is top level call.
1227 // Any other measurements are performed within.
1228
1229 beginMark('(React Tree Reconciliation)'); // Resume any measurements that were in progress during the last loop.
1230
1231 resumeTimers();
1232 }
1233}
1234function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
1235 {
1236 if (!supportsUserTiming) {
1237 return;
1238 }
1239
1240 var warning = null;
1241
1242 if (interruptedBy !== null) {
1243 if (interruptedBy.tag === HostRoot) {
1244 warning = 'A top-level update interrupted the previous render';
1245 } else {
1246 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
1247 warning = "An update to " + componentName + " interrupted the previous render";
1248 }
1249 } else if (commitCountInCurrentWorkLoop > 1) {
1250 warning = 'There were cascading updates';
1251 }
1252
1253 commitCountInCurrentWorkLoop = 0;
1254 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)'; // Pause any measurements until the next loop.
1255
1256 pauseTimers();
1257 endMark(label, '(React Tree Reconciliation)', warning);
1258 }
1259}
1260function startCommitTimer() {
1261 {
1262 if (!supportsUserTiming) {
1263 return;
1264 }
1265
1266 isCommitting = true;
1267 hasScheduledUpdateInCurrentCommit = false;
1268 labelsInCurrentCommit.clear();
1269 beginMark('(Committing Changes)');
1270 }
1271}
1272function stopCommitTimer() {
1273 {
1274 if (!supportsUserTiming) {
1275 return;
1276 }
1277
1278 var warning = null;
1279
1280 if (hasScheduledUpdateInCurrentCommit) {
1281 warning = 'Lifecycle hook scheduled a cascading update';
1282 } else if (commitCountInCurrentWorkLoop > 0) {
1283 warning = 'Caused by a cascading update in earlier commit';
1284 }
1285
1286 hasScheduledUpdateInCurrentCommit = false;
1287 commitCountInCurrentWorkLoop++;
1288 isCommitting = false;
1289 labelsInCurrentCommit.clear();
1290 endMark('(Committing Changes)', '(Committing Changes)', warning);
1291 }
1292}
1293function startCommitSnapshotEffectsTimer() {
1294 {
1295 if (!supportsUserTiming) {
1296 return;
1297 }
1298
1299 effectCountInCurrentCommit = 0;
1300 beginMark('(Committing Snapshot Effects)');
1301 }
1302}
1303function stopCommitSnapshotEffectsTimer() {
1304 {
1305 if (!supportsUserTiming) {
1306 return;
1307 }
1308
1309 var count = effectCountInCurrentCommit;
1310 effectCountInCurrentCommit = 0;
1311 endMark("(Committing Snapshot Effects: " + count + " Total)", '(Committing Snapshot Effects)', null);
1312 }
1313}
1314function startCommitHostEffectsTimer() {
1315 {
1316 if (!supportsUserTiming) {
1317 return;
1318 }
1319
1320 effectCountInCurrentCommit = 0;
1321 beginMark('(Committing Host Effects)');
1322 }
1323}
1324function stopCommitHostEffectsTimer() {
1325 {
1326 if (!supportsUserTiming) {
1327 return;
1328 }
1329
1330 var count = effectCountInCurrentCommit;
1331 effectCountInCurrentCommit = 0;
1332 endMark("(Committing Host Effects: " + count + " Total)", '(Committing Host Effects)', null);
1333 }
1334}
1335function startCommitLifeCyclesTimer() {
1336 {
1337 if (!supportsUserTiming) {
1338 return;
1339 }
1340
1341 effectCountInCurrentCommit = 0;
1342 beginMark('(Calling Lifecycle Methods)');
1343 }
1344}
1345function stopCommitLifeCyclesTimer() {
1346 {
1347 if (!supportsUserTiming) {
1348 return;
1349 }
1350
1351 var count = effectCountInCurrentCommit;
1352 effectCountInCurrentCommit = 0;
1353 endMark("(Calling Lifecycle Methods: " + count + " Total)", '(Calling Lifecycle Methods)', null);
1354 }
1355}
1356
1357var valueStack = [];
1358var fiberStack;
1359
1360{
1361 fiberStack = [];
1362}
1363
1364var index = -1;
1365
1366function createCursor(defaultValue) {
1367 return {
1368 current: defaultValue
1369 };
1370}
1371
1372function pop(cursor, fiber) {
1373 if (index < 0) {
1374 {
1375 error('Unexpected pop.');
1376 }
1377
1378 return;
1379 }
1380
1381 {
1382 if (fiber !== fiberStack[index]) {
1383 error('Unexpected Fiber popped.');
1384 }
1385 }
1386
1387 cursor.current = valueStack[index];
1388 valueStack[index] = null;
1389
1390 {
1391 fiberStack[index] = null;
1392 }
1393
1394 index--;
1395}
1396
1397function push(cursor, value, fiber) {
1398 index++;
1399 valueStack[index] = cursor.current;
1400
1401 {
1402 fiberStack[index] = fiber;
1403 }
1404
1405 cursor.current = value;
1406}
1407
1408var warnedAboutMissingGetChildContext;
1409
1410{
1411 warnedAboutMissingGetChildContext = {};
1412}
1413
1414var emptyContextObject = {};
1415
1416{
1417 Object.freeze(emptyContextObject);
1418} // A cursor to the current merged context object on the stack.
1419
1420
1421var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.
1422
1423var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.
1424// We use this to get access to the parent context after we have already
1425// pushed the next context provider, and now need to merge their contexts.
1426
1427var previousContext = emptyContextObject;
1428
1429function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
1430 {
1431 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
1432 // If the fiber is a context provider itself, when we read its context
1433 // we may have already pushed its own child context on the stack. A context
1434 // provider should not "see" its own child context. Therefore we read the
1435 // previous (parent) context instead for a context provider.
1436 return previousContext;
1437 }
1438
1439 return contextStackCursor.current;
1440 }
1441}
1442
1443function cacheContext(workInProgress, unmaskedContext, maskedContext) {
1444 {
1445 var instance = workInProgress.stateNode;
1446 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
1447 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
1448 }
1449}
1450
1451function getMaskedContext(workInProgress, unmaskedContext) {
1452 {
1453 var type = workInProgress.type;
1454 var contextTypes = type.contextTypes;
1455
1456 if (!contextTypes) {
1457 return emptyContextObject;
1458 } // Avoid recreating masked context unless unmasked context has changed.
1459 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
1460 // This may trigger infinite loops if componentWillReceiveProps calls setState.
1461
1462
1463 var instance = workInProgress.stateNode;
1464
1465 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
1466 return instance.__reactInternalMemoizedMaskedChildContext;
1467 }
1468
1469 var context = {};
1470
1471 for (var key in contextTypes) {
1472 context[key] = unmaskedContext[key];
1473 }
1474
1475 {
1476 var name = getComponentName(type) || 'Unknown';
1477 checkPropTypes(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
1478 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
1479 // Context is created before the class component is instantiated so check for instance.
1480
1481
1482 if (instance) {
1483 cacheContext(workInProgress, unmaskedContext, context);
1484 }
1485
1486 return context;
1487 }
1488}
1489
1490function hasContextChanged() {
1491 {
1492 return didPerformWorkStackCursor.current;
1493 }
1494}
1495
1496function isContextProvider(type) {
1497 {
1498 var childContextTypes = type.childContextTypes;
1499 return childContextTypes !== null && childContextTypes !== undefined;
1500 }
1501}
1502
1503function popContext(fiber) {
1504 {
1505 pop(didPerformWorkStackCursor, fiber);
1506 pop(contextStackCursor, fiber);
1507 }
1508}
1509
1510function popTopLevelContextObject(fiber) {
1511 {
1512 pop(didPerformWorkStackCursor, fiber);
1513 pop(contextStackCursor, fiber);
1514 }
1515}
1516
1517function pushTopLevelContextObject(fiber, context, didChange) {
1518 {
1519 if (!(contextStackCursor.current === emptyContextObject)) {
1520 {
1521 throw Error( "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." );
1522 }
1523 }
1524
1525 push(contextStackCursor, context, fiber);
1526 push(didPerformWorkStackCursor, didChange, fiber);
1527 }
1528}
1529
1530function processChildContext(fiber, type, parentContext) {
1531 {
1532 var instance = fiber.stateNode;
1533 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.
1534 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
1535
1536 if (typeof instance.getChildContext !== 'function') {
1537 {
1538 var componentName = getComponentName(type) || 'Unknown';
1539
1540 if (!warnedAboutMissingGetChildContext[componentName]) {
1541 warnedAboutMissingGetChildContext[componentName] = true;
1542
1543 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);
1544 }
1545 }
1546
1547 return parentContext;
1548 }
1549
1550 var childContext;
1551 startPhaseTimer(fiber, 'getChildContext');
1552 childContext = instance.getChildContext();
1553 stopPhaseTimer();
1554
1555 for (var contextKey in childContext) {
1556 if (!(contextKey in childContextTypes)) {
1557 {
1558 throw Error( (getComponentName(type) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes." );
1559 }
1560 }
1561 }
1562
1563 {
1564 var name = getComponentName(type) || 'Unknown';
1565 checkPropTypes(childContextTypes, childContext, 'child context', name, // In practice, there is one case in which we won't get a stack. It's when
1566 // somebody calls unstable_renderSubtreeIntoContainer() and we process
1567 // context from the parent component instance. The stack will be missing
1568 // because it's outside of the reconciliation, and so the pointer has not
1569 // been set. This is rare and doesn't matter. We'll also remove that API.
1570 getCurrentFiberStackInDev);
1571 }
1572
1573 return _assign({}, parentContext, {}, childContext);
1574 }
1575}
1576
1577function pushContextProvider(workInProgress) {
1578 {
1579 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.
1580 // If the instance does not exist yet, we will push null at first,
1581 // and replace it on the stack later when invalidating the context.
1582
1583 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.
1584 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
1585
1586 previousContext = contextStackCursor.current;
1587 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
1588 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
1589 return true;
1590 }
1591}
1592
1593function invalidateContextProvider(workInProgress, type, didChange) {
1594 {
1595 var instance = workInProgress.stateNode;
1596
1597 if (!instance) {
1598 {
1599 throw Error( "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." );
1600 }
1601 }
1602
1603 if (didChange) {
1604 // Merge parent and own context.
1605 // Skip this if we're not updating due to sCU.
1606 // This avoids unnecessarily recomputing memoized values.
1607 var mergedContext = processChildContext(workInProgress, type, previousContext);
1608 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.
1609 // It is important to unwind the context in the reverse order.
1610
1611 pop(didPerformWorkStackCursor, workInProgress);
1612 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.
1613
1614 push(contextStackCursor, mergedContext, workInProgress);
1615 push(didPerformWorkStackCursor, didChange, workInProgress);
1616 } else {
1617 pop(didPerformWorkStackCursor, workInProgress);
1618 push(didPerformWorkStackCursor, didChange, workInProgress);
1619 }
1620 }
1621}
1622
1623function findCurrentUnmaskedContext(fiber) {
1624 {
1625 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
1626 // makes sense elsewhere
1627 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {
1628 {
1629 throw Error( "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." );
1630 }
1631 }
1632
1633 var node = fiber;
1634
1635 do {
1636 switch (node.tag) {
1637 case HostRoot:
1638 return node.stateNode.context;
1639
1640 case ClassComponent:
1641 {
1642 var Component = node.type;
1643
1644 if (isContextProvider(Component)) {
1645 return node.stateNode.__reactInternalMemoizedMergedChildContext;
1646 }
1647
1648 break;
1649 }
1650 }
1651
1652 node = node.return;
1653 } while (node !== null);
1654
1655 {
1656 {
1657 throw Error( "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." );
1658 }
1659 }
1660 }
1661}
1662
1663var LegacyRoot = 0;
1664var BlockingRoot = 1;
1665var ConcurrentRoot = 2;
1666
1667var Scheduler_runWithPriority = Scheduler$1.unstable_runWithPriority,
1668 Scheduler_scheduleCallback = Scheduler$1.unstable_scheduleCallback,
1669 Scheduler_cancelCallback = Scheduler$1.unstable_cancelCallback,
1670 Scheduler_shouldYield = Scheduler$1.unstable_shouldYield,
1671 Scheduler_requestPaint = Scheduler$1.unstable_requestPaint,
1672 Scheduler_now = Scheduler$1.unstable_now,
1673 Scheduler_getCurrentPriorityLevel = Scheduler$1.unstable_getCurrentPriorityLevel,
1674 Scheduler_ImmediatePriority = Scheduler$1.unstable_ImmediatePriority,
1675 Scheduler_UserBlockingPriority = Scheduler$1.unstable_UserBlockingPriority,
1676 Scheduler_NormalPriority = Scheduler$1.unstable_NormalPriority,
1677 Scheduler_LowPriority = Scheduler$1.unstable_LowPriority,
1678 Scheduler_IdlePriority = Scheduler$1.unstable_IdlePriority;
1679
1680{
1681 // Provide explicit error message when production+profiling bundle of e.g.
1682 // react-dom is used with production (non-profiling) bundle of
1683 // scheduler/tracing
1684 if (!(tracing.__interactionsRef != null && tracing.__interactionsRef.current != null)) {
1685 {
1686 throw Error( "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at http://fb.me/react-profiling" );
1687 }
1688 }
1689}
1690
1691var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use
1692// ascending numbers so we can compare them like numbers. They start at 90 to
1693// avoid clashing with Scheduler's priorities.
1694
1695var ImmediatePriority = 99;
1696var UserBlockingPriority = 98;
1697var NormalPriority = 97;
1698var LowPriority = 96;
1699var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only.
1700
1701var NoPriority = 90;
1702var shouldYield = Scheduler_shouldYield;
1703var requestPaint = // Fall back gracefully if we're running an older version of Scheduler.
1704Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {};
1705var syncQueue = null;
1706var immediateQueueCallbackNode = null;
1707var isFlushingSyncQueue = false;
1708var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly.
1709// This will be the case for modern browsers that support `performance.now`. In
1710// older browsers, Scheduler falls back to `Date.now`, which returns a Unix
1711// timestamp. In that case, subtract the module initialization time to simulate
1712// the behavior of performance.now and keep our times small enough to fit
1713// within 32 bits.
1714// TODO: Consider lifting this into Scheduler.
1715
1716var now = initialTimeMs < 10000 ? Scheduler_now : function () {
1717 return Scheduler_now() - initialTimeMs;
1718};
1719function getCurrentPriorityLevel() {
1720 switch (Scheduler_getCurrentPriorityLevel()) {
1721 case Scheduler_ImmediatePriority:
1722 return ImmediatePriority;
1723
1724 case Scheduler_UserBlockingPriority:
1725 return UserBlockingPriority;
1726
1727 case Scheduler_NormalPriority:
1728 return NormalPriority;
1729
1730 case Scheduler_LowPriority:
1731 return LowPriority;
1732
1733 case Scheduler_IdlePriority:
1734 return IdlePriority;
1735
1736 default:
1737 {
1738 {
1739 throw Error( "Unknown priority level." );
1740 }
1741 }
1742
1743 }
1744}
1745
1746function reactPriorityToSchedulerPriority(reactPriorityLevel) {
1747 switch (reactPriorityLevel) {
1748 case ImmediatePriority:
1749 return Scheduler_ImmediatePriority;
1750
1751 case UserBlockingPriority:
1752 return Scheduler_UserBlockingPriority;
1753
1754 case NormalPriority:
1755 return Scheduler_NormalPriority;
1756
1757 case LowPriority:
1758 return Scheduler_LowPriority;
1759
1760 case IdlePriority:
1761 return Scheduler_IdlePriority;
1762
1763 default:
1764 {
1765 {
1766 throw Error( "Unknown priority level." );
1767 }
1768 }
1769
1770 }
1771}
1772
1773function runWithPriority(reactPriorityLevel, fn) {
1774 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
1775 return Scheduler_runWithPriority(priorityLevel, fn);
1776}
1777function scheduleCallback(reactPriorityLevel, callback, options) {
1778 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
1779 return Scheduler_scheduleCallback(priorityLevel, callback, options);
1780}
1781function scheduleSyncCallback(callback) {
1782 // Push this callback into an internal queue. We'll flush these either in
1783 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
1784 if (syncQueue === null) {
1785 syncQueue = [callback]; // Flush the queue in the next tick, at the earliest.
1786
1787 immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl);
1788 } else {
1789 // Push onto existing queue. Don't need to schedule a callback because
1790 // we already scheduled one when we created the queue.
1791 syncQueue.push(callback);
1792 }
1793
1794 return fakeCallbackNode;
1795}
1796function cancelCallback(callbackNode) {
1797 if (callbackNode !== fakeCallbackNode) {
1798 Scheduler_cancelCallback(callbackNode);
1799 }
1800}
1801function flushSyncCallbackQueue() {
1802 if (immediateQueueCallbackNode !== null) {
1803 var node = immediateQueueCallbackNode;
1804 immediateQueueCallbackNode = null;
1805 Scheduler_cancelCallback(node);
1806 }
1807
1808 flushSyncCallbackQueueImpl();
1809}
1810
1811function flushSyncCallbackQueueImpl() {
1812 if (!isFlushingSyncQueue && syncQueue !== null) {
1813 // Prevent re-entrancy.
1814 isFlushingSyncQueue = true;
1815 var i = 0;
1816
1817 try {
1818 var _isSync = true;
1819 var queue = syncQueue;
1820 runWithPriority(ImmediatePriority, function () {
1821 for (; i < queue.length; i++) {
1822 var callback = queue[i];
1823
1824 do {
1825 callback = callback(_isSync);
1826 } while (callback !== null);
1827 }
1828 });
1829 syncQueue = null;
1830 } catch (error) {
1831 // If something throws, leave the remaining callbacks on the queue.
1832 if (syncQueue !== null) {
1833 syncQueue = syncQueue.slice(i + 1);
1834 } // Resume flushing in the next tick
1835
1836
1837 Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue);
1838 throw error;
1839 } finally {
1840 isFlushingSyncQueue = false;
1841 }
1842 }
1843}
1844
1845var NoMode = 0;
1846var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root
1847// tag instead
1848
1849var BlockingMode = 2;
1850var ConcurrentMode = 4;
1851var ProfileMode = 8;
1852
1853// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
1854// Math.pow(2, 30) - 1
1855// 0b111111111111111111111111111111
1856var MAX_SIGNED_31_BIT_INT = 1073741823;
1857
1858var NoWork = 0; // TODO: Think of a better name for Never. The key difference with Idle is that
1859// Never work can be committed in an inconsistent state without tearing the UI.
1860// The main example is offscreen content, like a hidden subtree. So one possible
1861// name is Offscreen. However, it also includes dehydrated Suspense boundaries,
1862// which are inconsistent in the sense that they haven't finished yet, but
1863// aren't visibly inconsistent because the server rendered HTML matches what the
1864// hydrated tree would look like.
1865
1866var Never = 1; // Idle is slightly higher priority than Never. It must completely finish in
1867// order to be consistent.
1868
1869var Idle = 2; // Continuous Hydration is slightly higher than Idle and is used to increase
1870var Sync = MAX_SIGNED_31_BIT_INT;
1871var Batched = Sync - 1;
1872var UNIT_SIZE = 10;
1873var MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms.
1874
1875function msToExpirationTime(ms) {
1876 // Always subtract from the offset so that we don't clash with the magic number for NoWork.
1877 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
1878}
1879function expirationTimeToMs(expirationTime) {
1880 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
1881}
1882
1883function ceiling(num, precision) {
1884 return ((num / precision | 0) + 1) * precision;
1885}
1886
1887function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
1888 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
1889} // TODO: This corresponds to Scheduler's NormalPriority, not LowPriority. Update
1890// the names to reflect.
1891
1892
1893var LOW_PRIORITY_EXPIRATION = 5000;
1894var LOW_PRIORITY_BATCH_SIZE = 250;
1895function computeAsyncExpiration(currentTime) {
1896 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
1897}
1898function computeSuspenseExpiration(currentTime, timeoutMs) {
1899 // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time?
1900 return computeExpirationBucket(currentTime, timeoutMs, LOW_PRIORITY_BATCH_SIZE);
1901} // We intentionally set a higher expiration time for interactive updates in
1902// dev than in production.
1903//
1904// If the main thread is being blocked so long that you hit the expiration,
1905// it's a problem that could be solved with better scheduling.
1906//
1907// People will be more likely to notice this and fix it with the long
1908// expiration time in development.
1909//
1910// In production we opt for better UX at the risk of masking scheduling
1911// problems, by expiring fast.
1912
1913var HIGH_PRIORITY_EXPIRATION = 500 ;
1914var HIGH_PRIORITY_BATCH_SIZE = 100;
1915function computeInteractiveExpiration(currentTime) {
1916 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
1917}
1918function inferPriorityFromExpirationTime(currentTime, expirationTime) {
1919 if (expirationTime === Sync) {
1920 return ImmediatePriority;
1921 }
1922
1923 if (expirationTime === Never || expirationTime === Idle) {
1924 return IdlePriority;
1925 }
1926
1927 var msUntil = expirationTimeToMs(expirationTime) - expirationTimeToMs(currentTime);
1928
1929 if (msUntil <= 0) {
1930 return ImmediatePriority;
1931 }
1932
1933 if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) {
1934 return UserBlockingPriority;
1935 }
1936
1937 if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) {
1938 return NormalPriority;
1939 } // TODO: Handle LowPriority
1940 // Assume anything lower has idle priority
1941
1942
1943 return IdlePriority;
1944}
1945
1946/**
1947 * inlined Object.is polyfill to avoid requiring consumers ship their own
1948 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
1949 */
1950function is(x, y) {
1951 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
1952 ;
1953}
1954
1955var objectIs = typeof Object.is === 'function' ? Object.is : is;
1956
1957var hasOwnProperty = Object.prototype.hasOwnProperty;
1958/**
1959 * Performs equality by iterating through keys on an object and returning false
1960 * when any key has values which are not strictly equal between the arguments.
1961 * Returns true when the values of all keys are strictly equal.
1962 */
1963
1964function shallowEqual(objA, objB) {
1965 if (objectIs(objA, objB)) {
1966 return true;
1967 }
1968
1969 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
1970 return false;
1971 }
1972
1973 var keysA = Object.keys(objA);
1974 var keysB = Object.keys(objB);
1975
1976 if (keysA.length !== keysB.length) {
1977 return false;
1978 } // Test for A's keys different from B.
1979
1980
1981 for (var i = 0; i < keysA.length; i++) {
1982 if (!hasOwnProperty.call(objB, keysA[i]) || !objectIs(objA[keysA[i]], objB[keysA[i]])) {
1983 return false;
1984 }
1985 }
1986
1987 return true;
1988}
1989
1990var ReactStrictModeWarnings = {
1991 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
1992 flushPendingUnsafeLifecycleWarnings: function () {},
1993 recordLegacyContextWarning: function (fiber, instance) {},
1994 flushLegacyContextWarning: function () {},
1995 discardPendingWarnings: function () {}
1996};
1997
1998{
1999 var findStrictRoot = function (fiber) {
2000 var maybeStrictRoot = null;
2001 var node = fiber;
2002
2003 while (node !== null) {
2004 if (node.mode & StrictMode) {
2005 maybeStrictRoot = node;
2006 }
2007
2008 node = node.return;
2009 }
2010
2011 return maybeStrictRoot;
2012 };
2013
2014 var setToSortedString = function (set) {
2015 var array = [];
2016 set.forEach(function (value) {
2017 array.push(value);
2018 });
2019 return array.sort().join(', ');
2020 };
2021
2022 var pendingComponentWillMountWarnings = [];
2023 var pendingUNSAFE_ComponentWillMountWarnings = [];
2024 var pendingComponentWillReceivePropsWarnings = [];
2025 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2026 var pendingComponentWillUpdateWarnings = [];
2027 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
2028
2029 var didWarnAboutUnsafeLifecycles = new Set();
2030
2031 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
2032 // Dedup strategy: Warn once per component.
2033 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
2034 return;
2035 }
2036
2037 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.
2038 instance.componentWillMount.__suppressDeprecationWarning !== true) {
2039 pendingComponentWillMountWarnings.push(fiber);
2040 }
2041
2042 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') {
2043 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
2044 }
2045
2046 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
2047 pendingComponentWillReceivePropsWarnings.push(fiber);
2048 }
2049
2050 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
2051 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
2052 }
2053
2054 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
2055 pendingComponentWillUpdateWarnings.push(fiber);
2056 }
2057
2058 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
2059 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
2060 }
2061 };
2062
2063 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
2064 // We do an initial pass to gather component names
2065 var componentWillMountUniqueNames = new Set();
2066
2067 if (pendingComponentWillMountWarnings.length > 0) {
2068 pendingComponentWillMountWarnings.forEach(function (fiber) {
2069 componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2070 didWarnAboutUnsafeLifecycles.add(fiber.type);
2071 });
2072 pendingComponentWillMountWarnings = [];
2073 }
2074
2075 var UNSAFE_componentWillMountUniqueNames = new Set();
2076
2077 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
2078 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
2079 UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2080 didWarnAboutUnsafeLifecycles.add(fiber.type);
2081 });
2082 pendingUNSAFE_ComponentWillMountWarnings = [];
2083 }
2084
2085 var componentWillReceivePropsUniqueNames = new Set();
2086
2087 if (pendingComponentWillReceivePropsWarnings.length > 0) {
2088 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
2089 componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2090 didWarnAboutUnsafeLifecycles.add(fiber.type);
2091 });
2092 pendingComponentWillReceivePropsWarnings = [];
2093 }
2094
2095 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
2096
2097 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
2098 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
2099 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2100 didWarnAboutUnsafeLifecycles.add(fiber.type);
2101 });
2102 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2103 }
2104
2105 var componentWillUpdateUniqueNames = new Set();
2106
2107 if (pendingComponentWillUpdateWarnings.length > 0) {
2108 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
2109 componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
2110 didWarnAboutUnsafeLifecycles.add(fiber.type);
2111 });
2112 pendingComponentWillUpdateWarnings = [];
2113 }
2114
2115 var UNSAFE_componentWillUpdateUniqueNames = new Set();
2116
2117 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
2118 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
2119 UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
2120 didWarnAboutUnsafeLifecycles.add(fiber.type);
2121 });
2122 pendingUNSAFE_ComponentWillUpdateWarnings = [];
2123 } // Finally, we flush all the warnings
2124 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
2125
2126
2127 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
2128 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
2129
2130 error('Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://fb.me/react-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);
2131 }
2132
2133 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
2134 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
2135
2136 error('Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-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://fb.me/react-derived-state\n' + '\nPlease update the following components: %s', _sortedNames);
2137 }
2138
2139 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
2140 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
2141
2142 error('Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '\nPlease update the following components: %s', _sortedNames2);
2143 }
2144
2145 if (componentWillMountUniqueNames.size > 0) {
2146 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
2147
2148 warn('componentWillMount has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-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 17.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);
2149 }
2150
2151 if (componentWillReceivePropsUniqueNames.size > 0) {
2152 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
2153
2154 warn('componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-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://fb.me/react-derived-state\n' + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' + 'this warning in non-strict mode. In React 17.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);
2155 }
2156
2157 if (componentWillUpdateUniqueNames.size > 0) {
2158 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
2159
2160 warn('componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-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 17.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);
2161 }
2162 };
2163
2164 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
2165
2166 var didWarnAboutLegacyContext = new Set();
2167
2168 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
2169 var strictRoot = findStrictRoot(fiber);
2170
2171 if (strictRoot === null) {
2172 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.');
2173
2174 return;
2175 } // Dedup strategy: Warn once per component.
2176
2177
2178 if (didWarnAboutLegacyContext.has(fiber.type)) {
2179 return;
2180 }
2181
2182 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
2183
2184 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
2185 if (warningsForRoot === undefined) {
2186 warningsForRoot = [];
2187 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
2188 }
2189
2190 warningsForRoot.push(fiber);
2191 }
2192 };
2193
2194 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
2195 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
2196 if (fiberArray.length === 0) {
2197 return;
2198 }
2199
2200 var firstFiber = fiberArray[0];
2201 var uniqueNames = new Set();
2202 fiberArray.forEach(function (fiber) {
2203 uniqueNames.add(getComponentName(fiber.type) || 'Component');
2204 didWarnAboutLegacyContext.add(fiber.type);
2205 });
2206 var sortedNames = setToSortedString(uniqueNames);
2207 var firstComponentStack = getStackByFiberInDevAndProd(firstFiber);
2208
2209 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://fb.me/react-legacy-context' + '%s', sortedNames, firstComponentStack);
2210 });
2211 };
2212
2213 ReactStrictModeWarnings.discardPendingWarnings = function () {
2214 pendingComponentWillMountWarnings = [];
2215 pendingUNSAFE_ComponentWillMountWarnings = [];
2216 pendingComponentWillReceivePropsWarnings = [];
2217 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2218 pendingComponentWillUpdateWarnings = [];
2219 pendingUNSAFE_ComponentWillUpdateWarnings = [];
2220 pendingLegacyContextWarning = new Map();
2221 };
2222}
2223
2224var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
2225
2226var failedBoundaries = null;
2227var setRefreshHandler = function (handler) {
2228 {
2229 resolveFamily = handler;
2230 }
2231};
2232function resolveFunctionForHotReloading(type) {
2233 {
2234 if (resolveFamily === null) {
2235 // Hot reloading is disabled.
2236 return type;
2237 }
2238
2239 var family = resolveFamily(type);
2240
2241 if (family === undefined) {
2242 return type;
2243 } // Use the latest known implementation.
2244
2245
2246 return family.current;
2247 }
2248}
2249function resolveClassForHotReloading(type) {
2250 // No implementation differences.
2251 return resolveFunctionForHotReloading(type);
2252}
2253function resolveForwardRefForHotReloading(type) {
2254 {
2255 if (resolveFamily === null) {
2256 // Hot reloading is disabled.
2257 return type;
2258 }
2259
2260 var family = resolveFamily(type);
2261
2262 if (family === undefined) {
2263 // Check if we're dealing with a real forwardRef. Don't want to crash early.
2264 if (type !== null && type !== undefined && typeof type.render === 'function') {
2265 // ForwardRef is special because its resolved .type is an object,
2266 // but it's possible that we only have its inner render function in the map.
2267 // If that inner render function is different, we'll build a new forwardRef type.
2268 var currentRender = resolveFunctionForHotReloading(type.render);
2269
2270 if (type.render !== currentRender) {
2271 var syntheticType = {
2272 $$typeof: REACT_FORWARD_REF_TYPE,
2273 render: currentRender
2274 };
2275
2276 if (type.displayName !== undefined) {
2277 syntheticType.displayName = type.displayName;
2278 }
2279
2280 return syntheticType;
2281 }
2282 }
2283
2284 return type;
2285 } // Use the latest known implementation.
2286
2287
2288 return family.current;
2289 }
2290}
2291function isCompatibleFamilyForHotReloading(fiber, element) {
2292 {
2293 if (resolveFamily === null) {
2294 // Hot reloading is disabled.
2295 return false;
2296 }
2297
2298 var prevType = fiber.elementType;
2299 var nextType = element.type; // If we got here, we know types aren't === equal.
2300
2301 var needsCompareFamilies = false;
2302 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
2303
2304 switch (fiber.tag) {
2305 case ClassComponent:
2306 {
2307 if (typeof nextType === 'function') {
2308 needsCompareFamilies = true;
2309 }
2310
2311 break;
2312 }
2313
2314 case FunctionComponent:
2315 {
2316 if (typeof nextType === 'function') {
2317 needsCompareFamilies = true;
2318 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2319 // We don't know the inner type yet.
2320 // We're going to assume that the lazy inner type is stable,
2321 // and so it is sufficient to avoid reconciling it away.
2322 // We're not going to unwrap or actually use the new lazy type.
2323 needsCompareFamilies = true;
2324 }
2325
2326 break;
2327 }
2328
2329 case ForwardRef:
2330 {
2331 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
2332 needsCompareFamilies = true;
2333 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2334 needsCompareFamilies = true;
2335 }
2336
2337 break;
2338 }
2339
2340 case MemoComponent:
2341 case SimpleMemoComponent:
2342 {
2343 if ($$typeofNextType === REACT_MEMO_TYPE) {
2344 // TODO: if it was but can no longer be simple,
2345 // we shouldn't set this.
2346 needsCompareFamilies = true;
2347 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2348 needsCompareFamilies = true;
2349 }
2350
2351 break;
2352 }
2353
2354 default:
2355 return false;
2356 } // Check if both types have a family and it's the same one.
2357
2358
2359 if (needsCompareFamilies) {
2360 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
2361 // This means both of them need to be registered to preserve state.
2362 // If we unwrapped and compared the inner types for wrappers instead,
2363 // then we would risk falsely saying two separate memo(Foo)
2364 // calls are equivalent because they wrap the same Foo function.
2365 var prevFamily = resolveFamily(prevType);
2366
2367 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
2368 return true;
2369 }
2370 }
2371
2372 return false;
2373 }
2374}
2375function markFailedErrorBoundaryForHotReloading(fiber) {
2376 {
2377 if (resolveFamily === null) {
2378 // Hot reloading is disabled.
2379 return;
2380 }
2381
2382 if (typeof WeakSet !== 'function') {
2383 return;
2384 }
2385
2386 if (failedBoundaries === null) {
2387 failedBoundaries = new WeakSet();
2388 }
2389
2390 failedBoundaries.add(fiber);
2391 }
2392}
2393var scheduleRefresh = function (root, update) {
2394 {
2395 if (resolveFamily === null) {
2396 // Hot reloading is disabled.
2397 return;
2398 }
2399
2400 var staleFamilies = update.staleFamilies,
2401 updatedFamilies = update.updatedFamilies;
2402 flushPassiveEffects();
2403 flushSync(function () {
2404 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
2405 });
2406 }
2407};
2408var scheduleRoot = function (root, element) {
2409 {
2410 if (root.context !== emptyContextObject) {
2411 // Super edge case: root has a legacy _renderSubtree context
2412 // but we don't know the parentComponent so we can't pass it.
2413 // Just ignore. We'll delete this with _renderSubtree code path later.
2414 return;
2415 }
2416
2417 flushPassiveEffects();
2418 syncUpdates(function () {
2419 updateContainer(element, root, null, null);
2420 });
2421 }
2422};
2423
2424function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
2425 {
2426 var alternate = fiber.alternate,
2427 child = fiber.child,
2428 sibling = fiber.sibling,
2429 tag = fiber.tag,
2430 type = fiber.type;
2431 var candidateType = null;
2432
2433 switch (tag) {
2434 case FunctionComponent:
2435 case SimpleMemoComponent:
2436 case ClassComponent:
2437 candidateType = type;
2438 break;
2439
2440 case ForwardRef:
2441 candidateType = type.render;
2442 break;
2443 }
2444
2445 if (resolveFamily === null) {
2446 throw new Error('Expected resolveFamily to be set during hot reload.');
2447 }
2448
2449 var needsRender = false;
2450 var needsRemount = false;
2451
2452 if (candidateType !== null) {
2453 var family = resolveFamily(candidateType);
2454
2455 if (family !== undefined) {
2456 if (staleFamilies.has(family)) {
2457 needsRemount = true;
2458 } else if (updatedFamilies.has(family)) {
2459 if (tag === ClassComponent) {
2460 needsRemount = true;
2461 } else {
2462 needsRender = true;
2463 }
2464 }
2465 }
2466 }
2467
2468 if (failedBoundaries !== null) {
2469 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
2470 needsRemount = true;
2471 }
2472 }
2473
2474 if (needsRemount) {
2475 fiber._debugNeedsRemount = true;
2476 }
2477
2478 if (needsRemount || needsRender) {
2479 scheduleWork(fiber, Sync);
2480 }
2481
2482 if (child !== null && !needsRemount) {
2483 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
2484 }
2485
2486 if (sibling !== null) {
2487 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
2488 }
2489 }
2490}
2491
2492var findHostInstancesForRefresh = function (root, families) {
2493 {
2494 var hostInstances = new Set();
2495 var types = new Set(families.map(function (family) {
2496 return family.current;
2497 }));
2498 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
2499 return hostInstances;
2500 }
2501};
2502
2503function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
2504 {
2505 var child = fiber.child,
2506 sibling = fiber.sibling,
2507 tag = fiber.tag,
2508 type = fiber.type;
2509 var candidateType = null;
2510
2511 switch (tag) {
2512 case FunctionComponent:
2513 case SimpleMemoComponent:
2514 case ClassComponent:
2515 candidateType = type;
2516 break;
2517
2518 case ForwardRef:
2519 candidateType = type.render;
2520 break;
2521 }
2522
2523 var didMatch = false;
2524
2525 if (candidateType !== null) {
2526 if (types.has(candidateType)) {
2527 didMatch = true;
2528 }
2529 }
2530
2531 if (didMatch) {
2532 // We have a match. This only drills down to the closest host components.
2533 // There's no need to search deeper because for the purpose of giving
2534 // visual feedback, "flashing" outermost parent rectangles is sufficient.
2535 findHostInstancesForFiberShallowly(fiber, hostInstances);
2536 } else {
2537 // If there's no match, maybe there will be one further down in the child tree.
2538 if (child !== null) {
2539 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
2540 }
2541 }
2542
2543 if (sibling !== null) {
2544 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
2545 }
2546 }
2547}
2548
2549function findHostInstancesForFiberShallowly(fiber, hostInstances) {
2550 {
2551 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
2552
2553 if (foundHostInstances) {
2554 return;
2555 } // If we didn't find any host children, fallback to closest host parent.
2556
2557
2558 var node = fiber;
2559
2560 while (true) {
2561 switch (node.tag) {
2562 case HostComponent:
2563 hostInstances.add(node.stateNode);
2564 return;
2565
2566 case HostPortal:
2567 hostInstances.add(node.stateNode.containerInfo);
2568 return;
2569
2570 case HostRoot:
2571 hostInstances.add(node.stateNode.containerInfo);
2572 return;
2573 }
2574
2575 if (node.return === null) {
2576 throw new Error('Expected to reach root first.');
2577 }
2578
2579 node = node.return;
2580 }
2581 }
2582}
2583
2584function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
2585 {
2586 var node = fiber;
2587 var foundHostInstances = false;
2588
2589 while (true) {
2590 if (node.tag === HostComponent) {
2591 // We got a match.
2592 foundHostInstances = true;
2593 hostInstances.add(node.stateNode); // There may still be more, so keep searching.
2594 } else if (node.child !== null) {
2595 node.child.return = node;
2596 node = node.child;
2597 continue;
2598 }
2599
2600 if (node === fiber) {
2601 return foundHostInstances;
2602 }
2603
2604 while (node.sibling === null) {
2605 if (node.return === null || node.return === fiber) {
2606 return foundHostInstances;
2607 }
2608
2609 node = node.return;
2610 }
2611
2612 node.sibling.return = node.return;
2613 node = node.sibling;
2614 }
2615 }
2616
2617 return false;
2618}
2619
2620function resolveDefaultProps(Component, baseProps) {
2621 if (Component && Component.defaultProps) {
2622 // Resolve default props. Taken from ReactElement
2623 var props = _assign({}, baseProps);
2624
2625 var defaultProps = Component.defaultProps;
2626
2627 for (var propName in defaultProps) {
2628 if (props[propName] === undefined) {
2629 props[propName] = defaultProps[propName];
2630 }
2631 }
2632
2633 return props;
2634 }
2635
2636 return baseProps;
2637}
2638function readLazyComponentType(lazyComponent) {
2639 initializeLazyComponentType(lazyComponent);
2640
2641 if (lazyComponent._status !== Resolved) {
2642 throw lazyComponent._result;
2643 }
2644
2645 return lazyComponent._result;
2646}
2647
2648var valueCursor = createCursor(null);
2649var rendererSigil;
2650
2651{
2652 // Use this to detect multiple renderers using the same context
2653 rendererSigil = {};
2654}
2655
2656var currentlyRenderingFiber = null;
2657var lastContextDependency = null;
2658var lastContextWithAllBitsObserved = null;
2659var isDisallowedContextReadInDEV = false;
2660function resetContextDependencies() {
2661 // This is called right before React yields execution, to ensure `readContext`
2662 // cannot be called outside the render phase.
2663 currentlyRenderingFiber = null;
2664 lastContextDependency = null;
2665 lastContextWithAllBitsObserved = null;
2666
2667 {
2668 isDisallowedContextReadInDEV = false;
2669 }
2670}
2671function enterDisallowedContextReadInDEV() {
2672 {
2673 isDisallowedContextReadInDEV = true;
2674 }
2675}
2676function exitDisallowedContextReadInDEV() {
2677 {
2678 isDisallowedContextReadInDEV = false;
2679 }
2680}
2681function pushProvider(providerFiber, nextValue) {
2682 var context = providerFiber.type._context;
2683
2684 {
2685 push(valueCursor, context._currentValue2, providerFiber);
2686 context._currentValue2 = nextValue;
2687
2688 {
2689 if (context._currentRenderer2 !== undefined && context._currentRenderer2 !== null && context._currentRenderer2 !== rendererSigil) {
2690 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.');
2691 }
2692
2693 context._currentRenderer2 = rendererSigil;
2694 }
2695 }
2696}
2697function popProvider(providerFiber) {
2698 var currentValue = valueCursor.current;
2699 pop(valueCursor, providerFiber);
2700 var context = providerFiber.type._context;
2701
2702 {
2703 context._currentValue2 = currentValue;
2704 }
2705}
2706function calculateChangedBits(context, newValue, oldValue) {
2707 if (objectIs(oldValue, newValue)) {
2708 // No change
2709 return 0;
2710 } else {
2711 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
2712
2713 {
2714 if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) {
2715 error('calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits);
2716 }
2717 }
2718
2719 return changedBits | 0;
2720 }
2721}
2722function scheduleWorkOnParentPath(parent, renderExpirationTime) {
2723 // Update the child expiration time of all the ancestors, including
2724 // the alternates.
2725 var node = parent;
2726
2727 while (node !== null) {
2728 var alternate = node.alternate;
2729
2730 if (node.childExpirationTime < renderExpirationTime) {
2731 node.childExpirationTime = renderExpirationTime;
2732
2733 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
2734 alternate.childExpirationTime = renderExpirationTime;
2735 }
2736 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
2737 alternate.childExpirationTime = renderExpirationTime;
2738 } else {
2739 // Neither alternate was updated, which means the rest of the
2740 // ancestor path already has sufficient priority.
2741 break;
2742 }
2743
2744 node = node.return;
2745 }
2746}
2747function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
2748 var fiber = workInProgress.child;
2749
2750 if (fiber !== null) {
2751 // Set the return pointer of the child to the work-in-progress fiber.
2752 fiber.return = workInProgress;
2753 }
2754
2755 while (fiber !== null) {
2756 var nextFiber = void 0; // Visit this fiber.
2757
2758 var list = fiber.dependencies;
2759
2760 if (list !== null) {
2761 nextFiber = fiber.child;
2762 var dependency = list.firstContext;
2763
2764 while (dependency !== null) {
2765 // Check if the context matches.
2766 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
2767 // Match! Schedule an update on this fiber.
2768 if (fiber.tag === ClassComponent) {
2769 // Schedule a force update on the work-in-progress.
2770 var update = createUpdate(renderExpirationTime, null);
2771 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
2772 // update to the current fiber, too, which means it will persist even if
2773 // this render is thrown away. Since it's a race condition, not sure it's
2774 // worth fixing.
2775
2776 enqueueUpdate(fiber, update);
2777 }
2778
2779 if (fiber.expirationTime < renderExpirationTime) {
2780 fiber.expirationTime = renderExpirationTime;
2781 }
2782
2783 var alternate = fiber.alternate;
2784
2785 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
2786 alternate.expirationTime = renderExpirationTime;
2787 }
2788
2789 scheduleWorkOnParentPath(fiber.return, renderExpirationTime); // Mark the expiration time on the list, too.
2790
2791 if (list.expirationTime < renderExpirationTime) {
2792 list.expirationTime = renderExpirationTime;
2793 } // Since we already found a match, we can stop traversing the
2794 // dependency list.
2795
2796
2797 break;
2798 }
2799
2800 dependency = dependency.next;
2801 }
2802 } else if (fiber.tag === ContextProvider) {
2803 // Don't scan deeper if this is a matching provider
2804 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
2805 } else {
2806 // Traverse down.
2807 nextFiber = fiber.child;
2808 }
2809
2810 if (nextFiber !== null) {
2811 // Set the return pointer of the child to the work-in-progress fiber.
2812 nextFiber.return = fiber;
2813 } else {
2814 // No child. Traverse to next sibling.
2815 nextFiber = fiber;
2816
2817 while (nextFiber !== null) {
2818 if (nextFiber === workInProgress) {
2819 // We're back to the root of this subtree. Exit.
2820 nextFiber = null;
2821 break;
2822 }
2823
2824 var sibling = nextFiber.sibling;
2825
2826 if (sibling !== null) {
2827 // Set the return pointer of the sibling to the work-in-progress fiber.
2828 sibling.return = nextFiber.return;
2829 nextFiber = sibling;
2830 break;
2831 } // No more siblings. Traverse up.
2832
2833
2834 nextFiber = nextFiber.return;
2835 }
2836 }
2837
2838 fiber = nextFiber;
2839 }
2840}
2841function prepareToReadContext(workInProgress, renderExpirationTime) {
2842 currentlyRenderingFiber = workInProgress;
2843 lastContextDependency = null;
2844 lastContextWithAllBitsObserved = null;
2845 var dependencies = workInProgress.dependencies;
2846
2847 if (dependencies !== null) {
2848 var firstContext = dependencies.firstContext;
2849
2850 if (firstContext !== null) {
2851 if (dependencies.expirationTime >= renderExpirationTime) {
2852 // Context list has a pending update. Mark that this fiber performed work.
2853 markWorkInProgressReceivedUpdate();
2854 } // Reset the work-in-progress list
2855
2856
2857 dependencies.firstContext = null;
2858 }
2859 }
2860}
2861function readContext(context, observedBits) {
2862 {
2863 // This warning would fire if you read context inside a Hook like useMemo.
2864 // Unlike the class check below, it's not enforced in production for perf.
2865 if (isDisallowedContextReadInDEV) {
2866 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().');
2867 }
2868 }
2869
2870 if (lastContextWithAllBitsObserved === context) ; else if (observedBits === false || observedBits === 0) ; else {
2871 var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types.
2872
2873 if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) {
2874 // Observe all updates.
2875 lastContextWithAllBitsObserved = context;
2876 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
2877 } else {
2878 resolvedObservedBits = observedBits;
2879 }
2880
2881 var contextItem = {
2882 context: context,
2883 observedBits: resolvedObservedBits,
2884 next: null
2885 };
2886
2887 if (lastContextDependency === null) {
2888 if (!(currentlyRenderingFiber !== null)) {
2889 {
2890 throw 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()." );
2891 }
2892 } // This is the first dependency for this component. Create a new list.
2893
2894
2895 lastContextDependency = contextItem;
2896 currentlyRenderingFiber.dependencies = {
2897 expirationTime: NoWork,
2898 firstContext: contextItem,
2899 responders: null
2900 };
2901 } else {
2902 // Append a new context item.
2903 lastContextDependency = lastContextDependency.next = contextItem;
2904 }
2905 }
2906
2907 return context._currentValue2;
2908}
2909
2910var UpdateState = 0;
2911var ReplaceState = 1;
2912var ForceUpdate = 2;
2913var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
2914// It should only be read right after calling `processUpdateQueue`, via
2915// `checkHasForceUpdateAfterProcessing`.
2916
2917var hasForceUpdate = false;
2918var didWarnUpdateInsideUpdate;
2919var currentlyProcessingQueue;
2920
2921{
2922 didWarnUpdateInsideUpdate = false;
2923 currentlyProcessingQueue = null;
2924}
2925
2926function initializeUpdateQueue(fiber) {
2927 var queue = {
2928 baseState: fiber.memoizedState,
2929 baseQueue: null,
2930 shared: {
2931 pending: null
2932 },
2933 effects: null
2934 };
2935 fiber.updateQueue = queue;
2936}
2937function cloneUpdateQueue(current, workInProgress) {
2938 // Clone the update queue from current. Unless it's already a clone.
2939 var queue = workInProgress.updateQueue;
2940 var currentQueue = current.updateQueue;
2941
2942 if (queue === currentQueue) {
2943 var clone = {
2944 baseState: currentQueue.baseState,
2945 baseQueue: currentQueue.baseQueue,
2946 shared: currentQueue.shared,
2947 effects: currentQueue.effects
2948 };
2949 workInProgress.updateQueue = clone;
2950 }
2951}
2952function createUpdate(expirationTime, suspenseConfig) {
2953 var update = {
2954 expirationTime: expirationTime,
2955 suspenseConfig: suspenseConfig,
2956 tag: UpdateState,
2957 payload: null,
2958 callback: null,
2959 next: null
2960 };
2961 update.next = update;
2962
2963 {
2964 update.priority = getCurrentPriorityLevel();
2965 }
2966
2967 return update;
2968}
2969function enqueueUpdate(fiber, update) {
2970 var updateQueue = fiber.updateQueue;
2971
2972 if (updateQueue === null) {
2973 // Only occurs if the fiber has been unmounted.
2974 return;
2975 }
2976
2977 var sharedQueue = updateQueue.shared;
2978 var pending = sharedQueue.pending;
2979
2980 if (pending === null) {
2981 // This is the first update. Create a circular list.
2982 update.next = update;
2983 } else {
2984 update.next = pending.next;
2985 pending.next = update;
2986 }
2987
2988 sharedQueue.pending = update;
2989
2990 {
2991 if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) {
2992 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.');
2993
2994 didWarnUpdateInsideUpdate = true;
2995 }
2996 }
2997}
2998function enqueueCapturedUpdate(workInProgress, update) {
2999 var current = workInProgress.alternate;
3000
3001 if (current !== null) {
3002 // Ensure the work-in-progress queue is a clone
3003 cloneUpdateQueue(current, workInProgress);
3004 } // Captured updates go only on the work-in-progress queue.
3005
3006
3007 var queue = workInProgress.updateQueue; // Append the update to the end of the list.
3008
3009 var last = queue.baseQueue;
3010
3011 if (last === null) {
3012 queue.baseQueue = update.next = update;
3013 update.next = update;
3014 } else {
3015 update.next = last.next;
3016 last.next = update;
3017 }
3018}
3019
3020function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
3021 switch (update.tag) {
3022 case ReplaceState:
3023 {
3024 var payload = update.payload;
3025
3026 if (typeof payload === 'function') {
3027 // Updater function
3028 {
3029 enterDisallowedContextReadInDEV();
3030 }
3031
3032 var nextState = payload.call(instance, prevState, nextProps);
3033
3034 {
3035 exitDisallowedContextReadInDEV();
3036 }
3037
3038 return nextState;
3039 } // State object
3040
3041
3042 return payload;
3043 }
3044
3045 case CaptureUpdate:
3046 {
3047 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
3048 }
3049 // Intentional fallthrough
3050
3051 case UpdateState:
3052 {
3053 var _payload = update.payload;
3054 var partialState;
3055
3056 if (typeof _payload === 'function') {
3057 // Updater function
3058 {
3059 enterDisallowedContextReadInDEV();
3060 }
3061
3062 partialState = _payload.call(instance, prevState, nextProps);
3063
3064 {
3065 exitDisallowedContextReadInDEV();
3066 }
3067 } else {
3068 // Partial state object
3069 partialState = _payload;
3070 }
3071
3072 if (partialState === null || partialState === undefined) {
3073 // Null and undefined are treated as no-ops.
3074 return prevState;
3075 } // Merge the partial state and the previous state.
3076
3077
3078 return _assign({}, prevState, partialState);
3079 }
3080
3081 case ForceUpdate:
3082 {
3083 hasForceUpdate = true;
3084 return prevState;
3085 }
3086 }
3087
3088 return prevState;
3089}
3090
3091function processUpdateQueue(workInProgress, props, instance, renderExpirationTime) {
3092 // This is always non-null on a ClassComponent or HostRoot
3093 var queue = workInProgress.updateQueue;
3094 hasForceUpdate = false;
3095
3096 {
3097 currentlyProcessingQueue = queue.shared;
3098 } // The last rebase update that is NOT part of the base state.
3099
3100
3101 var baseQueue = queue.baseQueue; // The last pending update that hasn't been processed yet.
3102
3103 var pendingQueue = queue.shared.pending;
3104
3105 if (pendingQueue !== null) {
3106 // We have new updates that haven't been processed yet.
3107 // We'll add them to the base queue.
3108 if (baseQueue !== null) {
3109 // Merge the pending queue and the base queue.
3110 var baseFirst = baseQueue.next;
3111 var pendingFirst = pendingQueue.next;
3112 baseQueue.next = pendingFirst;
3113 pendingQueue.next = baseFirst;
3114 }
3115
3116 baseQueue = pendingQueue;
3117 queue.shared.pending = null; // TODO: Pass `current` as argument
3118
3119 var current = workInProgress.alternate;
3120
3121 if (current !== null) {
3122 var currentQueue = current.updateQueue;
3123
3124 if (currentQueue !== null) {
3125 currentQueue.baseQueue = pendingQueue;
3126 }
3127 }
3128 } // These values may change as we process the queue.
3129
3130
3131 if (baseQueue !== null) {
3132 var first = baseQueue.next; // Iterate through the list of updates to compute the result.
3133
3134 var newState = queue.baseState;
3135 var newExpirationTime = NoWork;
3136 var newBaseState = null;
3137 var newBaseQueueFirst = null;
3138 var newBaseQueueLast = null;
3139
3140 if (first !== null) {
3141 var update = first;
3142
3143 do {
3144 var updateExpirationTime = update.expirationTime;
3145
3146 if (updateExpirationTime < renderExpirationTime) {
3147 // Priority is insufficient. Skip this update. If this is the first
3148 // skipped update, the previous update/state is the new base
3149 // update/state.
3150 var clone = {
3151 expirationTime: update.expirationTime,
3152 suspenseConfig: update.suspenseConfig,
3153 tag: update.tag,
3154 payload: update.payload,
3155 callback: update.callback,
3156 next: null
3157 };
3158
3159 if (newBaseQueueLast === null) {
3160 newBaseQueueFirst = newBaseQueueLast = clone;
3161 newBaseState = newState;
3162 } else {
3163 newBaseQueueLast = newBaseQueueLast.next = clone;
3164 } // Update the remaining priority in the queue.
3165
3166
3167 if (updateExpirationTime > newExpirationTime) {
3168 newExpirationTime = updateExpirationTime;
3169 }
3170 } else {
3171 // This update does have sufficient priority.
3172 if (newBaseQueueLast !== null) {
3173 var _clone = {
3174 expirationTime: Sync,
3175 // This update is going to be committed so we never want uncommit it.
3176 suspenseConfig: update.suspenseConfig,
3177 tag: update.tag,
3178 payload: update.payload,
3179 callback: update.callback,
3180 next: null
3181 };
3182 newBaseQueueLast = newBaseQueueLast.next = _clone;
3183 } // Mark the event time of this update as relevant to this render pass.
3184 // TODO: This should ideally use the true event time of this update rather than
3185 // its priority which is a derived and not reverseable value.
3186 // TODO: We should skip this update if it was already committed but currently
3187 // we have no way of detecting the difference between a committed and suspended
3188 // update here.
3189
3190
3191 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process this update.
3192
3193 newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance);
3194 var callback = update.callback;
3195
3196 if (callback !== null) {
3197 workInProgress.effectTag |= Callback;
3198 var effects = queue.effects;
3199
3200 if (effects === null) {
3201 queue.effects = [update];
3202 } else {
3203 effects.push(update);
3204 }
3205 }
3206 }
3207
3208 update = update.next;
3209
3210 if (update === null || update === first) {
3211 pendingQueue = queue.shared.pending;
3212
3213 if (pendingQueue === null) {
3214 break;
3215 } else {
3216 // An update was scheduled from inside a reducer. Add the new
3217 // pending updates to the end of the list and keep processing.
3218 update = baseQueue.next = pendingQueue.next;
3219 pendingQueue.next = first;
3220 queue.baseQueue = baseQueue = pendingQueue;
3221 queue.shared.pending = null;
3222 }
3223 }
3224 } while (true);
3225 }
3226
3227 if (newBaseQueueLast === null) {
3228 newBaseState = newState;
3229 } else {
3230 newBaseQueueLast.next = newBaseQueueFirst;
3231 }
3232
3233 queue.baseState = newBaseState;
3234 queue.baseQueue = newBaseQueueLast; // Set the remaining expiration time to be whatever is remaining in the queue.
3235 // This should be fine because the only two other things that contribute to
3236 // expiration time are props and context. We're already in the middle of the
3237 // begin phase by the time we start processing the queue, so we've already
3238 // dealt with the props. Context in components that specify
3239 // shouldComponentUpdate is tricky; but we'll have to account for
3240 // that regardless.
3241
3242 markUnprocessedUpdateTime(newExpirationTime);
3243 workInProgress.expirationTime = newExpirationTime;
3244 workInProgress.memoizedState = newState;
3245 }
3246
3247 {
3248 currentlyProcessingQueue = null;
3249 }
3250}
3251
3252function callCallback(callback, context) {
3253 if (!(typeof callback === 'function')) {
3254 {
3255 throw Error( "Invalid argument passed as callback. Expected a function. Instead received: " + callback );
3256 }
3257 }
3258
3259 callback.call(context);
3260}
3261
3262function resetHasForceUpdateBeforeProcessing() {
3263 hasForceUpdate = false;
3264}
3265function checkHasForceUpdateAfterProcessing() {
3266 return hasForceUpdate;
3267}
3268function commitUpdateQueue(finishedWork, finishedQueue, instance) {
3269 // Commit the effects
3270 var effects = finishedQueue.effects;
3271 finishedQueue.effects = null;
3272
3273 if (effects !== null) {
3274 for (var i = 0; i < effects.length; i++) {
3275 var effect = effects[i];
3276 var callback = effect.callback;
3277
3278 if (callback !== null) {
3279 effect.callback = null;
3280 callCallback(callback, instance);
3281 }
3282 }
3283 }
3284}
3285
3286var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
3287function requestCurrentSuspenseConfig() {
3288 return ReactCurrentBatchConfig.suspense;
3289}
3290
3291var fakeInternalInstance = {};
3292var isArray = Array.isArray; // React.Component uses a shared frozen object by default.
3293// We'll use it to determine whether we need to initialize legacy refs.
3294
3295var emptyRefsObject = new React.Component().refs;
3296var didWarnAboutStateAssignmentForComponent;
3297var didWarnAboutUninitializedState;
3298var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
3299var didWarnAboutLegacyLifecyclesAndDerivedState;
3300var didWarnAboutUndefinedDerivedState;
3301var warnOnUndefinedDerivedState;
3302var warnOnInvalidCallback;
3303var didWarnAboutDirectlyAssigningPropsToState;
3304var didWarnAboutContextTypeAndContextTypes;
3305var didWarnAboutInvalidateContextType;
3306
3307{
3308 didWarnAboutStateAssignmentForComponent = new Set();
3309 didWarnAboutUninitializedState = new Set();
3310 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
3311 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
3312 didWarnAboutDirectlyAssigningPropsToState = new Set();
3313 didWarnAboutUndefinedDerivedState = new Set();
3314 didWarnAboutContextTypeAndContextTypes = new Set();
3315 didWarnAboutInvalidateContextType = new Set();
3316 var didWarnOnInvalidCallback = new Set();
3317
3318 warnOnInvalidCallback = function (callback, callerName) {
3319 if (callback === null || typeof callback === 'function') {
3320 return;
3321 }
3322
3323 var key = callerName + "_" + callback;
3324
3325 if (!didWarnOnInvalidCallback.has(key)) {
3326 didWarnOnInvalidCallback.add(key);
3327
3328 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
3329 }
3330 };
3331
3332 warnOnUndefinedDerivedState = function (type, partialState) {
3333 if (partialState === undefined) {
3334 var componentName = getComponentName(type) || 'Component';
3335
3336 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
3337 didWarnAboutUndefinedDerivedState.add(componentName);
3338
3339 error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
3340 }
3341 }
3342 }; // This is so gross but it's at least non-critical and can be removed if
3343 // it causes problems. This is meant to give a nicer error message for
3344 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
3345 // ...)) which otherwise throws a "_processChildContext is not a function"
3346 // exception.
3347
3348
3349 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
3350 enumerable: false,
3351 value: function () {
3352 {
3353 {
3354 throw 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)." );
3355 }
3356 }
3357 }
3358 });
3359 Object.freeze(fakeInternalInstance);
3360}
3361
3362function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
3363 var prevState = workInProgress.memoizedState;
3364
3365 var partialState = getDerivedStateFromProps(nextProps, prevState);
3366
3367 {
3368 warnOnUndefinedDerivedState(ctor, partialState);
3369 } // Merge the partial state and the previous state.
3370
3371
3372 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
3373 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
3374 // base state.
3375
3376 if (workInProgress.expirationTime === NoWork) {
3377 // Queue is always non-null for classes
3378 var updateQueue = workInProgress.updateQueue;
3379 updateQueue.baseState = memoizedState;
3380 }
3381}
3382var classComponentUpdater = {
3383 isMounted: isMounted,
3384 enqueueSetState: function (inst, payload, callback) {
3385 var fiber = get(inst);
3386 var currentTime = requestCurrentTimeForUpdate();
3387 var suspenseConfig = requestCurrentSuspenseConfig();
3388 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3389 var update = createUpdate(expirationTime, suspenseConfig);
3390 update.payload = payload;
3391
3392 if (callback !== undefined && callback !== null) {
3393 {
3394 warnOnInvalidCallback(callback, 'setState');
3395 }
3396
3397 update.callback = callback;
3398 }
3399
3400 enqueueUpdate(fiber, update);
3401 scheduleWork(fiber, expirationTime);
3402 },
3403 enqueueReplaceState: function (inst, payload, callback) {
3404 var fiber = get(inst);
3405 var currentTime = requestCurrentTimeForUpdate();
3406 var suspenseConfig = requestCurrentSuspenseConfig();
3407 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3408 var update = createUpdate(expirationTime, suspenseConfig);
3409 update.tag = ReplaceState;
3410 update.payload = payload;
3411
3412 if (callback !== undefined && callback !== null) {
3413 {
3414 warnOnInvalidCallback(callback, 'replaceState');
3415 }
3416
3417 update.callback = callback;
3418 }
3419
3420 enqueueUpdate(fiber, update);
3421 scheduleWork(fiber, expirationTime);
3422 },
3423 enqueueForceUpdate: function (inst, callback) {
3424 var fiber = get(inst);
3425 var currentTime = requestCurrentTimeForUpdate();
3426 var suspenseConfig = requestCurrentSuspenseConfig();
3427 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3428 var update = createUpdate(expirationTime, suspenseConfig);
3429 update.tag = ForceUpdate;
3430
3431 if (callback !== undefined && callback !== null) {
3432 {
3433 warnOnInvalidCallback(callback, 'forceUpdate');
3434 }
3435
3436 update.callback = callback;
3437 }
3438
3439 enqueueUpdate(fiber, update);
3440 scheduleWork(fiber, expirationTime);
3441 }
3442};
3443
3444function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
3445 var instance = workInProgress.stateNode;
3446
3447 if (typeof instance.shouldComponentUpdate === 'function') {
3448
3449 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
3450 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
3451 stopPhaseTimer();
3452
3453 {
3454 if (shouldUpdate === undefined) {
3455 error('%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component');
3456 }
3457 }
3458
3459 return shouldUpdate;
3460 }
3461
3462 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
3463 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
3464 }
3465
3466 return true;
3467}
3468
3469function checkClassInstance(workInProgress, ctor, newProps) {
3470 var instance = workInProgress.stateNode;
3471
3472 {
3473 var name = getComponentName(ctor) || 'Component';
3474 var renderPresent = instance.render;
3475
3476 if (!renderPresent) {
3477 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
3478 error('%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
3479 } else {
3480 error('%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
3481 }
3482 }
3483
3484 if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) {
3485 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);
3486 }
3487
3488 if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) {
3489 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);
3490 }
3491
3492 if (instance.propTypes) {
3493 error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
3494 }
3495
3496 if (instance.contextType) {
3497 error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name);
3498 }
3499
3500 {
3501 if (instance.contextTypes) {
3502 error('contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
3503 }
3504
3505 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
3506 didWarnAboutContextTypeAndContextTypes.add(ctor);
3507
3508 error('%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
3509 }
3510 }
3511
3512 if (typeof instance.componentShouldUpdate === 'function') {
3513 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);
3514 }
3515
3516 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
3517 error('%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentName(ctor) || 'A pure component');
3518 }
3519
3520 if (typeof instance.componentDidUnmount === 'function') {
3521 error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
3522 }
3523
3524 if (typeof instance.componentDidReceiveProps === 'function') {
3525 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);
3526 }
3527
3528 if (typeof instance.componentWillRecieveProps === 'function') {
3529 error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
3530 }
3531
3532 if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') {
3533 error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);
3534 }
3535
3536 var hasMutatedProps = instance.props !== newProps;
3537
3538 if (instance.props !== undefined && hasMutatedProps) {
3539 error('%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name);
3540 }
3541
3542 if (instance.defaultProps) {
3543 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);
3544 }
3545
3546 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
3547 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
3548
3549 error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
3550 }
3551
3552 if (typeof instance.getDerivedStateFromProps === 'function') {
3553 error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
3554 }
3555
3556 if (typeof instance.getDerivedStateFromError === 'function') {
3557 error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
3558 }
3559
3560 if (typeof ctor.getSnapshotBeforeUpdate === 'function') {
3561 error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name);
3562 }
3563
3564 var _state = instance.state;
3565
3566 if (_state && (typeof _state !== 'object' || isArray(_state))) {
3567 error('%s.state: must be set to an object or null', name);
3568 }
3569
3570 if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') {
3571 error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name);
3572 }
3573 }
3574}
3575
3576function adoptClassInstance(workInProgress, instance) {
3577 instance.updater = classComponentUpdater;
3578 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
3579
3580 set(instance, workInProgress);
3581
3582 {
3583 instance._reactInternalInstance = fakeInternalInstance;
3584 }
3585}
3586
3587function constructClassInstance(workInProgress, ctor, props) {
3588 var isLegacyContextConsumer = false;
3589 var unmaskedContext = emptyContextObject;
3590 var context = emptyContextObject;
3591 var contextType = ctor.contextType;
3592
3593 {
3594 if ('contextType' in ctor) {
3595 var isValid = // Allow null for conditional declaration
3596 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
3597
3598 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
3599 didWarnAboutInvalidateContextType.add(ctor);
3600 var addendum = '';
3601
3602 if (contextType === undefined) {
3603 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.';
3604 } else if (typeof contextType !== 'object') {
3605 addendum = ' However, it is set to a ' + typeof contextType + '.';
3606 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
3607 addendum = ' Did you accidentally pass the Context.Provider instead?';
3608 } else if (contextType._context !== undefined) {
3609 // <Context.Consumer>
3610 addendum = ' Did you accidentally pass the Context.Consumer instead?';
3611 } else {
3612 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
3613 }
3614
3615 error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
3616 }
3617 }
3618 }
3619
3620 if (typeof contextType === 'object' && contextType !== null) {
3621 context = readContext(contextType);
3622 } else {
3623 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
3624 var contextTypes = ctor.contextTypes;
3625 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
3626 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
3627 } // Instantiate twice to help detect side-effects.
3628
3629 var instance = new ctor(props, context);
3630 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
3631 adoptClassInstance(workInProgress, instance);
3632
3633 {
3634 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
3635 var componentName = getComponentName(ctor) || 'Component';
3636
3637 if (!didWarnAboutUninitializedState.has(componentName)) {
3638 didWarnAboutUninitializedState.add(componentName);
3639
3640 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);
3641 }
3642 } // If new component APIs are defined, "unsafe" lifecycles won't be called.
3643 // Warn about these lifecycles if they are present.
3644 // Don't warn about react-lifecycles-compat polyfilled methods though.
3645
3646
3647 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
3648 var foundWillMountName = null;
3649 var foundWillReceivePropsName = null;
3650 var foundWillUpdateName = null;
3651
3652 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
3653 foundWillMountName = 'componentWillMount';
3654 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
3655 foundWillMountName = 'UNSAFE_componentWillMount';
3656 }
3657
3658 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
3659 foundWillReceivePropsName = 'componentWillReceiveProps';
3660 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
3661 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
3662 }
3663
3664 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
3665 foundWillUpdateName = 'componentWillUpdate';
3666 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
3667 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
3668 }
3669
3670 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
3671 var _componentName = getComponentName(ctor) || 'Component';
3672
3673 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
3674
3675 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
3676 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
3677
3678 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://fb.me/react-unsafe-component-lifecycles', _componentName, newApiName, foundWillMountName !== null ? "\n " + foundWillMountName : '', foundWillReceivePropsName !== null ? "\n " + foundWillReceivePropsName : '', foundWillUpdateName !== null ? "\n " + foundWillUpdateName : '');
3679 }
3680 }
3681 }
3682 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
3683 // ReactFiberContext usually updates this cache but can't for newly-created instances.
3684
3685
3686 if (isLegacyContextConsumer) {
3687 cacheContext(workInProgress, unmaskedContext, context);
3688 }
3689
3690 return instance;
3691}
3692
3693function callComponentWillMount(workInProgress, instance) {
3694 startPhaseTimer(workInProgress, 'componentWillMount');
3695 var oldState = instance.state;
3696
3697 if (typeof instance.componentWillMount === 'function') {
3698 instance.componentWillMount();
3699 }
3700
3701 if (typeof instance.UNSAFE_componentWillMount === 'function') {
3702 instance.UNSAFE_componentWillMount();
3703 }
3704
3705 stopPhaseTimer();
3706
3707 if (oldState !== instance.state) {
3708 {
3709 error('%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress.type) || 'Component');
3710 }
3711
3712 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
3713 }
3714}
3715
3716function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
3717 var oldState = instance.state;
3718 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
3719
3720 if (typeof instance.componentWillReceiveProps === 'function') {
3721 instance.componentWillReceiveProps(newProps, nextContext);
3722 }
3723
3724 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
3725 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
3726 }
3727
3728 stopPhaseTimer();
3729
3730 if (instance.state !== oldState) {
3731 {
3732 var componentName = getComponentName(workInProgress.type) || 'Component';
3733
3734 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
3735 didWarnAboutStateAssignmentForComponent.add(componentName);
3736
3737 error('%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
3738 }
3739 }
3740
3741 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
3742 }
3743} // Invokes the mount life-cycles on a previously never rendered instance.
3744
3745
3746function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
3747 {
3748 checkClassInstance(workInProgress, ctor, newProps);
3749 }
3750
3751 var instance = workInProgress.stateNode;
3752 instance.props = newProps;
3753 instance.state = workInProgress.memoizedState;
3754 instance.refs = emptyRefsObject;
3755 initializeUpdateQueue(workInProgress);
3756 var contextType = ctor.contextType;
3757
3758 if (typeof contextType === 'object' && contextType !== null) {
3759 instance.context = readContext(contextType);
3760 } else {
3761 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
3762 instance.context = getMaskedContext(workInProgress, unmaskedContext);
3763 }
3764
3765 {
3766 if (instance.state === newProps) {
3767 var componentName = getComponentName(ctor) || 'Component';
3768
3769 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
3770 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
3771
3772 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);
3773 }
3774 }
3775
3776 if (workInProgress.mode & StrictMode) {
3777 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
3778 }
3779
3780 {
3781 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
3782 }
3783 }
3784
3785 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
3786 instance.state = workInProgress.memoizedState;
3787 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
3788
3789 if (typeof getDerivedStateFromProps === 'function') {
3790 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
3791 instance.state = workInProgress.memoizedState;
3792 } // In order to support react-lifecycles-compat polyfilled components,
3793 // Unsafe lifecycles should not be invoked for components using the new APIs.
3794
3795
3796 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
3797 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
3798 // process them now.
3799
3800 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
3801 instance.state = workInProgress.memoizedState;
3802 }
3803
3804 if (typeof instance.componentDidMount === 'function') {
3805 workInProgress.effectTag |= Update;
3806 }
3807}
3808
3809function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
3810 var instance = workInProgress.stateNode;
3811 var oldProps = workInProgress.memoizedProps;
3812 instance.props = oldProps;
3813 var oldContext = instance.context;
3814 var contextType = ctor.contextType;
3815 var nextContext = emptyContextObject;
3816
3817 if (typeof contextType === 'object' && contextType !== null) {
3818 nextContext = readContext(contextType);
3819 } else {
3820 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
3821 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
3822 }
3823
3824 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
3825 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
3826 // ever the previously attempted to render - not the "current". However,
3827 // during componentDidUpdate we pass the "current" props.
3828 // In order to support react-lifecycles-compat polyfilled components,
3829 // Unsafe lifecycles should not be invoked for components using the new APIs.
3830
3831 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
3832 if (oldProps !== newProps || oldContext !== nextContext) {
3833 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
3834 }
3835 }
3836
3837 resetHasForceUpdateBeforeProcessing();
3838 var oldState = workInProgress.memoizedState;
3839 var newState = instance.state = oldState;
3840 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
3841 newState = workInProgress.memoizedState;
3842
3843 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
3844 // If an update was already in progress, we should schedule an Update
3845 // effect even though we're bailing out, so that cWU/cDU are called.
3846 if (typeof instance.componentDidMount === 'function') {
3847 workInProgress.effectTag |= Update;
3848 }
3849
3850 return false;
3851 }
3852
3853 if (typeof getDerivedStateFromProps === 'function') {
3854 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
3855 newState = workInProgress.memoizedState;
3856 }
3857
3858 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
3859
3860 if (shouldUpdate) {
3861 // In order to support react-lifecycles-compat polyfilled components,
3862 // Unsafe lifecycles should not be invoked for components using the new APIs.
3863 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
3864 startPhaseTimer(workInProgress, 'componentWillMount');
3865
3866 if (typeof instance.componentWillMount === 'function') {
3867 instance.componentWillMount();
3868 }
3869
3870 if (typeof instance.UNSAFE_componentWillMount === 'function') {
3871 instance.UNSAFE_componentWillMount();
3872 }
3873
3874 stopPhaseTimer();
3875 }
3876
3877 if (typeof instance.componentDidMount === 'function') {
3878 workInProgress.effectTag |= Update;
3879 }
3880 } else {
3881 // If an update was already in progress, we should schedule an Update
3882 // effect even though we're bailing out, so that cWU/cDU are called.
3883 if (typeof instance.componentDidMount === 'function') {
3884 workInProgress.effectTag |= Update;
3885 } // If shouldComponentUpdate returned false, we should still update the
3886 // memoized state to indicate that this work can be reused.
3887
3888
3889 workInProgress.memoizedProps = newProps;
3890 workInProgress.memoizedState = newState;
3891 } // Update the existing instance's state, props, and context pointers even
3892 // if shouldComponentUpdate returns false.
3893
3894
3895 instance.props = newProps;
3896 instance.state = newState;
3897 instance.context = nextContext;
3898 return shouldUpdate;
3899} // Invokes the update life-cycles and returns false if it shouldn't rerender.
3900
3901
3902function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
3903 var instance = workInProgress.stateNode;
3904 cloneUpdateQueue(current, workInProgress);
3905 var oldProps = workInProgress.memoizedProps;
3906 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
3907 var oldContext = instance.context;
3908 var contextType = ctor.contextType;
3909 var nextContext = emptyContextObject;
3910
3911 if (typeof contextType === 'object' && contextType !== null) {
3912 nextContext = readContext(contextType);
3913 } else {
3914 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
3915 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
3916 }
3917
3918 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
3919 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
3920 // ever the previously attempted to render - not the "current". However,
3921 // during componentDidUpdate we pass the "current" props.
3922 // In order to support react-lifecycles-compat polyfilled components,
3923 // Unsafe lifecycles should not be invoked for components using the new APIs.
3924
3925 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
3926 if (oldProps !== newProps || oldContext !== nextContext) {
3927 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
3928 }
3929 }
3930
3931 resetHasForceUpdateBeforeProcessing();
3932 var oldState = workInProgress.memoizedState;
3933 var newState = instance.state = oldState;
3934 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
3935 newState = workInProgress.memoizedState;
3936
3937 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
3938 // If an update was already in progress, we should schedule an Update
3939 // effect even though we're bailing out, so that cWU/cDU are called.
3940 if (typeof instance.componentDidUpdate === 'function') {
3941 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
3942 workInProgress.effectTag |= Update;
3943 }
3944 }
3945
3946 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
3947 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
3948 workInProgress.effectTag |= Snapshot;
3949 }
3950 }
3951
3952 return false;
3953 }
3954
3955 if (typeof getDerivedStateFromProps === 'function') {
3956 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
3957 newState = workInProgress.memoizedState;
3958 }
3959
3960 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
3961
3962 if (shouldUpdate) {
3963 // In order to support react-lifecycles-compat polyfilled components,
3964 // Unsafe lifecycles should not be invoked for components using the new APIs.
3965 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
3966 startPhaseTimer(workInProgress, 'componentWillUpdate');
3967
3968 if (typeof instance.componentWillUpdate === 'function') {
3969 instance.componentWillUpdate(newProps, newState, nextContext);
3970 }
3971
3972 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
3973 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
3974 }
3975
3976 stopPhaseTimer();
3977 }
3978
3979 if (typeof instance.componentDidUpdate === 'function') {
3980 workInProgress.effectTag |= Update;
3981 }
3982
3983 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
3984 workInProgress.effectTag |= Snapshot;
3985 }
3986 } else {
3987 // If an update was already in progress, we should schedule an Update
3988 // effect even though we're bailing out, so that cWU/cDU are called.
3989 if (typeof instance.componentDidUpdate === 'function') {
3990 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
3991 workInProgress.effectTag |= Update;
3992 }
3993 }
3994
3995 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
3996 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
3997 workInProgress.effectTag |= Snapshot;
3998 }
3999 } // If shouldComponentUpdate returned false, we should still update the
4000 // memoized props/state to indicate that this work can be reused.
4001
4002
4003 workInProgress.memoizedProps = newProps;
4004 workInProgress.memoizedState = newState;
4005 } // Update the existing instance's state, props, and context pointers even
4006 // if shouldComponentUpdate returns false.
4007
4008
4009 instance.props = newProps;
4010 instance.state = newState;
4011 instance.context = nextContext;
4012 return shouldUpdate;
4013}
4014
4015var didWarnAboutMaps;
4016var didWarnAboutGenerators;
4017var didWarnAboutStringRefs;
4018var ownerHasKeyUseWarning;
4019var ownerHasFunctionTypeWarning;
4020
4021var warnForMissingKey = function (child) {};
4022
4023{
4024 didWarnAboutMaps = false;
4025 didWarnAboutGenerators = false;
4026 didWarnAboutStringRefs = {};
4027 /**
4028 * Warn if there's no key explicitly set on dynamic arrays of children or
4029 * object keys are not valid. This allows us to keep track of children between
4030 * updates.
4031 */
4032
4033 ownerHasKeyUseWarning = {};
4034 ownerHasFunctionTypeWarning = {};
4035
4036 warnForMissingKey = function (child) {
4037 if (child === null || typeof child !== 'object') {
4038 return;
4039 }
4040
4041 if (!child._store || child._store.validated || child.key != null) {
4042 return;
4043 }
4044
4045 if (!(typeof child._store === 'object')) {
4046 {
4047 throw Error( "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." );
4048 }
4049 }
4050
4051 child._store.validated = true;
4052 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
4053
4054 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
4055 return;
4056 }
4057
4058 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
4059
4060 error('Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
4061 };
4062}
4063
4064var isArray$1 = Array.isArray;
4065
4066function coerceRef(returnFiber, current, element) {
4067 var mixedRef = element.ref;
4068
4069 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
4070 {
4071 // TODO: Clean this up once we turn on the string ref warning for
4072 // everyone, because the strict mode case will no longer be relevant
4073 if ((returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs
4074 // because these cannot be automatically converted to an arrow function
4075 // using a codemod. Therefore, we don't have to warn about string refs again.
4076 !(element._owner && element._self && element._owner.stateNode !== element._self)) {
4077 var componentName = getComponentName(returnFiber.type) || 'Component';
4078
4079 if (!didWarnAboutStringRefs[componentName]) {
4080 {
4081 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://fb.me/react-strict-mode-string-ref%s', mixedRef, getStackByFiberInDevAndProd(returnFiber));
4082 }
4083
4084 didWarnAboutStringRefs[componentName] = true;
4085 }
4086 }
4087 }
4088
4089 if (element._owner) {
4090 var owner = element._owner;
4091 var inst;
4092
4093 if (owner) {
4094 var ownerFiber = owner;
4095
4096 if (!(ownerFiber.tag === ClassComponent)) {
4097 {
4098 throw Error( "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref" );
4099 }
4100 }
4101
4102 inst = ownerFiber.stateNode;
4103 }
4104
4105 if (!inst) {
4106 {
4107 throw Error( "Missing owner for string ref " + mixedRef + ". This error is likely caused by a bug in React. Please file an issue." );
4108 }
4109 }
4110
4111 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref
4112
4113 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
4114 return current.ref;
4115 }
4116
4117 var ref = function (value) {
4118 var refs = inst.refs;
4119
4120 if (refs === emptyRefsObject) {
4121 // This is a lazy pooled frozen object, so we need to initialize.
4122 refs = inst.refs = {};
4123 }
4124
4125 if (value === null) {
4126 delete refs[stringRef];
4127 } else {
4128 refs[stringRef] = value;
4129 }
4130 };
4131
4132 ref._stringRef = stringRef;
4133 return ref;
4134 } else {
4135 if (!(typeof mixedRef === 'string')) {
4136 {
4137 throw Error( "Expected ref to be a function, a string, an object returned by React.createRef(), or null." );
4138 }
4139 }
4140
4141 if (!element._owner) {
4142 {
4143 throw Error( "Element ref was specified as a string (" + mixedRef + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." );
4144 }
4145 }
4146 }
4147 }
4148
4149 return mixedRef;
4150}
4151
4152function throwOnInvalidObjectType(returnFiber, newChild) {
4153 if (returnFiber.type !== 'textarea') {
4154 var addendum = '';
4155
4156 {
4157 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
4158 }
4159
4160 {
4161 {
4162 throw Error( "Objects are not valid as a React child (found: " + (Object.prototype.toString.call(newChild) === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : newChild) + ")." + addendum );
4163 }
4164 }
4165 }
4166}
4167
4168function warnOnFunctionType() {
4169 {
4170 var currentComponentErrorInfo = '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.' + getCurrentFiberStackInDev();
4171
4172 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
4173 return;
4174 }
4175
4176 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
4177
4178 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.');
4179 }
4180} // This wrapper function exists because I expect to clone the code in each path
4181// to be able to optimize each path individually by branching early. This needs
4182// a compiler or we can do it manually. Helpers that don't need this branching
4183// live outside of this function.
4184
4185
4186function ChildReconciler(shouldTrackSideEffects) {
4187 function deleteChild(returnFiber, childToDelete) {
4188 if (!shouldTrackSideEffects) {
4189 // Noop.
4190 return;
4191 } // Deletions are added in reversed order so we add it to the front.
4192 // At this point, the return fiber's effect list is empty except for
4193 // deletions, so we can just append the deletion to the list. The remaining
4194 // effects aren't added until the complete phase. Once we implement
4195 // resuming, this may not be true.
4196
4197
4198 var last = returnFiber.lastEffect;
4199
4200 if (last !== null) {
4201 last.nextEffect = childToDelete;
4202 returnFiber.lastEffect = childToDelete;
4203 } else {
4204 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
4205 }
4206
4207 childToDelete.nextEffect = null;
4208 childToDelete.effectTag = Deletion;
4209 }
4210
4211 function deleteRemainingChildren(returnFiber, currentFirstChild) {
4212 if (!shouldTrackSideEffects) {
4213 // Noop.
4214 return null;
4215 } // TODO: For the shouldClone case, this could be micro-optimized a bit by
4216 // assuming that after the first child we've already added everything.
4217
4218
4219 var childToDelete = currentFirstChild;
4220
4221 while (childToDelete !== null) {
4222 deleteChild(returnFiber, childToDelete);
4223 childToDelete = childToDelete.sibling;
4224 }
4225
4226 return null;
4227 }
4228
4229 function mapRemainingChildren(returnFiber, currentFirstChild) {
4230 // Add the remaining children to a temporary map so that we can find them by
4231 // keys quickly. Implicit (null) keys get added to this set with their index
4232 // instead.
4233 var existingChildren = new Map();
4234 var existingChild = currentFirstChild;
4235
4236 while (existingChild !== null) {
4237 if (existingChild.key !== null) {
4238 existingChildren.set(existingChild.key, existingChild);
4239 } else {
4240 existingChildren.set(existingChild.index, existingChild);
4241 }
4242
4243 existingChild = existingChild.sibling;
4244 }
4245
4246 return existingChildren;
4247 }
4248
4249 function useFiber(fiber, pendingProps) {
4250 // We currently set sibling to null and index to 0 here because it is easy
4251 // to forget to do before returning it. E.g. for the single child case.
4252 var clone = createWorkInProgress(fiber, pendingProps);
4253 clone.index = 0;
4254 clone.sibling = null;
4255 return clone;
4256 }
4257
4258 function placeChild(newFiber, lastPlacedIndex, newIndex) {
4259 newFiber.index = newIndex;
4260
4261 if (!shouldTrackSideEffects) {
4262 // Noop.
4263 return lastPlacedIndex;
4264 }
4265
4266 var current = newFiber.alternate;
4267
4268 if (current !== null) {
4269 var oldIndex = current.index;
4270
4271 if (oldIndex < lastPlacedIndex) {
4272 // This is a move.
4273 newFiber.effectTag = Placement;
4274 return lastPlacedIndex;
4275 } else {
4276 // This item can stay in place.
4277 return oldIndex;
4278 }
4279 } else {
4280 // This is an insertion.
4281 newFiber.effectTag = Placement;
4282 return lastPlacedIndex;
4283 }
4284 }
4285
4286 function placeSingleChild(newFiber) {
4287 // This is simpler for the single child case. We only need to do a
4288 // placement for inserting new children.
4289 if (shouldTrackSideEffects && newFiber.alternate === null) {
4290 newFiber.effectTag = Placement;
4291 }
4292
4293 return newFiber;
4294 }
4295
4296 function updateTextNode(returnFiber, current, textContent, expirationTime) {
4297 if (current === null || current.tag !== HostText) {
4298 // Insert
4299 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
4300 created.return = returnFiber;
4301 return created;
4302 } else {
4303 // Update
4304 var existing = useFiber(current, textContent);
4305 existing.return = returnFiber;
4306 return existing;
4307 }
4308 }
4309
4310 function updateElement(returnFiber, current, element, expirationTime) {
4311 if (current !== null) {
4312 if (current.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
4313 isCompatibleFamilyForHotReloading(current, element) )) {
4314 // Move based on index
4315 var existing = useFiber(current, element.props);
4316 existing.ref = coerceRef(returnFiber, current, element);
4317 existing.return = returnFiber;
4318
4319 {
4320 existing._debugSource = element._source;
4321 existing._debugOwner = element._owner;
4322 }
4323
4324 return existing;
4325 }
4326 } // Insert
4327
4328
4329 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
4330 created.ref = coerceRef(returnFiber, current, element);
4331 created.return = returnFiber;
4332 return created;
4333 }
4334
4335 function updatePortal(returnFiber, current, portal, expirationTime) {
4336 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
4337 // Insert
4338 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
4339 created.return = returnFiber;
4340 return created;
4341 } else {
4342 // Update
4343 var existing = useFiber(current, portal.children || []);
4344 existing.return = returnFiber;
4345 return existing;
4346 }
4347 }
4348
4349 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
4350 if (current === null || current.tag !== Fragment) {
4351 // Insert
4352 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
4353 created.return = returnFiber;
4354 return created;
4355 } else {
4356 // Update
4357 var existing = useFiber(current, fragment);
4358 existing.return = returnFiber;
4359 return existing;
4360 }
4361 }
4362
4363 function createChild(returnFiber, newChild, expirationTime) {
4364 if (typeof newChild === 'string' || typeof newChild === 'number') {
4365 // Text nodes don't have keys. If the previous node is implicitly keyed
4366 // we can continue to replace it without aborting even if it is not a text
4367 // node.
4368 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
4369 created.return = returnFiber;
4370 return created;
4371 }
4372
4373 if (typeof newChild === 'object' && newChild !== null) {
4374 switch (newChild.$$typeof) {
4375 case REACT_ELEMENT_TYPE:
4376 {
4377 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
4378
4379 _created.ref = coerceRef(returnFiber, null, newChild);
4380 _created.return = returnFiber;
4381 return _created;
4382 }
4383
4384 case REACT_PORTAL_TYPE:
4385 {
4386 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
4387
4388 _created2.return = returnFiber;
4389 return _created2;
4390 }
4391 }
4392
4393 if (isArray$1(newChild) || getIteratorFn(newChild)) {
4394 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
4395
4396 _created3.return = returnFiber;
4397 return _created3;
4398 }
4399
4400 throwOnInvalidObjectType(returnFiber, newChild);
4401 }
4402
4403 {
4404 if (typeof newChild === 'function') {
4405 warnOnFunctionType();
4406 }
4407 }
4408
4409 return null;
4410 }
4411
4412 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
4413 // Update the fiber if the keys match, otherwise return null.
4414 var key = oldFiber !== null ? oldFiber.key : null;
4415
4416 if (typeof newChild === 'string' || typeof newChild === 'number') {
4417 // Text nodes don't have keys. If the previous node is implicitly keyed
4418 // we can continue to replace it without aborting even if it is not a text
4419 // node.
4420 if (key !== null) {
4421 return null;
4422 }
4423
4424 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
4425 }
4426
4427 if (typeof newChild === 'object' && newChild !== null) {
4428 switch (newChild.$$typeof) {
4429 case REACT_ELEMENT_TYPE:
4430 {
4431 if (newChild.key === key) {
4432 if (newChild.type === REACT_FRAGMENT_TYPE) {
4433 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
4434 }
4435
4436 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
4437 } else {
4438 return null;
4439 }
4440 }
4441
4442 case REACT_PORTAL_TYPE:
4443 {
4444 if (newChild.key === key) {
4445 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
4446 } else {
4447 return null;
4448 }
4449 }
4450 }
4451
4452 if (isArray$1(newChild) || getIteratorFn(newChild)) {
4453 if (key !== null) {
4454 return null;
4455 }
4456
4457 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
4458 }
4459
4460 throwOnInvalidObjectType(returnFiber, newChild);
4461 }
4462
4463 {
4464 if (typeof newChild === 'function') {
4465 warnOnFunctionType();
4466 }
4467 }
4468
4469 return null;
4470 }
4471
4472 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
4473 if (typeof newChild === 'string' || typeof newChild === 'number') {
4474 // Text nodes don't have keys, so we neither have to check the old nor
4475 // new node for the key. If both are text nodes, they match.
4476 var matchedFiber = existingChildren.get(newIdx) || null;
4477 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
4478 }
4479
4480 if (typeof newChild === 'object' && newChild !== null) {
4481 switch (newChild.$$typeof) {
4482 case REACT_ELEMENT_TYPE:
4483 {
4484 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4485
4486 if (newChild.type === REACT_FRAGMENT_TYPE) {
4487 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
4488 }
4489
4490 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
4491 }
4492
4493 case REACT_PORTAL_TYPE:
4494 {
4495 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4496
4497 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
4498 }
4499 }
4500
4501 if (isArray$1(newChild) || getIteratorFn(newChild)) {
4502 var _matchedFiber3 = existingChildren.get(newIdx) || null;
4503
4504 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
4505 }
4506
4507 throwOnInvalidObjectType(returnFiber, newChild);
4508 }
4509
4510 {
4511 if (typeof newChild === 'function') {
4512 warnOnFunctionType();
4513 }
4514 }
4515
4516 return null;
4517 }
4518 /**
4519 * Warns if there is a duplicate or missing key
4520 */
4521
4522
4523 function warnOnInvalidKey(child, knownKeys) {
4524 {
4525 if (typeof child !== 'object' || child === null) {
4526 return knownKeys;
4527 }
4528
4529 switch (child.$$typeof) {
4530 case REACT_ELEMENT_TYPE:
4531 case REACT_PORTAL_TYPE:
4532 warnForMissingKey(child);
4533 var key = child.key;
4534
4535 if (typeof key !== 'string') {
4536 break;
4537 }
4538
4539 if (knownKeys === null) {
4540 knownKeys = new Set();
4541 knownKeys.add(key);
4542 break;
4543 }
4544
4545 if (!knownKeys.has(key)) {
4546 knownKeys.add(key);
4547 break;
4548 }
4549
4550 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);
4551
4552 break;
4553 }
4554 }
4555
4556 return knownKeys;
4557 }
4558
4559 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
4560 // This algorithm can't optimize by searching from both ends since we
4561 // don't have backpointers on fibers. I'm trying to see how far we can get
4562 // with that model. If it ends up not being worth the tradeoffs, we can
4563 // add it later.
4564 // Even with a two ended optimization, we'd want to optimize for the case
4565 // where there are few changes and brute force the comparison instead of
4566 // going for the Map. It'd like to explore hitting that path first in
4567 // forward-only mode and only go for the Map once we notice that we need
4568 // lots of look ahead. This doesn't handle reversal as well as two ended
4569 // search but that's unusual. Besides, for the two ended optimization to
4570 // work on Iterables, we'd need to copy the whole set.
4571 // In this first iteration, we'll just live with hitting the bad case
4572 // (adding everything to a Map) in for every insert/move.
4573 // If you change this code, also update reconcileChildrenIterator() which
4574 // uses the same algorithm.
4575 {
4576 // First, validate keys.
4577 var knownKeys = null;
4578
4579 for (var i = 0; i < newChildren.length; i++) {
4580 var child = newChildren[i];
4581 knownKeys = warnOnInvalidKey(child, knownKeys);
4582 }
4583 }
4584
4585 var resultingFirstChild = null;
4586 var previousNewFiber = null;
4587 var oldFiber = currentFirstChild;
4588 var lastPlacedIndex = 0;
4589 var newIdx = 0;
4590 var nextOldFiber = null;
4591
4592 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
4593 if (oldFiber.index > newIdx) {
4594 nextOldFiber = oldFiber;
4595 oldFiber = null;
4596 } else {
4597 nextOldFiber = oldFiber.sibling;
4598 }
4599
4600 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
4601
4602 if (newFiber === null) {
4603 // TODO: This breaks on empty slots like null children. That's
4604 // unfortunate because it triggers the slow path all the time. We need
4605 // a better way to communicate whether this was a miss or null,
4606 // boolean, undefined, etc.
4607 if (oldFiber === null) {
4608 oldFiber = nextOldFiber;
4609 }
4610
4611 break;
4612 }
4613
4614 if (shouldTrackSideEffects) {
4615 if (oldFiber && newFiber.alternate === null) {
4616 // We matched the slot, but we didn't reuse the existing fiber, so we
4617 // need to delete the existing child.
4618 deleteChild(returnFiber, oldFiber);
4619 }
4620 }
4621
4622 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
4623
4624 if (previousNewFiber === null) {
4625 // TODO: Move out of the loop. This only happens for the first run.
4626 resultingFirstChild = newFiber;
4627 } else {
4628 // TODO: Defer siblings if we're not at the right index for this slot.
4629 // I.e. if we had null values before, then we want to defer this
4630 // for each null value. However, we also don't want to call updateSlot
4631 // with the previous one.
4632 previousNewFiber.sibling = newFiber;
4633 }
4634
4635 previousNewFiber = newFiber;
4636 oldFiber = nextOldFiber;
4637 }
4638
4639 if (newIdx === newChildren.length) {
4640 // We've reached the end of the new children. We can delete the rest.
4641 deleteRemainingChildren(returnFiber, oldFiber);
4642 return resultingFirstChild;
4643 }
4644
4645 if (oldFiber === null) {
4646 // If we don't have any more existing children we can choose a fast path
4647 // since the rest will all be insertions.
4648 for (; newIdx < newChildren.length; newIdx++) {
4649 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
4650
4651 if (_newFiber === null) {
4652 continue;
4653 }
4654
4655 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
4656
4657 if (previousNewFiber === null) {
4658 // TODO: Move out of the loop. This only happens for the first run.
4659 resultingFirstChild = _newFiber;
4660 } else {
4661 previousNewFiber.sibling = _newFiber;
4662 }
4663
4664 previousNewFiber = _newFiber;
4665 }
4666
4667 return resultingFirstChild;
4668 } // Add all children to a key map for quick lookups.
4669
4670
4671 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
4672
4673 for (; newIdx < newChildren.length; newIdx++) {
4674 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
4675
4676 if (_newFiber2 !== null) {
4677 if (shouldTrackSideEffects) {
4678 if (_newFiber2.alternate !== null) {
4679 // The new fiber is a work in progress, but if there exists a
4680 // current, that means that we reused the fiber. We need to delete
4681 // it from the child list so that we don't add it to the deletion
4682 // list.
4683 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
4684 }
4685 }
4686
4687 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
4688
4689 if (previousNewFiber === null) {
4690 resultingFirstChild = _newFiber2;
4691 } else {
4692 previousNewFiber.sibling = _newFiber2;
4693 }
4694
4695 previousNewFiber = _newFiber2;
4696 }
4697 }
4698
4699 if (shouldTrackSideEffects) {
4700 // Any existing children that weren't consumed above were deleted. We need
4701 // to add them to the deletion list.
4702 existingChildren.forEach(function (child) {
4703 return deleteChild(returnFiber, child);
4704 });
4705 }
4706
4707 return resultingFirstChild;
4708 }
4709
4710 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
4711 // This is the same implementation as reconcileChildrenArray(),
4712 // but using the iterator instead.
4713 var iteratorFn = getIteratorFn(newChildrenIterable);
4714
4715 if (!(typeof iteratorFn === 'function')) {
4716 {
4717 throw Error( "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." );
4718 }
4719 }
4720
4721 {
4722 // We don't support rendering Generators because it's a mutation.
4723 // See https://github.com/facebook/react/issues/12995
4724 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag
4725 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
4726 if (!didWarnAboutGenerators) {
4727 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.');
4728 }
4729
4730 didWarnAboutGenerators = true;
4731 } // Warn about using Maps as children
4732
4733
4734 if (newChildrenIterable.entries === iteratorFn) {
4735 if (!didWarnAboutMaps) {
4736 error('Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.');
4737 }
4738
4739 didWarnAboutMaps = true;
4740 } // First, validate keys.
4741 // We'll get a different iterator later for the main pass.
4742
4743
4744 var _newChildren = iteratorFn.call(newChildrenIterable);
4745
4746 if (_newChildren) {
4747 var knownKeys = null;
4748
4749 var _step = _newChildren.next();
4750
4751 for (; !_step.done; _step = _newChildren.next()) {
4752 var child = _step.value;
4753 knownKeys = warnOnInvalidKey(child, knownKeys);
4754 }
4755 }
4756 }
4757
4758 var newChildren = iteratorFn.call(newChildrenIterable);
4759
4760 if (!(newChildren != null)) {
4761 {
4762 throw Error( "An iterable object provided no iterator." );
4763 }
4764 }
4765
4766 var resultingFirstChild = null;
4767 var previousNewFiber = null;
4768 var oldFiber = currentFirstChild;
4769 var lastPlacedIndex = 0;
4770 var newIdx = 0;
4771 var nextOldFiber = null;
4772 var step = newChildren.next();
4773
4774 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
4775 if (oldFiber.index > newIdx) {
4776 nextOldFiber = oldFiber;
4777 oldFiber = null;
4778 } else {
4779 nextOldFiber = oldFiber.sibling;
4780 }
4781
4782 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
4783
4784 if (newFiber === null) {
4785 // TODO: This breaks on empty slots like null children. That's
4786 // unfortunate because it triggers the slow path all the time. We need
4787 // a better way to communicate whether this was a miss or null,
4788 // boolean, undefined, etc.
4789 if (oldFiber === null) {
4790 oldFiber = nextOldFiber;
4791 }
4792
4793 break;
4794 }
4795
4796 if (shouldTrackSideEffects) {
4797 if (oldFiber && newFiber.alternate === null) {
4798 // We matched the slot, but we didn't reuse the existing fiber, so we
4799 // need to delete the existing child.
4800 deleteChild(returnFiber, oldFiber);
4801 }
4802 }
4803
4804 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
4805
4806 if (previousNewFiber === null) {
4807 // TODO: Move out of the loop. This only happens for the first run.
4808 resultingFirstChild = newFiber;
4809 } else {
4810 // TODO: Defer siblings if we're not at the right index for this slot.
4811 // I.e. if we had null values before, then we want to defer this
4812 // for each null value. However, we also don't want to call updateSlot
4813 // with the previous one.
4814 previousNewFiber.sibling = newFiber;
4815 }
4816
4817 previousNewFiber = newFiber;
4818 oldFiber = nextOldFiber;
4819 }
4820
4821 if (step.done) {
4822 // We've reached the end of the new children. We can delete the rest.
4823 deleteRemainingChildren(returnFiber, oldFiber);
4824 return resultingFirstChild;
4825 }
4826
4827 if (oldFiber === null) {
4828 // If we don't have any more existing children we can choose a fast path
4829 // since the rest will all be insertions.
4830 for (; !step.done; newIdx++, step = newChildren.next()) {
4831 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
4832
4833 if (_newFiber3 === null) {
4834 continue;
4835 }
4836
4837 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
4838
4839 if (previousNewFiber === null) {
4840 // TODO: Move out of the loop. This only happens for the first run.
4841 resultingFirstChild = _newFiber3;
4842 } else {
4843 previousNewFiber.sibling = _newFiber3;
4844 }
4845
4846 previousNewFiber = _newFiber3;
4847 }
4848
4849 return resultingFirstChild;
4850 } // Add all children to a key map for quick lookups.
4851
4852
4853 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
4854
4855 for (; !step.done; newIdx++, step = newChildren.next()) {
4856 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
4857
4858 if (_newFiber4 !== null) {
4859 if (shouldTrackSideEffects) {
4860 if (_newFiber4.alternate !== null) {
4861 // The new fiber is a work in progress, but if there exists a
4862 // current, that means that we reused the fiber. We need to delete
4863 // it from the child list so that we don't add it to the deletion
4864 // list.
4865 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
4866 }
4867 }
4868
4869 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
4870
4871 if (previousNewFiber === null) {
4872 resultingFirstChild = _newFiber4;
4873 } else {
4874 previousNewFiber.sibling = _newFiber4;
4875 }
4876
4877 previousNewFiber = _newFiber4;
4878 }
4879 }
4880
4881 if (shouldTrackSideEffects) {
4882 // Any existing children that weren't consumed above were deleted. We need
4883 // to add them to the deletion list.
4884 existingChildren.forEach(function (child) {
4885 return deleteChild(returnFiber, child);
4886 });
4887 }
4888
4889 return resultingFirstChild;
4890 }
4891
4892 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
4893 // There's no need to check for keys on text nodes since we don't have a
4894 // way to define them.
4895 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
4896 // We already have an existing node so let's just update it and delete
4897 // the rest.
4898 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
4899 var existing = useFiber(currentFirstChild, textContent);
4900 existing.return = returnFiber;
4901 return existing;
4902 } // The existing first child is not a text node so we need to create one
4903 // and delete the existing ones.
4904
4905
4906 deleteRemainingChildren(returnFiber, currentFirstChild);
4907 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
4908 created.return = returnFiber;
4909 return created;
4910 }
4911
4912 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
4913 var key = element.key;
4914 var child = currentFirstChild;
4915
4916 while (child !== null) {
4917 // TODO: If key === null and child.key === null, then this only applies to
4918 // the first item in the list.
4919 if (child.key === key) {
4920 switch (child.tag) {
4921 case Fragment:
4922 {
4923 if (element.type === REACT_FRAGMENT_TYPE) {
4924 deleteRemainingChildren(returnFiber, child.sibling);
4925 var existing = useFiber(child, element.props.children);
4926 existing.return = returnFiber;
4927
4928 {
4929 existing._debugSource = element._source;
4930 existing._debugOwner = element._owner;
4931 }
4932
4933 return existing;
4934 }
4935
4936 break;
4937 }
4938
4939 case Block:
4940
4941 // We intentionally fallthrough here if enableBlocksAPI is not on.
4942 // eslint-disable-next-lined no-fallthrough
4943
4944 default:
4945 {
4946 if (child.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
4947 isCompatibleFamilyForHotReloading(child, element) )) {
4948 deleteRemainingChildren(returnFiber, child.sibling);
4949
4950 var _existing3 = useFiber(child, element.props);
4951
4952 _existing3.ref = coerceRef(returnFiber, child, element);
4953 _existing3.return = returnFiber;
4954
4955 {
4956 _existing3._debugSource = element._source;
4957 _existing3._debugOwner = element._owner;
4958 }
4959
4960 return _existing3;
4961 }
4962
4963 break;
4964 }
4965 } // Didn't match.
4966
4967
4968 deleteRemainingChildren(returnFiber, child);
4969 break;
4970 } else {
4971 deleteChild(returnFiber, child);
4972 }
4973
4974 child = child.sibling;
4975 }
4976
4977 if (element.type === REACT_FRAGMENT_TYPE) {
4978 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
4979 created.return = returnFiber;
4980 return created;
4981 } else {
4982 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
4983
4984 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
4985 _created4.return = returnFiber;
4986 return _created4;
4987 }
4988 }
4989
4990 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
4991 var key = portal.key;
4992 var child = currentFirstChild;
4993
4994 while (child !== null) {
4995 // TODO: If key === null and child.key === null, then this only applies to
4996 // the first item in the list.
4997 if (child.key === key) {
4998 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
4999 deleteRemainingChildren(returnFiber, child.sibling);
5000 var existing = useFiber(child, portal.children || []);
5001 existing.return = returnFiber;
5002 return existing;
5003 } else {
5004 deleteRemainingChildren(returnFiber, child);
5005 break;
5006 }
5007 } else {
5008 deleteChild(returnFiber, child);
5009 }
5010
5011 child = child.sibling;
5012 }
5013
5014 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
5015 created.return = returnFiber;
5016 return created;
5017 } // This API will tag the children with the side-effect of the reconciliation
5018 // itself. They will be added to the side-effect list as we pass through the
5019 // children and the parent.
5020
5021
5022 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
5023 // This function is not recursive.
5024 // If the top level item is an array, we treat it as a set of children,
5025 // not as a fragment. Nested arrays on the other hand will be treated as
5026 // fragment nodes. Recursion happens at the normal flow.
5027 // Handle top level unkeyed fragments as if they were arrays.
5028 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
5029 // We treat the ambiguous cases above the same.
5030 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
5031
5032 if (isUnkeyedTopLevelFragment) {
5033 newChild = newChild.props.children;
5034 } // Handle object types
5035
5036
5037 var isObject = typeof newChild === 'object' && newChild !== null;
5038
5039 if (isObject) {
5040 switch (newChild.$$typeof) {
5041 case REACT_ELEMENT_TYPE:
5042 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
5043
5044 case REACT_PORTAL_TYPE:
5045 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
5046 }
5047 }
5048
5049 if (typeof newChild === 'string' || typeof newChild === 'number') {
5050 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
5051 }
5052
5053 if (isArray$1(newChild)) {
5054 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
5055 }
5056
5057 if (getIteratorFn(newChild)) {
5058 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
5059 }
5060
5061 if (isObject) {
5062 throwOnInvalidObjectType(returnFiber, newChild);
5063 }
5064
5065 {
5066 if (typeof newChild === 'function') {
5067 warnOnFunctionType();
5068 }
5069 }
5070
5071 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
5072 // If the new child is undefined, and the return fiber is a composite
5073 // component, throw an error. If Fiber return types are disabled,
5074 // we already threw above.
5075 switch (returnFiber.tag) {
5076 case ClassComponent:
5077 {
5078 {
5079 var instance = returnFiber.stateNode;
5080
5081 if (instance.render._isMockFunction) {
5082 // We allow auto-mocks to proceed as if they're returning null.
5083 break;
5084 }
5085 }
5086 }
5087 // Intentionally fall through to the next case, which handles both
5088 // functions and classes
5089 // eslint-disable-next-lined no-fallthrough
5090
5091 case FunctionComponent:
5092 {
5093 var Component = returnFiber.type;
5094
5095 {
5096 {
5097 throw Error( (Component.displayName || Component.name || 'Component') + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." );
5098 }
5099 }
5100 }
5101 }
5102 } // Remaining cases are all treated as empty.
5103
5104
5105 return deleteRemainingChildren(returnFiber, currentFirstChild);
5106 }
5107
5108 return reconcileChildFibers;
5109}
5110
5111var reconcileChildFibers = ChildReconciler(true);
5112var mountChildFibers = ChildReconciler(false);
5113function cloneChildFibers(current, workInProgress) {
5114 if (!(current === null || workInProgress.child === current.child)) {
5115 {
5116 throw Error( "Resuming work not yet implemented." );
5117 }
5118 }
5119
5120 if (workInProgress.child === null) {
5121 return;
5122 }
5123
5124 var currentChild = workInProgress.child;
5125 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps);
5126 workInProgress.child = newChild;
5127 newChild.return = workInProgress;
5128
5129 while (currentChild.sibling !== null) {
5130 currentChild = currentChild.sibling;
5131 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps);
5132 newChild.return = workInProgress;
5133 }
5134
5135 newChild.sibling = null;
5136} // Reset a workInProgress child set to prepare it for a second pass.
5137
5138function resetChildFibers(workInProgress, renderExpirationTime) {
5139 var child = workInProgress.child;
5140
5141 while (child !== null) {
5142 resetWorkInProgress(child, renderExpirationTime);
5143 child = child.sibling;
5144 }
5145}
5146
5147var NO_CONTEXT$1 = {};
5148var contextStackCursor$1 = createCursor(NO_CONTEXT$1);
5149var contextFiberStackCursor = createCursor(NO_CONTEXT$1);
5150var rootInstanceStackCursor = createCursor(NO_CONTEXT$1);
5151
5152function requiredContext(c) {
5153 if (!(c !== NO_CONTEXT$1)) {
5154 {
5155 throw Error( "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." );
5156 }
5157 }
5158
5159 return c;
5160}
5161
5162function getRootHostContainer() {
5163 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5164 return rootInstance;
5165}
5166
5167function pushHostContainer(fiber, nextRootInstance) {
5168 // Push current root instance onto the stack;
5169 // This allows us to reset root when portals are popped.
5170 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
5171 // This enables us to pop only Fibers that provide unique contexts.
5172
5173 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
5174 // However, we can't just call getRootHostContext() and push it because
5175 // we'd have a different number of entries on the stack depending on
5176 // whether getRootHostContext() throws somewhere in renderer code or not.
5177 // So we push an empty value first. This lets us safely unwind on errors.
5178
5179 push(contextStackCursor$1, NO_CONTEXT$1, fiber);
5180 var nextRootContext = getRootHostContext(); // Now that we know this function doesn't throw, replace it.
5181
5182 pop(contextStackCursor$1, fiber);
5183 push(contextStackCursor$1, nextRootContext, fiber);
5184}
5185
5186function popHostContainer(fiber) {
5187 pop(contextStackCursor$1, fiber);
5188 pop(contextFiberStackCursor, fiber);
5189 pop(rootInstanceStackCursor, fiber);
5190}
5191
5192function getHostContext() {
5193 var context = requiredContext(contextStackCursor$1.current);
5194 return context;
5195}
5196
5197function pushHostContext(fiber) {
5198 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5199 var context = requiredContext(contextStackCursor$1.current);
5200 var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique.
5201
5202 if (context === nextContext) {
5203 return;
5204 } // Track the context and the Fiber that provided it.
5205 // This enables us to pop only Fibers that provide unique contexts.
5206
5207
5208 push(contextFiberStackCursor, fiber, fiber);
5209 push(contextStackCursor$1, nextContext, fiber);
5210}
5211
5212function popHostContext(fiber) {
5213 // Do not pop unless this Fiber provided the current context.
5214 // pushHostContext() only pushes Fibers that provide unique contexts.
5215 if (contextFiberStackCursor.current !== fiber) {
5216 return;
5217 }
5218
5219 pop(contextStackCursor$1, fiber);
5220 pop(contextFiberStackCursor, fiber);
5221}
5222
5223var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is
5224// inherited deeply down the subtree. The upper bits only affect
5225// this immediate suspense boundary and gets reset each new
5226// boundary or suspense list.
5227
5228var SubtreeSuspenseContextMask = 1; // Subtree Flags:
5229// InvisibleParentSuspenseContext indicates that one of our parent Suspense
5230// boundaries is not currently showing visible main content.
5231// Either because it is already showing a fallback or is not mounted at all.
5232// We can use this to determine if it is desirable to trigger a fallback at
5233// the parent. If not, then we might need to trigger undesirable boundaries
5234// and/or suspend the commit to avoid hiding the parent content.
5235
5236var InvisibleParentSuspenseContext = 1; // Shallow Flags:
5237// ForceSuspenseFallback can be used by SuspenseList to force newly added
5238// items into their fallback state during one of the render passes.
5239
5240var ForceSuspenseFallback = 2;
5241var suspenseStackCursor = createCursor(DefaultSuspenseContext);
5242function hasSuspenseContext(parentContext, flag) {
5243 return (parentContext & flag) !== 0;
5244}
5245function setDefaultShallowSuspenseContext(parentContext) {
5246 return parentContext & SubtreeSuspenseContextMask;
5247}
5248function setShallowSuspenseContext(parentContext, shallowContext) {
5249 return parentContext & SubtreeSuspenseContextMask | shallowContext;
5250}
5251function addSubtreeSuspenseContext(parentContext, subtreeContext) {
5252 return parentContext | subtreeContext;
5253}
5254function pushSuspenseContext(fiber, newContext) {
5255 push(suspenseStackCursor, newContext, fiber);
5256}
5257function popSuspenseContext(fiber) {
5258 pop(suspenseStackCursor, fiber);
5259}
5260
5261function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
5262 // If it was the primary children that just suspended, capture and render the
5263 // fallback. Otherwise, don't capture and bubble to the next boundary.
5264 var nextState = workInProgress.memoizedState;
5265
5266 if (nextState !== null) {
5267 if (nextState.dehydrated !== null) {
5268 // A dehydrated boundary always captures.
5269 return true;
5270 }
5271
5272 return false;
5273 }
5274
5275 var props = workInProgress.memoizedProps; // In order to capture, the Suspense component must have a fallback prop.
5276
5277 if (props.fallback === undefined) {
5278 return false;
5279 } // Regular boundaries always capture.
5280
5281
5282 if (props.unstable_avoidThisFallback !== true) {
5283 return true;
5284 } // If it's a boundary we should avoid, then we prefer to bubble up to the
5285 // parent boundary if it is currently invisible.
5286
5287
5288 if (hasInvisibleParent) {
5289 return false;
5290 } // If the parent is not able to handle it, we must handle it.
5291
5292
5293 return true;
5294}
5295function findFirstSuspended(row) {
5296 var node = row;
5297
5298 while (node !== null) {
5299 if (node.tag === SuspenseComponent) {
5300 var state = node.memoizedState;
5301
5302 if (state !== null) {
5303 var dehydrated = state.dehydrated;
5304
5305 if (dehydrated === null || isSuspenseInstancePending() || isSuspenseInstanceFallback()) {
5306 return node;
5307 }
5308 }
5309 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
5310 // keep track of whether it suspended or not.
5311 node.memoizedProps.revealOrder !== undefined) {
5312 var didSuspend = (node.effectTag & DidCapture) !== NoEffect;
5313
5314 if (didSuspend) {
5315 return node;
5316 }
5317 } else if (node.child !== null) {
5318 node.child.return = node;
5319 node = node.child;
5320 continue;
5321 }
5322
5323 if (node === row) {
5324 return null;
5325 }
5326
5327 while (node.sibling === null) {
5328 if (node.return === null || node.return === row) {
5329 return null;
5330 }
5331
5332 node = node.return;
5333 }
5334
5335 node.sibling.return = node.return;
5336 node = node.sibling;
5337 }
5338
5339 return null;
5340}
5341
5342function createDeprecatedResponderListener(responder, props) {
5343 var eventResponderListener = {
5344 responder: responder,
5345 props: props
5346 };
5347
5348 {
5349 Object.freeze(eventResponderListener);
5350 }
5351
5352 return eventResponderListener;
5353}
5354
5355var HasEffect =
5356/* */
53571; // Represents the phase in which the effect (not the clean-up) fires.
5358
5359var Layout =
5360/* */
53612;
5362var Passive$1 =
5363/* */
53644;
5365
5366var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher,
5367 ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig;
5368var didWarnAboutMismatchedHooksForComponent;
5369
5370{
5371 didWarnAboutMismatchedHooksForComponent = new Set();
5372}
5373
5374// These are set right before calling the component.
5375var renderExpirationTime = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from
5376// the work-in-progress hook.
5377
5378var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
5379// current hook list is the list that belongs to the current fiber. The
5380// work-in-progress hook list is a new list that will be added to the
5381// work-in-progress fiber.
5382
5383var currentHook = null;
5384var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This
5385// does not get reset if we do another render pass; only when we're completely
5386// finished evaluating this component. This is an optimization so we know
5387// whether we need to clear render phase updates after a throw.
5388
5389var didScheduleRenderPhaseUpdate = false;
5390var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
5391
5392var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
5393// The list stores the order of hooks used during the initial render (mount).
5394// Subsequent renders (updates) reference this list.
5395
5396var hookTypesDev = null;
5397var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
5398// the dependencies for Hooks that need them (e.g. useEffect or useMemo).
5399// When true, such Hooks will always be "remounted". Only used during hot reload.
5400
5401var ignorePreviousDependencies = false;
5402
5403function mountHookTypesDev() {
5404 {
5405 var hookName = currentHookNameInDev;
5406
5407 if (hookTypesDev === null) {
5408 hookTypesDev = [hookName];
5409 } else {
5410 hookTypesDev.push(hookName);
5411 }
5412 }
5413}
5414
5415function updateHookTypesDev() {
5416 {
5417 var hookName = currentHookNameInDev;
5418
5419 if (hookTypesDev !== null) {
5420 hookTypesUpdateIndexDev++;
5421
5422 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
5423 warnOnHookMismatchInDev(hookName);
5424 }
5425 }
5426 }
5427}
5428
5429function checkDepsAreArrayDev(deps) {
5430 {
5431 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
5432 // Verify deps, but only on mount to avoid extra checks.
5433 // It's unlikely their type would change as usually you define them inline.
5434 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);
5435 }
5436 }
5437}
5438
5439function warnOnHookMismatchInDev(currentHookName) {
5440 {
5441 var componentName = getComponentName(currentlyRenderingFiber$1.type);
5442
5443 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
5444 didWarnAboutMismatchedHooksForComponent.add(componentName);
5445
5446 if (hookTypesDev !== null) {
5447 var table = '';
5448 var secondColumnStart = 30;
5449
5450 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
5451 var oldHookName = hookTypesDev[i];
5452 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
5453 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
5454 // lol @ IE not supporting String#repeat
5455
5456 while (row.length < secondColumnStart) {
5457 row += ' ';
5458 }
5459
5460 row += newHookName + '\n';
5461 table += row;
5462 }
5463
5464 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://fb.me/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' ------------------------------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table);
5465 }
5466 }
5467 }
5468}
5469
5470function throwInvalidHookError() {
5471 {
5472 {
5473 throw 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:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." );
5474 }
5475 }
5476}
5477
5478function areHookInputsEqual(nextDeps, prevDeps) {
5479 {
5480 if (ignorePreviousDependencies) {
5481 // Only true when this component is being hot reloaded.
5482 return false;
5483 }
5484 }
5485
5486 if (prevDeps === null) {
5487 {
5488 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);
5489 }
5490
5491 return false;
5492 }
5493
5494 {
5495 // Don't bother comparing lengths in prod because these arrays should be
5496 // passed inline.
5497 if (nextDeps.length !== prevDeps.length) {
5498 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(', ') + "]");
5499 }
5500 }
5501
5502 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
5503 if (objectIs(nextDeps[i], prevDeps[i])) {
5504 continue;
5505 }
5506
5507 return false;
5508 }
5509
5510 return true;
5511}
5512
5513function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderExpirationTime) {
5514 renderExpirationTime = nextRenderExpirationTime;
5515 currentlyRenderingFiber$1 = workInProgress;
5516
5517 {
5518 hookTypesDev = current !== null ? current._debugHookTypes : null;
5519 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
5520
5521 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
5522 }
5523
5524 workInProgress.memoizedState = null;
5525 workInProgress.updateQueue = null;
5526 workInProgress.expirationTime = NoWork; // The following should have already been reset
5527 // currentHook = null;
5528 // workInProgressHook = null;
5529 // didScheduleRenderPhaseUpdate = false;
5530 // TODO Warn if no hooks are used at all during mount, then some are used during update.
5531 // Currently we will identify the update render as a mount because memoizedState === null.
5532 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
5533 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.
5534 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
5535 // so memoizedState would be null during updates and mounts.
5536
5537 {
5538 if (current !== null && current.memoizedState !== null) {
5539 ReactCurrentDispatcher.current = HooksDispatcherOnUpdateInDEV;
5540 } else if (hookTypesDev !== null) {
5541 // This dispatcher handles an edge case where a component is updating,
5542 // but no stateful hooks have been used.
5543 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
5544 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
5545 // This dispatcher does that.
5546 ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV;
5547 } else {
5548 ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV;
5549 }
5550 }
5551
5552 var children = Component(props, secondArg); // Check if there was a render phase update
5553
5554 if (workInProgress.expirationTime === renderExpirationTime) {
5555 // Keep rendering in a loop for as long as render phase updates continue to
5556 // be scheduled. Use a counter to prevent infinite loops.
5557 var numberOfReRenders = 0;
5558
5559 do {
5560 workInProgress.expirationTime = NoWork;
5561
5562 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {
5563 {
5564 throw Error( "Too many re-renders. React limits the number of renders to prevent an infinite loop." );
5565 }
5566 }
5567
5568 numberOfReRenders += 1;
5569
5570 {
5571 // Even when hot reloading, allow dependencies to stabilize
5572 // after first render to prevent infinite render phase updates.
5573 ignorePreviousDependencies = false;
5574 } // Start over from the beginning of the list
5575
5576
5577 currentHook = null;
5578 workInProgressHook = null;
5579 workInProgress.updateQueue = null;
5580
5581 {
5582 // Also validate hook order for cascading updates.
5583 hookTypesUpdateIndexDev = -1;
5584 }
5585
5586 ReactCurrentDispatcher.current = HooksDispatcherOnRerenderInDEV ;
5587 children = Component(props, secondArg);
5588 } while (workInProgress.expirationTime === renderExpirationTime);
5589 } // We can assume the previous dispatcher is always this one, since we set it
5590 // at the beginning of the render phase and there's no re-entrancy.
5591
5592
5593 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
5594
5595 {
5596 workInProgress._debugHookTypes = hookTypesDev;
5597 } // This check uses currentHook so that it works the same in DEV and prod bundles.
5598 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
5599
5600
5601 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
5602 renderExpirationTime = NoWork;
5603 currentlyRenderingFiber$1 = null;
5604 currentHook = null;
5605 workInProgressHook = null;
5606
5607 {
5608 currentHookNameInDev = null;
5609 hookTypesDev = null;
5610 hookTypesUpdateIndexDev = -1;
5611 }
5612
5613 didScheduleRenderPhaseUpdate = false;
5614
5615 if (!!didRenderTooFewHooks) {
5616 {
5617 throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." );
5618 }
5619 }
5620
5621 return children;
5622}
5623function bailoutHooks(current, workInProgress, expirationTime) {
5624 workInProgress.updateQueue = current.updateQueue;
5625 workInProgress.effectTag &= ~(Passive | Update);
5626
5627 if (current.expirationTime <= expirationTime) {
5628 current.expirationTime = NoWork;
5629 }
5630}
5631function resetHooksAfterThrow() {
5632 // We can assume the previous dispatcher is always this one, since we set it
5633 // at the beginning of the render phase and there's no re-entrancy.
5634 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
5635
5636 if (didScheduleRenderPhaseUpdate) {
5637 // There were render phase updates. These are only valid for this render
5638 // phase, which we are now aborting. Remove the updates from the queues so
5639 // they do not persist to the next render. Do not remove updates from hooks
5640 // that weren't processed.
5641 //
5642 // Only reset the updates from the queue if it has a clone. If it does
5643 // not have a clone, that means it wasn't processed, and the updates were
5644 // scheduled before we entered the render phase.
5645 var hook = currentlyRenderingFiber$1.memoizedState;
5646
5647 while (hook !== null) {
5648 var queue = hook.queue;
5649
5650 if (queue !== null) {
5651 queue.pending = null;
5652 }
5653
5654 hook = hook.next;
5655 }
5656 }
5657
5658 renderExpirationTime = NoWork;
5659 currentlyRenderingFiber$1 = null;
5660 currentHook = null;
5661 workInProgressHook = null;
5662
5663 {
5664 hookTypesDev = null;
5665 hookTypesUpdateIndexDev = -1;
5666 currentHookNameInDev = null;
5667 }
5668
5669 didScheduleRenderPhaseUpdate = false;
5670}
5671
5672function mountWorkInProgressHook() {
5673 var hook = {
5674 memoizedState: null,
5675 baseState: null,
5676 baseQueue: null,
5677 queue: null,
5678 next: null
5679 };
5680
5681 if (workInProgressHook === null) {
5682 // This is the first hook in the list
5683 currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;
5684 } else {
5685 // Append to the end of the list
5686 workInProgressHook = workInProgressHook.next = hook;
5687 }
5688
5689 return workInProgressHook;
5690}
5691
5692function updateWorkInProgressHook() {
5693 // This function is used both for updates and for re-renders triggered by a
5694 // render phase update. It assumes there is either a current hook we can
5695 // clone, or a work-in-progress hook from a previous render pass that we can
5696 // use as a base. When we reach the end of the base list, we must switch to
5697 // the dispatcher used for mounts.
5698 var nextCurrentHook;
5699
5700 if (currentHook === null) {
5701 var current = currentlyRenderingFiber$1.alternate;
5702
5703 if (current !== null) {
5704 nextCurrentHook = current.memoizedState;
5705 } else {
5706 nextCurrentHook = null;
5707 }
5708 } else {
5709 nextCurrentHook = currentHook.next;
5710 }
5711
5712 var nextWorkInProgressHook;
5713
5714 if (workInProgressHook === null) {
5715 nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;
5716 } else {
5717 nextWorkInProgressHook = workInProgressHook.next;
5718 }
5719
5720 if (nextWorkInProgressHook !== null) {
5721 // There's already a work-in-progress. Reuse it.
5722 workInProgressHook = nextWorkInProgressHook;
5723 nextWorkInProgressHook = workInProgressHook.next;
5724 currentHook = nextCurrentHook;
5725 } else {
5726 // Clone from the current hook.
5727 if (!(nextCurrentHook !== null)) {
5728 {
5729 throw Error( "Rendered more hooks than during the previous render." );
5730 }
5731 }
5732
5733 currentHook = nextCurrentHook;
5734 var newHook = {
5735 memoizedState: currentHook.memoizedState,
5736 baseState: currentHook.baseState,
5737 baseQueue: currentHook.baseQueue,
5738 queue: currentHook.queue,
5739 next: null
5740 };
5741
5742 if (workInProgressHook === null) {
5743 // This is the first hook in the list.
5744 currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;
5745 } else {
5746 // Append to the end of the list.
5747 workInProgressHook = workInProgressHook.next = newHook;
5748 }
5749 }
5750
5751 return workInProgressHook;
5752}
5753
5754function createFunctionComponentUpdateQueue() {
5755 return {
5756 lastEffect: null
5757 };
5758}
5759
5760function basicStateReducer(state, action) {
5761 // $FlowFixMe: Flow doesn't like mixed types
5762 return typeof action === 'function' ? action(state) : action;
5763}
5764
5765function mountReducer(reducer, initialArg, init) {
5766 var hook = mountWorkInProgressHook();
5767 var initialState;
5768
5769 if (init !== undefined) {
5770 initialState = init(initialArg);
5771 } else {
5772 initialState = initialArg;
5773 }
5774
5775 hook.memoizedState = hook.baseState = initialState;
5776 var queue = hook.queue = {
5777 pending: null,
5778 dispatch: null,
5779 lastRenderedReducer: reducer,
5780 lastRenderedState: initialState
5781 };
5782 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
5783 return [hook.memoizedState, dispatch];
5784}
5785
5786function updateReducer(reducer, initialArg, init) {
5787 var hook = updateWorkInProgressHook();
5788 var queue = hook.queue;
5789
5790 if (!(queue !== null)) {
5791 {
5792 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
5793 }
5794 }
5795
5796 queue.lastRenderedReducer = reducer;
5797 var current = currentHook; // The last rebase update that is NOT part of the base state.
5798
5799 var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet.
5800
5801 var pendingQueue = queue.pending;
5802
5803 if (pendingQueue !== null) {
5804 // We have new updates that haven't been processed yet.
5805 // We'll add them to the base queue.
5806 if (baseQueue !== null) {
5807 // Merge the pending queue and the base queue.
5808 var baseFirst = baseQueue.next;
5809 var pendingFirst = pendingQueue.next;
5810 baseQueue.next = pendingFirst;
5811 pendingQueue.next = baseFirst;
5812 }
5813
5814 current.baseQueue = baseQueue = pendingQueue;
5815 queue.pending = null;
5816 }
5817
5818 if (baseQueue !== null) {
5819 // We have a queue to process.
5820 var first = baseQueue.next;
5821 var newState = current.baseState;
5822 var newBaseState = null;
5823 var newBaseQueueFirst = null;
5824 var newBaseQueueLast = null;
5825 var update = first;
5826
5827 do {
5828 var updateExpirationTime = update.expirationTime;
5829
5830 if (updateExpirationTime < renderExpirationTime) {
5831 // Priority is insufficient. Skip this update. If this is the first
5832 // skipped update, the previous update/state is the new base
5833 // update/state.
5834 var clone = {
5835 expirationTime: update.expirationTime,
5836 suspenseConfig: update.suspenseConfig,
5837 action: update.action,
5838 eagerReducer: update.eagerReducer,
5839 eagerState: update.eagerState,
5840 next: null
5841 };
5842
5843 if (newBaseQueueLast === null) {
5844 newBaseQueueFirst = newBaseQueueLast = clone;
5845 newBaseState = newState;
5846 } else {
5847 newBaseQueueLast = newBaseQueueLast.next = clone;
5848 } // Update the remaining priority in the queue.
5849
5850
5851 if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) {
5852 currentlyRenderingFiber$1.expirationTime = updateExpirationTime;
5853 markUnprocessedUpdateTime(updateExpirationTime);
5854 }
5855 } else {
5856 // This update does have sufficient priority.
5857 if (newBaseQueueLast !== null) {
5858 var _clone = {
5859 expirationTime: Sync,
5860 // This update is going to be committed so we never want uncommit it.
5861 suspenseConfig: update.suspenseConfig,
5862 action: update.action,
5863 eagerReducer: update.eagerReducer,
5864 eagerState: update.eagerState,
5865 next: null
5866 };
5867 newBaseQueueLast = newBaseQueueLast.next = _clone;
5868 } // Mark the event time of this update as relevant to this render pass.
5869 // TODO: This should ideally use the true event time of this update rather than
5870 // its priority which is a derived and not reverseable value.
5871 // TODO: We should skip this update if it was already committed but currently
5872 // we have no way of detecting the difference between a committed and suspended
5873 // update here.
5874
5875
5876 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process this update.
5877
5878 if (update.eagerReducer === reducer) {
5879 // If this update was processed eagerly, and its reducer matches the
5880 // current reducer, we can use the eagerly computed state.
5881 newState = update.eagerState;
5882 } else {
5883 var action = update.action;
5884 newState = reducer(newState, action);
5885 }
5886 }
5887
5888 update = update.next;
5889 } while (update !== null && update !== first);
5890
5891 if (newBaseQueueLast === null) {
5892 newBaseState = newState;
5893 } else {
5894 newBaseQueueLast.next = newBaseQueueFirst;
5895 } // Mark that the fiber performed work, but only if the new state is
5896 // different from the current state.
5897
5898
5899 if (!objectIs(newState, hook.memoizedState)) {
5900 markWorkInProgressReceivedUpdate();
5901 }
5902
5903 hook.memoizedState = newState;
5904 hook.baseState = newBaseState;
5905 hook.baseQueue = newBaseQueueLast;
5906 queue.lastRenderedState = newState;
5907 }
5908
5909 var dispatch = queue.dispatch;
5910 return [hook.memoizedState, dispatch];
5911}
5912
5913function rerenderReducer(reducer, initialArg, init) {
5914 var hook = updateWorkInProgressHook();
5915 var queue = hook.queue;
5916
5917 if (!(queue !== null)) {
5918 {
5919 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
5920 }
5921 }
5922
5923 queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous
5924 // work-in-progress hook.
5925
5926 var dispatch = queue.dispatch;
5927 var lastRenderPhaseUpdate = queue.pending;
5928 var newState = hook.memoizedState;
5929
5930 if (lastRenderPhaseUpdate !== null) {
5931 // The queue doesn't persist past this render pass.
5932 queue.pending = null;
5933 var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;
5934 var update = firstRenderPhaseUpdate;
5935
5936 do {
5937 // Process this render phase update. We don't have to check the
5938 // priority because it will always be the same as the current
5939 // render's.
5940 var action = update.action;
5941 newState = reducer(newState, action);
5942 update = update.next;
5943 } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is
5944 // different from the current state.
5945
5946
5947 if (!objectIs(newState, hook.memoizedState)) {
5948 markWorkInProgressReceivedUpdate();
5949 }
5950
5951 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
5952 // the base state unless the queue is empty.
5953 // TODO: Not sure if this is the desired semantics, but it's what we
5954 // do for gDSFP. I can't remember why.
5955
5956 if (hook.baseQueue === null) {
5957 hook.baseState = newState;
5958 }
5959
5960 queue.lastRenderedState = newState;
5961 }
5962
5963 return [newState, dispatch];
5964}
5965
5966function mountState(initialState) {
5967 var hook = mountWorkInProgressHook();
5968
5969 if (typeof initialState === 'function') {
5970 // $FlowFixMe: Flow doesn't like mixed types
5971 initialState = initialState();
5972 }
5973
5974 hook.memoizedState = hook.baseState = initialState;
5975 var queue = hook.queue = {
5976 pending: null,
5977 dispatch: null,
5978 lastRenderedReducer: basicStateReducer,
5979 lastRenderedState: initialState
5980 };
5981 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
5982 return [hook.memoizedState, dispatch];
5983}
5984
5985function updateState(initialState) {
5986 return updateReducer(basicStateReducer);
5987}
5988
5989function rerenderState(initialState) {
5990 return rerenderReducer(basicStateReducer);
5991}
5992
5993function pushEffect(tag, create, destroy, deps) {
5994 var effect = {
5995 tag: tag,
5996 create: create,
5997 destroy: destroy,
5998 deps: deps,
5999 // Circular
6000 next: null
6001 };
6002 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
6003
6004 if (componentUpdateQueue === null) {
6005 componentUpdateQueue = createFunctionComponentUpdateQueue();
6006 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
6007 componentUpdateQueue.lastEffect = effect.next = effect;
6008 } else {
6009 var lastEffect = componentUpdateQueue.lastEffect;
6010
6011 if (lastEffect === null) {
6012 componentUpdateQueue.lastEffect = effect.next = effect;
6013 } else {
6014 var firstEffect = lastEffect.next;
6015 lastEffect.next = effect;
6016 effect.next = firstEffect;
6017 componentUpdateQueue.lastEffect = effect;
6018 }
6019 }
6020
6021 return effect;
6022}
6023
6024function mountRef(initialValue) {
6025 var hook = mountWorkInProgressHook();
6026 var ref = {
6027 current: initialValue
6028 };
6029
6030 {
6031 Object.seal(ref);
6032 }
6033
6034 hook.memoizedState = ref;
6035 return ref;
6036}
6037
6038function updateRef(initialValue) {
6039 var hook = updateWorkInProgressHook();
6040 return hook.memoizedState;
6041}
6042
6043function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
6044 var hook = mountWorkInProgressHook();
6045 var nextDeps = deps === undefined ? null : deps;
6046 currentlyRenderingFiber$1.effectTag |= fiberEffectTag;
6047 hook.memoizedState = pushEffect(HasEffect | hookEffectTag, create, undefined, nextDeps);
6048}
6049
6050function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
6051 var hook = updateWorkInProgressHook();
6052 var nextDeps = deps === undefined ? null : deps;
6053 var destroy = undefined;
6054
6055 if (currentHook !== null) {
6056 var prevEffect = currentHook.memoizedState;
6057 destroy = prevEffect.destroy;
6058
6059 if (nextDeps !== null) {
6060 var prevDeps = prevEffect.deps;
6061
6062 if (areHookInputsEqual(nextDeps, prevDeps)) {
6063 pushEffect(hookEffectTag, create, destroy, nextDeps);
6064 return;
6065 }
6066 }
6067 }
6068
6069 currentlyRenderingFiber$1.effectTag |= fiberEffectTag;
6070 hook.memoizedState = pushEffect(HasEffect | hookEffectTag, create, destroy, nextDeps);
6071}
6072
6073function mountEffect(create, deps) {
6074 {
6075 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
6076 if ('undefined' !== typeof jest) {
6077 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
6078 }
6079 }
6080
6081 return mountEffectImpl(Update | Passive, Passive$1, create, deps);
6082}
6083
6084function updateEffect(create, deps) {
6085 {
6086 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
6087 if ('undefined' !== typeof jest) {
6088 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
6089 }
6090 }
6091
6092 return updateEffectImpl(Update | Passive, Passive$1, create, deps);
6093}
6094
6095function mountLayoutEffect(create, deps) {
6096 return mountEffectImpl(Update, Layout, create, deps);
6097}
6098
6099function updateLayoutEffect(create, deps) {
6100 return updateEffectImpl(Update, Layout, create, deps);
6101}
6102
6103function imperativeHandleEffect(create, ref) {
6104 if (typeof ref === 'function') {
6105 var refCallback = ref;
6106
6107 var _inst = create();
6108
6109 refCallback(_inst);
6110 return function () {
6111 refCallback(null);
6112 };
6113 } else if (ref !== null && ref !== undefined) {
6114 var refObject = ref;
6115
6116 {
6117 if (!refObject.hasOwnProperty('current')) {
6118 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(', ') + '}');
6119 }
6120 }
6121
6122 var _inst2 = create();
6123
6124 refObject.current = _inst2;
6125 return function () {
6126 refObject.current = null;
6127 };
6128 }
6129}
6130
6131function mountImperativeHandle(ref, create, deps) {
6132 {
6133 if (typeof create !== 'function') {
6134 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
6135 }
6136 } // TODO: If deps are provided, should we skip comparing the ref itself?
6137
6138
6139 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6140 return mountEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6141}
6142
6143function updateImperativeHandle(ref, create, deps) {
6144 {
6145 if (typeof create !== 'function') {
6146 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
6147 }
6148 } // TODO: If deps are provided, should we skip comparing the ref itself?
6149
6150
6151 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6152 return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6153}
6154
6155function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.
6156 // The react-debug-hooks package injects its own implementation
6157 // so that e.g. DevTools can display custom hook values.
6158}
6159
6160var updateDebugValue = mountDebugValue;
6161
6162function mountCallback(callback, deps) {
6163 var hook = mountWorkInProgressHook();
6164 var nextDeps = deps === undefined ? null : deps;
6165 hook.memoizedState = [callback, nextDeps];
6166 return callback;
6167}
6168
6169function updateCallback(callback, deps) {
6170 var hook = updateWorkInProgressHook();
6171 var nextDeps = deps === undefined ? null : deps;
6172 var prevState = hook.memoizedState;
6173
6174 if (prevState !== null) {
6175 if (nextDeps !== null) {
6176 var prevDeps = prevState[1];
6177
6178 if (areHookInputsEqual(nextDeps, prevDeps)) {
6179 return prevState[0];
6180 }
6181 }
6182 }
6183
6184 hook.memoizedState = [callback, nextDeps];
6185 return callback;
6186}
6187
6188function mountMemo(nextCreate, deps) {
6189 var hook = mountWorkInProgressHook();
6190 var nextDeps = deps === undefined ? null : deps;
6191 var nextValue = nextCreate();
6192 hook.memoizedState = [nextValue, nextDeps];
6193 return nextValue;
6194}
6195
6196function updateMemo(nextCreate, deps) {
6197 var hook = updateWorkInProgressHook();
6198 var nextDeps = deps === undefined ? null : deps;
6199 var prevState = hook.memoizedState;
6200
6201 if (prevState !== null) {
6202 // Assume these are defined. If they're not, areHookInputsEqual will warn.
6203 if (nextDeps !== null) {
6204 var prevDeps = prevState[1];
6205
6206 if (areHookInputsEqual(nextDeps, prevDeps)) {
6207 return prevState[0];
6208 }
6209 }
6210 }
6211
6212 var nextValue = nextCreate();
6213 hook.memoizedState = [nextValue, nextDeps];
6214 return nextValue;
6215}
6216
6217function mountDeferredValue(value, config) {
6218 var _mountState = mountState(value),
6219 prevValue = _mountState[0],
6220 setValue = _mountState[1];
6221
6222 mountEffect(function () {
6223 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6224 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6225
6226 try {
6227 setValue(value);
6228 } finally {
6229 ReactCurrentBatchConfig$1.suspense = previousConfig;
6230 }
6231 }, [value, config]);
6232 return prevValue;
6233}
6234
6235function updateDeferredValue(value, config) {
6236 var _updateState = updateState(),
6237 prevValue = _updateState[0],
6238 setValue = _updateState[1];
6239
6240 updateEffect(function () {
6241 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6242 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6243
6244 try {
6245 setValue(value);
6246 } finally {
6247 ReactCurrentBatchConfig$1.suspense = previousConfig;
6248 }
6249 }, [value, config]);
6250 return prevValue;
6251}
6252
6253function rerenderDeferredValue(value, config) {
6254 var _rerenderState = rerenderState(),
6255 prevValue = _rerenderState[0],
6256 setValue = _rerenderState[1];
6257
6258 updateEffect(function () {
6259 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6260 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6261
6262 try {
6263 setValue(value);
6264 } finally {
6265 ReactCurrentBatchConfig$1.suspense = previousConfig;
6266 }
6267 }, [value, config]);
6268 return prevValue;
6269}
6270
6271function startTransition(setPending, config, callback) {
6272 var priorityLevel = getCurrentPriorityLevel();
6273 runWithPriority(priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel, function () {
6274 setPending(true);
6275 });
6276 runWithPriority(priorityLevel > NormalPriority ? NormalPriority : priorityLevel, function () {
6277 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6278 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6279
6280 try {
6281 setPending(false);
6282 callback();
6283 } finally {
6284 ReactCurrentBatchConfig$1.suspense = previousConfig;
6285 }
6286 });
6287}
6288
6289function mountTransition(config) {
6290 var _mountState2 = mountState(false),
6291 isPending = _mountState2[0],
6292 setPending = _mountState2[1];
6293
6294 var start = mountCallback(startTransition.bind(null, setPending, config), [setPending, config]);
6295 return [start, isPending];
6296}
6297
6298function updateTransition(config) {
6299 var _updateState2 = updateState(),
6300 isPending = _updateState2[0],
6301 setPending = _updateState2[1];
6302
6303 var start = updateCallback(startTransition.bind(null, setPending, config), [setPending, config]);
6304 return [start, isPending];
6305}
6306
6307function rerenderTransition(config) {
6308 var _rerenderState2 = rerenderState(),
6309 isPending = _rerenderState2[0],
6310 setPending = _rerenderState2[1];
6311
6312 var start = updateCallback(startTransition.bind(null, setPending, config), [setPending, config]);
6313 return [start, isPending];
6314}
6315
6316function dispatchAction(fiber, queue, action) {
6317 {
6318 if (typeof arguments[3] === 'function') {
6319 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().');
6320 }
6321 }
6322
6323 var currentTime = requestCurrentTimeForUpdate();
6324 var suspenseConfig = requestCurrentSuspenseConfig();
6325 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
6326 var update = {
6327 expirationTime: expirationTime,
6328 suspenseConfig: suspenseConfig,
6329 action: action,
6330 eagerReducer: null,
6331 eagerState: null,
6332 next: null
6333 };
6334
6335 {
6336 update.priority = getCurrentPriorityLevel();
6337 } // Append the update to the end of the list.
6338
6339
6340 var pending = queue.pending;
6341
6342 if (pending === null) {
6343 // This is the first update. Create a circular list.
6344 update.next = update;
6345 } else {
6346 update.next = pending.next;
6347 pending.next = update;
6348 }
6349
6350 queue.pending = update;
6351 var alternate = fiber.alternate;
6352
6353 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
6354 // This is a render phase update. Stash it in a lazily-created map of
6355 // queue -> linked list of updates. After this render pass, we'll restart
6356 // and apply the stashed updates on top of the work-in-progress hook.
6357 didScheduleRenderPhaseUpdate = true;
6358 update.expirationTime = renderExpirationTime;
6359 currentlyRenderingFiber$1.expirationTime = renderExpirationTime;
6360 } else {
6361 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
6362 // The queue is currently empty, which means we can eagerly compute the
6363 // next state before entering the render phase. If the new state is the
6364 // same as the current state, we may be able to bail out entirely.
6365 var lastRenderedReducer = queue.lastRenderedReducer;
6366
6367 if (lastRenderedReducer !== null) {
6368 var prevDispatcher;
6369
6370 {
6371 prevDispatcher = ReactCurrentDispatcher.current;
6372 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6373 }
6374
6375 try {
6376 var currentState = queue.lastRenderedState;
6377 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
6378 // it, on the update object. If the reducer hasn't changed by the
6379 // time we enter the render phase, then the eager state can be used
6380 // without calling the reducer again.
6381
6382 update.eagerReducer = lastRenderedReducer;
6383 update.eagerState = eagerState;
6384
6385 if (objectIs(eagerState, currentState)) {
6386 // Fast path. We can bail out without scheduling React to re-render.
6387 // It's still possible that we'll need to rebase this update later,
6388 // if the component re-renders for a different reason and by that
6389 // time the reducer has changed.
6390 return;
6391 }
6392 } catch (error) {// Suppress the error. It will throw again in the render phase.
6393 } finally {
6394 {
6395 ReactCurrentDispatcher.current = prevDispatcher;
6396 }
6397 }
6398 }
6399 }
6400
6401 {
6402 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
6403 if ('undefined' !== typeof jest) {
6404 warnIfNotScopedWithMatchingAct(fiber);
6405 warnIfNotCurrentlyActingUpdatesInDev(fiber);
6406 }
6407 }
6408
6409 scheduleWork(fiber, expirationTime);
6410 }
6411}
6412
6413var ContextOnlyDispatcher = {
6414 readContext: readContext,
6415 useCallback: throwInvalidHookError,
6416 useContext: throwInvalidHookError,
6417 useEffect: throwInvalidHookError,
6418 useImperativeHandle: throwInvalidHookError,
6419 useLayoutEffect: throwInvalidHookError,
6420 useMemo: throwInvalidHookError,
6421 useReducer: throwInvalidHookError,
6422 useRef: throwInvalidHookError,
6423 useState: throwInvalidHookError,
6424 useDebugValue: throwInvalidHookError,
6425 useResponder: throwInvalidHookError,
6426 useDeferredValue: throwInvalidHookError,
6427 useTransition: throwInvalidHookError
6428};
6429var HooksDispatcherOnMountInDEV = null;
6430var HooksDispatcherOnMountWithHookTypesInDEV = null;
6431var HooksDispatcherOnUpdateInDEV = null;
6432var HooksDispatcherOnRerenderInDEV = null;
6433var InvalidNestedHooksDispatcherOnMountInDEV = null;
6434var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
6435var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
6436
6437{
6438 var warnInvalidContextAccess = function () {
6439 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().');
6440 };
6441
6442 var warnInvalidHookAccess = function () {
6443 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://fb.me/rules-of-hooks');
6444 };
6445
6446 HooksDispatcherOnMountInDEV = {
6447 readContext: function (context, observedBits) {
6448 return readContext(context, observedBits);
6449 },
6450 useCallback: function (callback, deps) {
6451 currentHookNameInDev = 'useCallback';
6452 mountHookTypesDev();
6453 checkDepsAreArrayDev(deps);
6454 return mountCallback(callback, deps);
6455 },
6456 useContext: function (context, observedBits) {
6457 currentHookNameInDev = 'useContext';
6458 mountHookTypesDev();
6459 return readContext(context, observedBits);
6460 },
6461 useEffect: function (create, deps) {
6462 currentHookNameInDev = 'useEffect';
6463 mountHookTypesDev();
6464 checkDepsAreArrayDev(deps);
6465 return mountEffect(create, deps);
6466 },
6467 useImperativeHandle: function (ref, create, deps) {
6468 currentHookNameInDev = 'useImperativeHandle';
6469 mountHookTypesDev();
6470 checkDepsAreArrayDev(deps);
6471 return mountImperativeHandle(ref, create, deps);
6472 },
6473 useLayoutEffect: function (create, deps) {
6474 currentHookNameInDev = 'useLayoutEffect';
6475 mountHookTypesDev();
6476 checkDepsAreArrayDev(deps);
6477 return mountLayoutEffect(create, deps);
6478 },
6479 useMemo: function (create, deps) {
6480 currentHookNameInDev = 'useMemo';
6481 mountHookTypesDev();
6482 checkDepsAreArrayDev(deps);
6483 var prevDispatcher = ReactCurrentDispatcher.current;
6484 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6485
6486 try {
6487 return mountMemo(create, deps);
6488 } finally {
6489 ReactCurrentDispatcher.current = prevDispatcher;
6490 }
6491 },
6492 useReducer: function (reducer, initialArg, init) {
6493 currentHookNameInDev = 'useReducer';
6494 mountHookTypesDev();
6495 var prevDispatcher = ReactCurrentDispatcher.current;
6496 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6497
6498 try {
6499 return mountReducer(reducer, initialArg, init);
6500 } finally {
6501 ReactCurrentDispatcher.current = prevDispatcher;
6502 }
6503 },
6504 useRef: function (initialValue) {
6505 currentHookNameInDev = 'useRef';
6506 mountHookTypesDev();
6507 return mountRef(initialValue);
6508 },
6509 useState: function (initialState) {
6510 currentHookNameInDev = 'useState';
6511 mountHookTypesDev();
6512 var prevDispatcher = ReactCurrentDispatcher.current;
6513 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6514
6515 try {
6516 return mountState(initialState);
6517 } finally {
6518 ReactCurrentDispatcher.current = prevDispatcher;
6519 }
6520 },
6521 useDebugValue: function (value, formatterFn) {
6522 currentHookNameInDev = 'useDebugValue';
6523 mountHookTypesDev();
6524 return mountDebugValue();
6525 },
6526 useResponder: function (responder, props) {
6527 currentHookNameInDev = 'useResponder';
6528 mountHookTypesDev();
6529 return createDeprecatedResponderListener(responder, props);
6530 },
6531 useDeferredValue: function (value, config) {
6532 currentHookNameInDev = 'useDeferredValue';
6533 mountHookTypesDev();
6534 return mountDeferredValue(value, config);
6535 },
6536 useTransition: function (config) {
6537 currentHookNameInDev = 'useTransition';
6538 mountHookTypesDev();
6539 return mountTransition(config);
6540 }
6541 };
6542 HooksDispatcherOnMountWithHookTypesInDEV = {
6543 readContext: function (context, observedBits) {
6544 return readContext(context, observedBits);
6545 },
6546 useCallback: function (callback, deps) {
6547 currentHookNameInDev = 'useCallback';
6548 updateHookTypesDev();
6549 return mountCallback(callback, deps);
6550 },
6551 useContext: function (context, observedBits) {
6552 currentHookNameInDev = 'useContext';
6553 updateHookTypesDev();
6554 return readContext(context, observedBits);
6555 },
6556 useEffect: function (create, deps) {
6557 currentHookNameInDev = 'useEffect';
6558 updateHookTypesDev();
6559 return mountEffect(create, deps);
6560 },
6561 useImperativeHandle: function (ref, create, deps) {
6562 currentHookNameInDev = 'useImperativeHandle';
6563 updateHookTypesDev();
6564 return mountImperativeHandle(ref, create, deps);
6565 },
6566 useLayoutEffect: function (create, deps) {
6567 currentHookNameInDev = 'useLayoutEffect';
6568 updateHookTypesDev();
6569 return mountLayoutEffect(create, deps);
6570 },
6571 useMemo: function (create, deps) {
6572 currentHookNameInDev = 'useMemo';
6573 updateHookTypesDev();
6574 var prevDispatcher = ReactCurrentDispatcher.current;
6575 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6576
6577 try {
6578 return mountMemo(create, deps);
6579 } finally {
6580 ReactCurrentDispatcher.current = prevDispatcher;
6581 }
6582 },
6583 useReducer: function (reducer, initialArg, init) {
6584 currentHookNameInDev = 'useReducer';
6585 updateHookTypesDev();
6586 var prevDispatcher = ReactCurrentDispatcher.current;
6587 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6588
6589 try {
6590 return mountReducer(reducer, initialArg, init);
6591 } finally {
6592 ReactCurrentDispatcher.current = prevDispatcher;
6593 }
6594 },
6595 useRef: function (initialValue) {
6596 currentHookNameInDev = 'useRef';
6597 updateHookTypesDev();
6598 return mountRef(initialValue);
6599 },
6600 useState: function (initialState) {
6601 currentHookNameInDev = 'useState';
6602 updateHookTypesDev();
6603 var prevDispatcher = ReactCurrentDispatcher.current;
6604 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6605
6606 try {
6607 return mountState(initialState);
6608 } finally {
6609 ReactCurrentDispatcher.current = prevDispatcher;
6610 }
6611 },
6612 useDebugValue: function (value, formatterFn) {
6613 currentHookNameInDev = 'useDebugValue';
6614 updateHookTypesDev();
6615 return mountDebugValue();
6616 },
6617 useResponder: function (responder, props) {
6618 currentHookNameInDev = 'useResponder';
6619 updateHookTypesDev();
6620 return createDeprecatedResponderListener(responder, props);
6621 },
6622 useDeferredValue: function (value, config) {
6623 currentHookNameInDev = 'useDeferredValue';
6624 updateHookTypesDev();
6625 return mountDeferredValue(value, config);
6626 },
6627 useTransition: function (config) {
6628 currentHookNameInDev = 'useTransition';
6629 updateHookTypesDev();
6630 return mountTransition(config);
6631 }
6632 };
6633 HooksDispatcherOnUpdateInDEV = {
6634 readContext: function (context, observedBits) {
6635 return readContext(context, observedBits);
6636 },
6637 useCallback: function (callback, deps) {
6638 currentHookNameInDev = 'useCallback';
6639 updateHookTypesDev();
6640 return updateCallback(callback, deps);
6641 },
6642 useContext: function (context, observedBits) {
6643 currentHookNameInDev = 'useContext';
6644 updateHookTypesDev();
6645 return readContext(context, observedBits);
6646 },
6647 useEffect: function (create, deps) {
6648 currentHookNameInDev = 'useEffect';
6649 updateHookTypesDev();
6650 return updateEffect(create, deps);
6651 },
6652 useImperativeHandle: function (ref, create, deps) {
6653 currentHookNameInDev = 'useImperativeHandle';
6654 updateHookTypesDev();
6655 return updateImperativeHandle(ref, create, deps);
6656 },
6657 useLayoutEffect: function (create, deps) {
6658 currentHookNameInDev = 'useLayoutEffect';
6659 updateHookTypesDev();
6660 return updateLayoutEffect(create, deps);
6661 },
6662 useMemo: function (create, deps) {
6663 currentHookNameInDev = 'useMemo';
6664 updateHookTypesDev();
6665 var prevDispatcher = ReactCurrentDispatcher.current;
6666 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6667
6668 try {
6669 return updateMemo(create, deps);
6670 } finally {
6671 ReactCurrentDispatcher.current = prevDispatcher;
6672 }
6673 },
6674 useReducer: function (reducer, initialArg, init) {
6675 currentHookNameInDev = 'useReducer';
6676 updateHookTypesDev();
6677 var prevDispatcher = ReactCurrentDispatcher.current;
6678 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6679
6680 try {
6681 return updateReducer(reducer, initialArg, init);
6682 } finally {
6683 ReactCurrentDispatcher.current = prevDispatcher;
6684 }
6685 },
6686 useRef: function (initialValue) {
6687 currentHookNameInDev = 'useRef';
6688 updateHookTypesDev();
6689 return updateRef();
6690 },
6691 useState: function (initialState) {
6692 currentHookNameInDev = 'useState';
6693 updateHookTypesDev();
6694 var prevDispatcher = ReactCurrentDispatcher.current;
6695 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6696
6697 try {
6698 return updateState(initialState);
6699 } finally {
6700 ReactCurrentDispatcher.current = prevDispatcher;
6701 }
6702 },
6703 useDebugValue: function (value, formatterFn) {
6704 currentHookNameInDev = 'useDebugValue';
6705 updateHookTypesDev();
6706 return updateDebugValue();
6707 },
6708 useResponder: function (responder, props) {
6709 currentHookNameInDev = 'useResponder';
6710 updateHookTypesDev();
6711 return createDeprecatedResponderListener(responder, props);
6712 },
6713 useDeferredValue: function (value, config) {
6714 currentHookNameInDev = 'useDeferredValue';
6715 updateHookTypesDev();
6716 return updateDeferredValue(value, config);
6717 },
6718 useTransition: function (config) {
6719 currentHookNameInDev = 'useTransition';
6720 updateHookTypesDev();
6721 return updateTransition(config);
6722 }
6723 };
6724 HooksDispatcherOnRerenderInDEV = {
6725 readContext: function (context, observedBits) {
6726 return readContext(context, observedBits);
6727 },
6728 useCallback: function (callback, deps) {
6729 currentHookNameInDev = 'useCallback';
6730 updateHookTypesDev();
6731 return updateCallback(callback, deps);
6732 },
6733 useContext: function (context, observedBits) {
6734 currentHookNameInDev = 'useContext';
6735 updateHookTypesDev();
6736 return readContext(context, observedBits);
6737 },
6738 useEffect: function (create, deps) {
6739 currentHookNameInDev = 'useEffect';
6740 updateHookTypesDev();
6741 return updateEffect(create, deps);
6742 },
6743 useImperativeHandle: function (ref, create, deps) {
6744 currentHookNameInDev = 'useImperativeHandle';
6745 updateHookTypesDev();
6746 return updateImperativeHandle(ref, create, deps);
6747 },
6748 useLayoutEffect: function (create, deps) {
6749 currentHookNameInDev = 'useLayoutEffect';
6750 updateHookTypesDev();
6751 return updateLayoutEffect(create, deps);
6752 },
6753 useMemo: function (create, deps) {
6754 currentHookNameInDev = 'useMemo';
6755 updateHookTypesDev();
6756 var prevDispatcher = ReactCurrentDispatcher.current;
6757 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
6758
6759 try {
6760 return updateMemo(create, deps);
6761 } finally {
6762 ReactCurrentDispatcher.current = prevDispatcher;
6763 }
6764 },
6765 useReducer: function (reducer, initialArg, init) {
6766 currentHookNameInDev = 'useReducer';
6767 updateHookTypesDev();
6768 var prevDispatcher = ReactCurrentDispatcher.current;
6769 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
6770
6771 try {
6772 return rerenderReducer(reducer, initialArg, init);
6773 } finally {
6774 ReactCurrentDispatcher.current = prevDispatcher;
6775 }
6776 },
6777 useRef: function (initialValue) {
6778 currentHookNameInDev = 'useRef';
6779 updateHookTypesDev();
6780 return updateRef();
6781 },
6782 useState: function (initialState) {
6783 currentHookNameInDev = 'useState';
6784 updateHookTypesDev();
6785 var prevDispatcher = ReactCurrentDispatcher.current;
6786 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
6787
6788 try {
6789 return rerenderState(initialState);
6790 } finally {
6791 ReactCurrentDispatcher.current = prevDispatcher;
6792 }
6793 },
6794 useDebugValue: function (value, formatterFn) {
6795 currentHookNameInDev = 'useDebugValue';
6796 updateHookTypesDev();
6797 return updateDebugValue();
6798 },
6799 useResponder: function (responder, props) {
6800 currentHookNameInDev = 'useResponder';
6801 updateHookTypesDev();
6802 return createDeprecatedResponderListener(responder, props);
6803 },
6804 useDeferredValue: function (value, config) {
6805 currentHookNameInDev = 'useDeferredValue';
6806 updateHookTypesDev();
6807 return rerenderDeferredValue(value, config);
6808 },
6809 useTransition: function (config) {
6810 currentHookNameInDev = 'useTransition';
6811 updateHookTypesDev();
6812 return rerenderTransition(config);
6813 }
6814 };
6815 InvalidNestedHooksDispatcherOnMountInDEV = {
6816 readContext: function (context, observedBits) {
6817 warnInvalidContextAccess();
6818 return readContext(context, observedBits);
6819 },
6820 useCallback: function (callback, deps) {
6821 currentHookNameInDev = 'useCallback';
6822 warnInvalidHookAccess();
6823 mountHookTypesDev();
6824 return mountCallback(callback, deps);
6825 },
6826 useContext: function (context, observedBits) {
6827 currentHookNameInDev = 'useContext';
6828 warnInvalidHookAccess();
6829 mountHookTypesDev();
6830 return readContext(context, observedBits);
6831 },
6832 useEffect: function (create, deps) {
6833 currentHookNameInDev = 'useEffect';
6834 warnInvalidHookAccess();
6835 mountHookTypesDev();
6836 return mountEffect(create, deps);
6837 },
6838 useImperativeHandle: function (ref, create, deps) {
6839 currentHookNameInDev = 'useImperativeHandle';
6840 warnInvalidHookAccess();
6841 mountHookTypesDev();
6842 return mountImperativeHandle(ref, create, deps);
6843 },
6844 useLayoutEffect: function (create, deps) {
6845 currentHookNameInDev = 'useLayoutEffect';
6846 warnInvalidHookAccess();
6847 mountHookTypesDev();
6848 return mountLayoutEffect(create, deps);
6849 },
6850 useMemo: function (create, deps) {
6851 currentHookNameInDev = 'useMemo';
6852 warnInvalidHookAccess();
6853 mountHookTypesDev();
6854 var prevDispatcher = ReactCurrentDispatcher.current;
6855 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6856
6857 try {
6858 return mountMemo(create, deps);
6859 } finally {
6860 ReactCurrentDispatcher.current = prevDispatcher;
6861 }
6862 },
6863 useReducer: function (reducer, initialArg, init) {
6864 currentHookNameInDev = 'useReducer';
6865 warnInvalidHookAccess();
6866 mountHookTypesDev();
6867 var prevDispatcher = ReactCurrentDispatcher.current;
6868 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6869
6870 try {
6871 return mountReducer(reducer, initialArg, init);
6872 } finally {
6873 ReactCurrentDispatcher.current = prevDispatcher;
6874 }
6875 },
6876 useRef: function (initialValue) {
6877 currentHookNameInDev = 'useRef';
6878 warnInvalidHookAccess();
6879 mountHookTypesDev();
6880 return mountRef(initialValue);
6881 },
6882 useState: function (initialState) {
6883 currentHookNameInDev = 'useState';
6884 warnInvalidHookAccess();
6885 mountHookTypesDev();
6886 var prevDispatcher = ReactCurrentDispatcher.current;
6887 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
6888
6889 try {
6890 return mountState(initialState);
6891 } finally {
6892 ReactCurrentDispatcher.current = prevDispatcher;
6893 }
6894 },
6895 useDebugValue: function (value, formatterFn) {
6896 currentHookNameInDev = 'useDebugValue';
6897 warnInvalidHookAccess();
6898 mountHookTypesDev();
6899 return mountDebugValue();
6900 },
6901 useResponder: function (responder, props) {
6902 currentHookNameInDev = 'useResponder';
6903 warnInvalidHookAccess();
6904 mountHookTypesDev();
6905 return createDeprecatedResponderListener(responder, props);
6906 },
6907 useDeferredValue: function (value, config) {
6908 currentHookNameInDev = 'useDeferredValue';
6909 warnInvalidHookAccess();
6910 mountHookTypesDev();
6911 return mountDeferredValue(value, config);
6912 },
6913 useTransition: function (config) {
6914 currentHookNameInDev = 'useTransition';
6915 warnInvalidHookAccess();
6916 mountHookTypesDev();
6917 return mountTransition(config);
6918 }
6919 };
6920 InvalidNestedHooksDispatcherOnUpdateInDEV = {
6921 readContext: function (context, observedBits) {
6922 warnInvalidContextAccess();
6923 return readContext(context, observedBits);
6924 },
6925 useCallback: function (callback, deps) {
6926 currentHookNameInDev = 'useCallback';
6927 warnInvalidHookAccess();
6928 updateHookTypesDev();
6929 return updateCallback(callback, deps);
6930 },
6931 useContext: function (context, observedBits) {
6932 currentHookNameInDev = 'useContext';
6933 warnInvalidHookAccess();
6934 updateHookTypesDev();
6935 return readContext(context, observedBits);
6936 },
6937 useEffect: function (create, deps) {
6938 currentHookNameInDev = 'useEffect';
6939 warnInvalidHookAccess();
6940 updateHookTypesDev();
6941 return updateEffect(create, deps);
6942 },
6943 useImperativeHandle: function (ref, create, deps) {
6944 currentHookNameInDev = 'useImperativeHandle';
6945 warnInvalidHookAccess();
6946 updateHookTypesDev();
6947 return updateImperativeHandle(ref, create, deps);
6948 },
6949 useLayoutEffect: function (create, deps) {
6950 currentHookNameInDev = 'useLayoutEffect';
6951 warnInvalidHookAccess();
6952 updateHookTypesDev();
6953 return updateLayoutEffect(create, deps);
6954 },
6955 useMemo: function (create, deps) {
6956 currentHookNameInDev = 'useMemo';
6957 warnInvalidHookAccess();
6958 updateHookTypesDev();
6959 var prevDispatcher = ReactCurrentDispatcher.current;
6960 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6961
6962 try {
6963 return updateMemo(create, deps);
6964 } finally {
6965 ReactCurrentDispatcher.current = prevDispatcher;
6966 }
6967 },
6968 useReducer: function (reducer, initialArg, init) {
6969 currentHookNameInDev = 'useReducer';
6970 warnInvalidHookAccess();
6971 updateHookTypesDev();
6972 var prevDispatcher = ReactCurrentDispatcher.current;
6973 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6974
6975 try {
6976 return updateReducer(reducer, initialArg, init);
6977 } finally {
6978 ReactCurrentDispatcher.current = prevDispatcher;
6979 }
6980 },
6981 useRef: function (initialValue) {
6982 currentHookNameInDev = 'useRef';
6983 warnInvalidHookAccess();
6984 updateHookTypesDev();
6985 return updateRef();
6986 },
6987 useState: function (initialState) {
6988 currentHookNameInDev = 'useState';
6989 warnInvalidHookAccess();
6990 updateHookTypesDev();
6991 var prevDispatcher = ReactCurrentDispatcher.current;
6992 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6993
6994 try {
6995 return updateState(initialState);
6996 } finally {
6997 ReactCurrentDispatcher.current = prevDispatcher;
6998 }
6999 },
7000 useDebugValue: function (value, formatterFn) {
7001 currentHookNameInDev = 'useDebugValue';
7002 warnInvalidHookAccess();
7003 updateHookTypesDev();
7004 return updateDebugValue();
7005 },
7006 useResponder: function (responder, props) {
7007 currentHookNameInDev = 'useResponder';
7008 warnInvalidHookAccess();
7009 updateHookTypesDev();
7010 return createDeprecatedResponderListener(responder, props);
7011 },
7012 useDeferredValue: function (value, config) {
7013 currentHookNameInDev = 'useDeferredValue';
7014 warnInvalidHookAccess();
7015 updateHookTypesDev();
7016 return updateDeferredValue(value, config);
7017 },
7018 useTransition: function (config) {
7019 currentHookNameInDev = 'useTransition';
7020 warnInvalidHookAccess();
7021 updateHookTypesDev();
7022 return updateTransition(config);
7023 }
7024 };
7025 InvalidNestedHooksDispatcherOnRerenderInDEV = {
7026 readContext: function (context, observedBits) {
7027 warnInvalidContextAccess();
7028 return readContext(context, observedBits);
7029 },
7030 useCallback: function (callback, deps) {
7031 currentHookNameInDev = 'useCallback';
7032 warnInvalidHookAccess();
7033 updateHookTypesDev();
7034 return updateCallback(callback, deps);
7035 },
7036 useContext: function (context, observedBits) {
7037 currentHookNameInDev = 'useContext';
7038 warnInvalidHookAccess();
7039 updateHookTypesDev();
7040 return readContext(context, observedBits);
7041 },
7042 useEffect: function (create, deps) {
7043 currentHookNameInDev = 'useEffect';
7044 warnInvalidHookAccess();
7045 updateHookTypesDev();
7046 return updateEffect(create, deps);
7047 },
7048 useImperativeHandle: function (ref, create, deps) {
7049 currentHookNameInDev = 'useImperativeHandle';
7050 warnInvalidHookAccess();
7051 updateHookTypesDev();
7052 return updateImperativeHandle(ref, create, deps);
7053 },
7054 useLayoutEffect: function (create, deps) {
7055 currentHookNameInDev = 'useLayoutEffect';
7056 warnInvalidHookAccess();
7057 updateHookTypesDev();
7058 return updateLayoutEffect(create, deps);
7059 },
7060 useMemo: function (create, deps) {
7061 currentHookNameInDev = 'useMemo';
7062 warnInvalidHookAccess();
7063 updateHookTypesDev();
7064 var prevDispatcher = ReactCurrentDispatcher.current;
7065 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7066
7067 try {
7068 return updateMemo(create, deps);
7069 } finally {
7070 ReactCurrentDispatcher.current = prevDispatcher;
7071 }
7072 },
7073 useReducer: function (reducer, initialArg, init) {
7074 currentHookNameInDev = 'useReducer';
7075 warnInvalidHookAccess();
7076 updateHookTypesDev();
7077 var prevDispatcher = ReactCurrentDispatcher.current;
7078 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7079
7080 try {
7081 return rerenderReducer(reducer, initialArg, init);
7082 } finally {
7083 ReactCurrentDispatcher.current = prevDispatcher;
7084 }
7085 },
7086 useRef: function (initialValue) {
7087 currentHookNameInDev = 'useRef';
7088 warnInvalidHookAccess();
7089 updateHookTypesDev();
7090 return updateRef();
7091 },
7092 useState: function (initialState) {
7093 currentHookNameInDev = 'useState';
7094 warnInvalidHookAccess();
7095 updateHookTypesDev();
7096 var prevDispatcher = ReactCurrentDispatcher.current;
7097 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7098
7099 try {
7100 return rerenderState(initialState);
7101 } finally {
7102 ReactCurrentDispatcher.current = prevDispatcher;
7103 }
7104 },
7105 useDebugValue: function (value, formatterFn) {
7106 currentHookNameInDev = 'useDebugValue';
7107 warnInvalidHookAccess();
7108 updateHookTypesDev();
7109 return updateDebugValue();
7110 },
7111 useResponder: function (responder, props) {
7112 currentHookNameInDev = 'useResponder';
7113 warnInvalidHookAccess();
7114 updateHookTypesDev();
7115 return createDeprecatedResponderListener(responder, props);
7116 },
7117 useDeferredValue: function (value, config) {
7118 currentHookNameInDev = 'useDeferredValue';
7119 warnInvalidHookAccess();
7120 updateHookTypesDev();
7121 return rerenderDeferredValue(value, config);
7122 },
7123 useTransition: function (config) {
7124 currentHookNameInDev = 'useTransition';
7125 warnInvalidHookAccess();
7126 updateHookTypesDev();
7127 return rerenderTransition(config);
7128 }
7129 };
7130}
7131
7132var now$1 = Scheduler$1.unstable_now;
7133var commitTime = 0;
7134var profilerStartTime = -1;
7135
7136function getCommitTime() {
7137 return commitTime;
7138}
7139
7140function recordCommitTime() {
7141
7142 commitTime = now$1();
7143}
7144
7145function startProfilerTimer(fiber) {
7146
7147 profilerStartTime = now$1();
7148
7149 if (fiber.actualStartTime < 0) {
7150 fiber.actualStartTime = now$1();
7151 }
7152}
7153
7154function stopProfilerTimerIfRunning(fiber) {
7155
7156 profilerStartTime = -1;
7157}
7158
7159function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
7160
7161 if (profilerStartTime >= 0) {
7162 var elapsedTime = now$1() - profilerStartTime;
7163 fiber.actualDuration += elapsedTime;
7164
7165 if (overrideBaseTime) {
7166 fiber.selfBaseDuration = elapsedTime;
7167 }
7168
7169 profilerStartTime = -1;
7170 }
7171}
7172
7173function enterHydrationState(fiber) {
7174 {
7175 return false;
7176 }
7177}
7178
7179function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
7180 {
7181 {
7182 {
7183 throw Error( "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." );
7184 }
7185 }
7186 }
7187}
7188
7189function prepareToHydrateHostTextInstance(fiber) {
7190 {
7191 {
7192 {
7193 throw Error( "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." );
7194 }
7195 }
7196 }
7197 var shouldUpdate = hydrateTextInstance();
7198}
7199
7200function popHydrationState(fiber) {
7201 {
7202 return false;
7203 }
7204}
7205
7206var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
7207var didReceiveUpdate = false;
7208var didWarnAboutBadClass;
7209var didWarnAboutModulePatternComponent;
7210var didWarnAboutContextTypeOnFunctionComponent;
7211var didWarnAboutGetDerivedStateOnFunctionComponent;
7212var didWarnAboutFunctionRefs;
7213var didWarnAboutReassigningProps;
7214var didWarnAboutRevealOrder;
7215var didWarnAboutTailOptions;
7216
7217{
7218 didWarnAboutBadClass = {};
7219 didWarnAboutModulePatternComponent = {};
7220 didWarnAboutContextTypeOnFunctionComponent = {};
7221 didWarnAboutGetDerivedStateOnFunctionComponent = {};
7222 didWarnAboutFunctionRefs = {};
7223 didWarnAboutReassigningProps = false;
7224 didWarnAboutRevealOrder = {};
7225 didWarnAboutTailOptions = {};
7226}
7227
7228function reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime) {
7229 if (current === null) {
7230 // If this is a fresh new component that hasn't been rendered yet, we
7231 // won't update its child set by applying minimal side-effects. Instead,
7232 // we will add them all to the child before it gets rendered. That means
7233 // we can optimize this reconciliation pass by not tracking side-effects.
7234 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7235 } else {
7236 // If the current child is the same as the work in progress, it means that
7237 // we haven't yet started any work on these children. Therefore, we use
7238 // the clone algorithm to create a copy of all the current children.
7239 // If we had any progressed work already, that is invalid at this point so
7240 // let's throw it out.
7241 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
7242 }
7243}
7244
7245function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime) {
7246 // This function is fork of reconcileChildren. It's used in cases where we
7247 // want to reconcile without matching against the existing set. This has the
7248 // effect of all current children being unmounted; even if the type and key
7249 // are the same, the old child is unmounted and a new child is created.
7250 //
7251 // To do this, we're going to go through the reconcile algorithm twice. In
7252 // the first pass, we schedule a deletion for all the current children by
7253 // passing null.
7254 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderExpirationTime); // In the second pass, we mount the new children. The trick here is that we
7255 // pass null in place of where we usually pass the current child set. This has
7256 // the effect of remounting all children regardless of whether their
7257 // identities match.
7258
7259 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7260}
7261
7262function updateForwardRef(current, workInProgress, Component, nextProps, renderExpirationTime) {
7263 // TODO: current can be non-null here even if the component
7264 // hasn't yet mounted. This happens after the first render suspends.
7265 // We'll need to figure out if this is fine or can cause issues.
7266 {
7267 if (workInProgress.type !== workInProgress.elementType) {
7268 // Lazy component props can't be validated in createElement
7269 // because they're only guaranteed to be resolved here.
7270 var innerPropTypes = Component.propTypes;
7271
7272 if (innerPropTypes) {
7273 checkPropTypes(innerPropTypes, nextProps, // Resolved props
7274 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7275 }
7276 }
7277 }
7278
7279 var render = Component.render;
7280 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent
7281
7282 var nextChildren;
7283 prepareToReadContext(workInProgress, renderExpirationTime);
7284
7285 {
7286 ReactCurrentOwner$1.current = workInProgress;
7287 setIsRendering(true);
7288 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
7289
7290 setIsRendering(false);
7291 }
7292
7293 if (current !== null && !didReceiveUpdate) {
7294 bailoutHooks(current, workInProgress, renderExpirationTime);
7295 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7296 } // React DevTools reads this flag.
7297
7298
7299 workInProgress.effectTag |= PerformedWork;
7300 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7301 return workInProgress.child;
7302}
7303
7304function updateMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
7305 if (current === null) {
7306 var type = Component.type;
7307
7308 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.
7309 Component.defaultProps === undefined) {
7310 var resolvedType = type;
7311
7312 {
7313 resolvedType = resolveFunctionForHotReloading(type);
7314 } // If this is a plain function component without default props,
7315 // and with only the default shallow comparison, we upgrade it
7316 // to a SimpleMemoComponent to allow fast path updates.
7317
7318
7319 workInProgress.tag = SimpleMemoComponent;
7320 workInProgress.type = resolvedType;
7321
7322 {
7323 validateFunctionComponentInDev(workInProgress, type);
7324 }
7325
7326 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, updateExpirationTime, renderExpirationTime);
7327 }
7328
7329 {
7330 var innerPropTypes = type.propTypes;
7331
7332 if (innerPropTypes) {
7333 // Inner memo component props aren't currently validated in createElement.
7334 // We could move it there, but we'd still need this for lazy code path.
7335 checkPropTypes(innerPropTypes, nextProps, // Resolved props
7336 'prop', getComponentName(type), getCurrentFiberStackInDev);
7337 }
7338 }
7339
7340 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
7341 child.ref = workInProgress.ref;
7342 child.return = workInProgress;
7343 workInProgress.child = child;
7344 return child;
7345 }
7346
7347 {
7348 var _type = Component.type;
7349 var _innerPropTypes = _type.propTypes;
7350
7351 if (_innerPropTypes) {
7352 // Inner memo component props aren't currently validated in createElement.
7353 // We could move it there, but we'd still need this for lazy code path.
7354 checkPropTypes(_innerPropTypes, nextProps, // Resolved props
7355 'prop', getComponentName(_type), getCurrentFiberStackInDev);
7356 }
7357 }
7358
7359 var currentChild = current.child; // This is always exactly one child
7360
7361 if (updateExpirationTime < renderExpirationTime) {
7362 // This will be the props with resolved defaultProps,
7363 // unlike current.memoizedProps which will be the unresolved ones.
7364 var prevProps = currentChild.memoizedProps; // Default to shallow comparison
7365
7366 var compare = Component.compare;
7367 compare = compare !== null ? compare : shallowEqual;
7368
7369 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
7370 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7371 }
7372 } // React DevTools reads this flag.
7373
7374
7375 workInProgress.effectTag |= PerformedWork;
7376 var newChild = createWorkInProgress(currentChild, nextProps);
7377 newChild.ref = workInProgress.ref;
7378 newChild.return = workInProgress;
7379 workInProgress.child = newChild;
7380 return newChild;
7381}
7382
7383function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
7384 // TODO: current can be non-null here even if the component
7385 // hasn't yet mounted. This happens when the inner render suspends.
7386 // We'll need to figure out if this is fine or can cause issues.
7387 {
7388 if (workInProgress.type !== workInProgress.elementType) {
7389 // Lazy component props can't be validated in createElement
7390 // because they're only guaranteed to be resolved here.
7391 var outerMemoType = workInProgress.elementType;
7392
7393 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
7394 // We warn when you define propTypes on lazy()
7395 // so let's just skip over it to find memo() outer wrapper.
7396 // Inner props for memo are validated later.
7397 outerMemoType = refineResolvedLazyComponent(outerMemoType);
7398 }
7399
7400 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
7401
7402 if (outerPropTypes) {
7403 checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
7404 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
7405 } // Inner propTypes will be validated in the function component path.
7406
7407 }
7408 }
7409
7410 if (current !== null) {
7411 var prevProps = current.memoizedProps;
7412
7413 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload.
7414 workInProgress.type === current.type )) {
7415 didReceiveUpdate = false;
7416
7417 if (updateExpirationTime < renderExpirationTime) {
7418 // The pending update priority was cleared at the beginning of
7419 // beginWork. We're about to bail out, but there might be additional
7420 // updates at a lower priority. Usually, the priority level of the
7421 // remaining updates is accumlated during the evaluation of the
7422 // component (i.e. when processing the update queue). But since since
7423 // we're bailing out early *without* evaluating the component, we need
7424 // to account for it here, too. Reset to the value of the current fiber.
7425 // NOTE: This only applies to SimpleMemoComponent, not MemoComponent,
7426 // because a MemoComponent fiber does not have hooks or an update queue;
7427 // rather, it wraps around an inner component, which may or may not
7428 // contains hooks.
7429 // TODO: Move the reset at in beginWork out of the common path so that
7430 // this is no longer necessary.
7431 workInProgress.expirationTime = current.expirationTime;
7432 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7433 }
7434 }
7435 }
7436
7437 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime);
7438}
7439
7440function updateFragment(current, workInProgress, renderExpirationTime) {
7441 var nextChildren = workInProgress.pendingProps;
7442 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7443 return workInProgress.child;
7444}
7445
7446function updateMode(current, workInProgress, renderExpirationTime) {
7447 var nextChildren = workInProgress.pendingProps.children;
7448 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7449 return workInProgress.child;
7450}
7451
7452function updateProfiler(current, workInProgress, renderExpirationTime) {
7453 {
7454 workInProgress.effectTag |= Update;
7455 }
7456
7457 var nextProps = workInProgress.pendingProps;
7458 var nextChildren = nextProps.children;
7459 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7460 return workInProgress.child;
7461}
7462
7463function markRef(current, workInProgress) {
7464 var ref = workInProgress.ref;
7465
7466 if (current === null && ref !== null || current !== null && current.ref !== ref) {
7467 // Schedule a Ref effect
7468 workInProgress.effectTag |= Ref;
7469 }
7470}
7471
7472function updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
7473 {
7474 if (workInProgress.type !== workInProgress.elementType) {
7475 // Lazy component props can't be validated in createElement
7476 // because they're only guaranteed to be resolved here.
7477 var innerPropTypes = Component.propTypes;
7478
7479 if (innerPropTypes) {
7480 checkPropTypes(innerPropTypes, nextProps, // Resolved props
7481 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7482 }
7483 }
7484 }
7485
7486 var context;
7487
7488 {
7489 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
7490 context = getMaskedContext(workInProgress, unmaskedContext);
7491 }
7492
7493 var nextChildren;
7494 prepareToReadContext(workInProgress, renderExpirationTime);
7495
7496 {
7497 ReactCurrentOwner$1.current = workInProgress;
7498 setIsRendering(true);
7499 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
7500
7501 setIsRendering(false);
7502 }
7503
7504 if (current !== null && !didReceiveUpdate) {
7505 bailoutHooks(current, workInProgress, renderExpirationTime);
7506 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7507 } // React DevTools reads this flag.
7508
7509
7510 workInProgress.effectTag |= PerformedWork;
7511 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7512 return workInProgress.child;
7513}
7514
7515function updateClassComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
7516 {
7517 if (workInProgress.type !== workInProgress.elementType) {
7518 // Lazy component props can't be validated in createElement
7519 // because they're only guaranteed to be resolved here.
7520 var innerPropTypes = Component.propTypes;
7521
7522 if (innerPropTypes) {
7523 checkPropTypes(innerPropTypes, nextProps, // Resolved props
7524 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7525 }
7526 }
7527 } // Push context providers early to prevent context stack mismatches.
7528 // During mounting we don't know the child context yet as the instance doesn't exist.
7529 // We will invalidate the child context in finishClassComponent() right after rendering.
7530
7531
7532 var hasContext;
7533
7534 if (isContextProvider(Component)) {
7535 hasContext = true;
7536 pushContextProvider(workInProgress);
7537 } else {
7538 hasContext = false;
7539 }
7540
7541 prepareToReadContext(workInProgress, renderExpirationTime);
7542 var instance = workInProgress.stateNode;
7543 var shouldUpdate;
7544
7545 if (instance === null) {
7546 if (current !== null) {
7547 // A class component without an instance only mounts if it suspended
7548 // inside a non-concurrent tree, in an inconsistent state. We want to
7549 // treat it like a new mount, even though an empty version of it already
7550 // committed. Disconnect the alternate pointers.
7551 current.alternate = null;
7552 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
7553
7554 workInProgress.effectTag |= Placement;
7555 } // In the initial pass we might need to construct the instance.
7556
7557
7558 constructClassInstance(workInProgress, Component, nextProps);
7559 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7560 shouldUpdate = true;
7561 } else if (current === null) {
7562 // In a resume, we'll already have an instance we can reuse.
7563 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7564 } else {
7565 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderExpirationTime);
7566 }
7567
7568 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
7569
7570 {
7571 var inst = workInProgress.stateNode;
7572
7573 if (inst.props !== nextProps) {
7574 if (!didWarnAboutReassigningProps) {
7575 error('It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentName(workInProgress.type) || 'a component');
7576 }
7577
7578 didWarnAboutReassigningProps = true;
7579 }
7580 }
7581
7582 return nextUnitOfWork;
7583}
7584
7585function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
7586 // Refs should update even if shouldComponentUpdate returns false
7587 markRef(current, workInProgress);
7588 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
7589
7590 if (!shouldUpdate && !didCaptureError) {
7591 // Context providers should defer to sCU for rendering
7592 if (hasContext) {
7593 invalidateContextProvider(workInProgress, Component, false);
7594 }
7595
7596 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7597 }
7598
7599 var instance = workInProgress.stateNode; // Rerender
7600
7601 ReactCurrentOwner$1.current = workInProgress;
7602 var nextChildren;
7603
7604 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
7605 // If we captured an error, but getDerivedStateFromError is not defined,
7606 // unmount all the children. componentDidCatch will schedule an update to
7607 // re-render a fallback. This is temporary until we migrate everyone to
7608 // the new API.
7609 // TODO: Warn in a future release.
7610 nextChildren = null;
7611
7612 {
7613 stopProfilerTimerIfRunning();
7614 }
7615 } else {
7616 {
7617 setIsRendering(true);
7618 nextChildren = instance.render();
7619
7620 setIsRendering(false);
7621 }
7622 } // React DevTools reads this flag.
7623
7624
7625 workInProgress.effectTag |= PerformedWork;
7626
7627 if (current !== null && didCaptureError) {
7628 // If we're recovering from an error, reconcile without reusing any of
7629 // the existing children. Conceptually, the normal children and the children
7630 // that are shown on error are two different sets, so we shouldn't reuse
7631 // normal children even if their identities match.
7632 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime);
7633 } else {
7634 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7635 } // Memoize state using the values we just used to render.
7636 // TODO: Restructure so we never read values from the instance.
7637
7638
7639 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
7640
7641 if (hasContext) {
7642 invalidateContextProvider(workInProgress, Component, true);
7643 }
7644
7645 return workInProgress.child;
7646}
7647
7648function pushHostRootContext(workInProgress) {
7649 var root = workInProgress.stateNode;
7650
7651 if (root.pendingContext) {
7652 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
7653 } else if (root.context) {
7654 // Should always be set
7655 pushTopLevelContextObject(workInProgress, root.context, false);
7656 }
7657
7658 pushHostContainer(workInProgress, root.containerInfo);
7659}
7660
7661function updateHostRoot(current, workInProgress, renderExpirationTime) {
7662 pushHostRootContext(workInProgress);
7663 var updateQueue = workInProgress.updateQueue;
7664
7665 if (!(current !== null && updateQueue !== null)) {
7666 {
7667 throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." );
7668 }
7669 }
7670
7671 var nextProps = workInProgress.pendingProps;
7672 var prevState = workInProgress.memoizedState;
7673 var prevChildren = prevState !== null ? prevState.element : null;
7674 cloneUpdateQueue(current, workInProgress);
7675 processUpdateQueue(workInProgress, nextProps, null, renderExpirationTime);
7676 var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property
7677 // being called "element".
7678
7679 var nextChildren = nextState.element;
7680
7681 if (nextChildren === prevChildren) {
7682 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7683 }
7684
7685 var root = workInProgress.stateNode;
7686
7687 if (root.hydrate && enterHydrationState()) {
7688 // If we don't have any current children this might be the first pass.
7689 // We always try to hydrate. If this isn't a hydration pass there won't
7690 // be any children to hydrate which is effectively the same thing as
7691 // not hydrating.
7692 var child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7693 workInProgress.child = child;
7694 var node = child;
7695
7696 while (node) {
7697 // Mark each child as hydrating. This is a fast path to know whether this
7698 // tree is part of a hydrating tree. This is used to determine if a child
7699 // node has fully mounted yet, and for scheduling event replaying.
7700 // Conceptually this is similar to Placement in that a new subtree is
7701 // inserted into the React tree here. It just happens to not need DOM
7702 // mutations because it already exists.
7703 node.effectTag = node.effectTag & ~Placement | Hydrating;
7704 node = node.sibling;
7705 }
7706 } else {
7707 // Otherwise reset hydration state in case we aborted and resumed another
7708 // root.
7709 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7710 }
7711
7712 return workInProgress.child;
7713}
7714
7715function updateHostComponent(current, workInProgress, renderExpirationTime) {
7716 pushHostContext(workInProgress);
7717
7718 var type = workInProgress.type;
7719 var nextProps = workInProgress.pendingProps;
7720 var prevProps = current !== null ? current.memoizedProps : null;
7721 var nextChildren = nextProps.children;
7722
7723 if (prevProps !== null && shouldSetTextContent()) {
7724 // If we're switching from a direct text child to a normal child, or to
7725 // empty, we need to schedule the text content to be reset.
7726 workInProgress.effectTag |= ContentReset;
7727 }
7728
7729 markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden.
7730
7731 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree()) {
7732 {
7733 markSpawnedWork(Never);
7734 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
7735
7736
7737 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
7738 return null;
7739 }
7740
7741 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7742 return workInProgress.child;
7743}
7744
7745function updateHostText(current, workInProgress) {
7746 // immediately after.
7747
7748
7749 return null;
7750}
7751
7752function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
7753 if (_current !== null) {
7754 // A lazy component only mounts if it suspended inside a non-
7755 // concurrent tree, in an inconsistent state. We want to treat it like
7756 // a new mount, even though an empty version of it already committed.
7757 // Disconnect the alternate pointers.
7758 _current.alternate = null;
7759 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
7760
7761 workInProgress.effectTag |= Placement;
7762 }
7763
7764 var props = workInProgress.pendingProps; // We can't start a User Timing measurement with correct label yet.
7765 // Cancel and resume right after we know the tag.
7766
7767 cancelWorkTimer(workInProgress);
7768 var Component = readLazyComponentType(elementType); // Store the unwrapped component in the type.
7769
7770 workInProgress.type = Component;
7771 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
7772 startWorkTimer(workInProgress);
7773 var resolvedProps = resolveDefaultProps(Component, props);
7774 var child;
7775
7776 switch (resolvedTag) {
7777 case FunctionComponent:
7778 {
7779 {
7780 validateFunctionComponentInDev(workInProgress, Component);
7781 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
7782 }
7783
7784 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7785 return child;
7786 }
7787
7788 case ClassComponent:
7789 {
7790 {
7791 workInProgress.type = Component = resolveClassForHotReloading(Component);
7792 }
7793
7794 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7795 return child;
7796 }
7797
7798 case ForwardRef:
7799 {
7800 {
7801 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
7802 }
7803
7804 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7805 return child;
7806 }
7807
7808 case MemoComponent:
7809 {
7810 {
7811 if (workInProgress.type !== workInProgress.elementType) {
7812 var outerPropTypes = Component.propTypes;
7813
7814 if (outerPropTypes) {
7815 checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only
7816 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7817 }
7818 }
7819 }
7820
7821 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
7822 updateExpirationTime, renderExpirationTime);
7823 return child;
7824 }
7825 }
7826
7827 var hint = '';
7828
7829 {
7830 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
7831 hint = ' Did you wrap a component in React.lazy() more than once?';
7832 }
7833 } // This message intentionally doesn't mention ForwardRef or MemoComponent
7834 // because the fact that it's a separate type of work is an
7835 // implementation detail.
7836
7837
7838 {
7839 {
7840 throw Error( "Element type is invalid. Received a promise that resolves to: " + Component + ". Lazy element type must resolve to a class or function." + hint );
7841 }
7842 }
7843}
7844
7845function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
7846 if (_current !== null) {
7847 // An incomplete component only mounts if it suspended inside a non-
7848 // concurrent tree, in an inconsistent state. We want to treat it like
7849 // a new mount, even though an empty version of it already committed.
7850 // Disconnect the alternate pointers.
7851 _current.alternate = null;
7852 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
7853
7854 workInProgress.effectTag |= Placement;
7855 } // Promote the fiber to a class and try rendering again.
7856
7857
7858 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`
7859 // Push context providers early to prevent context stack mismatches.
7860 // During mounting we don't know the child context yet as the instance doesn't exist.
7861 // We will invalidate the child context in finishClassComponent() right after rendering.
7862
7863 var hasContext;
7864
7865 if (isContextProvider(Component)) {
7866 hasContext = true;
7867 pushContextProvider(workInProgress);
7868 } else {
7869 hasContext = false;
7870 }
7871
7872 prepareToReadContext(workInProgress, renderExpirationTime);
7873 constructClassInstance(workInProgress, Component, nextProps);
7874 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7875 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
7876}
7877
7878function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
7879 if (_current !== null) {
7880 // An indeterminate component only mounts if it suspended inside a non-
7881 // concurrent tree, in an inconsistent state. We want to treat it like
7882 // a new mount, even though an empty version of it already committed.
7883 // Disconnect the alternate pointers.
7884 _current.alternate = null;
7885 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
7886
7887 workInProgress.effectTag |= Placement;
7888 }
7889
7890 var props = workInProgress.pendingProps;
7891 var context;
7892
7893 {
7894 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
7895 context = getMaskedContext(workInProgress, unmaskedContext);
7896 }
7897
7898 prepareToReadContext(workInProgress, renderExpirationTime);
7899 var value;
7900
7901 {
7902 if (Component.prototype && typeof Component.prototype.render === 'function') {
7903 var componentName = getComponentName(Component) || 'Unknown';
7904
7905 if (!didWarnAboutBadClass[componentName]) {
7906 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);
7907
7908 didWarnAboutBadClass[componentName] = true;
7909 }
7910 }
7911
7912 if (workInProgress.mode & StrictMode) {
7913 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
7914 }
7915
7916 setIsRendering(true);
7917 ReactCurrentOwner$1.current = workInProgress;
7918 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
7919 setIsRendering(false);
7920 } // React DevTools reads this flag.
7921
7922
7923 workInProgress.effectTag |= PerformedWork;
7924
7925 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
7926 {
7927 var _componentName = getComponentName(Component) || 'Unknown';
7928
7929 if (!didWarnAboutModulePatternComponent[_componentName]) {
7930 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);
7931
7932 didWarnAboutModulePatternComponent[_componentName] = true;
7933 }
7934 } // Proceed under the assumption that this is a class instance
7935
7936
7937 workInProgress.tag = ClassComponent; // Throw out any hooks that were used.
7938
7939 workInProgress.memoizedState = null;
7940 workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches.
7941 // During mounting we don't know the child context yet as the instance doesn't exist.
7942 // We will invalidate the child context in finishClassComponent() right after rendering.
7943
7944 var hasContext = false;
7945
7946 if (isContextProvider(Component)) {
7947 hasContext = true;
7948 pushContextProvider(workInProgress);
7949 } else {
7950 hasContext = false;
7951 }
7952
7953 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
7954 initializeUpdateQueue(workInProgress);
7955 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
7956
7957 if (typeof getDerivedStateFromProps === 'function') {
7958 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
7959 }
7960
7961 adoptClassInstance(workInProgress, value);
7962 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
7963 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
7964 } else {
7965 // Proceed under the assumption that this is a function component
7966 workInProgress.tag = FunctionComponent;
7967
7968 reconcileChildren(null, workInProgress, value, renderExpirationTime);
7969
7970 {
7971 validateFunctionComponentInDev(workInProgress, Component);
7972 }
7973
7974 return workInProgress.child;
7975 }
7976}
7977
7978function validateFunctionComponentInDev(workInProgress, Component) {
7979 {
7980 if (Component) {
7981 if (Component.childContextTypes) {
7982 error('%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component');
7983 }
7984 }
7985
7986 if (workInProgress.ref !== null) {
7987 var info = '';
7988 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
7989
7990 if (ownerName) {
7991 info += '\n\nCheck the render method of `' + ownerName + '`.';
7992 }
7993
7994 var warningKey = ownerName || workInProgress._debugID || '';
7995 var debugSource = workInProgress._debugSource;
7996
7997 if (debugSource) {
7998 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
7999 }
8000
8001 if (!didWarnAboutFunctionRefs[warningKey]) {
8002 didWarnAboutFunctionRefs[warningKey] = true;
8003
8004 error('Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
8005 }
8006 }
8007
8008 if (typeof Component.getDerivedStateFromProps === 'function') {
8009 var _componentName2 = getComponentName(Component) || 'Unknown';
8010
8011 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) {
8012 error('%s: Function components do not support getDerivedStateFromProps.', _componentName2);
8013
8014 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true;
8015 }
8016 }
8017
8018 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
8019 var _componentName3 = getComponentName(Component) || 'Unknown';
8020
8021 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) {
8022 error('%s: Function components do not support contextType.', _componentName3);
8023
8024 didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true;
8025 }
8026 }
8027 }
8028}
8029
8030var SUSPENDED_MARKER = {
8031 dehydrated: null,
8032 retryTime: NoWork
8033};
8034
8035function shouldRemainOnFallback(suspenseContext, current, workInProgress) {
8036 // If the context is telling us that we should show a fallback, and we're not
8037 // already showing content, then we should show the fallback instead.
8038 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && (current === null || current.memoizedState !== null);
8039}
8040
8041function updateSuspenseComponent(current, workInProgress, renderExpirationTime) {
8042 var mode = workInProgress.mode;
8043 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
8044
8045 {
8046 if (shouldSuspend(workInProgress)) {
8047 workInProgress.effectTag |= DidCapture;
8048 }
8049 }
8050
8051 var suspenseContext = suspenseStackCursor.current;
8052 var nextDidTimeout = false;
8053 var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect;
8054
8055 if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) {
8056 // Something in this boundary's subtree already suspended. Switch to
8057 // rendering the fallback children.
8058 nextDidTimeout = true;
8059 workInProgress.effectTag &= ~DidCapture;
8060 } else {
8061 // Attempting the main content
8062 if (current === null || current.memoizedState !== null) {
8063 // This is a new mount or this boundary is already showing a fallback state.
8064 // Mark this subtree context as having at least one invisible parent that could
8065 // handle the fallback state.
8066 // Boundaries without fallbacks or should be avoided are not considered since
8067 // they cannot handle preferred fallback states.
8068 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {
8069 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
8070 }
8071 }
8072 }
8073
8074 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
8075 pushSuspenseContext(workInProgress, suspenseContext); // This next part is a bit confusing. If the children timeout, we switch to
8076 // showing the fallback children in place of the "primary" children.
8077 // However, we don't want to delete the primary children because then their
8078 // state will be lost (both the React state and the host state, e.g.
8079 // uncontrolled form inputs). Instead we keep them mounted and hide them.
8080 // Both the fallback children AND the primary children are rendered at the
8081 // same time. Once the primary children are un-suspended, we can delete
8082 // the fallback children — don't need to preserve their state.
8083 //
8084 // The two sets of children are siblings in the host environment, but
8085 // semantically, for purposes of reconciliation, they are two separate sets.
8086 // So we store them using two fragment fibers.
8087 //
8088 // However, we want to avoid allocating extra fibers for every placeholder.
8089 // They're only necessary when the children time out, because that's the
8090 // only time when both sets are mounted.
8091 //
8092 // So, the extra fragment fibers are only used if the children time out.
8093 // Otherwise, we render the primary children directly. This requires some
8094 // custom reconciliation logic to preserve the state of the primary
8095 // children. It's essentially a very basic form of re-parenting.
8096
8097 if (current === null) {
8098 // If we're currently hydrating, try to hydrate this boundary.
8099 // But only if this has a fallback.
8100 if (nextProps.fallback !== undefined) ; // This is the initial mount. This branch is pretty simple because there's
8101 // no previous state that needs to be preserved.
8102
8103
8104 if (nextDidTimeout) {
8105 // Mount separate fragments for primary and fallback children.
8106 var nextFallbackChildren = nextProps.fallback;
8107 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
8108 primaryChildFragment.return = workInProgress;
8109
8110 if ((workInProgress.mode & BlockingMode) === NoMode) {
8111 // Outside of blocking mode, we commit the effects from the
8112 // partially completed, timed-out tree, too.
8113 var progressedState = workInProgress.memoizedState;
8114 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
8115 primaryChildFragment.child = progressedPrimaryChild;
8116 var progressedChild = progressedPrimaryChild;
8117
8118 while (progressedChild !== null) {
8119 progressedChild.return = primaryChildFragment;
8120 progressedChild = progressedChild.sibling;
8121 }
8122 }
8123
8124 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
8125 fallbackChildFragment.return = workInProgress;
8126 primaryChildFragment.sibling = fallbackChildFragment; // Skip the primary children, and continue working on the
8127 // fallback children.
8128
8129 workInProgress.memoizedState = SUSPENDED_MARKER;
8130 workInProgress.child = primaryChildFragment;
8131 return fallbackChildFragment;
8132 } else {
8133 // Mount the primary children without an intermediate fragment fiber.
8134 var nextPrimaryChildren = nextProps.children;
8135 workInProgress.memoizedState = null;
8136 return workInProgress.child = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
8137 }
8138 } else {
8139 // This is an update. This branch is more complicated because we need to
8140 // ensure the state of the primary children is preserved.
8141 var prevState = current.memoizedState;
8142
8143 if (prevState !== null) {
8144 // wrapped in a fragment fiber.
8145
8146
8147 var currentPrimaryChildFragment = current.child;
8148 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
8149
8150 if (nextDidTimeout) {
8151 // Still timed out. Reuse the current primary children by cloning
8152 // its fragment. We're going to skip over these entirely.
8153 var _nextFallbackChildren2 = nextProps.fallback;
8154
8155 var _primaryChildFragment2 = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps);
8156
8157 _primaryChildFragment2.return = workInProgress;
8158
8159 if ((workInProgress.mode & BlockingMode) === NoMode) {
8160 // Outside of blocking mode, we commit the effects from the
8161 // partially completed, timed-out tree, too.
8162 var _progressedState = workInProgress.memoizedState;
8163
8164 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
8165
8166 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
8167 _primaryChildFragment2.child = _progressedPrimaryChild;
8168 var _progressedChild2 = _progressedPrimaryChild;
8169
8170 while (_progressedChild2 !== null) {
8171 _progressedChild2.return = _primaryChildFragment2;
8172 _progressedChild2 = _progressedChild2.sibling;
8173 }
8174 }
8175 } // Because primaryChildFragment is a new fiber that we're inserting as the
8176 // parent of a new tree, we need to set its treeBaseDuration.
8177
8178
8179 if ( workInProgress.mode & ProfileMode) {
8180 // treeBaseDuration is the sum of all the child tree base durations.
8181 var _treeBaseDuration = 0;
8182 var _hiddenChild = _primaryChildFragment2.child;
8183
8184 while (_hiddenChild !== null) {
8185 _treeBaseDuration += _hiddenChild.treeBaseDuration;
8186 _hiddenChild = _hiddenChild.sibling;
8187 }
8188
8189 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
8190 } // Clone the fallback child fragment, too. These we'll continue
8191 // working on.
8192
8193
8194 var _fallbackChildFragment2 = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren2);
8195
8196 _fallbackChildFragment2.return = workInProgress;
8197 _primaryChildFragment2.sibling = _fallbackChildFragment2;
8198 _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
8199 // fallback children.
8200
8201 workInProgress.memoizedState = SUSPENDED_MARKER;
8202 workInProgress.child = _primaryChildFragment2;
8203 return _fallbackChildFragment2;
8204 } else {
8205 // No longer suspended. Switch back to showing the primary children,
8206 // and remove the intermediate fragment fiber.
8207 var _nextPrimaryChildren = nextProps.children;
8208 var currentPrimaryChild = currentPrimaryChildFragment.child;
8209 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime); // If this render doesn't suspend, we need to delete the fallback
8210 // children. Wait until the complete phase, after we've confirmed the
8211 // fallback is no longer needed.
8212 // TODO: Would it be better to store the fallback fragment on
8213 // the stateNode?
8214 // Continue rendering the children, like we normally do.
8215
8216 workInProgress.memoizedState = null;
8217 return workInProgress.child = primaryChild;
8218 }
8219 } else {
8220 // The current tree has not already timed out. That means the primary
8221 // children are not wrapped in a fragment fiber.
8222 var _currentPrimaryChild = current.child;
8223
8224 if (nextDidTimeout) {
8225 // Timed out. Wrap the children in a fragment fiber to keep them
8226 // separate from the fallback children.
8227 var _nextFallbackChildren3 = nextProps.fallback;
8228
8229 var _primaryChildFragment3 = createFiberFromFragment( // It shouldn't matter what the pending props are because we aren't
8230 // going to render this fragment.
8231 null, mode, NoWork, null);
8232
8233 _primaryChildFragment3.return = workInProgress;
8234 _primaryChildFragment3.child = _currentPrimaryChild;
8235
8236 if (_currentPrimaryChild !== null) {
8237 _currentPrimaryChild.return = _primaryChildFragment3;
8238 } // Even though we're creating a new fiber, there are no new children,
8239 // because we're reusing an already mounted tree. So we don't need to
8240 // schedule a placement.
8241 // primaryChildFragment.effectTag |= Placement;
8242
8243
8244 if ((workInProgress.mode & BlockingMode) === NoMode) {
8245 // Outside of blocking mode, we commit the effects from the
8246 // partially completed, timed-out tree, too.
8247 var _progressedState2 = workInProgress.memoizedState;
8248
8249 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
8250
8251 _primaryChildFragment3.child = _progressedPrimaryChild2;
8252 var _progressedChild3 = _progressedPrimaryChild2;
8253
8254 while (_progressedChild3 !== null) {
8255 _progressedChild3.return = _primaryChildFragment3;
8256 _progressedChild3 = _progressedChild3.sibling;
8257 }
8258 } // Because primaryChildFragment is a new fiber that we're inserting as the
8259 // parent of a new tree, we need to set its treeBaseDuration.
8260
8261
8262 if ( workInProgress.mode & ProfileMode) {
8263 // treeBaseDuration is the sum of all the child tree base durations.
8264 var _treeBaseDuration2 = 0;
8265 var _hiddenChild2 = _primaryChildFragment3.child;
8266
8267 while (_hiddenChild2 !== null) {
8268 _treeBaseDuration2 += _hiddenChild2.treeBaseDuration;
8269 _hiddenChild2 = _hiddenChild2.sibling;
8270 }
8271
8272 _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2;
8273 } // Create a fragment from the fallback children, too.
8274
8275
8276 var _fallbackChildFragment3 = createFiberFromFragment(_nextFallbackChildren3, mode, renderExpirationTime, null);
8277
8278 _fallbackChildFragment3.return = workInProgress;
8279 _primaryChildFragment3.sibling = _fallbackChildFragment3;
8280 _fallbackChildFragment3.effectTag |= Placement;
8281 _primaryChildFragment3.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
8282 // fallback children.
8283
8284 workInProgress.memoizedState = SUSPENDED_MARKER;
8285 workInProgress.child = _primaryChildFragment3;
8286 return _fallbackChildFragment3;
8287 } else {
8288 // Still haven't timed out. Continue rendering the children, like we
8289 // normally do.
8290 workInProgress.memoizedState = null;
8291 var _nextPrimaryChildren2 = nextProps.children;
8292 return workInProgress.child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
8293 }
8294 }
8295 }
8296}
8297
8298function scheduleWorkOnFiber(fiber, renderExpirationTime) {
8299 if (fiber.expirationTime < renderExpirationTime) {
8300 fiber.expirationTime = renderExpirationTime;
8301 }
8302
8303 var alternate = fiber.alternate;
8304
8305 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
8306 alternate.expirationTime = renderExpirationTime;
8307 }
8308
8309 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
8310}
8311
8312function propagateSuspenseContextChange(workInProgress, firstChild, renderExpirationTime) {
8313 // Mark any Suspense boundaries with fallbacks as having work to do.
8314 // If they were previously forced into fallbacks, they may now be able
8315 // to unblock.
8316 var node = firstChild;
8317
8318 while (node !== null) {
8319 if (node.tag === SuspenseComponent) {
8320 var state = node.memoizedState;
8321
8322 if (state !== null) {
8323 scheduleWorkOnFiber(node, renderExpirationTime);
8324 }
8325 } else if (node.tag === SuspenseListComponent) {
8326 // If the tail is hidden there might not be an Suspense boundaries
8327 // to schedule work on. In this case we have to schedule it on the
8328 // list itself.
8329 // We don't have to traverse to the children of the list since
8330 // the list will propagate the change when it rerenders.
8331 scheduleWorkOnFiber(node, renderExpirationTime);
8332 } else if (node.child !== null) {
8333 node.child.return = node;
8334 node = node.child;
8335 continue;
8336 }
8337
8338 if (node === workInProgress) {
8339 return;
8340 }
8341
8342 while (node.sibling === null) {
8343 if (node.return === null || node.return === workInProgress) {
8344 return;
8345 }
8346
8347 node = node.return;
8348 }
8349
8350 node.sibling.return = node.return;
8351 node = node.sibling;
8352 }
8353}
8354
8355function findLastContentRow(firstChild) {
8356 // This is going to find the last row among these children that is already
8357 // showing content on the screen, as opposed to being in fallback state or
8358 // new. If a row has multiple Suspense boundaries, any of them being in the
8359 // fallback state, counts as the whole row being in a fallback state.
8360 // Note that the "rows" will be workInProgress, but any nested children
8361 // will still be current since we haven't rendered them yet. The mounted
8362 // order may not be the same as the new order. We use the new order.
8363 var row = firstChild;
8364 var lastContentRow = null;
8365
8366 while (row !== null) {
8367 var currentRow = row.alternate; // New rows can't be content rows.
8368
8369 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
8370 lastContentRow = row;
8371 }
8372
8373 row = row.sibling;
8374 }
8375
8376 return lastContentRow;
8377}
8378
8379function validateRevealOrder(revealOrder) {
8380 {
8381 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
8382 didWarnAboutRevealOrder[revealOrder] = true;
8383
8384 if (typeof revealOrder === 'string') {
8385 switch (revealOrder.toLowerCase()) {
8386 case 'together':
8387 case 'forwards':
8388 case 'backwards':
8389 {
8390 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
8391
8392 break;
8393 }
8394
8395 case 'forward':
8396 case 'backward':
8397 {
8398 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());
8399
8400 break;
8401 }
8402
8403 default:
8404 error('"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
8405
8406 break;
8407 }
8408 } else {
8409 error('%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
8410 }
8411 }
8412 }
8413}
8414
8415function validateTailOptions(tailMode, revealOrder) {
8416 {
8417 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
8418 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
8419 didWarnAboutTailOptions[tailMode] = true;
8420
8421 error('"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
8422 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
8423 didWarnAboutTailOptions[tailMode] = true;
8424
8425 error('<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
8426 }
8427 }
8428 }
8429}
8430
8431function validateSuspenseListNestedChild(childSlot, index) {
8432 {
8433 var isArray = Array.isArray(childSlot);
8434 var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function';
8435
8436 if (isArray || isIterable) {
8437 var type = isArray ? 'array' : 'iterable';
8438
8439 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);
8440
8441 return false;
8442 }
8443 }
8444
8445 return true;
8446}
8447
8448function validateSuspenseListChildren(children, revealOrder) {
8449 {
8450 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
8451 if (Array.isArray(children)) {
8452 for (var i = 0; i < children.length; i++) {
8453 if (!validateSuspenseListNestedChild(children[i], i)) {
8454 return;
8455 }
8456 }
8457 } else {
8458 var iteratorFn = getIteratorFn(children);
8459
8460 if (typeof iteratorFn === 'function') {
8461 var childrenIterator = iteratorFn.call(children);
8462
8463 if (childrenIterator) {
8464 var step = childrenIterator.next();
8465 var _i = 0;
8466
8467 for (; !step.done; step = childrenIterator.next()) {
8468 if (!validateSuspenseListNestedChild(step.value, _i)) {
8469 return;
8470 }
8471
8472 _i++;
8473 }
8474 }
8475 } else {
8476 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);
8477 }
8478 }
8479 }
8480 }
8481}
8482
8483function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode, lastEffectBeforeRendering) {
8484 var renderState = workInProgress.memoizedState;
8485
8486 if (renderState === null) {
8487 workInProgress.memoizedState = {
8488 isBackwards: isBackwards,
8489 rendering: null,
8490 renderingStartTime: 0,
8491 last: lastContentRow,
8492 tail: tail,
8493 tailExpiration: 0,
8494 tailMode: tailMode,
8495 lastEffect: lastEffectBeforeRendering
8496 };
8497 } else {
8498 // We can reuse the existing object from previous renders.
8499 renderState.isBackwards = isBackwards;
8500 renderState.rendering = null;
8501 renderState.renderingStartTime = 0;
8502 renderState.last = lastContentRow;
8503 renderState.tail = tail;
8504 renderState.tailExpiration = 0;
8505 renderState.tailMode = tailMode;
8506 renderState.lastEffect = lastEffectBeforeRendering;
8507 }
8508} // This can end up rendering this component multiple passes.
8509// The first pass splits the children fibers into two sets. A head and tail.
8510// We first render the head. If anything is in fallback state, we do another
8511// pass through beginWork to rerender all children (including the tail) with
8512// the force suspend context. If the first render didn't have anything in
8513// in fallback state. Then we render each row in the tail one-by-one.
8514// That happens in the completeWork phase without going back to beginWork.
8515
8516
8517function updateSuspenseListComponent(current, workInProgress, renderExpirationTime) {
8518 var nextProps = workInProgress.pendingProps;
8519 var revealOrder = nextProps.revealOrder;
8520 var tailMode = nextProps.tail;
8521 var newChildren = nextProps.children;
8522 validateRevealOrder(revealOrder);
8523 validateTailOptions(tailMode, revealOrder);
8524 validateSuspenseListChildren(newChildren, revealOrder);
8525 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
8526 var suspenseContext = suspenseStackCursor.current;
8527 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
8528
8529 if (shouldForceFallback) {
8530 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
8531 workInProgress.effectTag |= DidCapture;
8532 } else {
8533 var didSuspendBefore = current !== null && (current.effectTag & DidCapture) !== NoEffect;
8534
8535 if (didSuspendBefore) {
8536 // If we previously forced a fallback, we need to schedule work
8537 // on any nested boundaries to let them know to try to render
8538 // again. This is the same as context updating.
8539 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderExpirationTime);
8540 }
8541
8542 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
8543 }
8544
8545 pushSuspenseContext(workInProgress, suspenseContext);
8546
8547 if ((workInProgress.mode & BlockingMode) === NoMode) {
8548 // Outside of blocking mode, SuspenseList doesn't work so we just
8549 // use make it a noop by treating it as the default revealOrder.
8550 workInProgress.memoizedState = null;
8551 } else {
8552 switch (revealOrder) {
8553 case 'forwards':
8554 {
8555 var lastContentRow = findLastContentRow(workInProgress.child);
8556 var tail;
8557
8558 if (lastContentRow === null) {
8559 // The whole list is part of the tail.
8560 // TODO: We could fast path by just rendering the tail now.
8561 tail = workInProgress.child;
8562 workInProgress.child = null;
8563 } else {
8564 // Disconnect the tail rows after the content row.
8565 // We're going to render them separately later.
8566 tail = lastContentRow.sibling;
8567 lastContentRow.sibling = null;
8568 }
8569
8570 initSuspenseListRenderState(workInProgress, false, // isBackwards
8571 tail, lastContentRow, tailMode, workInProgress.lastEffect);
8572 break;
8573 }
8574
8575 case 'backwards':
8576 {
8577 // We're going to find the first row that has existing content.
8578 // At the same time we're going to reverse the list of everything
8579 // we pass in the meantime. That's going to be our tail in reverse
8580 // order.
8581 var _tail = null;
8582 var row = workInProgress.child;
8583 workInProgress.child = null;
8584
8585 while (row !== null) {
8586 var currentRow = row.alternate; // New rows can't be content rows.
8587
8588 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
8589 // This is the beginning of the main content.
8590 workInProgress.child = row;
8591 break;
8592 }
8593
8594 var nextRow = row.sibling;
8595 row.sibling = _tail;
8596 _tail = row;
8597 row = nextRow;
8598 } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
8599
8600
8601 initSuspenseListRenderState(workInProgress, true, // isBackwards
8602 _tail, null, // last
8603 tailMode, workInProgress.lastEffect);
8604 break;
8605 }
8606
8607 case 'together':
8608 {
8609 initSuspenseListRenderState(workInProgress, false, // isBackwards
8610 null, // tail
8611 null, // last
8612 undefined, workInProgress.lastEffect);
8613 break;
8614 }
8615
8616 default:
8617 {
8618 // The default reveal order is the same as not having
8619 // a boundary.
8620 workInProgress.memoizedState = null;
8621 }
8622 }
8623 }
8624
8625 return workInProgress.child;
8626}
8627
8628function updatePortalComponent(current, workInProgress, renderExpirationTime) {
8629 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
8630 var nextChildren = workInProgress.pendingProps;
8631
8632 if (current === null) {
8633 // Portals are special because we don't append the children during mount
8634 // but at commit. Therefore we need to track insertions which the normal
8635 // flow doesn't do during mount. This doesn't happen at the root because
8636 // the root always starts with a "current" with a null child.
8637 // TODO: Consider unifying this with how the root works.
8638 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8639 } else {
8640 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8641 }
8642
8643 return workInProgress.child;
8644}
8645
8646function updateContextProvider(current, workInProgress, renderExpirationTime) {
8647 var providerType = workInProgress.type;
8648 var context = providerType._context;
8649 var newProps = workInProgress.pendingProps;
8650 var oldProps = workInProgress.memoizedProps;
8651 var newValue = newProps.value;
8652
8653 {
8654 var providerPropTypes = workInProgress.type.propTypes;
8655
8656 if (providerPropTypes) {
8657 checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
8658 }
8659 }
8660
8661 pushProvider(workInProgress, newValue);
8662
8663 if (oldProps !== null) {
8664 var oldValue = oldProps.value;
8665 var changedBits = calculateChangedBits(context, newValue, oldValue);
8666
8667 if (changedBits === 0) {
8668 // No change. Bailout early if children are the same.
8669 if (oldProps.children === newProps.children && !hasContextChanged()) {
8670 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8671 }
8672 } else {
8673 // The context value changed. Search for matching consumers and schedule
8674 // them to update.
8675 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
8676 }
8677 }
8678
8679 var newChildren = newProps.children;
8680 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
8681 return workInProgress.child;
8682}
8683
8684var hasWarnedAboutUsingContextAsConsumer = false;
8685
8686function updateContextConsumer(current, workInProgress, renderExpirationTime) {
8687 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In
8688 // DEV mode, we create a separate object for Context.Consumer that acts
8689 // like a proxy to Context. This proxy object adds unnecessary code in PROD
8690 // so we use the old behaviour (Context.Consumer references Context) to
8691 // reduce size and overhead. The separate object references context via
8692 // a property called "_context", which also gives us the ability to check
8693 // in DEV mode if this property exists or not and warn if it does not.
8694
8695 {
8696 if (context._context === undefined) {
8697 // This may be because it's a Context (rather than a Consumer).
8698 // Or it may be because it's older React where they're the same thing.
8699 // We only want to warn if we're sure it's a new React.
8700 if (context !== context.Consumer) {
8701 if (!hasWarnedAboutUsingContextAsConsumer) {
8702 hasWarnedAboutUsingContextAsConsumer = true;
8703
8704 error('Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
8705 }
8706 }
8707 } else {
8708 context = context._context;
8709 }
8710 }
8711
8712 var newProps = workInProgress.pendingProps;
8713 var render = newProps.children;
8714
8715 {
8716 if (typeof render !== 'function') {
8717 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.');
8718 }
8719 }
8720
8721 prepareToReadContext(workInProgress, renderExpirationTime);
8722 var newValue = readContext(context, newProps.unstable_observedBits);
8723 var newChildren;
8724
8725 {
8726 ReactCurrentOwner$1.current = workInProgress;
8727 setIsRendering(true);
8728 newChildren = render(newValue);
8729 setIsRendering(false);
8730 } // React DevTools reads this flag.
8731
8732
8733 workInProgress.effectTag |= PerformedWork;
8734 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
8735 return workInProgress.child;
8736}
8737
8738function markWorkInProgressReceivedUpdate() {
8739 didReceiveUpdate = true;
8740}
8741
8742function bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime) {
8743 cancelWorkTimer(workInProgress);
8744
8745 if (current !== null) {
8746 // Reuse previous dependencies
8747 workInProgress.dependencies = current.dependencies;
8748 }
8749
8750 {
8751 // Don't update "base" render times for bailouts.
8752 stopProfilerTimerIfRunning();
8753 }
8754
8755 var updateExpirationTime = workInProgress.expirationTime;
8756
8757 if (updateExpirationTime !== NoWork) {
8758 markUnprocessedUpdateTime(updateExpirationTime);
8759 } // Check if the children have any pending work.
8760
8761
8762 var childExpirationTime = workInProgress.childExpirationTime;
8763
8764 if (childExpirationTime < renderExpirationTime) {
8765 // The children don't have any work either. We can skip them.
8766 // TODO: Once we add back resuming, we should check if the children are
8767 // a work-in-progress set. If so, we need to transfer their effects.
8768 return null;
8769 } else {
8770 // This fiber doesn't have work, but its subtree does. Clone the child
8771 // fibers and continue.
8772 cloneChildFibers(current, workInProgress);
8773 return workInProgress.child;
8774 }
8775}
8776
8777function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
8778 {
8779 var returnFiber = oldWorkInProgress.return;
8780
8781 if (returnFiber === null) {
8782 throw new Error('Cannot swap the root fiber.');
8783 } // Disconnect from the old current.
8784 // It will get deleted.
8785
8786
8787 current.alternate = null;
8788 oldWorkInProgress.alternate = null; // Connect to the new tree.
8789
8790 newWorkInProgress.index = oldWorkInProgress.index;
8791 newWorkInProgress.sibling = oldWorkInProgress.sibling;
8792 newWorkInProgress.return = oldWorkInProgress.return;
8793 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.
8794
8795 if (oldWorkInProgress === returnFiber.child) {
8796 returnFiber.child = newWorkInProgress;
8797 } else {
8798 var prevSibling = returnFiber.child;
8799
8800 if (prevSibling === null) {
8801 throw new Error('Expected parent to have a child.');
8802 }
8803
8804 while (prevSibling.sibling !== oldWorkInProgress) {
8805 prevSibling = prevSibling.sibling;
8806
8807 if (prevSibling === null) {
8808 throw new Error('Expected to find the previous sibling.');
8809 }
8810 }
8811
8812 prevSibling.sibling = newWorkInProgress;
8813 } // Delete the old fiber and place the new one.
8814 // Since the old fiber is disconnected, we have to schedule it manually.
8815
8816
8817 var last = returnFiber.lastEffect;
8818
8819 if (last !== null) {
8820 last.nextEffect = current;
8821 returnFiber.lastEffect = current;
8822 } else {
8823 returnFiber.firstEffect = returnFiber.lastEffect = current;
8824 }
8825
8826 current.nextEffect = null;
8827 current.effectTag = Deletion;
8828 newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber.
8829
8830 return newWorkInProgress;
8831 }
8832}
8833
8834function beginWork(current, workInProgress, renderExpirationTime) {
8835 var updateExpirationTime = workInProgress.expirationTime;
8836
8837 {
8838 if (workInProgress._debugNeedsRemount && current !== null) {
8839 // This will restart the begin phase with a new fiber.
8840 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.expirationTime));
8841 }
8842 }
8843
8844 if (current !== null) {
8845 var oldProps = current.memoizedProps;
8846 var newProps = workInProgress.pendingProps;
8847
8848 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
8849 workInProgress.type !== current.type )) {
8850 // If props or context changed, mark the fiber as having performed work.
8851 // This may be unset if the props are determined to be equal later (memo).
8852 didReceiveUpdate = true;
8853 } else if (updateExpirationTime < renderExpirationTime) {
8854 didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering
8855 // the begin phase. There's still some bookkeeping we that needs to be done
8856 // in this optimized path, mostly pushing stuff onto the stack.
8857
8858 switch (workInProgress.tag) {
8859 case HostRoot:
8860 pushHostRootContext(workInProgress);
8861 break;
8862
8863 case HostComponent:
8864 pushHostContext(workInProgress);
8865
8866 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(workInProgress.type)) {
8867 {
8868 markSpawnedWork(Never);
8869 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
8870
8871
8872 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
8873 return null;
8874 }
8875
8876 break;
8877
8878 case ClassComponent:
8879 {
8880 var Component = workInProgress.type;
8881
8882 if (isContextProvider(Component)) {
8883 pushContextProvider(workInProgress);
8884 }
8885
8886 break;
8887 }
8888
8889 case HostPortal:
8890 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
8891 break;
8892
8893 case ContextProvider:
8894 {
8895 var newValue = workInProgress.memoizedProps.value;
8896 pushProvider(workInProgress, newValue);
8897 break;
8898 }
8899
8900 case Profiler:
8901 {
8902 // Profiler should only call onRender when one of its descendants actually rendered.
8903 var hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
8904
8905 if (hasChildWork) {
8906 workInProgress.effectTag |= Update;
8907 }
8908 }
8909
8910 break;
8911
8912 case SuspenseComponent:
8913 {
8914 var state = workInProgress.memoizedState;
8915
8916 if (state !== null) {
8917 // whether to retry the primary children, or to skip over it and
8918 // go straight to the fallback. Check the priority of the primary
8919 // child fragment.
8920
8921
8922 var primaryChildFragment = workInProgress.child;
8923 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
8924
8925 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
8926 // The primary children have pending work. Use the normal path
8927 // to attempt to render the primary children again.
8928 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
8929 } else {
8930 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient
8931 // priority. Bailout.
8932
8933 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8934
8935 if (child !== null) {
8936 // The fallback children have pending work. Skip over the
8937 // primary children and work on the fallback.
8938 return child.sibling;
8939 } else {
8940 return null;
8941 }
8942 }
8943 } else {
8944 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
8945 }
8946
8947 break;
8948 }
8949
8950 case SuspenseListComponent:
8951 {
8952 var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect;
8953
8954 var _hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
8955
8956 if (didSuspendBefore) {
8957 if (_hasChildWork) {
8958 // If something was in fallback state last time, and we have all the
8959 // same children then we're still in progressive loading state.
8960 // Something might get unblocked by state updates or retries in the
8961 // tree which will affect the tail. So we need to use the normal
8962 // path to compute the correct tail.
8963 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
8964 } // If none of the children had any work, that means that none of
8965 // them got retried so they'll still be blocked in the same way
8966 // as before. We can fast bail out.
8967
8968
8969 workInProgress.effectTag |= DidCapture;
8970 } // If nothing suspended before and we're rendering the same children,
8971 // then the tail doesn't matter. Anything new that suspends will work
8972 // in the "together" mode, so we can continue from the state we had.
8973
8974
8975 var renderState = workInProgress.memoizedState;
8976
8977 if (renderState !== null) {
8978 // Reset to the "together" mode in case we've started a different
8979 // update in the past but didn't complete it.
8980 renderState.rendering = null;
8981 renderState.tail = null;
8982 }
8983
8984 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
8985
8986 if (_hasChildWork) {
8987 break;
8988 } else {
8989 // If none of the children had any work, that means that none of
8990 // them got retried so they'll still be blocked in the same way
8991 // as before. We can fast bail out.
8992 return null;
8993 }
8994 }
8995 }
8996
8997 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8998 } else {
8999 // An update was scheduled on this fiber, but there are no new props
9000 // nor legacy context. Set this to false. If an update queue or context
9001 // consumer produces a changed value, it will set this to true. Otherwise,
9002 // the component will assume the children have not changed and bail out.
9003 didReceiveUpdate = false;
9004 }
9005 } else {
9006 didReceiveUpdate = false;
9007 } // Before entering the begin phase, clear pending update priority.
9008 // TODO: This assumes that we're about to evaluate the component and process
9009 // the update queue. However, there's an exception: SimpleMemoComponent
9010 // sometimes bails out later in the begin phase. This indicates that we should
9011 // move this assignment out of the common path and into each branch.
9012
9013
9014 workInProgress.expirationTime = NoWork;
9015
9016 switch (workInProgress.tag) {
9017 case IndeterminateComponent:
9018 {
9019 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderExpirationTime);
9020 }
9021
9022 case LazyComponent:
9023 {
9024 var elementType = workInProgress.elementType;
9025 return mountLazyComponent(current, workInProgress, elementType, updateExpirationTime, renderExpirationTime);
9026 }
9027
9028 case FunctionComponent:
9029 {
9030 var _Component = workInProgress.type;
9031 var unresolvedProps = workInProgress.pendingProps;
9032 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
9033 return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderExpirationTime);
9034 }
9035
9036 case ClassComponent:
9037 {
9038 var _Component2 = workInProgress.type;
9039 var _unresolvedProps = workInProgress.pendingProps;
9040
9041 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
9042
9043 return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
9044 }
9045
9046 case HostRoot:
9047 return updateHostRoot(current, workInProgress, renderExpirationTime);
9048
9049 case HostComponent:
9050 return updateHostComponent(current, workInProgress, renderExpirationTime);
9051
9052 case HostText:
9053 return updateHostText();
9054
9055 case SuspenseComponent:
9056 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
9057
9058 case HostPortal:
9059 return updatePortalComponent(current, workInProgress, renderExpirationTime);
9060
9061 case ForwardRef:
9062 {
9063 var type = workInProgress.type;
9064 var _unresolvedProps2 = workInProgress.pendingProps;
9065
9066 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
9067
9068 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderExpirationTime);
9069 }
9070
9071 case Fragment:
9072 return updateFragment(current, workInProgress, renderExpirationTime);
9073
9074 case Mode:
9075 return updateMode(current, workInProgress, renderExpirationTime);
9076
9077 case Profiler:
9078 return updateProfiler(current, workInProgress, renderExpirationTime);
9079
9080 case ContextProvider:
9081 return updateContextProvider(current, workInProgress, renderExpirationTime);
9082
9083 case ContextConsumer:
9084 return updateContextConsumer(current, workInProgress, renderExpirationTime);
9085
9086 case MemoComponent:
9087 {
9088 var _type2 = workInProgress.type;
9089 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
9090
9091 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
9092
9093 {
9094 if (workInProgress.type !== workInProgress.elementType) {
9095 var outerPropTypes = _type2.propTypes;
9096
9097 if (outerPropTypes) {
9098 checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only
9099 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
9100 }
9101 }
9102 }
9103
9104 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
9105 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
9106 }
9107
9108 case SimpleMemoComponent:
9109 {
9110 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
9111 }
9112
9113 case IncompleteClassComponent:
9114 {
9115 var _Component3 = workInProgress.type;
9116 var _unresolvedProps4 = workInProgress.pendingProps;
9117
9118 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
9119
9120 return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
9121 }
9122
9123 case SuspenseListComponent:
9124 {
9125 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
9126 }
9127 }
9128
9129 {
9130 {
9131 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
9132 }
9133 }
9134}
9135
9136function markUpdate(workInProgress) {
9137 // Tag the fiber with an update effect. This turns a Placement into
9138 // a PlacementAndUpdate.
9139 workInProgress.effectTag |= Update;
9140}
9141
9142function markRef$1(workInProgress) {
9143 workInProgress.effectTag |= Ref;
9144}
9145
9146var appendAllChildren;
9147var updateHostContainer;
9148var updateHostComponent$1;
9149var updateHostText$1;
9150
9151{
9152 // Mutation mode
9153 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
9154 // We only have the top Fiber that was created but we need recurse down its
9155 // children to find all the terminal nodes.
9156 var node = workInProgress.child;
9157
9158 while (node !== null) {
9159 if (node.tag === HostComponent || node.tag === HostText) {
9160 appendInitialChild(parent, node.stateNode);
9161 } else if (node.tag === HostPortal) ; else if (node.child !== null) {
9162 node.child.return = node;
9163 node = node.child;
9164 continue;
9165 }
9166
9167 if (node === workInProgress) {
9168 return;
9169 }
9170
9171 while (node.sibling === null) {
9172 if (node.return === null || node.return === workInProgress) {
9173 return;
9174 }
9175
9176 node = node.return;
9177 }
9178
9179 node.sibling.return = node.return;
9180 node = node.sibling;
9181 }
9182 };
9183
9184 updateHostContainer = function (workInProgress) {// Noop
9185 };
9186
9187 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9188 // If we have an alternate, that means this is an update and we need to
9189 // schedule a side-effect to do the updates.
9190 var oldProps = current.memoizedProps;
9191
9192 if (oldProps === newProps) {
9193 // In mutation mode, this is sufficient for a bailout because
9194 // we won't touch this node even if children changed.
9195 return;
9196 } // If we get updated because one of our children updated, we don't
9197 // have newProps so we'll have to reuse them.
9198 // TODO: Split the update API as separate for the props vs. children.
9199 // Even better would be if children weren't special cased at all tho.
9200
9201
9202 var instance = workInProgress.stateNode;
9203 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host
9204 // component is hitting the resume path. Figure out why. Possibly
9205 // related to `hidden`.
9206
9207 var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component.
9208
9209 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
9210 // is a new ref we mark this as an update. All the work is done in commitWork.
9211
9212 if (updatePayload) {
9213 markUpdate(workInProgress);
9214 }
9215 };
9216
9217 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9218 // If the text differs, mark it as an update. All the work in done in commitWork.
9219 if (oldText !== newText) {
9220 markUpdate(workInProgress);
9221 }
9222 };
9223}
9224
9225function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
9226 switch (renderState.tailMode) {
9227 case 'hidden':
9228 {
9229 // Any insertions at the end of the tail list after this point
9230 // should be invisible. If there are already mounted boundaries
9231 // anything before them are not considered for collapsing.
9232 // Therefore we need to go through the whole tail to find if
9233 // there are any.
9234 var tailNode = renderState.tail;
9235 var lastTailNode = null;
9236
9237 while (tailNode !== null) {
9238 if (tailNode.alternate !== null) {
9239 lastTailNode = tailNode;
9240 }
9241
9242 tailNode = tailNode.sibling;
9243 } // Next we're simply going to delete all insertions after the
9244 // last rendered item.
9245
9246
9247 if (lastTailNode === null) {
9248 // All remaining items in the tail are insertions.
9249 renderState.tail = null;
9250 } else {
9251 // Detach the insertion after the last node that was already
9252 // inserted.
9253 lastTailNode.sibling = null;
9254 }
9255
9256 break;
9257 }
9258
9259 case 'collapsed':
9260 {
9261 // Any insertions at the end of the tail list after this point
9262 // should be invisible. If there are already mounted boundaries
9263 // anything before them are not considered for collapsing.
9264 // Therefore we need to go through the whole tail to find if
9265 // there are any.
9266 var _tailNode = renderState.tail;
9267 var _lastTailNode = null;
9268
9269 while (_tailNode !== null) {
9270 if (_tailNode.alternate !== null) {
9271 _lastTailNode = _tailNode;
9272 }
9273
9274 _tailNode = _tailNode.sibling;
9275 } // Next we're simply going to delete all insertions after the
9276 // last rendered item.
9277
9278
9279 if (_lastTailNode === null) {
9280 // All remaining items in the tail are insertions.
9281 if (!hasRenderedATailFallback && renderState.tail !== null) {
9282 // We suspended during the head. We want to show at least one
9283 // row at the tail. So we'll keep on and cut off the rest.
9284 renderState.tail.sibling = null;
9285 } else {
9286 renderState.tail = null;
9287 }
9288 } else {
9289 // Detach the insertion after the last node that was already
9290 // inserted.
9291 _lastTailNode.sibling = null;
9292 }
9293
9294 break;
9295 }
9296 }
9297}
9298
9299function completeWork(current, workInProgress, renderExpirationTime) {
9300 var newProps = workInProgress.pendingProps;
9301
9302 switch (workInProgress.tag) {
9303 case IndeterminateComponent:
9304 case LazyComponent:
9305 case SimpleMemoComponent:
9306 case FunctionComponent:
9307 case ForwardRef:
9308 case Fragment:
9309 case Mode:
9310 case Profiler:
9311 case ContextConsumer:
9312 case MemoComponent:
9313 return null;
9314
9315 case ClassComponent:
9316 {
9317 var Component = workInProgress.type;
9318
9319 if (isContextProvider(Component)) {
9320 popContext(workInProgress);
9321 }
9322
9323 return null;
9324 }
9325
9326 case HostRoot:
9327 {
9328 popHostContainer(workInProgress);
9329 popTopLevelContextObject(workInProgress);
9330 var fiberRoot = workInProgress.stateNode;
9331
9332 if (fiberRoot.pendingContext) {
9333 fiberRoot.context = fiberRoot.pendingContext;
9334 fiberRoot.pendingContext = null;
9335 }
9336
9337 if (current === null || current.child === null) {
9338 // If we hydrated, pop so that we can delete any remaining children
9339 // that weren't hydrated.
9340 var wasHydrated = popHydrationState();
9341
9342 if (wasHydrated) {
9343 // If we hydrated, then we'll need to schedule an update for
9344 // the commit side-effects on the root.
9345 markUpdate(workInProgress);
9346 }
9347 }
9348
9349 updateHostContainer(workInProgress);
9350 return null;
9351 }
9352
9353 case HostComponent:
9354 {
9355 popHostContext(workInProgress);
9356 var rootContainerInstance = getRootHostContainer();
9357 var type = workInProgress.type;
9358
9359 if (current !== null && workInProgress.stateNode != null) {
9360 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
9361
9362 if (current.ref !== workInProgress.ref) {
9363 markRef$1(workInProgress);
9364 }
9365 } else {
9366 if (!newProps) {
9367 if (!(workInProgress.stateNode !== null)) {
9368 {
9369 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
9370 }
9371 } // This can happen when we abort work.
9372
9373
9374 return null;
9375 }
9376
9377 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
9378 // "stack" as the parent. Then append children as we go in beginWork
9379 // or completeWork depending on whether we want to add them top->down or
9380 // bottom->up. Top->down is faster in IE11.
9381
9382 var _wasHydrated = popHydrationState();
9383
9384 if (_wasHydrated) {
9385 // TODO: Move this and createInstance step into the beginPhase
9386 // to consolidate.
9387 if (prepareToHydrateHostInstance()) {
9388 // If changes to the hydrated node need to be applied at the
9389 // commit-phase we mark this as such.
9390 markUpdate(workInProgress);
9391 }
9392 } else {
9393 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
9394 appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners
9395
9396 workInProgress.stateNode = instance;
9397 }
9398
9399 if (workInProgress.ref !== null) {
9400 // If there is a ref on a host node we need to schedule a callback
9401 markRef$1(workInProgress);
9402 }
9403 }
9404
9405 return null;
9406 }
9407
9408 case HostText:
9409 {
9410 var newText = newProps;
9411
9412 if (current && workInProgress.stateNode != null) {
9413 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
9414 // to schedule a side-effect to do the updates.
9415
9416 updateHostText$1(current, workInProgress, oldText, newText);
9417 } else {
9418 if (typeof newText !== 'string') {
9419 if (!(workInProgress.stateNode !== null)) {
9420 {
9421 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
9422 }
9423 } // This can happen when we abort work.
9424
9425 }
9426
9427 var _rootContainerInstance = getRootHostContainer();
9428
9429 var _currentHostContext = getHostContext();
9430
9431 var _wasHydrated2 = popHydrationState();
9432
9433 if (_wasHydrated2) {
9434 if (prepareToHydrateHostTextInstance()) {
9435 markUpdate(workInProgress);
9436 }
9437 } else {
9438 workInProgress.stateNode = createTextInstance(newText);
9439 }
9440 }
9441
9442 return null;
9443 }
9444
9445 case SuspenseComponent:
9446 {
9447 popSuspenseContext(workInProgress);
9448 var nextState = workInProgress.memoizedState;
9449
9450 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
9451 // Something suspended. Re-render with the fallback children.
9452 workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list.
9453
9454 return workInProgress;
9455 }
9456
9457 var nextDidTimeout = nextState !== null;
9458 var prevDidTimeout = false;
9459
9460 if (current === null) {
9461 if (workInProgress.memoizedProps.fallback !== undefined) ;
9462 } else {
9463 var prevState = current.memoizedState;
9464 prevDidTimeout = prevState !== null;
9465
9466 if (!nextDidTimeout && prevState !== null) {
9467 // We just switched from the fallback to the normal children.
9468 // Delete the fallback.
9469 // TODO: Would it be better to store the fallback fragment on
9470 // the stateNode during the begin phase?
9471 var currentFallbackChild = current.child.sibling;
9472
9473 if (currentFallbackChild !== null) {
9474 // Deletions go at the beginning of the return fiber's effect list
9475 var first = workInProgress.firstEffect;
9476
9477 if (first !== null) {
9478 workInProgress.firstEffect = currentFallbackChild;
9479 currentFallbackChild.nextEffect = first;
9480 } else {
9481 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
9482 currentFallbackChild.nextEffect = null;
9483 }
9484
9485 currentFallbackChild.effectTag = Deletion;
9486 }
9487 }
9488 }
9489
9490 if (nextDidTimeout && !prevDidTimeout) {
9491 // If this subtreee is running in blocking mode we can suspend,
9492 // otherwise we won't suspend.
9493 // TODO: This will still suspend a synchronous tree if anything
9494 // in the concurrent tree already suspended during this render.
9495 // This is a known bug.
9496 if ((workInProgress.mode & BlockingMode) !== NoMode) {
9497 // TODO: Move this back to throwException because this is too late
9498 // if this is a large tree which is common for initial loads. We
9499 // don't know if we should restart a render or not until we get
9500 // this marker, and this is too late.
9501 // If this render already had a ping or lower pri updates,
9502 // and this is the first time we know we're going to suspend we
9503 // should be able to immediately restart from within throwException.
9504 var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true;
9505
9506 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
9507 // If this was in an invisible tree or a new render, then showing
9508 // this boundary is ok.
9509 renderDidSuspend();
9510 } else {
9511 // Otherwise, we're going to have to hide content so we should
9512 // suspend for longer if possible.
9513 renderDidSuspendDelayIfPossible();
9514 }
9515 }
9516 }
9517
9518 {
9519 // TODO: Only schedule updates if these values are non equal, i.e. it changed.
9520 if (nextDidTimeout || prevDidTimeout) {
9521 // If this boundary just timed out, schedule an effect to attach a
9522 // retry listener to the promise. This flag is also used to hide the
9523 // primary children. In mutation mode, we also need the flag to
9524 // *unhide* children that were previously hidden, so check if this
9525 // is currently timed out, too.
9526 workInProgress.effectTag |= Update;
9527 }
9528 }
9529
9530 return null;
9531 }
9532
9533 case HostPortal:
9534 popHostContainer(workInProgress);
9535 updateHostContainer(workInProgress);
9536 return null;
9537
9538 case ContextProvider:
9539 // Pop provider fiber
9540 popProvider(workInProgress);
9541 return null;
9542
9543 case IncompleteClassComponent:
9544 {
9545 // Same as class component case. I put it down here so that the tags are
9546 // sequential to ensure this switch is compiled to a jump table.
9547 var _Component = workInProgress.type;
9548
9549 if (isContextProvider(_Component)) {
9550 popContext(workInProgress);
9551 }
9552
9553 return null;
9554 }
9555
9556 case SuspenseListComponent:
9557 {
9558 popSuspenseContext(workInProgress);
9559 var renderState = workInProgress.memoizedState;
9560
9561 if (renderState === null) {
9562 // We're running in the default, "independent" mode.
9563 // We don't do anything in this mode.
9564 return null;
9565 }
9566
9567 var didSuspendAlready = (workInProgress.effectTag & DidCapture) !== NoEffect;
9568 var renderedTail = renderState.rendering;
9569
9570 if (renderedTail === null) {
9571 // We just rendered the head.
9572 if (!didSuspendAlready) {
9573 // This is the first pass. We need to figure out if anything is still
9574 // suspended in the rendered set.
9575 // If new content unsuspended, but there's still some content that
9576 // didn't. Then we need to do a second pass that forces everything
9577 // to keep showing their fallbacks.
9578 // We might be suspended if something in this render pass suspended, or
9579 // something in the previous committed pass suspended. Otherwise,
9580 // there's no chance so we can skip the expensive call to
9581 // findFirstSuspended.
9582 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.effectTag & DidCapture) === NoEffect);
9583
9584 if (!cannotBeSuspended) {
9585 var row = workInProgress.child;
9586
9587 while (row !== null) {
9588 var suspended = findFirstSuspended(row);
9589
9590 if (suspended !== null) {
9591 didSuspendAlready = true;
9592 workInProgress.effectTag |= DidCapture;
9593 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
9594 // part of the second pass. In that case nothing will subscribe to
9595 // its thennables. Instead, we'll transfer its thennables to the
9596 // SuspenseList so that it can retry if they resolve.
9597 // There might be multiple of these in the list but since we're
9598 // going to wait for all of them anyway, it doesn't really matter
9599 // which ones gets to ping. In theory we could get clever and keep
9600 // track of how many dependencies remain but it gets tricky because
9601 // in the meantime, we can add/remove/change items and dependencies.
9602 // We might bail out of the loop before finding any but that
9603 // doesn't matter since that means that the other boundaries that
9604 // we did find already has their listeners attached.
9605
9606 var newThennables = suspended.updateQueue;
9607
9608 if (newThennables !== null) {
9609 workInProgress.updateQueue = newThennables;
9610 workInProgress.effectTag |= Update;
9611 } // Rerender the whole list, but this time, we'll force fallbacks
9612 // to stay in place.
9613 // Reset the effect list before doing the second pass since that's now invalid.
9614
9615
9616 if (renderState.lastEffect === null) {
9617 workInProgress.firstEffect = null;
9618 }
9619
9620 workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state.
9621
9622 resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately
9623 // rerender the children.
9624
9625 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
9626 return workInProgress.child;
9627 }
9628
9629 row = row.sibling;
9630 }
9631 }
9632 } else {
9633 cutOffTailIfNeeded(renderState, false);
9634 } // Next we're going to render the tail.
9635
9636 } else {
9637 // Append the rendered row to the child list.
9638 if (!didSuspendAlready) {
9639 var _suspended = findFirstSuspended(renderedTail);
9640
9641 if (_suspended !== null) {
9642 workInProgress.effectTag |= DidCapture;
9643 didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't
9644 // get lost if this row ends up dropped during a second pass.
9645
9646 var _newThennables = _suspended.updateQueue;
9647
9648 if (_newThennables !== null) {
9649 workInProgress.updateQueue = _newThennables;
9650 workInProgress.effectTag |= Update;
9651 }
9652
9653 cutOffTailIfNeeded(renderState, true); // This might have been modified.
9654
9655 if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate) {
9656 // We need to delete the row we just rendered.
9657 // Reset the effect list to what it was before we rendered this
9658 // child. The nested children have already appended themselves.
9659 var lastEffect = workInProgress.lastEffect = renderState.lastEffect; // Remove any effects that were appended after this point.
9660
9661 if (lastEffect !== null) {
9662 lastEffect.nextEffect = null;
9663 } // We're done.
9664
9665
9666 return null;
9667 }
9668 } else if ( // The time it took to render last row is greater than time until
9669 // the expiration.
9670 now() * 2 - renderState.renderingStartTime > renderState.tailExpiration && renderExpirationTime > Never) {
9671 // We have now passed our CPU deadline and we'll just give up further
9672 // attempts to render the main content and only render fallbacks.
9673 // The assumption is that this is usually faster.
9674 workInProgress.effectTag |= DidCapture;
9675 didSuspendAlready = true;
9676 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
9677 // to get it started back up to attempt the next item. If we can show
9678 // them, then they really have the same priority as this render.
9679 // So we'll pick it back up the very next render pass once we've had
9680 // an opportunity to yield for paint.
9681
9682 var nextPriority = renderExpirationTime - 1;
9683 workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority;
9684
9685 {
9686 markSpawnedWork(nextPriority);
9687 }
9688 }
9689 }
9690
9691 if (renderState.isBackwards) {
9692 // The effect list of the backwards tail will have been added
9693 // to the end. This breaks the guarantee that life-cycles fire in
9694 // sibling order but that isn't a strong guarantee promised by React.
9695 // Especially since these might also just pop in during future commits.
9696 // Append to the beginning of the list.
9697 renderedTail.sibling = workInProgress.child;
9698 workInProgress.child = renderedTail;
9699 } else {
9700 var previousSibling = renderState.last;
9701
9702 if (previousSibling !== null) {
9703 previousSibling.sibling = renderedTail;
9704 } else {
9705 workInProgress.child = renderedTail;
9706 }
9707
9708 renderState.last = renderedTail;
9709 }
9710 }
9711
9712 if (renderState.tail !== null) {
9713 // We still have tail rows to render.
9714 if (renderState.tailExpiration === 0) {
9715 // Heuristic for how long we're willing to spend rendering rows
9716 // until we just give up and show what we have so far.
9717 var TAIL_EXPIRATION_TIMEOUT_MS = 500;
9718 renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; // TODO: This is meant to mimic the train model or JND but this
9719 // is a per component value. It should really be since the start
9720 // of the total render or last commit. Consider using something like
9721 // globalMostRecentFallbackTime. That doesn't account for being
9722 // suspended for part of the time or when it's a new render.
9723 // It should probably use a global start time value instead.
9724 } // Pop a row.
9725
9726
9727 var next = renderState.tail;
9728 renderState.rendering = next;
9729 renderState.tail = next.sibling;
9730 renderState.lastEffect = workInProgress.lastEffect;
9731 renderState.renderingStartTime = now();
9732 next.sibling = null; // Restore the context.
9733 // TODO: We can probably just avoid popping it instead and only
9734 // setting it the first time we go from not suspended to suspended.
9735
9736 var suspenseContext = suspenseStackCursor.current;
9737
9738 if (didSuspendAlready) {
9739 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
9740 } else {
9741 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
9742 }
9743
9744 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
9745
9746 return next;
9747 }
9748
9749 return null;
9750 }
9751 }
9752
9753 {
9754 {
9755 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
9756 }
9757 }
9758}
9759
9760function unwindWork(workInProgress, renderExpirationTime) {
9761 switch (workInProgress.tag) {
9762 case ClassComponent:
9763 {
9764 var Component = workInProgress.type;
9765
9766 if (isContextProvider(Component)) {
9767 popContext(workInProgress);
9768 }
9769
9770 var effectTag = workInProgress.effectTag;
9771
9772 if (effectTag & ShouldCapture) {
9773 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
9774 return workInProgress;
9775 }
9776
9777 return null;
9778 }
9779
9780 case HostRoot:
9781 {
9782 popHostContainer(workInProgress);
9783 popTopLevelContextObject(workInProgress);
9784 var _effectTag = workInProgress.effectTag;
9785
9786 if (!((_effectTag & DidCapture) === NoEffect)) {
9787 {
9788 throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." );
9789 }
9790 }
9791
9792 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
9793 return workInProgress;
9794 }
9795
9796 case HostComponent:
9797 {
9798 // TODO: popHydrationState
9799 popHostContext(workInProgress);
9800 return null;
9801 }
9802
9803 case SuspenseComponent:
9804 {
9805 popSuspenseContext(workInProgress);
9806
9807 var _effectTag2 = workInProgress.effectTag;
9808
9809 if (_effectTag2 & ShouldCapture) {
9810 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
9811
9812 return workInProgress;
9813 }
9814
9815 return null;
9816 }
9817
9818 case SuspenseListComponent:
9819 {
9820 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
9821 // caught by a nested boundary. If not, it should bubble through.
9822
9823 return null;
9824 }
9825
9826 case HostPortal:
9827 popHostContainer(workInProgress);
9828 return null;
9829
9830 case ContextProvider:
9831 popProvider(workInProgress);
9832 return null;
9833
9834 default:
9835 return null;
9836 }
9837}
9838
9839function unwindInterruptedWork(interruptedWork) {
9840 switch (interruptedWork.tag) {
9841 case ClassComponent:
9842 {
9843 var childContextTypes = interruptedWork.type.childContextTypes;
9844
9845 if (childContextTypes !== null && childContextTypes !== undefined) {
9846 popContext(interruptedWork);
9847 }
9848
9849 break;
9850 }
9851
9852 case HostRoot:
9853 {
9854 popHostContainer(interruptedWork);
9855 popTopLevelContextObject(interruptedWork);
9856 break;
9857 }
9858
9859 case HostComponent:
9860 {
9861 popHostContext(interruptedWork);
9862 break;
9863 }
9864
9865 case HostPortal:
9866 popHostContainer(interruptedWork);
9867 break;
9868
9869 case SuspenseComponent:
9870 popSuspenseContext(interruptedWork);
9871 break;
9872
9873 case SuspenseListComponent:
9874 popSuspenseContext(interruptedWork);
9875 break;
9876
9877 case ContextProvider:
9878 popProvider(interruptedWork);
9879 break;
9880 }
9881}
9882
9883function createCapturedValue(value, source) {
9884 // If the value is an error, call this function immediately after it is thrown
9885 // so the stack is accurate.
9886 return {
9887 value: value,
9888 source: source,
9889 stack: getStackByFiberInDevAndProd(source)
9890 };
9891}
9892
9893var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
9894 var funcArgs = Array.prototype.slice.call(arguments, 3);
9895
9896 try {
9897 func.apply(context, funcArgs);
9898 } catch (error) {
9899 this.onError(error);
9900 }
9901};
9902
9903{
9904 // In DEV mode, we swap out invokeGuardedCallback for a special version
9905 // that plays more nicely with the browser's DevTools. The idea is to preserve
9906 // "Pause on exceptions" behavior. Because React wraps all user-provided
9907 // functions in invokeGuardedCallback, and the production version of
9908 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
9909 // like caught exceptions, and the DevTools won't pause unless the developer
9910 // takes the extra step of enabling pause on caught exceptions. This is
9911 // unintuitive, though, because even though React has caught the error, from
9912 // the developer's perspective, the error is uncaught.
9913 //
9914 // To preserve the expected "Pause on exceptions" behavior, we don't use a
9915 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
9916 // DOM node, and call the user-provided callback from inside an event handler
9917 // for that fake event. If the callback throws, the error is "captured" using
9918 // a global event handler. But because the error happens in a different
9919 // event loop context, it does not interrupt the normal program flow.
9920 // Effectively, this gives us try-catch behavior without actually using
9921 // try-catch. Neat!
9922 // Check that the browser supports the APIs we need to implement our special
9923 // DEV version of invokeGuardedCallback
9924 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
9925 var fakeNode = document.createElement('react');
9926
9927 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
9928 // If document doesn't exist we know for sure we will crash in this method
9929 // when we call document.createEvent(). However this can cause confusing
9930 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
9931 // So we preemptively throw with a better message instead.
9932 if (!(typeof document !== 'undefined')) {
9933 {
9934 throw 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." );
9935 }
9936 }
9937
9938 var evt = document.createEvent('Event'); // Keeps track of whether the user-provided callback threw an error. We
9939 // set this to true at the beginning, then set it to false right after
9940 // calling the function. If the function errors, `didError` will never be
9941 // set to false. This strategy works even if the browser is flaky and
9942 // fails to call our global error handler, because it doesn't rely on
9943 // the error event at all.
9944
9945 var didError = true; // Keeps track of the value of window.event so that we can reset it
9946 // during the callback to let user code access window.event in the
9947 // browsers that support it.
9948
9949 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event
9950 // dispatching: https://github.com/facebook/react/issues/13688
9951
9952 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event'); // Create an event handler for our fake event. We will synchronously
9953 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
9954 // call the user-provided callback.
9955
9956 var funcArgs = Array.prototype.slice.call(arguments, 3);
9957
9958 function callCallback() {
9959 // We immediately remove the callback from event listeners so that
9960 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
9961 // nested call would trigger the fake event handlers of any call higher
9962 // in the stack.
9963 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the
9964 // window.event assignment in both IE <= 10 as they throw an error
9965 // "Member not found" in strict mode, and in Firefox which does not
9966 // support window.event.
9967
9968 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
9969 window.event = windowEvent;
9970 }
9971
9972 func.apply(context, funcArgs);
9973 didError = false;
9974 } // Create a global error event handler. We use this to capture the value
9975 // that was thrown. It's possible that this error handler will fire more
9976 // than once; for example, if non-React code also calls `dispatchEvent`
9977 // and a handler for that event throws. We should be resilient to most of
9978 // those cases. Even if our error event handler fires more than once, the
9979 // last error event is always used. If the callback actually does error,
9980 // we know that the last error event is the correct one, because it's not
9981 // possible for anything else to have happened in between our callback
9982 // erroring and the code that follows the `dispatchEvent` call below. If
9983 // the callback doesn't error, but the error event was fired, we know to
9984 // ignore it because `didError` will be false, as described above.
9985
9986
9987 var error; // Use this to track whether the error event is ever called.
9988
9989 var didSetError = false;
9990 var isCrossOriginError = false;
9991
9992 function handleWindowError(event) {
9993 error = event.error;
9994 didSetError = true;
9995
9996 if (error === null && event.colno === 0 && event.lineno === 0) {
9997 isCrossOriginError = true;
9998 }
9999
10000 if (event.defaultPrevented) {
10001 // Some other error handler has prevented default.
10002 // Browsers silence the error report if this happens.
10003 // We'll remember this to later decide whether to log it or not.
10004 if (error != null && typeof error === 'object') {
10005 try {
10006 error._suppressLogging = true;
10007 } catch (inner) {// Ignore.
10008 }
10009 }
10010 }
10011 } // Create a fake event type.
10012
10013
10014 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers
10015
10016 window.addEventListener('error', handleWindowError);
10017 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function
10018 // errors, it will trigger our global error handler.
10019
10020 evt.initEvent(evtType, false, false);
10021 fakeNode.dispatchEvent(evt);
10022
10023 if (windowEventDescriptor) {
10024 Object.defineProperty(window, 'event', windowEventDescriptor);
10025 }
10026
10027 if (didError) {
10028 if (!didSetError) {
10029 // The callback errored, but the error event never fired.
10030 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.');
10031 } else if (isCrossOriginError) {
10032 error = new Error("A cross-origin error was thrown. React doesn't have access to " + 'the actual error object in development. ' + 'See https://fb.me/react-crossorigin-error for more information.');
10033 }
10034
10035 this.onError(error);
10036 } // Remove our event listeners
10037
10038
10039 window.removeEventListener('error', handleWindowError);
10040 };
10041
10042 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
10043 }
10044}
10045
10046var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
10047
10048var hasError = false;
10049var caughtError = null; // Used by event system to capture/rethrow the first error.
10050var reporter = {
10051 onError: function (error) {
10052 hasError = true;
10053 caughtError = error;
10054 }
10055};
10056/**
10057 * Call a function while guarding against errors that happens within it.
10058 * Returns an error if it throws, otherwise null.
10059 *
10060 * In production, this is implemented using a try-catch. The reason we don't
10061 * use a try-catch directly is so that we can swap out a different
10062 * implementation in DEV mode.
10063 *
10064 * @param {String} name of the guard to use for logging or debugging
10065 * @param {Function} func The function to invoke
10066 * @param {*} context The context to use when calling the function
10067 * @param {...*} args Arguments for function
10068 */
10069
10070function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
10071 hasError = false;
10072 caughtError = null;
10073 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
10074}
10075function hasCaughtError() {
10076 return hasError;
10077}
10078function clearCaughtError() {
10079 if (hasError) {
10080 var error = caughtError;
10081 hasError = false;
10082 caughtError = null;
10083 return error;
10084 } else {
10085 {
10086 {
10087 throw Error( "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." );
10088 }
10089 }
10090 }
10091}
10092
10093function logCapturedError(capturedError) {
10094
10095 var error = capturedError.error;
10096
10097 {
10098 var componentName = capturedError.componentName,
10099 componentStack = capturedError.componentStack,
10100 errorBoundaryName = capturedError.errorBoundaryName,
10101 errorBoundaryFound = capturedError.errorBoundaryFound,
10102 willRetry = capturedError.willRetry; // Browsers support silencing uncaught errors by calling
10103 // `preventDefault()` in window `error` handler.
10104 // We record this information as an expando on the error.
10105
10106 if (error != null && error._suppressLogging) {
10107 if (errorBoundaryFound && willRetry) {
10108 // The error is recoverable and was silenced.
10109 // Ignore it and don't print the stack addendum.
10110 // This is handy for testing error boundaries without noise.
10111 return;
10112 } // The error is fatal. Since the silencing might have
10113 // been accidental, we'll surface it anyway.
10114 // However, the browser would have silenced the original error
10115 // so we'll print it first, and then print the stack addendum.
10116
10117
10118 console['error'](error); // Don't transform to our wrapper
10119 // For a more detailed description of this block, see:
10120 // https://github.com/facebook/react/pull/13384
10121 }
10122
10123 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:';
10124 var errorBoundaryMessage; // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
10125
10126 if (errorBoundaryFound && errorBoundaryName) {
10127 if (willRetry) {
10128 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
10129 } else {
10130 errorBoundaryMessage = "This error was initially handled by the error boundary " + errorBoundaryName + ".\n" + "Recreating the tree from scratch failed so React will unmount the tree.";
10131 }
10132 } else {
10133 errorBoundaryMessage = 'Consider adding an error boundary to your tree to customize error handling behavior.\n' + 'Visit https://fb.me/react-error-boundaries to learn more about error boundaries.';
10134 }
10135
10136 var combinedMessage = "" + componentNameMessage + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.
10137 // We don't include the original error message and JS stack because the browser
10138 // has already printed it. Even if the application swallows the error, it is still
10139 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
10140
10141 console['error'](combinedMessage); // Don't transform to our wrapper
10142 }
10143}
10144
10145var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
10146
10147{
10148 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
10149}
10150
10151var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
10152function logError(boundary, errorInfo) {
10153 var source = errorInfo.source;
10154 var stack = errorInfo.stack;
10155
10156 if (stack === null && source !== null) {
10157 stack = getStackByFiberInDevAndProd(source);
10158 }
10159
10160 var capturedError = {
10161 componentName: source !== null ? getComponentName(source.type) : null,
10162 componentStack: stack !== null ? stack : '',
10163 error: errorInfo.value,
10164 errorBoundary: null,
10165 errorBoundaryName: null,
10166 errorBoundaryFound: false,
10167 willRetry: false
10168 };
10169
10170 if (boundary !== null && boundary.tag === ClassComponent) {
10171 capturedError.errorBoundary = boundary.stateNode;
10172 capturedError.errorBoundaryName = getComponentName(boundary.type);
10173 capturedError.errorBoundaryFound = true;
10174 capturedError.willRetry = true;
10175 }
10176
10177 try {
10178 logCapturedError(capturedError);
10179 } catch (e) {
10180 // This method must not throw, or React internal state will get messed up.
10181 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
10182 // we want to report this error outside of the normal stack as a last resort.
10183 // https://github.com/facebook/react/issues/13188
10184 setTimeout(function () {
10185 throw e;
10186 });
10187 }
10188}
10189
10190var callComponentWillUnmountWithTimer = function (current, instance) {
10191 startPhaseTimer(current, 'componentWillUnmount');
10192 instance.props = current.memoizedProps;
10193 instance.state = current.memoizedState;
10194 instance.componentWillUnmount();
10195 stopPhaseTimer();
10196}; // Capture errors so they don't interrupt unmounting.
10197
10198
10199function safelyCallComponentWillUnmount(current, instance) {
10200 {
10201 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);
10202
10203 if (hasCaughtError()) {
10204 var unmountError = clearCaughtError();
10205 captureCommitPhaseError(current, unmountError);
10206 }
10207 }
10208}
10209
10210function safelyDetachRef(current) {
10211 var ref = current.ref;
10212
10213 if (ref !== null) {
10214 if (typeof ref === 'function') {
10215 {
10216 invokeGuardedCallback(null, ref, null, null);
10217
10218 if (hasCaughtError()) {
10219 var refError = clearCaughtError();
10220 captureCommitPhaseError(current, refError);
10221 }
10222 }
10223 } else {
10224 ref.current = null;
10225 }
10226 }
10227}
10228
10229function safelyCallDestroy(current, destroy) {
10230 {
10231 invokeGuardedCallback(null, destroy, null);
10232
10233 if (hasCaughtError()) {
10234 var error = clearCaughtError();
10235 captureCommitPhaseError(current, error);
10236 }
10237 }
10238}
10239
10240function commitBeforeMutationLifeCycles(current, finishedWork) {
10241 switch (finishedWork.tag) {
10242 case FunctionComponent:
10243 case ForwardRef:
10244 case SimpleMemoComponent:
10245 case Block:
10246 {
10247 return;
10248 }
10249
10250 case ClassComponent:
10251 {
10252 if (finishedWork.effectTag & Snapshot) {
10253 if (current !== null) {
10254 var prevProps = current.memoizedProps;
10255 var prevState = current.memoizedState;
10256 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
10257 var instance = finishedWork.stateNode; // We could update instance props and state here,
10258 // but instead we rely on them being set during last render.
10259 // TODO: revisit this when we implement resuming.
10260
10261 {
10262 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
10263 if (instance.props !== finishedWork.memoizedProps) {
10264 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.', getComponentName(finishedWork.type) || 'instance');
10265 }
10266
10267 if (instance.state !== finishedWork.memoizedState) {
10268 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.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
10269 }
10270 }
10271 }
10272
10273 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
10274
10275 {
10276 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
10277
10278 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
10279 didWarnSet.add(finishedWork.type);
10280
10281 error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
10282 }
10283 }
10284
10285 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
10286 stopPhaseTimer();
10287 }
10288 }
10289
10290 return;
10291 }
10292
10293 case HostRoot:
10294 case HostComponent:
10295 case HostText:
10296 case HostPortal:
10297 case IncompleteClassComponent:
10298 // Nothing to do for these component types
10299 return;
10300 }
10301
10302 {
10303 {
10304 throw 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." );
10305 }
10306 }
10307}
10308
10309function commitHookEffectListUnmount(tag, finishedWork) {
10310 var updateQueue = finishedWork.updateQueue;
10311 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
10312
10313 if (lastEffect !== null) {
10314 var firstEffect = lastEffect.next;
10315 var effect = firstEffect;
10316
10317 do {
10318 if ((effect.tag & tag) === tag) {
10319 // Unmount
10320 var destroy = effect.destroy;
10321 effect.destroy = undefined;
10322
10323 if (destroy !== undefined) {
10324 destroy();
10325 }
10326 }
10327
10328 effect = effect.next;
10329 } while (effect !== firstEffect);
10330 }
10331}
10332
10333function commitHookEffectListMount(tag, finishedWork) {
10334 var updateQueue = finishedWork.updateQueue;
10335 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
10336
10337 if (lastEffect !== null) {
10338 var firstEffect = lastEffect.next;
10339 var effect = firstEffect;
10340
10341 do {
10342 if ((effect.tag & tag) === tag) {
10343 // Mount
10344 var create = effect.create;
10345 effect.destroy = create();
10346
10347 {
10348 var destroy = effect.destroy;
10349
10350 if (destroy !== undefined && typeof destroy !== 'function') {
10351 var addendum = void 0;
10352
10353 if (destroy === null) {
10354 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
10355 } else if (typeof destroy.then === 'function') {
10356 addendum = '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' + 'Instead, write the async function inside your effect ' + 'and call it immediately:\n\n' + 'useEffect(() => {\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://fb.me/react-hooks-data-fetching';
10357 } else {
10358 addendum = ' You returned: ' + destroy;
10359 }
10360
10361 error('An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
10362 }
10363 }
10364 }
10365
10366 effect = effect.next;
10367 } while (effect !== firstEffect);
10368 }
10369}
10370
10371function commitPassiveHookEffects(finishedWork) {
10372 if ((finishedWork.effectTag & Passive) !== NoEffect) {
10373 switch (finishedWork.tag) {
10374 case FunctionComponent:
10375 case ForwardRef:
10376 case SimpleMemoComponent:
10377 case Block:
10378 {
10379 // TODO (#17945) We should call all passive destroy functions (for all fibers)
10380 // before calling any create functions. The current approach only serializes
10381 // these for a single fiber.
10382 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork);
10383 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
10384 break;
10385 }
10386 }
10387 }
10388}
10389
10390function commitLifeCycles(finishedRoot, current, finishedWork, committedExpirationTime) {
10391 switch (finishedWork.tag) {
10392 case FunctionComponent:
10393 case ForwardRef:
10394 case SimpleMemoComponent:
10395 case Block:
10396 {
10397 // At this point layout effects have already been destroyed (during mutation phase).
10398 // This is done to prevent sibling component effects from interfering with each other,
10399 // e.g. a destroy function in one component should never override a ref set
10400 // by a create function in another component during the same commit.
10401 commitHookEffectListMount(Layout | HasEffect, finishedWork);
10402
10403 return;
10404 }
10405
10406 case ClassComponent:
10407 {
10408 var instance = finishedWork.stateNode;
10409
10410 if (finishedWork.effectTag & Update) {
10411 if (current === null) {
10412 startPhaseTimer(finishedWork, 'componentDidMount'); // We could update instance props and state here,
10413 // but instead we rely on them being set during last render.
10414 // TODO: revisit this when we implement resuming.
10415
10416 {
10417 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
10418 if (instance.props !== finishedWork.memoizedProps) {
10419 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.', getComponentName(finishedWork.type) || 'instance');
10420 }
10421
10422 if (instance.state !== finishedWork.memoizedState) {
10423 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.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
10424 }
10425 }
10426 }
10427
10428 instance.componentDidMount();
10429 stopPhaseTimer();
10430 } else {
10431 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
10432 var prevState = current.memoizedState;
10433 startPhaseTimer(finishedWork, 'componentDidUpdate'); // We could update instance props and state here,
10434 // but instead we rely on them being set during last render.
10435 // TODO: revisit this when we implement resuming.
10436
10437 {
10438 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
10439 if (instance.props !== finishedWork.memoizedProps) {
10440 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.', getComponentName(finishedWork.type) || 'instance');
10441 }
10442
10443 if (instance.state !== finishedWork.memoizedState) {
10444 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.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
10445 }
10446 }
10447 }
10448
10449 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
10450 stopPhaseTimer();
10451 }
10452 }
10453
10454 var updateQueue = finishedWork.updateQueue;
10455
10456 if (updateQueue !== null) {
10457 {
10458 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
10459 if (instance.props !== finishedWork.memoizedProps) {
10460 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.', getComponentName(finishedWork.type) || 'instance');
10461 }
10462
10463 if (instance.state !== finishedWork.memoizedState) {
10464 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.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
10465 }
10466 }
10467 } // We could update instance props and state here,
10468 // but instead we rely on them being set during last render.
10469 // TODO: revisit this when we implement resuming.
10470
10471
10472 commitUpdateQueue(finishedWork, updateQueue, instance);
10473 }
10474
10475 return;
10476 }
10477
10478 case HostRoot:
10479 {
10480 var _updateQueue = finishedWork.updateQueue;
10481
10482 if (_updateQueue !== null) {
10483 var _instance = null;
10484
10485 if (finishedWork.child !== null) {
10486 switch (finishedWork.child.tag) {
10487 case HostComponent:
10488 _instance = getPublicInstance(finishedWork.child.stateNode);
10489 break;
10490
10491 case ClassComponent:
10492 _instance = finishedWork.child.stateNode;
10493 break;
10494 }
10495 }
10496
10497 commitUpdateQueue(finishedWork, _updateQueue, _instance);
10498 }
10499
10500 return;
10501 }
10502
10503 case HostComponent:
10504 {
10505 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted
10506 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
10507 // These effects should only be committed when components are first mounted,
10508 // aka when there is no current/alternate.
10509
10510 if (current === null && finishedWork.effectTag & Update) {
10511 var type = finishedWork.type;
10512 var props = finishedWork.memoizedProps;
10513 }
10514
10515 return;
10516 }
10517
10518 case HostText:
10519 {
10520 // We have no life-cycles associated with text.
10521 return;
10522 }
10523
10524 case HostPortal:
10525 {
10526 // We have no life-cycles associated with portals.
10527 return;
10528 }
10529
10530 case Profiler:
10531 {
10532 {
10533 var onRender = finishedWork.memoizedProps.onRender;
10534
10535 if (typeof onRender === 'function') {
10536 {
10537 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
10538 }
10539 }
10540 }
10541
10542 return;
10543 }
10544
10545 case SuspenseComponent:
10546 {
10547 return;
10548 }
10549
10550 case SuspenseListComponent:
10551 case IncompleteClassComponent:
10552 case FundamentalComponent:
10553 case ScopeComponent:
10554 return;
10555 }
10556
10557 {
10558 {
10559 throw 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." );
10560 }
10561 }
10562}
10563
10564function hideOrUnhideAllChildren(finishedWork, isHidden) {
10565 {
10566 // We only have the top Fiber that was inserted but we need to recurse down its
10567 // children to find all the terminal nodes.
10568 var node = finishedWork;
10569
10570 while (true) {
10571 if (node.tag === HostComponent) {
10572 var instance = node.stateNode;
10573
10574 if (isHidden) {
10575 hideInstance(instance);
10576 } else {
10577 unhideInstance(node.stateNode, node.memoizedProps);
10578 }
10579 } else if (node.tag === HostText) {
10580 var _instance3 = node.stateNode;
10581
10582 if (isHidden) {
10583 hideTextInstance(_instance3);
10584 } else {
10585 unhideTextInstance(_instance3, node.memoizedProps);
10586 }
10587 } else if (node.tag === SuspenseComponent && node.memoizedState !== null && node.memoizedState.dehydrated === null) {
10588 // Found a nested Suspense component that timed out. Skip over the
10589 // primary child fragment, which should remain hidden.
10590 var fallbackChildFragment = node.child.sibling;
10591 fallbackChildFragment.return = node;
10592 node = fallbackChildFragment;
10593 continue;
10594 } else if (node.child !== null) {
10595 node.child.return = node;
10596 node = node.child;
10597 continue;
10598 }
10599
10600 if (node === finishedWork) {
10601 return;
10602 }
10603
10604 while (node.sibling === null) {
10605 if (node.return === null || node.return === finishedWork) {
10606 return;
10607 }
10608
10609 node = node.return;
10610 }
10611
10612 node.sibling.return = node.return;
10613 node = node.sibling;
10614 }
10615 }
10616}
10617
10618function commitAttachRef(finishedWork) {
10619 var ref = finishedWork.ref;
10620
10621 if (ref !== null) {
10622 var instance = finishedWork.stateNode;
10623 var instanceToUse;
10624
10625 switch (finishedWork.tag) {
10626 case HostComponent:
10627 instanceToUse = getPublicInstance(instance);
10628 break;
10629
10630 default:
10631 instanceToUse = instance;
10632 } // Moved outside to ensure DCE works with this flag
10633
10634 if (typeof ref === 'function') {
10635 ref(instanceToUse);
10636 } else {
10637 {
10638 if (!ref.hasOwnProperty('current')) {
10639 error('Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
10640 }
10641 }
10642
10643 ref.current = instanceToUse;
10644 }
10645 }
10646}
10647
10648function commitDetachRef(current) {
10649 var currentRef = current.ref;
10650
10651 if (currentRef !== null) {
10652 if (typeof currentRef === 'function') {
10653 currentRef(null);
10654 } else {
10655 currentRef.current = null;
10656 }
10657 }
10658} // User-originating errors (lifecycles and refs) should not interrupt
10659// deletion, so don't let them throw. Host-originating errors should
10660// interrupt deletion, so it's okay
10661
10662
10663function commitUnmount(finishedRoot, current, renderPriorityLevel) {
10664 onCommitUnmount(current);
10665
10666 switch (current.tag) {
10667 case FunctionComponent:
10668 case ForwardRef:
10669 case MemoComponent:
10670 case SimpleMemoComponent:
10671 case Block:
10672 {
10673 var updateQueue = current.updateQueue;
10674
10675 if (updateQueue !== null) {
10676 var lastEffect = updateQueue.lastEffect;
10677
10678 if (lastEffect !== null) {
10679 var firstEffect = lastEffect.next;
10680
10681 {
10682 // When the owner fiber is deleted, the destroy function of a passive
10683 // effect hook is called during the synchronous commit phase. This is
10684 // a concession to implementation complexity. Calling it in the
10685 // passive effect phase (like they usually are, when dependencies
10686 // change during an update) would require either traversing the
10687 // children of the deleted fiber again, or including unmount effects
10688 // as part of the fiber effect list.
10689 //
10690 // Because this is during the sync commit phase, we need to change
10691 // the priority.
10692 //
10693 // TODO: Reconsider this implementation trade off.
10694 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
10695 runWithPriority(priorityLevel, function () {
10696 var effect = firstEffect;
10697
10698 do {
10699 var _destroy = effect.destroy;
10700
10701 if (_destroy !== undefined) {
10702 safelyCallDestroy(current, _destroy);
10703 }
10704
10705 effect = effect.next;
10706 } while (effect !== firstEffect);
10707 });
10708 }
10709 }
10710 }
10711
10712 return;
10713 }
10714
10715 case ClassComponent:
10716 {
10717 safelyDetachRef(current);
10718 var instance = current.stateNode;
10719
10720 if (typeof instance.componentWillUnmount === 'function') {
10721 safelyCallComponentWillUnmount(current, instance);
10722 }
10723
10724 return;
10725 }
10726
10727 case HostComponent:
10728 {
10729
10730 safelyDetachRef(current);
10731 return;
10732 }
10733
10734 case HostPortal:
10735 {
10736 // TODO: this is recursive.
10737 // We are also not using this parent because
10738 // the portal will get pushed immediately.
10739 {
10740 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
10741 }
10742
10743 return;
10744 }
10745
10746 case FundamentalComponent:
10747 {
10748
10749 return;
10750 }
10751
10752 case DehydratedFragment:
10753 {
10754
10755 return;
10756 }
10757
10758 case ScopeComponent:
10759 {
10760
10761 return;
10762 }
10763 }
10764}
10765
10766function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) {
10767 // While we're inside a removed host node we don't want to call
10768 // removeChild on the inner nodes because they're removed by the top
10769 // call anyway. We also want to call componentWillUnmount on all
10770 // composites before this host node is removed from the tree. Therefore
10771 // we do an inner loop while we're still inside the host node.
10772 var node = root;
10773
10774 while (true) {
10775 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because they may contain more composite or host nodes.
10776 // Skip portals because commitUnmount() currently visits them recursively.
10777
10778 if (node.child !== null && ( // If we use mutation we drill down into portals using commitUnmount above.
10779 // If we don't use mutation we drill down into portals here instead.
10780 node.tag !== HostPortal)) {
10781 node.child.return = node;
10782 node = node.child;
10783 continue;
10784 }
10785
10786 if (node === root) {
10787 return;
10788 }
10789
10790 while (node.sibling === null) {
10791 if (node.return === null || node.return === root) {
10792 return;
10793 }
10794
10795 node = node.return;
10796 }
10797
10798 node.sibling.return = node.return;
10799 node = node.sibling;
10800 }
10801}
10802
10803function detachFiber(current) {
10804 var alternate = current.alternate; // Cut off the return pointers to disconnect it from the tree. Ideally, we
10805 // should clear the child pointer of the parent alternate to let this
10806 // get GC:ed but we don't know which for sure which parent is the current
10807 // one so we'll settle for GC:ing the subtree of this child. This child
10808 // itself will be GC:ed when the parent updates the next time.
10809
10810 current.return = null;
10811 current.child = null;
10812 current.memoizedState = null;
10813 current.updateQueue = null;
10814 current.dependencies = null;
10815 current.alternate = null;
10816 current.firstEffect = null;
10817 current.lastEffect = null;
10818 current.pendingProps = null;
10819 current.memoizedProps = null;
10820 current.stateNode = null;
10821
10822 if (alternate !== null) {
10823 detachFiber(alternate);
10824 }
10825}
10826
10827function getHostParentFiber(fiber) {
10828 var parent = fiber.return;
10829
10830 while (parent !== null) {
10831 if (isHostParent(parent)) {
10832 return parent;
10833 }
10834
10835 parent = parent.return;
10836 }
10837
10838 {
10839 {
10840 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
10841 }
10842 }
10843}
10844
10845function isHostParent(fiber) {
10846 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
10847}
10848
10849function getHostSibling(fiber) {
10850 // We're going to search forward into the tree until we find a sibling host
10851 // node. Unfortunately, if multiple insertions are done in a row we have to
10852 // search past them. This leads to exponential search for the next sibling.
10853 // TODO: Find a more efficient way to do this.
10854 var node = fiber;
10855
10856 siblings: while (true) {
10857 // If we didn't find anything, let's try the next sibling.
10858 while (node.sibling === null) {
10859 if (node.return === null || isHostParent(node.return)) {
10860 // If we pop out of the root or hit the parent the fiber we are the
10861 // last sibling.
10862 return null;
10863 }
10864
10865 node = node.return;
10866 }
10867
10868 node.sibling.return = node.return;
10869 node = node.sibling;
10870
10871 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {
10872 // If it is not host node and, we might have a host node inside it.
10873 // Try to search down until we find one.
10874 if (node.effectTag & Placement) {
10875 // If we don't have a child, try the siblings instead.
10876 continue siblings;
10877 } // If we don't have a child, try the siblings instead.
10878 // We also skip portals because they are not part of this host tree.
10879
10880
10881 if (node.child === null || node.tag === HostPortal) {
10882 continue siblings;
10883 } else {
10884 node.child.return = node;
10885 node = node.child;
10886 }
10887 } // Check if this host node is stable or about to be placed.
10888
10889
10890 if (!(node.effectTag & Placement)) {
10891 // Found it!
10892 return node.stateNode;
10893 }
10894 }
10895}
10896
10897function commitPlacement(finishedWork) {
10898
10899
10900 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.
10901
10902 var parent;
10903 var isContainer;
10904 var parentStateNode = parentFiber.stateNode;
10905
10906 switch (parentFiber.tag) {
10907 case HostComponent:
10908 parent = parentStateNode;
10909 isContainer = false;
10910 break;
10911
10912 case HostRoot:
10913 parent = parentStateNode.containerInfo;
10914 isContainer = true;
10915 break;
10916
10917 case HostPortal:
10918 parent = parentStateNode.containerInfo;
10919 isContainer = true;
10920 break;
10921
10922 case FundamentalComponent:
10923
10924 // eslint-disable-next-line-no-fallthrough
10925
10926 default:
10927 {
10928 {
10929 throw Error( "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." );
10930 }
10931 }
10932
10933 }
10934
10935 if (parentFiber.effectTag & ContentReset) {
10936
10937 parentFiber.effectTag &= ~ContentReset;
10938 }
10939
10940 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
10941 // children to find all the terminal nodes.
10942
10943 if (isContainer) {
10944 insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent);
10945 } else {
10946 insertOrAppendPlacementNode(finishedWork, before, parent);
10947 }
10948}
10949
10950function insertOrAppendPlacementNodeIntoContainer(node, before, parent) {
10951 var tag = node.tag;
10952 var isHost = tag === HostComponent || tag === HostText;
10953
10954 if (isHost || enableFundamentalAPI ) {
10955 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
10956
10957 if (before) {
10958 insertInContainerBefore(parent, stateNode, before);
10959 } else {
10960 appendChildToContainer(parent, stateNode);
10961 }
10962 } else if (tag === HostPortal) ; else {
10963 var child = node.child;
10964
10965 if (child !== null) {
10966 insertOrAppendPlacementNodeIntoContainer(child, before, parent);
10967 var sibling = child.sibling;
10968
10969 while (sibling !== null) {
10970 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);
10971 sibling = sibling.sibling;
10972 }
10973 }
10974 }
10975}
10976
10977function insertOrAppendPlacementNode(node, before, parent) {
10978 var tag = node.tag;
10979 var isHost = tag === HostComponent || tag === HostText;
10980
10981 if (isHost || enableFundamentalAPI ) {
10982 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
10983
10984 if (before) {
10985 insertBefore(parent, stateNode, before);
10986 } else {
10987 appendChild(parent, stateNode);
10988 }
10989 } else if (tag === HostPortal) ; else {
10990 var child = node.child;
10991
10992 if (child !== null) {
10993 insertOrAppendPlacementNode(child, before, parent);
10994 var sibling = child.sibling;
10995
10996 while (sibling !== null) {
10997 insertOrAppendPlacementNode(sibling, before, parent);
10998 sibling = sibling.sibling;
10999 }
11000 }
11001 }
11002}
11003
11004function unmountHostComponents(finishedRoot, current, renderPriorityLevel) {
11005 // We only have the top Fiber that was deleted but we need to recurse down its
11006 // children to find all the terminal nodes.
11007 var node = current; // Each iteration, currentParent is populated with node's host parent if not
11008 // currentParentIsValid.
11009
11010 var currentParentIsValid = false; // Note: these two variables *must* always be updated together.
11011
11012 var currentParent;
11013 var currentParentIsContainer;
11014
11015 while (true) {
11016 if (!currentParentIsValid) {
11017 var parent = node.return;
11018
11019 findParent: while (true) {
11020 if (!(parent !== null)) {
11021 {
11022 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
11023 }
11024 }
11025
11026 var parentStateNode = parent.stateNode;
11027
11028 switch (parent.tag) {
11029 case HostComponent:
11030 currentParent = parentStateNode;
11031 currentParentIsContainer = false;
11032 break findParent;
11033
11034 case HostRoot:
11035 currentParent = parentStateNode.containerInfo;
11036 currentParentIsContainer = true;
11037 break findParent;
11038
11039 case HostPortal:
11040 currentParent = parentStateNode.containerInfo;
11041 currentParentIsContainer = true;
11042 break findParent;
11043
11044 }
11045
11046 parent = parent.return;
11047 }
11048
11049 currentParentIsValid = true;
11050 }
11051
11052 if (node.tag === HostComponent || node.tag === HostText) {
11053 commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the
11054 // node from the tree.
11055
11056 if (currentParentIsContainer) {
11057 removeChildFromContainer(currentParent, node.stateNode);
11058 } else {
11059 removeChild(currentParent, node.stateNode);
11060 } // Don't visit children because we already visited them.
11061
11062 } else if (node.tag === HostPortal) {
11063 if (node.child !== null) {
11064 // When we go into a portal, it becomes the parent to remove from.
11065 // We will reassign it back when we pop the portal on the way up.
11066 currentParent = node.stateNode.containerInfo;
11067 currentParentIsContainer = true; // Visit children because portals might contain host components.
11068
11069 node.child.return = node;
11070 node = node.child;
11071 continue;
11072 }
11073 } else {
11074 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because we may find more host components below.
11075
11076 if (node.child !== null) {
11077 node.child.return = node;
11078 node = node.child;
11079 continue;
11080 }
11081 }
11082
11083 if (node === current) {
11084 return;
11085 }
11086
11087 while (node.sibling === null) {
11088 if (node.return === null || node.return === current) {
11089 return;
11090 }
11091
11092 node = node.return;
11093
11094 if (node.tag === HostPortal) {
11095 // When we go out of the portal, we need to restore the parent.
11096 // Since we don't keep a stack of them, we will search for it.
11097 currentParentIsValid = false;
11098 }
11099 }
11100
11101 node.sibling.return = node.return;
11102 node = node.sibling;
11103 }
11104}
11105
11106function commitDeletion(finishedRoot, current, renderPriorityLevel) {
11107 {
11108 // Recursively delete all host nodes from the parent.
11109 // Detach refs and call componentWillUnmount() on the whole subtree.
11110 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
11111 }
11112
11113 detachFiber(current);
11114}
11115
11116function commitWork(current, finishedWork) {
11117
11118 switch (finishedWork.tag) {
11119 case FunctionComponent:
11120 case ForwardRef:
11121 case MemoComponent:
11122 case SimpleMemoComponent:
11123 case Block:
11124 {
11125 // Layout effects are destroyed during the mutation phase so that all
11126 // destroy functions for all fibers are called before any create functions.
11127 // This prevents sibling component effects from interfering with each other,
11128 // e.g. a destroy function in one component should never override a ref set
11129 // by a create function in another component during the same commit.
11130 commitHookEffectListUnmount(Layout | HasEffect, finishedWork);
11131 return;
11132 }
11133
11134 case ClassComponent:
11135 {
11136 return;
11137 }
11138
11139 case HostComponent:
11140 {
11141 var instance = finishedWork.stateNode;
11142
11143 if (instance != null) {
11144 // Commit the work prepared earlier.
11145 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
11146 // as the newProps. The updatePayload will contain the real change in
11147 // this case.
11148
11149 var oldProps = current !== null ? current.memoizedProps : newProps;
11150 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.
11151
11152 var updatePayload = finishedWork.updateQueue;
11153 finishedWork.updateQueue = null;
11154
11155 if (updatePayload !== null) {
11156 commitUpdate(instance, updatePayload, type, oldProps, newProps);
11157 }
11158 }
11159
11160 return;
11161 }
11162
11163 case HostText:
11164 {
11165 if (!(finishedWork.stateNode !== null)) {
11166 {
11167 throw Error( "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." );
11168 }
11169 }
11170
11171 var textInstance = finishedWork.stateNode;
11172 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
11173 // as the newProps. The updatePayload will contain the real change in
11174 // this case.
11175
11176 var oldText = current !== null ? current.memoizedProps : newText;
11177 commitTextUpdate(textInstance, oldText, newText);
11178 return;
11179 }
11180
11181 case HostRoot:
11182 {
11183
11184 return;
11185 }
11186
11187 case Profiler:
11188 {
11189 return;
11190 }
11191
11192 case SuspenseComponent:
11193 {
11194 commitSuspenseComponent(finishedWork);
11195 attachSuspenseRetryListeners(finishedWork);
11196 return;
11197 }
11198
11199 case SuspenseListComponent:
11200 {
11201 attachSuspenseRetryListeners(finishedWork);
11202 return;
11203 }
11204
11205 case IncompleteClassComponent:
11206 {
11207 return;
11208 }
11209 }
11210
11211 {
11212 {
11213 throw 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." );
11214 }
11215 }
11216}
11217
11218function commitSuspenseComponent(finishedWork) {
11219 var newState = finishedWork.memoizedState;
11220 var newDidTimeout;
11221 var primaryChildParent = finishedWork;
11222
11223 if (newState === null) {
11224 newDidTimeout = false;
11225 } else {
11226 newDidTimeout = true;
11227 primaryChildParent = finishedWork.child;
11228 markCommitTimeOfFallback();
11229 }
11230
11231 if ( primaryChildParent !== null) {
11232 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
11233 }
11234}
11235
11236function attachSuspenseRetryListeners(finishedWork) {
11237 // If this boundary just timed out, then it will have a set of thenables.
11238 // For each thenable, attach a listener so that when it resolves, React
11239 // attempts to re-render the boundary in the primary (pre-timeout) state.
11240 var thenables = finishedWork.updateQueue;
11241
11242 if (thenables !== null) {
11243 finishedWork.updateQueue = null;
11244 var retryCache = finishedWork.stateNode;
11245
11246 if (retryCache === null) {
11247 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
11248 }
11249
11250 thenables.forEach(function (thenable) {
11251 // Memoize using the boundary fiber to prevent redundant listeners.
11252 var retry = resolveRetryThenable.bind(null, finishedWork, thenable);
11253
11254 if (!retryCache.has(thenable)) {
11255 {
11256 if (thenable.__reactDoNotTraceInteractions !== true) {
11257 retry = tracing.unstable_wrap(retry);
11258 }
11259 }
11260
11261 retryCache.add(thenable);
11262 thenable.then(retry, retry);
11263 }
11264 });
11265 }
11266}
11267
11268function commitResetTextContent(current) {
11269
11270 resetTextContent(current.stateNode);
11271}
11272
11273var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
11274
11275function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
11276 var update = createUpdate(expirationTime, null); // Unmount the root by rendering null.
11277
11278 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
11279 // being called "element".
11280
11281 update.payload = {
11282 element: null
11283 };
11284 var error = errorInfo.value;
11285
11286 update.callback = function () {
11287 onUncaughtError(error);
11288 logError(fiber, errorInfo);
11289 };
11290
11291 return update;
11292}
11293
11294function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
11295 var update = createUpdate(expirationTime, null);
11296 update.tag = CaptureUpdate;
11297 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
11298
11299 if (typeof getDerivedStateFromError === 'function') {
11300 var error$1 = errorInfo.value;
11301
11302 update.payload = function () {
11303 logError(fiber, errorInfo);
11304 return getDerivedStateFromError(error$1);
11305 };
11306 }
11307
11308 var inst = fiber.stateNode;
11309
11310 if (inst !== null && typeof inst.componentDidCatch === 'function') {
11311 update.callback = function callback() {
11312 {
11313 markFailedErrorBoundaryForHotReloading(fiber);
11314 }
11315
11316 if (typeof getDerivedStateFromError !== 'function') {
11317 // To preserve the preexisting retry behavior of error boundaries,
11318 // we keep track of which ones already failed during this batch.
11319 // This gets reset before we yield back to the browser.
11320 // TODO: Warn in strict mode if getDerivedStateFromError is
11321 // not defined.
11322 markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined
11323
11324 logError(fiber, errorInfo);
11325 }
11326
11327 var error$1 = errorInfo.value;
11328 var stack = errorInfo.stack;
11329 this.componentDidCatch(error$1, {
11330 componentStack: stack !== null ? stack : ''
11331 });
11332
11333 {
11334 if (typeof getDerivedStateFromError !== 'function') {
11335 // If componentDidCatch is the only error boundary method defined,
11336 // then it needs to call setState to recover from errors.
11337 // If no state update is scheduled then the boundary will swallow the error.
11338 if (fiber.expirationTime !== Sync) {
11339 error('%s: Error boundaries should implement getDerivedStateFromError(). ' + 'In that method, return a state update to display an error message or fallback UI.', getComponentName(fiber.type) || 'Unknown');
11340 }
11341 }
11342 }
11343 };
11344 } else {
11345 update.callback = function () {
11346 markFailedErrorBoundaryForHotReloading(fiber);
11347 };
11348 }
11349
11350 return update;
11351}
11352
11353function attachPingListener(root, renderExpirationTime, thenable) {
11354 // Attach a listener to the promise to "ping" the root and retry. But
11355 // only if one does not already exist for the current render expiration
11356 // time (which acts like a "thread ID" here).
11357 var pingCache = root.pingCache;
11358 var threadIDs;
11359
11360 if (pingCache === null) {
11361 pingCache = root.pingCache = new PossiblyWeakMap();
11362 threadIDs = new Set();
11363 pingCache.set(thenable, threadIDs);
11364 } else {
11365 threadIDs = pingCache.get(thenable);
11366
11367 if (threadIDs === undefined) {
11368 threadIDs = new Set();
11369 pingCache.set(thenable, threadIDs);
11370 }
11371 }
11372
11373 if (!threadIDs.has(renderExpirationTime)) {
11374 // Memoize using the thread ID to prevent redundant listeners.
11375 threadIDs.add(renderExpirationTime);
11376 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
11377 thenable.then(ping, ping);
11378 }
11379}
11380
11381function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
11382 // The source fiber did not complete.
11383 sourceFiber.effectTag |= Incomplete; // Its effect list is no longer valid.
11384
11385 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
11386
11387 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
11388 // This is a thenable.
11389 var thenable = value;
11390
11391 if ((sourceFiber.mode & BlockingMode) === NoMode) {
11392 // Reset the memoizedState to what it was before we attempted
11393 // to render it.
11394 var currentSource = sourceFiber.alternate;
11395
11396 if (currentSource) {
11397 sourceFiber.updateQueue = currentSource.updateQueue;
11398 sourceFiber.memoizedState = currentSource.memoizedState;
11399 sourceFiber.expirationTime = currentSource.expirationTime;
11400 } else {
11401 sourceFiber.updateQueue = null;
11402 sourceFiber.memoizedState = null;
11403 }
11404 }
11405
11406 var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext); // Schedule the nearest Suspense to re-render the timed out view.
11407
11408 var _workInProgress = returnFiber;
11409
11410 do {
11411 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) {
11412 // Found the nearest boundary.
11413 // Stash the promise on the boundary fiber. If the boundary times out, we'll
11414 // attach another listener to flip the boundary back to its normal state.
11415 var thenables = _workInProgress.updateQueue;
11416
11417 if (thenables === null) {
11418 var updateQueue = new Set();
11419 updateQueue.add(thenable);
11420 _workInProgress.updateQueue = updateQueue;
11421 } else {
11422 thenables.add(thenable);
11423 } // If the boundary is outside of blocking mode, we should *not*
11424 // suspend the commit. Pretend as if the suspended component rendered
11425 // null and keep rendering. In the commit phase, we'll schedule a
11426 // subsequent synchronous update to re-render the Suspense.
11427 //
11428 // Note: It doesn't matter whether the component that suspended was
11429 // inside a blocking mode tree. If the Suspense is outside of it, we
11430 // should *not* suspend the commit.
11431
11432
11433 if ((_workInProgress.mode & BlockingMode) === NoMode) {
11434 _workInProgress.effectTag |= DidCapture; // We're going to commit this fiber even though it didn't complete.
11435 // But we shouldn't call any lifecycle methods or callbacks. Remove
11436 // all lifecycle effect tags.
11437
11438 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
11439
11440 if (sourceFiber.tag === ClassComponent) {
11441 var currentSourceFiber = sourceFiber.alternate;
11442
11443 if (currentSourceFiber === null) {
11444 // This is a new mount. Change the tag so it's not mistaken for a
11445 // completed class component. For example, we should not call
11446 // componentWillUnmount if it is deleted.
11447 sourceFiber.tag = IncompleteClassComponent;
11448 } else {
11449 // When we try rendering again, we should not reuse the current fiber,
11450 // since it's known to be in an inconsistent state. Use a force update to
11451 // prevent a bail out.
11452 var update = createUpdate(Sync, null);
11453 update.tag = ForceUpdate;
11454 enqueueUpdate(sourceFiber, update);
11455 }
11456 } // The source fiber did not complete. Mark it with Sync priority to
11457 // indicate that it still has pending work.
11458
11459
11460 sourceFiber.expirationTime = Sync; // Exit without suspending.
11461
11462 return;
11463 } // Confirmed that the boundary is in a concurrent mode tree. Continue
11464 // with the normal suspend path.
11465 //
11466 // After this we'll use a set of heuristics to determine whether this
11467 // render pass will run to completion or restart or "suspend" the commit.
11468 // The actual logic for this is spread out in different places.
11469 //
11470 // This first principle is that if we're going to suspend when we complete
11471 // a root, then we should also restart if we get an update or ping that
11472 // might unsuspend it, and vice versa. The only reason to suspend is
11473 // because you think you might want to restart before committing. However,
11474 // it doesn't make sense to restart only while in the period we're suspended.
11475 //
11476 // Restarting too aggressively is also not good because it starves out any
11477 // intermediate loading state. So we use heuristics to determine when.
11478 // Suspense Heuristics
11479 //
11480 // If nothing threw a Promise or all the same fallbacks are already showing,
11481 // then don't suspend/restart.
11482 //
11483 // If this is an initial render of a new tree of Suspense boundaries and
11484 // those trigger a fallback, then don't suspend/restart. We want to ensure
11485 // that we can show the initial loading state as quickly as possible.
11486 //
11487 // If we hit a "Delayed" case, such as when we'd switch from content back into
11488 // a fallback, then we should always suspend/restart. SuspenseConfig applies to
11489 // this case. If none is defined, JND is used instead.
11490 //
11491 // If we're already showing a fallback and it gets "retried", allowing us to show
11492 // another level, but there's still an inner boundary that would show a fallback,
11493 // then we suspend/restart for 500ms since the last time we showed a fallback
11494 // anywhere in the tree. This effectively throttles progressive loading into a
11495 // consistent train of commits. This also gives us an opportunity to restart to
11496 // get to the completed state slightly earlier.
11497 //
11498 // If there's ambiguity due to batching it's resolved in preference of:
11499 // 1) "delayed", 2) "initial render", 3) "retry".
11500 //
11501 // We want to ensure that a "busy" state doesn't get force committed. We want to
11502 // ensure that new initial loading states can commit as soon as possible.
11503
11504
11505 attachPingListener(root, renderExpirationTime, thenable);
11506 _workInProgress.effectTag |= ShouldCapture;
11507 _workInProgress.expirationTime = renderExpirationTime;
11508 return;
11509 } // This boundary already captured during this render. Continue to the next
11510 // boundary.
11511
11512
11513 _workInProgress = _workInProgress.return;
11514 } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode.
11515 // TODO: Use invariant so the message is stripped in prod?
11516
11517
11518 value = new Error((getComponentName(sourceFiber.type) || 'A React component') + ' suspended while rendering, but no fallback UI was specified.\n' + '\n' + 'Add a <Suspense fallback=...> component higher in the tree to ' + 'provide a loading indicator or placeholder to display.' + getStackByFiberInDevAndProd(sourceFiber));
11519 } // We didn't find a boundary that could handle this type of exception. Start
11520 // over and traverse parent path again, this time treating the exception
11521 // as an error.
11522
11523
11524 renderDidError();
11525 value = createCapturedValue(value, sourceFiber);
11526 var workInProgress = returnFiber;
11527
11528 do {
11529 switch (workInProgress.tag) {
11530 case HostRoot:
11531 {
11532 var _errorInfo = value;
11533 workInProgress.effectTag |= ShouldCapture;
11534 workInProgress.expirationTime = renderExpirationTime;
11535
11536 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
11537
11538 enqueueCapturedUpdate(workInProgress, _update);
11539 return;
11540 }
11541
11542 case ClassComponent:
11543 // Capture and retry
11544 var errorInfo = value;
11545 var ctor = workInProgress.type;
11546 var instance = workInProgress.stateNode;
11547
11548 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
11549 workInProgress.effectTag |= ShouldCapture;
11550 workInProgress.expirationTime = renderExpirationTime; // Schedule the error boundary to re-render using updated state
11551
11552 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
11553
11554 enqueueCapturedUpdate(workInProgress, _update2);
11555 return;
11556 }
11557
11558 break;
11559 }
11560
11561 workInProgress = workInProgress.return;
11562 } while (workInProgress !== null);
11563}
11564
11565var ceil = Math.ceil;
11566var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher,
11567 ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner,
11568 IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;
11569var NoContext =
11570/* */
115710;
11572var BatchedContext =
11573/* */
115741;
11575var DiscreteEventContext =
11576/* */
115774;
11578var LegacyUnbatchedContext =
11579/* */
115808;
11581var RenderContext =
11582/* */
1158316;
11584var CommitContext =
11585/* */
1158632;
11587var RootIncomplete = 0;
11588var RootFatalErrored = 1;
11589var RootErrored = 2;
11590var RootSuspended = 3;
11591var RootSuspendedWithDelay = 4;
11592var RootCompleted = 5;
11593// Describes where we are in the React execution stack
11594var executionContext = NoContext; // The root we're working on
11595
11596var workInProgressRoot = null; // The fiber we're working on
11597
11598var workInProgress = null; // The expiration time we're rendering
11599
11600var renderExpirationTime$1 = NoWork; // Whether to root completed, errored, suspended, etc.
11601
11602var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown
11603
11604var workInProgressRootFatalError = null; // Most recent event time among processed updates during this render.
11605// This is conceptually a time stamp but expressed in terms of an ExpirationTime
11606// because we deal mostly with expiration times in the hot path, so this avoids
11607// the conversion happening in the hot path.
11608
11609var workInProgressRootLatestProcessedExpirationTime = Sync;
11610var workInProgressRootLatestSuspenseTimeout = Sync;
11611var workInProgressRootCanSuspendUsingConfig = null; // The work left over by components that were visited during this render. Only
11612// includes unprocessed updates, not work in bailed out children.
11613
11614var workInProgressRootNextUnprocessedUpdateTime = NoWork; // If we're pinged while rendering we don't always restart immediately.
11615// This flag determines if it might be worthwhile to restart if an opportunity
11616// happens latere.
11617
11618var workInProgressRootHasPendingPing = false; // The most recent time we committed a fallback. This lets us ensure a train
11619// model where we don't commit new loading states in too quick succession.
11620
11621var globalMostRecentFallbackTime = 0;
11622var FALLBACK_THROTTLE_MS = 500;
11623var nextEffect = null;
11624var hasUncaughtError = false;
11625var firstUncaughtError = null;
11626var legacyErrorBoundariesThatAlreadyFailed = null;
11627var rootDoesHavePassiveEffects = false;
11628var rootWithPendingPassiveEffects = null;
11629var pendingPassiveEffectsRenderPriority = NoPriority;
11630var pendingPassiveEffectsExpirationTime = NoWork;
11631var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates
11632
11633var NESTED_UPDATE_LIMIT = 50;
11634var nestedUpdateCount = 0;
11635var rootWithNestedUpdates = null;
11636var NESTED_PASSIVE_UPDATE_LIMIT = 50;
11637var nestedPassiveUpdateCount = 0;
11638var interruptedBy = null; // Marks the need to reschedule pending interactions at these expiration times
11639// during the commit phase. This enables them to be traced across components
11640// that spawn new work during render. E.g. hidden boundaries, suspended SSR
11641// hydration or SuspenseList.
11642
11643var spawnedWorkDuringRender = null; // Expiration times are computed by adding to the current time (the start
11644// time). However, if two updates are scheduled within the same event, we
11645// should treat their start times as simultaneous, even if the actual clock
11646// time has advanced between the first and second call.
11647// In other words, because expiration times determine how updates are batched,
11648// we want all updates of like priority that occur within the same event to
11649// receive the same expiration time. Otherwise we get tearing.
11650
11651var currentEventTime = NoWork;
11652function requestCurrentTimeForUpdate() {
11653 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
11654 // We're inside React, so it's fine to read the actual time.
11655 return msToExpirationTime(now());
11656 } // We're not inside React, so we may be in the middle of a browser event.
11657
11658
11659 if (currentEventTime !== NoWork) {
11660 // Use the same start time for all updates until we enter React again.
11661 return currentEventTime;
11662 } // This is the first update since React yielded. Compute a new start time.
11663
11664
11665 currentEventTime = msToExpirationTime(now());
11666 return currentEventTime;
11667}
11668function getCurrentTime() {
11669 return msToExpirationTime(now());
11670}
11671function computeExpirationForFiber(currentTime, fiber, suspenseConfig) {
11672 var mode = fiber.mode;
11673
11674 if ((mode & BlockingMode) === NoMode) {
11675 return Sync;
11676 }
11677
11678 var priorityLevel = getCurrentPriorityLevel();
11679
11680 if ((mode & ConcurrentMode) === NoMode) {
11681 return priorityLevel === ImmediatePriority ? Sync : Batched;
11682 }
11683
11684 if ((executionContext & RenderContext) !== NoContext) {
11685 // Use whatever time we're already rendering
11686 // TODO: Should there be a way to opt out, like with `runWithPriority`?
11687 return renderExpirationTime$1;
11688 }
11689
11690 var expirationTime;
11691
11692 if (suspenseConfig !== null) {
11693 // Compute an expiration time based on the Suspense timeout.
11694 expirationTime = computeSuspenseExpiration(currentTime, suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
11695 } else {
11696 // Compute an expiration time based on the Scheduler priority.
11697 switch (priorityLevel) {
11698 case ImmediatePriority:
11699 expirationTime = Sync;
11700 break;
11701
11702 case UserBlockingPriority:
11703 // TODO: Rename this to computeUserBlockingExpiration
11704 expirationTime = computeInteractiveExpiration(currentTime);
11705 break;
11706
11707 case NormalPriority:
11708 case LowPriority:
11709 // TODO: Handle LowPriority
11710 // TODO: Rename this to... something better.
11711 expirationTime = computeAsyncExpiration(currentTime);
11712 break;
11713
11714 case IdlePriority:
11715 expirationTime = Idle;
11716 break;
11717
11718 default:
11719 {
11720 {
11721 throw Error( "Expected a valid priority level" );
11722 }
11723 }
11724
11725 }
11726 } // If we're in the middle of rendering a tree, do not update at the same
11727 // expiration time that is already rendering.
11728 // TODO: We shouldn't have to do this if the update is on a different root.
11729 // Refactor computeExpirationForFiber + scheduleUpdate so we have access to
11730 // the root when we check for this condition.
11731
11732
11733 if (workInProgressRoot !== null && expirationTime === renderExpirationTime$1) {
11734 // This is a trick to move this update into a separate batch
11735 expirationTime -= 1;
11736 }
11737
11738 return expirationTime;
11739}
11740function scheduleUpdateOnFiber(fiber, expirationTime) {
11741 checkForNestedUpdates();
11742 warnAboutRenderPhaseUpdatesInDEV(fiber);
11743 var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);
11744
11745 if (root === null) {
11746 warnAboutUpdateOnUnmountedFiberInDEV(fiber);
11747 return;
11748 }
11749
11750 checkForInterruption(fiber, expirationTime);
11751 recordScheduleUpdate(); // TODO: computeExpirationForFiber also reads the priority. Pass the
11752 // priority as an argument to that function and this one.
11753
11754 var priorityLevel = getCurrentPriorityLevel();
11755
11756 if (expirationTime === Sync) {
11757 if ( // Check if we're inside unbatchedUpdates
11758 (executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering
11759 (executionContext & (RenderContext | CommitContext)) === NoContext) {
11760 // Register pending interactions on the root to avoid losing traced interaction data.
11761 schedulePendingInteractions(root, expirationTime); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed
11762 // root inside of batchedUpdates should be synchronous, but layout updates
11763 // should be deferred until the end of the batch.
11764
11765 performSyncWorkOnRoot(root);
11766 } else {
11767 ensureRootIsScheduled(root);
11768 schedulePendingInteractions(root, expirationTime);
11769
11770 if (executionContext === NoContext) {
11771 // Flush the synchronous work now, unless we're already working or inside
11772 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
11773 // scheduleCallbackForFiber to preserve the ability to schedule a callback
11774 // without immediately flushing it. We only do this for user-initiated
11775 // updates, to preserve historical behavior of legacy mode.
11776 flushSyncCallbackQueue();
11777 }
11778 }
11779 } else {
11780 ensureRootIsScheduled(root);
11781 schedulePendingInteractions(root, expirationTime);
11782 }
11783
11784 if ((executionContext & DiscreteEventContext) !== NoContext && ( // Only updates at user-blocking priority or greater are considered
11785 // discrete, even inside a discrete event.
11786 priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority)) {
11787 // This is the result of a discrete event. Track the lowest priority
11788 // discrete update per root so we can flush them early, if needed.
11789 if (rootsWithPendingDiscreteUpdates === null) {
11790 rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);
11791 } else {
11792 var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);
11793
11794 if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {
11795 rootsWithPendingDiscreteUpdates.set(root, expirationTime);
11796 }
11797 }
11798 }
11799}
11800var scheduleWork = scheduleUpdateOnFiber; // This is split into a separate function so we can mark a fiber with pending
11801// work without treating it as a typical update that originates from an event;
11802// e.g. retrying a Suspense boundary isn't an update, but it does schedule work
11803// on a fiber.
11804
11805function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
11806 // Update the source fiber's expiration time
11807 if (fiber.expirationTime < expirationTime) {
11808 fiber.expirationTime = expirationTime;
11809 }
11810
11811 var alternate = fiber.alternate;
11812
11813 if (alternate !== null && alternate.expirationTime < expirationTime) {
11814 alternate.expirationTime = expirationTime;
11815 } // Walk the parent path to the root and update the child expiration time.
11816
11817
11818 var node = fiber.return;
11819 var root = null;
11820
11821 if (node === null && fiber.tag === HostRoot) {
11822 root = fiber.stateNode;
11823 } else {
11824 while (node !== null) {
11825 alternate = node.alternate;
11826
11827 if (node.childExpirationTime < expirationTime) {
11828 node.childExpirationTime = expirationTime;
11829
11830 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
11831 alternate.childExpirationTime = expirationTime;
11832 }
11833 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
11834 alternate.childExpirationTime = expirationTime;
11835 }
11836
11837 if (node.return === null && node.tag === HostRoot) {
11838 root = node.stateNode;
11839 break;
11840 }
11841
11842 node = node.return;
11843 }
11844 }
11845
11846 if (root !== null) {
11847 if (workInProgressRoot === root) {
11848 // Received an update to a tree that's in the middle of rendering. Mark
11849 // that's unprocessed work on this root.
11850 markUnprocessedUpdateTime(expirationTime);
11851
11852 if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
11853 // The root already suspended with a delay, which means this render
11854 // definitely won't finish. Since we have a new update, let's mark it as
11855 // suspended now, right before marking the incoming update. This has the
11856 // effect of interrupting the current render and switching to the update.
11857 // TODO: This happens to work when receiving an update during the render
11858 // phase, because of the trick inside computeExpirationForFiber to
11859 // subtract 1 from `renderExpirationTime` to move it into a
11860 // separate bucket. But we should probably model it with an exception,
11861 // using the same mechanism we use to force hydration of a subtree.
11862 // TODO: This does not account for low pri updates that were already
11863 // scheduled before the root started rendering. Need to track the next
11864 // pending expiration time (perhaps by backtracking the return path) and
11865 // then trigger a restart in the `renderDidSuspendDelayIfPossible` path.
11866 markRootSuspendedAtTime(root, renderExpirationTime$1);
11867 }
11868 } // Mark that the root has a pending update.
11869
11870
11871 markRootUpdatedAtTime(root, expirationTime);
11872 }
11873
11874 return root;
11875}
11876
11877function getNextRootExpirationTimeToWorkOn(root) {
11878 // Determines the next expiration time that the root should render, taking
11879 // into account levels that may be suspended, or levels that may have
11880 // received a ping.
11881 var lastExpiredTime = root.lastExpiredTime;
11882
11883 if (lastExpiredTime !== NoWork) {
11884 return lastExpiredTime;
11885 } // "Pending" refers to any update that hasn't committed yet, including if it
11886 // suspended. The "suspended" range is therefore a subset.
11887
11888
11889 var firstPendingTime = root.firstPendingTime;
11890
11891 if (!isRootSuspendedAtTime(root, firstPendingTime)) {
11892 // The highest priority pending time is not suspended. Let's work on that.
11893 return firstPendingTime;
11894 } // If the first pending time is suspended, check if there's a lower priority
11895 // pending level that we know about. Or check if we received a ping. Work
11896 // on whichever is higher priority.
11897
11898
11899 var lastPingedTime = root.lastPingedTime;
11900 var nextKnownPendingLevel = root.nextKnownPendingLevel;
11901 var nextLevel = lastPingedTime > nextKnownPendingLevel ? lastPingedTime : nextKnownPendingLevel;
11902
11903 if ( nextLevel <= Idle && firstPendingTime !== nextLevel) {
11904 // Don't work on Idle/Never priority unless everything else is committed.
11905 return NoWork;
11906 }
11907
11908 return nextLevel;
11909} // Use this function to schedule a task for a root. There's only one task per
11910// root; if a task was already scheduled, we'll check to make sure the
11911// expiration time of the existing task is the same as the expiration time of
11912// the next level that the root has work on. This function is called on every
11913// update, and right before exiting a task.
11914
11915
11916function ensureRootIsScheduled(root) {
11917 var lastExpiredTime = root.lastExpiredTime;
11918
11919 if (lastExpiredTime !== NoWork) {
11920 // Special case: Expired work should flush synchronously.
11921 root.callbackExpirationTime = Sync;
11922 root.callbackPriority = ImmediatePriority;
11923 root.callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
11924 return;
11925 }
11926
11927 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
11928 var existingCallbackNode = root.callbackNode;
11929
11930 if (expirationTime === NoWork) {
11931 // There's nothing to work on.
11932 if (existingCallbackNode !== null) {
11933 root.callbackNode = null;
11934 root.callbackExpirationTime = NoWork;
11935 root.callbackPriority = NoPriority;
11936 }
11937
11938 return;
11939 } // TODO: If this is an update, we already read the current time. Pass the
11940 // time as an argument.
11941
11942
11943 var currentTime = requestCurrentTimeForUpdate();
11944 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime); // If there's an existing render task, confirm it has the correct priority and
11945 // expiration time. Otherwise, we'll cancel it and schedule a new one.
11946
11947 if (existingCallbackNode !== null) {
11948 var existingCallbackPriority = root.callbackPriority;
11949 var existingCallbackExpirationTime = root.callbackExpirationTime;
11950
11951 if ( // Callback must have the exact same expiration time.
11952 existingCallbackExpirationTime === expirationTime && // Callback must have greater or equal priority.
11953 existingCallbackPriority >= priorityLevel) {
11954 // Existing callback is sufficient.
11955 return;
11956 } // Need to schedule a new task.
11957 // TODO: Instead of scheduling a new task, we should be able to change the
11958 // priority of the existing one.
11959
11960
11961 cancelCallback(existingCallbackNode);
11962 }
11963
11964 root.callbackExpirationTime = expirationTime;
11965 root.callbackPriority = priorityLevel;
11966 var callbackNode;
11967
11968 if (expirationTime === Sync) {
11969 // Sync React callbacks are scheduled on a special internal queue
11970 callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
11971 } else {
11972 callbackNode = scheduleCallback(priorityLevel, performConcurrentWorkOnRoot.bind(null, root), // Compute a task timeout based on the expiration time. This also affects
11973 // ordering because tasks are processed in timeout order.
11974 {
11975 timeout: expirationTimeToMs(expirationTime) - now()
11976 });
11977 }
11978
11979 root.callbackNode = callbackNode;
11980} // This is the entry point for every concurrent task, i.e. anything that
11981// goes through Scheduler.
11982
11983
11984function performConcurrentWorkOnRoot(root, didTimeout) {
11985 // Since we know we're in a React event, we can clear the current
11986 // event time. The next update will compute a new event time.
11987 currentEventTime = NoWork;
11988
11989 if (didTimeout) {
11990 // The render task took too long to complete. Mark the current time as
11991 // expired to synchronously render all expired work in a single batch.
11992 var currentTime = requestCurrentTimeForUpdate();
11993 markRootExpiredAtTime(root, currentTime); // This will schedule a synchronous callback.
11994
11995 ensureRootIsScheduled(root);
11996 return null;
11997 } // Determine the next expiration time to work on, using the fields stored
11998 // on the root.
11999
12000
12001 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
12002
12003 if (expirationTime !== NoWork) {
12004 var originalCallbackNode = root.callbackNode;
12005
12006 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
12007 {
12008 throw Error( "Should not already be working." );
12009 }
12010 }
12011
12012 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
12013 // and prepare a fresh one. Otherwise we'll continue where we left off.
12014
12015 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) {
12016 prepareFreshStack(root, expirationTime);
12017 startWorkOnPendingInteractions(root, expirationTime);
12018 } // If we have a work-in-progress fiber, it means there's still work to do
12019 // in this root.
12020
12021
12022 if (workInProgress !== null) {
12023 var prevExecutionContext = executionContext;
12024 executionContext |= RenderContext;
12025 var prevDispatcher = pushDispatcher();
12026 var prevInteractions = pushInteractions(root);
12027 startWorkLoopTimer(workInProgress);
12028
12029 do {
12030 try {
12031 workLoopConcurrent();
12032 break;
12033 } catch (thrownValue) {
12034 handleError(root, thrownValue);
12035 }
12036 } while (true);
12037
12038 resetContextDependencies();
12039 executionContext = prevExecutionContext;
12040 popDispatcher(prevDispatcher);
12041
12042 {
12043 popInteractions(prevInteractions);
12044 }
12045
12046 if (workInProgressRootExitStatus === RootFatalErrored) {
12047 var fatalError = workInProgressRootFatalError;
12048 stopInterruptedWorkLoopTimer();
12049 prepareFreshStack(root, expirationTime);
12050 markRootSuspendedAtTime(root, expirationTime);
12051 ensureRootIsScheduled(root);
12052 throw fatalError;
12053 }
12054
12055 if (workInProgress !== null) {
12056 // There's still work left over. Exit without committing.
12057 stopInterruptedWorkLoopTimer();
12058 } else {
12059 // We now have a consistent tree. The next step is either to commit it,
12060 // or, if something suspended, wait to commit it after a timeout.
12061 stopFinishedWorkLoopTimer();
12062 var finishedWork = root.finishedWork = root.current.alternate;
12063 root.finishedExpirationTime = expirationTime;
12064 finishConcurrentRender(root, finishedWork, workInProgressRootExitStatus, expirationTime);
12065 }
12066
12067 ensureRootIsScheduled(root);
12068
12069 if (root.callbackNode === originalCallbackNode) {
12070 // The task node scheduled for this root is the same one that's
12071 // currently executed. Need to return a continuation.
12072 return performConcurrentWorkOnRoot.bind(null, root);
12073 }
12074 }
12075 }
12076
12077 return null;
12078}
12079
12080function finishConcurrentRender(root, finishedWork, exitStatus, expirationTime) {
12081 // Set this to null to indicate there's no in-progress render.
12082 workInProgressRoot = null;
12083
12084 switch (exitStatus) {
12085 case RootIncomplete:
12086 case RootFatalErrored:
12087 {
12088 {
12089 {
12090 throw Error( "Root did not complete. This is a bug in React." );
12091 }
12092 }
12093 }
12094 // Flow knows about invariant, so it complains if I add a break
12095 // statement, but eslint doesn't know about invariant, so it complains
12096 // if I do. eslint-disable-next-line no-fallthrough
12097
12098 case RootErrored:
12099 {
12100 // If this was an async render, the error may have happened due to
12101 // a mutation in a concurrent event. Try rendering one more time,
12102 // synchronously, to see if the error goes away. If there are
12103 // lower priority updates, let's include those, too, in case they
12104 // fix the inconsistency. Render at Idle to include all updates.
12105 // If it was Idle or Never or some not-yet-invented time, render
12106 // at that time.
12107 markRootExpiredAtTime(root, expirationTime > Idle ? Idle : expirationTime); // We assume that this second render pass will be synchronous
12108 // and therefore not hit this path again.
12109
12110 break;
12111 }
12112
12113 case RootSuspended:
12114 {
12115 markRootSuspendedAtTime(root, expirationTime);
12116 var lastSuspendedTime = root.lastSuspendedTime;
12117
12118 if (expirationTime === lastSuspendedTime) {
12119 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
12120 } // We have an acceptable loading state. We need to figure out if we
12121 // should immediately commit it or wait a bit.
12122 // If we have processed new updates during this render, we may now
12123 // have a new loading state ready. We want to ensure that we commit
12124 // that as soon as possible.
12125
12126
12127 var hasNotProcessedNewUpdates = workInProgressRootLatestProcessedExpirationTime === Sync;
12128
12129 if (hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope
12130 !( IsThisRendererActing.current)) {
12131 // If we have not processed any new updates during this pass, then
12132 // this is either a retry of an existing fallback state or a
12133 // hidden tree. Hidden trees shouldn't be batched with other work
12134 // and after that's fixed it can only be a retry. We're going to
12135 // throttle committing retries so that we don't show too many
12136 // loading states too quickly.
12137 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.
12138
12139 if (msUntilTimeout > 10) {
12140 if (workInProgressRootHasPendingPing) {
12141 var lastPingedTime = root.lastPingedTime;
12142
12143 if (lastPingedTime === NoWork || lastPingedTime >= expirationTime) {
12144 // This render was pinged but we didn't get to restart
12145 // earlier so try restarting now instead.
12146 root.lastPingedTime = expirationTime;
12147 prepareFreshStack(root, expirationTime);
12148 break;
12149 }
12150 }
12151
12152 var nextTime = getNextRootExpirationTimeToWorkOn(root);
12153
12154 if (nextTime !== NoWork && nextTime !== expirationTime) {
12155 // There's additional work on this root.
12156 break;
12157 }
12158
12159 if (lastSuspendedTime !== NoWork && lastSuspendedTime !== expirationTime) {
12160 // We should prefer to render the fallback of at the last
12161 // suspended level. Ping the last suspended level to try
12162 // rendering it again.
12163 root.lastPingedTime = lastSuspendedTime;
12164 break;
12165 } // The render is suspended, it hasn't timed out, and there's no
12166 // lower priority work to do. Instead of committing the fallback
12167 // immediately, wait for more data to arrive.
12168
12169
12170 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);
12171 break;
12172 }
12173 } // The work expired. Commit immediately.
12174
12175
12176 commitRoot(root);
12177 break;
12178 }
12179
12180 case RootSuspendedWithDelay:
12181 {
12182 markRootSuspendedAtTime(root, expirationTime);
12183 var _lastSuspendedTime = root.lastSuspendedTime;
12184
12185 if (expirationTime === _lastSuspendedTime) {
12186 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
12187 }
12188
12189 if ( // do not delay if we're inside an act() scope
12190 !( IsThisRendererActing.current)) {
12191 // We're suspended in a state that should be avoided. We'll try to
12192 // avoid committing it for as long as the timeouts let us.
12193 if (workInProgressRootHasPendingPing) {
12194 var _lastPingedTime = root.lastPingedTime;
12195
12196 if (_lastPingedTime === NoWork || _lastPingedTime >= expirationTime) {
12197 // This render was pinged but we didn't get to restart earlier
12198 // so try restarting now instead.
12199 root.lastPingedTime = expirationTime;
12200 prepareFreshStack(root, expirationTime);
12201 break;
12202 }
12203 }
12204
12205 var _nextTime = getNextRootExpirationTimeToWorkOn(root);
12206
12207 if (_nextTime !== NoWork && _nextTime !== expirationTime) {
12208 // There's additional work on this root.
12209 break;
12210 }
12211
12212 if (_lastSuspendedTime !== NoWork && _lastSuspendedTime !== expirationTime) {
12213 // We should prefer to render the fallback of at the last
12214 // suspended level. Ping the last suspended level to try
12215 // rendering it again.
12216 root.lastPingedTime = _lastSuspendedTime;
12217 break;
12218 }
12219
12220 var _msUntilTimeout;
12221
12222 if (workInProgressRootLatestSuspenseTimeout !== Sync) {
12223 // We have processed a suspense config whose expiration time we
12224 // can use as the timeout.
12225 _msUntilTimeout = expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now();
12226 } else if (workInProgressRootLatestProcessedExpirationTime === Sync) {
12227 // This should never normally happen because only new updates
12228 // cause delayed states, so we should have processed something.
12229 // However, this could also happen in an offscreen tree.
12230 _msUntilTimeout = 0;
12231 } else {
12232 // If we don't have a suspense config, we're going to use a
12233 // heuristic to determine how long we can suspend.
12234 var eventTimeMs = inferTimeFromExpirationTime(workInProgressRootLatestProcessedExpirationTime);
12235 var currentTimeMs = now();
12236 var timeUntilExpirationMs = expirationTimeToMs(expirationTime) - currentTimeMs;
12237 var timeElapsed = currentTimeMs - eventTimeMs;
12238
12239 if (timeElapsed < 0) {
12240 // We get this wrong some time since we estimate the time.
12241 timeElapsed = 0;
12242 }
12243
12244 _msUntilTimeout = jnd(timeElapsed) - timeElapsed; // Clamp the timeout to the expiration time. TODO: Once the
12245 // event time is exact instead of inferred from expiration time
12246 // we don't need this.
12247
12248 if (timeUntilExpirationMs < _msUntilTimeout) {
12249 _msUntilTimeout = timeUntilExpirationMs;
12250 }
12251 } // Don't bother with a very short suspense time.
12252
12253
12254 if (_msUntilTimeout > 10) {
12255 // The render is suspended, it hasn't timed out, and there's no
12256 // lower priority work to do. Instead of committing the fallback
12257 // immediately, wait for more data to arrive.
12258 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);
12259 break;
12260 }
12261 } // The work expired. Commit immediately.
12262
12263
12264 commitRoot(root);
12265 break;
12266 }
12267
12268 case RootCompleted:
12269 {
12270 // The work completed. Ready to commit.
12271 if ( // do not delay if we're inside an act() scope
12272 !( IsThisRendererActing.current) && workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null) {
12273 // If we have exceeded the minimum loading delay, which probably
12274 // means we have shown a spinner already, we might have to suspend
12275 // a bit longer to ensure that the spinner is shown for
12276 // enough time.
12277 var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay(workInProgressRootLatestProcessedExpirationTime, expirationTime, workInProgressRootCanSuspendUsingConfig);
12278
12279 if (_msUntilTimeout2 > 10) {
12280 markRootSuspendedAtTime(root, expirationTime);
12281 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout2);
12282 break;
12283 }
12284 }
12285
12286 commitRoot(root);
12287 break;
12288 }
12289
12290 default:
12291 {
12292 {
12293 {
12294 throw Error( "Unknown root exit status." );
12295 }
12296 }
12297 }
12298 }
12299} // This is the entry point for synchronous tasks that don't go
12300// through Scheduler
12301
12302
12303function performSyncWorkOnRoot(root) {
12304 // Check if there's expired work on this root. Otherwise, render at Sync.
12305 var lastExpiredTime = root.lastExpiredTime;
12306 var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync;
12307
12308 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
12309 {
12310 throw Error( "Should not already be working." );
12311 }
12312 }
12313
12314 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
12315 // and prepare a fresh one. Otherwise we'll continue where we left off.
12316
12317 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) {
12318 prepareFreshStack(root, expirationTime);
12319 startWorkOnPendingInteractions(root, expirationTime);
12320 } // If we have a work-in-progress fiber, it means there's still work to do
12321 // in this root.
12322
12323
12324 if (workInProgress !== null) {
12325 var prevExecutionContext = executionContext;
12326 executionContext |= RenderContext;
12327 var prevDispatcher = pushDispatcher();
12328 var prevInteractions = pushInteractions(root);
12329 startWorkLoopTimer(workInProgress);
12330
12331 do {
12332 try {
12333 workLoopSync();
12334 break;
12335 } catch (thrownValue) {
12336 handleError(root, thrownValue);
12337 }
12338 } while (true);
12339
12340 resetContextDependencies();
12341 executionContext = prevExecutionContext;
12342 popDispatcher(prevDispatcher);
12343
12344 {
12345 popInteractions(prevInteractions);
12346 }
12347
12348 if (workInProgressRootExitStatus === RootFatalErrored) {
12349 var fatalError = workInProgressRootFatalError;
12350 stopInterruptedWorkLoopTimer();
12351 prepareFreshStack(root, expirationTime);
12352 markRootSuspendedAtTime(root, expirationTime);
12353 ensureRootIsScheduled(root);
12354 throw fatalError;
12355 }
12356
12357 if (workInProgress !== null) {
12358 // This is a sync render, so we should have finished the whole tree.
12359 {
12360 {
12361 throw Error( "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." );
12362 }
12363 }
12364 } else {
12365 // We now have a consistent tree. Because this is a sync render, we
12366 // will commit it even if something suspended.
12367 stopFinishedWorkLoopTimer();
12368 root.finishedWork = root.current.alternate;
12369 root.finishedExpirationTime = expirationTime;
12370 finishSyncRender(root);
12371 } // Before exiting, make sure there's a callback scheduled for the next
12372 // pending level.
12373
12374
12375 ensureRootIsScheduled(root);
12376 }
12377
12378 return null;
12379}
12380
12381function finishSyncRender(root) {
12382 // Set this to null to indicate there's no in-progress render.
12383 workInProgressRoot = null;
12384 commitRoot(root);
12385}
12386function syncUpdates(fn, a, b, c) {
12387 return runWithPriority(ImmediatePriority, fn.bind(null, a, b, c));
12388}
12389
12390function batchedUpdates(fn, a) {
12391 var prevExecutionContext = executionContext;
12392 executionContext |= BatchedContext;
12393
12394 try {
12395 return fn(a);
12396 } finally {
12397 executionContext = prevExecutionContext;
12398
12399 if (executionContext === NoContext) {
12400 // Flush the immediate callbacks that were scheduled during this batch
12401 flushSyncCallbackQueue();
12402 }
12403 }
12404}
12405function flushSync(fn, a) {
12406 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
12407 {
12408 {
12409 throw Error( "flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering." );
12410 }
12411 }
12412 }
12413
12414 var prevExecutionContext = executionContext;
12415 executionContext |= BatchedContext;
12416
12417 try {
12418 return runWithPriority(ImmediatePriority, fn.bind(null, a));
12419 } finally {
12420 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
12421 // Note that this will happen even if batchedUpdates is higher up
12422 // the stack.
12423
12424 flushSyncCallbackQueue();
12425 }
12426}
12427
12428function prepareFreshStack(root, expirationTime) {
12429 root.finishedWork = null;
12430 root.finishedExpirationTime = NoWork;
12431 var timeoutHandle = root.timeoutHandle;
12432
12433 if (timeoutHandle !== noTimeout) {
12434 // The root previous suspended and scheduled a timeout to commit a fallback
12435 // state. Now that we have additional work, cancel the timeout.
12436 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
12437
12438 cancelTimeout(timeoutHandle);
12439 }
12440
12441 if (workInProgress !== null) {
12442 var interruptedWork = workInProgress.return;
12443
12444 while (interruptedWork !== null) {
12445 unwindInterruptedWork(interruptedWork);
12446 interruptedWork = interruptedWork.return;
12447 }
12448 }
12449
12450 workInProgressRoot = root;
12451 workInProgress = createWorkInProgress(root.current, null);
12452 renderExpirationTime$1 = expirationTime;
12453 workInProgressRootExitStatus = RootIncomplete;
12454 workInProgressRootFatalError = null;
12455 workInProgressRootLatestProcessedExpirationTime = Sync;
12456 workInProgressRootLatestSuspenseTimeout = Sync;
12457 workInProgressRootCanSuspendUsingConfig = null;
12458 workInProgressRootNextUnprocessedUpdateTime = NoWork;
12459 workInProgressRootHasPendingPing = false;
12460
12461 {
12462 spawnedWorkDuringRender = null;
12463 }
12464
12465 {
12466 ReactStrictModeWarnings.discardPendingWarnings();
12467 }
12468}
12469
12470function handleError(root, thrownValue) {
12471 do {
12472 try {
12473 // Reset module-level state that was set during the render phase.
12474 resetContextDependencies();
12475 resetHooksAfterThrow();
12476 resetCurrentFiber();
12477
12478 if (workInProgress === null || workInProgress.return === null) {
12479 // Expected to be working on a non-root fiber. This is a fatal error
12480 // because there's no ancestor that can handle it; the root is
12481 // supposed to capture all errors that weren't caught by an error
12482 // boundary.
12483 workInProgressRootExitStatus = RootFatalErrored;
12484 workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next
12485 // sibling, or the parent if there are no siblings. But since the root
12486 // has no siblings nor a parent, we set it to null. Usually this is
12487 // handled by `completeUnitOfWork` or `unwindWork`, but since we're
12488 // interntionally not calling those, we need set it here.
12489 // TODO: Consider calling `unwindWork` to pop the contexts.
12490
12491 workInProgress = null;
12492 return null;
12493 }
12494
12495 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
12496 // Record the time spent rendering before an error was thrown. This
12497 // avoids inaccurate Profiler durations in the case of a
12498 // suspended render.
12499 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
12500 }
12501
12502 throwException(root, workInProgress.return, workInProgress, thrownValue, renderExpirationTime$1);
12503 workInProgress = completeUnitOfWork(workInProgress);
12504 } catch (yetAnotherThrownValue) {
12505 // Something in the return path also threw.
12506 thrownValue = yetAnotherThrownValue;
12507 continue;
12508 } // Return to the normal work loop.
12509
12510
12511 return;
12512 } while (true);
12513}
12514
12515function pushDispatcher(root) {
12516 var prevDispatcher = ReactCurrentDispatcher$1.current;
12517 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
12518
12519 if (prevDispatcher === null) {
12520 // The React isomorphic package does not include a default dispatcher.
12521 // Instead the first renderer will lazily attach one, in order to give
12522 // nicer error messages.
12523 return ContextOnlyDispatcher;
12524 } else {
12525 return prevDispatcher;
12526 }
12527}
12528
12529function popDispatcher(prevDispatcher) {
12530 ReactCurrentDispatcher$1.current = prevDispatcher;
12531}
12532
12533function pushInteractions(root) {
12534 {
12535 var prevInteractions = tracing.__interactionsRef.current;
12536 tracing.__interactionsRef.current = root.memoizedInteractions;
12537 return prevInteractions;
12538 }
12539}
12540
12541function popInteractions(prevInteractions) {
12542 {
12543 tracing.__interactionsRef.current = prevInteractions;
12544 }
12545}
12546
12547function markCommitTimeOfFallback() {
12548 globalMostRecentFallbackTime = now();
12549}
12550function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) {
12551 if (expirationTime < workInProgressRootLatestProcessedExpirationTime && expirationTime > Idle) {
12552 workInProgressRootLatestProcessedExpirationTime = expirationTime;
12553 }
12554
12555 if (suspenseConfig !== null) {
12556 if (expirationTime < workInProgressRootLatestSuspenseTimeout && expirationTime > Idle) {
12557 workInProgressRootLatestSuspenseTimeout = expirationTime; // Most of the time we only have one config and getting wrong is not bad.
12558
12559 workInProgressRootCanSuspendUsingConfig = suspenseConfig;
12560 }
12561 }
12562}
12563function markUnprocessedUpdateTime(expirationTime) {
12564 if (expirationTime > workInProgressRootNextUnprocessedUpdateTime) {
12565 workInProgressRootNextUnprocessedUpdateTime = expirationTime;
12566 }
12567}
12568function renderDidSuspend() {
12569 if (workInProgressRootExitStatus === RootIncomplete) {
12570 workInProgressRootExitStatus = RootSuspended;
12571 }
12572}
12573function renderDidSuspendDelayIfPossible() {
12574 if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {
12575 workInProgressRootExitStatus = RootSuspendedWithDelay;
12576 } // Check if there's a lower priority update somewhere else in the tree.
12577
12578
12579 if (workInProgressRootNextUnprocessedUpdateTime !== NoWork && workInProgressRoot !== null) {
12580 // Mark the current render as suspended, and then mark that there's a
12581 // pending update.
12582 // TODO: This should immediately interrupt the current render, instead
12583 // of waiting until the next time we yield.
12584 markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime$1);
12585 markRootUpdatedAtTime(workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime);
12586 }
12587}
12588function renderDidError() {
12589 if (workInProgressRootExitStatus !== RootCompleted) {
12590 workInProgressRootExitStatus = RootErrored;
12591 }
12592} // Called during render to determine if anything has suspended.
12593// Returns false if we're not sure.
12594
12595function renderHasNotSuspendedYet() {
12596 // If something errored or completed, we can't really be sure,
12597 // so those are false.
12598 return workInProgressRootExitStatus === RootIncomplete;
12599}
12600
12601function inferTimeFromExpirationTime(expirationTime) {
12602 // We don't know exactly when the update was scheduled, but we can infer an
12603 // approximate start time from the expiration time.
12604 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
12605 return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
12606}
12607
12608function inferTimeFromExpirationTimeWithSuspenseConfig(expirationTime, suspenseConfig) {
12609 // We don't know exactly when the update was scheduled, but we can infer an
12610 // approximate start time from the expiration time by subtracting the timeout
12611 // that was added to the event time.
12612 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
12613 return earliestExpirationTimeMs - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
12614} // The work loop is an extremely hot path. Tell Closure not to inline it.
12615
12616/** @noinline */
12617
12618
12619function workLoopSync() {
12620 // Already timed out, so perform work without checking if we need to yield.
12621 while (workInProgress !== null) {
12622 workInProgress = performUnitOfWork(workInProgress);
12623 }
12624}
12625/** @noinline */
12626
12627
12628function workLoopConcurrent() {
12629 // Perform work until Scheduler asks us to yield
12630 while (workInProgress !== null && !shouldYield()) {
12631 workInProgress = performUnitOfWork(workInProgress);
12632 }
12633}
12634
12635function performUnitOfWork(unitOfWork) {
12636 // The current, flushed, state of this fiber is the alternate. Ideally
12637 // nothing should rely on this, but relying on it here means that we don't
12638 // need an additional field on the work in progress.
12639 var current = unitOfWork.alternate;
12640 startWorkTimer(unitOfWork);
12641 setCurrentFiber(unitOfWork);
12642 var next;
12643
12644 if ( (unitOfWork.mode & ProfileMode) !== NoMode) {
12645 startProfilerTimer(unitOfWork);
12646 next = beginWork$1(current, unitOfWork, renderExpirationTime$1);
12647 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
12648 } else {
12649 next = beginWork$1(current, unitOfWork, renderExpirationTime$1);
12650 }
12651
12652 resetCurrentFiber();
12653 unitOfWork.memoizedProps = unitOfWork.pendingProps;
12654
12655 if (next === null) {
12656 // If this doesn't spawn new work, complete the current work.
12657 next = completeUnitOfWork(unitOfWork);
12658 }
12659
12660 ReactCurrentOwner$2.current = null;
12661 return next;
12662}
12663
12664function completeUnitOfWork(unitOfWork) {
12665 // Attempt to complete the current unit of work, then move to the next
12666 // sibling. If there are no more siblings, return to the parent fiber.
12667 workInProgress = unitOfWork;
12668
12669 do {
12670 // The current, flushed, state of this fiber is the alternate. Ideally
12671 // nothing should rely on this, but relying on it here means that we don't
12672 // need an additional field on the work in progress.
12673 var current = workInProgress.alternate;
12674 var returnFiber = workInProgress.return; // Check if the work completed or if something threw.
12675
12676 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
12677 setCurrentFiber(workInProgress);
12678 var next = void 0;
12679
12680 if ( (workInProgress.mode & ProfileMode) === NoMode) {
12681 next = completeWork(current, workInProgress, renderExpirationTime$1);
12682 } else {
12683 startProfilerTimer(workInProgress);
12684 next = completeWork(current, workInProgress, renderExpirationTime$1); // Update render duration assuming we didn't error.
12685
12686 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
12687 }
12688
12689 stopWorkTimer(workInProgress);
12690 resetCurrentFiber();
12691 resetChildExpirationTime(workInProgress);
12692
12693 if (next !== null) {
12694 // Completing this fiber spawned new work. Work on that next.
12695 return next;
12696 }
12697
12698 if (returnFiber !== null && // Do not append effects to parents if a sibling failed to complete
12699 (returnFiber.effectTag & Incomplete) === NoEffect) {
12700 // Append all the effects of the subtree and this fiber onto the effect
12701 // list of the parent. The completion order of the children affects the
12702 // side-effect order.
12703 if (returnFiber.firstEffect === null) {
12704 returnFiber.firstEffect = workInProgress.firstEffect;
12705 }
12706
12707 if (workInProgress.lastEffect !== null) {
12708 if (returnFiber.lastEffect !== null) {
12709 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
12710 }
12711
12712 returnFiber.lastEffect = workInProgress.lastEffect;
12713 } // If this fiber had side-effects, we append it AFTER the children's
12714 // side-effects. We can perform certain side-effects earlier if needed,
12715 // by doing multiple passes over the effect list. We don't want to
12716 // schedule our own side-effect on our own list because if end up
12717 // reusing children we'll schedule this effect onto itself since we're
12718 // at the end.
12719
12720
12721 var effectTag = workInProgress.effectTag; // Skip both NoWork and PerformedWork tags when creating the effect
12722 // list. PerformedWork effect is read by React DevTools but shouldn't be
12723 // committed.
12724
12725 if (effectTag > PerformedWork) {
12726 if (returnFiber.lastEffect !== null) {
12727 returnFiber.lastEffect.nextEffect = workInProgress;
12728 } else {
12729 returnFiber.firstEffect = workInProgress;
12730 }
12731
12732 returnFiber.lastEffect = workInProgress;
12733 }
12734 }
12735 } else {
12736 // This fiber did not complete because something threw. Pop values off
12737 // the stack without entering the complete phase. If this is a boundary,
12738 // capture values if possible.
12739 var _next = unwindWork(workInProgress); // Because this fiber did not complete, don't reset its expiration time.
12740
12741
12742 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
12743 // Record the render duration for the fiber that errored.
12744 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); // Include the time spent working on failed children before continuing.
12745
12746 var actualDuration = workInProgress.actualDuration;
12747 var child = workInProgress.child;
12748
12749 while (child !== null) {
12750 actualDuration += child.actualDuration;
12751 child = child.sibling;
12752 }
12753
12754 workInProgress.actualDuration = actualDuration;
12755 }
12756
12757 if (_next !== null) {
12758 // If completing this work spawned new work, do that next. We'll come
12759 // back here again.
12760 // Since we're restarting, remove anything that is not a host effect
12761 // from the effect tag.
12762 // TODO: The name stopFailedWorkTimer is misleading because Suspense
12763 // also captures and restarts.
12764 stopFailedWorkTimer(workInProgress);
12765 _next.effectTag &= HostEffectMask;
12766 return _next;
12767 }
12768
12769 stopWorkTimer(workInProgress);
12770
12771 if (returnFiber !== null) {
12772 // Mark the parent fiber as incomplete and clear its effect list.
12773 returnFiber.firstEffect = returnFiber.lastEffect = null;
12774 returnFiber.effectTag |= Incomplete;
12775 }
12776 }
12777
12778 var siblingFiber = workInProgress.sibling;
12779
12780 if (siblingFiber !== null) {
12781 // If there is more work to do in this returnFiber, do that next.
12782 return siblingFiber;
12783 } // Otherwise, return to the parent
12784
12785
12786 workInProgress = returnFiber;
12787 } while (workInProgress !== null); // We've reached the root.
12788
12789
12790 if (workInProgressRootExitStatus === RootIncomplete) {
12791 workInProgressRootExitStatus = RootCompleted;
12792 }
12793
12794 return null;
12795}
12796
12797function getRemainingExpirationTime(fiber) {
12798 var updateExpirationTime = fiber.expirationTime;
12799 var childExpirationTime = fiber.childExpirationTime;
12800 return updateExpirationTime > childExpirationTime ? updateExpirationTime : childExpirationTime;
12801}
12802
12803function resetChildExpirationTime(completedWork) {
12804 if (renderExpirationTime$1 !== Never && completedWork.childExpirationTime === Never) {
12805 // The children of this component are hidden. Don't bubble their
12806 // expiration times.
12807 return;
12808 }
12809
12810 var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time.
12811
12812 if ( (completedWork.mode & ProfileMode) !== NoMode) {
12813 // In profiling mode, resetChildExpirationTime is also used to reset
12814 // profiler durations.
12815 var actualDuration = completedWork.actualDuration;
12816 var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will
12817 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
12818 // When work is done, it should bubble to the parent's actualDuration. If
12819 // the fiber has not been cloned though, (meaning no work was done), then
12820 // this value will reflect the amount of time spent working on a previous
12821 // render. In that case it should not bubble. We determine whether it was
12822 // cloned by comparing the child pointer.
12823
12824 var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;
12825 var child = completedWork.child;
12826
12827 while (child !== null) {
12828 var childUpdateExpirationTime = child.expirationTime;
12829 var childChildExpirationTime = child.childExpirationTime;
12830
12831 if (childUpdateExpirationTime > newChildExpirationTime) {
12832 newChildExpirationTime = childUpdateExpirationTime;
12833 }
12834
12835 if (childChildExpirationTime > newChildExpirationTime) {
12836 newChildExpirationTime = childChildExpirationTime;
12837 }
12838
12839 if (shouldBubbleActualDurations) {
12840 actualDuration += child.actualDuration;
12841 }
12842
12843 treeBaseDuration += child.treeBaseDuration;
12844 child = child.sibling;
12845 }
12846
12847 completedWork.actualDuration = actualDuration;
12848 completedWork.treeBaseDuration = treeBaseDuration;
12849 } else {
12850 var _child = completedWork.child;
12851
12852 while (_child !== null) {
12853 var _childUpdateExpirationTime = _child.expirationTime;
12854 var _childChildExpirationTime = _child.childExpirationTime;
12855
12856 if (_childUpdateExpirationTime > newChildExpirationTime) {
12857 newChildExpirationTime = _childUpdateExpirationTime;
12858 }
12859
12860 if (_childChildExpirationTime > newChildExpirationTime) {
12861 newChildExpirationTime = _childChildExpirationTime;
12862 }
12863
12864 _child = _child.sibling;
12865 }
12866 }
12867
12868 completedWork.childExpirationTime = newChildExpirationTime;
12869}
12870
12871function commitRoot(root) {
12872 var renderPriorityLevel = getCurrentPriorityLevel();
12873 runWithPriority(ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel));
12874 return null;
12875}
12876
12877function commitRootImpl(root, renderPriorityLevel) {
12878 do {
12879 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which
12880 // means `flushPassiveEffects` will sometimes result in additional
12881 // passive effects. So we need to keep flushing in a loop until there are
12882 // no more pending effects.
12883 // TODO: Might be better if `flushPassiveEffects` did not automatically
12884 // flush synchronous work at the end, to avoid factoring hazards like this.
12885 flushPassiveEffects();
12886 } while (rootWithPendingPassiveEffects !== null);
12887
12888 flushRenderPhaseStrictModeWarningsInDEV();
12889
12890 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
12891 {
12892 throw Error( "Should not already be working." );
12893 }
12894 }
12895
12896 var finishedWork = root.finishedWork;
12897 var expirationTime = root.finishedExpirationTime;
12898
12899 if (finishedWork === null) {
12900 return null;
12901 }
12902
12903 root.finishedWork = null;
12904 root.finishedExpirationTime = NoWork;
12905
12906 if (!(finishedWork !== root.current)) {
12907 {
12908 throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." );
12909 }
12910 } // commitRoot never returns a continuation; it always finishes synchronously.
12911 // So we can clear these now to allow a new callback to be scheduled.
12912
12913
12914 root.callbackNode = null;
12915 root.callbackExpirationTime = NoWork;
12916 root.callbackPriority = NoPriority;
12917 root.nextKnownPendingLevel = NoWork;
12918 startCommitTimer(); // Update the first and last pending times on this root. The new first
12919 // pending time is whatever is left on the root fiber.
12920
12921 var remainingExpirationTimeBeforeCommit = getRemainingExpirationTime(finishedWork);
12922 markRootFinishedAtTime(root, expirationTime, remainingExpirationTimeBeforeCommit);
12923
12924 if (root === workInProgressRoot) {
12925 // We can reset these now that they are finished.
12926 workInProgressRoot = null;
12927 workInProgress = null;
12928 renderExpirationTime$1 = NoWork;
12929 } // This indicates that the last root we worked on is not the same one that
12930 // we're committing now. This most commonly happens when a suspended root
12931 // times out.
12932 // Get the list of effects.
12933
12934
12935 var firstEffect;
12936
12937 if (finishedWork.effectTag > PerformedWork) {
12938 // A fiber's effect list consists only of its children, not itself. So if
12939 // the root has an effect, we need to add it to the end of the list. The
12940 // resulting list is the set that would belong to the root's parent, if it
12941 // had one; that is, all the effects in the tree including the root.
12942 if (finishedWork.lastEffect !== null) {
12943 finishedWork.lastEffect.nextEffect = finishedWork;
12944 firstEffect = finishedWork.firstEffect;
12945 } else {
12946 firstEffect = finishedWork;
12947 }
12948 } else {
12949 // There is no effect on the root.
12950 firstEffect = finishedWork.firstEffect;
12951 }
12952
12953 if (firstEffect !== null) {
12954 var prevExecutionContext = executionContext;
12955 executionContext |= CommitContext;
12956 var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles
12957
12958 ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass
12959 // of the effect list for each phase: all mutation effects come before all
12960 // layout effects, and so on.
12961 // The first phase a "before mutation" phase. We use this phase to read the
12962 // state of the host tree right before we mutate it. This is where
12963 // getSnapshotBeforeUpdate is called.
12964
12965 startCommitSnapshotEffectsTimer();
12966 prepareForCommit(root.containerInfo);
12967 nextEffect = firstEffect;
12968
12969 do {
12970 {
12971 invokeGuardedCallback(null, commitBeforeMutationEffects, null);
12972
12973 if (hasCaughtError()) {
12974 if (!(nextEffect !== null)) {
12975 {
12976 throw Error( "Should be working on an effect." );
12977 }
12978 }
12979
12980 var error = clearCaughtError();
12981 captureCommitPhaseError(nextEffect, error);
12982 nextEffect = nextEffect.nextEffect;
12983 }
12984 }
12985 } while (nextEffect !== null);
12986
12987 stopCommitSnapshotEffectsTimer();
12988
12989 {
12990 // Mark the current commit time to be shared by all Profilers in this
12991 // batch. This enables them to be grouped later.
12992 recordCommitTime();
12993 } // The next phase is the mutation phase, where we mutate the host tree.
12994
12995
12996 startCommitHostEffectsTimer();
12997 nextEffect = firstEffect;
12998
12999 do {
13000 {
13001 invokeGuardedCallback(null, commitMutationEffects, null, root, renderPriorityLevel);
13002
13003 if (hasCaughtError()) {
13004 if (!(nextEffect !== null)) {
13005 {
13006 throw Error( "Should be working on an effect." );
13007 }
13008 }
13009
13010 var _error = clearCaughtError();
13011
13012 captureCommitPhaseError(nextEffect, _error);
13013 nextEffect = nextEffect.nextEffect;
13014 }
13015 }
13016 } while (nextEffect !== null);
13017
13018 stopCommitHostEffectsTimer();
13019 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
13020 // the mutation phase, so that the previous tree is still current during
13021 // componentWillUnmount, but before the layout phase, so that the finished
13022 // work is current during componentDidMount/Update.
13023
13024 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
13025 // the host tree after it's been mutated. The idiomatic use case for this is
13026 // layout, but class component lifecycles also fire here for legacy reasons.
13027
13028 startCommitLifeCyclesTimer();
13029 nextEffect = firstEffect;
13030
13031 do {
13032 {
13033 invokeGuardedCallback(null, commitLayoutEffects, null, root, expirationTime);
13034
13035 if (hasCaughtError()) {
13036 if (!(nextEffect !== null)) {
13037 {
13038 throw Error( "Should be working on an effect." );
13039 }
13040 }
13041
13042 var _error2 = clearCaughtError();
13043
13044 captureCommitPhaseError(nextEffect, _error2);
13045 nextEffect = nextEffect.nextEffect;
13046 }
13047 }
13048 } while (nextEffect !== null);
13049
13050 stopCommitLifeCyclesTimer();
13051 nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an
13052 // opportunity to paint.
13053
13054 requestPaint();
13055
13056 {
13057 popInteractions(prevInteractions);
13058 }
13059
13060 executionContext = prevExecutionContext;
13061 } else {
13062 // No effects.
13063 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
13064 // no effects.
13065 // TODO: Maybe there's a better way to report this.
13066
13067 startCommitSnapshotEffectsTimer();
13068 stopCommitSnapshotEffectsTimer();
13069
13070 {
13071 recordCommitTime();
13072 }
13073
13074 startCommitHostEffectsTimer();
13075 stopCommitHostEffectsTimer();
13076 startCommitLifeCyclesTimer();
13077 stopCommitLifeCyclesTimer();
13078 }
13079
13080 stopCommitTimer();
13081 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
13082
13083 if (rootDoesHavePassiveEffects) {
13084 // This commit has passive effects. Stash a reference to them. But don't
13085 // schedule a callback until after flushing layout work.
13086 rootDoesHavePassiveEffects = false;
13087 rootWithPendingPassiveEffects = root;
13088 pendingPassiveEffectsExpirationTime = expirationTime;
13089 pendingPassiveEffectsRenderPriority = renderPriorityLevel;
13090 } else {
13091 // We are done with the effect chain at this point so let's clear the
13092 // nextEffect pointers to assist with GC. If we have passive effects, we'll
13093 // clear this in flushPassiveEffects.
13094 nextEffect = firstEffect;
13095
13096 while (nextEffect !== null) {
13097 var nextNextEffect = nextEffect.nextEffect;
13098 nextEffect.nextEffect = null;
13099 nextEffect = nextNextEffect;
13100 }
13101 } // Check if there's remaining work on this root
13102
13103
13104 var remainingExpirationTime = root.firstPendingTime;
13105
13106 if (remainingExpirationTime !== NoWork) {
13107 {
13108 if (spawnedWorkDuringRender !== null) {
13109 var expirationTimes = spawnedWorkDuringRender;
13110 spawnedWorkDuringRender = null;
13111
13112 for (var i = 0; i < expirationTimes.length; i++) {
13113 scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);
13114 }
13115 }
13116
13117 schedulePendingInteractions(root, remainingExpirationTime);
13118 }
13119 } else {
13120 // If there's no remaining work, we can clear the set of already failed
13121 // error boundaries.
13122 legacyErrorBoundariesThatAlreadyFailed = null;
13123 }
13124
13125 {
13126 if (!rootDidHavePassiveEffects) {
13127 // If there are no passive effects, then we can complete the pending interactions.
13128 // Otherwise, we'll wait until after the passive effects are flushed.
13129 // Wait to do this until after remaining work has been scheduled,
13130 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.
13131 finishPendingInteractions(root, expirationTime);
13132 }
13133 }
13134
13135 if (remainingExpirationTime === Sync) {
13136 // Count the number of times the root synchronously re-renders without
13137 // finishing. If there are too many, it indicates an infinite update loop.
13138 if (root === rootWithNestedUpdates) {
13139 nestedUpdateCount++;
13140 } else {
13141 nestedUpdateCount = 0;
13142 rootWithNestedUpdates = root;
13143 }
13144 } else {
13145 nestedUpdateCount = 0;
13146 }
13147
13148 onCommitRoot(finishedWork.stateNode, expirationTime); // Always call this before exiting `commitRoot`, to ensure that any
13149 // additional work on this root is scheduled.
13150
13151 ensureRootIsScheduled(root);
13152
13153 if (hasUncaughtError) {
13154 hasUncaughtError = false;
13155 var _error3 = firstUncaughtError;
13156 firstUncaughtError = null;
13157 throw _error3;
13158 }
13159
13160 if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
13161 // This is a legacy edge case. We just committed the initial mount of
13162 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
13163 // synchronously, but layout updates should be deferred until the end
13164 // of the batch.
13165 return null;
13166 } // If layout work was scheduled, flush it now.
13167
13168
13169 flushSyncCallbackQueue();
13170 return null;
13171}
13172
13173function commitBeforeMutationEffects() {
13174 while (nextEffect !== null) {
13175 var effectTag = nextEffect.effectTag;
13176
13177 if ((effectTag & Snapshot) !== NoEffect) {
13178 setCurrentFiber(nextEffect);
13179 recordEffect();
13180 var current = nextEffect.alternate;
13181 commitBeforeMutationLifeCycles(current, nextEffect);
13182 resetCurrentFiber();
13183 }
13184
13185 if ((effectTag & Passive) !== NoEffect) {
13186 // If there are passive effects, schedule a callback to flush at
13187 // the earliest opportunity.
13188 if (!rootDoesHavePassiveEffects) {
13189 rootDoesHavePassiveEffects = true;
13190 scheduleCallback(NormalPriority, function () {
13191 flushPassiveEffects();
13192 return null;
13193 });
13194 }
13195 }
13196
13197 nextEffect = nextEffect.nextEffect;
13198 }
13199}
13200
13201function commitMutationEffects(root, renderPriorityLevel) {
13202 // TODO: Should probably move the bulk of this function to commitWork.
13203 while (nextEffect !== null) {
13204 setCurrentFiber(nextEffect);
13205 var effectTag = nextEffect.effectTag;
13206
13207 if (effectTag & ContentReset) {
13208 commitResetTextContent(nextEffect);
13209 }
13210
13211 if (effectTag & Ref) {
13212 var current = nextEffect.alternate;
13213
13214 if (current !== null) {
13215 commitDetachRef(current);
13216 }
13217 } // The following switch statement is only concerned about placement,
13218 // updates, and deletions. To avoid needing to add a case for every possible
13219 // bitmap value, we remove the secondary effects from the effect tag and
13220 // switch on that value.
13221
13222
13223 var primaryEffectTag = effectTag & (Placement | Update | Deletion | Hydrating);
13224
13225 switch (primaryEffectTag) {
13226 case Placement:
13227 {
13228 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
13229 // inserted, before any life-cycles like componentDidMount gets called.
13230 // TODO: findDOMNode doesn't rely on this any more but isMounted does
13231 // and isMounted is deprecated anyway so we should be able to kill this.
13232
13233 nextEffect.effectTag &= ~Placement;
13234 break;
13235 }
13236
13237 case PlacementAndUpdate:
13238 {
13239 // Placement
13240 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
13241 // inserted, before any life-cycles like componentDidMount gets called.
13242
13243 nextEffect.effectTag &= ~Placement; // Update
13244
13245 var _current = nextEffect.alternate;
13246 commitWork(_current, nextEffect);
13247 break;
13248 }
13249
13250 case Hydrating:
13251 {
13252 nextEffect.effectTag &= ~Hydrating;
13253 break;
13254 }
13255
13256 case HydratingAndUpdate:
13257 {
13258 nextEffect.effectTag &= ~Hydrating; // Update
13259
13260 var _current2 = nextEffect.alternate;
13261 commitWork(_current2, nextEffect);
13262 break;
13263 }
13264
13265 case Update:
13266 {
13267 var _current3 = nextEffect.alternate;
13268 commitWork(_current3, nextEffect);
13269 break;
13270 }
13271
13272 case Deletion:
13273 {
13274 commitDeletion(root, nextEffect, renderPriorityLevel);
13275 break;
13276 }
13277 } // TODO: Only record a mutation effect if primaryEffectTag is non-zero.
13278
13279
13280 recordEffect();
13281 resetCurrentFiber();
13282 nextEffect = nextEffect.nextEffect;
13283 }
13284}
13285
13286function commitLayoutEffects(root, committedExpirationTime) {
13287 // TODO: Should probably move the bulk of this function to commitWork.
13288 while (nextEffect !== null) {
13289 setCurrentFiber(nextEffect);
13290 var effectTag = nextEffect.effectTag;
13291
13292 if (effectTag & (Update | Callback)) {
13293 recordEffect();
13294 var current = nextEffect.alternate;
13295 commitLifeCycles(root, current, nextEffect);
13296 }
13297
13298 if (effectTag & Ref) {
13299 recordEffect();
13300 commitAttachRef(nextEffect);
13301 }
13302
13303 resetCurrentFiber();
13304 nextEffect = nextEffect.nextEffect;
13305 }
13306}
13307
13308function flushPassiveEffects() {
13309 if (pendingPassiveEffectsRenderPriority !== NoPriority) {
13310 var priorityLevel = pendingPassiveEffectsRenderPriority > NormalPriority ? NormalPriority : pendingPassiveEffectsRenderPriority;
13311 pendingPassiveEffectsRenderPriority = NoPriority;
13312 return runWithPriority(priorityLevel, flushPassiveEffectsImpl);
13313 }
13314}
13315
13316function flushPassiveEffectsImpl() {
13317 if (rootWithPendingPassiveEffects === null) {
13318 return false;
13319 }
13320
13321 var root = rootWithPendingPassiveEffects;
13322 var expirationTime = pendingPassiveEffectsExpirationTime;
13323 rootWithPendingPassiveEffects = null;
13324 pendingPassiveEffectsExpirationTime = NoWork;
13325
13326 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
13327 {
13328 throw Error( "Cannot flush passive effects while already rendering." );
13329 }
13330 }
13331
13332 var prevExecutionContext = executionContext;
13333 executionContext |= CommitContext;
13334 var prevInteractions = pushInteractions(root);
13335
13336 {
13337 // Note: This currently assumes there are no passive effects on the root fiber
13338 // because the root is not part of its own effect list.
13339 // This could change in the future.
13340 var _effect2 = root.current.firstEffect;
13341
13342 while (_effect2 !== null) {
13343 {
13344 setCurrentFiber(_effect2);
13345 invokeGuardedCallback(null, commitPassiveHookEffects, null, _effect2);
13346
13347 if (hasCaughtError()) {
13348 if (!(_effect2 !== null)) {
13349 {
13350 throw Error( "Should be working on an effect." );
13351 }
13352 }
13353
13354 var _error5 = clearCaughtError();
13355
13356 captureCommitPhaseError(_effect2, _error5);
13357 }
13358
13359 resetCurrentFiber();
13360 }
13361
13362 var nextNextEffect = _effect2.nextEffect; // Remove nextEffect pointer to assist GC
13363
13364 _effect2.nextEffect = null;
13365 _effect2 = nextNextEffect;
13366 }
13367 }
13368
13369 {
13370 popInteractions(prevInteractions);
13371 finishPendingInteractions(root, expirationTime);
13372 }
13373
13374 executionContext = prevExecutionContext;
13375 flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this
13376 // exceeds the limit, we'll fire a warning.
13377
13378 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
13379 return true;
13380}
13381
13382function isAlreadyFailedLegacyErrorBoundary(instance) {
13383 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
13384}
13385function markLegacyErrorBoundaryAsFailed(instance) {
13386 if (legacyErrorBoundariesThatAlreadyFailed === null) {
13387 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
13388 } else {
13389 legacyErrorBoundariesThatAlreadyFailed.add(instance);
13390 }
13391}
13392
13393function prepareToThrowUncaughtError(error) {
13394 if (!hasUncaughtError) {
13395 hasUncaughtError = true;
13396 firstUncaughtError = error;
13397 }
13398}
13399
13400var onUncaughtError = prepareToThrowUncaughtError;
13401
13402function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
13403 var errorInfo = createCapturedValue(error, sourceFiber);
13404 var update = createRootErrorUpdate(rootFiber, errorInfo, Sync);
13405 enqueueUpdate(rootFiber, update);
13406 var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);
13407
13408 if (root !== null) {
13409 ensureRootIsScheduled(root);
13410 schedulePendingInteractions(root, Sync);
13411 }
13412}
13413
13414function captureCommitPhaseError(sourceFiber, error) {
13415 if (sourceFiber.tag === HostRoot) {
13416 // Error was thrown at the root. There is no parent, so the root
13417 // itself should capture it.
13418 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);
13419 return;
13420 }
13421
13422 var fiber = sourceFiber.return;
13423
13424 while (fiber !== null) {
13425 if (fiber.tag === HostRoot) {
13426 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);
13427 return;
13428 } else if (fiber.tag === ClassComponent) {
13429 var ctor = fiber.type;
13430 var instance = fiber.stateNode;
13431
13432 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
13433 var errorInfo = createCapturedValue(error, sourceFiber);
13434 var update = createClassErrorUpdate(fiber, errorInfo, // TODO: This is always sync
13435 Sync);
13436 enqueueUpdate(fiber, update);
13437 var root = markUpdateTimeFromFiberToRoot(fiber, Sync);
13438
13439 if (root !== null) {
13440 ensureRootIsScheduled(root);
13441 schedulePendingInteractions(root, Sync);
13442 }
13443
13444 return;
13445 }
13446 }
13447
13448 fiber = fiber.return;
13449 }
13450}
13451function pingSuspendedRoot(root, thenable, suspendedTime) {
13452 var pingCache = root.pingCache;
13453
13454 if (pingCache !== null) {
13455 // The thenable resolved, so we no longer need to memoize, because it will
13456 // never be thrown again.
13457 pingCache.delete(thenable);
13458 }
13459
13460 if (workInProgressRoot === root && renderExpirationTime$1 === suspendedTime) {
13461 // Received a ping at the same priority level at which we're currently
13462 // rendering. We might want to restart this render. This should mirror
13463 // the logic of whether or not a root suspends once it completes.
13464 // TODO: If we're rendering sync either due to Sync, Batched or expired,
13465 // we should probably never restart.
13466 // If we're suspended with delay, we'll always suspend so we can always
13467 // restart. If we're suspended without any updates, it might be a retry.
13468 // If it's early in the retry we can restart. We can't know for sure
13469 // whether we'll eventually process an update during this render pass,
13470 // but it's somewhat unlikely that we get to a ping before that, since
13471 // getting to the root most update is usually very fast.
13472 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && workInProgressRootLatestProcessedExpirationTime === Sync && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
13473 // Restart from the root. Don't need to schedule a ping because
13474 // we're already working on this tree.
13475 prepareFreshStack(root, renderExpirationTime$1);
13476 } else {
13477 // Even though we can't restart right now, we might get an
13478 // opportunity later. So we mark this render as having a ping.
13479 workInProgressRootHasPendingPing = true;
13480 }
13481
13482 return;
13483 }
13484
13485 if (!isRootSuspendedAtTime(root, suspendedTime)) {
13486 // The root is no longer suspended at this time.
13487 return;
13488 }
13489
13490 var lastPingedTime = root.lastPingedTime;
13491
13492 if (lastPingedTime !== NoWork && lastPingedTime < suspendedTime) {
13493 // There's already a lower priority ping scheduled.
13494 return;
13495 } // Mark the time at which this ping was scheduled.
13496
13497
13498 root.lastPingedTime = suspendedTime;
13499
13500 ensureRootIsScheduled(root);
13501 schedulePendingInteractions(root, suspendedTime);
13502}
13503
13504function retryTimedOutBoundary(boundaryFiber, retryTime) {
13505 // The boundary fiber (a Suspense component or SuspenseList component)
13506 // previously was rendered in its fallback state. One of the promises that
13507 // suspended it has resolved, which means at least part of the tree was
13508 // likely unblocked. Try rendering again, at a new expiration time.
13509 if (retryTime === NoWork) {
13510 var suspenseConfig = null; // Retries don't carry over the already committed update.
13511
13512 var currentTime = requestCurrentTimeForUpdate();
13513 retryTime = computeExpirationForFiber(currentTime, boundaryFiber, suspenseConfig);
13514 } // TODO: Special case idle priority?
13515
13516
13517 var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);
13518
13519 if (root !== null) {
13520 ensureRootIsScheduled(root);
13521 schedulePendingInteractions(root, retryTime);
13522 }
13523}
13524function resolveRetryThenable(boundaryFiber, thenable) {
13525 var retryTime = NoWork; // Default
13526
13527 var retryCache;
13528
13529 {
13530 retryCache = boundaryFiber.stateNode;
13531 }
13532
13533 if (retryCache !== null) {
13534 // The thenable resolved, so we no longer need to memoize, because it will
13535 // never be thrown again.
13536 retryCache.delete(thenable);
13537 }
13538
13539 retryTimedOutBoundary(boundaryFiber, retryTime);
13540} // Computes the next Just Noticeable Difference (JND) boundary.
13541// The theory is that a person can't tell the difference between small differences in time.
13542// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
13543// difference in the experience. However, waiting for longer might mean that we can avoid
13544// showing an intermediate loading state. The longer we have already waited, the harder it
13545// is to tell small differences in time. Therefore, the longer we've already waited,
13546// the longer we can wait additionally. At some point we have to give up though.
13547// We pick a train model where the next boundary commits at a consistent schedule.
13548// These particular numbers are vague estimates. We expect to adjust them based on research.
13549
13550function jnd(timeElapsed) {
13551 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
13552}
13553
13554function computeMsUntilSuspenseLoadingDelay(mostRecentEventTime, committedExpirationTime, suspenseConfig) {
13555 var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0;
13556
13557 if (busyMinDurationMs <= 0) {
13558 return 0;
13559 }
13560
13561 var busyDelayMs = suspenseConfig.busyDelayMs | 0; // Compute the time until this render pass would expire.
13562
13563 var currentTimeMs = now();
13564 var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig(mostRecentEventTime, suspenseConfig);
13565 var timeElapsed = currentTimeMs - eventTimeMs;
13566
13567 if (timeElapsed <= busyDelayMs) {
13568 // If we haven't yet waited longer than the initial delay, we don't
13569 // have to wait any additional time.
13570 return 0;
13571 }
13572
13573 var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed; // This is the value that is passed to `setTimeout`.
13574
13575 return msUntilTimeout;
13576}
13577
13578function checkForNestedUpdates() {
13579 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
13580 nestedUpdateCount = 0;
13581 rootWithNestedUpdates = null;
13582
13583 {
13584 {
13585 throw 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." );
13586 }
13587 }
13588 }
13589
13590 {
13591 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
13592 nestedPassiveUpdateCount = 0;
13593
13594 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.');
13595 }
13596 }
13597}
13598
13599function flushRenderPhaseStrictModeWarningsInDEV() {
13600 {
13601 ReactStrictModeWarnings.flushLegacyContextWarning();
13602
13603 {
13604 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
13605 }
13606 }
13607}
13608
13609function stopFinishedWorkLoopTimer() {
13610 var didCompleteRoot = true;
13611 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
13612 interruptedBy = null;
13613}
13614
13615function stopInterruptedWorkLoopTimer() {
13616 // TODO: Track which fiber caused the interruption.
13617 var didCompleteRoot = false;
13618 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
13619 interruptedBy = null;
13620}
13621
13622function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) {
13623 if ( workInProgressRoot !== null && updateExpirationTime > renderExpirationTime$1) {
13624 interruptedBy = fiberThatReceivedUpdate;
13625 }
13626}
13627
13628var didWarnStateUpdateForUnmountedComponent = null;
13629
13630function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
13631 {
13632 var tag = fiber.tag;
13633
13634 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent && tag !== Block) {
13635 // Only warn for user-defined components, not internal ones like Suspense.
13636 return;
13637 }
13638 // the problematic code almost always lies inside that component.
13639
13640
13641 var componentName = getComponentName(fiber.type) || 'ReactComponent';
13642
13643 if (didWarnStateUpdateForUnmountedComponent !== null) {
13644 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {
13645 return;
13646 }
13647
13648 didWarnStateUpdateForUnmountedComponent.add(componentName);
13649 } else {
13650 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);
13651 }
13652
13653 error("Can't perform a React state update on an unmounted component. This " + 'is a no-op, but it indicates a memory leak in your application. To ' + 'fix, cancel all subscriptions and asynchronous tasks in %s.%s', tag === ClassComponent ? 'the componentWillUnmount method' : 'a useEffect cleanup function', getStackByFiberInDevAndProd(fiber));
13654 }
13655}
13656
13657var beginWork$1;
13658
13659{
13660 beginWork$1 = beginWork;
13661}
13662
13663var didWarnAboutUpdateInRender = false;
13664var didWarnAboutUpdateInRenderForAnotherComponent;
13665
13666{
13667 didWarnAboutUpdateInRenderForAnotherComponent = new Set();
13668}
13669
13670function warnAboutRenderPhaseUpdatesInDEV(fiber) {
13671 {
13672 if (isRendering && (executionContext & RenderContext) !== NoContext) {
13673 switch (fiber.tag) {
13674 case FunctionComponent:
13675 case ForwardRef:
13676 case SimpleMemoComponent:
13677 {
13678 var renderingComponentName = workInProgress && getComponentName(workInProgress.type) || 'Unknown'; // Dedupe by the rendering component because it's the one that needs to be fixed.
13679
13680 var dedupeKey = renderingComponentName;
13681
13682 if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) {
13683 didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey);
13684 var setStateComponentName = getComponentName(fiber.type) || 'Unknown';
13685
13686 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://fb.me/setstate-in-render', setStateComponentName, renderingComponentName, renderingComponentName);
13687 }
13688
13689 break;
13690 }
13691
13692 case ClassComponent:
13693 {
13694 if (!didWarnAboutUpdateInRender) {
13695 error('Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure ' + 'function of props and state.');
13696
13697 didWarnAboutUpdateInRender = true;
13698 }
13699
13700 break;
13701 }
13702 }
13703 }
13704 }
13705} // a 'shared' variable that changes when act() opens/closes in tests.
13706
13707
13708var IsThisRendererActing = {
13709 current: false
13710};
13711function warnIfNotScopedWithMatchingAct(fiber) {
13712 {
13713 if ( IsSomeRendererActing.current === true && IsThisRendererActing.current !== true) {
13714 error("It looks like you're using the wrong act() around your test interactions.\n" + 'Be sure to use the matching version of act() corresponding to your renderer:\n\n' + '// for react-dom:\n' + "import {act} from 'react-dom/test-utils';\n" + '// ...\n' + 'act(() => ...);\n\n' + '// for react-test-renderer:\n' + "import TestRenderer from 'react-test-renderer';\n" + 'const {act} = TestRenderer;\n' + '// ...\n' + 'act(() => ...);' + '%s', getStackByFiberInDevAndProd(fiber));
13715 }
13716 }
13717}
13718function warnIfNotCurrentlyActingEffectsInDEV(fiber) {
13719 {
13720 if ( (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
13721 error('An update to %s ran an effect, but 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://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber));
13722 }
13723 }
13724}
13725
13726function warnIfNotCurrentlyActingUpdatesInDEV(fiber) {
13727 {
13728 if ( executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
13729 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://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber));
13730 }
13731 }
13732}
13733
13734var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; // In tests, we want to enforce a mocked scheduler.
13735
13736var didWarnAboutUnmockedScheduler = false; // TODO Before we release concurrent mode, revisit this and decide whether a mocked
13737// scheduler is the actual recommendation. The alternative could be a testing build,
13738// a new lib, or whatever; we dunno just yet. This message is for early adopters
13739// to get their tests right.
13740
13741function warnIfUnmockedScheduler(fiber) {
13742 {
13743 if (didWarnAboutUnmockedScheduler === false && Scheduler$1.unstable_flushAllWithoutAsserting === undefined) {
13744 if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) {
13745 didWarnAboutUnmockedScheduler = true;
13746
13747 error('In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \n' + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + 'For more info, visit https://fb.me/react-mock-scheduler');
13748 }
13749 }
13750 }
13751}
13752
13753function computeThreadID(root, expirationTime) {
13754 // Interaction threads are unique per root and expiration time.
13755 return expirationTime * 1000 + root.interactionThreadID;
13756}
13757
13758function markSpawnedWork(expirationTime) {
13759
13760 if (spawnedWorkDuringRender === null) {
13761 spawnedWorkDuringRender = [expirationTime];
13762 } else {
13763 spawnedWorkDuringRender.push(expirationTime);
13764 }
13765}
13766
13767function scheduleInteractions(root, expirationTime, interactions) {
13768
13769 if (interactions.size > 0) {
13770 var pendingInteractionMap = root.pendingInteractionMap;
13771 var pendingInteractions = pendingInteractionMap.get(expirationTime);
13772
13773 if (pendingInteractions != null) {
13774 interactions.forEach(function (interaction) {
13775 if (!pendingInteractions.has(interaction)) {
13776 // Update the pending async work count for previously unscheduled interaction.
13777 interaction.__count++;
13778 }
13779
13780 pendingInteractions.add(interaction);
13781 });
13782 } else {
13783 pendingInteractionMap.set(expirationTime, new Set(interactions)); // Update the pending async work count for the current interactions.
13784
13785 interactions.forEach(function (interaction) {
13786 interaction.__count++;
13787 });
13788 }
13789
13790 var subscriber = tracing.__subscriberRef.current;
13791
13792 if (subscriber !== null) {
13793 var threadID = computeThreadID(root, expirationTime);
13794 subscriber.onWorkScheduled(interactions, threadID);
13795 }
13796 }
13797}
13798
13799function schedulePendingInteractions(root, expirationTime) {
13800
13801 scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current);
13802}
13803
13804function startWorkOnPendingInteractions(root, expirationTime) {
13805 // we can accurately attribute time spent working on it, And so that cascading
13806 // work triggered during the render phase will be associated with it.
13807
13808
13809 var interactions = new Set();
13810 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
13811 if (scheduledExpirationTime >= expirationTime) {
13812 scheduledInteractions.forEach(function (interaction) {
13813 return interactions.add(interaction);
13814 });
13815 }
13816 }); // Store the current set of interactions on the FiberRoot for a few reasons:
13817 // We can re-use it in hot functions like performConcurrentWorkOnRoot()
13818 // without having to recalculate it. We will also use it in commitWork() to
13819 // pass to any Profiler onRender() hooks. This also provides DevTools with a
13820 // way to access it when the onCommitRoot() hook is called.
13821
13822 root.memoizedInteractions = interactions;
13823
13824 if (interactions.size > 0) {
13825 var subscriber = tracing.__subscriberRef.current;
13826
13827 if (subscriber !== null) {
13828 var threadID = computeThreadID(root, expirationTime);
13829
13830 try {
13831 subscriber.onWorkStarted(interactions, threadID);
13832 } catch (error) {
13833 // If the subscriber throws, rethrow it in a separate task
13834 scheduleCallback(ImmediatePriority, function () {
13835 throw error;
13836 });
13837 }
13838 }
13839 }
13840}
13841
13842function finishPendingInteractions(root, committedExpirationTime) {
13843
13844 var earliestRemainingTimeAfterCommit = root.firstPendingTime;
13845 var subscriber;
13846
13847 try {
13848 subscriber = tracing.__subscriberRef.current;
13849
13850 if (subscriber !== null && root.memoizedInteractions.size > 0) {
13851 var threadID = computeThreadID(root, committedExpirationTime);
13852 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
13853 }
13854 } catch (error) {
13855 // If the subscriber throws, rethrow it in a separate task
13856 scheduleCallback(ImmediatePriority, function () {
13857 throw error;
13858 });
13859 } finally {
13860 // Clear completed interactions from the pending Map.
13861 // Unless the render was suspended or cascading work was scheduled,
13862 // In which case– leave pending interactions until the subsequent render.
13863 var pendingInteractionMap = root.pendingInteractionMap;
13864 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
13865 // Only decrement the pending interaction count if we're done.
13866 // If there's still work at the current priority,
13867 // That indicates that we are waiting for suspense data.
13868 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
13869 pendingInteractionMap.delete(scheduledExpirationTime);
13870 scheduledInteractions.forEach(function (interaction) {
13871 interaction.__count--;
13872
13873 if (subscriber !== null && interaction.__count === 0) {
13874 try {
13875 subscriber.onInteractionScheduledWorkCompleted(interaction);
13876 } catch (error) {
13877 // If the subscriber throws, rethrow it in a separate task
13878 scheduleCallback(ImmediatePriority, function () {
13879 throw error;
13880 });
13881 }
13882 }
13883 });
13884 }
13885 });
13886 }
13887}
13888
13889var onScheduleFiberRoot = null;
13890var onCommitFiberRoot = null;
13891var onCommitFiberUnmount = null;
13892var hasLoggedError = false;
13893var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
13894function injectInternals(internals) {
13895 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
13896 // No DevTools
13897 return false;
13898 }
13899
13900 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
13901
13902 if (hook.isDisabled) {
13903 // This isn't a real property on the hook, but it can be set to opt out
13904 // of DevTools integration and associated warnings and logs.
13905 // https://github.com/facebook/react/issues/3877
13906 return true;
13907 }
13908
13909 if (!hook.supportsFiber) {
13910 {
13911 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://fb.me/react-devtools');
13912 } // DevTools exists, even though it doesn't support Fiber.
13913
13914
13915 return true;
13916 }
13917
13918 try {
13919 var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
13920
13921 if (true) {
13922 // Only used by Fast Refresh
13923 if (typeof hook.onScheduleFiberRoot === 'function') {
13924 onScheduleFiberRoot = function (root, children) {
13925 try {
13926 hook.onScheduleFiberRoot(rendererID, root, children);
13927 } catch (err) {
13928 if (true && !hasLoggedError) {
13929 hasLoggedError = true;
13930
13931 error('React instrumentation encountered an error: %s', err);
13932 }
13933 }
13934 };
13935 }
13936 }
13937
13938 onCommitFiberRoot = function (root, expirationTime) {
13939 try {
13940 var didError = (root.current.effectTag & DidCapture) === DidCapture;
13941
13942 if (enableProfilerTimer) {
13943 var currentTime = getCurrentTime();
13944 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime);
13945 hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
13946 } else {
13947 hook.onCommitFiberRoot(rendererID, root, undefined, didError);
13948 }
13949 } catch (err) {
13950 if (true) {
13951 if (!hasLoggedError) {
13952 hasLoggedError = true;
13953
13954 error('React instrumentation encountered an error: %s', err);
13955 }
13956 }
13957 }
13958 };
13959
13960 onCommitFiberUnmount = function (fiber) {
13961 try {
13962 hook.onCommitFiberUnmount(rendererID, fiber);
13963 } catch (err) {
13964 if (true) {
13965 if (!hasLoggedError) {
13966 hasLoggedError = true;
13967
13968 error('React instrumentation encountered an error: %s', err);
13969 }
13970 }
13971 }
13972 };
13973 } catch (err) {
13974 // Catch all errors because it is unsafe to throw during initialization.
13975 {
13976 error('React instrumentation encountered an error: %s.', err);
13977 }
13978 } // DevTools exists
13979
13980
13981 return true;
13982}
13983function onScheduleRoot(root, children) {
13984 if (typeof onScheduleFiberRoot === 'function') {
13985 onScheduleFiberRoot(root, children);
13986 }
13987}
13988function onCommitRoot(root, expirationTime) {
13989 if (typeof onCommitFiberRoot === 'function') {
13990 onCommitFiberRoot(root, expirationTime);
13991 }
13992}
13993function onCommitUnmount(fiber) {
13994 if (typeof onCommitFiberUnmount === 'function') {
13995 onCommitFiberUnmount(fiber);
13996 }
13997}
13998
13999var hasBadMapPolyfill;
14000
14001{
14002 hasBadMapPolyfill = false;
14003
14004 try {
14005 var nonExtensibleObject = Object.preventExtensions({});
14006 var testMap = new Map([[nonExtensibleObject, null]]);
14007 var testSet = new Set([nonExtensibleObject]); // This is necessary for Rollup to not consider these unused.
14008 // https://github.com/rollup/rollup/issues/1771
14009 // TODO: we can remove these if Rollup fixes the bug.
14010
14011 testMap.set(0, 0);
14012 testSet.add(0);
14013 } catch (e) {
14014 // TODO: Consider warning about bad polyfills
14015 hasBadMapPolyfill = true;
14016 }
14017}
14018
14019var debugCounter = 1;
14020
14021function FiberNode(tag, pendingProps, key, mode) {
14022 // Instance
14023 this.tag = tag;
14024 this.key = key;
14025 this.elementType = null;
14026 this.type = null;
14027 this.stateNode = null; // Fiber
14028
14029 this.return = null;
14030 this.child = null;
14031 this.sibling = null;
14032 this.index = 0;
14033 this.ref = null;
14034 this.pendingProps = pendingProps;
14035 this.memoizedProps = null;
14036 this.updateQueue = null;
14037 this.memoizedState = null;
14038 this.dependencies = null;
14039 this.mode = mode; // Effects
14040
14041 this.effectTag = NoEffect;
14042 this.nextEffect = null;
14043 this.firstEffect = null;
14044 this.lastEffect = null;
14045 this.expirationTime = NoWork;
14046 this.childExpirationTime = NoWork;
14047 this.alternate = null;
14048
14049 {
14050 // Note: The following is done to avoid a v8 performance cliff.
14051 //
14052 // Initializing the fields below to smis and later updating them with
14053 // double values will cause Fibers to end up having separate shapes.
14054 // This behavior/bug has something to do with Object.preventExtension().
14055 // Fortunately this only impacts DEV builds.
14056 // Unfortunately it makes React unusably slow for some applications.
14057 // To work around this, initialize the fields below with doubles.
14058 //
14059 // Learn more about this here:
14060 // https://github.com/facebook/react/issues/14365
14061 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
14062 this.actualDuration = Number.NaN;
14063 this.actualStartTime = Number.NaN;
14064 this.selfBaseDuration = Number.NaN;
14065 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
14066 // This won't trigger the performance cliff mentioned above,
14067 // and it simplifies other profiler code (including DevTools).
14068
14069 this.actualDuration = 0;
14070 this.actualStartTime = -1;
14071 this.selfBaseDuration = 0;
14072 this.treeBaseDuration = 0;
14073 } // This is normally DEV-only except www when it adds listeners.
14074 // TODO: remove the User Timing integration in favor of Root Events.
14075
14076
14077 {
14078 this._debugID = debugCounter++;
14079 this._debugIsCurrentlyTiming = false;
14080 }
14081
14082 {
14083 this._debugSource = null;
14084 this._debugOwner = null;
14085 this._debugNeedsRemount = false;
14086 this._debugHookTypes = null;
14087
14088 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
14089 Object.preventExtensions(this);
14090 }
14091 }
14092} // This is a constructor function, rather than a POJO constructor, still
14093// please ensure we do the following:
14094// 1) Nobody should add any instance methods on this. Instance methods can be
14095// more difficult to predict when they get optimized and they are almost
14096// never inlined properly in static compilers.
14097// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
14098// always know when it is a fiber.
14099// 3) We might want to experiment with using numeric keys since they are easier
14100// to optimize in a non-JIT environment.
14101// 4) We can easily go from a constructor to a createFiber object literal if that
14102// is faster.
14103// 5) It should be easy to port this to a C struct and keep a C implementation
14104// compatible.
14105
14106
14107var createFiber = function (tag, pendingProps, key, mode) {
14108 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
14109 return new FiberNode(tag, pendingProps, key, mode);
14110};
14111
14112function shouldConstruct(Component) {
14113 var prototype = Component.prototype;
14114 return !!(prototype && prototype.isReactComponent);
14115}
14116
14117function isSimpleFunctionComponent(type) {
14118 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
14119}
14120function resolveLazyComponentTag(Component) {
14121 if (typeof Component === 'function') {
14122 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
14123 } else if (Component !== undefined && Component !== null) {
14124 var $$typeof = Component.$$typeof;
14125
14126 if ($$typeof === REACT_FORWARD_REF_TYPE) {
14127 return ForwardRef;
14128 }
14129
14130 if ($$typeof === REACT_MEMO_TYPE) {
14131 return MemoComponent;
14132 }
14133 }
14134
14135 return IndeterminateComponent;
14136} // This is used to create an alternate fiber to do work on.
14137
14138function createWorkInProgress(current, pendingProps) {
14139 var workInProgress = current.alternate;
14140
14141 if (workInProgress === null) {
14142 // We use a double buffering pooling technique because we know that we'll
14143 // only ever need at most two versions of a tree. We pool the "other" unused
14144 // node that we're free to reuse. This is lazily created to avoid allocating
14145 // extra objects for things that are never updated. It also allow us to
14146 // reclaim the extra memory if needed.
14147 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
14148 workInProgress.elementType = current.elementType;
14149 workInProgress.type = current.type;
14150 workInProgress.stateNode = current.stateNode;
14151
14152 {
14153 // DEV-only fields
14154 {
14155 workInProgress._debugID = current._debugID;
14156 }
14157
14158 workInProgress._debugSource = current._debugSource;
14159 workInProgress._debugOwner = current._debugOwner;
14160 workInProgress._debugHookTypes = current._debugHookTypes;
14161 }
14162
14163 workInProgress.alternate = current;
14164 current.alternate = workInProgress;
14165 } else {
14166 workInProgress.pendingProps = pendingProps; // We already have an alternate.
14167 // Reset the effect tag.
14168
14169 workInProgress.effectTag = NoEffect; // The effect list is no longer valid.
14170
14171 workInProgress.nextEffect = null;
14172 workInProgress.firstEffect = null;
14173 workInProgress.lastEffect = null;
14174
14175 {
14176 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
14177 // This prevents time from endlessly accumulating in new commits.
14178 // This has the downside of resetting values for different priority renders,
14179 // But works for yielding (the common case) and should support resuming.
14180 workInProgress.actualDuration = 0;
14181 workInProgress.actualStartTime = -1;
14182 }
14183 }
14184
14185 workInProgress.childExpirationTime = current.childExpirationTime;
14186 workInProgress.expirationTime = current.expirationTime;
14187 workInProgress.child = current.child;
14188 workInProgress.memoizedProps = current.memoizedProps;
14189 workInProgress.memoizedState = current.memoizedState;
14190 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
14191 // it cannot be shared with the current fiber.
14192
14193 var currentDependencies = current.dependencies;
14194 workInProgress.dependencies = currentDependencies === null ? null : {
14195 expirationTime: currentDependencies.expirationTime,
14196 firstContext: currentDependencies.firstContext,
14197 responders: currentDependencies.responders
14198 }; // These will be overridden during the parent's reconciliation
14199
14200 workInProgress.sibling = current.sibling;
14201 workInProgress.index = current.index;
14202 workInProgress.ref = current.ref;
14203
14204 {
14205 workInProgress.selfBaseDuration = current.selfBaseDuration;
14206 workInProgress.treeBaseDuration = current.treeBaseDuration;
14207 }
14208
14209 {
14210 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
14211
14212 switch (workInProgress.tag) {
14213 case IndeterminateComponent:
14214 case FunctionComponent:
14215 case SimpleMemoComponent:
14216 workInProgress.type = resolveFunctionForHotReloading(current.type);
14217 break;
14218
14219 case ClassComponent:
14220 workInProgress.type = resolveClassForHotReloading(current.type);
14221 break;
14222
14223 case ForwardRef:
14224 workInProgress.type = resolveForwardRefForHotReloading(current.type);
14225 break;
14226 }
14227 }
14228
14229 return workInProgress;
14230} // Used to reuse a Fiber for a second pass.
14231
14232function resetWorkInProgress(workInProgress, renderExpirationTime) {
14233 // This resets the Fiber to what createFiber or createWorkInProgress would
14234 // have set the values to before during the first pass. Ideally this wouldn't
14235 // be necessary but unfortunately many code paths reads from the workInProgress
14236 // when they should be reading from current and writing to workInProgress.
14237 // We assume pendingProps, index, key, ref, return are still untouched to
14238 // avoid doing another reconciliation.
14239 // Reset the effect tag but keep any Placement tags, since that's something
14240 // that child fiber is setting, not the reconciliation.
14241 workInProgress.effectTag &= Placement; // The effect list is no longer valid.
14242
14243 workInProgress.nextEffect = null;
14244 workInProgress.firstEffect = null;
14245 workInProgress.lastEffect = null;
14246 var current = workInProgress.alternate;
14247
14248 if (current === null) {
14249 // Reset to createFiber's initial values.
14250 workInProgress.childExpirationTime = NoWork;
14251 workInProgress.expirationTime = renderExpirationTime;
14252 workInProgress.child = null;
14253 workInProgress.memoizedProps = null;
14254 workInProgress.memoizedState = null;
14255 workInProgress.updateQueue = null;
14256 workInProgress.dependencies = null;
14257
14258 {
14259 // Note: We don't reset the actualTime counts. It's useful to accumulate
14260 // actual time across multiple render passes.
14261 workInProgress.selfBaseDuration = 0;
14262 workInProgress.treeBaseDuration = 0;
14263 }
14264 } else {
14265 // Reset to the cloned values that createWorkInProgress would've.
14266 workInProgress.childExpirationTime = current.childExpirationTime;
14267 workInProgress.expirationTime = current.expirationTime;
14268 workInProgress.child = current.child;
14269 workInProgress.memoizedProps = current.memoizedProps;
14270 workInProgress.memoizedState = current.memoizedState;
14271 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
14272 // it cannot be shared with the current fiber.
14273
14274 var currentDependencies = current.dependencies;
14275 workInProgress.dependencies = currentDependencies === null ? null : {
14276 expirationTime: currentDependencies.expirationTime,
14277 firstContext: currentDependencies.firstContext,
14278 responders: currentDependencies.responders
14279 };
14280
14281 {
14282 // Note: We don't reset the actualTime counts. It's useful to accumulate
14283 // actual time across multiple render passes.
14284 workInProgress.selfBaseDuration = current.selfBaseDuration;
14285 workInProgress.treeBaseDuration = current.treeBaseDuration;
14286 }
14287 }
14288
14289 return workInProgress;
14290}
14291function createHostRootFiber(tag) {
14292 var mode;
14293
14294 if (tag === ConcurrentRoot) {
14295 mode = ConcurrentMode | BlockingMode | StrictMode;
14296 } else if (tag === BlockingRoot) {
14297 mode = BlockingMode | StrictMode;
14298 } else {
14299 mode = NoMode;
14300 }
14301
14302 if ( isDevToolsPresent) {
14303 // Always collect profile timings when DevTools are present.
14304 // This enables DevTools to start capturing timing at any point–
14305 // Without some nodes in the tree having empty base times.
14306 mode |= ProfileMode;
14307 }
14308
14309 return createFiber(HostRoot, null, null, mode);
14310}
14311function createFiberFromTypeAndProps(type, // React$ElementType
14312key, pendingProps, owner, mode, expirationTime) {
14313 var fiber;
14314 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
14315
14316 var resolvedType = type;
14317
14318 if (typeof type === 'function') {
14319 if (shouldConstruct(type)) {
14320 fiberTag = ClassComponent;
14321
14322 {
14323 resolvedType = resolveClassForHotReloading(resolvedType);
14324 }
14325 } else {
14326 {
14327 resolvedType = resolveFunctionForHotReloading(resolvedType);
14328 }
14329 }
14330 } else if (typeof type === 'string') {
14331 fiberTag = HostComponent;
14332 } else {
14333 getTag: switch (type) {
14334 case REACT_FRAGMENT_TYPE:
14335 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
14336
14337 case REACT_CONCURRENT_MODE_TYPE:
14338 fiberTag = Mode;
14339 mode |= ConcurrentMode | BlockingMode | StrictMode;
14340 break;
14341
14342 case REACT_STRICT_MODE_TYPE:
14343 fiberTag = Mode;
14344 mode |= StrictMode;
14345 break;
14346
14347 case REACT_PROFILER_TYPE:
14348 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
14349
14350 case REACT_SUSPENSE_TYPE:
14351 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
14352
14353 case REACT_SUSPENSE_LIST_TYPE:
14354 return createFiberFromSuspenseList(pendingProps, mode, expirationTime, key);
14355
14356 default:
14357 {
14358 if (typeof type === 'object' && type !== null) {
14359 switch (type.$$typeof) {
14360 case REACT_PROVIDER_TYPE:
14361 fiberTag = ContextProvider;
14362 break getTag;
14363
14364 case REACT_CONTEXT_TYPE:
14365 // This is a consumer
14366 fiberTag = ContextConsumer;
14367 break getTag;
14368
14369 case REACT_FORWARD_REF_TYPE:
14370 fiberTag = ForwardRef;
14371
14372 {
14373 resolvedType = resolveForwardRefForHotReloading(resolvedType);
14374 }
14375
14376 break getTag;
14377
14378 case REACT_MEMO_TYPE:
14379 fiberTag = MemoComponent;
14380 break getTag;
14381
14382 case REACT_LAZY_TYPE:
14383 fiberTag = LazyComponent;
14384 resolvedType = null;
14385 break getTag;
14386
14387 case REACT_BLOCK_TYPE:
14388 fiberTag = Block;
14389 break getTag;
14390
14391 }
14392 }
14393
14394 var info = '';
14395
14396 {
14397 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
14398 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.';
14399 }
14400
14401 var ownerName = owner ? getComponentName(owner.type) : null;
14402
14403 if (ownerName) {
14404 info += '\n\nCheck the render method of `' + ownerName + '`.';
14405 }
14406 }
14407
14408 {
14409 {
14410 throw 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 );
14411 }
14412 }
14413 }
14414 }
14415 }
14416
14417 fiber = createFiber(fiberTag, pendingProps, key, mode);
14418 fiber.elementType = type;
14419 fiber.type = resolvedType;
14420 fiber.expirationTime = expirationTime;
14421 return fiber;
14422}
14423function createFiberFromElement(element, mode, expirationTime) {
14424 var owner = null;
14425
14426 {
14427 owner = element._owner;
14428 }
14429
14430 var type = element.type;
14431 var key = element.key;
14432 var pendingProps = element.props;
14433 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
14434
14435 {
14436 fiber._debugSource = element._source;
14437 fiber._debugOwner = element._owner;
14438 }
14439
14440 return fiber;
14441}
14442function createFiberFromFragment(elements, mode, expirationTime, key) {
14443 var fiber = createFiber(Fragment, elements, key, mode);
14444 fiber.expirationTime = expirationTime;
14445 return fiber;
14446}
14447
14448function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
14449 {
14450 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
14451 error('Profiler must specify an "id" string and "onRender" function as props');
14452 }
14453 }
14454
14455 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); // TODO: The Profiler fiber shouldn't have a type. It has a tag.
14456
14457 fiber.elementType = REACT_PROFILER_TYPE;
14458 fiber.type = REACT_PROFILER_TYPE;
14459 fiber.expirationTime = expirationTime;
14460 return fiber;
14461}
14462
14463function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
14464 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
14465 // This needs to be fixed in getComponentName so that it relies on the tag
14466 // instead.
14467
14468 fiber.type = REACT_SUSPENSE_TYPE;
14469 fiber.elementType = REACT_SUSPENSE_TYPE;
14470 fiber.expirationTime = expirationTime;
14471 return fiber;
14472}
14473function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) {
14474 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
14475
14476 {
14477 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.
14478 // This needs to be fixed in getComponentName so that it relies on the tag
14479 // instead.
14480 fiber.type = REACT_SUSPENSE_LIST_TYPE;
14481 }
14482
14483 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
14484 fiber.expirationTime = expirationTime;
14485 return fiber;
14486}
14487function createFiberFromText(content, mode, expirationTime) {
14488 var fiber = createFiber(HostText, content, null, mode);
14489 fiber.expirationTime = expirationTime;
14490 return fiber;
14491}
14492function createFiberFromPortal(portal, mode, expirationTime) {
14493 var pendingProps = portal.children !== null ? portal.children : [];
14494 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
14495 fiber.expirationTime = expirationTime;
14496 fiber.stateNode = {
14497 containerInfo: portal.containerInfo,
14498 pendingChildren: null,
14499 // Used by persistent updates
14500 implementation: portal.implementation
14501 };
14502 return fiber;
14503} // Used for stashing WIP properties to replay failed work in DEV.
14504
14505function FiberRootNode(containerInfo, tag, hydrate) {
14506 this.tag = tag;
14507 this.current = null;
14508 this.containerInfo = containerInfo;
14509 this.pendingChildren = null;
14510 this.pingCache = null;
14511 this.finishedExpirationTime = NoWork;
14512 this.finishedWork = null;
14513 this.timeoutHandle = noTimeout;
14514 this.context = null;
14515 this.pendingContext = null;
14516 this.hydrate = hydrate;
14517 this.callbackNode = null;
14518 this.callbackPriority = NoPriority;
14519 this.firstPendingTime = NoWork;
14520 this.firstSuspendedTime = NoWork;
14521 this.lastSuspendedTime = NoWork;
14522 this.nextKnownPendingLevel = NoWork;
14523 this.lastPingedTime = NoWork;
14524 this.lastExpiredTime = NoWork;
14525
14526 {
14527 this.interactionThreadID = tracing.unstable_getThreadID();
14528 this.memoizedInteractions = new Set();
14529 this.pendingInteractionMap = new Map();
14530 }
14531}
14532
14533function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) {
14534 var root = new FiberRootNode(containerInfo, tag, hydrate);
14535 // stateNode is any.
14536
14537
14538 var uninitializedFiber = createHostRootFiber(tag);
14539 root.current = uninitializedFiber;
14540 uninitializedFiber.stateNode = root;
14541 initializeUpdateQueue(uninitializedFiber);
14542 return root;
14543}
14544function isRootSuspendedAtTime(root, expirationTime) {
14545 var firstSuspendedTime = root.firstSuspendedTime;
14546 var lastSuspendedTime = root.lastSuspendedTime;
14547 return firstSuspendedTime !== NoWork && firstSuspendedTime >= expirationTime && lastSuspendedTime <= expirationTime;
14548}
14549function markRootSuspendedAtTime(root, expirationTime) {
14550 var firstSuspendedTime = root.firstSuspendedTime;
14551 var lastSuspendedTime = root.lastSuspendedTime;
14552
14553 if (firstSuspendedTime < expirationTime) {
14554 root.firstSuspendedTime = expirationTime;
14555 }
14556
14557 if (lastSuspendedTime > expirationTime || firstSuspendedTime === NoWork) {
14558 root.lastSuspendedTime = expirationTime;
14559 }
14560
14561 if (expirationTime <= root.lastPingedTime) {
14562 root.lastPingedTime = NoWork;
14563 }
14564
14565 if (expirationTime <= root.lastExpiredTime) {
14566 root.lastExpiredTime = NoWork;
14567 }
14568}
14569function markRootUpdatedAtTime(root, expirationTime) {
14570 // Update the range of pending times
14571 var firstPendingTime = root.firstPendingTime;
14572
14573 if (expirationTime > firstPendingTime) {
14574 root.firstPendingTime = expirationTime;
14575 } // Update the range of suspended times. Treat everything lower priority or
14576 // equal to this update as unsuspended.
14577
14578
14579 var firstSuspendedTime = root.firstSuspendedTime;
14580
14581 if (firstSuspendedTime !== NoWork) {
14582 if (expirationTime >= firstSuspendedTime) {
14583 // The entire suspended range is now unsuspended.
14584 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
14585 } else if (expirationTime >= root.lastSuspendedTime) {
14586 root.lastSuspendedTime = expirationTime + 1;
14587 } // This is a pending level. Check if it's higher priority than the next
14588 // known pending level.
14589
14590
14591 if (expirationTime > root.nextKnownPendingLevel) {
14592 root.nextKnownPendingLevel = expirationTime;
14593 }
14594 }
14595}
14596function markRootFinishedAtTime(root, finishedExpirationTime, remainingExpirationTime) {
14597 // Update the range of pending times
14598 root.firstPendingTime = remainingExpirationTime; // Update the range of suspended times. Treat everything higher priority or
14599 // equal to this update as unsuspended.
14600
14601 if (finishedExpirationTime <= root.lastSuspendedTime) {
14602 // The entire suspended range is now unsuspended.
14603 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
14604 } else if (finishedExpirationTime <= root.firstSuspendedTime) {
14605 // Part of the suspended range is now unsuspended. Narrow the range to
14606 // include everything between the unsuspended time (non-inclusive) and the
14607 // last suspended time.
14608 root.firstSuspendedTime = finishedExpirationTime - 1;
14609 }
14610
14611 if (finishedExpirationTime <= root.lastPingedTime) {
14612 // Clear the pinged time
14613 root.lastPingedTime = NoWork;
14614 }
14615
14616 if (finishedExpirationTime <= root.lastExpiredTime) {
14617 // Clear the expired time
14618 root.lastExpiredTime = NoWork;
14619 }
14620}
14621function markRootExpiredAtTime(root, expirationTime) {
14622 var lastExpiredTime = root.lastExpiredTime;
14623
14624 if (lastExpiredTime === NoWork || lastExpiredTime > expirationTime) {
14625 root.lastExpiredTime = expirationTime;
14626 }
14627}
14628
14629var didWarnAboutMessageChannel = false;
14630var enqueueTaskImpl = null;
14631function enqueueTask(task) {
14632 if (enqueueTaskImpl === null) {
14633 try {
14634 // read require off the module object to get around the bundlers.
14635 // we don't want them to detect a require and bundle a Node polyfill.
14636 var requireString = ('require' + Math.random()).slice(0, 7);
14637 var nodeRequire = module && module[requireString]; // assuming we're in node, let's try to get node's
14638 // version of setImmediate, bypassing fake timers if any.
14639
14640 enqueueTaskImpl = nodeRequire('timers').setImmediate;
14641 } catch (_err) {
14642 // we're in a browser
14643 // we can't use regular timers because they may still be faked
14644 // so we try MessageChannel+postMessage instead
14645 enqueueTaskImpl = function (callback) {
14646 {
14647 if (didWarnAboutMessageChannel === false) {
14648 didWarnAboutMessageChannel = true;
14649
14650 if (typeof MessageChannel === 'undefined') {
14651 error('This browser does not have a MessageChannel implementation, ' + 'so enqueuing tasks via await act(async () => ...) will fail. ' + 'Please file an issue at https://github.com/facebook/react/issues ' + 'if you encounter this warning.');
14652 }
14653 }
14654 }
14655
14656 var channel = new MessageChannel();
14657 channel.port1.onmessage = callback;
14658 channel.port2.postMessage(undefined);
14659 };
14660 }
14661 }
14662
14663 return enqueueTaskImpl(task);
14664}
14665
14666var didWarnAboutNestedUpdates;
14667
14668{
14669 didWarnAboutNestedUpdates = false;
14670}
14671
14672function getContextForSubtree(parentComponent) {
14673 if (!parentComponent) {
14674 return emptyContextObject;
14675 }
14676
14677 var fiber = get(parentComponent);
14678 var parentContext = findCurrentUnmaskedContext(fiber);
14679
14680 if (fiber.tag === ClassComponent) {
14681 var Component = fiber.type;
14682
14683 if (isContextProvider(Component)) {
14684 return processChildContext(fiber, Component, parentContext);
14685 }
14686 }
14687
14688 return parentContext;
14689}
14690
14691function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) {
14692 return createFiberRoot(containerInfo, tag, hydrate);
14693}
14694function updateContainer(element, container, parentComponent, callback) {
14695 {
14696 onScheduleRoot(container, element);
14697 }
14698
14699 var current$1 = container.current;
14700 var currentTime = requestCurrentTimeForUpdate();
14701
14702 {
14703 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
14704 if ('undefined' !== typeof jest) {
14705 warnIfUnmockedScheduler(current$1);
14706 warnIfNotScopedWithMatchingAct(current$1);
14707 }
14708 }
14709
14710 var suspenseConfig = requestCurrentSuspenseConfig();
14711 var expirationTime = computeExpirationForFiber(currentTime, current$1, suspenseConfig);
14712 var context = getContextForSubtree(parentComponent);
14713
14714 if (container.context === null) {
14715 container.context = context;
14716 } else {
14717 container.pendingContext = context;
14718 }
14719
14720 {
14721 if (isRendering && current !== null && !didWarnAboutNestedUpdates) {
14722 didWarnAboutNestedUpdates = true;
14723
14724 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.', getComponentName(current.type) || 'Unknown');
14725 }
14726 }
14727
14728 var update = createUpdate(expirationTime, suspenseConfig); // Caution: React DevTools currently depends on this property
14729 // being called "element".
14730
14731 update.payload = {
14732 element: element
14733 };
14734 callback = callback === undefined ? null : callback;
14735
14736 if (callback !== null) {
14737 {
14738 if (typeof callback !== 'function') {
14739 error('render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
14740 }
14741 }
14742
14743 update.callback = callback;
14744 }
14745
14746 enqueueUpdate(current$1, update);
14747 scheduleWork(current$1, expirationTime);
14748 return expirationTime;
14749}
14750function getPublicRootInstance(container) {
14751 var containerFiber = container.current;
14752
14753 if (!containerFiber.child) {
14754 return null;
14755 }
14756
14757 switch (containerFiber.child.tag) {
14758 case HostComponent:
14759 return getPublicInstance(containerFiber.child.stateNode);
14760
14761 default:
14762 return containerFiber.child.stateNode;
14763 }
14764}
14765
14766var shouldSuspendImpl = function (fiber) {
14767 return false;
14768};
14769
14770function shouldSuspend(fiber) {
14771 return shouldSuspendImpl(fiber);
14772}
14773var overrideHookState = null;
14774var overrideProps = null;
14775var scheduleUpdate = null;
14776var setSuspenseHandler = null;
14777
14778{
14779 var copyWithSetImpl = function (obj, path, idx, value) {
14780 if (idx >= path.length) {
14781 return value;
14782 }
14783
14784 var key = path[idx];
14785 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj); // $FlowFixMe number or string is fine here
14786
14787 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
14788 return updated;
14789 };
14790
14791 var copyWithSet = function (obj, path, value) {
14792 return copyWithSetImpl(obj, path, 0, value);
14793 }; // Support DevTools editable values for useState and useReducer.
14794
14795
14796 overrideHookState = function (fiber, id, path, value) {
14797 // For now, the "id" of stateful hooks is just the stateful hook index.
14798 // This may change in the future with e.g. nested hooks.
14799 var currentHook = fiber.memoizedState;
14800
14801 while (currentHook !== null && id > 0) {
14802 currentHook = currentHook.next;
14803 id--;
14804 }
14805
14806 if (currentHook !== null) {
14807 var newState = copyWithSet(currentHook.memoizedState, path, value);
14808 currentHook.memoizedState = newState;
14809 currentHook.baseState = newState; // We aren't actually adding an update to the queue,
14810 // because there is no update we can add for useReducer hooks that won't trigger an error.
14811 // (There's no appropriate action type for DevTools overrides.)
14812 // As a result though, React will see the scheduled update as a noop and bailout.
14813 // Shallow cloning props works as a workaround for now to bypass the bailout check.
14814
14815 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
14816 scheduleWork(fiber, Sync);
14817 }
14818 }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
14819
14820
14821 overrideProps = function (fiber, path, value) {
14822 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
14823
14824 if (fiber.alternate) {
14825 fiber.alternate.pendingProps = fiber.pendingProps;
14826 }
14827
14828 scheduleWork(fiber, Sync);
14829 };
14830
14831 scheduleUpdate = function (fiber) {
14832 scheduleWork(fiber, Sync);
14833 };
14834
14835 setSuspenseHandler = function (newShouldSuspendImpl) {
14836 shouldSuspendImpl = newShouldSuspendImpl;
14837 };
14838}
14839
14840function injectIntoDevTools(devToolsConfig) {
14841 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
14842 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
14843 return injectInternals(_assign({}, devToolsConfig, {
14844 overrideHookState: overrideHookState,
14845 overrideProps: overrideProps,
14846 setSuspenseHandler: setSuspenseHandler,
14847 scheduleUpdate: scheduleUpdate,
14848 currentDispatcherRef: ReactCurrentDispatcher,
14849 findHostInstanceByFiber: function (fiber) {
14850 var hostFiber = findCurrentHostFiber(fiber);
14851
14852 if (hostFiber === null) {
14853 return null;
14854 }
14855
14856 return hostFiber.stateNode;
14857 },
14858 findFiberByHostInstance: function (instance) {
14859 if (!findFiberByHostInstance) {
14860 // Might not be implemented by the renderer.
14861 return null;
14862 }
14863
14864 return findFiberByHostInstance(instance);
14865 },
14866 // React Refresh
14867 findHostInstancesForRefresh: findHostInstancesForRefresh ,
14868 scheduleRefresh: scheduleRefresh ,
14869 scheduleRoot: scheduleRoot ,
14870 setRefreshHandler: setRefreshHandler ,
14871 // Enables DevTools to append owner stacks to error messages in DEV mode.
14872 getCurrentFiber: function () {
14873 return current;
14874 }
14875 }));
14876}
14877var IsSomeRendererActing$1 = ReactSharedInternals.IsSomeRendererActing;
14878var isSchedulerMocked = typeof Scheduler$1.unstable_flushAllWithoutAsserting === 'function';
14879
14880var flushWork = Scheduler$1.unstable_flushAllWithoutAsserting || function () {
14881 var didFlushWork = false;
14882
14883 while (flushPassiveEffects()) {
14884 didFlushWork = true;
14885 }
14886
14887 return didFlushWork;
14888};
14889
14890function flushWorkAndMicroTasks(onDone) {
14891 try {
14892 flushWork();
14893 enqueueTask(function () {
14894 if (flushWork()) {
14895 flushWorkAndMicroTasks(onDone);
14896 } else {
14897 onDone();
14898 }
14899 });
14900 } catch (err) {
14901 onDone(err);
14902 }
14903} // we track the 'depth' of the act() calls with this counter,
14904// so we can tell if any async act() calls try to run in parallel.
14905
14906
14907var actingUpdatesScopeDepth = 0;
14908
14909function act(callback) {
14910
14911 var previousActingUpdatesScopeDepth = actingUpdatesScopeDepth;
14912 var previousIsSomeRendererActing;
14913 var previousIsThisRendererActing;
14914 actingUpdatesScopeDepth++;
14915 previousIsSomeRendererActing = IsSomeRendererActing$1.current;
14916 previousIsThisRendererActing = IsThisRendererActing.current;
14917 IsSomeRendererActing$1.current = true;
14918 IsThisRendererActing.current = true;
14919
14920 function onDone() {
14921 actingUpdatesScopeDepth--;
14922 IsSomeRendererActing$1.current = previousIsSomeRendererActing;
14923 IsThisRendererActing.current = previousIsThisRendererActing;
14924
14925 {
14926 if (actingUpdatesScopeDepth > previousActingUpdatesScopeDepth) {
14927 // if it's _less than_ previousActingUpdatesScopeDepth, then we can assume the 'other' one has warned
14928 error('You seem to have overlapping act() calls, this is not supported. ' + 'Be sure to await previous act() calls before making a new one. ');
14929 }
14930 }
14931 }
14932
14933 var result;
14934
14935 try {
14936 result = batchedUpdates(callback);
14937 } catch (error) {
14938 // on sync errors, we still want to 'cleanup' and decrement actingUpdatesScopeDepth
14939 onDone();
14940 throw error;
14941 }
14942
14943 if (result !== null && typeof result === 'object' && typeof result.then === 'function') {
14944 // setup a boolean that gets set to true only
14945 // once this act() call is await-ed
14946 var called = false;
14947
14948 {
14949 if (typeof Promise !== 'undefined') {
14950 //eslint-disable-next-line no-undef
14951 Promise.resolve().then(function () {}).then(function () {
14952 if (called === false) {
14953 error('You called act(async () => ...) without await. ' + 'This could lead to unexpected testing behaviour, interleaving multiple act ' + 'calls and mixing their scopes. You should - await act(async () => ...);');
14954 }
14955 });
14956 }
14957 } // in the async case, the returned thenable runs the callback, flushes
14958 // effects and microtasks in a loop until flushPassiveEffects() === false,
14959 // and cleans up
14960
14961
14962 return {
14963 then: function (resolve, reject) {
14964 called = true;
14965 result.then(function () {
14966 if (actingUpdatesScopeDepth > 1 || isSchedulerMocked === true && previousIsSomeRendererActing === true) {
14967 onDone();
14968 resolve();
14969 return;
14970 } // we're about to exit the act() scope,
14971 // now's the time to flush tasks/effects
14972
14973
14974 flushWorkAndMicroTasks(function (err) {
14975 onDone();
14976
14977 if (err) {
14978 reject(err);
14979 } else {
14980 resolve();
14981 }
14982 });
14983 }, function (err) {
14984 onDone();
14985 reject(err);
14986 });
14987 }
14988 };
14989 } else {
14990 {
14991 if (result !== undefined) {
14992 error('The callback passed to act(...) function ' + 'must return undefined, or a Promise. You returned %s', result);
14993 }
14994 } // flush effects until none remain, and cleanup
14995
14996
14997 try {
14998 if (actingUpdatesScopeDepth === 1 && (isSchedulerMocked === false || previousIsSomeRendererActing === false)) {
14999 // we're about to exit the act() scope,
15000 // now's the time to flush effects
15001 flushWork();
15002 }
15003
15004 onDone();
15005 } catch (err) {
15006 onDone();
15007 throw err;
15008 } // in the sync case, the returned thenable only warns *if* await-ed
15009
15010
15011 return {
15012 then: function (resolve) {
15013 {
15014 error('Do not await the result of calling act(...) with sync logic, it is not a Promise.');
15015 }
15016
15017 resolve();
15018 }
15019 };
15020 }
15021}
15022
15023var ReactVersion = '16.13.1';
15024
15025var defaultTestOptions = {
15026 createNodeMock: function () {
15027 return null;
15028 }
15029};
15030
15031function toJSON(inst) {
15032 if (inst.isHidden) {
15033 // Omit timed out children from output entirely. This seems like the least
15034 // surprising behavior. We could perhaps add a separate API that includes
15035 // them, if it turns out people need it.
15036 return null;
15037 }
15038
15039 switch (inst.tag) {
15040 case 'TEXT':
15041 return inst.text;
15042
15043 case 'INSTANCE':
15044 {
15045 /* eslint-disable no-unused-vars */
15046 // We don't include the `children` prop in JSON.
15047 // Instead, we will include the actual rendered children.
15048 var _inst$props = inst.props,
15049 children = _inst$props.children,
15050 props = _objectWithoutPropertiesLoose(_inst$props, ["children"]);
15051 /* eslint-enable */
15052
15053
15054 var renderedChildren = null;
15055
15056 if (inst.children && inst.children.length) {
15057 for (var i = 0; i < inst.children.length; i++) {
15058 var renderedChild = toJSON(inst.children[i]);
15059
15060 if (renderedChild !== null) {
15061 if (renderedChildren === null) {
15062 renderedChildren = [renderedChild];
15063 } else {
15064 renderedChildren.push(renderedChild);
15065 }
15066 }
15067 }
15068 }
15069
15070 var json = {
15071 type: inst.type,
15072 props: props,
15073 children: renderedChildren
15074 };
15075 Object.defineProperty(json, '$$typeof', {
15076 value: Symbol.for('react.test.json')
15077 });
15078 return json;
15079 }
15080
15081 default:
15082 throw new Error("Unexpected node type in toJSON: " + inst.tag);
15083 }
15084}
15085
15086function childrenToTree(node) {
15087 if (!node) {
15088 return null;
15089 }
15090
15091 var children = nodeAndSiblingsArray(node);
15092
15093 if (children.length === 0) {
15094 return null;
15095 } else if (children.length === 1) {
15096 return toTree(children[0]);
15097 }
15098
15099 return flatten(children.map(toTree));
15100}
15101
15102function nodeAndSiblingsArray(nodeWithSibling) {
15103 var array = [];
15104 var node = nodeWithSibling;
15105
15106 while (node != null) {
15107 array.push(node);
15108 node = node.sibling;
15109 }
15110
15111 return array;
15112}
15113
15114function flatten(arr) {
15115 var result = [];
15116 var stack = [{
15117 i: 0,
15118 array: arr
15119 }];
15120
15121 while (stack.length) {
15122 var n = stack.pop();
15123
15124 while (n.i < n.array.length) {
15125 var el = n.array[n.i];
15126 n.i += 1;
15127
15128 if (Array.isArray(el)) {
15129 stack.push(n);
15130 stack.push({
15131 i: 0,
15132 array: el
15133 });
15134 break;
15135 }
15136
15137 result.push(el);
15138 }
15139 }
15140
15141 return result;
15142}
15143
15144function toTree(node) {
15145 if (node == null) {
15146 return null;
15147 }
15148
15149 switch (node.tag) {
15150 case HostRoot:
15151 return childrenToTree(node.child);
15152
15153 case HostPortal:
15154 return childrenToTree(node.child);
15155
15156 case ClassComponent:
15157 return {
15158 nodeType: 'component',
15159 type: node.type,
15160 props: _assign({}, node.memoizedProps),
15161 instance: node.stateNode,
15162 rendered: childrenToTree(node.child)
15163 };
15164
15165 case FunctionComponent:
15166 case SimpleMemoComponent:
15167 return {
15168 nodeType: 'component',
15169 type: node.type,
15170 props: _assign({}, node.memoizedProps),
15171 instance: null,
15172 rendered: childrenToTree(node.child)
15173 };
15174
15175 case Block:
15176 return {
15177 nodeType: 'block',
15178 type: node.type,
15179 props: _assign({}, node.memoizedProps),
15180 instance: null,
15181 rendered: childrenToTree(node.child)
15182 };
15183
15184 case HostComponent:
15185 {
15186 return {
15187 nodeType: 'host',
15188 type: node.type,
15189 props: _assign({}, node.memoizedProps),
15190 instance: null,
15191 // TODO: use createNodeMock here somehow?
15192 rendered: flatten(nodeAndSiblingsArray(node.child).map(toTree))
15193 };
15194 }
15195
15196 case HostText:
15197 return node.stateNode.text;
15198
15199 case Fragment:
15200 case ContextProvider:
15201 case ContextConsumer:
15202 case Mode:
15203 case Profiler:
15204 case ForwardRef:
15205 case MemoComponent:
15206 case IncompleteClassComponent:
15207 case ScopeComponent:
15208 return childrenToTree(node.child);
15209
15210 default:
15211 {
15212 {
15213 throw Error( "toTree() does not yet know how to handle nodes with tag=" + node.tag );
15214 }
15215 }
15216
15217 }
15218}
15219
15220var validWrapperTypes = new Set([FunctionComponent, ClassComponent, HostComponent, ForwardRef, MemoComponent, SimpleMemoComponent, Block, // Normally skipped, but used when there's more than one root child.
15221HostRoot]);
15222
15223function getChildren(parent) {
15224 var children = [];
15225 var startingNode = parent;
15226 var node = startingNode;
15227
15228 if (node.child === null) {
15229 return children;
15230 }
15231
15232 node.child.return = node;
15233 node = node.child;
15234
15235 outer: while (true) {
15236 var descend = false;
15237
15238 if (validWrapperTypes.has(node.tag)) {
15239 children.push(wrapFiber(node));
15240 } else if (node.tag === HostText) {
15241 children.push('' + node.memoizedProps);
15242 } else {
15243 descend = true;
15244 }
15245
15246 if (descend && node.child !== null) {
15247 node.child.return = node;
15248 node = node.child;
15249 continue;
15250 }
15251
15252 while (node.sibling === null) {
15253 if (node.return === startingNode) {
15254 break outer;
15255 }
15256
15257 node = node.return;
15258 }
15259
15260 node.sibling.return = node.return;
15261 node = node.sibling;
15262 }
15263
15264 return children;
15265}
15266
15267var ReactTestInstance =
15268/*#__PURE__*/
15269function () {
15270 var _proto = ReactTestInstance.prototype;
15271
15272 _proto._currentFiber = function _currentFiber() {
15273 // Throws if this component has been unmounted.
15274 var fiber = findCurrentFiberUsingSlowPath(this._fiber);
15275
15276 if (!(fiber !== null)) {
15277 {
15278 throw Error( "Can't read from currently-mounting component. This error is likely caused by a bug in React. Please file an issue." );
15279 }
15280 }
15281
15282 return fiber;
15283 };
15284
15285 function ReactTestInstance(fiber) {
15286 if (!validWrapperTypes.has(fiber.tag)) {
15287 {
15288 throw Error( "Unexpected object passed to ReactTestInstance constructor (tag: " + fiber.tag + "). This is probably a bug in React." );
15289 }
15290 }
15291
15292 this._fiber = fiber;
15293 }
15294
15295 // Custom search functions
15296 _proto.find = function find(predicate) {
15297 return expectOne(this.findAll(predicate, {
15298 deep: false
15299 }), "matching custom predicate: " + predicate.toString());
15300 };
15301
15302 _proto.findByType = function findByType(type) {
15303 return expectOne(this.findAllByType(type, {
15304 deep: false
15305 }), "with node type: \"" + (type.displayName || type.name) + "\"");
15306 };
15307
15308 _proto.findByProps = function findByProps(props) {
15309 return expectOne(this.findAllByProps(props, {
15310 deep: false
15311 }), "with props: " + JSON.stringify(props));
15312 };
15313
15314 _proto.findAll = function findAll(predicate) {
15315 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
15316 return _findAll(this, predicate, options);
15317 };
15318
15319 _proto.findAllByType = function findAllByType(type) {
15320 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
15321 return _findAll(this, function (node) {
15322 return node.type === type;
15323 }, options);
15324 };
15325
15326 _proto.findAllByProps = function findAllByProps(props) {
15327 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
15328 return _findAll(this, function (node) {
15329 return node.props && propsMatch(node.props, props);
15330 }, options);
15331 };
15332
15333 _createClass(ReactTestInstance, [{
15334 key: "instance",
15335 get: function () {
15336 if (this._fiber.tag === HostComponent) {
15337 return getPublicInstance(this._fiber.stateNode);
15338 } else {
15339 return this._fiber.stateNode;
15340 }
15341 }
15342 }, {
15343 key: "type",
15344 get: function () {
15345 return this._fiber.type;
15346 }
15347 }, {
15348 key: "props",
15349 get: function () {
15350 return this._currentFiber().memoizedProps;
15351 }
15352 }, {
15353 key: "parent",
15354 get: function () {
15355 var parent = this._fiber.return;
15356
15357 while (parent !== null) {
15358 if (validWrapperTypes.has(parent.tag)) {
15359 if (parent.tag === HostRoot) {
15360 // Special case: we only "materialize" instances for roots
15361 // if they have more than a single child. So we'll check that now.
15362 if (getChildren(parent).length < 2) {
15363 return null;
15364 }
15365 }
15366
15367 return wrapFiber(parent);
15368 }
15369
15370 parent = parent.return;
15371 }
15372
15373 return null;
15374 }
15375 }, {
15376 key: "children",
15377 get: function () {
15378 return getChildren(this._currentFiber());
15379 }
15380 }]);
15381
15382 return ReactTestInstance;
15383}();
15384
15385function _findAll(root, predicate, options) {
15386 var deep = options ? options.deep : true;
15387 var results = [];
15388
15389 if (predicate(root)) {
15390 results.push(root);
15391
15392 if (!deep) {
15393 return results;
15394 }
15395 }
15396
15397 root.children.forEach(function (child) {
15398 if (typeof child === 'string') {
15399 return;
15400 }
15401
15402 results.push.apply(results, _findAll(child, predicate, options));
15403 });
15404 return results;
15405}
15406
15407function expectOne(all, message) {
15408 if (all.length === 1) {
15409 return all[0];
15410 }
15411
15412 var prefix = all.length === 0 ? 'No instances found ' : "Expected 1 but found " + all.length + " instances ";
15413 throw new Error(prefix + message);
15414}
15415
15416function propsMatch(props, filter) {
15417 for (var key in filter) {
15418 if (props[key] !== filter[key]) {
15419 return false;
15420 }
15421 }
15422
15423 return true;
15424}
15425
15426var ReactTestRendererFiber = {
15427 _Scheduler: Scheduler,
15428 create: function (element, options) {
15429 var createNodeMock = defaultTestOptions.createNodeMock;
15430 var isConcurrent = false;
15431
15432 if (typeof options === 'object' && options !== null) {
15433 if (typeof options.createNodeMock === 'function') {
15434 createNodeMock = options.createNodeMock;
15435 }
15436
15437 if (options.unstable_isConcurrent === true) {
15438 isConcurrent = true;
15439 }
15440 }
15441
15442 var container = {
15443 children: [],
15444 createNodeMock: createNodeMock,
15445 tag: 'CONTAINER'
15446 };
15447 var root = createContainer(container, isConcurrent ? ConcurrentRoot : LegacyRoot, false);
15448
15449 if (!(root != null)) {
15450 {
15451 throw Error( "something went wrong" );
15452 }
15453 }
15454
15455 updateContainer(element, root, null, null);
15456 var entry = {
15457 _Scheduler: Scheduler,
15458 root: undefined,
15459 // makes flow happy
15460 // we define a 'getter' for 'root' below using 'Object.defineProperty'
15461 toJSON: function () {
15462 if (root == null || root.current == null || container == null) {
15463 return null;
15464 }
15465
15466 if (container.children.length === 0) {
15467 return null;
15468 }
15469
15470 if (container.children.length === 1) {
15471 return toJSON(container.children[0]);
15472 }
15473
15474 if (container.children.length === 2 && container.children[0].isHidden === true && container.children[1].isHidden === false) {
15475 // Omit timed out children from output entirely, including the fact that we
15476 // temporarily wrap fallback and timed out children in an array.
15477 return toJSON(container.children[1]);
15478 }
15479
15480 var renderedChildren = null;
15481
15482 if (container.children && container.children.length) {
15483 for (var i = 0; i < container.children.length; i++) {
15484 var renderedChild = toJSON(container.children[i]);
15485
15486 if (renderedChild !== null) {
15487 if (renderedChildren === null) {
15488 renderedChildren = [renderedChild];
15489 } else {
15490 renderedChildren.push(renderedChild);
15491 }
15492 }
15493 }
15494 }
15495
15496 return renderedChildren;
15497 },
15498 toTree: function () {
15499 if (root == null || root.current == null) {
15500 return null;
15501 }
15502
15503 return toTree(root.current);
15504 },
15505 update: function (newElement) {
15506 if (root == null || root.current == null) {
15507 return;
15508 }
15509
15510 updateContainer(newElement, root, null, null);
15511 },
15512 unmount: function () {
15513 if (root == null || root.current == null) {
15514 return;
15515 }
15516
15517 updateContainer(null, root, null, null);
15518 container = null;
15519 root = null;
15520 },
15521 getInstance: function () {
15522 if (root == null || root.current == null) {
15523 return null;
15524 }
15525
15526 return getPublicRootInstance(root);
15527 },
15528 unstable_flushSync: function (fn) {
15529 return flushSync(fn);
15530 }
15531 };
15532 Object.defineProperty(entry, 'root', {
15533 configurable: true,
15534 enumerable: true,
15535 get: function () {
15536 if (root === null) {
15537 throw new Error("Can't access .root on unmounted test renderer");
15538 }
15539
15540 var children = getChildren(root.current);
15541
15542 if (children.length === 0) {
15543 throw new Error("Can't access .root on unmounted test renderer");
15544 } else if (children.length === 1) {
15545 // Normally, we skip the root and just give you the child.
15546 return children[0];
15547 } else {
15548 // However, we give you the root if there's more than one root child.
15549 // We could make this the behavior for all cases but it would be a breaking change.
15550 return wrapFiber(root.current);
15551 }
15552 }
15553 });
15554 return entry;
15555 },
15556
15557 /* eslint-disable-next-line camelcase */
15558 unstable_batchedUpdates: batchedUpdates,
15559 act: act
15560};
15561var fiberToWrapper = new WeakMap();
15562
15563function wrapFiber(fiber) {
15564 var wrapper = fiberToWrapper.get(fiber);
15565
15566 if (wrapper === undefined && fiber.alternate !== null) {
15567 wrapper = fiberToWrapper.get(fiber.alternate);
15568 }
15569
15570 if (wrapper === undefined) {
15571 wrapper = new ReactTestInstance(fiber);
15572 fiberToWrapper.set(fiber, wrapper);
15573 }
15574
15575 return wrapper;
15576} // Enable ReactTestRenderer to be used to test DevTools integration.
15577
15578
15579injectIntoDevTools({
15580 findFiberByHostInstance: function () {
15581 throw new Error('TestRenderer does not support findFiberByHostInstance()');
15582 },
15583 bundleType: 1 ,
15584 version: ReactVersion,
15585 rendererPackageName: 'react-test-renderer'
15586});
15587
15588// TODO: decide on the top-level export form.
15589// This is hacky but makes it work with both Rollup and Jest.
15590
15591
15592var reactTestRenderer = ReactTestRendererFiber.default || ReactTestRendererFiber;
15593
15594module.exports = reactTestRenderer;
15595 })();
15596}