UNPKG

600 kBJavaScriptView Raw
1/** @license React v16.9.0-rc.0
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
25// Do not require this module directly! Use normal `invariant` calls with
26// template literal strings. The messages will be converted to ReactError during
27// build, and in production they will be minified.
28
29// Do not require this module directly! Use normal `invariant` calls with
30// template literal strings. The messages will be converted to ReactError during
31// build, and in production they will be minified.
32
33function ReactError(error) {
34 error.name = 'Invariant Violation';
35 return error;
36}
37
38var FunctionComponent = 0;
39var ClassComponent = 1;
40var IndeterminateComponent = 2; // Before we know whether it is function or class
41var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
42var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
43var HostComponent = 5;
44var HostText = 6;
45var Fragment = 7;
46var Mode = 8;
47var ContextConsumer = 9;
48var ContextProvider = 10;
49var ForwardRef = 11;
50var Profiler = 12;
51var SuspenseComponent = 13;
52var MemoComponent = 14;
53var SimpleMemoComponent = 15;
54var LazyComponent = 16;
55var IncompleteClassComponent = 17;
56var DehydratedSuspenseComponent = 18;
57var SuspenseListComponent = 19;
58var FundamentalComponent = 20;
59
60/**
61 * Use invariant() to assert state which your program assumes to be true.
62 *
63 * Provide sprintf-style format (only %s is supported) and arguments
64 * to provide information about what broke and what you were
65 * expecting.
66 *
67 * The invariant message will be stripped in production, but the invariant
68 * will remain to ensure logic does not differ in production.
69 */
70
71/**
72 * Similar to invariant but only logs a warning if the condition is not met.
73 * This can be used to log issues in development environments in critical
74 * paths. Removing the logging code for production environments will keep the
75 * same logic and follow the same code paths.
76 */
77
78var warningWithoutStack = function () {};
79
80{
81 warningWithoutStack = function (condition, format) {
82 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
83 args[_key - 2] = arguments[_key];
84 }
85
86 if (format === undefined) {
87 throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
88 }
89 if (args.length > 8) {
90 // Check before the condition to catch violations early.
91 throw new Error('warningWithoutStack() currently supports at most 8 arguments.');
92 }
93 if (condition) {
94 return;
95 }
96 if (typeof console !== 'undefined') {
97 var argsWithFormat = args.map(function (item) {
98 return '' + item;
99 });
100 argsWithFormat.unshift('Warning: ' + format);
101
102 // We intentionally don't use spread (or .apply) directly because it
103 // breaks IE9: https://github.com/facebook/react/issues/13610
104 Function.prototype.apply.call(console.error, console, argsWithFormat);
105 }
106 try {
107 // --- Welcome to debugging React ---
108 // This error was thrown as a convenience so that you can use this stack
109 // to find the callsite that caused this warning to fire.
110 var argIndex = 0;
111 var message = 'Warning: ' + format.replace(/%s/g, function () {
112 return args[argIndex++];
113 });
114 throw new Error(message);
115 } catch (x) {}
116 };
117}
118
119var warningWithoutStack$1 = warningWithoutStack;
120
121/**
122 * `ReactInstanceMap` maintains a mapping from a public facing stateful
123 * instance (key) and the internal representation (value). This allows public
124 * methods to accept the user facing instance as an argument and map them back
125 * to internal methods.
126 *
127 * Note that this module is currently shared and assumed to be stateless.
128 * If this becomes an actual Map, that will break.
129 */
130
131/**
132 * This API should be called `delete` but we'd have to make sure to always
133 * transform these to strings for IE support. When this transform is fully
134 * supported we can rename it.
135 */
136
137
138function get(key) {
139 return key._reactInternalFiber;
140}
141
142
143
144function set(key, value) {
145 key._reactInternalFiber = value;
146}
147
148var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
149
150// Prevent newer renderers from RTE when used with older react package versions.
151// Current owner and dispatcher used to share the same ref,
152// but PR #14548 split them out to better support the react-debug-tools package.
153if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
154 ReactSharedInternals.ReactCurrentDispatcher = {
155 current: null
156 };
157}
158if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {
159 ReactSharedInternals.ReactCurrentBatchConfig = {
160 suspense: null
161 };
162}
163
164// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
165// nor polyfill, then a plain number is used for performance.
166var hasSymbol = typeof Symbol === 'function' && Symbol.for;
167
168var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
169var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
170var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
171var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
172var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
173var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
174var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace;
175// TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
176// (unstable) APIs that have been removed. Can we remove the symbols?
177
178var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
179var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
180var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
181var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
182var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
183var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
184var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for('react.fundamental') : 0xead5;
185var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for('react.responder') : 0xead6;
186
187var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
188var FAUX_ITERATOR_SYMBOL = '@@iterator';
189
190function getIteratorFn(maybeIterable) {
191 if (maybeIterable === null || typeof maybeIterable !== 'object') {
192 return null;
193 }
194 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
195 if (typeof maybeIterator === 'function') {
196 return maybeIterator;
197 }
198 return null;
199}
200
201var Pending = 0;
202var Resolved = 1;
203var Rejected = 2;
204
205function refineResolvedLazyComponent(lazyComponent) {
206 return lazyComponent._status === Resolved ? lazyComponent._result : null;
207}
208
209function getWrappedName(outerType, innerType, wrapperName) {
210 var functionName = innerType.displayName || innerType.name || '';
211 return outerType.displayName || (functionName !== '' ? wrapperName + '(' + functionName + ')' : wrapperName);
212}
213
214function getComponentName(type) {
215 if (type == null) {
216 // Host root, text node or just invalid type.
217 return null;
218 }
219 {
220 if (typeof type.tag === 'number') {
221 warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
222 }
223 }
224 if (typeof type === 'function') {
225 return type.displayName || type.name || null;
226 }
227 if (typeof type === 'string') {
228 return type;
229 }
230 switch (type) {
231 case REACT_FRAGMENT_TYPE:
232 return 'Fragment';
233 case REACT_PORTAL_TYPE:
234 return 'Portal';
235 case REACT_PROFILER_TYPE:
236 return 'Profiler';
237 case REACT_STRICT_MODE_TYPE:
238 return 'StrictMode';
239 case REACT_SUSPENSE_TYPE:
240 return 'Suspense';
241 case REACT_SUSPENSE_LIST_TYPE:
242 return 'SuspenseList';
243 }
244 if (typeof type === 'object') {
245 switch (type.$$typeof) {
246 case REACT_CONTEXT_TYPE:
247 return 'Context.Consumer';
248 case REACT_PROVIDER_TYPE:
249 return 'Context.Provider';
250 case REACT_FORWARD_REF_TYPE:
251 return getWrappedName(type, type.render, 'ForwardRef');
252 case REACT_MEMO_TYPE:
253 return getComponentName(type.type);
254 case REACT_LAZY_TYPE:
255 {
256 var thenable = type;
257 var resolvedThenable = refineResolvedLazyComponent(thenable);
258 if (resolvedThenable) {
259 return getComponentName(resolvedThenable);
260 }
261 break;
262 }
263 }
264 }
265 return null;
266}
267
268// Don't change these two values. They're used by React Dev Tools.
269var NoEffect = /* */0;
270var PerformedWork = /* */1;
271
272// You can change the rest (and add more).
273var Placement = /* */2;
274var Update = /* */4;
275var PlacementAndUpdate = /* */6;
276var Deletion = /* */8;
277var ContentReset = /* */16;
278var Callback = /* */32;
279var DidCapture = /* */64;
280var Ref = /* */128;
281var Snapshot = /* */256;
282var Passive = /* */512;
283
284// Passive & Update & Callback & Ref & Snapshot
285var LifecycleEffectMask = /* */932;
286
287// Union of all host effects
288var HostEffectMask = /* */1023;
289
290var Incomplete = /* */1024;
291var ShouldCapture = /* */2048;
292
293var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
294
295var MOUNTING = 1;
296var MOUNTED = 2;
297var UNMOUNTED = 3;
298
299function isFiberMountedImpl(fiber) {
300 var node = fiber;
301 if (!fiber.alternate) {
302 // If there is no alternate, this might be a new tree that isn't inserted
303 // yet. If it is, then it will have a pending insertion effect on it.
304 if ((node.effectTag & Placement) !== NoEffect) {
305 return MOUNTING;
306 }
307 while (node.return) {
308 node = node.return;
309 if ((node.effectTag & Placement) !== NoEffect) {
310 return MOUNTING;
311 }
312 }
313 } else {
314 while (node.return) {
315 node = node.return;
316 }
317 }
318 if (node.tag === HostRoot) {
319 // TODO: Check if this was a nested HostRoot when used with
320 // renderContainerIntoSubtree.
321 return MOUNTED;
322 }
323 // If we didn't hit the root, that means that we're in an disconnected tree
324 // that has been unmounted.
325 return UNMOUNTED;
326}
327
328function isFiberMounted(fiber) {
329 return isFiberMountedImpl(fiber) === MOUNTED;
330}
331
332function isMounted(component) {
333 {
334 var owner = ReactCurrentOwner.current;
335 if (owner !== null && owner.tag === ClassComponent) {
336 var ownerFiber = owner;
337 var instance = ownerFiber.stateNode;
338 !instance._warnedAboutRefsInRender ? warningWithoutStack$1(false, '%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') : void 0;
339 instance._warnedAboutRefsInRender = true;
340 }
341 }
342
343 var fiber = get(component);
344 if (!fiber) {
345 return false;
346 }
347 return isFiberMountedImpl(fiber) === MOUNTED;
348}
349
350function assertIsMounted(fiber) {
351 (function () {
352 if (!(isFiberMountedImpl(fiber) === MOUNTED)) {
353 {
354 throw ReactError(Error('Unable to find node on an unmounted component.'));
355 }
356 }
357 })();
358}
359
360function findCurrentFiberUsingSlowPath(fiber) {
361 var alternate = fiber.alternate;
362 if (!alternate) {
363 // If there is no alternate, then we only need to check if it is mounted.
364 var state = isFiberMountedImpl(fiber);
365 (function () {
366 if (!(state !== UNMOUNTED)) {
367 {
368 throw ReactError(Error('Unable to find node on an unmounted component.'));
369 }
370 }
371 })();
372 if (state === MOUNTING) {
373 return null;
374 }
375 return fiber;
376 }
377 // If we have two possible branches, we'll walk backwards up to the root
378 // to see what path the root points to. On the way we may hit one of the
379 // special cases and we'll deal with them.
380 var a = fiber;
381 var b = alternate;
382 while (true) {
383 var parentA = a.return;
384 if (parentA === null) {
385 // We're at the root.
386 break;
387 }
388 var parentB = parentA.alternate;
389 if (parentB === null) {
390 // There is no alternate. This is an unusual case. Currently, it only
391 // happens when a Suspense component is hidden. An extra fragment fiber
392 // is inserted in between the Suspense fiber and its children. Skip
393 // over this extra fragment fiber and proceed to the next parent.
394 var nextParent = parentA.return;
395 if (nextParent !== null) {
396 a = b = nextParent;
397 continue;
398 }
399 // If there's no parent, we're at the root.
400 break;
401 }
402
403 // If both copies of the parent fiber point to the same child, we can
404 // assume that the child is current. This happens when we bailout on low
405 // priority: the bailed out fiber's child reuses the current child.
406 if (parentA.child === parentB.child) {
407 var child = parentA.child;
408 while (child) {
409 if (child === a) {
410 // We've determined that A is the current branch.
411 assertIsMounted(parentA);
412 return fiber;
413 }
414 if (child === b) {
415 // We've determined that B is the current branch.
416 assertIsMounted(parentA);
417 return alternate;
418 }
419 child = child.sibling;
420 }
421 // We should never have an alternate for any mounting node. So the only
422 // way this could possibly happen is if this was unmounted, if at all.
423 (function () {
424 {
425 {
426 throw ReactError(Error('Unable to find node on an unmounted component.'));
427 }
428 }
429 })();
430 }
431
432 if (a.return !== b.return) {
433 // The return pointer of A and the return pointer of B point to different
434 // fibers. We assume that return pointers never criss-cross, so A must
435 // belong to the child set of A.return, and B must belong to the child
436 // set of B.return.
437 a = parentA;
438 b = parentB;
439 } else {
440 // The return pointers point to the same fiber. We'll have to use the
441 // default, slow path: scan the child sets of each parent alternate to see
442 // which child belongs to which set.
443 //
444 // Search parent A's child set
445 var didFindChild = false;
446 var _child = parentA.child;
447 while (_child) {
448 if (_child === a) {
449 didFindChild = true;
450 a = parentA;
451 b = parentB;
452 break;
453 }
454 if (_child === b) {
455 didFindChild = true;
456 b = parentA;
457 a = parentB;
458 break;
459 }
460 _child = _child.sibling;
461 }
462 if (!didFindChild) {
463 // Search parent B's child set
464 _child = parentB.child;
465 while (_child) {
466 if (_child === a) {
467 didFindChild = true;
468 a = parentB;
469 b = parentA;
470 break;
471 }
472 if (_child === b) {
473 didFindChild = true;
474 b = parentB;
475 a = parentA;
476 break;
477 }
478 _child = _child.sibling;
479 }
480 (function () {
481 if (!didFindChild) {
482 {
483 throw ReactError(Error('Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.'));
484 }
485 }
486 })();
487 }
488 }
489
490 (function () {
491 if (!(a.alternate === b)) {
492 {
493 throw ReactError(Error('Return fibers should always be each others\' alternates. This error is likely caused by a bug in React. Please file an issue.'));
494 }
495 }
496 })();
497 }
498 // If the root is not a host container, we're in a disconnected tree. I.e.
499 // unmounted.
500 (function () {
501 if (!(a.tag === HostRoot)) {
502 {
503 throw ReactError(Error('Unable to find node on an unmounted component.'));
504 }
505 }
506 })();
507 if (a.stateNode.current === a) {
508 // We've determined that A is the current branch.
509 return fiber;
510 }
511 // Otherwise B has to be current branch.
512 return alternate;
513}
514
515function findCurrentHostFiber(parent) {
516 var currentParent = findCurrentFiberUsingSlowPath(parent);
517 if (!currentParent) {
518 return null;
519 }
520
521 // Next we'll drill down this component to find the first HostComponent/Text.
522 var node = currentParent;
523 while (true) {
524 if (node.tag === HostComponent || node.tag === HostText) {
525 return node;
526 } else if (node.child) {
527 node.child.return = node;
528 node = node.child;
529 continue;
530 }
531 if (node === currentParent) {
532 return null;
533 }
534 while (!node.sibling) {
535 if (!node.return || node.return === currentParent) {
536 return null;
537 }
538 node = node.return;
539 }
540 node.sibling.return = node.return;
541 node = node.sibling;
542 }
543 // Flow needs the return null here, but ESLint complains about it.
544 // eslint-disable-next-line no-unreachable
545 return null;
546}
547
548/**
549 * Similar to invariant but only logs a warning if the condition is not met.
550 * This can be used to log issues in development environments in critical
551 * paths. Removing the logging code for production environments will keep the
552 * same logic and follow the same code paths.
553 */
554
555var warning = warningWithoutStack$1;
556
557{
558 warning = function (condition, format) {
559 if (condition) {
560 return;
561 }
562 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
563 var stack = ReactDebugCurrentFrame.getStackAddendum();
564 // eslint-disable-next-line react-internal/warning-and-invariant-args
565
566 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
567 args[_key - 2] = arguments[_key];
568 }
569
570 warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack]));
571 };
572}
573
574var warning$1 = warning;
575
576var debugRenderPhaseSideEffects = false;
577var debugRenderPhaseSideEffectsForStrictMode = false;
578var enableUserTimingAPI = true;
579var warnAboutDeprecatedLifecycles = true;
580var replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
581var enableProfilerTimer = true;
582var enableSchedulerTracing = true;
583var enableSuspenseServerRenderer = false;
584
585
586
587
588
589
590var enableFlareAPI = false;
591var enableFundamentalAPI = false;
592
593var warnAboutUnmockedScheduler = false;
594var revertPassiveEffectsChange = false;
595var flushSuspenseFallbacksInTests = true;
596
597var enableSuspenseCallback = false;
598var warnAboutDefaultPropsOnFunctionComponents = false;
599var disableLegacyContext = false;
600var disableSchedulerTimeoutBasedOnReactExpirationTime = false;
601
602// Only used in www builds.
603
604// Renderers that don't support persistence
605// can re-export everything from this module.
606
607function shim() {
608 (function () {
609 {
610 {
611 throw ReactError(Error('The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue.'));
612 }
613 }
614 })();
615}
616
617// Persistence (when unsupported)
618var supportsPersistence = false;
619var cloneInstance = shim;
620var cloneFundamentalInstance = shim;
621var createContainerChildSet = shim;
622var appendChildToContainerChildSet = shim;
623var finalizeContainerChildren = shim;
624var replaceContainerChildren = shim;
625var cloneHiddenInstance = shim;
626var cloneHiddenTextInstance = shim;
627
628// Renderers that don't support hydration
629// can re-export everything from this module.
630
631function shim$1() {
632 (function () {
633 {
634 {
635 throw ReactError(Error('The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue.'));
636 }
637 }
638 })();
639}
640
641// Hydration (when unsupported)
642
643var supportsHydration = false;
644var canHydrateInstance = shim$1;
645var canHydrateTextInstance = shim$1;
646var canHydrateSuspenseInstance = shim$1;
647var isSuspenseInstancePending = shim$1;
648var isSuspenseInstanceFallback = shim$1;
649var registerSuspenseInstanceRetry = shim$1;
650var getNextHydratableSibling = shim$1;
651var getFirstHydratableChild = shim$1;
652var hydrateInstance = shim$1;
653var hydrateTextInstance = shim$1;
654var getNextHydratableInstanceAfterSuspenseInstance = shim$1;
655var clearSuspenseBoundary = shim$1;
656var clearSuspenseBoundaryFromContainer = shim$1;
657var didNotMatchHydratedContainerTextInstance = shim$1;
658var didNotMatchHydratedTextInstance = shim$1;
659var didNotHydrateContainerInstance = shim$1;
660var didNotHydrateInstance = shim$1;
661var didNotFindHydratableContainerInstance = shim$1;
662var didNotFindHydratableContainerTextInstance = shim$1;
663var didNotFindHydratableContainerSuspenseInstance = shim$1;
664var didNotFindHydratableInstance = shim$1;
665var didNotFindHydratableTextInstance = shim$1;
666var didNotFindHydratableSuspenseInstance = shim$1;
667
668function _objectWithoutProperties$1(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
669
670var EVENT_COMPONENT_CONTEXT = {};
671var NO_CONTEXT = {};
672var UPDATE_SIGNAL = {};
673{
674 Object.freeze(NO_CONTEXT);
675 Object.freeze(UPDATE_SIGNAL);
676}
677
678function getPublicInstance(inst) {
679 switch (inst.tag) {
680 case 'INSTANCE':
681 var _createNodeMock = inst.rootContainerInstance.createNodeMock;
682 return _createNodeMock({
683 type: inst.type,
684 props: inst.props
685 });
686 default:
687 return inst;
688 }
689}
690
691function appendChild(parentInstance, child) {
692 {
693 !Array.isArray(parentInstance.children) ? warning$1(false, '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.') : void 0;
694 }
695 var index = parentInstance.children.indexOf(child);
696 if (index !== -1) {
697 parentInstance.children.splice(index, 1);
698 }
699 parentInstance.children.push(child);
700}
701
702function insertBefore(parentInstance, child, beforeChild) {
703 var index = parentInstance.children.indexOf(child);
704 if (index !== -1) {
705 parentInstance.children.splice(index, 1);
706 }
707 var beforeIndex = parentInstance.children.indexOf(beforeChild);
708 parentInstance.children.splice(beforeIndex, 0, child);
709}
710
711function removeChild(parentInstance, child) {
712 var index = parentInstance.children.indexOf(child);
713 parentInstance.children.splice(index, 1);
714}
715
716function getRootHostContext(rootContainerInstance) {
717 return NO_CONTEXT;
718}
719
720function getChildHostContext(parentHostContext, type, rootContainerInstance) {
721 return NO_CONTEXT;
722}
723
724function prepareForCommit(containerInfo) {
725 // noop
726}
727
728function resetAfterCommit(containerInfo) {
729 // noop
730}
731
732function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
733 var propsToUse = props;
734 if (enableFlareAPI) {
735 if (props.listeners != null) {
736 // We want to remove the "listeners" prop
737 // as we don't want it in the test renderer's
738 // instance props.
739 var listeners = props.listeners,
740 otherProps = _objectWithoutProperties$1(props, ['listeners']); // eslint-disable-line
741
742
743 propsToUse = otherProps;
744 }
745 }
746 return {
747 type: type,
748 props: propsToUse,
749 isHidden: false,
750 children: [],
751 rootContainerInstance: rootContainerInstance,
752 tag: 'INSTANCE'
753 };
754}
755
756function appendInitialChild(parentInstance, child) {
757 var index = parentInstance.children.indexOf(child);
758 if (index !== -1) {
759 parentInstance.children.splice(index, 1);
760 }
761 parentInstance.children.push(child);
762}
763
764function finalizeInitialChildren(testElement, type, props, rootContainerInstance, hostContext) {
765 return false;
766}
767
768function prepareUpdate(testElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
769 return UPDATE_SIGNAL;
770}
771
772function shouldSetTextContent(type, props) {
773 return false;
774}
775
776function shouldDeprioritizeSubtree(type, props) {
777 return false;
778}
779
780function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
781 if (true && enableFlareAPI) {
782 !(hostContext !== EVENT_COMPONENT_CONTEXT) ? warning$1(false, 'validateDOMNesting: React event components cannot have text DOM nodes as children. ' + 'Wrap the child text "%s" in an element.', text) : void 0;
783 }
784 return {
785 text: text,
786 isHidden: false,
787 tag: 'TEXT'
788 };
789}
790
791var isPrimaryRenderer = false;
792var warnsIfNotActing = true;
793
794var scheduleTimeout = setTimeout;
795var cancelTimeout = clearTimeout;
796var noTimeout = -1;
797
798// -------------------
799// Mutation
800// -------------------
801
802var supportsMutation = true;
803
804function commitUpdate(instance, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
805 instance.type = type;
806 instance.props = newProps;
807}
808
809
810
811function commitTextUpdate(textInstance, oldText, newText) {
812 textInstance.text = newText;
813}
814
815function resetTextContent(testElement) {
816 // noop
817}
818
819var appendChildToContainer = appendChild;
820var insertInContainerBefore = insertBefore;
821var removeChildFromContainer = removeChild;
822
823function hideInstance(instance) {
824 instance.isHidden = true;
825}
826
827function hideTextInstance(textInstance) {
828 textInstance.isHidden = true;
829}
830
831function unhideInstance(instance, props) {
832 instance.isHidden = false;
833}
834
835function unhideTextInstance(textInstance, text) {
836 textInstance.isHidden = false;
837}
838
839
840
841
842
843function getFundamentalComponentInstance(fundamentalInstance) {
844 var impl = fundamentalInstance.impl,
845 props = fundamentalInstance.props,
846 state = fundamentalInstance.state;
847
848 return impl.getInstance(null, props, state);
849}
850
851function mountFundamentalComponent(fundamentalInstance) {
852 var impl = fundamentalInstance.impl,
853 instance = fundamentalInstance.instance,
854 props = fundamentalInstance.props,
855 state = fundamentalInstance.state;
856
857 var onMount = impl.onMount;
858 if (onMount !== undefined) {
859 onMount(null, instance, props, state);
860 }
861}
862
863function shouldUpdateFundamentalComponent(fundamentalInstance) {
864 var impl = fundamentalInstance.impl,
865 prevProps = fundamentalInstance.prevProps,
866 props = fundamentalInstance.props,
867 state = fundamentalInstance.state;
868
869 var shouldUpdate = impl.shouldUpdate;
870 if (shouldUpdate !== undefined) {
871 return shouldUpdate(null, prevProps, props, state);
872 }
873 return true;
874}
875
876function updateFundamentalComponent(fundamentalInstance) {
877 var impl = fundamentalInstance.impl,
878 instance = fundamentalInstance.instance,
879 prevProps = fundamentalInstance.prevProps,
880 props = fundamentalInstance.props,
881 state = fundamentalInstance.state;
882
883 var onUpdate = impl.onUpdate;
884 if (onUpdate !== undefined) {
885 onUpdate(null, instance, prevProps, props, state);
886 }
887}
888
889function unmountFundamentalComponent(fundamentalInstance) {
890 var impl = fundamentalInstance.impl,
891 instance = fundamentalInstance.instance,
892 props = fundamentalInstance.props,
893 state = fundamentalInstance.state;
894
895 var onUnmount = impl.onUnmount;
896 if (onUnmount !== undefined) {
897 onUnmount(null, instance, props, state);
898 }
899}
900
901var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
902
903var describeComponentFrame = function (name, source, ownerName) {
904 var sourceInfo = '';
905 if (source) {
906 var path = source.fileName;
907 var fileName = path.replace(BEFORE_SLASH_RE, '');
908 {
909 // In DEV, include code for a common special case:
910 // prefer "folder/index.js" instead of just "index.js".
911 if (/^index\./.test(fileName)) {
912 var match = path.match(BEFORE_SLASH_RE);
913 if (match) {
914 var pathBeforeSlash = match[1];
915 if (pathBeforeSlash) {
916 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
917 fileName = folderName + '/' + fileName;
918 }
919 }
920 }
921 }
922 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
923 } else if (ownerName) {
924 sourceInfo = ' (created by ' + ownerName + ')';
925 }
926 return '\n in ' + (name || 'Unknown') + sourceInfo;
927};
928
929var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
930
931function describeFiber(fiber) {
932 switch (fiber.tag) {
933 case HostRoot:
934 case HostPortal:
935 case HostText:
936 case Fragment:
937 case ContextProvider:
938 case ContextConsumer:
939 return '';
940 default:
941 var owner = fiber._debugOwner;
942 var source = fiber._debugSource;
943 var name = getComponentName(fiber.type);
944 var ownerName = null;
945 if (owner) {
946 ownerName = getComponentName(owner.type);
947 }
948 return describeComponentFrame(name, source, ownerName);
949 }
950}
951
952function getStackByFiberInDevAndProd(workInProgress) {
953 var info = '';
954 var node = workInProgress;
955 do {
956 info += describeFiber(node);
957 node = node.return;
958 } while (node);
959 return info;
960}
961
962var current = null;
963var phase = null;
964
965function getCurrentFiberOwnerNameInDevOrNull() {
966 {
967 if (current === null) {
968 return null;
969 }
970 var owner = current._debugOwner;
971 if (owner !== null && typeof owner !== 'undefined') {
972 return getComponentName(owner.type);
973 }
974 }
975 return null;
976}
977
978function getCurrentFiberStackInDev() {
979 {
980 if (current === null) {
981 return '';
982 }
983 // Safe because if current fiber exists, we are reconciling,
984 // and it is guaranteed to be the work-in-progress version.
985 return getStackByFiberInDevAndProd(current);
986 }
987 return '';
988}
989
990function resetCurrentFiber() {
991 {
992 ReactDebugCurrentFrame.getCurrentStack = null;
993 current = null;
994 phase = null;
995 }
996}
997
998function setCurrentFiber(fiber) {
999 {
1000 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
1001 current = fiber;
1002 phase = null;
1003 }
1004}
1005
1006function setCurrentPhase(lifeCyclePhase) {
1007 {
1008 phase = lifeCyclePhase;
1009 }
1010}
1011
1012// Prefix measurements so that it's possible to filter them.
1013// Longer prefixes are hard to read in DevTools.
1014var reactEmoji = '\u269B';
1015var warningEmoji = '\u26D4';
1016var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
1017
1018// Keep track of current fiber so that we know the path to unwind on pause.
1019// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
1020var currentFiber = null;
1021// If we're in the middle of user code, which fiber and method is it?
1022// Reusing `currentFiber` would be confusing for this because user code fiber
1023// can change during commit phase too, but we don't need to unwind it (since
1024// lifecycles in the commit phase don't resemble a tree).
1025var currentPhase = null;
1026var currentPhaseFiber = null;
1027// Did lifecycle hook schedule an update? This is often a performance problem,
1028// so we will keep track of it, and include it in the report.
1029// Track commits caused by cascading updates.
1030var isCommitting = false;
1031var hasScheduledUpdateInCurrentCommit = false;
1032var hasScheduledUpdateInCurrentPhase = false;
1033var commitCountInCurrentWorkLoop = 0;
1034var effectCountInCurrentCommit = 0;
1035var isWaitingForCallback = false;
1036// During commits, we only show a measurement once per method name
1037// to avoid stretch the commit phase with measurement overhead.
1038var labelsInCurrentCommit = new Set();
1039
1040var formatMarkName = function (markName) {
1041 return reactEmoji + ' ' + markName;
1042};
1043
1044var formatLabel = function (label, warning) {
1045 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
1046 var suffix = warning ? ' Warning: ' + warning : '';
1047 return '' + prefix + label + suffix;
1048};
1049
1050var beginMark = function (markName) {
1051 performance.mark(formatMarkName(markName));
1052};
1053
1054var clearMark = function (markName) {
1055 performance.clearMarks(formatMarkName(markName));
1056};
1057
1058var endMark = function (label, markName, warning) {
1059 var formattedMarkName = formatMarkName(markName);
1060 var formattedLabel = formatLabel(label, warning);
1061 try {
1062 performance.measure(formattedLabel, formattedMarkName);
1063 } catch (err) {}
1064 // If previous mark was missing for some reason, this will throw.
1065 // This could only happen if React crashed in an unexpected place earlier.
1066 // Don't pile on with more errors.
1067
1068 // Clear marks immediately to avoid growing buffer.
1069 performance.clearMarks(formattedMarkName);
1070 performance.clearMeasures(formattedLabel);
1071};
1072
1073var getFiberMarkName = function (label, debugID) {
1074 return label + ' (#' + debugID + ')';
1075};
1076
1077var getFiberLabel = function (componentName, isMounted, phase) {
1078 if (phase === null) {
1079 // These are composite component total time measurements.
1080 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
1081 } else {
1082 // Composite component methods.
1083 return componentName + '.' + phase;
1084 }
1085};
1086
1087var beginFiberMark = function (fiber, phase) {
1088 var componentName = getComponentName(fiber.type) || 'Unknown';
1089 var debugID = fiber._debugID;
1090 var isMounted = fiber.alternate !== null;
1091 var label = getFiberLabel(componentName, isMounted, phase);
1092
1093 if (isCommitting && labelsInCurrentCommit.has(label)) {
1094 // During the commit phase, we don't show duplicate labels because
1095 // there is a fixed overhead for every measurement, and we don't
1096 // want to stretch the commit phase beyond necessary.
1097 return false;
1098 }
1099 labelsInCurrentCommit.add(label);
1100
1101 var markName = getFiberMarkName(label, debugID);
1102 beginMark(markName);
1103 return true;
1104};
1105
1106var clearFiberMark = function (fiber, phase) {
1107 var componentName = getComponentName(fiber.type) || 'Unknown';
1108 var debugID = fiber._debugID;
1109 var isMounted = fiber.alternate !== null;
1110 var label = getFiberLabel(componentName, isMounted, phase);
1111 var markName = getFiberMarkName(label, debugID);
1112 clearMark(markName);
1113};
1114
1115var endFiberMark = function (fiber, phase, warning) {
1116 var componentName = getComponentName(fiber.type) || 'Unknown';
1117 var debugID = fiber._debugID;
1118 var isMounted = fiber.alternate !== null;
1119 var label = getFiberLabel(componentName, isMounted, phase);
1120 var markName = getFiberMarkName(label, debugID);
1121 endMark(label, markName, warning);
1122};
1123
1124var shouldIgnoreFiber = function (fiber) {
1125 // Host components should be skipped in the timeline.
1126 // We could check typeof fiber.type, but does this work with RN?
1127 switch (fiber.tag) {
1128 case HostRoot:
1129 case HostComponent:
1130 case HostText:
1131 case HostPortal:
1132 case Fragment:
1133 case ContextProvider:
1134 case ContextConsumer:
1135 case Mode:
1136 return true;
1137 default:
1138 return false;
1139 }
1140};
1141
1142var clearPendingPhaseMeasurement = function () {
1143 if (currentPhase !== null && currentPhaseFiber !== null) {
1144 clearFiberMark(currentPhaseFiber, currentPhase);
1145 }
1146 currentPhaseFiber = null;
1147 currentPhase = null;
1148 hasScheduledUpdateInCurrentPhase = false;
1149};
1150
1151var pauseTimers = function () {
1152 // Stops all currently active measurements so that they can be resumed
1153 // if we continue in a later deferred loop from the same unit of work.
1154 var fiber = currentFiber;
1155 while (fiber) {
1156 if (fiber._debugIsCurrentlyTiming) {
1157 endFiberMark(fiber, null, null);
1158 }
1159 fiber = fiber.return;
1160 }
1161};
1162
1163var resumeTimersRecursively = function (fiber) {
1164 if (fiber.return !== null) {
1165 resumeTimersRecursively(fiber.return);
1166 }
1167 if (fiber._debugIsCurrentlyTiming) {
1168 beginFiberMark(fiber, null);
1169 }
1170};
1171
1172var resumeTimers = function () {
1173 // Resumes all measurements that were active during the last deferred loop.
1174 if (currentFiber !== null) {
1175 resumeTimersRecursively(currentFiber);
1176 }
1177};
1178
1179function recordEffect() {
1180 if (enableUserTimingAPI) {
1181 effectCountInCurrentCommit++;
1182 }
1183}
1184
1185function recordScheduleUpdate() {
1186 if (enableUserTimingAPI) {
1187 if (isCommitting) {
1188 hasScheduledUpdateInCurrentCommit = true;
1189 }
1190 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
1191 hasScheduledUpdateInCurrentPhase = true;
1192 }
1193 }
1194}
1195
1196function startRequestCallbackTimer() {
1197 if (enableUserTimingAPI) {
1198 if (supportsUserTiming && !isWaitingForCallback) {
1199 isWaitingForCallback = true;
1200 beginMark('(Waiting for async callback...)');
1201 }
1202 }
1203}
1204
1205function stopRequestCallbackTimer(didExpire) {
1206 if (enableUserTimingAPI) {
1207 if (supportsUserTiming) {
1208 isWaitingForCallback = false;
1209 var warning = didExpire ? 'Update expired; will flush synchronously' : null;
1210 endMark('(Waiting for async callback...)', '(Waiting for async callback...)', warning);
1211 }
1212 }
1213}
1214
1215function startWorkTimer(fiber) {
1216 if (enableUserTimingAPI) {
1217 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1218 return;
1219 }
1220 // If we pause, this is the fiber to unwind from.
1221 currentFiber = fiber;
1222 if (!beginFiberMark(fiber, null)) {
1223 return;
1224 }
1225 fiber._debugIsCurrentlyTiming = true;
1226 }
1227}
1228
1229function cancelWorkTimer(fiber) {
1230 if (enableUserTimingAPI) {
1231 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1232 return;
1233 }
1234 // Remember we shouldn't complete measurement for this fiber.
1235 // Otherwise flamechart will be deep even for small updates.
1236 fiber._debugIsCurrentlyTiming = false;
1237 clearFiberMark(fiber, null);
1238 }
1239}
1240
1241function stopWorkTimer(fiber) {
1242 if (enableUserTimingAPI) {
1243 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1244 return;
1245 }
1246 // If we pause, its parent is the fiber to unwind from.
1247 currentFiber = fiber.return;
1248 if (!fiber._debugIsCurrentlyTiming) {
1249 return;
1250 }
1251 fiber._debugIsCurrentlyTiming = false;
1252 endFiberMark(fiber, null, null);
1253 }
1254}
1255
1256function stopFailedWorkTimer(fiber) {
1257 if (enableUserTimingAPI) {
1258 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1259 return;
1260 }
1261 // If we pause, its parent is the fiber to unwind from.
1262 currentFiber = fiber.return;
1263 if (!fiber._debugIsCurrentlyTiming) {
1264 return;
1265 }
1266 fiber._debugIsCurrentlyTiming = false;
1267 var warning = fiber.tag === SuspenseComponent || fiber.tag === DehydratedSuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
1268 endFiberMark(fiber, null, warning);
1269 }
1270}
1271
1272function startPhaseTimer(fiber, phase) {
1273 if (enableUserTimingAPI) {
1274 if (!supportsUserTiming) {
1275 return;
1276 }
1277 clearPendingPhaseMeasurement();
1278 if (!beginFiberMark(fiber, phase)) {
1279 return;
1280 }
1281 currentPhaseFiber = fiber;
1282 currentPhase = phase;
1283 }
1284}
1285
1286function stopPhaseTimer() {
1287 if (enableUserTimingAPI) {
1288 if (!supportsUserTiming) {
1289 return;
1290 }
1291 if (currentPhase !== null && currentPhaseFiber !== null) {
1292 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
1293 endFiberMark(currentPhaseFiber, currentPhase, warning);
1294 }
1295 currentPhase = null;
1296 currentPhaseFiber = null;
1297 }
1298}
1299
1300function startWorkLoopTimer(nextUnitOfWork) {
1301 if (enableUserTimingAPI) {
1302 currentFiber = nextUnitOfWork;
1303 if (!supportsUserTiming) {
1304 return;
1305 }
1306 commitCountInCurrentWorkLoop = 0;
1307 // This is top level call.
1308 // Any other measurements are performed within.
1309 beginMark('(React Tree Reconciliation)');
1310 // Resume any measurements that were in progress during the last loop.
1311 resumeTimers();
1312 }
1313}
1314
1315function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
1316 if (enableUserTimingAPI) {
1317 if (!supportsUserTiming) {
1318 return;
1319 }
1320 var warning = null;
1321 if (interruptedBy !== null) {
1322 if (interruptedBy.tag === HostRoot) {
1323 warning = 'A top-level update interrupted the previous render';
1324 } else {
1325 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
1326 warning = 'An update to ' + componentName + ' interrupted the previous render';
1327 }
1328 } else if (commitCountInCurrentWorkLoop > 1) {
1329 warning = 'There were cascading updates';
1330 }
1331 commitCountInCurrentWorkLoop = 0;
1332 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)';
1333 // Pause any measurements until the next loop.
1334 pauseTimers();
1335 endMark(label, '(React Tree Reconciliation)', warning);
1336 }
1337}
1338
1339function startCommitTimer() {
1340 if (enableUserTimingAPI) {
1341 if (!supportsUserTiming) {
1342 return;
1343 }
1344 isCommitting = true;
1345 hasScheduledUpdateInCurrentCommit = false;
1346 labelsInCurrentCommit.clear();
1347 beginMark('(Committing Changes)');
1348 }
1349}
1350
1351function stopCommitTimer() {
1352 if (enableUserTimingAPI) {
1353 if (!supportsUserTiming) {
1354 return;
1355 }
1356
1357 var warning = null;
1358 if (hasScheduledUpdateInCurrentCommit) {
1359 warning = 'Lifecycle hook scheduled a cascading update';
1360 } else if (commitCountInCurrentWorkLoop > 0) {
1361 warning = 'Caused by a cascading update in earlier commit';
1362 }
1363 hasScheduledUpdateInCurrentCommit = false;
1364 commitCountInCurrentWorkLoop++;
1365 isCommitting = false;
1366 labelsInCurrentCommit.clear();
1367
1368 endMark('(Committing Changes)', '(Committing Changes)', warning);
1369 }
1370}
1371
1372function startCommitSnapshotEffectsTimer() {
1373 if (enableUserTimingAPI) {
1374 if (!supportsUserTiming) {
1375 return;
1376 }
1377 effectCountInCurrentCommit = 0;
1378 beginMark('(Committing Snapshot Effects)');
1379 }
1380}
1381
1382function stopCommitSnapshotEffectsTimer() {
1383 if (enableUserTimingAPI) {
1384 if (!supportsUserTiming) {
1385 return;
1386 }
1387 var count = effectCountInCurrentCommit;
1388 effectCountInCurrentCommit = 0;
1389 endMark('(Committing Snapshot Effects: ' + count + ' Total)', '(Committing Snapshot Effects)', null);
1390 }
1391}
1392
1393function startCommitHostEffectsTimer() {
1394 if (enableUserTimingAPI) {
1395 if (!supportsUserTiming) {
1396 return;
1397 }
1398 effectCountInCurrentCommit = 0;
1399 beginMark('(Committing Host Effects)');
1400 }
1401}
1402
1403function stopCommitHostEffectsTimer() {
1404 if (enableUserTimingAPI) {
1405 if (!supportsUserTiming) {
1406 return;
1407 }
1408 var count = effectCountInCurrentCommit;
1409 effectCountInCurrentCommit = 0;
1410 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
1411 }
1412}
1413
1414function startCommitLifeCyclesTimer() {
1415 if (enableUserTimingAPI) {
1416 if (!supportsUserTiming) {
1417 return;
1418 }
1419 effectCountInCurrentCommit = 0;
1420 beginMark('(Calling Lifecycle Methods)');
1421 }
1422}
1423
1424function stopCommitLifeCyclesTimer() {
1425 if (enableUserTimingAPI) {
1426 if (!supportsUserTiming) {
1427 return;
1428 }
1429 var count = effectCountInCurrentCommit;
1430 effectCountInCurrentCommit = 0;
1431 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
1432 }
1433}
1434
1435var valueStack = [];
1436
1437var fiberStack = void 0;
1438
1439{
1440 fiberStack = [];
1441}
1442
1443var index = -1;
1444
1445function createCursor(defaultValue) {
1446 return {
1447 current: defaultValue
1448 };
1449}
1450
1451function pop(cursor, fiber) {
1452 if (index < 0) {
1453 {
1454 warningWithoutStack$1(false, 'Unexpected pop.');
1455 }
1456 return;
1457 }
1458
1459 {
1460 if (fiber !== fiberStack[index]) {
1461 warningWithoutStack$1(false, 'Unexpected Fiber popped.');
1462 }
1463 }
1464
1465 cursor.current = valueStack[index];
1466
1467 valueStack[index] = null;
1468
1469 {
1470 fiberStack[index] = null;
1471 }
1472
1473 index--;
1474}
1475
1476function push(cursor, value, fiber) {
1477 index++;
1478
1479 valueStack[index] = cursor.current;
1480
1481 {
1482 fiberStack[index] = fiber;
1483 }
1484
1485 cursor.current = value;
1486}
1487
1488var warnedAboutMissingGetChildContext = void 0;
1489
1490{
1491 warnedAboutMissingGetChildContext = {};
1492}
1493
1494var emptyContextObject = {};
1495{
1496 Object.freeze(emptyContextObject);
1497}
1498
1499// A cursor to the current merged context object on the stack.
1500var contextStackCursor = createCursor(emptyContextObject);
1501// A cursor to a boolean indicating whether the context has changed.
1502var didPerformWorkStackCursor = createCursor(false);
1503// Keep track of the previous context object that was on the stack.
1504// We use this to get access to the parent context after we have already
1505// pushed the next context provider, and now need to merge their contexts.
1506var previousContext = emptyContextObject;
1507
1508function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
1509 if (disableLegacyContext) {
1510 return emptyContextObject;
1511 } else {
1512 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
1513 // If the fiber is a context provider itself, when we read its context
1514 // we may have already pushed its own child context on the stack. A context
1515 // provider should not "see" its own child context. Therefore we read the
1516 // previous (parent) context instead for a context provider.
1517 return previousContext;
1518 }
1519 return contextStackCursor.current;
1520 }
1521}
1522
1523function cacheContext(workInProgress, unmaskedContext, maskedContext) {
1524 if (disableLegacyContext) {
1525 return;
1526 } else {
1527 var instance = workInProgress.stateNode;
1528 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
1529 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
1530 }
1531}
1532
1533function getMaskedContext(workInProgress, unmaskedContext) {
1534 if (disableLegacyContext) {
1535 return emptyContextObject;
1536 } else {
1537 var type = workInProgress.type;
1538 var contextTypes = type.contextTypes;
1539 if (!contextTypes) {
1540 return emptyContextObject;
1541 }
1542
1543 // Avoid recreating masked context unless unmasked context has changed.
1544 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
1545 // This may trigger infinite loops if componentWillReceiveProps calls setState.
1546 var instance = workInProgress.stateNode;
1547 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
1548 return instance.__reactInternalMemoizedMaskedChildContext;
1549 }
1550
1551 var context = {};
1552 for (var key in contextTypes) {
1553 context[key] = unmaskedContext[key];
1554 }
1555
1556 {
1557 var name = getComponentName(type) || 'Unknown';
1558 checkPropTypes(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
1559 }
1560
1561 // Cache unmasked context so we can avoid recreating masked context unless necessary.
1562 // Context is created before the class component is instantiated so check for instance.
1563 if (instance) {
1564 cacheContext(workInProgress, unmaskedContext, context);
1565 }
1566
1567 return context;
1568 }
1569}
1570
1571function hasContextChanged() {
1572 if (disableLegacyContext) {
1573 return false;
1574 } else {
1575 return didPerformWorkStackCursor.current;
1576 }
1577}
1578
1579function isContextProvider(type) {
1580 if (disableLegacyContext) {
1581 return false;
1582 } else {
1583 var childContextTypes = type.childContextTypes;
1584 return childContextTypes !== null && childContextTypes !== undefined;
1585 }
1586}
1587
1588function popContext(fiber) {
1589 if (disableLegacyContext) {
1590 return;
1591 } else {
1592 pop(didPerformWorkStackCursor, fiber);
1593 pop(contextStackCursor, fiber);
1594 }
1595}
1596
1597function popTopLevelContextObject(fiber) {
1598 if (disableLegacyContext) {
1599 return;
1600 } else {
1601 pop(didPerformWorkStackCursor, fiber);
1602 pop(contextStackCursor, fiber);
1603 }
1604}
1605
1606function pushTopLevelContextObject(fiber, context, didChange) {
1607 if (disableLegacyContext) {
1608 return;
1609 } else {
1610 (function () {
1611 if (!(contextStackCursor.current === emptyContextObject)) {
1612 {
1613 throw ReactError(Error('Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue.'));
1614 }
1615 }
1616 })();
1617
1618 push(contextStackCursor, context, fiber);
1619 push(didPerformWorkStackCursor, didChange, fiber);
1620 }
1621}
1622
1623function processChildContext(fiber, type, parentContext) {
1624 if (disableLegacyContext) {
1625 return parentContext;
1626 } else {
1627 var instance = fiber.stateNode;
1628 var childContextTypes = type.childContextTypes;
1629
1630 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
1631 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
1632 if (typeof instance.getChildContext !== 'function') {
1633 {
1634 var componentName = getComponentName(type) || 'Unknown';
1635
1636 if (!warnedAboutMissingGetChildContext[componentName]) {
1637 warnedAboutMissingGetChildContext[componentName] = true;
1638 warningWithoutStack$1(false, '%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);
1639 }
1640 }
1641 return parentContext;
1642 }
1643
1644 var childContext = void 0;
1645 {
1646 setCurrentPhase('getChildContext');
1647 }
1648 startPhaseTimer(fiber, 'getChildContext');
1649 childContext = instance.getChildContext();
1650 stopPhaseTimer();
1651 {
1652 setCurrentPhase(null);
1653 }
1654 for (var contextKey in childContext) {
1655 (function () {
1656 if (!(contextKey in childContextTypes)) {
1657 {
1658 throw ReactError(Error((getComponentName(type) || 'Unknown') + '.getChildContext(): key "' + contextKey + '" is not defined in childContextTypes.'));
1659 }
1660 }
1661 })();
1662 }
1663 {
1664 var name = getComponentName(type) || 'Unknown';
1665 checkPropTypes(childContextTypes, childContext, 'child context', name,
1666 // In practice, there is one case in which we won't get a stack. It's when
1667 // somebody calls unstable_renderSubtreeIntoContainer() and we process
1668 // context from the parent component instance. The stack will be missing
1669 // because it's outside of the reconciliation, and so the pointer has not
1670 // been set. This is rare and doesn't matter. We'll also remove that API.
1671 getCurrentFiberStackInDev);
1672 }
1673
1674 return _assign({}, parentContext, childContext);
1675 }
1676}
1677
1678function pushContextProvider(workInProgress) {
1679 if (disableLegacyContext) {
1680 return false;
1681 } else {
1682 var instance = workInProgress.stateNode;
1683 // We push the context as early as possible to ensure stack integrity.
1684 // If the instance does not exist yet, we will push null at first,
1685 // and replace it on the stack later when invalidating the context.
1686 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject;
1687
1688 // Remember the parent context so we can merge with it later.
1689 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
1690 previousContext = contextStackCursor.current;
1691 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
1692 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
1693
1694 return true;
1695 }
1696}
1697
1698function invalidateContextProvider(workInProgress, type, didChange) {
1699 if (disableLegacyContext) {
1700 return;
1701 } else {
1702 var instance = workInProgress.stateNode;
1703 (function () {
1704 if (!instance) {
1705 {
1706 throw ReactError(Error('Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue.'));
1707 }
1708 }
1709 })();
1710
1711 if (didChange) {
1712 // Merge parent and own context.
1713 // Skip this if we're not updating due to sCU.
1714 // This avoids unnecessarily recomputing memoized values.
1715 var mergedContext = processChildContext(workInProgress, type, previousContext);
1716 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
1717
1718 // Replace the old (or empty) context with the new one.
1719 // It is important to unwind the context in the reverse order.
1720 pop(didPerformWorkStackCursor, workInProgress);
1721 pop(contextStackCursor, workInProgress);
1722 // Now push the new context and mark that it has changed.
1723 push(contextStackCursor, mergedContext, workInProgress);
1724 push(didPerformWorkStackCursor, didChange, workInProgress);
1725 } else {
1726 pop(didPerformWorkStackCursor, workInProgress);
1727 push(didPerformWorkStackCursor, didChange, workInProgress);
1728 }
1729 }
1730}
1731
1732function findCurrentUnmaskedContext(fiber) {
1733 if (disableLegacyContext) {
1734 return emptyContextObject;
1735 } else {
1736 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
1737 // makes sense elsewhere
1738 (function () {
1739 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {
1740 {
1741 throw ReactError(Error('Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue.'));
1742 }
1743 }
1744 })();
1745
1746 var node = fiber;
1747 do {
1748 switch (node.tag) {
1749 case HostRoot:
1750 return node.stateNode.context;
1751 case ClassComponent:
1752 {
1753 var Component = node.type;
1754 if (isContextProvider(Component)) {
1755 return node.stateNode.__reactInternalMemoizedMergedChildContext;
1756 }
1757 break;
1758 }
1759 }
1760 node = node.return;
1761 } while (node !== null);
1762 (function () {
1763 {
1764 {
1765 throw ReactError(Error('Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.'));
1766 }
1767 }
1768 })();
1769 }
1770}
1771
1772var LegacyRoot = 0;
1773var BatchedRoot = 1;
1774var ConcurrentRoot = 2;
1775
1776// Intentionally not named imports because Rollup would use dynamic dispatch for
1777// CommonJS interop named imports.
1778var Scheduler_runWithPriority = Scheduler$1.unstable_runWithPriority;
1779var Scheduler_scheduleCallback = Scheduler$1.unstable_scheduleCallback;
1780var Scheduler_cancelCallback = Scheduler$1.unstable_cancelCallback;
1781var Scheduler_shouldYield = Scheduler$1.unstable_shouldYield;
1782var Scheduler_requestPaint = Scheduler$1.unstable_requestPaint;
1783var Scheduler_now = Scheduler$1.unstable_now;
1784var Scheduler_getCurrentPriorityLevel = Scheduler$1.unstable_getCurrentPriorityLevel;
1785var Scheduler_ImmediatePriority = Scheduler$1.unstable_ImmediatePriority;
1786var Scheduler_UserBlockingPriority = Scheduler$1.unstable_UserBlockingPriority;
1787var Scheduler_NormalPriority = Scheduler$1.unstable_NormalPriority;
1788var Scheduler_LowPriority = Scheduler$1.unstable_LowPriority;
1789var Scheduler_IdlePriority = Scheduler$1.unstable_IdlePriority;
1790
1791
1792if (enableSchedulerTracing) {
1793 // Provide explicit error message when production+profiling bundle of e.g.
1794 // react-dom is used with production (non-profiling) bundle of
1795 // scheduler/tracing
1796 (function () {
1797 if (!(tracing.__interactionsRef != null && tracing.__interactionsRef.current != null)) {
1798 {
1799 throw ReactError(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'));
1800 }
1801 }
1802 })();
1803}
1804
1805var fakeCallbackNode = {};
1806
1807// Except for NoPriority, these correspond to Scheduler priorities. We use
1808// ascending numbers so we can compare them like numbers. They start at 90 to
1809// avoid clashing with Scheduler's priorities.
1810var ImmediatePriority = 99;
1811var UserBlockingPriority = 98;
1812var NormalPriority = 97;
1813var LowPriority = 96;
1814var IdlePriority = 95;
1815// NoPriority is the absence of priority. Also React-only.
1816var NoPriority = 90;
1817
1818var shouldYield = Scheduler_shouldYield;
1819var requestPaint =
1820// Fall back gracefully if we're running an older version of Scheduler.
1821Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {};
1822
1823var syncQueue = null;
1824var immediateQueueCallbackNode = null;
1825var isFlushingSyncQueue = false;
1826var initialTimeMs = Scheduler_now();
1827
1828// If the initial timestamp is reasonably small, use Scheduler's `now` directly.
1829// This will be the case for modern browsers that support `performance.now`. In
1830// older browsers, Scheduler falls back to `Date.now`, which returns a Unix
1831// timestamp. In that case, subtract the module initialization time to simulate
1832// the behavior of performance.now and keep our times small enough to fit
1833// within 32 bits.
1834// TODO: Consider lifting this into Scheduler.
1835var now = initialTimeMs < 10000 ? Scheduler_now : function () {
1836 return Scheduler_now() - initialTimeMs;
1837};
1838
1839function getCurrentPriorityLevel() {
1840 switch (Scheduler_getCurrentPriorityLevel()) {
1841 case Scheduler_ImmediatePriority:
1842 return ImmediatePriority;
1843 case Scheduler_UserBlockingPriority:
1844 return UserBlockingPriority;
1845 case Scheduler_NormalPriority:
1846 return NormalPriority;
1847 case Scheduler_LowPriority:
1848 return LowPriority;
1849 case Scheduler_IdlePriority:
1850 return IdlePriority;
1851 default:
1852 (function () {
1853 {
1854 {
1855 throw ReactError(Error('Unknown priority level.'));
1856 }
1857 }
1858 })();
1859 }
1860}
1861
1862function reactPriorityToSchedulerPriority(reactPriorityLevel) {
1863 switch (reactPriorityLevel) {
1864 case ImmediatePriority:
1865 return Scheduler_ImmediatePriority;
1866 case UserBlockingPriority:
1867 return Scheduler_UserBlockingPriority;
1868 case NormalPriority:
1869 return Scheduler_NormalPriority;
1870 case LowPriority:
1871 return Scheduler_LowPriority;
1872 case IdlePriority:
1873 return Scheduler_IdlePriority;
1874 default:
1875 (function () {
1876 {
1877 {
1878 throw ReactError(Error('Unknown priority level.'));
1879 }
1880 }
1881 })();
1882 }
1883}
1884
1885function runWithPriority(reactPriorityLevel, fn) {
1886 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
1887 return Scheduler_runWithPriority(priorityLevel, fn);
1888}
1889
1890function scheduleCallback(reactPriorityLevel, callback, options) {
1891 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
1892 return Scheduler_scheduleCallback(priorityLevel, callback, options);
1893}
1894
1895function scheduleSyncCallback(callback) {
1896 // Push this callback into an internal queue. We'll flush these either in
1897 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
1898 if (syncQueue === null) {
1899 syncQueue = [callback];
1900 // Flush the queue in the next tick, at the earliest.
1901 immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl);
1902 } else {
1903 // Push onto existing queue. Don't need to schedule a callback because
1904 // we already scheduled one when we created the queue.
1905 syncQueue.push(callback);
1906 }
1907 return fakeCallbackNode;
1908}
1909
1910function cancelCallback(callbackNode) {
1911 if (callbackNode !== fakeCallbackNode) {
1912 Scheduler_cancelCallback(callbackNode);
1913 }
1914}
1915
1916function flushSyncCallbackQueue() {
1917 if (immediateQueueCallbackNode !== null) {
1918 Scheduler_cancelCallback(immediateQueueCallbackNode);
1919 }
1920 flushSyncCallbackQueueImpl();
1921}
1922
1923function flushSyncCallbackQueueImpl() {
1924 if (!isFlushingSyncQueue && syncQueue !== null) {
1925 // Prevent re-entrancy.
1926 isFlushingSyncQueue = true;
1927 var i = 0;
1928 try {
1929 var _isSync = true;
1930 var queue = syncQueue;
1931 runWithPriority(ImmediatePriority, function () {
1932 for (; i < queue.length; i++) {
1933 var callback = queue[i];
1934 do {
1935 callback = callback(_isSync);
1936 } while (callback !== null);
1937 }
1938 });
1939 syncQueue = null;
1940 } catch (error) {
1941 // If something throws, leave the remaining callbacks on the queue.
1942 if (syncQueue !== null) {
1943 syncQueue = syncQueue.slice(i + 1);
1944 }
1945 // Resume flushing in the next tick
1946 Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue);
1947 throw error;
1948 } finally {
1949 isFlushingSyncQueue = false;
1950 }
1951 }
1952}
1953
1954var NoMode = 0;
1955var StrictMode = 1;
1956// TODO: Remove BatchedMode and ConcurrentMode by reading from the root
1957// tag instead
1958var BatchedMode = 2;
1959var ConcurrentMode = 4;
1960var ProfileMode = 8;
1961
1962// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
1963// Math.pow(2, 30) - 1
1964// 0b111111111111111111111111111111
1965var MAX_SIGNED_31_BIT_INT = 1073741823;
1966
1967var NoWork = 0;
1968var Never = 1;
1969var Sync = MAX_SIGNED_31_BIT_INT;
1970var Batched = Sync - 1;
1971
1972var UNIT_SIZE = 10;
1973var MAGIC_NUMBER_OFFSET = Batched - 1;
1974
1975// 1 unit of expiration time represents 10ms.
1976function msToExpirationTime(ms) {
1977 // Always add an offset so that we don't clash with the magic number for NoWork.
1978 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
1979}
1980
1981function expirationTimeToMs(expirationTime) {
1982 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
1983}
1984
1985function ceiling(num, precision) {
1986 return ((num / precision | 0) + 1) * precision;
1987}
1988
1989function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
1990 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
1991}
1992
1993// TODO: This corresponds to Scheduler's NormalPriority, not LowPriority. Update
1994// the names to reflect.
1995var LOW_PRIORITY_EXPIRATION = 5000;
1996var LOW_PRIORITY_BATCH_SIZE = 250;
1997
1998function computeAsyncExpiration(currentTime) {
1999 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
2000}
2001
2002function computeSuspenseExpiration(currentTime, timeoutMs) {
2003 // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time?
2004 return computeExpirationBucket(currentTime, timeoutMs, LOW_PRIORITY_BATCH_SIZE);
2005}
2006
2007// We intentionally set a higher expiration time for interactive updates in
2008// dev than in production.
2009//
2010// If the main thread is being blocked so long that you hit the expiration,
2011// it's a problem that could be solved with better scheduling.
2012//
2013// People will be more likely to notice this and fix it with the long
2014// expiration time in development.
2015//
2016// In production we opt for better UX at the risk of masking scheduling
2017// problems, by expiring fast.
2018var HIGH_PRIORITY_EXPIRATION = 500;
2019var HIGH_PRIORITY_BATCH_SIZE = 100;
2020
2021function computeInteractiveExpiration(currentTime) {
2022 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
2023}
2024
2025function inferPriorityFromExpirationTime(currentTime, expirationTime) {
2026 if (expirationTime === Sync) {
2027 return ImmediatePriority;
2028 }
2029 if (expirationTime === Never) {
2030 return IdlePriority;
2031 }
2032 var msUntil = expirationTimeToMs(expirationTime) - expirationTimeToMs(currentTime);
2033 if (msUntil <= 0) {
2034 return ImmediatePriority;
2035 }
2036 if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) {
2037 return UserBlockingPriority;
2038 }
2039 if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) {
2040 return NormalPriority;
2041 }
2042
2043 // TODO: Handle LowPriority
2044
2045 // Assume anything lower has idle priority
2046 return IdlePriority;
2047}
2048
2049/**
2050 * inlined Object.is polyfill to avoid requiring consumers ship their own
2051 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
2052 */
2053function is(x, y) {
2054 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
2055 ;
2056}
2057
2058var hasOwnProperty = Object.prototype.hasOwnProperty;
2059
2060/**
2061 * Performs equality by iterating through keys on an object and returning false
2062 * when any key has values which are not strictly equal between the arguments.
2063 * Returns true when the values of all keys are strictly equal.
2064 */
2065function shallowEqual(objA, objB) {
2066 if (is(objA, objB)) {
2067 return true;
2068 }
2069
2070 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
2071 return false;
2072 }
2073
2074 var keysA = Object.keys(objA);
2075 var keysB = Object.keys(objB);
2076
2077 if (keysA.length !== keysB.length) {
2078 return false;
2079 }
2080
2081 // Test for A's keys different from B.
2082 for (var i = 0; i < keysA.length; i++) {
2083 if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
2084 return false;
2085 }
2086 }
2087
2088 return true;
2089}
2090
2091/**
2092 * Forked from fbjs/warning:
2093 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
2094 *
2095 * Only change is we use console.warn instead of console.error,
2096 * and do nothing when 'console' is not supported.
2097 * This really simplifies the code.
2098 * ---
2099 * Similar to invariant but only logs a warning if the condition is not met.
2100 * This can be used to log issues in development environments in critical
2101 * paths. Removing the logging code for production environments will keep the
2102 * same logic and follow the same code paths.
2103 */
2104
2105var lowPriorityWarning = function () {};
2106
2107{
2108 var printWarning = function (format) {
2109 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
2110 args[_key - 1] = arguments[_key];
2111 }
2112
2113 var argIndex = 0;
2114 var message = 'Warning: ' + format.replace(/%s/g, function () {
2115 return args[argIndex++];
2116 });
2117 if (typeof console !== 'undefined') {
2118 console.warn(message);
2119 }
2120 try {
2121 // --- Welcome to debugging React ---
2122 // This error was thrown as a convenience so that you can use this stack
2123 // to find the callsite that caused this warning to fire.
2124 throw new Error(message);
2125 } catch (x) {}
2126 };
2127
2128 lowPriorityWarning = function (condition, format) {
2129 if (format === undefined) {
2130 throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument');
2131 }
2132 if (!condition) {
2133 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
2134 args[_key2 - 2] = arguments[_key2];
2135 }
2136
2137 printWarning.apply(undefined, [format].concat(args));
2138 }
2139 };
2140}
2141
2142var lowPriorityWarning$1 = lowPriorityWarning;
2143
2144var ReactStrictModeWarnings = {
2145 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
2146 flushPendingUnsafeLifecycleWarnings: function () {},
2147 recordLegacyContextWarning: function (fiber, instance) {},
2148 flushLegacyContextWarning: function () {},
2149 discardPendingWarnings: function () {}
2150};
2151
2152{
2153 var findStrictRoot = function (fiber) {
2154 var maybeStrictRoot = null;
2155
2156 var node = fiber;
2157 while (node !== null) {
2158 if (node.mode & StrictMode) {
2159 maybeStrictRoot = node;
2160 }
2161 node = node.return;
2162 }
2163
2164 return maybeStrictRoot;
2165 };
2166
2167 var setToSortedString = function (set) {
2168 var array = [];
2169 set.forEach(function (value) {
2170 array.push(value);
2171 });
2172 return array.sort().join(', ');
2173 };
2174
2175 var pendingComponentWillMountWarnings = [];
2176 var pendingUNSAFE_ComponentWillMountWarnings = [];
2177 var pendingComponentWillReceivePropsWarnings = [];
2178 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2179 var pendingComponentWillUpdateWarnings = [];
2180 var pendingUNSAFE_ComponentWillUpdateWarnings = [];
2181
2182 // Tracks components we have already warned about.
2183 var didWarnAboutUnsafeLifecycles = new Set();
2184
2185 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
2186 // Dedup strategy: Warn once per component.
2187 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
2188 return;
2189 }
2190
2191 if (typeof instance.componentWillMount === 'function' &&
2192 // Don't warn about react-lifecycles-compat polyfilled components.
2193 instance.componentWillMount.__suppressDeprecationWarning !== true) {
2194 pendingComponentWillMountWarnings.push(fiber);
2195 }
2196
2197 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') {
2198 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
2199 }
2200
2201 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
2202 pendingComponentWillReceivePropsWarnings.push(fiber);
2203 }
2204
2205 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
2206 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
2207 }
2208
2209 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
2210 pendingComponentWillUpdateWarnings.push(fiber);
2211 }
2212
2213 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
2214 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
2215 }
2216 };
2217
2218 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
2219 // We do an initial pass to gather component names
2220 var componentWillMountUniqueNames = new Set();
2221 if (pendingComponentWillMountWarnings.length > 0) {
2222 pendingComponentWillMountWarnings.forEach(function (fiber) {
2223 componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2224 didWarnAboutUnsafeLifecycles.add(fiber.type);
2225 });
2226 pendingComponentWillMountWarnings = [];
2227 }
2228
2229 var UNSAFE_componentWillMountUniqueNames = new Set();
2230 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
2231 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
2232 UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2233 didWarnAboutUnsafeLifecycles.add(fiber.type);
2234 });
2235 pendingUNSAFE_ComponentWillMountWarnings = [];
2236 }
2237
2238 var componentWillReceivePropsUniqueNames = new Set();
2239 if (pendingComponentWillReceivePropsWarnings.length > 0) {
2240 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
2241 componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2242 didWarnAboutUnsafeLifecycles.add(fiber.type);
2243 });
2244
2245 pendingComponentWillReceivePropsWarnings = [];
2246 }
2247
2248 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
2249 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
2250 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
2251 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2252 didWarnAboutUnsafeLifecycles.add(fiber.type);
2253 });
2254
2255 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2256 }
2257
2258 var componentWillUpdateUniqueNames = new Set();
2259 if (pendingComponentWillUpdateWarnings.length > 0) {
2260 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
2261 componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
2262 didWarnAboutUnsafeLifecycles.add(fiber.type);
2263 });
2264
2265 pendingComponentWillUpdateWarnings = [];
2266 }
2267
2268 var UNSAFE_componentWillUpdateUniqueNames = new Set();
2269 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
2270 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
2271 UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
2272 didWarnAboutUnsafeLifecycles.add(fiber.type);
2273 });
2274
2275 pendingUNSAFE_ComponentWillUpdateWarnings = [];
2276 }
2277
2278 // Finally, we flush all the warnings
2279 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
2280 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
2281 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
2282 warningWithoutStack$1(false, 'Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://fb.me/react-async-component-lifecycle-hooks 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);
2283 }
2284
2285 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
2286 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
2287 warningWithoutStack$1(false, 'Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-async-component-lifecycle-hooks 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);
2288 }
2289
2290 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
2291 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
2292 warningWithoutStack$1(false, 'Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '\nPlease update the following components: %s', _sortedNames2);
2293 }
2294
2295 if (componentWillMountUniqueNames.size > 0) {
2296 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
2297
2298 lowPriorityWarning$1(false, 'componentWillMount has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-async-component-lifecycle-hooks 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);
2299 }
2300
2301 if (componentWillReceivePropsUniqueNames.size > 0) {
2302 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
2303
2304 lowPriorityWarning$1(false, 'componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-async-component-lifecycle-hooks 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);
2305 }
2306
2307 if (componentWillUpdateUniqueNames.size > 0) {
2308 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
2309
2310 lowPriorityWarning$1(false, 'componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-async-component-lifecycle-hooks 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);
2311 }
2312 };
2313
2314 var pendingLegacyContextWarning = new Map();
2315
2316 // Tracks components we have already warned about.
2317 var didWarnAboutLegacyContext = new Set();
2318
2319 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
2320 var strictRoot = findStrictRoot(fiber);
2321 if (strictRoot === null) {
2322 warningWithoutStack$1(false, '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.');
2323 return;
2324 }
2325
2326 // Dedup strategy: Warn once per component.
2327 if (didWarnAboutLegacyContext.has(fiber.type)) {
2328 return;
2329 }
2330
2331 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
2332
2333 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
2334 if (warningsForRoot === undefined) {
2335 warningsForRoot = [];
2336 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
2337 }
2338 warningsForRoot.push(fiber);
2339 }
2340 };
2341
2342 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
2343 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
2344 var uniqueNames = new Set();
2345 fiberArray.forEach(function (fiber) {
2346 uniqueNames.add(getComponentName(fiber.type) || 'Component');
2347 didWarnAboutLegacyContext.add(fiber.type);
2348 });
2349
2350 var sortedNames = setToSortedString(uniqueNames);
2351 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
2352
2353 warningWithoutStack$1(false, 'Legacy context API has been detected within a strict-mode tree: %s' + '\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:' + '\nhttps://fb.me/react-legacy-context', strictRootComponentStack, sortedNames);
2354 });
2355 };
2356
2357 ReactStrictModeWarnings.discardPendingWarnings = function () {
2358 pendingComponentWillMountWarnings = [];
2359 pendingUNSAFE_ComponentWillMountWarnings = [];
2360 pendingComponentWillReceivePropsWarnings = [];
2361 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2362 pendingComponentWillUpdateWarnings = [];
2363 pendingUNSAFE_ComponentWillUpdateWarnings = [];
2364 pendingLegacyContextWarning = new Map();
2365 };
2366}
2367
2368// Resolves type to a family.
2369
2370
2371// Used by React Refresh runtime through DevTools Global Hook.
2372
2373
2374var resolveFamily = null;
2375// $FlowFixMe Flow gets confused by a WeakSet feature check below.
2376var failedBoundaries = null;
2377
2378var setRefreshHandler = function (handler) {
2379 {
2380 resolveFamily = handler;
2381 }
2382};
2383
2384function resolveFunctionForHotReloading(type) {
2385 {
2386 if (resolveFamily === null) {
2387 // Hot reloading is disabled.
2388 return type;
2389 }
2390 var family = resolveFamily(type);
2391 if (family === undefined) {
2392 return type;
2393 }
2394 // Use the latest known implementation.
2395 return family.current;
2396 }
2397}
2398
2399function resolveClassForHotReloading(type) {
2400 // No implementation differences.
2401 return resolveFunctionForHotReloading(type);
2402}
2403
2404function resolveForwardRefForHotReloading(type) {
2405 {
2406 if (resolveFamily === null) {
2407 // Hot reloading is disabled.
2408 return type;
2409 }
2410 var family = resolveFamily(type);
2411 if (family === undefined) {
2412 // Check if we're dealing with a real forwardRef. Don't want to crash early.
2413 if (type !== null && type !== undefined && typeof type.render === 'function') {
2414 // ForwardRef is special because its resolved .type is an object,
2415 // but it's possible that we only have its inner render function in the map.
2416 // If that inner render function is different, we'll build a new forwardRef type.
2417 var currentRender = resolveFunctionForHotReloading(type.render);
2418 if (type.render !== currentRender) {
2419 var syntheticType = {
2420 $$typeof: REACT_FORWARD_REF_TYPE,
2421 render: currentRender
2422 };
2423 if (type.displayName !== undefined) {
2424 syntheticType.displayName = type.displayName;
2425 }
2426 return syntheticType;
2427 }
2428 }
2429 return type;
2430 }
2431 // Use the latest known implementation.
2432 return family.current;
2433 }
2434}
2435
2436function isCompatibleFamilyForHotReloading(fiber, element) {
2437 {
2438 if (resolveFamily === null) {
2439 // Hot reloading is disabled.
2440 return false;
2441 }
2442
2443 var prevType = fiber.elementType;
2444 var nextType = element.type;
2445
2446 // If we got here, we know types aren't === equal.
2447 var needsCompareFamilies = false;
2448
2449 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
2450
2451 switch (fiber.tag) {
2452 case ClassComponent:
2453 {
2454 if (typeof nextType === 'function') {
2455 needsCompareFamilies = true;
2456 }
2457 break;
2458 }
2459 case FunctionComponent:
2460 {
2461 if (typeof nextType === 'function') {
2462 needsCompareFamilies = true;
2463 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2464 // We don't know the inner type yet.
2465 // We're going to assume that the lazy inner type is stable,
2466 // and so it is sufficient to avoid reconciling it away.
2467 // We're not going to unwrap or actually use the new lazy type.
2468 needsCompareFamilies = true;
2469 }
2470 break;
2471 }
2472 case ForwardRef:
2473 {
2474 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
2475 needsCompareFamilies = true;
2476 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2477 needsCompareFamilies = true;
2478 }
2479 break;
2480 }
2481 case MemoComponent:
2482 case SimpleMemoComponent:
2483 {
2484 if ($$typeofNextType === REACT_MEMO_TYPE) {
2485 // TODO: if it was but can no longer be simple,
2486 // we shouldn't set this.
2487 needsCompareFamilies = true;
2488 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2489 needsCompareFamilies = true;
2490 }
2491 break;
2492 }
2493 default:
2494 return false;
2495 }
2496
2497 // Check if both types have a family and it's the same one.
2498 if (needsCompareFamilies) {
2499 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
2500 // This means both of them need to be registered to preserve state.
2501 // If we unwrapped and compared the inner types for wrappers instead,
2502 // then we would risk falsely saying two separate memo(Foo)
2503 // calls are equivalent because they wrap the same Foo function.
2504 var prevFamily = resolveFamily(prevType);
2505 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
2506 return true;
2507 }
2508 }
2509 return false;
2510 }
2511}
2512
2513function markFailedErrorBoundaryForHotReloading(fiber) {
2514 {
2515 if (resolveFamily === null) {
2516 // Hot reloading is disabled.
2517 return;
2518 }
2519 if (typeof WeakSet !== 'function') {
2520 return;
2521 }
2522 if (failedBoundaries === null) {
2523 failedBoundaries = new WeakSet();
2524 }
2525 failedBoundaries.add(fiber);
2526 }
2527}
2528
2529var scheduleRefresh = function (root, update) {
2530 {
2531 if (resolveFamily === null) {
2532 // Hot reloading is disabled.
2533 return;
2534 }
2535 var _staleFamilies = update.staleFamilies,
2536 _updatedFamilies = update.updatedFamilies;
2537
2538 flushPassiveEffects();
2539 flushSync(function () {
2540 scheduleFibersWithFamiliesRecursively(root.current, _updatedFamilies, _staleFamilies);
2541 });
2542 }
2543};
2544
2545var scheduleRoot = function (root, element) {
2546 {
2547 if (root.context !== emptyContextObject) {
2548 // Super edge case: root has a legacy _renderSubtree context
2549 // but we don't know the parentComponent so we can't pass it.
2550 // Just ignore. We'll delete this with _renderSubtree code path later.
2551 return;
2552 }
2553 flushPassiveEffects();
2554 updateContainerAtExpirationTime(element, root, null, Sync, null);
2555 }
2556};
2557
2558function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
2559 {
2560 var alternate = fiber.alternate,
2561 child = fiber.child,
2562 sibling = fiber.sibling,
2563 tag = fiber.tag,
2564 type = fiber.type;
2565
2566
2567 var candidateType = null;
2568 switch (tag) {
2569 case FunctionComponent:
2570 case SimpleMemoComponent:
2571 case ClassComponent:
2572 candidateType = type;
2573 break;
2574 case ForwardRef:
2575 candidateType = type.render;
2576 break;
2577 default:
2578 break;
2579 }
2580
2581 if (resolveFamily === null) {
2582 throw new Error('Expected resolveFamily to be set during hot reload.');
2583 }
2584
2585 var needsRender = false;
2586 var needsRemount = false;
2587 if (candidateType !== null) {
2588 var family = resolveFamily(candidateType);
2589 if (family !== undefined) {
2590 if (staleFamilies.has(family)) {
2591 needsRemount = true;
2592 } else if (updatedFamilies.has(family)) {
2593 needsRender = true;
2594 }
2595 }
2596 }
2597 if (failedBoundaries !== null) {
2598 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
2599 needsRemount = true;
2600 }
2601 }
2602
2603 if (needsRemount) {
2604 fiber._debugNeedsRemount = true;
2605 }
2606 if (needsRemount || needsRender) {
2607 scheduleWork(fiber, Sync);
2608 }
2609 if (child !== null && !needsRemount) {
2610 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
2611 }
2612 if (sibling !== null) {
2613 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
2614 }
2615 }
2616}
2617
2618var findHostInstancesForRefresh = function (root, families) {
2619 {
2620 var hostInstances = new Set();
2621 var types = new Set(families.map(function (family) {
2622 return family.current;
2623 }));
2624 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
2625 return hostInstances;
2626 }
2627};
2628
2629function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
2630 {
2631 var child = fiber.child,
2632 sibling = fiber.sibling,
2633 tag = fiber.tag,
2634 type = fiber.type;
2635
2636
2637 var candidateType = null;
2638 switch (tag) {
2639 case FunctionComponent:
2640 case SimpleMemoComponent:
2641 case ClassComponent:
2642 candidateType = type;
2643 break;
2644 case ForwardRef:
2645 candidateType = type.render;
2646 break;
2647 default:
2648 break;
2649 }
2650
2651 var didMatch = false;
2652 if (candidateType !== null) {
2653 if (types.has(candidateType)) {
2654 didMatch = true;
2655 }
2656 }
2657
2658 if (didMatch) {
2659 // We have a match. This only drills down to the closest host components.
2660 // There's no need to search deeper because for the purpose of giving
2661 // visual feedback, "flashing" outermost parent rectangles is sufficient.
2662 findHostInstancesForFiberShallowly(fiber, hostInstances);
2663 } else {
2664 // If there's no match, maybe there will be one further down in the child tree.
2665 if (child !== null) {
2666 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
2667 }
2668 }
2669
2670 if (sibling !== null) {
2671 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
2672 }
2673 }
2674}
2675
2676function findHostInstancesForFiberShallowly(fiber, hostInstances) {
2677 {
2678 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
2679 if (foundHostInstances) {
2680 return;
2681 }
2682 // If we didn't find any host children, fallback to closest host parent.
2683 var node = fiber;
2684 while (true) {
2685 switch (node.tag) {
2686 case HostComponent:
2687 hostInstances.add(node.stateNode);
2688 return;
2689 case HostPortal:
2690 hostInstances.add(node.stateNode.containerInfo);
2691 return;
2692 case HostRoot:
2693 hostInstances.add(node.stateNode.containerInfo);
2694 return;
2695 }
2696 if (node.return === null) {
2697 throw new Error('Expected to reach root first.');
2698 }
2699 node = node.return;
2700 }
2701 }
2702}
2703
2704function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
2705 {
2706 var node = fiber;
2707 var foundHostInstances = false;
2708 while (true) {
2709 if (node.tag === HostComponent) {
2710 // We got a match.
2711 foundHostInstances = true;
2712 hostInstances.add(node.stateNode);
2713 // There may still be more, so keep searching.
2714 } else if (node.child !== null) {
2715 node.child.return = node;
2716 node = node.child;
2717 continue;
2718 }
2719 if (node === fiber) {
2720 return foundHostInstances;
2721 }
2722 while (node.sibling === null) {
2723 if (node.return === null || node.return === fiber) {
2724 return foundHostInstances;
2725 }
2726 node = node.return;
2727 }
2728 node.sibling.return = node.return;
2729 node = node.sibling;
2730 }
2731 }
2732 return false;
2733}
2734
2735function resolveDefaultProps(Component, baseProps) {
2736 if (Component && Component.defaultProps) {
2737 // Resolve default props. Taken from ReactElement
2738 var props = _assign({}, baseProps);
2739 var defaultProps = Component.defaultProps;
2740 for (var propName in defaultProps) {
2741 if (props[propName] === undefined) {
2742 props[propName] = defaultProps[propName];
2743 }
2744 }
2745 return props;
2746 }
2747 return baseProps;
2748}
2749
2750function readLazyComponentType(lazyComponent) {
2751 var status = lazyComponent._status;
2752 var result = lazyComponent._result;
2753 switch (status) {
2754 case Resolved:
2755 {
2756 var Component = result;
2757 return Component;
2758 }
2759 case Rejected:
2760 {
2761 var error = result;
2762 throw error;
2763 }
2764 case Pending:
2765 {
2766 var thenable = result;
2767 throw thenable;
2768 }
2769 default:
2770 {
2771 lazyComponent._status = Pending;
2772 var ctor = lazyComponent._ctor;
2773 var _thenable = ctor();
2774 _thenable.then(function (moduleObject) {
2775 if (lazyComponent._status === Pending) {
2776 var defaultExport = moduleObject.default;
2777 {
2778 if (defaultExport === undefined) {
2779 warning$1(false, '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);
2780 }
2781 }
2782 lazyComponent._status = Resolved;
2783 lazyComponent._result = defaultExport;
2784 }
2785 }, function (error) {
2786 if (lazyComponent._status === Pending) {
2787 lazyComponent._status = Rejected;
2788 lazyComponent._result = error;
2789 }
2790 });
2791 // Handle synchronous thenables.
2792 switch (lazyComponent._status) {
2793 case Resolved:
2794 return lazyComponent._result;
2795 case Rejected:
2796 throw lazyComponent._result;
2797 }
2798 lazyComponent._result = _thenable;
2799 throw _thenable;
2800 }
2801 }
2802}
2803
2804var valueCursor = createCursor(null);
2805
2806var rendererSigil = void 0;
2807{
2808 // Use this to detect multiple renderers using the same context
2809 rendererSigil = {};
2810}
2811
2812var currentlyRenderingFiber = null;
2813var lastContextDependency = null;
2814var lastContextWithAllBitsObserved = null;
2815
2816var isDisallowedContextReadInDEV = false;
2817
2818function resetContextDependencies() {
2819 // This is called right before React yields execution, to ensure `readContext`
2820 // cannot be called outside the render phase.
2821 currentlyRenderingFiber = null;
2822 lastContextDependency = null;
2823 lastContextWithAllBitsObserved = null;
2824 {
2825 isDisallowedContextReadInDEV = false;
2826 }
2827}
2828
2829function enterDisallowedContextReadInDEV() {
2830 {
2831 isDisallowedContextReadInDEV = true;
2832 }
2833}
2834
2835function exitDisallowedContextReadInDEV() {
2836 {
2837 isDisallowedContextReadInDEV = false;
2838 }
2839}
2840
2841function pushProvider(providerFiber, nextValue) {
2842 var context = providerFiber.type._context;
2843
2844 if (isPrimaryRenderer) {
2845 push(valueCursor, context._currentValue, providerFiber);
2846
2847 context._currentValue = nextValue;
2848 {
2849 !(context._currentRenderer === undefined || context._currentRenderer === null || context._currentRenderer === rendererSigil) ? warningWithoutStack$1(false, 'Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.') : void 0;
2850 context._currentRenderer = rendererSigil;
2851 }
2852 } else {
2853 push(valueCursor, context._currentValue2, providerFiber);
2854
2855 context._currentValue2 = nextValue;
2856 {
2857 !(context._currentRenderer2 === undefined || context._currentRenderer2 === null || context._currentRenderer2 === rendererSigil) ? warningWithoutStack$1(false, 'Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.') : void 0;
2858 context._currentRenderer2 = rendererSigil;
2859 }
2860 }
2861}
2862
2863function popProvider(providerFiber) {
2864 var currentValue = valueCursor.current;
2865
2866 pop(valueCursor, providerFiber);
2867
2868 var context = providerFiber.type._context;
2869 if (isPrimaryRenderer) {
2870 context._currentValue = currentValue;
2871 } else {
2872 context._currentValue2 = currentValue;
2873 }
2874}
2875
2876function calculateChangedBits(context, newValue, oldValue) {
2877 if (is(oldValue, newValue)) {
2878 // No change
2879 return 0;
2880 } else {
2881 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
2882
2883 {
2884 !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0;
2885 }
2886 return changedBits | 0;
2887 }
2888}
2889
2890function scheduleWorkOnParentPath(parent, renderExpirationTime) {
2891 // Update the child expiration time of all the ancestors, including
2892 // the alternates.
2893 var node = parent;
2894 while (node !== null) {
2895 var alternate = node.alternate;
2896 if (node.childExpirationTime < renderExpirationTime) {
2897 node.childExpirationTime = renderExpirationTime;
2898 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
2899 alternate.childExpirationTime = renderExpirationTime;
2900 }
2901 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
2902 alternate.childExpirationTime = renderExpirationTime;
2903 } else {
2904 // Neither alternate was updated, which means the rest of the
2905 // ancestor path already has sufficient priority.
2906 break;
2907 }
2908 node = node.return;
2909 }
2910}
2911
2912function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
2913 var fiber = workInProgress.child;
2914 if (fiber !== null) {
2915 // Set the return pointer of the child to the work-in-progress fiber.
2916 fiber.return = workInProgress;
2917 }
2918 while (fiber !== null) {
2919 var nextFiber = void 0;
2920
2921 // Visit this fiber.
2922 var list = fiber.dependencies;
2923 if (list !== null) {
2924 nextFiber = fiber.child;
2925
2926 var dependency = list.firstContext;
2927 while (dependency !== null) {
2928 // Check if the context matches.
2929 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
2930 // Match! Schedule an update on this fiber.
2931
2932 if (fiber.tag === ClassComponent) {
2933 // Schedule a force update on the work-in-progress.
2934 var update = createUpdate(renderExpirationTime, null);
2935 update.tag = ForceUpdate;
2936 // TODO: Because we don't have a work-in-progress, this will add the
2937 // update to the current fiber, too, which means it will persist even if
2938 // this render is thrown away. Since it's a race condition, not sure it's
2939 // worth fixing.
2940 enqueueUpdate(fiber, update);
2941 }
2942
2943 if (fiber.expirationTime < renderExpirationTime) {
2944 fiber.expirationTime = renderExpirationTime;
2945 }
2946 var alternate = fiber.alternate;
2947 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
2948 alternate.expirationTime = renderExpirationTime;
2949 }
2950
2951 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
2952
2953 // Mark the expiration time on the list, too.
2954 if (list.expirationTime < renderExpirationTime) {
2955 list.expirationTime = renderExpirationTime;
2956 }
2957
2958 // Since we already found a match, we can stop traversing the
2959 // dependency list.
2960 break;
2961 }
2962 dependency = dependency.next;
2963 }
2964 } else if (fiber.tag === ContextProvider) {
2965 // Don't scan deeper if this is a matching provider
2966 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
2967 } else if (enableSuspenseServerRenderer && fiber.tag === DehydratedSuspenseComponent) {
2968 // If a dehydrated suspense component is in this subtree, we don't know
2969 // if it will have any context consumers in it. The best we can do is
2970 // mark it as having updates on its children.
2971 if (fiber.expirationTime < renderExpirationTime) {
2972 fiber.expirationTime = renderExpirationTime;
2973 }
2974 var _alternate = fiber.alternate;
2975 if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) {
2976 _alternate.expirationTime = renderExpirationTime;
2977 }
2978 // This is intentionally passing this fiber as the parent
2979 // because we want to schedule this fiber as having work
2980 // on its children. We'll use the childExpirationTime on
2981 // this fiber to indicate that a context has changed.
2982 scheduleWorkOnParentPath(fiber, renderExpirationTime);
2983 nextFiber = fiber.sibling;
2984 } else {
2985 // Traverse down.
2986 nextFiber = fiber.child;
2987 }
2988
2989 if (nextFiber !== null) {
2990 // Set the return pointer of the child to the work-in-progress fiber.
2991 nextFiber.return = fiber;
2992 } else {
2993 // No child. Traverse to next sibling.
2994 nextFiber = fiber;
2995 while (nextFiber !== null) {
2996 if (nextFiber === workInProgress) {
2997 // We're back to the root of this subtree. Exit.
2998 nextFiber = null;
2999 break;
3000 }
3001 var sibling = nextFiber.sibling;
3002 if (sibling !== null) {
3003 // Set the return pointer of the sibling to the work-in-progress fiber.
3004 sibling.return = nextFiber.return;
3005 nextFiber = sibling;
3006 break;
3007 }
3008 // No more siblings. Traverse up.
3009 nextFiber = nextFiber.return;
3010 }
3011 }
3012 fiber = nextFiber;
3013 }
3014}
3015
3016function prepareToReadContext(workInProgress, renderExpirationTime) {
3017 currentlyRenderingFiber = workInProgress;
3018 lastContextDependency = null;
3019 lastContextWithAllBitsObserved = null;
3020
3021 var dependencies = workInProgress.dependencies;
3022 if (dependencies !== null) {
3023 var firstContext = dependencies.firstContext;
3024 if (firstContext !== null) {
3025 if (dependencies.expirationTime >= renderExpirationTime) {
3026 // Context list has a pending update. Mark that this fiber performed work.
3027 markWorkInProgressReceivedUpdate();
3028 }
3029 // Reset the work-in-progress list
3030 dependencies.firstContext = null;
3031 }
3032 }
3033}
3034
3035function readContext(context, observedBits) {
3036 {
3037 // This warning would fire if you read context inside a Hook like useMemo.
3038 // Unlike the class check below, it's not enforced in production for perf.
3039 !!isDisallowedContextReadInDEV ? warning$1(false, '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().') : void 0;
3040 }
3041
3042 if (lastContextWithAllBitsObserved === context) {
3043 // Nothing to do. We already observe everything in this context.
3044 } else if (observedBits === false || observedBits === 0) {
3045 // Do not observe any updates.
3046 } else {
3047 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types.
3048 if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) {
3049 // Observe all updates.
3050 lastContextWithAllBitsObserved = context;
3051 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
3052 } else {
3053 resolvedObservedBits = observedBits;
3054 }
3055
3056 var contextItem = {
3057 context: context,
3058 observedBits: resolvedObservedBits,
3059 next: null
3060 };
3061
3062 if (lastContextDependency === null) {
3063 (function () {
3064 if (!(currentlyRenderingFiber !== null)) {
3065 {
3066 throw ReactError(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().'));
3067 }
3068 }
3069 })();
3070
3071 // This is the first dependency for this component. Create a new list.
3072 lastContextDependency = contextItem;
3073 currentlyRenderingFiber.dependencies = {
3074 expirationTime: NoWork,
3075 firstContext: contextItem,
3076 responders: null
3077 };
3078 } else {
3079 // Append a new context item.
3080 lastContextDependency = lastContextDependency.next = contextItem;
3081 }
3082 }
3083 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
3084}
3085
3086// UpdateQueue is a linked list of prioritized updates.
3087//
3088// Like fibers, update queues come in pairs: a current queue, which represents
3089// the visible state of the screen, and a work-in-progress queue, which can be
3090// mutated and processed asynchronously before it is committed — a form of
3091// double buffering. If a work-in-progress render is discarded before finishing,
3092// we create a new work-in-progress by cloning the current queue.
3093//
3094// Both queues share a persistent, singly-linked list structure. To schedule an
3095// update, we append it to the end of both queues. Each queue maintains a
3096// pointer to first update in the persistent list that hasn't been processed.
3097// The work-in-progress pointer always has a position equal to or greater than
3098// the current queue, since we always work on that one. The current queue's
3099// pointer is only updated during the commit phase, when we swap in the
3100// work-in-progress.
3101//
3102// For example:
3103//
3104// Current pointer: A - B - C - D - E - F
3105// Work-in-progress pointer: D - E - F
3106// ^
3107// The work-in-progress queue has
3108// processed more updates than current.
3109//
3110// The reason we append to both queues is because otherwise we might drop
3111// updates without ever processing them. For example, if we only add updates to
3112// the work-in-progress queue, some updates could be lost whenever a work-in
3113// -progress render restarts by cloning from current. Similarly, if we only add
3114// updates to the current queue, the updates will be lost whenever an already
3115// in-progress queue commits and swaps with the current queue. However, by
3116// adding to both queues, we guarantee that the update will be part of the next
3117// work-in-progress. (And because the work-in-progress queue becomes the
3118// current queue once it commits, there's no danger of applying the same
3119// update twice.)
3120//
3121// Prioritization
3122// --------------
3123//
3124// Updates are not sorted by priority, but by insertion; new updates are always
3125// appended to the end of the list.
3126//
3127// The priority is still important, though. When processing the update queue
3128// during the render phase, only the updates with sufficient priority are
3129// included in the result. If we skip an update because it has insufficient
3130// priority, it remains in the queue to be processed later, during a lower
3131// priority render. Crucially, all updates subsequent to a skipped update also
3132// remain in the queue *regardless of their priority*. That means high priority
3133// updates are sometimes processed twice, at two separate priorities. We also
3134// keep track of a base state, that represents the state before the first
3135// update in the queue is applied.
3136//
3137// For example:
3138//
3139// Given a base state of '', and the following queue of updates
3140//
3141// A1 - B2 - C1 - D2
3142//
3143// where the number indicates the priority, and the update is applied to the
3144// previous state by appending a letter, React will process these updates as
3145// two separate renders, one per distinct priority level:
3146//
3147// First render, at priority 1:
3148// Base state: ''
3149// Updates: [A1, C1]
3150// Result state: 'AC'
3151//
3152// Second render, at priority 2:
3153// Base state: 'A' <- The base state does not include C1,
3154// because B2 was skipped.
3155// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
3156// Result state: 'ABCD'
3157//
3158// Because we process updates in insertion order, and rebase high priority
3159// updates when preceding updates are skipped, the final result is deterministic
3160// regardless of priority. Intermediate state may vary according to system
3161// resources, but the final state is always the same.
3162
3163var UpdateState = 0;
3164var ReplaceState = 1;
3165var ForceUpdate = 2;
3166var CaptureUpdate = 3;
3167
3168// Global state that is reset at the beginning of calling `processUpdateQueue`.
3169// It should only be read right after calling `processUpdateQueue`, via
3170// `checkHasForceUpdateAfterProcessing`.
3171var hasForceUpdate = false;
3172
3173var didWarnUpdateInsideUpdate = void 0;
3174var currentlyProcessingQueue = void 0;
3175
3176{
3177 didWarnUpdateInsideUpdate = false;
3178 currentlyProcessingQueue = null;
3179
3180}
3181
3182function createUpdateQueue(baseState) {
3183 var queue = {
3184 baseState: baseState,
3185 firstUpdate: null,
3186 lastUpdate: null,
3187 firstCapturedUpdate: null,
3188 lastCapturedUpdate: null,
3189 firstEffect: null,
3190 lastEffect: null,
3191 firstCapturedEffect: null,
3192 lastCapturedEffect: null
3193 };
3194 return queue;
3195}
3196
3197function cloneUpdateQueue(currentQueue) {
3198 var queue = {
3199 baseState: currentQueue.baseState,
3200 firstUpdate: currentQueue.firstUpdate,
3201 lastUpdate: currentQueue.lastUpdate,
3202
3203 // TODO: With resuming, if we bail out and resuse the child tree, we should
3204 // keep these effects.
3205 firstCapturedUpdate: null,
3206 lastCapturedUpdate: null,
3207
3208 firstEffect: null,
3209 lastEffect: null,
3210
3211 firstCapturedEffect: null,
3212 lastCapturedEffect: null
3213 };
3214 return queue;
3215}
3216
3217function createUpdate(expirationTime, suspenseConfig) {
3218 var update = {
3219 expirationTime: expirationTime,
3220 suspenseConfig: suspenseConfig,
3221
3222 tag: UpdateState,
3223 payload: null,
3224 callback: null,
3225
3226 next: null,
3227 nextEffect: null
3228 };
3229 {
3230 update.priority = getCurrentPriorityLevel();
3231 }
3232 return update;
3233}
3234
3235function appendUpdateToQueue(queue, update) {
3236 // Append the update to the end of the list.
3237 if (queue.lastUpdate === null) {
3238 // Queue is empty
3239 queue.firstUpdate = queue.lastUpdate = update;
3240 } else {
3241 queue.lastUpdate.next = update;
3242 queue.lastUpdate = update;
3243 }
3244}
3245
3246function enqueueUpdate(fiber, update) {
3247 // Update queues are created lazily.
3248 var alternate = fiber.alternate;
3249 var queue1 = void 0;
3250 var queue2 = void 0;
3251 if (alternate === null) {
3252 // There's only one fiber.
3253 queue1 = fiber.updateQueue;
3254 queue2 = null;
3255 if (queue1 === null) {
3256 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
3257 }
3258 } else {
3259 // There are two owners.
3260 queue1 = fiber.updateQueue;
3261 queue2 = alternate.updateQueue;
3262 if (queue1 === null) {
3263 if (queue2 === null) {
3264 // Neither fiber has an update queue. Create new ones.
3265 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
3266 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
3267 } else {
3268 // Only one fiber has an update queue. Clone to create a new one.
3269 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
3270 }
3271 } else {
3272 if (queue2 === null) {
3273 // Only one fiber has an update queue. Clone to create a new one.
3274 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
3275 } else {
3276 // Both owners have an update queue.
3277 }
3278 }
3279 }
3280 if (queue2 === null || queue1 === queue2) {
3281 // There's only a single queue.
3282 appendUpdateToQueue(queue1, update);
3283 } else {
3284 // There are two queues. We need to append the update to both queues,
3285 // while accounting for the persistent structure of the list — we don't
3286 // want the same update to be added multiple times.
3287 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
3288 // One of the queues is not empty. We must add the update to both queues.
3289 appendUpdateToQueue(queue1, update);
3290 appendUpdateToQueue(queue2, update);
3291 } else {
3292 // Both queues are non-empty. The last update is the same in both lists,
3293 // because of structural sharing. So, only append to one of the lists.
3294 appendUpdateToQueue(queue1, update);
3295 // But we still need to update the `lastUpdate` pointer of queue2.
3296 queue2.lastUpdate = update;
3297 }
3298 }
3299
3300 {
3301 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
3302 warningWithoutStack$1(false, '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.');
3303 didWarnUpdateInsideUpdate = true;
3304 }
3305 }
3306}
3307
3308function enqueueCapturedUpdate(workInProgress, update) {
3309 // Captured updates go into a separate list, and only on the work-in-
3310 // progress queue.
3311 var workInProgressQueue = workInProgress.updateQueue;
3312 if (workInProgressQueue === null) {
3313 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
3314 } else {
3315 // TODO: I put this here rather than createWorkInProgress so that we don't
3316 // clone the queue unnecessarily. There's probably a better way to
3317 // structure this.
3318 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
3319 }
3320
3321 // Append the update to the end of the list.
3322 if (workInProgressQueue.lastCapturedUpdate === null) {
3323 // This is the first render phase update
3324 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
3325 } else {
3326 workInProgressQueue.lastCapturedUpdate.next = update;
3327 workInProgressQueue.lastCapturedUpdate = update;
3328 }
3329}
3330
3331function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
3332 var current = workInProgress.alternate;
3333 if (current !== null) {
3334 // If the work-in-progress queue is equal to the current queue,
3335 // we need to clone it first.
3336 if (queue === current.updateQueue) {
3337 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
3338 }
3339 }
3340 return queue;
3341}
3342
3343function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
3344 switch (update.tag) {
3345 case ReplaceState:
3346 {
3347 var _payload = update.payload;
3348 if (typeof _payload === 'function') {
3349 // Updater function
3350 {
3351 enterDisallowedContextReadInDEV();
3352 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
3353 _payload.call(instance, prevState, nextProps);
3354 }
3355 }
3356 var nextState = _payload.call(instance, prevState, nextProps);
3357 {
3358 exitDisallowedContextReadInDEV();
3359 }
3360 return nextState;
3361 }
3362 // State object
3363 return _payload;
3364 }
3365 case CaptureUpdate:
3366 {
3367 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
3368 }
3369 // Intentional fallthrough
3370 case UpdateState:
3371 {
3372 var _payload2 = update.payload;
3373 var partialState = void 0;
3374 if (typeof _payload2 === 'function') {
3375 // Updater function
3376 {
3377 enterDisallowedContextReadInDEV();
3378 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
3379 _payload2.call(instance, prevState, nextProps);
3380 }
3381 }
3382 partialState = _payload2.call(instance, prevState, nextProps);
3383 {
3384 exitDisallowedContextReadInDEV();
3385 }
3386 } else {
3387 // Partial state object
3388 partialState = _payload2;
3389 }
3390 if (partialState === null || partialState === undefined) {
3391 // Null and undefined are treated as no-ops.
3392 return prevState;
3393 }
3394 // Merge the partial state and the previous state.
3395 return _assign({}, prevState, partialState);
3396 }
3397 case ForceUpdate:
3398 {
3399 hasForceUpdate = true;
3400 return prevState;
3401 }
3402 }
3403 return prevState;
3404}
3405
3406function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
3407 hasForceUpdate = false;
3408
3409 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
3410
3411 {
3412 currentlyProcessingQueue = queue;
3413 }
3414
3415 // These values may change as we process the queue.
3416 var newBaseState = queue.baseState;
3417 var newFirstUpdate = null;
3418 var newExpirationTime = NoWork;
3419
3420 // Iterate through the list of updates to compute the result.
3421 var update = queue.firstUpdate;
3422 var resultState = newBaseState;
3423 while (update !== null) {
3424 var updateExpirationTime = update.expirationTime;
3425 if (updateExpirationTime < renderExpirationTime) {
3426 // This update does not have sufficient priority. Skip it.
3427 if (newFirstUpdate === null) {
3428 // This is the first skipped update. It will be the first update in
3429 // the new list.
3430 newFirstUpdate = update;
3431 // Since this is the first update that was skipped, the current result
3432 // is the new base state.
3433 newBaseState = resultState;
3434 }
3435 // Since this update will remain in the list, update the remaining
3436 // expiration time.
3437 if (newExpirationTime < updateExpirationTime) {
3438 newExpirationTime = updateExpirationTime;
3439 }
3440 } else {
3441 // This update does have sufficient priority.
3442
3443 // Mark the event time of this update as relevant to this render pass.
3444 // TODO: This should ideally use the true event time of this update rather than
3445 // its priority which is a derived and not reverseable value.
3446 // TODO: We should skip this update if it was already committed but currently
3447 // we have no way of detecting the difference between a committed and suspended
3448 // update here.
3449 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig);
3450
3451 // Process it and compute a new result.
3452 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
3453 var _callback = update.callback;
3454 if (_callback !== null) {
3455 workInProgress.effectTag |= Callback;
3456 // Set this to null, in case it was mutated during an aborted render.
3457 update.nextEffect = null;
3458 if (queue.lastEffect === null) {
3459 queue.firstEffect = queue.lastEffect = update;
3460 } else {
3461 queue.lastEffect.nextEffect = update;
3462 queue.lastEffect = update;
3463 }
3464 }
3465 }
3466 // Continue to the next update.
3467 update = update.next;
3468 }
3469
3470 // Separately, iterate though the list of captured updates.
3471 var newFirstCapturedUpdate = null;
3472 update = queue.firstCapturedUpdate;
3473 while (update !== null) {
3474 var _updateExpirationTime = update.expirationTime;
3475 if (_updateExpirationTime < renderExpirationTime) {
3476 // This update does not have sufficient priority. Skip it.
3477 if (newFirstCapturedUpdate === null) {
3478 // This is the first skipped captured update. It will be the first
3479 // update in the new list.
3480 newFirstCapturedUpdate = update;
3481 // If this is the first update that was skipped, the current result is
3482 // the new base state.
3483 if (newFirstUpdate === null) {
3484 newBaseState = resultState;
3485 }
3486 }
3487 // Since this update will remain in the list, update the remaining
3488 // expiration time.
3489 if (newExpirationTime < _updateExpirationTime) {
3490 newExpirationTime = _updateExpirationTime;
3491 }
3492 } else {
3493 // This update does have sufficient priority. Process it and compute
3494 // a new result.
3495 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
3496 var _callback2 = update.callback;
3497 if (_callback2 !== null) {
3498 workInProgress.effectTag |= Callback;
3499 // Set this to null, in case it was mutated during an aborted render.
3500 update.nextEffect = null;
3501 if (queue.lastCapturedEffect === null) {
3502 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
3503 } else {
3504 queue.lastCapturedEffect.nextEffect = update;
3505 queue.lastCapturedEffect = update;
3506 }
3507 }
3508 }
3509 update = update.next;
3510 }
3511
3512 if (newFirstUpdate === null) {
3513 queue.lastUpdate = null;
3514 }
3515 if (newFirstCapturedUpdate === null) {
3516 queue.lastCapturedUpdate = null;
3517 } else {
3518 workInProgress.effectTag |= Callback;
3519 }
3520 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
3521 // We processed every update, without skipping. That means the new base
3522 // state is the same as the result state.
3523 newBaseState = resultState;
3524 }
3525
3526 queue.baseState = newBaseState;
3527 queue.firstUpdate = newFirstUpdate;
3528 queue.firstCapturedUpdate = newFirstCapturedUpdate;
3529
3530 // Set the remaining expiration time to be whatever is remaining in the queue.
3531 // This should be fine because the only two other things that contribute to
3532 // expiration time are props and context. We're already in the middle of the
3533 // begin phase by the time we start processing the queue, so we've already
3534 // dealt with the props. Context in components that specify
3535 // shouldComponentUpdate is tricky; but we'll have to account for
3536 // that regardless.
3537 workInProgress.expirationTime = newExpirationTime;
3538 workInProgress.memoizedState = resultState;
3539
3540 {
3541 currentlyProcessingQueue = null;
3542 }
3543}
3544
3545function callCallback(callback, context) {
3546 (function () {
3547 if (!(typeof callback === 'function')) {
3548 {
3549 throw ReactError(Error('Invalid argument passed as callback. Expected a function. Instead received: ' + callback));
3550 }
3551 }
3552 })();
3553 callback.call(context);
3554}
3555
3556function resetHasForceUpdateBeforeProcessing() {
3557 hasForceUpdate = false;
3558}
3559
3560function checkHasForceUpdateAfterProcessing() {
3561 return hasForceUpdate;
3562}
3563
3564function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
3565 // If the finished render included captured updates, and there are still
3566 // lower priority updates left over, we need to keep the captured updates
3567 // in the queue so that they are rebased and not dropped once we process the
3568 // queue again at the lower priority.
3569 if (finishedQueue.firstCapturedUpdate !== null) {
3570 // Join the captured update list to the end of the normal list.
3571 if (finishedQueue.lastUpdate !== null) {
3572 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
3573 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
3574 }
3575 // Clear the list of captured updates.
3576 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
3577 }
3578
3579 // Commit the effects
3580 commitUpdateEffects(finishedQueue.firstEffect, instance);
3581 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
3582
3583 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
3584 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
3585}
3586
3587function commitUpdateEffects(effect, instance) {
3588 while (effect !== null) {
3589 var _callback3 = effect.callback;
3590 if (_callback3 !== null) {
3591 effect.callback = null;
3592 callCallback(_callback3, instance);
3593 }
3594 effect = effect.nextEffect;
3595 }
3596}
3597
3598var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
3599
3600
3601function requestCurrentSuspenseConfig() {
3602 return ReactCurrentBatchConfig.suspense;
3603}
3604
3605var fakeInternalInstance = {};
3606var isArray$1 = Array.isArray;
3607
3608// React.Component uses a shared frozen object by default.
3609// We'll use it to determine whether we need to initialize legacy refs.
3610var emptyRefsObject = new React.Component().refs;
3611
3612var didWarnAboutStateAssignmentForComponent = void 0;
3613var didWarnAboutUninitializedState = void 0;
3614var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0;
3615var didWarnAboutLegacyLifecyclesAndDerivedState = void 0;
3616var didWarnAboutUndefinedDerivedState = void 0;
3617var warnOnUndefinedDerivedState = void 0;
3618var warnOnInvalidCallback = void 0;
3619var didWarnAboutDirectlyAssigningPropsToState = void 0;
3620var didWarnAboutContextTypeAndContextTypes = void 0;
3621var didWarnAboutInvalidateContextType = void 0;
3622
3623{
3624 didWarnAboutStateAssignmentForComponent = new Set();
3625 didWarnAboutUninitializedState = new Set();
3626 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
3627 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
3628 didWarnAboutDirectlyAssigningPropsToState = new Set();
3629 didWarnAboutUndefinedDerivedState = new Set();
3630 didWarnAboutContextTypeAndContextTypes = new Set();
3631 didWarnAboutInvalidateContextType = new Set();
3632
3633 var didWarnOnInvalidCallback = new Set();
3634
3635 warnOnInvalidCallback = function (callback, callerName) {
3636 if (callback === null || typeof callback === 'function') {
3637 return;
3638 }
3639 var key = callerName + '_' + callback;
3640 if (!didWarnOnInvalidCallback.has(key)) {
3641 didWarnOnInvalidCallback.add(key);
3642 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
3643 }
3644 };
3645
3646 warnOnUndefinedDerivedState = function (type, partialState) {
3647 if (partialState === undefined) {
3648 var componentName = getComponentName(type) || 'Component';
3649 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
3650 didWarnAboutUndefinedDerivedState.add(componentName);
3651 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
3652 }
3653 }
3654 };
3655
3656 // This is so gross but it's at least non-critical and can be removed if
3657 // it causes problems. This is meant to give a nicer error message for
3658 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
3659 // ...)) which otherwise throws a "_processChildContext is not a function"
3660 // exception.
3661 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
3662 enumerable: false,
3663 value: function () {
3664 (function () {
3665 {
3666 {
3667 throw ReactError(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).'));
3668 }
3669 }
3670 })();
3671 }
3672 });
3673 Object.freeze(fakeInternalInstance);
3674}
3675
3676function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
3677 var prevState = workInProgress.memoizedState;
3678
3679 {
3680 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
3681 // Invoke the function an extra time to help detect side-effects.
3682 getDerivedStateFromProps(nextProps, prevState);
3683 }
3684 }
3685
3686 var partialState = getDerivedStateFromProps(nextProps, prevState);
3687
3688 {
3689 warnOnUndefinedDerivedState(ctor, partialState);
3690 }
3691 // Merge the partial state and the previous state.
3692 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
3693 workInProgress.memoizedState = memoizedState;
3694
3695 // Once the update queue is empty, persist the derived state onto the
3696 // base state.
3697 var updateQueue = workInProgress.updateQueue;
3698 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
3699 updateQueue.baseState = memoizedState;
3700 }
3701}
3702
3703var classComponentUpdater = {
3704 isMounted: isMounted,
3705 enqueueSetState: function (inst, payload, callback) {
3706 var fiber = get(inst);
3707 var currentTime = requestCurrentTime();
3708 var suspenseConfig = requestCurrentSuspenseConfig();
3709 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3710
3711 var update = createUpdate(expirationTime, suspenseConfig);
3712 update.payload = payload;
3713 if (callback !== undefined && callback !== null) {
3714 {
3715 warnOnInvalidCallback(callback, 'setState');
3716 }
3717 update.callback = callback;
3718 }
3719
3720 if (revertPassiveEffectsChange) {
3721 flushPassiveEffects();
3722 }
3723 enqueueUpdate(fiber, update);
3724 scheduleWork(fiber, expirationTime);
3725 },
3726 enqueueReplaceState: function (inst, payload, callback) {
3727 var fiber = get(inst);
3728 var currentTime = requestCurrentTime();
3729 var suspenseConfig = requestCurrentSuspenseConfig();
3730 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3731
3732 var update = createUpdate(expirationTime, suspenseConfig);
3733 update.tag = ReplaceState;
3734 update.payload = payload;
3735
3736 if (callback !== undefined && callback !== null) {
3737 {
3738 warnOnInvalidCallback(callback, 'replaceState');
3739 }
3740 update.callback = callback;
3741 }
3742
3743 if (revertPassiveEffectsChange) {
3744 flushPassiveEffects();
3745 }
3746 enqueueUpdate(fiber, update);
3747 scheduleWork(fiber, expirationTime);
3748 },
3749 enqueueForceUpdate: function (inst, callback) {
3750 var fiber = get(inst);
3751 var currentTime = requestCurrentTime();
3752 var suspenseConfig = requestCurrentSuspenseConfig();
3753 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3754
3755 var update = createUpdate(expirationTime, suspenseConfig);
3756 update.tag = ForceUpdate;
3757
3758 if (callback !== undefined && callback !== null) {
3759 {
3760 warnOnInvalidCallback(callback, 'forceUpdate');
3761 }
3762 update.callback = callback;
3763 }
3764
3765 if (revertPassiveEffectsChange) {
3766 flushPassiveEffects();
3767 }
3768 enqueueUpdate(fiber, update);
3769 scheduleWork(fiber, expirationTime);
3770 }
3771};
3772
3773function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
3774 var instance = workInProgress.stateNode;
3775 if (typeof instance.shouldComponentUpdate === 'function') {
3776 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
3777 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
3778 stopPhaseTimer();
3779
3780 {
3781 !(shouldUpdate !== undefined) ? warningWithoutStack$1(false, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component') : void 0;
3782 }
3783
3784 return shouldUpdate;
3785 }
3786
3787 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
3788 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
3789 }
3790
3791 return true;
3792}
3793
3794function checkClassInstance(workInProgress, ctor, newProps) {
3795 var instance = workInProgress.stateNode;
3796 {
3797 var name = getComponentName(ctor) || 'Component';
3798 var renderPresent = instance.render;
3799
3800 if (!renderPresent) {
3801 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
3802 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
3803 } else {
3804 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
3805 }
3806 }
3807
3808 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
3809 !noGetInitialStateOnES6 ? warningWithoutStack$1(false, '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) : void 0;
3810 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
3811 !noGetDefaultPropsOnES6 ? warningWithoutStack$1(false, '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) : void 0;
3812 var noInstancePropTypes = !instance.propTypes;
3813 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
3814 var noInstanceContextType = !instance.contextType;
3815 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
3816
3817 if (disableLegacyContext) {
3818 if (ctor.childContextTypes) {
3819 warningWithoutStack$1(false, '%s uses the legacy childContextTypes API which is no longer supported. ' + 'Use React.createContext() instead.', name);
3820 }
3821 if (ctor.contextTypes) {
3822 warningWithoutStack$1(false, '%s uses the legacy contextTypes API which is no longer supported. ' + 'Use React.createContext() with static contextType instead.', name);
3823 }
3824 } else {
3825 var noInstanceContextTypes = !instance.contextTypes;
3826 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
3827
3828 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
3829 didWarnAboutContextTypeAndContextTypes.add(ctor);
3830 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
3831 }
3832 }
3833
3834 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
3835 !noComponentShouldUpdate ? warningWithoutStack$1(false, '%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) : void 0;
3836 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
3837 warningWithoutStack$1(false, '%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');
3838 }
3839 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
3840 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
3841 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
3842 !noComponentDidReceiveProps ? warningWithoutStack$1(false, '%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) : void 0;
3843 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
3844 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
3845 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
3846 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
3847 var hasMutatedProps = instance.props !== newProps;
3848 !(instance.props === undefined || !hasMutatedProps) ? warningWithoutStack$1(false, '%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name) : void 0;
3849 var noInstanceDefaultProps = !instance.defaultProps;
3850 !noInstanceDefaultProps ? warningWithoutStack$1(false, '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) : void 0;
3851
3852 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
3853 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
3854 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
3855 }
3856
3857 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
3858 !noInstanceGetDerivedStateFromProps ? warningWithoutStack$1(false, '%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name) : void 0;
3859 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
3860 !noInstanceGetDerivedStateFromCatch ? warningWithoutStack$1(false, '%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name) : void 0;
3861 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
3862 !noStaticGetSnapshotBeforeUpdate ? warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name) : void 0;
3863 var _state = instance.state;
3864 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
3865 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
3866 }
3867 if (typeof instance.getChildContext === 'function') {
3868 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
3869 }
3870 }
3871}
3872
3873function adoptClassInstance(workInProgress, instance) {
3874 instance.updater = classComponentUpdater;
3875 workInProgress.stateNode = instance;
3876 // The instance needs access to the fiber so that it can schedule updates
3877 set(instance, workInProgress);
3878 {
3879 instance._reactInternalInstance = fakeInternalInstance;
3880 }
3881}
3882
3883function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
3884 var isLegacyContextConsumer = false;
3885 var unmaskedContext = emptyContextObject;
3886 var context = emptyContextObject;
3887 var contextType = ctor.contextType;
3888
3889 {
3890 if ('contextType' in ctor) {
3891 var isValid =
3892 // Allow null for conditional declaration
3893 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
3894
3895 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
3896 didWarnAboutInvalidateContextType.add(ctor);
3897
3898 var addendum = '';
3899 if (contextType === undefined) {
3900 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.';
3901 } else if (typeof contextType !== 'object') {
3902 addendum = ' However, it is set to a ' + typeof contextType + '.';
3903 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
3904 addendum = ' Did you accidentally pass the Context.Provider instead?';
3905 } else if (contextType._context !== undefined) {
3906 // <Context.Consumer>
3907 addendum = ' Did you accidentally pass the Context.Consumer instead?';
3908 } else {
3909 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
3910 }
3911 warningWithoutStack$1(false, '%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
3912 }
3913 }
3914 }
3915
3916 if (typeof contextType === 'object' && contextType !== null) {
3917 context = readContext(contextType);
3918 } else if (!disableLegacyContext) {
3919 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
3920 var contextTypes = ctor.contextTypes;
3921 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
3922 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
3923 }
3924
3925 // Instantiate twice to help detect side-effects.
3926 {
3927 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
3928 new ctor(props, context); // eslint-disable-line no-new
3929 }
3930 }
3931
3932 var instance = new ctor(props, context);
3933 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
3934 adoptClassInstance(workInProgress, instance);
3935
3936 {
3937 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
3938 var componentName = getComponentName(ctor) || 'Component';
3939 if (!didWarnAboutUninitializedState.has(componentName)) {
3940 didWarnAboutUninitializedState.add(componentName);
3941 warningWithoutStack$1(false, '`%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);
3942 }
3943 }
3944
3945 // If new component APIs are defined, "unsafe" lifecycles won't be called.
3946 // Warn about these lifecycles if they are present.
3947 // Don't warn about react-lifecycles-compat polyfilled methods though.
3948 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
3949 var foundWillMountName = null;
3950 var foundWillReceivePropsName = null;
3951 var foundWillUpdateName = null;
3952 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
3953 foundWillMountName = 'componentWillMount';
3954 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
3955 foundWillMountName = 'UNSAFE_componentWillMount';
3956 }
3957 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
3958 foundWillReceivePropsName = 'componentWillReceiveProps';
3959 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
3960 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
3961 }
3962 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
3963 foundWillUpdateName = 'componentWillUpdate';
3964 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
3965 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
3966 }
3967 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
3968 var _componentName = getComponentName(ctor) || 'Component';
3969 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
3970 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
3971 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
3972 warningWithoutStack$1(false, '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-async-component-lifecycle-hooks', _componentName, newApiName, foundWillMountName !== null ? '\n ' + foundWillMountName : '', foundWillReceivePropsName !== null ? '\n ' + foundWillReceivePropsName : '', foundWillUpdateName !== null ? '\n ' + foundWillUpdateName : '');
3973 }
3974 }
3975 }
3976 }
3977
3978 // Cache unmasked context so we can avoid recreating masked context unless necessary.
3979 // ReactFiberContext usually updates this cache but can't for newly-created instances.
3980 if (isLegacyContextConsumer) {
3981 cacheContext(workInProgress, unmaskedContext, context);
3982 }
3983
3984 return instance;
3985}
3986
3987function callComponentWillMount(workInProgress, instance) {
3988 startPhaseTimer(workInProgress, 'componentWillMount');
3989 var oldState = instance.state;
3990
3991 if (typeof instance.componentWillMount === 'function') {
3992 instance.componentWillMount();
3993 }
3994 if (typeof instance.UNSAFE_componentWillMount === 'function') {
3995 instance.UNSAFE_componentWillMount();
3996 }
3997
3998 stopPhaseTimer();
3999
4000 if (oldState !== instance.state) {
4001 {
4002 warningWithoutStack$1(false, '%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress.type) || 'Component');
4003 }
4004 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4005 }
4006}
4007
4008function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
4009 var oldState = instance.state;
4010 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
4011 if (typeof instance.componentWillReceiveProps === 'function') {
4012 instance.componentWillReceiveProps(newProps, nextContext);
4013 }
4014 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4015 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
4016 }
4017 stopPhaseTimer();
4018
4019 if (instance.state !== oldState) {
4020 {
4021 var componentName = getComponentName(workInProgress.type) || 'Component';
4022 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
4023 didWarnAboutStateAssignmentForComponent.add(componentName);
4024 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
4025 }
4026 }
4027 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4028 }
4029}
4030
4031// Invokes the mount life-cycles on a previously never rendered instance.
4032function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4033 {
4034 checkClassInstance(workInProgress, ctor, newProps);
4035 }
4036
4037 var instance = workInProgress.stateNode;
4038 instance.props = newProps;
4039 instance.state = workInProgress.memoizedState;
4040 instance.refs = emptyRefsObject;
4041
4042 var contextType = ctor.contextType;
4043 if (typeof contextType === 'object' && contextType !== null) {
4044 instance.context = readContext(contextType);
4045 } else if (disableLegacyContext) {
4046 instance.context = emptyContextObject;
4047 } else {
4048 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4049 instance.context = getMaskedContext(workInProgress, unmaskedContext);
4050 }
4051
4052 {
4053 if (instance.state === newProps) {
4054 var componentName = getComponentName(ctor) || 'Component';
4055 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
4056 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
4057 warningWithoutStack$1(false, '%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);
4058 }
4059 }
4060
4061 if (workInProgress.mode & StrictMode) {
4062 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
4063 }
4064
4065 if (warnAboutDeprecatedLifecycles) {
4066 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
4067 }
4068 }
4069
4070 var updateQueue = workInProgress.updateQueue;
4071 if (updateQueue !== null) {
4072 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4073 instance.state = workInProgress.memoizedState;
4074 }
4075
4076 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4077 if (typeof getDerivedStateFromProps === 'function') {
4078 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4079 instance.state = workInProgress.memoizedState;
4080 }
4081
4082 // In order to support react-lifecycles-compat polyfilled components,
4083 // Unsafe lifecycles should not be invoked for components using the new APIs.
4084 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4085 callComponentWillMount(workInProgress, instance);
4086 // If we had additional state updates during this life-cycle, let's
4087 // process them now.
4088 updateQueue = workInProgress.updateQueue;
4089 if (updateQueue !== null) {
4090 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4091 instance.state = workInProgress.memoizedState;
4092 }
4093 }
4094
4095 if (typeof instance.componentDidMount === 'function') {
4096 workInProgress.effectTag |= Update;
4097 }
4098}
4099
4100function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4101 var instance = workInProgress.stateNode;
4102
4103 var oldProps = workInProgress.memoizedProps;
4104 instance.props = oldProps;
4105
4106 var oldContext = instance.context;
4107 var contextType = ctor.contextType;
4108 var nextContext = emptyContextObject;
4109 if (typeof contextType === 'object' && contextType !== null) {
4110 nextContext = readContext(contextType);
4111 } else if (!disableLegacyContext) {
4112 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4113 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
4114 }
4115
4116 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4117 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
4118
4119 // Note: During these life-cycles, instance.props/instance.state are what
4120 // ever the previously attempted to render - not the "current". However,
4121 // during componentDidUpdate we pass the "current" props.
4122
4123 // In order to support react-lifecycles-compat polyfilled components,
4124 // Unsafe lifecycles should not be invoked for components using the new APIs.
4125 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4126 if (oldProps !== newProps || oldContext !== nextContext) {
4127 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4128 }
4129 }
4130
4131 resetHasForceUpdateBeforeProcessing();
4132
4133 var oldState = workInProgress.memoizedState;
4134 var newState = instance.state = oldState;
4135 var updateQueue = workInProgress.updateQueue;
4136 if (updateQueue !== null) {
4137 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4138 newState = workInProgress.memoizedState;
4139 }
4140 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4141 // If an update was already in progress, we should schedule an Update
4142 // effect even though we're bailing out, so that cWU/cDU are called.
4143 if (typeof instance.componentDidMount === 'function') {
4144 workInProgress.effectTag |= Update;
4145 }
4146 return false;
4147 }
4148
4149 if (typeof getDerivedStateFromProps === 'function') {
4150 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4151 newState = workInProgress.memoizedState;
4152 }
4153
4154 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4155
4156 if (shouldUpdate) {
4157 // In order to support react-lifecycles-compat polyfilled components,
4158 // Unsafe lifecycles should not be invoked for components using the new APIs.
4159 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4160 startPhaseTimer(workInProgress, 'componentWillMount');
4161 if (typeof instance.componentWillMount === 'function') {
4162 instance.componentWillMount();
4163 }
4164 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4165 instance.UNSAFE_componentWillMount();
4166 }
4167 stopPhaseTimer();
4168 }
4169 if (typeof instance.componentDidMount === 'function') {
4170 workInProgress.effectTag |= Update;
4171 }
4172 } else {
4173 // If an update was already in progress, we should schedule an Update
4174 // effect even though we're bailing out, so that cWU/cDU are called.
4175 if (typeof instance.componentDidMount === 'function') {
4176 workInProgress.effectTag |= Update;
4177 }
4178
4179 // If shouldComponentUpdate returned false, we should still update the
4180 // memoized state to indicate that this work can be reused.
4181 workInProgress.memoizedProps = newProps;
4182 workInProgress.memoizedState = newState;
4183 }
4184
4185 // Update the existing instance's state, props, and context pointers even
4186 // if shouldComponentUpdate returns false.
4187 instance.props = newProps;
4188 instance.state = newState;
4189 instance.context = nextContext;
4190
4191 return shouldUpdate;
4192}
4193
4194// Invokes the update life-cycles and returns false if it shouldn't rerender.
4195function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
4196 var instance = workInProgress.stateNode;
4197
4198 var oldProps = workInProgress.memoizedProps;
4199 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
4200
4201 var oldContext = instance.context;
4202 var contextType = ctor.contextType;
4203 var nextContext = emptyContextObject;
4204 if (typeof contextType === 'object' && contextType !== null) {
4205 nextContext = readContext(contextType);
4206 } else if (!disableLegacyContext) {
4207 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4208 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
4209 }
4210
4211 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4212 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
4213
4214 // Note: During these life-cycles, instance.props/instance.state are what
4215 // ever the previously attempted to render - not the "current". However,
4216 // during componentDidUpdate we pass the "current" props.
4217
4218 // In order to support react-lifecycles-compat polyfilled components,
4219 // Unsafe lifecycles should not be invoked for components using the new APIs.
4220 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4221 if (oldProps !== newProps || oldContext !== nextContext) {
4222 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4223 }
4224 }
4225
4226 resetHasForceUpdateBeforeProcessing();
4227
4228 var oldState = workInProgress.memoizedState;
4229 var newState = instance.state = oldState;
4230 var updateQueue = workInProgress.updateQueue;
4231 if (updateQueue !== null) {
4232 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4233 newState = workInProgress.memoizedState;
4234 }
4235
4236 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4237 // If an update was already in progress, we should schedule an Update
4238 // effect even though we're bailing out, so that cWU/cDU are called.
4239 if (typeof instance.componentDidUpdate === 'function') {
4240 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4241 workInProgress.effectTag |= Update;
4242 }
4243 }
4244 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4245 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4246 workInProgress.effectTag |= Snapshot;
4247 }
4248 }
4249 return false;
4250 }
4251
4252 if (typeof getDerivedStateFromProps === 'function') {
4253 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4254 newState = workInProgress.memoizedState;
4255 }
4256
4257 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4258
4259 if (shouldUpdate) {
4260 // In order to support react-lifecycles-compat polyfilled components,
4261 // Unsafe lifecycles should not be invoked for components using the new APIs.
4262 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
4263 startPhaseTimer(workInProgress, 'componentWillUpdate');
4264 if (typeof instance.componentWillUpdate === 'function') {
4265 instance.componentWillUpdate(newProps, newState, nextContext);
4266 }
4267 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4268 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
4269 }
4270 stopPhaseTimer();
4271 }
4272 if (typeof instance.componentDidUpdate === 'function') {
4273 workInProgress.effectTag |= Update;
4274 }
4275 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4276 workInProgress.effectTag |= Snapshot;
4277 }
4278 } else {
4279 // If an update was already in progress, we should schedule an Update
4280 // effect even though we're bailing out, so that cWU/cDU are called.
4281 if (typeof instance.componentDidUpdate === 'function') {
4282 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4283 workInProgress.effectTag |= Update;
4284 }
4285 }
4286 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4287 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4288 workInProgress.effectTag |= Snapshot;
4289 }
4290 }
4291
4292 // If shouldComponentUpdate returned false, we should still update the
4293 // memoized props/state to indicate that this work can be reused.
4294 workInProgress.memoizedProps = newProps;
4295 workInProgress.memoizedState = newState;
4296 }
4297
4298 // Update the existing instance's state, props, and context pointers even
4299 // if shouldComponentUpdate returns false.
4300 instance.props = newProps;
4301 instance.state = newState;
4302 instance.context = nextContext;
4303
4304 return shouldUpdate;
4305}
4306
4307var didWarnAboutMaps = void 0;
4308var didWarnAboutGenerators = void 0;
4309var didWarnAboutStringRefInStrictMode = void 0;
4310var ownerHasKeyUseWarning = void 0;
4311var ownerHasFunctionTypeWarning = void 0;
4312var warnForMissingKey = function (child) {};
4313
4314{
4315 didWarnAboutMaps = false;
4316 didWarnAboutGenerators = false;
4317 didWarnAboutStringRefInStrictMode = {};
4318
4319 /**
4320 * Warn if there's no key explicitly set on dynamic arrays of children or
4321 * object keys are not valid. This allows us to keep track of children between
4322 * updates.
4323 */
4324 ownerHasKeyUseWarning = {};
4325 ownerHasFunctionTypeWarning = {};
4326
4327 warnForMissingKey = function (child) {
4328 if (child === null || typeof child !== 'object') {
4329 return;
4330 }
4331 if (!child._store || child._store.validated || child.key != null) {
4332 return;
4333 }
4334 (function () {
4335 if (!(typeof child._store === 'object')) {
4336 {
4337 throw ReactError(Error('React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue.'));
4338 }
4339 }
4340 })();
4341 child._store.validated = true;
4342
4343 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
4344 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
4345 return;
4346 }
4347 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
4348
4349 warning$1(false, 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
4350 };
4351}
4352
4353var isArray = Array.isArray;
4354
4355function coerceRef(returnFiber, current$$1, element) {
4356 var mixedRef = element.ref;
4357 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
4358 {
4359 if (returnFiber.mode & StrictMode) {
4360 var componentName = getComponentName(returnFiber.type) || 'Component';
4361 if (!didWarnAboutStringRefInStrictMode[componentName]) {
4362 warningWithoutStack$1(false, '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 createRef() instead.' + '\n%s' + '\n\nLearn more about using refs safely here:' + '\nhttps://fb.me/react-strict-mode-string-ref', mixedRef, getStackByFiberInDevAndProd(returnFiber));
4363 didWarnAboutStringRefInStrictMode[componentName] = true;
4364 }
4365 }
4366 }
4367
4368 if (element._owner) {
4369 var owner = element._owner;
4370 var inst = void 0;
4371 if (owner) {
4372 var ownerFiber = owner;
4373 (function () {
4374 if (!(ownerFiber.tag === ClassComponent)) {
4375 {
4376 throw ReactError(Error('Function components cannot have refs. Did you mean to use React.forwardRef()?'));
4377 }
4378 }
4379 })();
4380 inst = ownerFiber.stateNode;
4381 }
4382 (function () {
4383 if (!inst) {
4384 {
4385 throw ReactError(Error('Missing owner for string ref ' + mixedRef + '. This error is likely caused by a bug in React. Please file an issue.'));
4386 }
4387 }
4388 })();
4389 var stringRef = '' + mixedRef;
4390 // Check if previous string ref matches new string ref
4391 if (current$$1 !== null && current$$1.ref !== null && typeof current$$1.ref === 'function' && current$$1.ref._stringRef === stringRef) {
4392 return current$$1.ref;
4393 }
4394 var ref = function (value) {
4395 var refs = inst.refs;
4396 if (refs === emptyRefsObject) {
4397 // This is a lazy pooled frozen object, so we need to initialize.
4398 refs = inst.refs = {};
4399 }
4400 if (value === null) {
4401 delete refs[stringRef];
4402 } else {
4403 refs[stringRef] = value;
4404 }
4405 };
4406 ref._stringRef = stringRef;
4407 return ref;
4408 } else {
4409 (function () {
4410 if (!(typeof mixedRef === 'string')) {
4411 {
4412 throw ReactError(Error('Expected ref to be a function, a string, an object returned by React.createRef(), or null.'));
4413 }
4414 }
4415 })();
4416 (function () {
4417 if (!element._owner) {
4418 {
4419 throw ReactError(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.'));
4420 }
4421 }
4422 })();
4423 }
4424 }
4425 return mixedRef;
4426}
4427
4428function throwOnInvalidObjectType(returnFiber, newChild) {
4429 if (returnFiber.type !== 'textarea') {
4430 var addendum = '';
4431 {
4432 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
4433 }
4434 (function () {
4435 {
4436 {
4437 throw ReactError(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));
4438 }
4439 }
4440 })();
4441 }
4442}
4443
4444function warnOnFunctionType() {
4445 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();
4446
4447 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
4448 return;
4449 }
4450 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
4451
4452 warning$1(false, '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.');
4453}
4454
4455// This wrapper function exists because I expect to clone the code in each path
4456// to be able to optimize each path individually by branching early. This needs
4457// a compiler or we can do it manually. Helpers that don't need this branching
4458// live outside of this function.
4459function ChildReconciler(shouldTrackSideEffects) {
4460 function deleteChild(returnFiber, childToDelete) {
4461 if (!shouldTrackSideEffects) {
4462 // Noop.
4463 return;
4464 }
4465 // Deletions are added in reversed order so we add it to the front.
4466 // At this point, the return fiber's effect list is empty except for
4467 // deletions, so we can just append the deletion to the list. The remaining
4468 // effects aren't added until the complete phase. Once we implement
4469 // resuming, this may not be true.
4470 var last = returnFiber.lastEffect;
4471 if (last !== null) {
4472 last.nextEffect = childToDelete;
4473 returnFiber.lastEffect = childToDelete;
4474 } else {
4475 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
4476 }
4477 childToDelete.nextEffect = null;
4478 childToDelete.effectTag = Deletion;
4479 }
4480
4481 function deleteRemainingChildren(returnFiber, currentFirstChild) {
4482 if (!shouldTrackSideEffects) {
4483 // Noop.
4484 return null;
4485 }
4486
4487 // TODO: For the shouldClone case, this could be micro-optimized a bit by
4488 // assuming that after the first child we've already added everything.
4489 var childToDelete = currentFirstChild;
4490 while (childToDelete !== null) {
4491 deleteChild(returnFiber, childToDelete);
4492 childToDelete = childToDelete.sibling;
4493 }
4494 return null;
4495 }
4496
4497 function mapRemainingChildren(returnFiber, currentFirstChild) {
4498 // Add the remaining children to a temporary map so that we can find them by
4499 // keys quickly. Implicit (null) keys get added to this set with their index
4500 var existingChildren = new Map();
4501
4502 var existingChild = currentFirstChild;
4503 while (existingChild !== null) {
4504 if (existingChild.key !== null) {
4505 existingChildren.set(existingChild.key, existingChild);
4506 } else {
4507 existingChildren.set(existingChild.index, existingChild);
4508 }
4509 existingChild = existingChild.sibling;
4510 }
4511 return existingChildren;
4512 }
4513
4514 function useFiber(fiber, pendingProps, expirationTime) {
4515 // We currently set sibling to null and index to 0 here because it is easy
4516 // to forget to do before returning it. E.g. for the single child case.
4517 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
4518 clone.index = 0;
4519 clone.sibling = null;
4520 return clone;
4521 }
4522
4523 function placeChild(newFiber, lastPlacedIndex, newIndex) {
4524 newFiber.index = newIndex;
4525 if (!shouldTrackSideEffects) {
4526 // Noop.
4527 return lastPlacedIndex;
4528 }
4529 var current$$1 = newFiber.alternate;
4530 if (current$$1 !== null) {
4531 var oldIndex = current$$1.index;
4532 if (oldIndex < lastPlacedIndex) {
4533 // This is a move.
4534 newFiber.effectTag = Placement;
4535 return lastPlacedIndex;
4536 } else {
4537 // This item can stay in place.
4538 return oldIndex;
4539 }
4540 } else {
4541 // This is an insertion.
4542 newFiber.effectTag = Placement;
4543 return lastPlacedIndex;
4544 }
4545 }
4546
4547 function placeSingleChild(newFiber) {
4548 // This is simpler for the single child case. We only need to do a
4549 // placement for inserting new children.
4550 if (shouldTrackSideEffects && newFiber.alternate === null) {
4551 newFiber.effectTag = Placement;
4552 }
4553 return newFiber;
4554 }
4555
4556 function updateTextNode(returnFiber, current$$1, textContent, expirationTime) {
4557 if (current$$1 === null || current$$1.tag !== HostText) {
4558 // Insert
4559 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
4560 created.return = returnFiber;
4561 return created;
4562 } else {
4563 // Update
4564 var existing = useFiber(current$$1, textContent, expirationTime);
4565 existing.return = returnFiber;
4566 return existing;
4567 }
4568 }
4569
4570 function updateElement(returnFiber, current$$1, element, expirationTime) {
4571 if (current$$1 !== null && (current$$1.elementType === element.type || (
4572 // Keep this check inline so it only runs on the false path:
4573 isCompatibleFamilyForHotReloading(current$$1, element)))) {
4574 // Move based on index
4575 var existing = useFiber(current$$1, element.props, expirationTime);
4576 existing.ref = coerceRef(returnFiber, current$$1, element);
4577 existing.return = returnFiber;
4578 {
4579 existing._debugSource = element._source;
4580 existing._debugOwner = element._owner;
4581 }
4582 return existing;
4583 } else {
4584 // Insert
4585 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
4586 created.ref = coerceRef(returnFiber, current$$1, element);
4587 created.return = returnFiber;
4588 return created;
4589 }
4590 }
4591
4592 function updatePortal(returnFiber, current$$1, portal, expirationTime) {
4593 if (current$$1 === null || current$$1.tag !== HostPortal || current$$1.stateNode.containerInfo !== portal.containerInfo || current$$1.stateNode.implementation !== portal.implementation) {
4594 // Insert
4595 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
4596 created.return = returnFiber;
4597 return created;
4598 } else {
4599 // Update
4600 var existing = useFiber(current$$1, portal.children || [], expirationTime);
4601 existing.return = returnFiber;
4602 return existing;
4603 }
4604 }
4605
4606 function updateFragment(returnFiber, current$$1, fragment, expirationTime, key) {
4607 if (current$$1 === null || current$$1.tag !== Fragment) {
4608 // Insert
4609 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
4610 created.return = returnFiber;
4611 return created;
4612 } else {
4613 // Update
4614 var existing = useFiber(current$$1, fragment, expirationTime);
4615 existing.return = returnFiber;
4616 return existing;
4617 }
4618 }
4619
4620 function createChild(returnFiber, newChild, expirationTime) {
4621 if (typeof newChild === 'string' || typeof newChild === 'number') {
4622 // Text nodes don't have keys. If the previous node is implicitly keyed
4623 // we can continue to replace it without aborting even if it is not a text
4624 // node.
4625 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
4626 created.return = returnFiber;
4627 return created;
4628 }
4629
4630 if (typeof newChild === 'object' && newChild !== null) {
4631 switch (newChild.$$typeof) {
4632 case REACT_ELEMENT_TYPE:
4633 {
4634 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
4635 _created.ref = coerceRef(returnFiber, null, newChild);
4636 _created.return = returnFiber;
4637 return _created;
4638 }
4639 case REACT_PORTAL_TYPE:
4640 {
4641 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
4642 _created2.return = returnFiber;
4643 return _created2;
4644 }
4645 }
4646
4647 if (isArray(newChild) || getIteratorFn(newChild)) {
4648 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
4649 _created3.return = returnFiber;
4650 return _created3;
4651 }
4652
4653 throwOnInvalidObjectType(returnFiber, newChild);
4654 }
4655
4656 {
4657 if (typeof newChild === 'function') {
4658 warnOnFunctionType();
4659 }
4660 }
4661
4662 return null;
4663 }
4664
4665 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
4666 // Update the fiber if the keys match, otherwise return null.
4667
4668 var key = oldFiber !== null ? oldFiber.key : null;
4669
4670 if (typeof newChild === 'string' || typeof newChild === 'number') {
4671 // Text nodes don't have keys. If the previous node is implicitly keyed
4672 // we can continue to replace it without aborting even if it is not a text
4673 // node.
4674 if (key !== null) {
4675 return null;
4676 }
4677 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
4678 }
4679
4680 if (typeof newChild === 'object' && newChild !== null) {
4681 switch (newChild.$$typeof) {
4682 case REACT_ELEMENT_TYPE:
4683 {
4684 if (newChild.key === key) {
4685 if (newChild.type === REACT_FRAGMENT_TYPE) {
4686 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
4687 }
4688 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
4689 } else {
4690 return null;
4691 }
4692 }
4693 case REACT_PORTAL_TYPE:
4694 {
4695 if (newChild.key === key) {
4696 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
4697 } else {
4698 return null;
4699 }
4700 }
4701 }
4702
4703 if (isArray(newChild) || getIteratorFn(newChild)) {
4704 if (key !== null) {
4705 return null;
4706 }
4707
4708 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
4709 }
4710
4711 throwOnInvalidObjectType(returnFiber, newChild);
4712 }
4713
4714 {
4715 if (typeof newChild === 'function') {
4716 warnOnFunctionType();
4717 }
4718 }
4719
4720 return null;
4721 }
4722
4723 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
4724 if (typeof newChild === 'string' || typeof newChild === 'number') {
4725 // Text nodes don't have keys, so we neither have to check the old nor
4726 // new node for the key. If both are text nodes, they match.
4727 var matchedFiber = existingChildren.get(newIdx) || null;
4728 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
4729 }
4730
4731 if (typeof newChild === 'object' && newChild !== null) {
4732 switch (newChild.$$typeof) {
4733 case REACT_ELEMENT_TYPE:
4734 {
4735 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4736 if (newChild.type === REACT_FRAGMENT_TYPE) {
4737 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
4738 }
4739 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
4740 }
4741 case REACT_PORTAL_TYPE:
4742 {
4743 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4744 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
4745 }
4746 }
4747
4748 if (isArray(newChild) || getIteratorFn(newChild)) {
4749 var _matchedFiber3 = existingChildren.get(newIdx) || null;
4750 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
4751 }
4752
4753 throwOnInvalidObjectType(returnFiber, newChild);
4754 }
4755
4756 {
4757 if (typeof newChild === 'function') {
4758 warnOnFunctionType();
4759 }
4760 }
4761
4762 return null;
4763 }
4764
4765 /**
4766 * Warns if there is a duplicate or missing key
4767 */
4768 function warnOnInvalidKey(child, knownKeys) {
4769 {
4770 if (typeof child !== 'object' || child === null) {
4771 return knownKeys;
4772 }
4773 switch (child.$$typeof) {
4774 case REACT_ELEMENT_TYPE:
4775 case REACT_PORTAL_TYPE:
4776 warnForMissingKey(child);
4777 var key = child.key;
4778 if (typeof key !== 'string') {
4779 break;
4780 }
4781 if (knownKeys === null) {
4782 knownKeys = new Set();
4783 knownKeys.add(key);
4784 break;
4785 }
4786 if (!knownKeys.has(key)) {
4787 knownKeys.add(key);
4788 break;
4789 }
4790 warning$1(false, '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);
4791 break;
4792 default:
4793 break;
4794 }
4795 }
4796 return knownKeys;
4797 }
4798
4799 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
4800 // This algorithm can't optimize by searching from both ends since we
4801 // don't have backpointers on fibers. I'm trying to see how far we can get
4802 // with that model. If it ends up not being worth the tradeoffs, we can
4803 // add it later.
4804
4805 // Even with a two ended optimization, we'd want to optimize for the case
4806 // where there are few changes and brute force the comparison instead of
4807 // going for the Map. It'd like to explore hitting that path first in
4808 // forward-only mode and only go for the Map once we notice that we need
4809 // lots of look ahead. This doesn't handle reversal as well as two ended
4810 // search but that's unusual. Besides, for the two ended optimization to
4811 // work on Iterables, we'd need to copy the whole set.
4812
4813 // In this first iteration, we'll just live with hitting the bad case
4814 // (adding everything to a Map) in for every insert/move.
4815
4816 // If you change this code, also update reconcileChildrenIterator() which
4817 // uses the same algorithm.
4818
4819 {
4820 // First, validate keys.
4821 var knownKeys = null;
4822 for (var i = 0; i < newChildren.length; i++) {
4823 var child = newChildren[i];
4824 knownKeys = warnOnInvalidKey(child, knownKeys);
4825 }
4826 }
4827
4828 var resultingFirstChild = null;
4829 var previousNewFiber = null;
4830
4831 var oldFiber = currentFirstChild;
4832 var lastPlacedIndex = 0;
4833 var newIdx = 0;
4834 var nextOldFiber = null;
4835 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
4836 if (oldFiber.index > newIdx) {
4837 nextOldFiber = oldFiber;
4838 oldFiber = null;
4839 } else {
4840 nextOldFiber = oldFiber.sibling;
4841 }
4842 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
4843 if (newFiber === null) {
4844 // TODO: This breaks on empty slots like null children. That's
4845 // unfortunate because it triggers the slow path all the time. We need
4846 // a better way to communicate whether this was a miss or null,
4847 // boolean, undefined, etc.
4848 if (oldFiber === null) {
4849 oldFiber = nextOldFiber;
4850 }
4851 break;
4852 }
4853 if (shouldTrackSideEffects) {
4854 if (oldFiber && newFiber.alternate === null) {
4855 // We matched the slot, but we didn't reuse the existing fiber, so we
4856 // need to delete the existing child.
4857 deleteChild(returnFiber, oldFiber);
4858 }
4859 }
4860 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
4861 if (previousNewFiber === null) {
4862 // TODO: Move out of the loop. This only happens for the first run.
4863 resultingFirstChild = newFiber;
4864 } else {
4865 // TODO: Defer siblings if we're not at the right index for this slot.
4866 // I.e. if we had null values before, then we want to defer this
4867 // for each null value. However, we also don't want to call updateSlot
4868 // with the previous one.
4869 previousNewFiber.sibling = newFiber;
4870 }
4871 previousNewFiber = newFiber;
4872 oldFiber = nextOldFiber;
4873 }
4874
4875 if (newIdx === newChildren.length) {
4876 // We've reached the end of the new children. We can delete the rest.
4877 deleteRemainingChildren(returnFiber, oldFiber);
4878 return resultingFirstChild;
4879 }
4880
4881 if (oldFiber === null) {
4882 // If we don't have any more existing children we can choose a fast path
4883 // since the rest will all be insertions.
4884 for (; newIdx < newChildren.length; newIdx++) {
4885 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
4886 if (_newFiber === null) {
4887 continue;
4888 }
4889 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
4890 if (previousNewFiber === null) {
4891 // TODO: Move out of the loop. This only happens for the first run.
4892 resultingFirstChild = _newFiber;
4893 } else {
4894 previousNewFiber.sibling = _newFiber;
4895 }
4896 previousNewFiber = _newFiber;
4897 }
4898 return resultingFirstChild;
4899 }
4900
4901 // Add all children to a key map for quick lookups.
4902 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
4903
4904 // Keep scanning and use the map to restore deleted items as moves.
4905 for (; newIdx < newChildren.length; newIdx++) {
4906 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
4907 if (_newFiber2 !== null) {
4908 if (shouldTrackSideEffects) {
4909 if (_newFiber2.alternate !== null) {
4910 // The new fiber is a work in progress, but if there exists a
4911 // current, that means that we reused the fiber. We need to delete
4912 // it from the child list so that we don't add it to the deletion
4913 // list.
4914 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
4915 }
4916 }
4917 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
4918 if (previousNewFiber === null) {
4919 resultingFirstChild = _newFiber2;
4920 } else {
4921 previousNewFiber.sibling = _newFiber2;
4922 }
4923 previousNewFiber = _newFiber2;
4924 }
4925 }
4926
4927 if (shouldTrackSideEffects) {
4928 // Any existing children that weren't consumed above were deleted. We need
4929 // to add them to the deletion list.
4930 existingChildren.forEach(function (child) {
4931 return deleteChild(returnFiber, child);
4932 });
4933 }
4934
4935 return resultingFirstChild;
4936 }
4937
4938 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
4939 // This is the same implementation as reconcileChildrenArray(),
4940 // but using the iterator instead.
4941
4942 var iteratorFn = getIteratorFn(newChildrenIterable);
4943 (function () {
4944 if (!(typeof iteratorFn === 'function')) {
4945 {
4946 throw ReactError(Error('An object is not an iterable. This error is likely caused by a bug in React. Please file an issue.'));
4947 }
4948 }
4949 })();
4950
4951 {
4952 // We don't support rendering Generators because it's a mutation.
4953 // See https://github.com/facebook/react/issues/12995
4954 if (typeof Symbol === 'function' &&
4955 // $FlowFixMe Flow doesn't know about toStringTag
4956 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
4957 !didWarnAboutGenerators ? warning$1(false, '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.') : void 0;
4958 didWarnAboutGenerators = true;
4959 }
4960
4961 // Warn about using Maps as children
4962 if (newChildrenIterable.entries === iteratorFn) {
4963 !didWarnAboutMaps ? warning$1(false, 'Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.') : void 0;
4964 didWarnAboutMaps = true;
4965 }
4966
4967 // First, validate keys.
4968 // We'll get a different iterator later for the main pass.
4969 var _newChildren = iteratorFn.call(newChildrenIterable);
4970 if (_newChildren) {
4971 var knownKeys = null;
4972 var _step = _newChildren.next();
4973 for (; !_step.done; _step = _newChildren.next()) {
4974 var child = _step.value;
4975 knownKeys = warnOnInvalidKey(child, knownKeys);
4976 }
4977 }
4978 }
4979
4980 var newChildren = iteratorFn.call(newChildrenIterable);
4981 (function () {
4982 if (!(newChildren != null)) {
4983 {
4984 throw ReactError(Error('An iterable object provided no iterator.'));
4985 }
4986 }
4987 })();
4988
4989 var resultingFirstChild = null;
4990 var previousNewFiber = null;
4991
4992 var oldFiber = currentFirstChild;
4993 var lastPlacedIndex = 0;
4994 var newIdx = 0;
4995 var nextOldFiber = null;
4996
4997 var step = newChildren.next();
4998 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
4999 if (oldFiber.index > newIdx) {
5000 nextOldFiber = oldFiber;
5001 oldFiber = null;
5002 } else {
5003 nextOldFiber = oldFiber.sibling;
5004 }
5005 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
5006 if (newFiber === null) {
5007 // TODO: This breaks on empty slots like null children. That's
5008 // unfortunate because it triggers the slow path all the time. We need
5009 // a better way to communicate whether this was a miss or null,
5010 // boolean, undefined, etc.
5011 if (oldFiber === null) {
5012 oldFiber = nextOldFiber;
5013 }
5014 break;
5015 }
5016 if (shouldTrackSideEffects) {
5017 if (oldFiber && newFiber.alternate === null) {
5018 // We matched the slot, but we didn't reuse the existing fiber, so we
5019 // need to delete the existing child.
5020 deleteChild(returnFiber, oldFiber);
5021 }
5022 }
5023 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
5024 if (previousNewFiber === null) {
5025 // TODO: Move out of the loop. This only happens for the first run.
5026 resultingFirstChild = newFiber;
5027 } else {
5028 // TODO: Defer siblings if we're not at the right index for this slot.
5029 // I.e. if we had null values before, then we want to defer this
5030 // for each null value. However, we also don't want to call updateSlot
5031 // with the previous one.
5032 previousNewFiber.sibling = newFiber;
5033 }
5034 previousNewFiber = newFiber;
5035 oldFiber = nextOldFiber;
5036 }
5037
5038 if (step.done) {
5039 // We've reached the end of the new children. We can delete the rest.
5040 deleteRemainingChildren(returnFiber, oldFiber);
5041 return resultingFirstChild;
5042 }
5043
5044 if (oldFiber === null) {
5045 // If we don't have any more existing children we can choose a fast path
5046 // since the rest will all be insertions.
5047 for (; !step.done; newIdx++, step = newChildren.next()) {
5048 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
5049 if (_newFiber3 === null) {
5050 continue;
5051 }
5052 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
5053 if (previousNewFiber === null) {
5054 // TODO: Move out of the loop. This only happens for the first run.
5055 resultingFirstChild = _newFiber3;
5056 } else {
5057 previousNewFiber.sibling = _newFiber3;
5058 }
5059 previousNewFiber = _newFiber3;
5060 }
5061 return resultingFirstChild;
5062 }
5063
5064 // Add all children to a key map for quick lookups.
5065 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
5066
5067 // Keep scanning and use the map to restore deleted items as moves.
5068 for (; !step.done; newIdx++, step = newChildren.next()) {
5069 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
5070 if (_newFiber4 !== null) {
5071 if (shouldTrackSideEffects) {
5072 if (_newFiber4.alternate !== null) {
5073 // The new fiber is a work in progress, but if there exists a
5074 // current, that means that we reused the fiber. We need to delete
5075 // it from the child list so that we don't add it to the deletion
5076 // list.
5077 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
5078 }
5079 }
5080 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
5081 if (previousNewFiber === null) {
5082 resultingFirstChild = _newFiber4;
5083 } else {
5084 previousNewFiber.sibling = _newFiber4;
5085 }
5086 previousNewFiber = _newFiber4;
5087 }
5088 }
5089
5090 if (shouldTrackSideEffects) {
5091 // Any existing children that weren't consumed above were deleted. We need
5092 // to add them to the deletion list.
5093 existingChildren.forEach(function (child) {
5094 return deleteChild(returnFiber, child);
5095 });
5096 }
5097
5098 return resultingFirstChild;
5099 }
5100
5101 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
5102 // There's no need to check for keys on text nodes since we don't have a
5103 // way to define them.
5104 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
5105 // We already have an existing node so let's just update it and delete
5106 // the rest.
5107 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
5108 var existing = useFiber(currentFirstChild, textContent, expirationTime);
5109 existing.return = returnFiber;
5110 return existing;
5111 }
5112 // The existing first child is not a text node so we need to create one
5113 // and delete the existing ones.
5114 deleteRemainingChildren(returnFiber, currentFirstChild);
5115 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
5116 created.return = returnFiber;
5117 return created;
5118 }
5119
5120 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
5121 var key = element.key;
5122 var child = currentFirstChild;
5123 while (child !== null) {
5124 // TODO: If key === null and child.key === null, then this only applies to
5125 // the first item in the list.
5126 if (child.key === key) {
5127 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type || (
5128 // Keep this check inline so it only runs on the false path:
5129 isCompatibleFamilyForHotReloading(child, element))) {
5130 deleteRemainingChildren(returnFiber, child.sibling);
5131 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
5132 existing.ref = coerceRef(returnFiber, child, element);
5133 existing.return = returnFiber;
5134 {
5135 existing._debugSource = element._source;
5136 existing._debugOwner = element._owner;
5137 }
5138 return existing;
5139 } else {
5140 deleteRemainingChildren(returnFiber, child);
5141 break;
5142 }
5143 } else {
5144 deleteChild(returnFiber, child);
5145 }
5146 child = child.sibling;
5147 }
5148
5149 if (element.type === REACT_FRAGMENT_TYPE) {
5150 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
5151 created.return = returnFiber;
5152 return created;
5153 } else {
5154 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
5155 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
5156 _created4.return = returnFiber;
5157 return _created4;
5158 }
5159 }
5160
5161 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
5162 var key = portal.key;
5163 var child = currentFirstChild;
5164 while (child !== null) {
5165 // TODO: If key === null and child.key === null, then this only applies to
5166 // the first item in the list.
5167 if (child.key === key) {
5168 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
5169 deleteRemainingChildren(returnFiber, child.sibling);
5170 var existing = useFiber(child, portal.children || [], expirationTime);
5171 existing.return = returnFiber;
5172 return existing;
5173 } else {
5174 deleteRemainingChildren(returnFiber, child);
5175 break;
5176 }
5177 } else {
5178 deleteChild(returnFiber, child);
5179 }
5180 child = child.sibling;
5181 }
5182
5183 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
5184 created.return = returnFiber;
5185 return created;
5186 }
5187
5188 // This API will tag the children with the side-effect of the reconciliation
5189 // itself. They will be added to the side-effect list as we pass through the
5190 // children and the parent.
5191 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
5192 // This function is not recursive.
5193 // If the top level item is an array, we treat it as a set of children,
5194 // not as a fragment. Nested arrays on the other hand will be treated as
5195 // fragment nodes. Recursion happens at the normal flow.
5196
5197 // Handle top level unkeyed fragments as if they were arrays.
5198 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
5199 // We treat the ambiguous cases above the same.
5200 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
5201 if (isUnkeyedTopLevelFragment) {
5202 newChild = newChild.props.children;
5203 }
5204
5205 // Handle object types
5206 var isObject = typeof newChild === 'object' && newChild !== null;
5207
5208 if (isObject) {
5209 switch (newChild.$$typeof) {
5210 case REACT_ELEMENT_TYPE:
5211 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
5212 case REACT_PORTAL_TYPE:
5213 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
5214 }
5215 }
5216
5217 if (typeof newChild === 'string' || typeof newChild === 'number') {
5218 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
5219 }
5220
5221 if (isArray(newChild)) {
5222 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
5223 }
5224
5225 if (getIteratorFn(newChild)) {
5226 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
5227 }
5228
5229 if (isObject) {
5230 throwOnInvalidObjectType(returnFiber, newChild);
5231 }
5232
5233 {
5234 if (typeof newChild === 'function') {
5235 warnOnFunctionType();
5236 }
5237 }
5238 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
5239 // If the new child is undefined, and the return fiber is a composite
5240 // component, throw an error. If Fiber return types are disabled,
5241 // we already threw above.
5242 switch (returnFiber.tag) {
5243 case ClassComponent:
5244 {
5245 {
5246 var instance = returnFiber.stateNode;
5247 if (instance.render._isMockFunction) {
5248 // We allow auto-mocks to proceed as if they're returning null.
5249 break;
5250 }
5251 }
5252 }
5253 // Intentionally fall through to the next case, which handles both
5254 // functions and classes
5255 // eslint-disable-next-lined no-fallthrough
5256 case FunctionComponent:
5257 {
5258 var Component = returnFiber.type;
5259 (function () {
5260 {
5261 {
5262 throw ReactError(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.'));
5263 }
5264 }
5265 })();
5266 }
5267 }
5268 }
5269
5270 // Remaining cases are all treated as empty.
5271 return deleteRemainingChildren(returnFiber, currentFirstChild);
5272 }
5273
5274 return reconcileChildFibers;
5275}
5276
5277var reconcileChildFibers = ChildReconciler(true);
5278var mountChildFibers = ChildReconciler(false);
5279
5280function cloneChildFibers(current$$1, workInProgress) {
5281 (function () {
5282 if (!(current$$1 === null || workInProgress.child === current$$1.child)) {
5283 {
5284 throw ReactError(Error('Resuming work not yet implemented.'));
5285 }
5286 }
5287 })();
5288
5289 if (workInProgress.child === null) {
5290 return;
5291 }
5292
5293 var currentChild = workInProgress.child;
5294 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
5295 workInProgress.child = newChild;
5296
5297 newChild.return = workInProgress;
5298 while (currentChild.sibling !== null) {
5299 currentChild = currentChild.sibling;
5300 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
5301 newChild.return = workInProgress;
5302 }
5303 newChild.sibling = null;
5304}
5305
5306// Reset a workInProgress child set to prepare it for a second pass.
5307function resetChildFibers(workInProgress, renderExpirationTime) {
5308 var child = workInProgress.child;
5309 while (child !== null) {
5310 resetWorkInProgress(child, renderExpirationTime);
5311 child = child.sibling;
5312 }
5313}
5314
5315var NO_CONTEXT$1 = {};
5316
5317var contextStackCursor$1 = createCursor(NO_CONTEXT$1);
5318var contextFiberStackCursor = createCursor(NO_CONTEXT$1);
5319var rootInstanceStackCursor = createCursor(NO_CONTEXT$1);
5320
5321function requiredContext(c) {
5322 (function () {
5323 if (!(c !== NO_CONTEXT$1)) {
5324 {
5325 throw ReactError(Error('Expected host context to exist. This error is likely caused by a bug in React. Please file an issue.'));
5326 }
5327 }
5328 })();
5329 return c;
5330}
5331
5332function getRootHostContainer() {
5333 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5334 return rootInstance;
5335}
5336
5337function pushHostContainer(fiber, nextRootInstance) {
5338 // Push current root instance onto the stack;
5339 // This allows us to reset root when portals are popped.
5340 push(rootInstanceStackCursor, nextRootInstance, fiber);
5341 // Track the context and the Fiber that provided it.
5342 // This enables us to pop only Fibers that provide unique contexts.
5343 push(contextFiberStackCursor, fiber, fiber);
5344
5345 // Finally, we need to push the host context to the stack.
5346 // However, we can't just call getRootHostContext() and push it because
5347 // we'd have a different number of entries on the stack depending on
5348 // whether getRootHostContext() throws somewhere in renderer code or not.
5349 // So we push an empty value first. This lets us safely unwind on errors.
5350 push(contextStackCursor$1, NO_CONTEXT$1, fiber);
5351 var nextRootContext = getRootHostContext(nextRootInstance);
5352 // Now that we know this function doesn't throw, replace it.
5353 pop(contextStackCursor$1, fiber);
5354 push(contextStackCursor$1, nextRootContext, fiber);
5355}
5356
5357function popHostContainer(fiber) {
5358 pop(contextStackCursor$1, fiber);
5359 pop(contextFiberStackCursor, fiber);
5360 pop(rootInstanceStackCursor, fiber);
5361}
5362
5363function getHostContext() {
5364 var context = requiredContext(contextStackCursor$1.current);
5365 return context;
5366}
5367
5368function pushHostContext(fiber) {
5369 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5370 var context = requiredContext(contextStackCursor$1.current);
5371 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
5372
5373 // Don't push this Fiber's context unless it's unique.
5374 if (context === nextContext) {
5375 return;
5376 }
5377
5378 // Track the context and the Fiber that provided it.
5379 // This enables us to pop only Fibers that provide unique contexts.
5380 push(contextFiberStackCursor, fiber, fiber);
5381 push(contextStackCursor$1, nextContext, fiber);
5382}
5383
5384function popHostContext(fiber) {
5385 // Do not pop unless this Fiber provided the current context.
5386 // pushHostContext() only pushes Fibers that provide unique contexts.
5387 if (contextFiberStackCursor.current !== fiber) {
5388 return;
5389 }
5390
5391 pop(contextStackCursor$1, fiber);
5392 pop(contextFiberStackCursor, fiber);
5393}
5394
5395var DefaultSuspenseContext = 0;
5396
5397// The Suspense Context is split into two parts. The lower bits is
5398// inherited deeply down the subtree. The upper bits only affect
5399// this immediate suspense boundary and gets reset each new
5400// boundary or suspense list.
5401var SubtreeSuspenseContextMask = 1;
5402
5403// Subtree Flags:
5404
5405// InvisibleParentSuspenseContext indicates that one of our parent Suspense
5406// boundaries is not currently showing visible main content.
5407// Either because it is already showing a fallback or is not mounted at all.
5408// We can use this to determine if it is desirable to trigger a fallback at
5409// the parent. If not, then we might need to trigger undesirable boundaries
5410// and/or suspend the commit to avoid hiding the parent content.
5411var InvisibleParentSuspenseContext = 1;
5412
5413// Shallow Flags:
5414
5415// ForceSuspenseFallback can be used by SuspenseList to force newly added
5416// items into their fallback state during one of the render passes.
5417var ForceSuspenseFallback = 2;
5418
5419var suspenseStackCursor = createCursor(DefaultSuspenseContext);
5420
5421function hasSuspenseContext(parentContext, flag) {
5422 return (parentContext & flag) !== 0;
5423}
5424
5425function setDefaultShallowSuspenseContext(parentContext) {
5426 return parentContext & SubtreeSuspenseContextMask;
5427}
5428
5429function setShallowSuspenseContext(parentContext, shallowContext) {
5430 return parentContext & SubtreeSuspenseContextMask | shallowContext;
5431}
5432
5433function addSubtreeSuspenseContext(parentContext, subtreeContext) {
5434 return parentContext | subtreeContext;
5435}
5436
5437function pushSuspenseContext(fiber, newContext) {
5438 push(suspenseStackCursor, newContext, fiber);
5439}
5440
5441function popSuspenseContext(fiber) {
5442 pop(suspenseStackCursor, fiber);
5443}
5444
5445// TODO: This is now an empty object. Should we switch this to a boolean?
5446// Alternatively we can make this use an effect tag similar to SuspenseList.
5447
5448
5449function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
5450 // If it was the primary children that just suspended, capture and render the
5451 var nextState = workInProgress.memoizedState;
5452 if (nextState !== null) {
5453 return false;
5454 }
5455 var props = workInProgress.memoizedProps;
5456 // In order to capture, the Suspense component must have a fallback prop.
5457 if (props.fallback === undefined) {
5458 return false;
5459 }
5460 // Regular boundaries always capture.
5461 if (props.unstable_avoidThisFallback !== true) {
5462 return true;
5463 }
5464 // If it's a boundary we should avoid, then we prefer to bubble up to the
5465 // parent boundary if it is currently invisible.
5466 if (hasInvisibleParent) {
5467 return false;
5468 }
5469 // If the parent is not able to handle it, we must handle it.
5470 return true;
5471}
5472
5473function findFirstSuspended(row) {
5474 var node = row;
5475 while (node !== null) {
5476 if (node.tag === SuspenseComponent) {
5477 var state = node.memoizedState;
5478 if (state !== null) {
5479 return node;
5480 }
5481 } else if (node.tag === SuspenseListComponent &&
5482 // revealOrder undefined can't be trusted because it don't
5483 // keep track of whether it suspended or not.
5484 node.memoizedProps.revealOrder !== undefined) {
5485 var didSuspend = (node.effectTag & DidCapture) !== NoEffect;
5486 if (didSuspend) {
5487 return node;
5488 }
5489 } else if (node.child !== null) {
5490 node.child.return = node;
5491 node = node.child;
5492 continue;
5493 }
5494 if (node === row) {
5495 return null;
5496 }
5497 while (node.sibling === null) {
5498 if (node.return === null || node.return === row) {
5499 return null;
5500 }
5501 node = node.return;
5502 }
5503 node.sibling.return = node.return;
5504 node = node.sibling;
5505 }
5506 return null;
5507}
5508
5509function createResponderListener(responder, props) {
5510 var eventResponderListener = {
5511 responder: responder,
5512 props: props
5513 };
5514 {
5515 Object.freeze(eventResponderListener);
5516 }
5517 return eventResponderListener;
5518}
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528function createResponderInstance(responder, responderProps, responderState, target, fiber) {
5529 return {
5530 fiber: fiber,
5531 props: responderProps,
5532 responder: responder,
5533 rootEventTypes: null,
5534 state: responderState,
5535 target: target
5536 };
5537}
5538
5539var NoEffect$1 = /* */0;
5540var UnmountSnapshot = /* */2;
5541var UnmountMutation = /* */4;
5542var MountMutation = /* */8;
5543var UnmountLayout = /* */16;
5544var MountLayout = /* */32;
5545var MountPassive = /* */64;
5546var UnmountPassive = /* */128;
5547
5548var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
5549
5550
5551var didWarnAboutMismatchedHooksForComponent = void 0;
5552{
5553 didWarnAboutMismatchedHooksForComponent = new Set();
5554}
5555
5556// These are set right before calling the component.
5557var renderExpirationTime$1 = NoWork;
5558// The work-in-progress fiber. I've named it differently to distinguish it from
5559// the work-in-progress hook.
5560var currentlyRenderingFiber$1 = null;
5561
5562// Hooks are stored as a linked list on the fiber's memoizedState field. The
5563// current hook list is the list that belongs to the current fiber. The
5564// work-in-progress hook list is a new list that will be added to the
5565// work-in-progress fiber.
5566var currentHook = null;
5567var nextCurrentHook = null;
5568var firstWorkInProgressHook = null;
5569var workInProgressHook = null;
5570var nextWorkInProgressHook = null;
5571
5572var remainingExpirationTime = NoWork;
5573var componentUpdateQueue = null;
5574var sideEffectTag = 0;
5575
5576// Updates scheduled during render will trigger an immediate re-render at the
5577// end of the current pass. We can't store these updates on the normal queue,
5578// because if the work is aborted, they should be discarded. Because this is
5579// a relatively rare case, we also don't want to add an additional field to
5580// either the hook or queue object types. So we store them in a lazily create
5581// map of queue -> render-phase updates, which are discarded once the component
5582// completes without re-rendering.
5583
5584// Whether an update was scheduled during the currently executing render pass.
5585var didScheduleRenderPhaseUpdate = false;
5586// Lazily created map of render-phase updates
5587var renderPhaseUpdates = null;
5588// Counter to prevent infinite loops.
5589var numberOfReRenders = 0;
5590var RE_RENDER_LIMIT = 25;
5591
5592// In DEV, this is the name of the currently executing primitive hook
5593var currentHookNameInDev = null;
5594
5595// In DEV, this list ensures that hooks are called in the same order between renders.
5596// The list stores the order of hooks used during the initial render (mount).
5597// Subsequent renders (updates) reference this list.
5598var hookTypesDev = null;
5599var hookTypesUpdateIndexDev = -1;
5600
5601// In DEV, this tracks whether currently rendering component needs to ignore
5602// the dependencies for Hooks that need them (e.g. useEffect or useMemo).
5603// When true, such Hooks will always be "remounted". Only used during hot reload.
5604var ignorePreviousDependencies = false;
5605
5606function mountHookTypesDev() {
5607 {
5608 var hookName = currentHookNameInDev;
5609
5610 if (hookTypesDev === null) {
5611 hookTypesDev = [hookName];
5612 } else {
5613 hookTypesDev.push(hookName);
5614 }
5615 }
5616}
5617
5618function updateHookTypesDev() {
5619 {
5620 var hookName = currentHookNameInDev;
5621
5622 if (hookTypesDev !== null) {
5623 hookTypesUpdateIndexDev++;
5624 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
5625 warnOnHookMismatchInDev(hookName);
5626 }
5627 }
5628 }
5629}
5630
5631function checkDepsAreArrayDev(deps) {
5632 {
5633 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
5634 // Verify deps, but only on mount to avoid extra checks.
5635 // It's unlikely their type would change as usually you define them inline.
5636 warning$1(false, '%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);
5637 }
5638 }
5639}
5640
5641function warnOnHookMismatchInDev(currentHookName) {
5642 {
5643 var componentName = getComponentName(currentlyRenderingFiber$1.type);
5644 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
5645 didWarnAboutMismatchedHooksForComponent.add(componentName);
5646
5647 if (hookTypesDev !== null) {
5648 var table = '';
5649
5650 var secondColumnStart = 30;
5651
5652 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
5653 var oldHookName = hookTypesDev[i];
5654 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
5655
5656 var row = i + 1 + '. ' + oldHookName;
5657
5658 // Extra space so second column lines up
5659 // lol @ IE not supporting String#repeat
5660 while (row.length < secondColumnStart) {
5661 row += ' ';
5662 }
5663
5664 row += newHookName + '\n';
5665
5666 table += row;
5667 }
5668
5669 warning$1(false, '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);
5670 }
5671 }
5672 }
5673}
5674
5675function throwInvalidHookError() {
5676 (function () {
5677 {
5678 {
5679 throw ReactError(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.'));
5680 }
5681 }
5682 })();
5683}
5684
5685function areHookInputsEqual(nextDeps, prevDeps) {
5686 {
5687 if (ignorePreviousDependencies) {
5688 // Only true when this component is being hot reloaded.
5689 return false;
5690 }
5691 }
5692
5693 if (prevDeps === null) {
5694 {
5695 warning$1(false, '%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);
5696 }
5697 return false;
5698 }
5699
5700 {
5701 // Don't bother comparing lengths in prod because these arrays should be
5702 // passed inline.
5703 if (nextDeps.length !== prevDeps.length) {
5704 warning$1(false, '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(', ') + ']');
5705 }
5706 }
5707 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
5708 if (is(nextDeps[i], prevDeps[i])) {
5709 continue;
5710 }
5711 return false;
5712 }
5713 return true;
5714}
5715
5716function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
5717 renderExpirationTime$1 = nextRenderExpirationTime;
5718 currentlyRenderingFiber$1 = workInProgress;
5719 nextCurrentHook = current !== null ? current.memoizedState : null;
5720
5721 {
5722 hookTypesDev = current !== null ? current._debugHookTypes : null;
5723 hookTypesUpdateIndexDev = -1;
5724 // Used for hot reloading:
5725 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
5726 }
5727
5728 // The following should have already been reset
5729 // currentHook = null;
5730 // workInProgressHook = null;
5731
5732 // remainingExpirationTime = NoWork;
5733 // componentUpdateQueue = null;
5734
5735 // didScheduleRenderPhaseUpdate = false;
5736 // renderPhaseUpdates = null;
5737 // numberOfReRenders = 0;
5738 // sideEffectTag = 0;
5739
5740 // TODO Warn if no hooks are used at all during mount, then some are used during update.
5741 // Currently we will identify the update render as a mount because nextCurrentHook === null.
5742 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
5743
5744 // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used.
5745 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
5746 // so nextCurrentHook would be null during updates and mounts.
5747 {
5748 if (nextCurrentHook !== null) {
5749 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
5750 } else if (hookTypesDev !== null) {
5751 // This dispatcher handles an edge case where a component is updating,
5752 // but no stateful hooks have been used.
5753 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
5754 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
5755 // This dispatcher does that.
5756 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
5757 } else {
5758 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
5759 }
5760 }
5761
5762 var children = Component(props, refOrContext);
5763
5764 if (didScheduleRenderPhaseUpdate) {
5765 do {
5766 didScheduleRenderPhaseUpdate = false;
5767 numberOfReRenders += 1;
5768
5769 // Start over from the beginning of the list
5770 nextCurrentHook = current !== null ? current.memoizedState : null;
5771 nextWorkInProgressHook = firstWorkInProgressHook;
5772
5773 currentHook = null;
5774 workInProgressHook = null;
5775 componentUpdateQueue = null;
5776
5777 {
5778 // Also validate hook order for cascading updates.
5779 hookTypesUpdateIndexDev = -1;
5780 }
5781
5782 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
5783
5784 children = Component(props, refOrContext);
5785 } while (didScheduleRenderPhaseUpdate);
5786
5787 renderPhaseUpdates = null;
5788 numberOfReRenders = 0;
5789 }
5790
5791 // We can assume the previous dispatcher is always this one, since we set it
5792 // at the beginning of the render phase and there's no re-entrancy.
5793 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
5794
5795 var renderedWork = currentlyRenderingFiber$1;
5796
5797 renderedWork.memoizedState = firstWorkInProgressHook;
5798 renderedWork.expirationTime = remainingExpirationTime;
5799 renderedWork.updateQueue = componentUpdateQueue;
5800 renderedWork.effectTag |= sideEffectTag;
5801
5802 {
5803 renderedWork._debugHookTypes = hookTypesDev;
5804 }
5805
5806 // This check uses currentHook so that it works the same in DEV and prod bundles.
5807 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
5808 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
5809
5810 renderExpirationTime$1 = NoWork;
5811 currentlyRenderingFiber$1 = null;
5812
5813 currentHook = null;
5814 nextCurrentHook = null;
5815 firstWorkInProgressHook = null;
5816 workInProgressHook = null;
5817 nextWorkInProgressHook = null;
5818
5819 {
5820 currentHookNameInDev = null;
5821 hookTypesDev = null;
5822 hookTypesUpdateIndexDev = -1;
5823 }
5824
5825 remainingExpirationTime = NoWork;
5826 componentUpdateQueue = null;
5827 sideEffectTag = 0;
5828
5829 // These were reset above
5830 // didScheduleRenderPhaseUpdate = false;
5831 // renderPhaseUpdates = null;
5832 // numberOfReRenders = 0;
5833
5834 (function () {
5835 if (!!didRenderTooFewHooks) {
5836 {
5837 throw ReactError(Error('Rendered fewer hooks than expected. This may be caused by an accidental early return statement.'));
5838 }
5839 }
5840 })();
5841
5842 return children;
5843}
5844
5845function bailoutHooks(current, workInProgress, expirationTime) {
5846 workInProgress.updateQueue = current.updateQueue;
5847 workInProgress.effectTag &= ~(Passive | Update);
5848 if (current.expirationTime <= expirationTime) {
5849 current.expirationTime = NoWork;
5850 }
5851}
5852
5853function resetHooks() {
5854 // We can assume the previous dispatcher is always this one, since we set it
5855 // at the beginning of the render phase and there's no re-entrancy.
5856 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
5857
5858 // This is used to reset the state of this module when a component throws.
5859 // It's also called inside mountIndeterminateComponent if we determine the
5860 // component is a module-style component.
5861 renderExpirationTime$1 = NoWork;
5862 currentlyRenderingFiber$1 = null;
5863
5864 currentHook = null;
5865 nextCurrentHook = null;
5866 firstWorkInProgressHook = null;
5867 workInProgressHook = null;
5868 nextWorkInProgressHook = null;
5869
5870 {
5871 hookTypesDev = null;
5872 hookTypesUpdateIndexDev = -1;
5873
5874 currentHookNameInDev = null;
5875 }
5876
5877 remainingExpirationTime = NoWork;
5878 componentUpdateQueue = null;
5879 sideEffectTag = 0;
5880
5881 didScheduleRenderPhaseUpdate = false;
5882 renderPhaseUpdates = null;
5883 numberOfReRenders = 0;
5884}
5885
5886function mountWorkInProgressHook() {
5887 var hook = {
5888 memoizedState: null,
5889
5890 baseState: null,
5891 queue: null,
5892 baseUpdate: null,
5893
5894 next: null
5895 };
5896
5897 if (workInProgressHook === null) {
5898 // This is the first hook in the list
5899 firstWorkInProgressHook = workInProgressHook = hook;
5900 } else {
5901 // Append to the end of the list
5902 workInProgressHook = workInProgressHook.next = hook;
5903 }
5904 return workInProgressHook;
5905}
5906
5907function updateWorkInProgressHook() {
5908 // This function is used both for updates and for re-renders triggered by a
5909 // render phase update. It assumes there is either a current hook we can
5910 // clone, or a work-in-progress hook from a previous render pass that we can
5911 // use as a base. When we reach the end of the base list, we must switch to
5912 // the dispatcher used for mounts.
5913 if (nextWorkInProgressHook !== null) {
5914 // There's already a work-in-progress. Reuse it.
5915 workInProgressHook = nextWorkInProgressHook;
5916 nextWorkInProgressHook = workInProgressHook.next;
5917
5918 currentHook = nextCurrentHook;
5919 nextCurrentHook = currentHook !== null ? currentHook.next : null;
5920 } else {
5921 // Clone from the current hook.
5922 (function () {
5923 if (!(nextCurrentHook !== null)) {
5924 {
5925 throw ReactError(Error('Rendered more hooks than during the previous render.'));
5926 }
5927 }
5928 })();
5929 currentHook = nextCurrentHook;
5930
5931 var newHook = {
5932 memoizedState: currentHook.memoizedState,
5933
5934 baseState: currentHook.baseState,
5935 queue: currentHook.queue,
5936 baseUpdate: currentHook.baseUpdate,
5937
5938 next: null
5939 };
5940
5941 if (workInProgressHook === null) {
5942 // This is the first hook in the list.
5943 workInProgressHook = firstWorkInProgressHook = newHook;
5944 } else {
5945 // Append to the end of the list.
5946 workInProgressHook = workInProgressHook.next = newHook;
5947 }
5948 nextCurrentHook = currentHook.next;
5949 }
5950 return workInProgressHook;
5951}
5952
5953function createFunctionComponentUpdateQueue() {
5954 return {
5955 lastEffect: null
5956 };
5957}
5958
5959function basicStateReducer(state, action) {
5960 return typeof action === 'function' ? action(state) : action;
5961}
5962
5963function mountReducer(reducer, initialArg, init) {
5964 var hook = mountWorkInProgressHook();
5965 var initialState = void 0;
5966 if (init !== undefined) {
5967 initialState = init(initialArg);
5968 } else {
5969 initialState = initialArg;
5970 }
5971 hook.memoizedState = hook.baseState = initialState;
5972 var queue = hook.queue = {
5973 last: null,
5974 dispatch: null,
5975 lastRenderedReducer: reducer,
5976 lastRenderedState: initialState
5977 };
5978 var dispatch = queue.dispatch = dispatchAction.bind(null,
5979 // Flow doesn't know this is non-null, but we do.
5980 currentlyRenderingFiber$1, queue);
5981 return [hook.memoizedState, dispatch];
5982}
5983
5984function updateReducer(reducer, initialArg, init) {
5985 var hook = updateWorkInProgressHook();
5986 var queue = hook.queue;
5987 (function () {
5988 if (!(queue !== null)) {
5989 {
5990 throw ReactError(Error('Should have a queue. This is likely a bug in React. Please file an issue.'));
5991 }
5992 }
5993 })();
5994
5995 queue.lastRenderedReducer = reducer;
5996
5997 if (numberOfReRenders > 0) {
5998 // This is a re-render. Apply the new render phase updates to the previous
5999 var _dispatch = queue.dispatch;
6000 if (renderPhaseUpdates !== null) {
6001 // Render phase updates are stored in a map of queue -> linked list
6002 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
6003 if (firstRenderPhaseUpdate !== undefined) {
6004 renderPhaseUpdates.delete(queue);
6005 var newState = hook.memoizedState;
6006 var update = firstRenderPhaseUpdate;
6007 do {
6008 // Process this render phase update. We don't have to check the
6009 // priority because it will always be the same as the current
6010 // render's.
6011 var _action = update.action;
6012 newState = reducer(newState, _action);
6013 update = update.next;
6014 } while (update !== null);
6015
6016 // Mark that the fiber performed work, but only if the new state is
6017 // different from the current state.
6018 if (!is(newState, hook.memoizedState)) {
6019 markWorkInProgressReceivedUpdate();
6020 }
6021
6022 hook.memoizedState = newState;
6023 // Don't persist the state accumulated from the render phase updates to
6024 // the base state unless the queue is empty.
6025 // TODO: Not sure if this is the desired semantics, but it's what we
6026 // do for gDSFP. I can't remember why.
6027 if (hook.baseUpdate === queue.last) {
6028 hook.baseState = newState;
6029 }
6030
6031 queue.lastRenderedState = newState;
6032
6033 return [newState, _dispatch];
6034 }
6035 }
6036 return [hook.memoizedState, _dispatch];
6037 }
6038
6039 // The last update in the entire queue
6040 var last = queue.last;
6041 // The last update that is part of the base state.
6042 var baseUpdate = hook.baseUpdate;
6043 var baseState = hook.baseState;
6044
6045 // Find the first unprocessed update.
6046 var first = void 0;
6047 if (baseUpdate !== null) {
6048 if (last !== null) {
6049 // For the first update, the queue is a circular linked list where
6050 // `queue.last.next = queue.first`. Once the first update commits, and
6051 // the `baseUpdate` is no longer empty, we can unravel the list.
6052 last.next = null;
6053 }
6054 first = baseUpdate.next;
6055 } else {
6056 first = last !== null ? last.next : null;
6057 }
6058 if (first !== null) {
6059 var _newState = baseState;
6060 var newBaseState = null;
6061 var newBaseUpdate = null;
6062 var prevUpdate = baseUpdate;
6063 var _update = first;
6064 var didSkip = false;
6065 do {
6066 var updateExpirationTime = _update.expirationTime;
6067 if (updateExpirationTime < renderExpirationTime$1) {
6068 // Priority is insufficient. Skip this update. If this is the first
6069 // skipped update, the previous update/state is the new base
6070 // update/state.
6071 if (!didSkip) {
6072 didSkip = true;
6073 newBaseUpdate = prevUpdate;
6074 newBaseState = _newState;
6075 }
6076 // Update the remaining priority in the queue.
6077 if (updateExpirationTime > remainingExpirationTime) {
6078 remainingExpirationTime = updateExpirationTime;
6079 }
6080 } else {
6081 // This update does have sufficient priority.
6082
6083 // Mark the event time of this update as relevant to this render pass.
6084 // TODO: This should ideally use the true event time of this update rather than
6085 // its priority which is a derived and not reverseable value.
6086 // TODO: We should skip this update if it was already committed but currently
6087 // we have no way of detecting the difference between a committed and suspended
6088 // update here.
6089 markRenderEventTimeAndConfig(updateExpirationTime, _update.suspenseConfig);
6090
6091 // Process this update.
6092 if (_update.eagerReducer === reducer) {
6093 // If this update was processed eagerly, and its reducer matches the
6094 // current reducer, we can use the eagerly computed state.
6095 _newState = _update.eagerState;
6096 } else {
6097 var _action2 = _update.action;
6098 _newState = reducer(_newState, _action2);
6099 }
6100 }
6101 prevUpdate = _update;
6102 _update = _update.next;
6103 } while (_update !== null && _update !== first);
6104
6105 if (!didSkip) {
6106 newBaseUpdate = prevUpdate;
6107 newBaseState = _newState;
6108 }
6109
6110 // Mark that the fiber performed work, but only if the new state is
6111 // different from the current state.
6112 if (!is(_newState, hook.memoizedState)) {
6113 markWorkInProgressReceivedUpdate();
6114 }
6115
6116 hook.memoizedState = _newState;
6117 hook.baseUpdate = newBaseUpdate;
6118 hook.baseState = newBaseState;
6119
6120 queue.lastRenderedState = _newState;
6121 }
6122
6123 var dispatch = queue.dispatch;
6124 return [hook.memoizedState, dispatch];
6125}
6126
6127function mountState(initialState) {
6128 var hook = mountWorkInProgressHook();
6129 if (typeof initialState === 'function') {
6130 initialState = initialState();
6131 }
6132 hook.memoizedState = hook.baseState = initialState;
6133 var queue = hook.queue = {
6134 last: null,
6135 dispatch: null,
6136 lastRenderedReducer: basicStateReducer,
6137 lastRenderedState: initialState
6138 };
6139 var dispatch = queue.dispatch = dispatchAction.bind(null,
6140 // Flow doesn't know this is non-null, but we do.
6141 currentlyRenderingFiber$1, queue);
6142 return [hook.memoizedState, dispatch];
6143}
6144
6145function updateState(initialState) {
6146 return updateReducer(basicStateReducer, initialState);
6147}
6148
6149function pushEffect(tag, create, destroy, deps) {
6150 var effect = {
6151 tag: tag,
6152 create: create,
6153 destroy: destroy,
6154 deps: deps,
6155 // Circular
6156 next: null
6157 };
6158 if (componentUpdateQueue === null) {
6159 componentUpdateQueue = createFunctionComponentUpdateQueue();
6160 componentUpdateQueue.lastEffect = effect.next = effect;
6161 } else {
6162 var _lastEffect = componentUpdateQueue.lastEffect;
6163 if (_lastEffect === null) {
6164 componentUpdateQueue.lastEffect = effect.next = effect;
6165 } else {
6166 var firstEffect = _lastEffect.next;
6167 _lastEffect.next = effect;
6168 effect.next = firstEffect;
6169 componentUpdateQueue.lastEffect = effect;
6170 }
6171 }
6172 return effect;
6173}
6174
6175function mountRef(initialValue) {
6176 var hook = mountWorkInProgressHook();
6177 var ref = { current: initialValue };
6178 {
6179 Object.seal(ref);
6180 }
6181 hook.memoizedState = ref;
6182 return ref;
6183}
6184
6185function updateRef(initialValue) {
6186 var hook = updateWorkInProgressHook();
6187 return hook.memoizedState;
6188}
6189
6190function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
6191 var hook = mountWorkInProgressHook();
6192 var nextDeps = deps === undefined ? null : deps;
6193 sideEffectTag |= fiberEffectTag;
6194 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);
6195}
6196
6197function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
6198 var hook = updateWorkInProgressHook();
6199 var nextDeps = deps === undefined ? null : deps;
6200 var destroy = undefined;
6201
6202 if (currentHook !== null) {
6203 var prevEffect = currentHook.memoizedState;
6204 destroy = prevEffect.destroy;
6205 if (nextDeps !== null) {
6206 var prevDeps = prevEffect.deps;
6207 if (areHookInputsEqual(nextDeps, prevDeps)) {
6208 pushEffect(NoEffect$1, create, destroy, nextDeps);
6209 return;
6210 }
6211 }
6212 }
6213
6214 sideEffectTag |= fiberEffectTag;
6215 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);
6216}
6217
6218function mountEffect(create, deps) {
6219 {
6220 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
6221 if ('undefined' !== typeof jest) {
6222 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
6223 }
6224 }
6225 return mountEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
6226}
6227
6228function updateEffect(create, deps) {
6229 {
6230 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
6231 if ('undefined' !== typeof jest) {
6232 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
6233 }
6234 }
6235 return updateEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
6236}
6237
6238function mountLayoutEffect(create, deps) {
6239 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
6240}
6241
6242function updateLayoutEffect(create, deps) {
6243 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
6244}
6245
6246function imperativeHandleEffect(create, ref) {
6247 if (typeof ref === 'function') {
6248 var refCallback = ref;
6249 var _inst = create();
6250 refCallback(_inst);
6251 return function () {
6252 refCallback(null);
6253 };
6254 } else if (ref !== null && ref !== undefined) {
6255 var refObject = ref;
6256 {
6257 !refObject.hasOwnProperty('current') ? warning$1(false, '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(', ') + '}') : void 0;
6258 }
6259 var _inst2 = create();
6260 refObject.current = _inst2;
6261 return function () {
6262 refObject.current = null;
6263 };
6264 }
6265}
6266
6267function mountImperativeHandle(ref, create, deps) {
6268 {
6269 !(typeof create === 'function') ? warning$1(false, 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null') : void 0;
6270 }
6271
6272 // TODO: If deps are provided, should we skip comparing the ref itself?
6273 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6274
6275 return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6276}
6277
6278function updateImperativeHandle(ref, create, deps) {
6279 {
6280 !(typeof create === 'function') ? warning$1(false, 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null') : void 0;
6281 }
6282
6283 // TODO: If deps are provided, should we skip comparing the ref itself?
6284 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6285
6286 return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6287}
6288
6289function mountDebugValue(value, formatterFn) {
6290 // This hook is normally a no-op.
6291 // The react-debug-hooks package injects its own implementation
6292 // so that e.g. DevTools can display custom hook values.
6293}
6294
6295var updateDebugValue = mountDebugValue;
6296
6297function mountCallback(callback, deps) {
6298 var hook = mountWorkInProgressHook();
6299 var nextDeps = deps === undefined ? null : deps;
6300 hook.memoizedState = [callback, nextDeps];
6301 return callback;
6302}
6303
6304function updateCallback(callback, deps) {
6305 var hook = updateWorkInProgressHook();
6306 var nextDeps = deps === undefined ? null : deps;
6307 var prevState = hook.memoizedState;
6308 if (prevState !== null) {
6309 if (nextDeps !== null) {
6310 var prevDeps = prevState[1];
6311 if (areHookInputsEqual(nextDeps, prevDeps)) {
6312 return prevState[0];
6313 }
6314 }
6315 }
6316 hook.memoizedState = [callback, nextDeps];
6317 return callback;
6318}
6319
6320function mountMemo(nextCreate, deps) {
6321 var hook = mountWorkInProgressHook();
6322 var nextDeps = deps === undefined ? null : deps;
6323 var nextValue = nextCreate();
6324 hook.memoizedState = [nextValue, nextDeps];
6325 return nextValue;
6326}
6327
6328function updateMemo(nextCreate, deps) {
6329 var hook = updateWorkInProgressHook();
6330 var nextDeps = deps === undefined ? null : deps;
6331 var prevState = hook.memoizedState;
6332 if (prevState !== null) {
6333 // Assume these are defined. If they're not, areHookInputsEqual will warn.
6334 if (nextDeps !== null) {
6335 var prevDeps = prevState[1];
6336 if (areHookInputsEqual(nextDeps, prevDeps)) {
6337 return prevState[0];
6338 }
6339 }
6340 }
6341 var nextValue = nextCreate();
6342 hook.memoizedState = [nextValue, nextDeps];
6343 return nextValue;
6344}
6345
6346function dispatchAction(fiber, queue, action) {
6347 (function () {
6348 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {
6349 {
6350 throw ReactError(Error('Too many re-renders. React limits the number of renders to prevent an infinite loop.'));
6351 }
6352 }
6353 })();
6354
6355 {
6356 !(arguments.length <= 3) ? warning$1(false, "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().') : void 0;
6357 }
6358
6359 var alternate = fiber.alternate;
6360 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
6361 // This is a render phase update. Stash it in a lazily-created map of
6362 // queue -> linked list of updates. After this render pass, we'll restart
6363 // and apply the stashed updates on top of the work-in-progress hook.
6364 didScheduleRenderPhaseUpdate = true;
6365 var update = {
6366 expirationTime: renderExpirationTime$1,
6367 suspenseConfig: null,
6368 action: action,
6369 eagerReducer: null,
6370 eagerState: null,
6371 next: null
6372 };
6373 {
6374 update.priority = getCurrentPriorityLevel();
6375 }
6376 if (renderPhaseUpdates === null) {
6377 renderPhaseUpdates = new Map();
6378 }
6379 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
6380 if (firstRenderPhaseUpdate === undefined) {
6381 renderPhaseUpdates.set(queue, update);
6382 } else {
6383 // Append the update to the end of the list.
6384 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
6385 while (lastRenderPhaseUpdate.next !== null) {
6386 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
6387 }
6388 lastRenderPhaseUpdate.next = update;
6389 }
6390 } else {
6391 if (revertPassiveEffectsChange) {
6392 flushPassiveEffects();
6393 }
6394
6395 var currentTime = requestCurrentTime();
6396 var _suspenseConfig = requestCurrentSuspenseConfig();
6397 var _expirationTime = computeExpirationForFiber(currentTime, fiber, _suspenseConfig);
6398
6399 var _update2 = {
6400 expirationTime: _expirationTime,
6401 suspenseConfig: _suspenseConfig,
6402 action: action,
6403 eagerReducer: null,
6404 eagerState: null,
6405 next: null
6406 };
6407
6408 {
6409 _update2.priority = getCurrentPriorityLevel();
6410 }
6411
6412 // Append the update to the end of the list.
6413 var _last = queue.last;
6414 if (_last === null) {
6415 // This is the first update. Create a circular list.
6416 _update2.next = _update2;
6417 } else {
6418 var first = _last.next;
6419 if (first !== null) {
6420 // Still circular.
6421 _update2.next = first;
6422 }
6423 _last.next = _update2;
6424 }
6425 queue.last = _update2;
6426
6427 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
6428 // The queue is currently empty, which means we can eagerly compute the
6429 // next state before entering the render phase. If the new state is the
6430 // same as the current state, we may be able to bail out entirely.
6431 var _lastRenderedReducer = queue.lastRenderedReducer;
6432 if (_lastRenderedReducer !== null) {
6433 var prevDispatcher = void 0;
6434 {
6435 prevDispatcher = ReactCurrentDispatcher$1.current;
6436 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6437 }
6438 try {
6439 var currentState = queue.lastRenderedState;
6440 var _eagerState = _lastRenderedReducer(currentState, action);
6441 // Stash the eagerly computed state, and the reducer used to compute
6442 // it, on the update object. If the reducer hasn't changed by the
6443 // time we enter the render phase, then the eager state can be used
6444 // without calling the reducer again.
6445 _update2.eagerReducer = _lastRenderedReducer;
6446 _update2.eagerState = _eagerState;
6447 if (is(_eagerState, currentState)) {
6448 // Fast path. We can bail out without scheduling React to re-render.
6449 // It's still possible that we'll need to rebase this update later,
6450 // if the component re-renders for a different reason and by that
6451 // time the reducer has changed.
6452 return;
6453 }
6454 } catch (error) {
6455 // Suppress the error. It will throw again in the render phase.
6456 } finally {
6457 {
6458 ReactCurrentDispatcher$1.current = prevDispatcher;
6459 }
6460 }
6461 }
6462 }
6463 {
6464 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
6465 if ('undefined' !== typeof jest) {
6466 warnIfNotScopedWithMatchingAct(fiber);
6467 warnIfNotCurrentlyActingUpdatesInDev(fiber);
6468 }
6469 }
6470 scheduleWork(fiber, _expirationTime);
6471 }
6472}
6473
6474var ContextOnlyDispatcher = {
6475 readContext: readContext,
6476
6477 useCallback: throwInvalidHookError,
6478 useContext: throwInvalidHookError,
6479 useEffect: throwInvalidHookError,
6480 useImperativeHandle: throwInvalidHookError,
6481 useLayoutEffect: throwInvalidHookError,
6482 useMemo: throwInvalidHookError,
6483 useReducer: throwInvalidHookError,
6484 useRef: throwInvalidHookError,
6485 useState: throwInvalidHookError,
6486 useDebugValue: throwInvalidHookError,
6487 useResponder: throwInvalidHookError
6488};
6489
6490var HooksDispatcherOnMountInDEV = null;
6491var HooksDispatcherOnMountWithHookTypesInDEV = null;
6492var HooksDispatcherOnUpdateInDEV = null;
6493var InvalidNestedHooksDispatcherOnMountInDEV = null;
6494var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
6495
6496{
6497 var warnInvalidContextAccess = function () {
6498 warning$1(false, '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().');
6499 };
6500
6501 var warnInvalidHookAccess = function () {
6502 warning$1(false, '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');
6503 };
6504
6505 HooksDispatcherOnMountInDEV = {
6506 readContext: function (context, observedBits) {
6507 return readContext(context, observedBits);
6508 },
6509 useCallback: function (callback, deps) {
6510 currentHookNameInDev = 'useCallback';
6511 mountHookTypesDev();
6512 checkDepsAreArrayDev(deps);
6513 return mountCallback(callback, deps);
6514 },
6515 useContext: function (context, observedBits) {
6516 currentHookNameInDev = 'useContext';
6517 mountHookTypesDev();
6518 return readContext(context, observedBits);
6519 },
6520 useEffect: function (create, deps) {
6521 currentHookNameInDev = 'useEffect';
6522 mountHookTypesDev();
6523 checkDepsAreArrayDev(deps);
6524 return mountEffect(create, deps);
6525 },
6526 useImperativeHandle: function (ref, create, deps) {
6527 currentHookNameInDev = 'useImperativeHandle';
6528 mountHookTypesDev();
6529 checkDepsAreArrayDev(deps);
6530 return mountImperativeHandle(ref, create, deps);
6531 },
6532 useLayoutEffect: function (create, deps) {
6533 currentHookNameInDev = 'useLayoutEffect';
6534 mountHookTypesDev();
6535 checkDepsAreArrayDev(deps);
6536 return mountLayoutEffect(create, deps);
6537 },
6538 useMemo: function (create, deps) {
6539 currentHookNameInDev = 'useMemo';
6540 mountHookTypesDev();
6541 checkDepsAreArrayDev(deps);
6542 var prevDispatcher = ReactCurrentDispatcher$1.current;
6543 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6544 try {
6545 return mountMemo(create, deps);
6546 } finally {
6547 ReactCurrentDispatcher$1.current = prevDispatcher;
6548 }
6549 },
6550 useReducer: function (reducer, initialArg, init) {
6551 currentHookNameInDev = 'useReducer';
6552 mountHookTypesDev();
6553 var prevDispatcher = ReactCurrentDispatcher$1.current;
6554 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6555 try {
6556 return mountReducer(reducer, initialArg, init);
6557 } finally {
6558 ReactCurrentDispatcher$1.current = prevDispatcher;
6559 }
6560 },
6561 useRef: function (initialValue) {
6562 currentHookNameInDev = 'useRef';
6563 mountHookTypesDev();
6564 return mountRef(initialValue);
6565 },
6566 useState: function (initialState) {
6567 currentHookNameInDev = 'useState';
6568 mountHookTypesDev();
6569 var prevDispatcher = ReactCurrentDispatcher$1.current;
6570 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6571 try {
6572 return mountState(initialState);
6573 } finally {
6574 ReactCurrentDispatcher$1.current = prevDispatcher;
6575 }
6576 },
6577 useDebugValue: function (value, formatterFn) {
6578 currentHookNameInDev = 'useDebugValue';
6579 mountHookTypesDev();
6580 return mountDebugValue(value, formatterFn);
6581 },
6582 useResponder: function (responder, props) {
6583 currentHookNameInDev = 'useResponder';
6584 mountHookTypesDev();
6585 return createResponderListener(responder, props);
6586 }
6587 };
6588
6589 HooksDispatcherOnMountWithHookTypesInDEV = {
6590 readContext: function (context, observedBits) {
6591 return readContext(context, observedBits);
6592 },
6593 useCallback: function (callback, deps) {
6594 currentHookNameInDev = 'useCallback';
6595 updateHookTypesDev();
6596 return mountCallback(callback, deps);
6597 },
6598 useContext: function (context, observedBits) {
6599 currentHookNameInDev = 'useContext';
6600 updateHookTypesDev();
6601 return readContext(context, observedBits);
6602 },
6603 useEffect: function (create, deps) {
6604 currentHookNameInDev = 'useEffect';
6605 updateHookTypesDev();
6606 return mountEffect(create, deps);
6607 },
6608 useImperativeHandle: function (ref, create, deps) {
6609 currentHookNameInDev = 'useImperativeHandle';
6610 updateHookTypesDev();
6611 return mountImperativeHandle(ref, create, deps);
6612 },
6613 useLayoutEffect: function (create, deps) {
6614 currentHookNameInDev = 'useLayoutEffect';
6615 updateHookTypesDev();
6616 return mountLayoutEffect(create, deps);
6617 },
6618 useMemo: function (create, deps) {
6619 currentHookNameInDev = 'useMemo';
6620 updateHookTypesDev();
6621 var prevDispatcher = ReactCurrentDispatcher$1.current;
6622 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6623 try {
6624 return mountMemo(create, deps);
6625 } finally {
6626 ReactCurrentDispatcher$1.current = prevDispatcher;
6627 }
6628 },
6629 useReducer: function (reducer, initialArg, init) {
6630 currentHookNameInDev = 'useReducer';
6631 updateHookTypesDev();
6632 var prevDispatcher = ReactCurrentDispatcher$1.current;
6633 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6634 try {
6635 return mountReducer(reducer, initialArg, init);
6636 } finally {
6637 ReactCurrentDispatcher$1.current = prevDispatcher;
6638 }
6639 },
6640 useRef: function (initialValue) {
6641 currentHookNameInDev = 'useRef';
6642 updateHookTypesDev();
6643 return mountRef(initialValue);
6644 },
6645 useState: function (initialState) {
6646 currentHookNameInDev = 'useState';
6647 updateHookTypesDev();
6648 var prevDispatcher = ReactCurrentDispatcher$1.current;
6649 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6650 try {
6651 return mountState(initialState);
6652 } finally {
6653 ReactCurrentDispatcher$1.current = prevDispatcher;
6654 }
6655 },
6656 useDebugValue: function (value, formatterFn) {
6657 currentHookNameInDev = 'useDebugValue';
6658 updateHookTypesDev();
6659 return mountDebugValue(value, formatterFn);
6660 },
6661 useResponder: function (responder, props) {
6662 currentHookNameInDev = 'useResponder';
6663 updateHookTypesDev();
6664 return createResponderListener(responder, props);
6665 }
6666 };
6667
6668 HooksDispatcherOnUpdateInDEV = {
6669 readContext: function (context, observedBits) {
6670 return readContext(context, observedBits);
6671 },
6672 useCallback: function (callback, deps) {
6673 currentHookNameInDev = 'useCallback';
6674 updateHookTypesDev();
6675 return updateCallback(callback, deps);
6676 },
6677 useContext: function (context, observedBits) {
6678 currentHookNameInDev = 'useContext';
6679 updateHookTypesDev();
6680 return readContext(context, observedBits);
6681 },
6682 useEffect: function (create, deps) {
6683 currentHookNameInDev = 'useEffect';
6684 updateHookTypesDev();
6685 return updateEffect(create, deps);
6686 },
6687 useImperativeHandle: function (ref, create, deps) {
6688 currentHookNameInDev = 'useImperativeHandle';
6689 updateHookTypesDev();
6690 return updateImperativeHandle(ref, create, deps);
6691 },
6692 useLayoutEffect: function (create, deps) {
6693 currentHookNameInDev = 'useLayoutEffect';
6694 updateHookTypesDev();
6695 return updateLayoutEffect(create, deps);
6696 },
6697 useMemo: function (create, deps) {
6698 currentHookNameInDev = 'useMemo';
6699 updateHookTypesDev();
6700 var prevDispatcher = ReactCurrentDispatcher$1.current;
6701 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6702 try {
6703 return updateMemo(create, deps);
6704 } finally {
6705 ReactCurrentDispatcher$1.current = prevDispatcher;
6706 }
6707 },
6708 useReducer: function (reducer, initialArg, init) {
6709 currentHookNameInDev = 'useReducer';
6710 updateHookTypesDev();
6711 var prevDispatcher = ReactCurrentDispatcher$1.current;
6712 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6713 try {
6714 return updateReducer(reducer, initialArg, init);
6715 } finally {
6716 ReactCurrentDispatcher$1.current = prevDispatcher;
6717 }
6718 },
6719 useRef: function (initialValue) {
6720 currentHookNameInDev = 'useRef';
6721 updateHookTypesDev();
6722 return updateRef(initialValue);
6723 },
6724 useState: function (initialState) {
6725 currentHookNameInDev = 'useState';
6726 updateHookTypesDev();
6727 var prevDispatcher = ReactCurrentDispatcher$1.current;
6728 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6729 try {
6730 return updateState(initialState);
6731 } finally {
6732 ReactCurrentDispatcher$1.current = prevDispatcher;
6733 }
6734 },
6735 useDebugValue: function (value, formatterFn) {
6736 currentHookNameInDev = 'useDebugValue';
6737 updateHookTypesDev();
6738 return updateDebugValue(value, formatterFn);
6739 },
6740 useResponder: function (responder, props) {
6741 currentHookNameInDev = 'useResponder';
6742 updateHookTypesDev();
6743 return createResponderListener(responder, props);
6744 }
6745 };
6746
6747 InvalidNestedHooksDispatcherOnMountInDEV = {
6748 readContext: function (context, observedBits) {
6749 warnInvalidContextAccess();
6750 return readContext(context, observedBits);
6751 },
6752 useCallback: function (callback, deps) {
6753 currentHookNameInDev = 'useCallback';
6754 warnInvalidHookAccess();
6755 mountHookTypesDev();
6756 return mountCallback(callback, deps);
6757 },
6758 useContext: function (context, observedBits) {
6759 currentHookNameInDev = 'useContext';
6760 warnInvalidHookAccess();
6761 mountHookTypesDev();
6762 return readContext(context, observedBits);
6763 },
6764 useEffect: function (create, deps) {
6765 currentHookNameInDev = 'useEffect';
6766 warnInvalidHookAccess();
6767 mountHookTypesDev();
6768 return mountEffect(create, deps);
6769 },
6770 useImperativeHandle: function (ref, create, deps) {
6771 currentHookNameInDev = 'useImperativeHandle';
6772 warnInvalidHookAccess();
6773 mountHookTypesDev();
6774 return mountImperativeHandle(ref, create, deps);
6775 },
6776 useLayoutEffect: function (create, deps) {
6777 currentHookNameInDev = 'useLayoutEffect';
6778 warnInvalidHookAccess();
6779 mountHookTypesDev();
6780 return mountLayoutEffect(create, deps);
6781 },
6782 useMemo: function (create, deps) {
6783 currentHookNameInDev = 'useMemo';
6784 warnInvalidHookAccess();
6785 mountHookTypesDev();
6786 var prevDispatcher = ReactCurrentDispatcher$1.current;
6787 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6788 try {
6789 return mountMemo(create, deps);
6790 } finally {
6791 ReactCurrentDispatcher$1.current = prevDispatcher;
6792 }
6793 },
6794 useReducer: function (reducer, initialArg, init) {
6795 currentHookNameInDev = 'useReducer';
6796 warnInvalidHookAccess();
6797 mountHookTypesDev();
6798 var prevDispatcher = ReactCurrentDispatcher$1.current;
6799 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6800 try {
6801 return mountReducer(reducer, initialArg, init);
6802 } finally {
6803 ReactCurrentDispatcher$1.current = prevDispatcher;
6804 }
6805 },
6806 useRef: function (initialValue) {
6807 currentHookNameInDev = 'useRef';
6808 warnInvalidHookAccess();
6809 mountHookTypesDev();
6810 return mountRef(initialValue);
6811 },
6812 useState: function (initialState) {
6813 currentHookNameInDev = 'useState';
6814 warnInvalidHookAccess();
6815 mountHookTypesDev();
6816 var prevDispatcher = ReactCurrentDispatcher$1.current;
6817 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6818 try {
6819 return mountState(initialState);
6820 } finally {
6821 ReactCurrentDispatcher$1.current = prevDispatcher;
6822 }
6823 },
6824 useDebugValue: function (value, formatterFn) {
6825 currentHookNameInDev = 'useDebugValue';
6826 warnInvalidHookAccess();
6827 mountHookTypesDev();
6828 return mountDebugValue(value, formatterFn);
6829 },
6830 useResponder: function (responder, props) {
6831 currentHookNameInDev = 'useResponder';
6832 warnInvalidHookAccess();
6833 mountHookTypesDev();
6834 return createResponderListener(responder, props);
6835 }
6836 };
6837
6838 InvalidNestedHooksDispatcherOnUpdateInDEV = {
6839 readContext: function (context, observedBits) {
6840 warnInvalidContextAccess();
6841 return readContext(context, observedBits);
6842 },
6843 useCallback: function (callback, deps) {
6844 currentHookNameInDev = 'useCallback';
6845 warnInvalidHookAccess();
6846 updateHookTypesDev();
6847 return updateCallback(callback, deps);
6848 },
6849 useContext: function (context, observedBits) {
6850 currentHookNameInDev = 'useContext';
6851 warnInvalidHookAccess();
6852 updateHookTypesDev();
6853 return readContext(context, observedBits);
6854 },
6855 useEffect: function (create, deps) {
6856 currentHookNameInDev = 'useEffect';
6857 warnInvalidHookAccess();
6858 updateHookTypesDev();
6859 return updateEffect(create, deps);
6860 },
6861 useImperativeHandle: function (ref, create, deps) {
6862 currentHookNameInDev = 'useImperativeHandle';
6863 warnInvalidHookAccess();
6864 updateHookTypesDev();
6865 return updateImperativeHandle(ref, create, deps);
6866 },
6867 useLayoutEffect: function (create, deps) {
6868 currentHookNameInDev = 'useLayoutEffect';
6869 warnInvalidHookAccess();
6870 updateHookTypesDev();
6871 return updateLayoutEffect(create, deps);
6872 },
6873 useMemo: function (create, deps) {
6874 currentHookNameInDev = 'useMemo';
6875 warnInvalidHookAccess();
6876 updateHookTypesDev();
6877 var prevDispatcher = ReactCurrentDispatcher$1.current;
6878 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6879 try {
6880 return updateMemo(create, deps);
6881 } finally {
6882 ReactCurrentDispatcher$1.current = prevDispatcher;
6883 }
6884 },
6885 useReducer: function (reducer, initialArg, init) {
6886 currentHookNameInDev = 'useReducer';
6887 warnInvalidHookAccess();
6888 updateHookTypesDev();
6889 var prevDispatcher = ReactCurrentDispatcher$1.current;
6890 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6891 try {
6892 return updateReducer(reducer, initialArg, init);
6893 } finally {
6894 ReactCurrentDispatcher$1.current = prevDispatcher;
6895 }
6896 },
6897 useRef: function (initialValue) {
6898 currentHookNameInDev = 'useRef';
6899 warnInvalidHookAccess();
6900 updateHookTypesDev();
6901 return updateRef(initialValue);
6902 },
6903 useState: function (initialState) {
6904 currentHookNameInDev = 'useState';
6905 warnInvalidHookAccess();
6906 updateHookTypesDev();
6907 var prevDispatcher = ReactCurrentDispatcher$1.current;
6908 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6909 try {
6910 return updateState(initialState);
6911 } finally {
6912 ReactCurrentDispatcher$1.current = prevDispatcher;
6913 }
6914 },
6915 useDebugValue: function (value, formatterFn) {
6916 currentHookNameInDev = 'useDebugValue';
6917 warnInvalidHookAccess();
6918 updateHookTypesDev();
6919 return updateDebugValue(value, formatterFn);
6920 },
6921 useResponder: function (responder, props) {
6922 currentHookNameInDev = 'useResponder';
6923 warnInvalidHookAccess();
6924 updateHookTypesDev();
6925 return createResponderListener(responder, props);
6926 }
6927 };
6928}
6929
6930// Intentionally not named imports because Rollup would use dynamic dispatch for
6931// CommonJS interop named imports.
6932var now$1 = Scheduler$1.unstable_now;
6933
6934
6935var commitTime = 0;
6936var profilerStartTime = -1;
6937
6938function getCommitTime() {
6939 return commitTime;
6940}
6941
6942function recordCommitTime() {
6943 if (!enableProfilerTimer) {
6944 return;
6945 }
6946 commitTime = now$1();
6947}
6948
6949function startProfilerTimer(fiber) {
6950 if (!enableProfilerTimer) {
6951 return;
6952 }
6953
6954 profilerStartTime = now$1();
6955
6956 if (fiber.actualStartTime < 0) {
6957 fiber.actualStartTime = now$1();
6958 }
6959}
6960
6961function stopProfilerTimerIfRunning(fiber) {
6962 if (!enableProfilerTimer) {
6963 return;
6964 }
6965 profilerStartTime = -1;
6966}
6967
6968function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
6969 if (!enableProfilerTimer) {
6970 return;
6971 }
6972
6973 if (profilerStartTime >= 0) {
6974 var elapsedTime = now$1() - profilerStartTime;
6975 fiber.actualDuration += elapsedTime;
6976 if (overrideBaseTime) {
6977 fiber.selfBaseDuration = elapsedTime;
6978 }
6979 profilerStartTime = -1;
6980 }
6981}
6982
6983// The deepest Fiber on the stack involved in a hydration context.
6984// This may have been an insertion or a hydration.
6985var hydrationParentFiber = null;
6986var nextHydratableInstance = null;
6987var isHydrating = false;
6988
6989function enterHydrationState(fiber) {
6990 if (!supportsHydration) {
6991 return false;
6992 }
6993
6994 var parentInstance = fiber.stateNode.containerInfo;
6995 nextHydratableInstance = getFirstHydratableChild(parentInstance);
6996 hydrationParentFiber = fiber;
6997 isHydrating = true;
6998 return true;
6999}
7000
7001function reenterHydrationStateFromDehydratedSuspenseInstance(fiber) {
7002 if (!supportsHydration) {
7003 return false;
7004 }
7005
7006 var suspenseInstance = fiber.stateNode;
7007 nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
7008 popToNextHostParent(fiber);
7009 isHydrating = true;
7010 return true;
7011}
7012
7013function deleteHydratableInstance(returnFiber, instance) {
7014 {
7015 switch (returnFiber.tag) {
7016 case HostRoot:
7017 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
7018 break;
7019 case HostComponent:
7020 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
7021 break;
7022 }
7023 }
7024
7025 var childToDelete = createFiberFromHostInstanceForDeletion();
7026 childToDelete.stateNode = instance;
7027 childToDelete.return = returnFiber;
7028 childToDelete.effectTag = Deletion;
7029
7030 // This might seem like it belongs on progressedFirstDeletion. However,
7031 // these children are not part of the reconciliation list of children.
7032 // Even if we abort and rereconcile the children, that will try to hydrate
7033 // again and the nodes are still in the host tree so these will be
7034 // recreated.
7035 if (returnFiber.lastEffect !== null) {
7036 returnFiber.lastEffect.nextEffect = childToDelete;
7037 returnFiber.lastEffect = childToDelete;
7038 } else {
7039 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
7040 }
7041}
7042
7043function insertNonHydratedInstance(returnFiber, fiber) {
7044 fiber.effectTag |= Placement;
7045 {
7046 switch (returnFiber.tag) {
7047 case HostRoot:
7048 {
7049 var parentContainer = returnFiber.stateNode.containerInfo;
7050 switch (fiber.tag) {
7051 case HostComponent:
7052 var type = fiber.type;
7053 var props = fiber.pendingProps;
7054 didNotFindHydratableContainerInstance(parentContainer, type, props);
7055 break;
7056 case HostText:
7057 var text = fiber.pendingProps;
7058 didNotFindHydratableContainerTextInstance(parentContainer, text);
7059 break;
7060 case SuspenseComponent:
7061 didNotFindHydratableContainerSuspenseInstance(parentContainer);
7062 break;
7063 }
7064 break;
7065 }
7066 case HostComponent:
7067 {
7068 var parentType = returnFiber.type;
7069 var parentProps = returnFiber.memoizedProps;
7070 var parentInstance = returnFiber.stateNode;
7071 switch (fiber.tag) {
7072 case HostComponent:
7073 var _type = fiber.type;
7074 var _props = fiber.pendingProps;
7075 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
7076 break;
7077 case HostText:
7078 var _text = fiber.pendingProps;
7079 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
7080 break;
7081 case SuspenseComponent:
7082 didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance);
7083 break;
7084 }
7085 break;
7086 }
7087 default:
7088 return;
7089 }
7090 }
7091}
7092
7093function tryHydrate(fiber, nextInstance) {
7094 switch (fiber.tag) {
7095 case HostComponent:
7096 {
7097 var type = fiber.type;
7098 var props = fiber.pendingProps;
7099 var instance = canHydrateInstance(nextInstance, type, props);
7100 if (instance !== null) {
7101 fiber.stateNode = instance;
7102 return true;
7103 }
7104 return false;
7105 }
7106 case HostText:
7107 {
7108 var text = fiber.pendingProps;
7109 var textInstance = canHydrateTextInstance(nextInstance, text);
7110 if (textInstance !== null) {
7111 fiber.stateNode = textInstance;
7112 return true;
7113 }
7114 return false;
7115 }
7116 case SuspenseComponent:
7117 {
7118 if (enableSuspenseServerRenderer) {
7119 var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
7120 if (suspenseInstance !== null) {
7121 // Downgrade the tag to a dehydrated component until we've hydrated it.
7122 fiber.tag = DehydratedSuspenseComponent;
7123 fiber.stateNode = suspenseInstance;
7124 return true;
7125 }
7126 }
7127 return false;
7128 }
7129 default:
7130 return false;
7131 }
7132}
7133
7134function tryToClaimNextHydratableInstance(fiber) {
7135 if (!isHydrating) {
7136 return;
7137 }
7138 var nextInstance = nextHydratableInstance;
7139 if (!nextInstance) {
7140 // Nothing to hydrate. Make it an insertion.
7141 insertNonHydratedInstance(hydrationParentFiber, fiber);
7142 isHydrating = false;
7143 hydrationParentFiber = fiber;
7144 return;
7145 }
7146 var firstAttemptedInstance = nextInstance;
7147 if (!tryHydrate(fiber, nextInstance)) {
7148 // If we can't hydrate this instance let's try the next one.
7149 // We use this as a heuristic. It's based on intuition and not data so it
7150 // might be flawed or unnecessary.
7151 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
7152 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
7153 // Nothing to hydrate. Make it an insertion.
7154 insertNonHydratedInstance(hydrationParentFiber, fiber);
7155 isHydrating = false;
7156 hydrationParentFiber = fiber;
7157 return;
7158 }
7159 // We matched the next one, we'll now assume that the first one was
7160 // superfluous and we'll delete it. Since we can't eagerly delete it
7161 // we'll have to schedule a deletion. To do that, this node needs a dummy
7162 // fiber associated with it.
7163 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
7164 }
7165 hydrationParentFiber = fiber;
7166 nextHydratableInstance = getFirstHydratableChild(nextInstance);
7167}
7168
7169function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
7170 if (!supportsHydration) {
7171 (function () {
7172 {
7173 {
7174 throw ReactError(Error('Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'));
7175 }
7176 }
7177 })();
7178 }
7179
7180 var instance = fiber.stateNode;
7181 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
7182 // TODO: Type this specific to this type of component.
7183 fiber.updateQueue = updatePayload;
7184 // If the update payload indicates that there is a change or if there
7185 // is a new ref we mark this as an update.
7186 if (updatePayload !== null) {
7187 return true;
7188 }
7189 return false;
7190}
7191
7192function prepareToHydrateHostTextInstance(fiber) {
7193 if (!supportsHydration) {
7194 (function () {
7195 {
7196 {
7197 throw ReactError(Error('Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'));
7198 }
7199 }
7200 })();
7201 }
7202
7203 var textInstance = fiber.stateNode;
7204 var textContent = fiber.memoizedProps;
7205 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
7206 {
7207 if (shouldUpdate) {
7208 // We assume that prepareToHydrateHostTextInstance is called in a context where the
7209 // hydration parent is the parent host component of this host text.
7210 var returnFiber = hydrationParentFiber;
7211 if (returnFiber !== null) {
7212 switch (returnFiber.tag) {
7213 case HostRoot:
7214 {
7215 var parentContainer = returnFiber.stateNode.containerInfo;
7216 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
7217 break;
7218 }
7219 case HostComponent:
7220 {
7221 var parentType = returnFiber.type;
7222 var parentProps = returnFiber.memoizedProps;
7223 var parentInstance = returnFiber.stateNode;
7224 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
7225 break;
7226 }
7227 }
7228 }
7229 }
7230 }
7231 return shouldUpdate;
7232}
7233
7234function skipPastDehydratedSuspenseInstance(fiber) {
7235 if (!supportsHydration) {
7236 (function () {
7237 {
7238 {
7239 throw ReactError(Error('Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'));
7240 }
7241 }
7242 })();
7243 }
7244 var suspenseInstance = fiber.stateNode;
7245 (function () {
7246 if (!suspenseInstance) {
7247 {
7248 throw ReactError(Error('Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.'));
7249 }
7250 }
7251 })();
7252 nextHydratableInstance = getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
7253}
7254
7255function popToNextHostParent(fiber) {
7256 var parent = fiber.return;
7257 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== DehydratedSuspenseComponent) {
7258 parent = parent.return;
7259 }
7260 hydrationParentFiber = parent;
7261}
7262
7263function popHydrationState(fiber) {
7264 if (!supportsHydration) {
7265 return false;
7266 }
7267 if (fiber !== hydrationParentFiber) {
7268 // We're deeper than the current hydration context, inside an inserted
7269 // tree.
7270 return false;
7271 }
7272 if (!isHydrating) {
7273 // If we're not currently hydrating but we're in a hydration context, then
7274 // we were an insertion and now need to pop up reenter hydration of our
7275 // siblings.
7276 popToNextHostParent(fiber);
7277 isHydrating = true;
7278 return false;
7279 }
7280
7281 var type = fiber.type;
7282
7283 // If we have any remaining hydratable nodes, we need to delete them now.
7284 // We only do this deeper than head and body since they tend to have random
7285 // other nodes in them. We also ignore components with pure text content in
7286 // side of them.
7287 // TODO: Better heuristic.
7288 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
7289 var nextInstance = nextHydratableInstance;
7290 while (nextInstance) {
7291 deleteHydratableInstance(fiber, nextInstance);
7292 nextInstance = getNextHydratableSibling(nextInstance);
7293 }
7294 }
7295
7296 popToNextHostParent(fiber);
7297 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
7298 return true;
7299}
7300
7301function resetHydrationState() {
7302 if (!supportsHydration) {
7303 return;
7304 }
7305
7306 hydrationParentFiber = null;
7307 nextHydratableInstance = null;
7308 isHydrating = false;
7309}
7310
7311var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
7312
7313var didReceiveUpdate = false;
7314
7315var didWarnAboutBadClass = void 0;
7316var didWarnAboutModulePatternComponent = void 0;
7317var didWarnAboutContextTypeOnFunctionComponent = void 0;
7318var didWarnAboutGetDerivedStateOnFunctionComponent = void 0;
7319var didWarnAboutFunctionRefs = void 0;
7320var didWarnAboutReassigningProps = void 0;
7321var didWarnAboutMaxDuration = void 0;
7322var didWarnAboutRevealOrder = void 0;
7323var didWarnAboutTailOptions = void 0;
7324var didWarnAboutDefaultPropsOnFunctionComponent = void 0;
7325
7326{
7327 didWarnAboutBadClass = {};
7328 didWarnAboutModulePatternComponent = {};
7329 didWarnAboutContextTypeOnFunctionComponent = {};
7330 didWarnAboutGetDerivedStateOnFunctionComponent = {};
7331 didWarnAboutFunctionRefs = {};
7332 didWarnAboutReassigningProps = false;
7333 didWarnAboutMaxDuration = false;
7334 didWarnAboutRevealOrder = {};
7335 didWarnAboutTailOptions = {};
7336 didWarnAboutDefaultPropsOnFunctionComponent = {};
7337}
7338
7339function reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime) {
7340 if (current$$1 === null) {
7341 // If this is a fresh new component that hasn't been rendered yet, we
7342 // won't update its child set by applying minimal side-effects. Instead,
7343 // we will add them all to the child before it gets rendered. That means
7344 // we can optimize this reconciliation pass by not tracking side-effects.
7345 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7346 } else {
7347 // If the current child is the same as the work in progress, it means that
7348 // we haven't yet started any work on these children. Therefore, we use
7349 // the clone algorithm to create a copy of all the current children.
7350
7351 // If we had any progressed work already, that is invalid at this point so
7352 // let's throw it out.
7353 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, nextChildren, renderExpirationTime);
7354 }
7355}
7356
7357function forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime) {
7358 // This function is fork of reconcileChildren. It's used in cases where we
7359 // want to reconcile without matching against the existing set. This has the
7360 // effect of all current children being unmounted; even if the type and key
7361 // are the same, the old child is unmounted and a new child is created.
7362 //
7363 // To do this, we're going to go through the reconcile algorithm twice. In
7364 // the first pass, we schedule a deletion for all the current children by
7365 // passing null.
7366 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, null, renderExpirationTime);
7367 // In the second pass, we mount the new children. The trick here is that we
7368 // pass null in place of where we usually pass the current child set. This has
7369 // the effect of remounting all children regardless of whether their their
7370 // identity matches.
7371 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7372}
7373
7374function updateForwardRef(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
7375 // TODO: current can be non-null here even if the component
7376 // hasn't yet mounted. This happens after the first render suspends.
7377 // We'll need to figure out if this is fine or can cause issues.
7378
7379 {
7380 if (workInProgress.type !== workInProgress.elementType) {
7381 // Lazy component props can't be validated in createElement
7382 // because they're only guaranteed to be resolved here.
7383 var innerPropTypes = Component.propTypes;
7384 if (innerPropTypes) {
7385 checkPropTypes(innerPropTypes, nextProps, // Resolved props
7386 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7387 }
7388 }
7389 }
7390
7391 var render = Component.render;
7392 var ref = workInProgress.ref;
7393
7394 // The rest is a fork of updateFunctionComponent
7395 var nextChildren = void 0;
7396 prepareToReadContext(workInProgress, renderExpirationTime);
7397 {
7398 ReactCurrentOwner$2.current = workInProgress;
7399 setCurrentPhase('render');
7400 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
7401 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7402 // Only double-render components with Hooks
7403 if (workInProgress.memoizedState !== null) {
7404 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
7405 }
7406 }
7407 setCurrentPhase(null);
7408 }
7409
7410 if (current$$1 !== null && !didReceiveUpdate) {
7411 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
7412 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
7413 }
7414
7415 // React DevTools reads this flag.
7416 workInProgress.effectTag |= PerformedWork;
7417 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
7418 return workInProgress.child;
7419}
7420
7421function updateMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
7422 if (current$$1 === null) {
7423 var type = Component.type;
7424 if (isSimpleFunctionComponent(type) && Component.compare === null &&
7425 // SimpleMemoComponent codepath doesn't resolve outer props either.
7426 Component.defaultProps === undefined) {
7427 var resolvedType = type;
7428 {
7429 resolvedType = resolveFunctionForHotReloading(type);
7430 }
7431 // If this is a plain function component without default props,
7432 // and with only the default shallow comparison, we upgrade it
7433 // to a SimpleMemoComponent to allow fast path updates.
7434 workInProgress.tag = SimpleMemoComponent;
7435 workInProgress.type = resolvedType;
7436 {
7437 validateFunctionComponentInDev(workInProgress, type);
7438 }
7439 return updateSimpleMemoComponent(current$$1, workInProgress, resolvedType, nextProps, updateExpirationTime, renderExpirationTime);
7440 }
7441 {
7442 var innerPropTypes = type.propTypes;
7443 if (innerPropTypes) {
7444 // Inner memo component props aren't currently validated in createElement.
7445 // We could move it there, but we'd still need this for lazy code path.
7446 checkPropTypes(innerPropTypes, nextProps, // Resolved props
7447 'prop', getComponentName(type), getCurrentFiberStackInDev);
7448 }
7449 }
7450 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
7451 child.ref = workInProgress.ref;
7452 child.return = workInProgress;
7453 workInProgress.child = child;
7454 return child;
7455 }
7456 {
7457 var _type = Component.type;
7458 var _innerPropTypes = _type.propTypes;
7459 if (_innerPropTypes) {
7460 // Inner memo component props aren't currently validated in createElement.
7461 // We could move it there, but we'd still need this for lazy code path.
7462 checkPropTypes(_innerPropTypes, nextProps, // Resolved props
7463 'prop', getComponentName(_type), getCurrentFiberStackInDev);
7464 }
7465 }
7466 var currentChild = current$$1.child; // This is always exactly one child
7467 if (updateExpirationTime < renderExpirationTime) {
7468 // This will be the props with resolved defaultProps,
7469 // unlike current.memoizedProps which will be the unresolved ones.
7470 var prevProps = currentChild.memoizedProps;
7471 // Default to shallow comparison
7472 var compare = Component.compare;
7473 compare = compare !== null ? compare : shallowEqual;
7474 if (compare(prevProps, nextProps) && current$$1.ref === workInProgress.ref) {
7475 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
7476 }
7477 }
7478 // React DevTools reads this flag.
7479 workInProgress.effectTag |= PerformedWork;
7480 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
7481 newChild.ref = workInProgress.ref;
7482 newChild.return = workInProgress;
7483 workInProgress.child = newChild;
7484 return newChild;
7485}
7486
7487function updateSimpleMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
7488 // TODO: current can be non-null here even if the component
7489 // hasn't yet mounted. This happens when the inner render suspends.
7490 // We'll need to figure out if this is fine or can cause issues.
7491
7492 {
7493 if (workInProgress.type !== workInProgress.elementType) {
7494 // Lazy component props can't be validated in createElement
7495 // because they're only guaranteed to be resolved here.
7496 var outerMemoType = workInProgress.elementType;
7497 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
7498 // We warn when you define propTypes on lazy()
7499 // so let's just skip over it to find memo() outer wrapper.
7500 // Inner props for memo are validated later.
7501 outerMemoType = refineResolvedLazyComponent(outerMemoType);
7502 }
7503 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
7504 if (outerPropTypes) {
7505 checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
7506 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
7507 }
7508 // Inner propTypes will be validated in the function component path.
7509 }
7510 }
7511 if (current$$1 !== null) {
7512 var prevProps = current$$1.memoizedProps;
7513 if (shallowEqual(prevProps, nextProps) && current$$1.ref === workInProgress.ref && (
7514 // Prevent bailout if the implementation changed due to hot reload:
7515 workInProgress.type === current$$1.type)) {
7516 didReceiveUpdate = false;
7517 if (updateExpirationTime < renderExpirationTime) {
7518 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
7519 }
7520 }
7521 }
7522 return updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
7523}
7524
7525function updateFragment(current$$1, workInProgress, renderExpirationTime) {
7526 var nextChildren = workInProgress.pendingProps;
7527 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
7528 return workInProgress.child;
7529}
7530
7531function updateMode(current$$1, workInProgress, renderExpirationTime) {
7532 var nextChildren = workInProgress.pendingProps.children;
7533 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
7534 return workInProgress.child;
7535}
7536
7537function updateProfiler(current$$1, workInProgress, renderExpirationTime) {
7538 if (enableProfilerTimer) {
7539 workInProgress.effectTag |= Update;
7540 }
7541 var nextProps = workInProgress.pendingProps;
7542 var nextChildren = nextProps.children;
7543 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
7544 return workInProgress.child;
7545}
7546
7547function markRef(current$$1, workInProgress) {
7548 var ref = workInProgress.ref;
7549 if (current$$1 === null && ref !== null || current$$1 !== null && current$$1.ref !== ref) {
7550 // Schedule a Ref effect
7551 workInProgress.effectTag |= Ref;
7552 }
7553}
7554
7555function updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
7556 {
7557 if (workInProgress.type !== workInProgress.elementType) {
7558 // Lazy component props can't be validated in createElement
7559 // because they're only guaranteed to be resolved here.
7560 var innerPropTypes = Component.propTypes;
7561 if (innerPropTypes) {
7562 checkPropTypes(innerPropTypes, nextProps, // Resolved props
7563 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7564 }
7565 }
7566 }
7567
7568 var context = void 0;
7569 if (!disableLegacyContext) {
7570 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
7571 context = getMaskedContext(workInProgress, unmaskedContext);
7572 }
7573
7574 var nextChildren = void 0;
7575 prepareToReadContext(workInProgress, renderExpirationTime);
7576 {
7577 ReactCurrentOwner$2.current = workInProgress;
7578 setCurrentPhase('render');
7579 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
7580 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7581 // Only double-render components with Hooks
7582 if (workInProgress.memoizedState !== null) {
7583 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
7584 }
7585 }
7586 setCurrentPhase(null);
7587 }
7588
7589 if (current$$1 !== null && !didReceiveUpdate) {
7590 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
7591 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
7592 }
7593
7594 // React DevTools reads this flag.
7595 workInProgress.effectTag |= PerformedWork;
7596 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
7597 return workInProgress.child;
7598}
7599
7600function updateClassComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
7601 {
7602 if (workInProgress.type !== workInProgress.elementType) {
7603 // Lazy component props can't be validated in createElement
7604 // because they're only guaranteed to be resolved here.
7605 var innerPropTypes = Component.propTypes;
7606 if (innerPropTypes) {
7607 checkPropTypes(innerPropTypes, nextProps, // Resolved props
7608 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7609 }
7610 }
7611 }
7612
7613 // Push context providers early to prevent context stack mismatches.
7614 // During mounting we don't know the child context yet as the instance doesn't exist.
7615 // We will invalidate the child context in finishClassComponent() right after rendering.
7616 var hasContext = void 0;
7617 if (isContextProvider(Component)) {
7618 hasContext = true;
7619 pushContextProvider(workInProgress);
7620 } else {
7621 hasContext = false;
7622 }
7623 prepareToReadContext(workInProgress, renderExpirationTime);
7624
7625 var instance = workInProgress.stateNode;
7626 var shouldUpdate = void 0;
7627 if (instance === null) {
7628 if (current$$1 !== null) {
7629 // An class component without an instance only mounts if it suspended
7630 // inside a non- concurrent tree, in an inconsistent state. We want to
7631 // tree it like a new mount, even though an empty version of it already
7632 // committed. Disconnect the alternate pointers.
7633 current$$1.alternate = null;
7634 workInProgress.alternate = null;
7635 // Since this is conceptually a new fiber, schedule a Placement effect
7636 workInProgress.effectTag |= Placement;
7637 }
7638 // In the initial pass we might need to construct the instance.
7639 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7640 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7641 shouldUpdate = true;
7642 } else if (current$$1 === null) {
7643 // In a resume, we'll already have an instance we can reuse.
7644 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7645 } else {
7646 shouldUpdate = updateClassInstance(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
7647 }
7648 var nextUnitOfWork = finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
7649 {
7650 var inst = workInProgress.stateNode;
7651 if (inst.props !== nextProps) {
7652 !didWarnAboutReassigningProps ? warning$1(false, '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') : void 0;
7653 didWarnAboutReassigningProps = true;
7654 }
7655 }
7656 return nextUnitOfWork;
7657}
7658
7659function finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
7660 // Refs should update even if shouldComponentUpdate returns false
7661 markRef(current$$1, workInProgress);
7662
7663 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
7664
7665 if (!shouldUpdate && !didCaptureError) {
7666 // Context providers should defer to sCU for rendering
7667 if (hasContext) {
7668 invalidateContextProvider(workInProgress, Component, false);
7669 }
7670
7671 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
7672 }
7673
7674 var instance = workInProgress.stateNode;
7675
7676 // Rerender
7677 ReactCurrentOwner$2.current = workInProgress;
7678 var nextChildren = void 0;
7679 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
7680 // If we captured an error, but getDerivedStateFrom catch is not defined,
7681 // unmount all the children. componentDidCatch will schedule an update to
7682 // re-render a fallback. This is temporary until we migrate everyone to
7683 // the new API.
7684 // TODO: Warn in a future release.
7685 nextChildren = null;
7686
7687 if (enableProfilerTimer) {
7688 stopProfilerTimerIfRunning(workInProgress);
7689 }
7690 } else {
7691 {
7692 setCurrentPhase('render');
7693 nextChildren = instance.render();
7694 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7695 instance.render();
7696 }
7697 setCurrentPhase(null);
7698 }
7699 }
7700
7701 // React DevTools reads this flag.
7702 workInProgress.effectTag |= PerformedWork;
7703 if (current$$1 !== null && didCaptureError) {
7704 // If we're recovering from an error, reconcile without reusing any of
7705 // the existing children. Conceptually, the normal children and the children
7706 // that are shown on error are two different sets, so we shouldn't reuse
7707 // normal children even if their identities match.
7708 forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime);
7709 } else {
7710 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
7711 }
7712
7713 // Memoize state using the values we just used to render.
7714 // TODO: Restructure so we never read values from the instance.
7715 workInProgress.memoizedState = instance.state;
7716
7717 // The context might have changed so we need to recalculate it.
7718 if (hasContext) {
7719 invalidateContextProvider(workInProgress, Component, true);
7720 }
7721
7722 return workInProgress.child;
7723}
7724
7725function pushHostRootContext(workInProgress) {
7726 var root = workInProgress.stateNode;
7727 if (root.pendingContext) {
7728 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
7729 } else if (root.context) {
7730 // Should always be set
7731 pushTopLevelContextObject(workInProgress, root.context, false);
7732 }
7733 pushHostContainer(workInProgress, root.containerInfo);
7734}
7735
7736function updateHostRoot(current$$1, workInProgress, renderExpirationTime) {
7737 pushHostRootContext(workInProgress);
7738 var updateQueue = workInProgress.updateQueue;
7739 (function () {
7740 if (!(updateQueue !== null)) {
7741 {
7742 throw ReactError(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.'));
7743 }
7744 }
7745 })();
7746 var nextProps = workInProgress.pendingProps;
7747 var prevState = workInProgress.memoizedState;
7748 var prevChildren = prevState !== null ? prevState.element : null;
7749 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
7750 var nextState = workInProgress.memoizedState;
7751 // Caution: React DevTools currently depends on this property
7752 // being called "element".
7753 var nextChildren = nextState.element;
7754 if (nextChildren === prevChildren) {
7755 // If the state is the same as before, that's a bailout because we had
7756 // no work that expires at this time.
7757 resetHydrationState();
7758 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
7759 }
7760 var root = workInProgress.stateNode;
7761 if ((current$$1 === null || current$$1.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
7762 // If we don't have any current children this might be the first pass.
7763 // We always try to hydrate. If this isn't a hydration pass there won't
7764 // be any children to hydrate which is effectively the same thing as
7765 // not hydrating.
7766
7767 // This is a bit of a hack. We track the host root as a placement to
7768 // know that we're currently in a mounting state. That way isMounted
7769 // works as expected. We must reset this before committing.
7770 // TODO: Delete this when we delete isMounted and findDOMNode.
7771 workInProgress.effectTag |= Placement;
7772
7773 // Ensure that children mount into this root without tracking
7774 // side-effects. This ensures that we don't store Placement effects on
7775 // nodes that will be hydrated.
7776 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7777 } else {
7778 // Otherwise reset hydration state in case we aborted and resumed another
7779 // root.
7780 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
7781 resetHydrationState();
7782 }
7783 return workInProgress.child;
7784}
7785
7786function updateHostComponent(current$$1, workInProgress, renderExpirationTime) {
7787 pushHostContext(workInProgress);
7788
7789 if (current$$1 === null) {
7790 tryToClaimNextHydratableInstance(workInProgress);
7791 }
7792
7793 var type = workInProgress.type;
7794 var nextProps = workInProgress.pendingProps;
7795 var prevProps = current$$1 !== null ? current$$1.memoizedProps : null;
7796
7797 var nextChildren = nextProps.children;
7798 var isDirectTextChild = shouldSetTextContent(type, nextProps);
7799
7800 if (isDirectTextChild) {
7801 // We special case a direct text child of a host node. This is a common
7802 // case. We won't handle it as a reified child. We will instead handle
7803 // this in the host environment that also have access to this prop. That
7804 // avoids allocating another HostText fiber and traversing it.
7805 nextChildren = null;
7806 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
7807 // If we're switching from a direct text child to a normal child, or to
7808 // empty, we need to schedule the text content to be reset.
7809 workInProgress.effectTag |= ContentReset;
7810 }
7811
7812 markRef(current$$1, workInProgress);
7813
7814 // Check the host config to see if the children are offscreen/hidden.
7815 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(type, nextProps)) {
7816 if (enableSchedulerTracing) {
7817 markSpawnedWork(Never);
7818 }
7819 // Schedule this fiber to re-render at offscreen priority. Then bailout.
7820 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
7821 return null;
7822 }
7823
7824 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
7825 return workInProgress.child;
7826}
7827
7828function updateHostText(current$$1, workInProgress) {
7829 if (current$$1 === null) {
7830 tryToClaimNextHydratableInstance(workInProgress);
7831 }
7832 // Nothing to do here. This is terminal. We'll do the completion step
7833 // immediately after.
7834 return null;
7835}
7836
7837function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
7838 if (_current !== null) {
7839 // An lazy component only mounts if it suspended inside a non-
7840 // concurrent tree, in an inconsistent state. We want to treat it like
7841 // a new mount, even though an empty version of it already committed.
7842 // Disconnect the alternate pointers.
7843 _current.alternate = null;
7844 workInProgress.alternate = null;
7845 // Since this is conceptually a new fiber, schedule a Placement effect
7846 workInProgress.effectTag |= Placement;
7847 }
7848
7849 var props = workInProgress.pendingProps;
7850 // We can't start a User Timing measurement with correct label yet.
7851 // Cancel and resume right after we know the tag.
7852 cancelWorkTimer(workInProgress);
7853 var Component = readLazyComponentType(elementType);
7854 // Store the unwrapped component in the type.
7855 workInProgress.type = Component;
7856 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
7857 startWorkTimer(workInProgress);
7858 var resolvedProps = resolveDefaultProps(Component, props);
7859 var child = void 0;
7860 switch (resolvedTag) {
7861 case FunctionComponent:
7862 {
7863 {
7864 validateFunctionComponentInDev(workInProgress, Component);
7865 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
7866 }
7867 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7868 break;
7869 }
7870 case ClassComponent:
7871 {
7872 {
7873 workInProgress.type = Component = resolveClassForHotReloading(Component);
7874 }
7875 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7876 break;
7877 }
7878 case ForwardRef:
7879 {
7880 {
7881 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
7882 }
7883 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7884 break;
7885 }
7886 case MemoComponent:
7887 {
7888 {
7889 if (workInProgress.type !== workInProgress.elementType) {
7890 var outerPropTypes = Component.propTypes;
7891 if (outerPropTypes) {
7892 checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only
7893 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7894 }
7895 }
7896 }
7897 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
7898 updateExpirationTime, renderExpirationTime);
7899 break;
7900 }
7901 default:
7902 {
7903 var hint = '';
7904 {
7905 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
7906 hint = ' Did you wrap a component in React.lazy() more than once?';
7907 }
7908 }
7909 // This message intentionally doesn't mention ForwardRef or MemoComponent
7910 // because the fact that it's a separate type of work is an
7911 // implementation detail.
7912 (function () {
7913 {
7914 {
7915 throw ReactError(Error('Element type is invalid. Received a promise that resolves to: ' + Component + '. Lazy element type must resolve to a class or function.' + hint));
7916 }
7917 }
7918 })();
7919 }
7920 }
7921 return child;
7922}
7923
7924function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
7925 if (_current !== null) {
7926 // An incomplete component only mounts if it suspended inside a non-
7927 // concurrent tree, in an inconsistent state. We want to treat it like
7928 // a new mount, even though an empty version of it already committed.
7929 // Disconnect the alternate pointers.
7930 _current.alternate = null;
7931 workInProgress.alternate = null;
7932 // Since this is conceptually a new fiber, schedule a Placement effect
7933 workInProgress.effectTag |= Placement;
7934 }
7935
7936 // Promote the fiber to a class and try rendering again.
7937 workInProgress.tag = ClassComponent;
7938
7939 // The rest of this function is a fork of `updateClassComponent`
7940
7941 // Push context providers early to prevent context stack mismatches.
7942 // During mounting we don't know the child context yet as the instance doesn't exist.
7943 // We will invalidate the child context in finishClassComponent() right after rendering.
7944 var hasContext = void 0;
7945 if (isContextProvider(Component)) {
7946 hasContext = true;
7947 pushContextProvider(workInProgress);
7948 } else {
7949 hasContext = false;
7950 }
7951 prepareToReadContext(workInProgress, renderExpirationTime);
7952
7953 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7954 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7955
7956 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
7957}
7958
7959function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
7960 if (_current !== null) {
7961 // An indeterminate component only mounts if it suspended inside a non-
7962 // concurrent tree, in an inconsistent state. We want to treat it like
7963 // a new mount, even though an empty version of it already committed.
7964 // Disconnect the alternate pointers.
7965 _current.alternate = null;
7966 workInProgress.alternate = null;
7967 // Since this is conceptually a new fiber, schedule a Placement effect
7968 workInProgress.effectTag |= Placement;
7969 }
7970
7971 var props = workInProgress.pendingProps;
7972 var context = void 0;
7973 if (!disableLegacyContext) {
7974 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
7975 context = getMaskedContext(workInProgress, unmaskedContext);
7976 }
7977
7978 prepareToReadContext(workInProgress, renderExpirationTime);
7979 var value = void 0;
7980
7981 {
7982 if (Component.prototype && typeof Component.prototype.render === 'function') {
7983 var componentName = getComponentName(Component) || 'Unknown';
7984
7985 if (!didWarnAboutBadClass[componentName]) {
7986 warningWithoutStack$1(false, "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);
7987 didWarnAboutBadClass[componentName] = true;
7988 }
7989 }
7990
7991 if (workInProgress.mode & StrictMode) {
7992 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
7993 }
7994
7995 ReactCurrentOwner$2.current = workInProgress;
7996 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
7997 }
7998 // React DevTools reads this flag.
7999 workInProgress.effectTag |= PerformedWork;
8000
8001 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
8002 {
8003 var _componentName = getComponentName(Component) || 'Unknown';
8004 if (!didWarnAboutModulePatternComponent[_componentName]) {
8005 warningWithoutStack$1(false, '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);
8006 didWarnAboutModulePatternComponent[_componentName] = true;
8007 }
8008 }
8009
8010 // Proceed under the assumption that this is a class instance
8011 workInProgress.tag = ClassComponent;
8012
8013 // Throw out any hooks that were used.
8014 resetHooks();
8015
8016 // Push context providers early to prevent context stack mismatches.
8017 // During mounting we don't know the child context yet as the instance doesn't exist.
8018 // We will invalidate the child context in finishClassComponent() right after rendering.
8019 var hasContext = false;
8020 if (isContextProvider(Component)) {
8021 hasContext = true;
8022 pushContextProvider(workInProgress);
8023 } else {
8024 hasContext = false;
8025 }
8026
8027 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
8028
8029 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
8030 if (typeof getDerivedStateFromProps === 'function') {
8031 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
8032 }
8033
8034 adoptClassInstance(workInProgress, value);
8035 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
8036 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
8037 } else {
8038 // Proceed under the assumption that this is a function component
8039 workInProgress.tag = FunctionComponent;
8040 {
8041 if (disableLegacyContext && Component.contextTypes) {
8042 warningWithoutStack$1(false, '%s uses the legacy contextTypes API which is no longer supported. ' + 'Use React.createContext() with React.useContext() instead.', getComponentName(Component) || 'Unknown');
8043 }
8044
8045 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8046 // Only double-render components with Hooks
8047 if (workInProgress.memoizedState !== null) {
8048 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
8049 }
8050 }
8051 }
8052 reconcileChildren(null, workInProgress, value, renderExpirationTime);
8053 {
8054 validateFunctionComponentInDev(workInProgress, Component);
8055 }
8056 return workInProgress.child;
8057 }
8058}
8059
8060function validateFunctionComponentInDev(workInProgress, Component) {
8061 if (Component) {
8062 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
8063 }
8064 if (workInProgress.ref !== null) {
8065 var info = '';
8066 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
8067 if (ownerName) {
8068 info += '\n\nCheck the render method of `' + ownerName + '`.';
8069 }
8070
8071 var warningKey = ownerName || workInProgress._debugID || '';
8072 var debugSource = workInProgress._debugSource;
8073 if (debugSource) {
8074 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
8075 }
8076 if (!didWarnAboutFunctionRefs[warningKey]) {
8077 didWarnAboutFunctionRefs[warningKey] = true;
8078 warning$1(false, 'Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
8079 }
8080 }
8081
8082 if (warnAboutDefaultPropsOnFunctionComponents && Component.defaultProps !== undefined) {
8083 var componentName = getComponentName(Component) || 'Unknown';
8084
8085 if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) {
8086 warningWithoutStack$1(false, '%s: Support for defaultProps will be removed from function components ' + 'in a future major release. Use JavaScript default parameters instead.', componentName);
8087 didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true;
8088 }
8089 }
8090
8091 if (typeof Component.getDerivedStateFromProps === 'function') {
8092 var _componentName2 = getComponentName(Component) || 'Unknown';
8093
8094 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) {
8095 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', _componentName2);
8096 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true;
8097 }
8098 }
8099
8100 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
8101 var _componentName3 = getComponentName(Component) || 'Unknown';
8102
8103 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) {
8104 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName3);
8105 didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true;
8106 }
8107 }
8108}
8109
8110// TODO: This is now an empty object. Should we just make it a boolean?
8111var SUSPENDED_MARKER = {};
8112
8113function shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) {
8114 // If the context is telling us that we should show a fallback, and we're not
8115 // already showing content, then we should show the fallback instead.
8116 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && (current$$1 === null || current$$1.memoizedState !== null);
8117}
8118
8119function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
8120 var mode = workInProgress.mode;
8121 var nextProps = workInProgress.pendingProps;
8122
8123 // This is used by DevTools to force a boundary to suspend.
8124 {
8125 if (shouldSuspend(workInProgress)) {
8126 workInProgress.effectTag |= DidCapture;
8127 }
8128 }
8129
8130 var suspenseContext = suspenseStackCursor.current;
8131
8132 var nextState = null;
8133 var nextDidTimeout = false;
8134
8135 if ((workInProgress.effectTag & DidCapture) !== NoEffect || shouldRemainOnFallback(suspenseContext, current$$1, workInProgress)) {
8136 // Something in this boundary's subtree already suspended. Switch to
8137 // rendering the fallback children.
8138 nextState = SUSPENDED_MARKER;
8139 nextDidTimeout = true;
8140 workInProgress.effectTag &= ~DidCapture;
8141 } else {
8142 // Attempting the main content
8143 if (current$$1 === null || current$$1.memoizedState !== null) {
8144 // This is a new mount or this boundary is already showing a fallback state.
8145 // Mark this subtree context as having at least one invisible parent that could
8146 // handle the fallback state.
8147 // Boundaries without fallbacks or should be avoided are not considered since
8148 // they cannot handle preferred fallback states.
8149 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {
8150 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
8151 }
8152 }
8153 }
8154
8155 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
8156
8157 pushSuspenseContext(workInProgress, suspenseContext);
8158
8159 {
8160 if ('maxDuration' in nextProps) {
8161 if (!didWarnAboutMaxDuration) {
8162 didWarnAboutMaxDuration = true;
8163 warning$1(false, 'maxDuration has been removed from React. ' + 'Remove the maxDuration prop.');
8164 }
8165 }
8166 }
8167
8168 // This next part is a bit confusing. If the children timeout, we switch to
8169 // showing the fallback children in place of the "primary" children.
8170 // However, we don't want to delete the primary children because then their
8171 // state will be lost (both the React state and the host state, e.g.
8172 // uncontrolled form inputs). Instead we keep them mounted and hide them.
8173 // Both the fallback children AND the primary children are rendered at the
8174 // same time. Once the primary children are un-suspended, we can delete
8175 // the fallback children — don't need to preserve their state.
8176 //
8177 // The two sets of children are siblings in the host environment, but
8178 // semantically, for purposes of reconciliation, they are two separate sets.
8179 // So we store them using two fragment fibers.
8180 //
8181 // However, we want to avoid allocating extra fibers for every placeholder.
8182 // They're only necessary when the children time out, because that's the
8183 // only time when both sets are mounted.
8184 //
8185 // So, the extra fragment fibers are only used if the children time out.
8186 // Otherwise, we render the primary children directly. This requires some
8187 // custom reconciliation logic to preserve the state of the primary
8188 // children. It's essentially a very basic form of re-parenting.
8189
8190 // `child` points to the child fiber. In the normal case, this is the first
8191 // fiber of the primary children set. In the timed-out case, it's a
8192 // a fragment fiber containing the primary children.
8193 var child = void 0;
8194 // `next` points to the next fiber React should render. In the normal case,
8195 // it's the same as `child`: the first fiber of the primary children set.
8196 // In the timed-out case, it's a fragment fiber containing the *fallback*
8197 // children -- we skip over the primary children entirely.
8198 var next = void 0;
8199 if (current$$1 === null) {
8200 if (enableSuspenseServerRenderer) {
8201 // If we're currently hydrating, try to hydrate this boundary.
8202 // But only if this has a fallback.
8203 if (nextProps.fallback !== undefined) {
8204 tryToClaimNextHydratableInstance(workInProgress);
8205 // This could've changed the tag if this was a dehydrated suspense component.
8206 if (workInProgress.tag === DehydratedSuspenseComponent) {
8207 popSuspenseContext(workInProgress);
8208 return updateDehydratedSuspenseComponent(null, workInProgress, renderExpirationTime);
8209 }
8210 }
8211 }
8212
8213 // This is the initial mount. This branch is pretty simple because there's
8214 // no previous state that needs to be preserved.
8215 if (nextDidTimeout) {
8216 // Mount separate fragments for primary and fallback children.
8217 var nextFallbackChildren = nextProps.fallback;
8218 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
8219 primaryChildFragment.return = workInProgress;
8220
8221 if ((workInProgress.mode & BatchedMode) === NoMode) {
8222 // Outside of batched mode, we commit the effects from the
8223 var progressedState = workInProgress.memoizedState;
8224 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
8225 primaryChildFragment.child = progressedPrimaryChild;
8226 var progressedChild = progressedPrimaryChild;
8227 while (progressedChild !== null) {
8228 progressedChild.return = primaryChildFragment;
8229 progressedChild = progressedChild.sibling;
8230 }
8231 }
8232
8233 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
8234 fallbackChildFragment.return = workInProgress;
8235 primaryChildFragment.sibling = fallbackChildFragment;
8236 child = primaryChildFragment;
8237 // Skip the primary children, and continue working on the
8238 // fallback children.
8239 next = fallbackChildFragment;
8240 } else {
8241 // Mount the primary children without an intermediate fragment fiber.
8242 var nextPrimaryChildren = nextProps.children;
8243 child = next = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
8244 }
8245 } else {
8246 // This is an update. This branch is more complicated because we need to
8247 // ensure the state of the primary children is preserved.
8248 var prevState = current$$1.memoizedState;
8249 var prevDidTimeout = prevState !== null;
8250 if (prevDidTimeout) {
8251 // The current tree already timed out. That means each child set is
8252 var currentPrimaryChildFragment = current$$1.child;
8253 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
8254 if (nextDidTimeout) {
8255 // Still timed out. Reuse the current primary children by cloning
8256 // its fragment. We're going to skip over these entirely.
8257 var _nextFallbackChildren = nextProps.fallback;
8258 var _primaryChildFragment = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
8259 _primaryChildFragment.return = workInProgress;
8260
8261 if ((workInProgress.mode & BatchedMode) === NoMode) {
8262 // Outside of batched mode, we commit the effects from the
8263 var _progressedState = workInProgress.memoizedState;
8264 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
8265 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
8266 _primaryChildFragment.child = _progressedPrimaryChild;
8267 var _progressedChild = _progressedPrimaryChild;
8268 while (_progressedChild !== null) {
8269 _progressedChild.return = _primaryChildFragment;
8270 _progressedChild = _progressedChild.sibling;
8271 }
8272 }
8273 }
8274
8275 // Because primaryChildFragment is a new fiber that we're inserting as the
8276 // parent of a new tree, we need to set its treeBaseDuration.
8277 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
8278 // treeBaseDuration is the sum of all the child tree base durations.
8279 var treeBaseDuration = 0;
8280 var hiddenChild = _primaryChildFragment.child;
8281 while (hiddenChild !== null) {
8282 treeBaseDuration += hiddenChild.treeBaseDuration;
8283 hiddenChild = hiddenChild.sibling;
8284 }
8285 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
8286 }
8287
8288 // Clone the fallback child fragment, too. These we'll continue
8289 // working on.
8290 var _fallbackChildFragment = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime);
8291 _fallbackChildFragment.return = workInProgress;
8292 _primaryChildFragment.sibling = _fallbackChildFragment;
8293 child = _primaryChildFragment;
8294 _primaryChildFragment.childExpirationTime = NoWork;
8295 // Skip the primary children, and continue working on the
8296 // fallback children.
8297 next = _fallbackChildFragment;
8298 } else {
8299 // No longer suspended. Switch back to showing the primary children,
8300 // and remove the intermediate fragment fiber.
8301 var _nextPrimaryChildren = nextProps.children;
8302 var currentPrimaryChild = currentPrimaryChildFragment.child;
8303 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime);
8304
8305 // If this render doesn't suspend, we need to delete the fallback
8306 // children. Wait until the complete phase, after we've confirmed the
8307 // fallback is no longer needed.
8308 // TODO: Would it be better to store the fallback fragment on
8309 // the stateNode?
8310
8311 // Continue rendering the children, like we normally do.
8312 child = next = primaryChild;
8313 }
8314 } else {
8315 // The current tree has not already timed out. That means the primary
8316 // children are not wrapped in a fragment fiber.
8317 var _currentPrimaryChild = current$$1.child;
8318 if (nextDidTimeout) {
8319 // Timed out. Wrap the children in a fragment fiber to keep them
8320 // separate from the fallback children.
8321 var _nextFallbackChildren2 = nextProps.fallback;
8322 var _primaryChildFragment2 = createFiberFromFragment(
8323 // It shouldn't matter what the pending props are because we aren't
8324 // going to render this fragment.
8325 null, mode, NoWork, null);
8326 _primaryChildFragment2.return = workInProgress;
8327 _primaryChildFragment2.child = _currentPrimaryChild;
8328 if (_currentPrimaryChild !== null) {
8329 _currentPrimaryChild.return = _primaryChildFragment2;
8330 }
8331
8332 // Even though we're creating a new fiber, there are no new children,
8333 // because we're reusing an already mounted tree. So we don't need to
8334 // schedule a placement.
8335 // primaryChildFragment.effectTag |= Placement;
8336
8337 if ((workInProgress.mode & BatchedMode) === NoMode) {
8338 // Outside of batched mode, we commit the effects from the
8339 var _progressedState2 = workInProgress.memoizedState;
8340 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
8341 _primaryChildFragment2.child = _progressedPrimaryChild2;
8342 var _progressedChild2 = _progressedPrimaryChild2;
8343 while (_progressedChild2 !== null) {
8344 _progressedChild2.return = _primaryChildFragment2;
8345 _progressedChild2 = _progressedChild2.sibling;
8346 }
8347 }
8348
8349 // Because primaryChildFragment is a new fiber that we're inserting as the
8350 // parent of a new tree, we need to set its treeBaseDuration.
8351 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
8352 // treeBaseDuration is the sum of all the child tree base durations.
8353 var _treeBaseDuration = 0;
8354 var _hiddenChild = _primaryChildFragment2.child;
8355 while (_hiddenChild !== null) {
8356 _treeBaseDuration += _hiddenChild.treeBaseDuration;
8357 _hiddenChild = _hiddenChild.sibling;
8358 }
8359 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
8360 }
8361
8362 // Create a fragment from the fallback children, too.
8363 var _fallbackChildFragment2 = createFiberFromFragment(_nextFallbackChildren2, mode, renderExpirationTime, null);
8364 _fallbackChildFragment2.return = workInProgress;
8365 _primaryChildFragment2.sibling = _fallbackChildFragment2;
8366 _fallbackChildFragment2.effectTag |= Placement;
8367 child = _primaryChildFragment2;
8368 _primaryChildFragment2.childExpirationTime = NoWork;
8369 // Skip the primary children, and continue working on the
8370 // fallback children.
8371 next = _fallbackChildFragment2;
8372 } else {
8373 // Still haven't timed out. Continue rendering the children, like we
8374 // normally do.
8375 var _nextPrimaryChildren2 = nextProps.children;
8376 next = child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
8377 }
8378 }
8379 workInProgress.stateNode = current$$1.stateNode;
8380 }
8381
8382 workInProgress.memoizedState = nextState;
8383 workInProgress.child = child;
8384 return next;
8385}
8386
8387function retrySuspenseComponentWithoutHydrating(current$$1, workInProgress, renderExpirationTime) {
8388 // Detach from the current dehydrated boundary.
8389 current$$1.alternate = null;
8390 workInProgress.alternate = null;
8391
8392 // Insert a deletion in the effect list.
8393 var returnFiber = workInProgress.return;
8394 (function () {
8395 if (!(returnFiber !== null)) {
8396 {
8397 throw ReactError(Error('Suspense boundaries are never on the root. This is probably a bug in React.'));
8398 }
8399 }
8400 })();
8401 var last = returnFiber.lastEffect;
8402 if (last !== null) {
8403 last.nextEffect = current$$1;
8404 returnFiber.lastEffect = current$$1;
8405 } else {
8406 returnFiber.firstEffect = returnFiber.lastEffect = current$$1;
8407 }
8408 current$$1.nextEffect = null;
8409 current$$1.effectTag = Deletion;
8410
8411 popSuspenseContext(workInProgress);
8412
8413 // Upgrade this work in progress to a real Suspense component.
8414 workInProgress.tag = SuspenseComponent;
8415 workInProgress.stateNode = null;
8416 workInProgress.memoizedState = null;
8417 // This is now an insertion.
8418 workInProgress.effectTag |= Placement;
8419 // Retry as a real Suspense component.
8420 return updateSuspenseComponent(null, workInProgress, renderExpirationTime);
8421}
8422
8423function updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
8424 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
8425 var suspenseInstance = workInProgress.stateNode;
8426 if (current$$1 === null) {
8427 // During the first pass, we'll bail out and not drill into the children.
8428 // Instead, we'll leave the content in place and try to hydrate it later.
8429 if (isSuspenseInstanceFallback(suspenseInstance)) {
8430 // This is a client-only boundary. Since we won't get any content from the server
8431 // for this, we need to schedule that at a higher priority based on when it would
8432 // have timed out. In theory we could render it in this pass but it would have the
8433 // wrong priority associated with it and will prevent hydration of parent path.
8434 // Instead, we'll leave work left on it to render it in a separate commit.
8435
8436 // TODO This time should be the time at which the server rendered response that is
8437 // a parent to this boundary was displayed. However, since we currently don't have
8438 // a protocol to transfer that time, we'll just estimate it by using the current
8439 // time. This will mean that Suspense timeouts are slightly shifted to later than
8440 // they should be.
8441 var serverDisplayTime = requestCurrentTime();
8442 // Schedule a normal pri update to render this content.
8443 workInProgress.expirationTime = computeAsyncExpiration(serverDisplayTime);
8444 } else {
8445 // We'll continue hydrating the rest at offscreen priority since we'll already
8446 // be showing the right content coming from the server, it is no rush.
8447 workInProgress.expirationTime = Never;
8448 }
8449 return null;
8450 }
8451 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
8452 // Something suspended. Leave the existing children in place.
8453 // TODO: In non-concurrent mode, should we commit the nodes we have hydrated so far?
8454 workInProgress.child = null;
8455 return null;
8456 }
8457 if (isSuspenseInstanceFallback(suspenseInstance)) {
8458 // This boundary is in a permanent fallback state. In this case, we'll never
8459 // get an update and we'll never be able to hydrate the final content. Let's just try the
8460 // client side render instead.
8461 return retrySuspenseComponentWithoutHydrating(current$$1, workInProgress, renderExpirationTime);
8462 }
8463 // We use childExpirationTime to indicate that a child might depend on context, so if
8464 // any context has changed, we need to treat is as if the input might have changed.
8465 var hasContextChanged$$1 = current$$1.childExpirationTime >= renderExpirationTime;
8466 if (didReceiveUpdate || hasContextChanged$$1) {
8467 // This boundary has changed since the first render. This means that we are now unable to
8468 // hydrate it. We might still be able to hydrate it using an earlier expiration time but
8469 // during this render we can't. Instead, we're going to delete the whole subtree and
8470 // instead inject a new real Suspense boundary to take its place, which may render content
8471 // or fallback. The real Suspense boundary will suspend for a while so we have some time
8472 // to ensure it can produce real content, but all state and pending events will be lost.
8473 return retrySuspenseComponentWithoutHydrating(current$$1, workInProgress, renderExpirationTime);
8474 } else if (isSuspenseInstancePending(suspenseInstance)) {
8475 // This component is still pending more data from the server, so we can't hydrate its
8476 // content. We treat it as if this component suspended itself. It might seem as if
8477 // we could just try to render it client-side instead. However, this will perform a
8478 // lot of unnecessary work and is unlikely to complete since it often will suspend
8479 // on missing data anyway. Additionally, the server might be able to render more
8480 // than we can on the client yet. In that case we'd end up with more fallback states
8481 // on the client than if we just leave it alone. If the server times out or errors
8482 // these should update this boundary to the permanent Fallback state instead.
8483 // Mark it as having captured (i.e. suspended).
8484 workInProgress.effectTag |= DidCapture;
8485 // Leave the children in place. I.e. empty.
8486 workInProgress.child = null;
8487 // Register a callback to retry this boundary once the server has sent the result.
8488 registerSuspenseInstanceRetry(suspenseInstance, retryTimedOutBoundary.bind(null, current$$1));
8489 return null;
8490 } else {
8491 // This is the first attempt.
8492 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress);
8493 var nextProps = workInProgress.pendingProps;
8494 var nextChildren = nextProps.children;
8495 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8496 return workInProgress.child;
8497 }
8498}
8499
8500function propagateSuspenseContextChange(workInProgress, firstChild, renderExpirationTime) {
8501 // Mark any Suspense boundaries with fallbacks as having work to do.
8502 // If they were previously forced into fallbacks, they may now be able
8503 // to unblock.
8504 var node = firstChild;
8505 while (node !== null) {
8506 if (node.tag === SuspenseComponent) {
8507 var state = node.memoizedState;
8508 if (state !== null) {
8509 if (node.expirationTime < renderExpirationTime) {
8510 node.expirationTime = renderExpirationTime;
8511 }
8512 var alternate = node.alternate;
8513 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
8514 alternate.expirationTime = renderExpirationTime;
8515 }
8516 scheduleWorkOnParentPath(node.return, renderExpirationTime);
8517 }
8518 } else if (node.child !== null) {
8519 node.child.return = node;
8520 node = node.child;
8521 continue;
8522 }
8523 if (node === workInProgress) {
8524 return;
8525 }
8526 while (node.sibling === null) {
8527 if (node.return === null || node.return === workInProgress) {
8528 return;
8529 }
8530 node = node.return;
8531 }
8532 node.sibling.return = node.return;
8533 node = node.sibling;
8534 }
8535}
8536
8537function findLastContentRow(firstChild) {
8538 // This is going to find the last row among these children that is already
8539 // showing content on the screen, as opposed to being in fallback state or
8540 // new. If a row has multiple Suspense boundaries, any of them being in the
8541 // fallback state, counts as the whole row being in a fallback state.
8542 // Note that the "rows" will be workInProgress, but any nested children
8543 // will still be current since we haven't rendered them yet. The mounted
8544 // order may not be the same as the new order. We use the new order.
8545 var row = firstChild;
8546 var lastContentRow = null;
8547 while (row !== null) {
8548 var currentRow = row.alternate;
8549 // New rows can't be content rows.
8550 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
8551 lastContentRow = row;
8552 }
8553 row = row.sibling;
8554 }
8555 return lastContentRow;
8556}
8557
8558function validateRevealOrder(revealOrder) {
8559 {
8560 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
8561 didWarnAboutRevealOrder[revealOrder] = true;
8562 if (typeof revealOrder === 'string') {
8563 switch (revealOrder.toLowerCase()) {
8564 case 'together':
8565 case 'forwards':
8566 case 'backwards':
8567 {
8568 warning$1(false, '"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
8569 break;
8570 }
8571 case 'forward':
8572 case 'backward':
8573 {
8574 warning$1(false, '"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase());
8575 break;
8576 }
8577 default:
8578 warning$1(false, '"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
8579 break;
8580 }
8581 } else {
8582 warning$1(false, '%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
8583 }
8584 }
8585 }
8586}
8587
8588function validateTailOptions(tailMode, revealOrder) {
8589 {
8590 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
8591 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
8592 didWarnAboutTailOptions[tailMode] = true;
8593 warning$1(false, '"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
8594 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
8595 didWarnAboutTailOptions[tailMode] = true;
8596 warning$1(false, '<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
8597 }
8598 }
8599 }
8600}
8601
8602function validateSuspenseListNestedChild(childSlot, index) {
8603 {
8604 var isArray = Array.isArray(childSlot);
8605 var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function';
8606 if (isArray || isIterable) {
8607 var type = isArray ? 'array' : 'iterable';
8608 warning$1(false, '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);
8609 return false;
8610 }
8611 }
8612 return true;
8613}
8614
8615function validateSuspenseListChildren(children, revealOrder) {
8616 {
8617 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
8618 if (Array.isArray(children)) {
8619 for (var i = 0; i < children.length; i++) {
8620 if (!validateSuspenseListNestedChild(children[i], i)) {
8621 return;
8622 }
8623 }
8624 } else {
8625 var iteratorFn = getIteratorFn(children);
8626 if (typeof iteratorFn === 'function') {
8627 var childrenIterator = iteratorFn.call(children);
8628 if (childrenIterator) {
8629 var step = childrenIterator.next();
8630 var _i = 0;
8631 for (; !step.done; step = childrenIterator.next()) {
8632 if (!validateSuspenseListNestedChild(step.value, _i)) {
8633 return;
8634 }
8635 _i++;
8636 }
8637 }
8638 } else {
8639 warning$1(false, '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);
8640 }
8641 }
8642 }
8643 }
8644}
8645
8646function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode) {
8647 var renderState = workInProgress.memoizedState;
8648 if (renderState === null) {
8649 workInProgress.memoizedState = {
8650 isBackwards: isBackwards,
8651 rendering: null,
8652 last: lastContentRow,
8653 tail: tail,
8654 tailExpiration: 0,
8655 tailMode: tailMode
8656 };
8657 } else {
8658 // We can reuse the existing object from previous renders.
8659 renderState.isBackwards = isBackwards;
8660 renderState.rendering = null;
8661 renderState.last = lastContentRow;
8662 renderState.tail = tail;
8663 renderState.tailExpiration = 0;
8664 renderState.tailMode = tailMode;
8665 }
8666}
8667
8668// This can end up rendering this component multiple passes.
8669// The first pass splits the children fibers into two sets. A head and tail.
8670// We first render the head. If anything is in fallback state, we do another
8671// pass through beginWork to rerender all children (including the tail) with
8672// the force suspend context. If the first render didn't have anything in
8673// in fallback state. Then we render each row in the tail one-by-one.
8674// That happens in the completeWork phase without going back to beginWork.
8675function updateSuspenseListComponent(current$$1, workInProgress, renderExpirationTime) {
8676 var nextProps = workInProgress.pendingProps;
8677 var revealOrder = nextProps.revealOrder;
8678 var tailMode = nextProps.tail;
8679 var newChildren = nextProps.children;
8680
8681 validateRevealOrder(revealOrder);
8682 validateTailOptions(tailMode, revealOrder);
8683 validateSuspenseListChildren(newChildren, revealOrder);
8684
8685 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
8686
8687 var suspenseContext = suspenseStackCursor.current;
8688
8689 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
8690 if (shouldForceFallback) {
8691 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
8692 workInProgress.effectTag |= DidCapture;
8693 } else {
8694 var didSuspendBefore = current$$1 !== null && (current$$1.effectTag & DidCapture) !== NoEffect;
8695 if (didSuspendBefore) {
8696 // If we previously forced a fallback, we need to schedule work
8697 // on any nested boundaries to let them know to try to render
8698 // again. This is the same as context updating.
8699 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderExpirationTime);
8700 }
8701 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
8702 }
8703 pushSuspenseContext(workInProgress, suspenseContext);
8704
8705 if ((workInProgress.mode & BatchedMode) === NoMode) {
8706 // Outside of batched mode, SuspenseList doesn't work so we just
8707 // use make it a noop by treating it as the default revealOrder.
8708 workInProgress.memoizedState = null;
8709 } else {
8710 switch (revealOrder) {
8711 case 'forwards':
8712 {
8713 var lastContentRow = findLastContentRow(workInProgress.child);
8714 var tail = void 0;
8715 if (lastContentRow === null) {
8716 // The whole list is part of the tail.
8717 // TODO: We could fast path by just rendering the tail now.
8718 tail = workInProgress.child;
8719 workInProgress.child = null;
8720 } else {
8721 // Disconnect the tail rows after the content row.
8722 // We're going to render them separately later.
8723 tail = lastContentRow.sibling;
8724 lastContentRow.sibling = null;
8725 }
8726 initSuspenseListRenderState(workInProgress, false, // isBackwards
8727 tail, lastContentRow, tailMode);
8728 break;
8729 }
8730 case 'backwards':
8731 {
8732 // We're going to find the first row that has existing content.
8733 // At the same time we're going to reverse the list of everything
8734 // we pass in the meantime. That's going to be our tail in reverse
8735 // order.
8736 var _tail = null;
8737 var row = workInProgress.child;
8738 workInProgress.child = null;
8739 while (row !== null) {
8740 var currentRow = row.alternate;
8741 // New rows can't be content rows.
8742 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
8743 // This is the beginning of the main content.
8744 workInProgress.child = row;
8745 break;
8746 }
8747 var nextRow = row.sibling;
8748 row.sibling = _tail;
8749 _tail = row;
8750 row = nextRow;
8751 }
8752 // TODO: If workInProgress.child is null, we can continue on the tail immediately.
8753 initSuspenseListRenderState(workInProgress, true, // isBackwards
8754 _tail, null, // last
8755 tailMode);
8756 break;
8757 }
8758 case 'together':
8759 {
8760 initSuspenseListRenderState(workInProgress, false, // isBackwards
8761 null, // tail
8762 null, // last
8763 undefined);
8764 break;
8765 }
8766 default:
8767 {
8768 // The default reveal order is the same as not having
8769 // a boundary.
8770 workInProgress.memoizedState = null;
8771 }
8772 }
8773 }
8774 return workInProgress.child;
8775}
8776
8777function updatePortalComponent(current$$1, workInProgress, renderExpirationTime) {
8778 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
8779 var nextChildren = workInProgress.pendingProps;
8780 if (current$$1 === null) {
8781 // Portals are special because we don't append the children during mount
8782 // but at commit. Therefore we need to track insertions which the normal
8783 // flow doesn't do during mount. This doesn't happen at the root because
8784 // the root always starts with a "current" with a null child.
8785 // TODO: Consider unifying this with how the root works.
8786 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8787 } else {
8788 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
8789 }
8790 return workInProgress.child;
8791}
8792
8793function updateContextProvider(current$$1, workInProgress, renderExpirationTime) {
8794 var providerType = workInProgress.type;
8795 var context = providerType._context;
8796
8797 var newProps = workInProgress.pendingProps;
8798 var oldProps = workInProgress.memoizedProps;
8799
8800 var newValue = newProps.value;
8801
8802 {
8803 var providerPropTypes = workInProgress.type.propTypes;
8804
8805 if (providerPropTypes) {
8806 checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
8807 }
8808 }
8809
8810 pushProvider(workInProgress, newValue);
8811
8812 if (oldProps !== null) {
8813 var oldValue = oldProps.value;
8814 var changedBits = calculateChangedBits(context, newValue, oldValue);
8815 if (changedBits === 0) {
8816 // No change. Bailout early if children are the same.
8817 if (oldProps.children === newProps.children && !hasContextChanged()) {
8818 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
8819 }
8820 } else {
8821 // The context value changed. Search for matching consumers and schedule
8822 // them to update.
8823 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
8824 }
8825 }
8826
8827 var newChildren = newProps.children;
8828 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
8829 return workInProgress.child;
8830}
8831
8832var hasWarnedAboutUsingContextAsConsumer = false;
8833
8834function updateContextConsumer(current$$1, workInProgress, renderExpirationTime) {
8835 var context = workInProgress.type;
8836 // The logic below for Context differs depending on PROD or DEV mode. In
8837 // DEV mode, we create a separate object for Context.Consumer that acts
8838 // like a proxy to Context. This proxy object adds unnecessary code in PROD
8839 // so we use the old behaviour (Context.Consumer references Context) to
8840 // reduce size and overhead. The separate object references context via
8841 // a property called "_context", which also gives us the ability to check
8842 // in DEV mode if this property exists or not and warn if it does not.
8843 {
8844 if (context._context === undefined) {
8845 // This may be because it's a Context (rather than a Consumer).
8846 // Or it may be because it's older React where they're the same thing.
8847 // We only want to warn if we're sure it's a new React.
8848 if (context !== context.Consumer) {
8849 if (!hasWarnedAboutUsingContextAsConsumer) {
8850 hasWarnedAboutUsingContextAsConsumer = true;
8851 warning$1(false, 'Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
8852 }
8853 }
8854 } else {
8855 context = context._context;
8856 }
8857 }
8858 var newProps = workInProgress.pendingProps;
8859 var render = newProps.children;
8860
8861 {
8862 !(typeof render === 'function') ? warningWithoutStack$1(false, '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.') : void 0;
8863 }
8864
8865 prepareToReadContext(workInProgress, renderExpirationTime);
8866 var newValue = readContext(context, newProps.unstable_observedBits);
8867 var newChildren = void 0;
8868 {
8869 ReactCurrentOwner$2.current = workInProgress;
8870 setCurrentPhase('render');
8871 newChildren = render(newValue);
8872 setCurrentPhase(null);
8873 }
8874
8875 // React DevTools reads this flag.
8876 workInProgress.effectTag |= PerformedWork;
8877 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
8878 return workInProgress.child;
8879}
8880
8881function updateFundamentalComponent$1(current$$1, workInProgress, renderExpirationTime) {
8882 var fundamentalImpl = workInProgress.type.impl;
8883 if (fundamentalImpl.reconcileChildren === false) {
8884 return null;
8885 }
8886 var nextProps = workInProgress.pendingProps;
8887 var nextChildren = nextProps.children;
8888
8889 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
8890 return workInProgress.child;
8891}
8892
8893function markWorkInProgressReceivedUpdate() {
8894 didReceiveUpdate = true;
8895}
8896
8897function bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime) {
8898 cancelWorkTimer(workInProgress);
8899
8900 if (current$$1 !== null) {
8901 // Reuse previous dependencies
8902 workInProgress.dependencies = current$$1.dependencies;
8903 }
8904
8905 if (enableProfilerTimer) {
8906 // Don't update "base" render times for bailouts.
8907 stopProfilerTimerIfRunning(workInProgress);
8908 }
8909
8910 // Check if the children have any pending work.
8911 var childExpirationTime = workInProgress.childExpirationTime;
8912 if (childExpirationTime < renderExpirationTime) {
8913 // The children don't have any work either. We can skip them.
8914 // TODO: Once we add back resuming, we should check if the children are
8915 // a work-in-progress set. If so, we need to transfer their effects.
8916 return null;
8917 } else {
8918 // This fiber doesn't have work, but its subtree does. Clone the child
8919 // fibers and continue.
8920 cloneChildFibers(current$$1, workInProgress);
8921 return workInProgress.child;
8922 }
8923}
8924
8925function remountFiber(current$$1, oldWorkInProgress, newWorkInProgress) {
8926 {
8927 var returnFiber = oldWorkInProgress.return;
8928 if (returnFiber === null) {
8929 throw new Error('Cannot swap the root fiber.');
8930 }
8931
8932 // Disconnect from the old current.
8933 // It will get deleted.
8934 current$$1.alternate = null;
8935 oldWorkInProgress.alternate = null;
8936
8937 // Connect to the new tree.
8938 newWorkInProgress.index = oldWorkInProgress.index;
8939 newWorkInProgress.sibling = oldWorkInProgress.sibling;
8940 newWorkInProgress.return = oldWorkInProgress.return;
8941 newWorkInProgress.ref = oldWorkInProgress.ref;
8942
8943 // Replace the child/sibling pointers above it.
8944 if (oldWorkInProgress === returnFiber.child) {
8945 returnFiber.child = newWorkInProgress;
8946 } else {
8947 var prevSibling = returnFiber.child;
8948 if (prevSibling === null) {
8949 throw new Error('Expected parent to have a child.');
8950 }
8951 while (prevSibling.sibling !== oldWorkInProgress) {
8952 prevSibling = prevSibling.sibling;
8953 if (prevSibling === null) {
8954 throw new Error('Expected to find the previous sibling.');
8955 }
8956 }
8957 prevSibling.sibling = newWorkInProgress;
8958 }
8959
8960 // Delete the old fiber and place the new one.
8961 // Since the old fiber is disconnected, we have to schedule it manually.
8962 var last = returnFiber.lastEffect;
8963 if (last !== null) {
8964 last.nextEffect = current$$1;
8965 returnFiber.lastEffect = current$$1;
8966 } else {
8967 returnFiber.firstEffect = returnFiber.lastEffect = current$$1;
8968 }
8969 current$$1.nextEffect = null;
8970 current$$1.effectTag = Deletion;
8971
8972 newWorkInProgress.effectTag |= Placement;
8973
8974 // Restart work from the new fiber.
8975 return newWorkInProgress;
8976 }
8977}
8978
8979function beginWork$1(current$$1, workInProgress, renderExpirationTime) {
8980 var updateExpirationTime = workInProgress.expirationTime;
8981
8982 {
8983 if (workInProgress._debugNeedsRemount && current$$1 !== null) {
8984 // This will restart the begin phase with a new fiber.
8985 return remountFiber(current$$1, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.expirationTime));
8986 }
8987 }
8988
8989 if (current$$1 !== null) {
8990 var oldProps = current$$1.memoizedProps;
8991 var newProps = workInProgress.pendingProps;
8992
8993 if (oldProps !== newProps || hasContextChanged() || (
8994 // Force a re-render if the implementation changed due to hot reload:
8995 workInProgress.type !== current$$1.type)) {
8996 // If props or context changed, mark the fiber as having performed work.
8997 // This may be unset if the props are determined to be equal later (memo).
8998 didReceiveUpdate = true;
8999 } else if (updateExpirationTime < renderExpirationTime) {
9000 didReceiveUpdate = false;
9001 // This fiber does not have any pending work. Bailout without entering
9002 // the begin phase. There's still some bookkeeping we that needs to be done
9003 // in this optimized path, mostly pushing stuff onto the stack.
9004 switch (workInProgress.tag) {
9005 case HostRoot:
9006 pushHostRootContext(workInProgress);
9007 resetHydrationState();
9008 break;
9009 case HostComponent:
9010 pushHostContext(workInProgress);
9011 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(workInProgress.type, newProps)) {
9012 if (enableSchedulerTracing) {
9013 markSpawnedWork(Never);
9014 }
9015 // Schedule this fiber to re-render at offscreen priority. Then bailout.
9016 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
9017 return null;
9018 }
9019 break;
9020 case ClassComponent:
9021 {
9022 var Component = workInProgress.type;
9023 if (isContextProvider(Component)) {
9024 pushContextProvider(workInProgress);
9025 }
9026 break;
9027 }
9028 case HostPortal:
9029 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
9030 break;
9031 case ContextProvider:
9032 {
9033 var newValue = workInProgress.memoizedProps.value;
9034 pushProvider(workInProgress, newValue);
9035 break;
9036 }
9037 case Profiler:
9038 if (enableProfilerTimer) {
9039 workInProgress.effectTag |= Update;
9040 }
9041 break;
9042 case SuspenseComponent:
9043 {
9044 var state = workInProgress.memoizedState;
9045 var didTimeout = state !== null;
9046 if (didTimeout) {
9047 // If this boundary is currently timed out, we need to decide
9048 // whether to retry the primary children, or to skip over it and
9049 // go straight to the fallback. Check the priority of the primary
9050 var primaryChildFragment = workInProgress.child;
9051 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
9052 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
9053 // The primary children have pending work. Use the normal path
9054 // to attempt to render the primary children again.
9055 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
9056 } else {
9057 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
9058 // The primary children do not have pending work with sufficient
9059 // priority. Bailout.
9060 var child = bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
9061 if (child !== null) {
9062 // The fallback children have pending work. Skip over the
9063 // primary children and work on the fallback.
9064 return child.sibling;
9065 } else {
9066 return null;
9067 }
9068 }
9069 } else {
9070 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
9071 }
9072 break;
9073 }
9074 case DehydratedSuspenseComponent:
9075 {
9076 if (enableSuspenseServerRenderer) {
9077 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
9078 // We know that this component will suspend again because if it has
9079 // been unsuspended it has committed as a regular Suspense component.
9080 // If it needs to be retried, it should have work scheduled on it.
9081 workInProgress.effectTag |= DidCapture;
9082 }
9083 break;
9084 }
9085 case SuspenseListComponent:
9086 {
9087 var didSuspendBefore = (current$$1.effectTag & DidCapture) !== NoEffect;
9088
9089 var hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
9090
9091 if (didSuspendBefore) {
9092 if (hasChildWork) {
9093 // If something was in fallback state last time, and we have all the
9094 // same children then we're still in progressive loading state.
9095 // Something might get unblocked by state updates or retries in the
9096 // tree which will affect the tail. So we need to use the normal
9097 // path to compute the correct tail.
9098 return updateSuspenseListComponent(current$$1, workInProgress, renderExpirationTime);
9099 }
9100 // If none of the children had any work, that means that none of
9101 // them got retried so they'll still be blocked in the same way
9102 // as before. We can fast bail out.
9103 workInProgress.effectTag |= DidCapture;
9104 }
9105
9106 // If nothing suspended before and we're rendering the same children,
9107 // then the tail doesn't matter. Anything new that suspends will work
9108 // in the "together" mode, so we can continue from the state we had.
9109 var renderState = workInProgress.memoizedState;
9110 if (renderState !== null) {
9111 // Reset to the "together" mode in case we've started a different
9112 // update in the past but didn't complete it.
9113 renderState.rendering = null;
9114 renderState.tail = null;
9115 }
9116 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
9117
9118 if (hasChildWork) {
9119 break;
9120 } else {
9121 // If none of the children had any work, that means that none of
9122 // them got retried so they'll still be blocked in the same way
9123 // as before. We can fast bail out.
9124 return null;
9125 }
9126 }
9127 }
9128 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
9129 }
9130 } else {
9131 didReceiveUpdate = false;
9132 }
9133
9134 // Before entering the begin phase, clear the expiration time.
9135 workInProgress.expirationTime = NoWork;
9136
9137 switch (workInProgress.tag) {
9138 case IndeterminateComponent:
9139 {
9140 return mountIndeterminateComponent(current$$1, workInProgress, workInProgress.type, renderExpirationTime);
9141 }
9142 case LazyComponent:
9143 {
9144 var elementType = workInProgress.elementType;
9145 return mountLazyComponent(current$$1, workInProgress, elementType, updateExpirationTime, renderExpirationTime);
9146 }
9147 case FunctionComponent:
9148 {
9149 var _Component = workInProgress.type;
9150 var unresolvedProps = workInProgress.pendingProps;
9151 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
9152 return updateFunctionComponent(current$$1, workInProgress, _Component, resolvedProps, renderExpirationTime);
9153 }
9154 case ClassComponent:
9155 {
9156 var _Component2 = workInProgress.type;
9157 var _unresolvedProps = workInProgress.pendingProps;
9158 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
9159 return updateClassComponent(current$$1, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
9160 }
9161 case HostRoot:
9162 return updateHostRoot(current$$1, workInProgress, renderExpirationTime);
9163 case HostComponent:
9164 return updateHostComponent(current$$1, workInProgress, renderExpirationTime);
9165 case HostText:
9166 return updateHostText(current$$1, workInProgress);
9167 case SuspenseComponent:
9168 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
9169 case HostPortal:
9170 return updatePortalComponent(current$$1, workInProgress, renderExpirationTime);
9171 case ForwardRef:
9172 {
9173 var type = workInProgress.type;
9174 var _unresolvedProps2 = workInProgress.pendingProps;
9175 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
9176 return updateForwardRef(current$$1, workInProgress, type, _resolvedProps2, renderExpirationTime);
9177 }
9178 case Fragment:
9179 return updateFragment(current$$1, workInProgress, renderExpirationTime);
9180 case Mode:
9181 return updateMode(current$$1, workInProgress, renderExpirationTime);
9182 case Profiler:
9183 return updateProfiler(current$$1, workInProgress, renderExpirationTime);
9184 case ContextProvider:
9185 return updateContextProvider(current$$1, workInProgress, renderExpirationTime);
9186 case ContextConsumer:
9187 return updateContextConsumer(current$$1, workInProgress, renderExpirationTime);
9188 case MemoComponent:
9189 {
9190 var _type2 = workInProgress.type;
9191 var _unresolvedProps3 = workInProgress.pendingProps;
9192 // Resolve outer props first, then resolve inner props.
9193 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
9194 {
9195 if (workInProgress.type !== workInProgress.elementType) {
9196 var outerPropTypes = _type2.propTypes;
9197 if (outerPropTypes) {
9198 checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only
9199 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
9200 }
9201 }
9202 }
9203 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
9204 return updateMemoComponent(current$$1, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
9205 }
9206 case SimpleMemoComponent:
9207 {
9208 return updateSimpleMemoComponent(current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
9209 }
9210 case IncompleteClassComponent:
9211 {
9212 var _Component3 = workInProgress.type;
9213 var _unresolvedProps4 = workInProgress.pendingProps;
9214 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
9215 return mountIncompleteClassComponent(current$$1, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
9216 }
9217 case DehydratedSuspenseComponent:
9218 {
9219 if (enableSuspenseServerRenderer) {
9220 return updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
9221 }
9222 break;
9223 }
9224 case SuspenseListComponent:
9225 {
9226 return updateSuspenseListComponent(current$$1, workInProgress, renderExpirationTime);
9227 }
9228 case FundamentalComponent:
9229 {
9230 if (enableFundamentalAPI) {
9231 return updateFundamentalComponent$1(current$$1, workInProgress, renderExpirationTime);
9232 }
9233 break;
9234 }
9235 }
9236 (function () {
9237 {
9238 {
9239 throw ReactError(Error('Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.'));
9240 }
9241 }
9242 })();
9243}
9244
9245function createFundamentalStateInstance(currentFiber, props, impl, state) {
9246 return {
9247 currentFiber: currentFiber,
9248 impl: impl,
9249 instance: null,
9250 prevProps: null,
9251 props: props,
9252 state: state
9253 };
9254}
9255
9256var emptyObject = {};
9257var isArray$2 = Array.isArray;
9258
9259function markUpdate(workInProgress) {
9260 // Tag the fiber with an update effect. This turns a Placement into
9261 // a PlacementAndUpdate.
9262 workInProgress.effectTag |= Update;
9263}
9264
9265function markRef$1(workInProgress) {
9266 workInProgress.effectTag |= Ref;
9267}
9268
9269var appendAllChildren = void 0;
9270var updateHostContainer = void 0;
9271var updateHostComponent$1 = void 0;
9272var updateHostText$1 = void 0;
9273if (supportsMutation) {
9274 // Mutation mode
9275
9276 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
9277 // We only have the top Fiber that was created but we need recurse down its
9278 // children to find all the terminal nodes.
9279 var node = workInProgress.child;
9280 while (node !== null) {
9281 if (node.tag === HostComponent || node.tag === HostText) {
9282 appendInitialChild(parent, node.stateNode);
9283 } else if (node.tag === FundamentalComponent) {
9284 appendInitialChild(parent, node.stateNode.instance);
9285 } else if (node.tag === HostPortal) {
9286 // If we have a portal child, then we don't want to traverse
9287 // down its children. Instead, we'll get insertions from each child in
9288 // the portal directly.
9289 } else if (node.child !== null) {
9290 node.child.return = node;
9291 node = node.child;
9292 continue;
9293 }
9294 if (node === workInProgress) {
9295 return;
9296 }
9297 while (node.sibling === null) {
9298 if (node.return === null || node.return === workInProgress) {
9299 return;
9300 }
9301 node = node.return;
9302 }
9303 node.sibling.return = node.return;
9304 node = node.sibling;
9305 }
9306 };
9307
9308 updateHostContainer = function (workInProgress) {
9309 // Noop
9310 };
9311 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9312 // If we have an alternate, that means this is an update and we need to
9313 // schedule a side-effect to do the updates.
9314 var oldProps = current.memoizedProps;
9315 if (oldProps === newProps) {
9316 // In mutation mode, this is sufficient for a bailout because
9317 // we won't touch this node even if children changed.
9318 return;
9319 }
9320
9321 // If we get updated because one of our children updated, we don't
9322 // have newProps so we'll have to reuse them.
9323 // TODO: Split the update API as separate for the props vs. children.
9324 // Even better would be if children weren't special cased at all tho.
9325 var instance = workInProgress.stateNode;
9326 var currentHostContext = getHostContext();
9327 // TODO: Experiencing an error where oldProps is null. Suggests a host
9328 // component is hitting the resume path. Figure out why. Possibly
9329 // related to `hidden`.
9330 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9331 // TODO: Type this specific to this type of component.
9332 workInProgress.updateQueue = updatePayload;
9333 // If the update payload indicates that there is a change or if there
9334 // is a new ref we mark this as an update. All the work is done in commitWork.
9335 if (updatePayload) {
9336 markUpdate(workInProgress);
9337 }
9338 };
9339 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9340 // If the text differs, mark it as an update. All the work in done in commitWork.
9341 if (oldText !== newText) {
9342 markUpdate(workInProgress);
9343 }
9344 };
9345} else if (supportsPersistence) {
9346 // Persistent host tree mode
9347
9348 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
9349 // We only have the top Fiber that was created but we need recurse down its
9350 // children to find all the terminal nodes.
9351 var node = workInProgress.child;
9352 while (node !== null) {
9353 // eslint-disable-next-line no-labels
9354 branches: if (node.tag === HostComponent) {
9355 var instance = node.stateNode;
9356 if (needsVisibilityToggle && isHidden) {
9357 // This child is inside a timed out tree. Hide it.
9358 var props = node.memoizedProps;
9359 var type = node.type;
9360 instance = cloneHiddenInstance(instance, type, props, node);
9361 }
9362 appendInitialChild(parent, instance);
9363 } else if (node.tag === HostText) {
9364 var _instance = node.stateNode;
9365 if (needsVisibilityToggle && isHidden) {
9366 // This child is inside a timed out tree. Hide it.
9367 var text = node.memoizedProps;
9368 _instance = cloneHiddenTextInstance(_instance, text, node);
9369 }
9370 appendInitialChild(parent, _instance);
9371 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
9372 var _instance2 = node.stateNode.instance;
9373 if (needsVisibilityToggle && isHidden) {
9374 // This child is inside a timed out tree. Hide it.
9375 var _props = node.memoizedProps;
9376 var _type = node.type;
9377 _instance2 = cloneHiddenInstance(_instance2, _type, _props, node);
9378 }
9379 appendInitialChild(parent, _instance2);
9380 } else if (node.tag === HostPortal) {
9381 // If we have a portal child, then we don't want to traverse
9382 // down its children. Instead, we'll get insertions from each child in
9383 // the portal directly.
9384 } else if (node.tag === SuspenseComponent) {
9385 if ((node.effectTag & Update) !== NoEffect) {
9386 // Need to toggle the visibility of the primary children.
9387 var newIsHidden = node.memoizedState !== null;
9388 if (newIsHidden) {
9389 var primaryChildParent = node.child;
9390 if (primaryChildParent !== null) {
9391 if (primaryChildParent.child !== null) {
9392 primaryChildParent.child.return = primaryChildParent;
9393 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
9394 }
9395 var fallbackChildParent = primaryChildParent.sibling;
9396 if (fallbackChildParent !== null) {
9397 fallbackChildParent.return = node;
9398 node = fallbackChildParent;
9399 continue;
9400 }
9401 }
9402 }
9403 }
9404 if (node.child !== null) {
9405 // Continue traversing like normal
9406 node.child.return = node;
9407 node = node.child;
9408 continue;
9409 }
9410 } else if (node.child !== null) {
9411 node.child.return = node;
9412 node = node.child;
9413 continue;
9414 }
9415 // $FlowFixMe This is correct but Flow is confused by the labeled break.
9416 node = node;
9417 if (node === workInProgress) {
9418 return;
9419 }
9420 while (node.sibling === null) {
9421 if (node.return === null || node.return === workInProgress) {
9422 return;
9423 }
9424 node = node.return;
9425 }
9426 node.sibling.return = node.return;
9427 node = node.sibling;
9428 }
9429 };
9430
9431 // An unfortunate fork of appendAllChildren because we have two different parent types.
9432 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
9433 // We only have the top Fiber that was created but we need recurse down its
9434 // children to find all the terminal nodes.
9435 var node = workInProgress.child;
9436 while (node !== null) {
9437 // eslint-disable-next-line no-labels
9438 branches: if (node.tag === HostComponent) {
9439 var instance = node.stateNode;
9440 if (needsVisibilityToggle && isHidden) {
9441 // This child is inside a timed out tree. Hide it.
9442 var props = node.memoizedProps;
9443 var type = node.type;
9444 instance = cloneHiddenInstance(instance, type, props, node);
9445 }
9446 appendChildToContainerChildSet(containerChildSet, instance);
9447 } else if (node.tag === HostText) {
9448 var _instance3 = node.stateNode;
9449 if (needsVisibilityToggle && isHidden) {
9450 // This child is inside a timed out tree. Hide it.
9451 var text = node.memoizedProps;
9452 _instance3 = cloneHiddenTextInstance(_instance3, text, node);
9453 }
9454 appendChildToContainerChildSet(containerChildSet, _instance3);
9455 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
9456 var _instance4 = node.stateNode.instance;
9457 if (needsVisibilityToggle && isHidden) {
9458 // This child is inside a timed out tree. Hide it.
9459 var _props2 = node.memoizedProps;
9460 var _type2 = node.type;
9461 _instance4 = cloneHiddenInstance(_instance4, _type2, _props2, node);
9462 }
9463 appendChildToContainerChildSet(containerChildSet, _instance4);
9464 } else if (node.tag === HostPortal) {
9465 // If we have a portal child, then we don't want to traverse
9466 // down its children. Instead, we'll get insertions from each child in
9467 // the portal directly.
9468 } else if (node.tag === SuspenseComponent) {
9469 if ((node.effectTag & Update) !== NoEffect) {
9470 // Need to toggle the visibility of the primary children.
9471 var newIsHidden = node.memoizedState !== null;
9472 if (newIsHidden) {
9473 var primaryChildParent = node.child;
9474 if (primaryChildParent !== null) {
9475 if (primaryChildParent.child !== null) {
9476 primaryChildParent.child.return = primaryChildParent;
9477 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
9478 }
9479 var fallbackChildParent = primaryChildParent.sibling;
9480 if (fallbackChildParent !== null) {
9481 fallbackChildParent.return = node;
9482 node = fallbackChildParent;
9483 continue;
9484 }
9485 }
9486 }
9487 }
9488 if (node.child !== null) {
9489 // Continue traversing like normal
9490 node.child.return = node;
9491 node = node.child;
9492 continue;
9493 }
9494 } else if (node.child !== null) {
9495 node.child.return = node;
9496 node = node.child;
9497 continue;
9498 }
9499 // $FlowFixMe This is correct but Flow is confused by the labeled break.
9500 node = node;
9501 if (node === workInProgress) {
9502 return;
9503 }
9504 while (node.sibling === null) {
9505 if (node.return === null || node.return === workInProgress) {
9506 return;
9507 }
9508 node = node.return;
9509 }
9510 node.sibling.return = node.return;
9511 node = node.sibling;
9512 }
9513 };
9514 updateHostContainer = function (workInProgress) {
9515 var portalOrRoot = workInProgress.stateNode;
9516 var childrenUnchanged = workInProgress.firstEffect === null;
9517 if (childrenUnchanged) {
9518 // No changes, just reuse the existing instance.
9519 } else {
9520 var container = portalOrRoot.containerInfo;
9521 var newChildSet = createContainerChildSet(container);
9522 // If children might have changed, we have to add them all to the set.
9523 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
9524 portalOrRoot.pendingChildren = newChildSet;
9525 // Schedule an update on the container to swap out the container.
9526 markUpdate(workInProgress);
9527 finalizeContainerChildren(container, newChildSet);
9528 }
9529 };
9530 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9531 var currentInstance = current.stateNode;
9532 var oldProps = current.memoizedProps;
9533 // If there are no effects associated with this node, then none of our children had any updates.
9534 // This guarantees that we can reuse all of them.
9535 var childrenUnchanged = workInProgress.firstEffect === null;
9536 if (childrenUnchanged && oldProps === newProps) {
9537 // No changes, just reuse the existing instance.
9538 // Note that this might release a previous clone.
9539 workInProgress.stateNode = currentInstance;
9540 return;
9541 }
9542 var recyclableInstance = workInProgress.stateNode;
9543 var currentHostContext = getHostContext();
9544 var updatePayload = null;
9545 if (oldProps !== newProps) {
9546 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9547 }
9548 if (childrenUnchanged && updatePayload === null) {
9549 // No changes, just reuse the existing instance.
9550 // Note that this might release a previous clone.
9551 workInProgress.stateNode = currentInstance;
9552 return;
9553 }
9554 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
9555 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
9556 markUpdate(workInProgress);
9557 }
9558 workInProgress.stateNode = newInstance;
9559 if (childrenUnchanged) {
9560 // If there are no other effects in this tree, we need to flag this node as having one.
9561 // Even though we're not going to use it for anything.
9562 // Otherwise parents won't know that there are new children to propagate upwards.
9563 markUpdate(workInProgress);
9564 } else {
9565 // If children might have changed, we have to add them all to the set.
9566 appendAllChildren(newInstance, workInProgress, false, false);
9567 }
9568 };
9569 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9570 if (oldText !== newText) {
9571 // If the text content differs, we'll create a new text instance for it.
9572 var rootContainerInstance = getRootHostContainer();
9573 var currentHostContext = getHostContext();
9574 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
9575 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
9576 // This lets the parents know that at least one of their children has changed.
9577 markUpdate(workInProgress);
9578 }
9579 };
9580} else {
9581 // No host operations
9582 updateHostContainer = function (workInProgress) {
9583 // Noop
9584 };
9585 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9586 // Noop
9587 };
9588 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9589 // Noop
9590 };
9591}
9592
9593function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
9594 switch (renderState.tailMode) {
9595 case 'hidden':
9596 {
9597 // Any insertions at the end of the tail list after this point
9598 // should be invisible. If there are already mounted boundaries
9599 // anything before them are not considered for collapsing.
9600 // Therefore we need to go through the whole tail to find if
9601 // there are any.
9602 var tailNode = renderState.tail;
9603 var lastTailNode = null;
9604 while (tailNode !== null) {
9605 if (tailNode.alternate !== null) {
9606 lastTailNode = tailNode;
9607 }
9608 tailNode = tailNode.sibling;
9609 }
9610 // Next we're simply going to delete all insertions after the
9611 // last rendered item.
9612 if (lastTailNode === null) {
9613 // All remaining items in the tail are insertions.
9614 renderState.tail = null;
9615 } else {
9616 // Detach the insertion after the last node that was already
9617 // inserted.
9618 lastTailNode.sibling = null;
9619 }
9620 break;
9621 }
9622 case 'collapsed':
9623 {
9624 // Any insertions at the end of the tail list after this point
9625 // should be invisible. If there are already mounted boundaries
9626 // anything before them are not considered for collapsing.
9627 // Therefore we need to go through the whole tail to find if
9628 // there are any.
9629 var _tailNode = renderState.tail;
9630 var _lastTailNode = null;
9631 while (_tailNode !== null) {
9632 if (_tailNode.alternate !== null) {
9633 _lastTailNode = _tailNode;
9634 }
9635 _tailNode = _tailNode.sibling;
9636 }
9637 // Next we're simply going to delete all insertions after the
9638 // last rendered item.
9639 if (_lastTailNode === null) {
9640 // All remaining items in the tail are insertions.
9641 if (!hasRenderedATailFallback && renderState.tail !== null) {
9642 // We suspended during the head. We want to show at least one
9643 // row at the tail. So we'll keep on and cut off the rest.
9644 renderState.tail.sibling = null;
9645 } else {
9646 renderState.tail = null;
9647 }
9648 } else {
9649 // Detach the insertion after the last node that was already
9650 // inserted.
9651 _lastTailNode.sibling = null;
9652 }
9653 break;
9654 }
9655 }
9656}
9657
9658function completeWork(current, workInProgress, renderExpirationTime) {
9659 var newProps = workInProgress.pendingProps;
9660
9661 switch (workInProgress.tag) {
9662 case IndeterminateComponent:
9663 break;
9664 case LazyComponent:
9665 break;
9666 case SimpleMemoComponent:
9667 case FunctionComponent:
9668 break;
9669 case ClassComponent:
9670 {
9671 var Component = workInProgress.type;
9672 if (isContextProvider(Component)) {
9673 popContext(workInProgress);
9674 }
9675 break;
9676 }
9677 case HostRoot:
9678 {
9679 popHostContainer(workInProgress);
9680 popTopLevelContextObject(workInProgress);
9681 var fiberRoot = workInProgress.stateNode;
9682 if (fiberRoot.pendingContext) {
9683 fiberRoot.context = fiberRoot.pendingContext;
9684 fiberRoot.pendingContext = null;
9685 }
9686 if (current === null || current.child === null) {
9687 // If we hydrated, pop so that we can delete any remaining children
9688 // that weren't hydrated.
9689 popHydrationState(workInProgress);
9690 // This resets the hacky state to fix isMounted before committing.
9691 // TODO: Delete this when we delete isMounted and findDOMNode.
9692 workInProgress.effectTag &= ~Placement;
9693 }
9694 updateHostContainer(workInProgress);
9695 break;
9696 }
9697 case HostComponent:
9698 {
9699 popHostContext(workInProgress);
9700 var rootContainerInstance = getRootHostContainer();
9701 var type = workInProgress.type;
9702 if (current !== null && workInProgress.stateNode != null) {
9703 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
9704
9705 if (enableFlareAPI) {
9706 var prevListeners = current.memoizedProps.listeners;
9707 var nextListeners = newProps.listeners;
9708 var instance = workInProgress.stateNode;
9709 if (prevListeners !== nextListeners) {
9710 updateEventListeners(nextListeners, instance, rootContainerInstance, workInProgress);
9711 }
9712 }
9713
9714 if (current.ref !== workInProgress.ref) {
9715 markRef$1(workInProgress);
9716 }
9717 } else {
9718 if (!newProps) {
9719 (function () {
9720 if (!(workInProgress.stateNode !== null)) {
9721 {
9722 throw ReactError(Error('We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.'));
9723 }
9724 }
9725 })();
9726 // This can happen when we abort work.
9727 break;
9728 }
9729
9730 var currentHostContext = getHostContext();
9731 // TODO: Move createInstance to beginWork and keep it on a context
9732 // "stack" as the parent. Then append children as we go in beginWork
9733 // or completeWork depending on we want to add then top->down or
9734 // bottom->up. Top->down is faster in IE11.
9735 var wasHydrated = popHydrationState(workInProgress);
9736 if (wasHydrated) {
9737 // TODO: Move this and createInstance step into the beginPhase
9738 // to consolidate.
9739 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
9740 // If changes to the hydrated node needs to be applied at the
9741 // commit-phase we mark this as such.
9742 markUpdate(workInProgress);
9743 }
9744 } else {
9745 var _instance5 = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
9746
9747 appendAllChildren(_instance5, workInProgress, false, false);
9748
9749 if (enableFlareAPI) {
9750 var listeners = newProps.listeners;
9751 if (listeners != null) {
9752 updateEventListeners(listeners, _instance5, rootContainerInstance, workInProgress);
9753 }
9754 }
9755
9756 // Certain renderers require commit-time effects for initial mount.
9757 // (eg DOM renderer supports auto-focus for certain elements).
9758 // Make sure such renderers get scheduled for later work.
9759 if (finalizeInitialChildren(_instance5, type, newProps, rootContainerInstance, currentHostContext)) {
9760 markUpdate(workInProgress);
9761 }
9762 workInProgress.stateNode = _instance5;
9763 }
9764
9765 if (workInProgress.ref !== null) {
9766 // If there is a ref on a host node we need to schedule a callback
9767 markRef$1(workInProgress);
9768 }
9769 }
9770 break;
9771 }
9772 case HostText:
9773 {
9774 var newText = newProps;
9775 if (current && workInProgress.stateNode != null) {
9776 var oldText = current.memoizedProps;
9777 // If we have an alternate, that means this is an update and we need
9778 // to schedule a side-effect to do the updates.
9779 updateHostText$1(current, workInProgress, oldText, newText);
9780 } else {
9781 if (typeof newText !== 'string') {
9782 (function () {
9783 if (!(workInProgress.stateNode !== null)) {
9784 {
9785 throw ReactError(Error('We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.'));
9786 }
9787 }
9788 })();
9789 // This can happen when we abort work.
9790 }
9791 var _rootContainerInstance = getRootHostContainer();
9792 var _currentHostContext = getHostContext();
9793 var _wasHydrated = popHydrationState(workInProgress);
9794 if (_wasHydrated) {
9795 if (prepareToHydrateHostTextInstance(workInProgress)) {
9796 markUpdate(workInProgress);
9797 }
9798 } else {
9799 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
9800 }
9801 }
9802 break;
9803 }
9804 case ForwardRef:
9805 break;
9806 case SuspenseComponent:
9807 {
9808 popSuspenseContext(workInProgress);
9809 var nextState = workInProgress.memoizedState;
9810 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
9811 // Something suspended. Re-render with the fallback children.
9812 workInProgress.expirationTime = renderExpirationTime;
9813 // Do not reset the effect list.
9814 return workInProgress;
9815 }
9816
9817 var nextDidTimeout = nextState !== null;
9818 var prevDidTimeout = false;
9819 if (current === null) {
9820 // In cases where we didn't find a suitable hydration boundary we never
9821 // downgraded this to a DehydratedSuspenseComponent, but we still need to
9822 // pop the hydration state since we might be inside the insertion tree.
9823 popHydrationState(workInProgress);
9824 } else {
9825 var prevState = current.memoizedState;
9826 prevDidTimeout = prevState !== null;
9827 if (!nextDidTimeout && prevState !== null) {
9828 // We just switched from the fallback to the normal children.
9829 // Delete the fallback.
9830 // TODO: Would it be better to store the fallback fragment on
9831 var currentFallbackChild = current.child.sibling;
9832 if (currentFallbackChild !== null) {
9833 // Deletions go at the beginning of the return fiber's effect list
9834 var first = workInProgress.firstEffect;
9835 if (first !== null) {
9836 workInProgress.firstEffect = currentFallbackChild;
9837 currentFallbackChild.nextEffect = first;
9838 } else {
9839 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
9840 currentFallbackChild.nextEffect = null;
9841 }
9842 currentFallbackChild.effectTag = Deletion;
9843 }
9844 }
9845 }
9846
9847 if (nextDidTimeout && !prevDidTimeout) {
9848 // If this subtreee is running in batched mode we can suspend,
9849 // otherwise we won't suspend.
9850 // TODO: This will still suspend a synchronous tree if anything
9851 // in the concurrent tree already suspended during this render.
9852 // This is a known bug.
9853 if ((workInProgress.mode & BatchedMode) !== NoMode) {
9854 // TODO: Move this back to throwException because this is too late
9855 // if this is a large tree which is common for initial loads. We
9856 // don't know if we should restart a render or not until we get
9857 // this marker, and this is too late.
9858 // If this render already had a ping or lower pri updates,
9859 // and this is the first time we know we're going to suspend we
9860 // should be able to immediately restart from within throwException.
9861 var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true;
9862 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
9863 // If this was in an invisible tree or a new render, then showing
9864 // this boundary is ok.
9865 renderDidSuspend();
9866 } else {
9867 // Otherwise, we're going to have to hide content so we should
9868 // suspend for longer if possible.
9869 renderDidSuspendDelayIfPossible();
9870 }
9871 }
9872 }
9873
9874 if (supportsPersistence) {
9875 // TODO: Only schedule updates if not prevDidTimeout.
9876 if (nextDidTimeout) {
9877 // If this boundary just timed out, schedule an effect to attach a
9878 // retry listener to the proimse. This flag is also used to hide the
9879 // primary children.
9880 workInProgress.effectTag |= Update;
9881 }
9882 }
9883 if (supportsMutation) {
9884 // TODO: Only schedule updates if these values are non equal, i.e. it changed.
9885 if (nextDidTimeout || prevDidTimeout) {
9886 // If this boundary just timed out, schedule an effect to attach a
9887 // retry listener to the proimse. This flag is also used to hide the
9888 // primary children. In mutation mode, we also need the flag to
9889 // *unhide* children that were previously hidden, so check if the
9890 // is currently timed out, too.
9891 workInProgress.effectTag |= Update;
9892 }
9893 }
9894 if (enableSuspenseCallback && workInProgress.updateQueue !== null && workInProgress.memoizedProps.suspenseCallback != null) {
9895 // Always notify the callback
9896 workInProgress.effectTag |= Update;
9897 }
9898 break;
9899 }
9900 case Fragment:
9901 break;
9902 case Mode:
9903 break;
9904 case Profiler:
9905 break;
9906 case HostPortal:
9907 popHostContainer(workInProgress);
9908 updateHostContainer(workInProgress);
9909 break;
9910 case ContextProvider:
9911 // Pop provider fiber
9912 popProvider(workInProgress);
9913 break;
9914 case ContextConsumer:
9915 break;
9916 case MemoComponent:
9917 break;
9918 case IncompleteClassComponent:
9919 {
9920 // Same as class component case. I put it down here so that the tags are
9921 // sequential to ensure this switch is compiled to a jump table.
9922 var _Component = workInProgress.type;
9923 if (isContextProvider(_Component)) {
9924 popContext(workInProgress);
9925 }
9926 break;
9927 }
9928 case DehydratedSuspenseComponent:
9929 {
9930 if (enableSuspenseServerRenderer) {
9931 popSuspenseContext(workInProgress);
9932 if (current === null) {
9933 var _wasHydrated2 = popHydrationState(workInProgress);
9934 (function () {
9935 if (!_wasHydrated2) {
9936 {
9937 throw ReactError(Error('A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.'));
9938 }
9939 }
9940 })();
9941 if (enableSchedulerTracing) {
9942 markSpawnedWork(Never);
9943 }
9944 skipPastDehydratedSuspenseInstance(workInProgress);
9945 } else if ((workInProgress.effectTag & DidCapture) === NoEffect) {
9946 // This boundary did not suspend so it's now hydrated.
9947 // To handle any future suspense cases, we're going to now upgrade it
9948 // to a Suspense component. We detach it from the existing current fiber.
9949 current.alternate = null;
9950 workInProgress.alternate = null;
9951 workInProgress.tag = SuspenseComponent;
9952 workInProgress.memoizedState = null;
9953 workInProgress.stateNode = null;
9954 }
9955 }
9956 break;
9957 }
9958 case SuspenseListComponent:
9959 {
9960 popSuspenseContext(workInProgress);
9961
9962 var renderState = workInProgress.memoizedState;
9963
9964 if (renderState === null) {
9965 // We're running in the default, "independent" mode. We don't do anything
9966 // in this mode.
9967 break;
9968 }
9969
9970 var didSuspendAlready = (workInProgress.effectTag & DidCapture) !== NoEffect;
9971
9972 var renderedTail = renderState.rendering;
9973 if (renderedTail === null) {
9974 // We just rendered the head.
9975 if (!didSuspendAlready) {
9976 // This is the first pass. We need to figure out if anything is still
9977 // suspended in the rendered set.
9978
9979 // If new content unsuspended, but there's still some content that
9980 // didn't. Then we need to do a second pass that forces everything
9981 // to keep showing their fallbacks.
9982
9983 // We might be suspended if something in this render pass suspended, or
9984 // something in the previous committed pass suspended. Otherwise,
9985 // there's no chance so we can skip the expensive call to
9986 // findFirstSuspended.
9987 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.effectTag & DidCapture) === NoEffect);
9988 if (!cannotBeSuspended) {
9989 var row = workInProgress.child;
9990 while (row !== null) {
9991 var suspended = findFirstSuspended(row);
9992 if (suspended !== null) {
9993 didSuspendAlready = true;
9994 workInProgress.effectTag |= DidCapture;
9995 cutOffTailIfNeeded(renderState, false);
9996
9997 // If this is a newly suspended tree, it might not get committed as
9998 // part of the second pass. In that case nothing will subscribe to
9999 // its thennables. Instead, we'll transfer its thennables to the
10000 // SuspenseList so that it can retry if they resolve.
10001 // There might be multiple of these in the list but since we're
10002 // going to wait for all of them anyway, it doesn't really matter
10003 // which ones gets to ping. In theory we could get clever and keep
10004 // track of how many dependencies remain but it gets tricky because
10005 // in the meantime, we can add/remove/change items and dependencies.
10006 // We might bail out of the loop before finding any but that
10007 // doesn't matter since that means that the other boundaries that
10008 // we did find already has their listeners attached.
10009 var newThennables = suspended.updateQueue;
10010 if (newThennables !== null) {
10011 workInProgress.updateQueue = newThennables;
10012 workInProgress.effectTag |= Update;
10013 }
10014
10015 // Rerender the whole list, but this time, we'll force fallbacks
10016 // to stay in place.
10017 // Reset the effect list before doing the second pass since that's now invalid.
10018 workInProgress.firstEffect = workInProgress.lastEffect = null;
10019 // Reset the child fibers to their original state.
10020 resetChildFibers(workInProgress, renderExpirationTime);
10021
10022 // Set up the Suspense Context to force suspense and immediately
10023 // rerender the children.
10024 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
10025 return workInProgress.child;
10026 }
10027 row = row.sibling;
10028 }
10029 }
10030 } else {
10031 cutOffTailIfNeeded(renderState, false);
10032 }
10033 // Next we're going to render the tail.
10034 } else {
10035 // Append the rendered row to the child list.
10036 if (!didSuspendAlready) {
10037 var _suspended = findFirstSuspended(renderedTail);
10038 if (_suspended !== null) {
10039 workInProgress.effectTag |= DidCapture;
10040 didSuspendAlready = true;
10041 cutOffTailIfNeeded(renderState, true);
10042 // This might have been modified.
10043 if (renderState.tail === null && renderState.tailMode === 'hidden') {
10044 // We need to delete the row we just rendered.
10045 // Ensure we transfer the update queue to the parent.
10046 var _newThennables = _suspended.updateQueue;
10047 if (_newThennables !== null) {
10048 workInProgress.updateQueue = _newThennables;
10049 workInProgress.effectTag |= Update;
10050 }
10051 // Reset the effect list to what it w as before we rendered this
10052 // child. The nested children have already appended themselves.
10053 var lastEffect = workInProgress.lastEffect = renderState.lastEffect;
10054 // Remove any effects that were appended after this point.
10055 if (lastEffect !== null) {
10056 lastEffect.nextEffect = null;
10057 }
10058 // We're done.
10059 return null;
10060 }
10061 } else if (now() > renderState.tailExpiration && renderExpirationTime > Never) {
10062 // We have now passed our CPU deadline and we'll just give up further
10063 // attempts to render the main content and only render fallbacks.
10064 // The assumption is that this is usually faster.
10065 workInProgress.effectTag |= DidCapture;
10066 didSuspendAlready = true;
10067
10068 cutOffTailIfNeeded(renderState, false);
10069
10070 // Since nothing actually suspended, there will nothing to ping this
10071 // to get it started back up to attempt the next item. If we can show
10072 // them, then they really have the same priority as this render.
10073 // So we'll pick it back up the very next render pass once we've had
10074 // an opportunity to yield for paint.
10075
10076 var nextPriority = renderExpirationTime - 1;
10077 workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority;
10078 if (enableSchedulerTracing) {
10079 markSpawnedWork(nextPriority);
10080 }
10081 }
10082 }
10083 if (renderState.isBackwards) {
10084 // The effect list of the backwards tail will have been added
10085 // to the end. This breaks the guarantee that life-cycles fire in
10086 // sibling order but that isn't a strong guarantee promised by React.
10087 // Especially since these might also just pop in during future commits.
10088 // Append to the beginning of the list.
10089 renderedTail.sibling = workInProgress.child;
10090 workInProgress.child = renderedTail;
10091 } else {
10092 var previousSibling = renderState.last;
10093 if (previousSibling !== null) {
10094 previousSibling.sibling = renderedTail;
10095 } else {
10096 workInProgress.child = renderedTail;
10097 }
10098 renderState.last = renderedTail;
10099 }
10100 }
10101
10102 if (renderState.tail !== null) {
10103 // We still have tail rows to render.
10104 if (renderState.tailExpiration === 0) {
10105 // Heuristic for how long we're willing to spend rendering rows
10106 // until we just give up and show what we have so far.
10107 var TAIL_EXPIRATION_TIMEOUT_MS = 500;
10108 renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS;
10109 }
10110 // Pop a row.
10111 var next = renderState.tail;
10112 renderState.rendering = next;
10113 renderState.tail = next.sibling;
10114 renderState.lastEffect = workInProgress.lastEffect;
10115 next.sibling = null;
10116
10117 // Restore the context.
10118 // TODO: We can probably just avoid popping it instead and only
10119 // setting it the first time we go from not suspended to suspended.
10120 var suspenseContext = suspenseStackCursor.current;
10121 if (didSuspendAlready) {
10122 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
10123 } else {
10124 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
10125 }
10126 pushSuspenseContext(workInProgress, suspenseContext);
10127 // Do a pass over the next row.
10128 return next;
10129 }
10130 break;
10131 }
10132 case FundamentalComponent:
10133 {
10134 if (enableFundamentalAPI) {
10135 var fundamentalImpl = workInProgress.type.impl;
10136 var fundamentalInstance = workInProgress.stateNode;
10137
10138 if (fundamentalInstance === null) {
10139 var getInitialState = fundamentalImpl.getInitialState;
10140 var fundamentalState = void 0;
10141 if (getInitialState !== undefined) {
10142 fundamentalState = getInitialState(newProps);
10143 }
10144 fundamentalInstance = workInProgress.stateNode = createFundamentalStateInstance(workInProgress, newProps, fundamentalImpl, fundamentalState || {});
10145 var _instance6 = getFundamentalComponentInstance(fundamentalInstance);
10146 fundamentalInstance.instance = _instance6;
10147 if (fundamentalImpl.reconcileChildren === false) {
10148 return null;
10149 }
10150 appendAllChildren(_instance6, workInProgress, false, false);
10151 mountFundamentalComponent(fundamentalInstance);
10152 } else {
10153 // We fire update in commit phase
10154 var prevProps = fundamentalInstance.props;
10155 fundamentalInstance.prevProps = prevProps;
10156 fundamentalInstance.props = newProps;
10157 fundamentalInstance.currentFiber = workInProgress;
10158 if (supportsPersistence) {
10159 var _instance7 = cloneFundamentalInstance(fundamentalInstance);
10160 fundamentalInstance.instance = _instance7;
10161 appendAllChildren(_instance7, workInProgress, false, false);
10162 }
10163 var shouldUpdate = shouldUpdateFundamentalComponent(fundamentalInstance);
10164 if (shouldUpdate) {
10165 markUpdate(workInProgress);
10166 }
10167 }
10168 }
10169 break;
10170 }
10171 default:
10172 (function () {
10173 {
10174 {
10175 throw ReactError(Error('Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.'));
10176 }
10177 }
10178 })();
10179 }
10180
10181 return null;
10182}
10183
10184function mountEventResponder(responder, responderProps, instance, rootContainerInstance, fiber, respondersMap) {
10185 var responderState = emptyObject;
10186 var getInitialState = responder.getInitialState;
10187 if (getInitialState !== null) {
10188 responderState = getInitialState(responderProps);
10189 }
10190 var responderInstance = createResponderInstance(responder, responderProps, responderState, instance, fiber);
10191 respondersMap.set(responder, responderInstance);
10192}
10193
10194function updateEventListener(listener, fiber, visistedResponders, respondersMap, instance, rootContainerInstance) {
10195 var responder = void 0;
10196 var props = void 0;
10197
10198 if (listener) {
10199 responder = listener.responder;
10200 props = listener.props;
10201 }
10202 (function () {
10203 if (!(responder && responder.$$typeof === REACT_RESPONDER_TYPE)) {
10204 {
10205 throw ReactError(Error('An invalid value was used as an event listener. Expect one or many event listeners created via React.unstable_useResponer().'));
10206 }
10207 }
10208 })();
10209 var listenerProps = props;
10210 if (visistedResponders.has(responder)) {
10211 // show warning
10212 {
10213 warning$1(false, 'Duplicate event responder "%s" found in event listeners. ' + 'Event listeners passed to elements cannot use the same event responder more than once.', responder.displayName);
10214 }
10215 return;
10216 }
10217 visistedResponders.add(responder);
10218 var responderInstance = respondersMap.get(responder);
10219
10220 if (responderInstance === undefined) {
10221 // Mount
10222 mountEventResponder(responder, listenerProps, instance, rootContainerInstance, fiber, respondersMap);
10223 } else {
10224 // Update
10225 responderInstance.props = listenerProps;
10226 responderInstance.fiber = fiber;
10227 }
10228}
10229
10230function updateEventListeners(listeners, instance, rootContainerInstance, fiber) {
10231 var visistedResponders = new Set();
10232 var dependencies = fiber.dependencies;
10233 if (listeners != null) {
10234 if (dependencies === null) {
10235 dependencies = fiber.dependencies = {
10236 expirationTime: NoWork,
10237 firstContext: null,
10238 responders: new Map()
10239 };
10240 }
10241 var respondersMap = dependencies.responders;
10242 if (respondersMap === null) {
10243 respondersMap = new Map();
10244 }
10245 if (isArray$2(listeners)) {
10246 for (var i = 0, length = listeners.length; i < length; i++) {
10247 var listener = listeners[i];
10248 updateEventListener(listener, fiber, visistedResponders, respondersMap, instance, rootContainerInstance);
10249 }
10250 } else {
10251 updateEventListener(listeners, fiber, visistedResponders, respondersMap, instance, rootContainerInstance);
10252 }
10253 }
10254 if (dependencies !== null) {
10255 var _respondersMap = dependencies.responders;
10256 if (_respondersMap !== null) {
10257 // Unmount
10258 var mountedResponders = Array.from(_respondersMap.keys());
10259 for (var _i = 0, _length = mountedResponders.length; _i < _length; _i++) {
10260 var mountedResponder = mountedResponders[_i];
10261 if (!visistedResponders.has(mountedResponder)) {
10262 var responderInstance = _respondersMap.get(mountedResponder);
10263 _respondersMap.delete(mountedResponder);
10264 }
10265 }
10266 }
10267 }
10268}
10269
10270function unwindWork(workInProgress, renderExpirationTime) {
10271 switch (workInProgress.tag) {
10272 case ClassComponent:
10273 {
10274 var Component = workInProgress.type;
10275 if (isContextProvider(Component)) {
10276 popContext(workInProgress);
10277 }
10278 var effectTag = workInProgress.effectTag;
10279 if (effectTag & ShouldCapture) {
10280 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
10281 return workInProgress;
10282 }
10283 return null;
10284 }
10285 case HostRoot:
10286 {
10287 popHostContainer(workInProgress);
10288 popTopLevelContextObject(workInProgress);
10289 var _effectTag = workInProgress.effectTag;
10290 (function () {
10291 if (!((_effectTag & DidCapture) === NoEffect)) {
10292 {
10293 throw ReactError(Error('The root failed to unmount after an error. This is likely a bug in React. Please file an issue.'));
10294 }
10295 }
10296 })();
10297 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
10298 return workInProgress;
10299 }
10300 case HostComponent:
10301 {
10302 // TODO: popHydrationState
10303 popHostContext(workInProgress);
10304 return null;
10305 }
10306 case SuspenseComponent:
10307 {
10308 popSuspenseContext(workInProgress);
10309 var _effectTag2 = workInProgress.effectTag;
10310 if (_effectTag2 & ShouldCapture) {
10311 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture;
10312 // Captured a suspense effect. Re-render the boundary.
10313 return workInProgress;
10314 }
10315 return null;
10316 }
10317 case DehydratedSuspenseComponent:
10318 {
10319 if (enableSuspenseServerRenderer) {
10320 // TODO: popHydrationState
10321 popSuspenseContext(workInProgress);
10322 var _effectTag3 = workInProgress.effectTag;
10323 if (_effectTag3 & ShouldCapture) {
10324 workInProgress.effectTag = _effectTag3 & ~ShouldCapture | DidCapture;
10325 // Captured a suspense effect. Re-render the boundary.
10326 return workInProgress;
10327 }
10328 }
10329 return null;
10330 }
10331 case SuspenseListComponent:
10332 {
10333 popSuspenseContext(workInProgress);
10334 // SuspenseList doesn't actually catch anything. It should've been
10335 // caught by a nested boundary. If not, it should bubble through.
10336 return null;
10337 }
10338 case HostPortal:
10339 popHostContainer(workInProgress);
10340 return null;
10341 case ContextProvider:
10342 popProvider(workInProgress);
10343 return null;
10344 default:
10345 return null;
10346 }
10347}
10348
10349function unwindInterruptedWork(interruptedWork) {
10350 switch (interruptedWork.tag) {
10351 case ClassComponent:
10352 {
10353 var childContextTypes = interruptedWork.type.childContextTypes;
10354 if (childContextTypes !== null && childContextTypes !== undefined) {
10355 popContext(interruptedWork);
10356 }
10357 break;
10358 }
10359 case HostRoot:
10360 {
10361 popHostContainer(interruptedWork);
10362 popTopLevelContextObject(interruptedWork);
10363 break;
10364 }
10365 case HostComponent:
10366 {
10367 popHostContext(interruptedWork);
10368 break;
10369 }
10370 case HostPortal:
10371 popHostContainer(interruptedWork);
10372 break;
10373 case SuspenseComponent:
10374 popSuspenseContext(interruptedWork);
10375 break;
10376 case DehydratedSuspenseComponent:
10377 if (enableSuspenseServerRenderer) {
10378 // TODO: popHydrationState
10379 popSuspenseContext(interruptedWork);
10380 }
10381 break;
10382 case SuspenseListComponent:
10383 popSuspenseContext(interruptedWork);
10384 break;
10385 case ContextProvider:
10386 popProvider(interruptedWork);
10387 break;
10388 default:
10389 break;
10390 }
10391}
10392
10393function createCapturedValue(value, source) {
10394 // If the value is an error, call this function immediately after it is thrown
10395 // so the stack is accurate.
10396 return {
10397 value: value,
10398 source: source,
10399 stack: getStackByFiberInDevAndProd(source)
10400 };
10401}
10402
10403var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
10404 var funcArgs = Array.prototype.slice.call(arguments, 3);
10405 try {
10406 func.apply(context, funcArgs);
10407 } catch (error) {
10408 this.onError(error);
10409 }
10410};
10411
10412{
10413 // In DEV mode, we swap out invokeGuardedCallback for a special version
10414 // that plays more nicely with the browser's DevTools. The idea is to preserve
10415 // "Pause on exceptions" behavior. Because React wraps all user-provided
10416 // functions in invokeGuardedCallback, and the production version of
10417 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
10418 // like caught exceptions, and the DevTools won't pause unless the developer
10419 // takes the extra step of enabling pause on caught exceptions. This is
10420 // unintuitive, though, because even though React has caught the error, from
10421 // the developer's perspective, the error is uncaught.
10422 //
10423 // To preserve the expected "Pause on exceptions" behavior, we don't use a
10424 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
10425 // DOM node, and call the user-provided callback from inside an event handler
10426 // for that fake event. If the callback throws, the error is "captured" using
10427 // a global event handler. But because the error happens in a different
10428 // event loop context, it does not interrupt the normal program flow.
10429 // Effectively, this gives us try-catch behavior without actually using
10430 // try-catch. Neat!
10431
10432 // Check that the browser supports the APIs we need to implement our special
10433 // DEV version of invokeGuardedCallback
10434 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
10435 var fakeNode = document.createElement('react');
10436
10437 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
10438 // If document doesn't exist we know for sure we will crash in this method
10439 // when we call document.createEvent(). However this can cause confusing
10440 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
10441 // So we preemptively throw with a better message instead.
10442 (function () {
10443 if (!(typeof document !== 'undefined')) {
10444 {
10445 throw ReactError(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.'));
10446 }
10447 }
10448 })();
10449 var evt = document.createEvent('Event');
10450
10451 // Keeps track of whether the user-provided callback threw an error. We
10452 // set this to true at the beginning, then set it to false right after
10453 // calling the function. If the function errors, `didError` will never be
10454 // set to false. This strategy works even if the browser is flaky and
10455 // fails to call our global error handler, because it doesn't rely on
10456 // the error event at all.
10457 var didError = true;
10458
10459 // Keeps track of the value of window.event so that we can reset it
10460 // during the callback to let user code access window.event in the
10461 // browsers that support it.
10462 var windowEvent = window.event;
10463
10464 // Keeps track of the descriptor of window.event to restore it after event
10465 // dispatching: https://github.com/facebook/react/issues/13688
10466 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
10467
10468 // Create an event handler for our fake event. We will synchronously
10469 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
10470 // call the user-provided callback.
10471 var funcArgs = Array.prototype.slice.call(arguments, 3);
10472 function callCallback() {
10473 // We immediately remove the callback from event listeners so that
10474 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
10475 // nested call would trigger the fake event handlers of any call higher
10476 // in the stack.
10477 fakeNode.removeEventListener(evtType, callCallback, false);
10478
10479 // We check for window.hasOwnProperty('event') to prevent the
10480 // window.event assignment in both IE <= 10 as they throw an error
10481 // "Member not found" in strict mode, and in Firefox which does not
10482 // support window.event.
10483 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
10484 window.event = windowEvent;
10485 }
10486
10487 func.apply(context, funcArgs);
10488 didError = false;
10489 }
10490
10491 // Create a global error event handler. We use this to capture the value
10492 // that was thrown. It's possible that this error handler will fire more
10493 // than once; for example, if non-React code also calls `dispatchEvent`
10494 // and a handler for that event throws. We should be resilient to most of
10495 // those cases. Even if our error event handler fires more than once, the
10496 // last error event is always used. If the callback actually does error,
10497 // we know that the last error event is the correct one, because it's not
10498 // possible for anything else to have happened in between our callback
10499 // erroring and the code that follows the `dispatchEvent` call below. If
10500 // the callback doesn't error, but the error event was fired, we know to
10501 // ignore it because `didError` will be false, as described above.
10502 var error = void 0;
10503 // Use this to track whether the error event is ever called.
10504 var didSetError = false;
10505 var isCrossOriginError = false;
10506
10507 function handleWindowError(event) {
10508 error = event.error;
10509 didSetError = true;
10510 if (error === null && event.colno === 0 && event.lineno === 0) {
10511 isCrossOriginError = true;
10512 }
10513 if (event.defaultPrevented) {
10514 // Some other error handler has prevented default.
10515 // Browsers silence the error report if this happens.
10516 // We'll remember this to later decide whether to log it or not.
10517 if (error != null && typeof error === 'object') {
10518 try {
10519 error._suppressLogging = true;
10520 } catch (inner) {
10521 // Ignore.
10522 }
10523 }
10524 }
10525 }
10526
10527 // Create a fake event type.
10528 var evtType = 'react-' + (name ? name : 'invokeguardedcallback');
10529
10530 // Attach our event handlers
10531 window.addEventListener('error', handleWindowError);
10532 fakeNode.addEventListener(evtType, callCallback, false);
10533
10534 // Synchronously dispatch our fake event. If the user-provided function
10535 // errors, it will trigger our global error handler.
10536 evt.initEvent(evtType, false, false);
10537 fakeNode.dispatchEvent(evt);
10538
10539 if (windowEventDescriptor) {
10540 Object.defineProperty(window, 'event', windowEventDescriptor);
10541 }
10542
10543 if (didError) {
10544 if (!didSetError) {
10545 // The callback errored, but the error event never fired.
10546 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.');
10547 } else if (isCrossOriginError) {
10548 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.');
10549 }
10550 this.onError(error);
10551 }
10552
10553 // Remove our event listeners
10554 window.removeEventListener('error', handleWindowError);
10555 };
10556
10557 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
10558 }
10559}
10560
10561var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
10562
10563// Used by Fiber to simulate a try-catch.
10564var hasError = false;
10565var caughtError = null;
10566
10567var reporter = {
10568 onError: function (error) {
10569 hasError = true;
10570 caughtError = error;
10571 }
10572};
10573
10574/**
10575 * Call a function while guarding against errors that happens within it.
10576 * Returns an error if it throws, otherwise null.
10577 *
10578 * In production, this is implemented using a try-catch. The reason we don't
10579 * use a try-catch directly is so that we can swap out a different
10580 * implementation in DEV mode.
10581 *
10582 * @param {String} name of the guard to use for logging or debugging
10583 * @param {Function} func The function to invoke
10584 * @param {*} context The context to use when calling the function
10585 * @param {...*} args Arguments for function
10586 */
10587function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
10588 hasError = false;
10589 caughtError = null;
10590 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
10591}
10592
10593/**
10594 * Same as invokeGuardedCallback, but instead of returning an error, it stores
10595 * it in a global so it can be rethrown by `rethrowCaughtError` later.
10596 * TODO: See if caughtError and rethrowError can be unified.
10597 *
10598 * @param {String} name of the guard to use for logging or debugging
10599 * @param {Function} func The function to invoke
10600 * @param {*} context The context to use when calling the function
10601 * @param {...*} args Arguments for function
10602 */
10603
10604
10605/**
10606 * During execution of guarded functions we will capture the first error which
10607 * we will rethrow to be handled by the top level error handler.
10608 */
10609
10610
10611function hasCaughtError() {
10612 return hasError;
10613}
10614
10615function clearCaughtError() {
10616 if (hasError) {
10617 var error = caughtError;
10618 hasError = false;
10619 caughtError = null;
10620 return error;
10621 } else {
10622 (function () {
10623 {
10624 {
10625 throw ReactError(Error('clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.'));
10626 }
10627 }
10628 })();
10629 }
10630}
10631
10632// This module is forked in different environments.
10633// By default, return `true` to log errors to the console.
10634// Forks can return `false` if this isn't desirable.
10635function showErrorDialog(capturedError) {
10636 return true;
10637}
10638
10639function logCapturedError(capturedError) {
10640 var logError = showErrorDialog(capturedError);
10641
10642 // Allow injected showErrorDialog() to prevent default console.error logging.
10643 // This enables renderers like ReactNative to better manage redbox behavior.
10644 if (logError === false) {
10645 return;
10646 }
10647
10648 var error = capturedError.error;
10649 {
10650 var componentName = capturedError.componentName,
10651 componentStack = capturedError.componentStack,
10652 errorBoundaryName = capturedError.errorBoundaryName,
10653 errorBoundaryFound = capturedError.errorBoundaryFound,
10654 willRetry = capturedError.willRetry;
10655
10656 // Browsers support silencing uncaught errors by calling
10657 // `preventDefault()` in window `error` handler.
10658 // We record this information as an expando on the error.
10659
10660 if (error != null && error._suppressLogging) {
10661 if (errorBoundaryFound && willRetry) {
10662 // The error is recoverable and was silenced.
10663 // Ignore it and don't print the stack addendum.
10664 // This is handy for testing error boundaries without noise.
10665 return;
10666 }
10667 // The error is fatal. Since the silencing might have
10668 // been accidental, we'll surface it anyway.
10669 // However, the browser would have silenced the original error
10670 // so we'll print it first, and then print the stack addendum.
10671 console.error(error);
10672 // For a more detailed description of this block, see:
10673 // https://github.com/facebook/react/pull/13384
10674 }
10675
10676 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
10677
10678 var errorBoundaryMessage = void 0;
10679 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
10680 if (errorBoundaryFound && errorBoundaryName) {
10681 if (willRetry) {
10682 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
10683 } else {
10684 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
10685 }
10686 } else {
10687 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.';
10688 }
10689 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
10690
10691 // In development, we provide our own message with just the component stack.
10692 // We don't include the original error message and JS stack because the browser
10693 // has already printed it. Even if the application swallows the error, it is still
10694 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
10695 console.error(combinedMessage);
10696 }
10697}
10698
10699var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
10700{
10701 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
10702}
10703
10704var PossiblyWeakSet$1 = typeof WeakSet === 'function' ? WeakSet : Set;
10705
10706function logError(boundary, errorInfo) {
10707 var source = errorInfo.source;
10708 var stack = errorInfo.stack;
10709 if (stack === null && source !== null) {
10710 stack = getStackByFiberInDevAndProd(source);
10711 }
10712
10713 var capturedError = {
10714 componentName: source !== null ? getComponentName(source.type) : null,
10715 componentStack: stack !== null ? stack : '',
10716 error: errorInfo.value,
10717 errorBoundary: null,
10718 errorBoundaryName: null,
10719 errorBoundaryFound: false,
10720 willRetry: false
10721 };
10722
10723 if (boundary !== null && boundary.tag === ClassComponent) {
10724 capturedError.errorBoundary = boundary.stateNode;
10725 capturedError.errorBoundaryName = getComponentName(boundary.type);
10726 capturedError.errorBoundaryFound = true;
10727 capturedError.willRetry = true;
10728 }
10729
10730 try {
10731 logCapturedError(capturedError);
10732 } catch (e) {
10733 // This method must not throw, or React internal state will get messed up.
10734 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
10735 // we want to report this error outside of the normal stack as a last resort.
10736 // https://github.com/facebook/react/issues/13188
10737 setTimeout(function () {
10738 throw e;
10739 });
10740 }
10741}
10742
10743var callComponentWillUnmountWithTimer = function (current$$1, instance) {
10744 startPhaseTimer(current$$1, 'componentWillUnmount');
10745 instance.props = current$$1.memoizedProps;
10746 instance.state = current$$1.memoizedState;
10747 instance.componentWillUnmount();
10748 stopPhaseTimer();
10749};
10750
10751// Capture errors so they don't interrupt unmounting.
10752function safelyCallComponentWillUnmount(current$$1, instance) {
10753 {
10754 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current$$1, instance);
10755 if (hasCaughtError()) {
10756 var unmountError = clearCaughtError();
10757 captureCommitPhaseError(current$$1, unmountError);
10758 }
10759 }
10760}
10761
10762function safelyDetachRef(current$$1) {
10763 var ref = current$$1.ref;
10764 if (ref !== null) {
10765 if (typeof ref === 'function') {
10766 {
10767 invokeGuardedCallback(null, ref, null, null);
10768 if (hasCaughtError()) {
10769 var refError = clearCaughtError();
10770 captureCommitPhaseError(current$$1, refError);
10771 }
10772 }
10773 } else {
10774 ref.current = null;
10775 }
10776 }
10777}
10778
10779function safelyCallDestroy(current$$1, destroy) {
10780 {
10781 invokeGuardedCallback(null, destroy, null);
10782 if (hasCaughtError()) {
10783 var error = clearCaughtError();
10784 captureCommitPhaseError(current$$1, error);
10785 }
10786 }
10787}
10788
10789function commitBeforeMutationLifeCycles(current$$1, finishedWork) {
10790 switch (finishedWork.tag) {
10791 case FunctionComponent:
10792 case ForwardRef:
10793 case SimpleMemoComponent:
10794 {
10795 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
10796 return;
10797 }
10798 case ClassComponent:
10799 {
10800 if (finishedWork.effectTag & Snapshot) {
10801 if (current$$1 !== null) {
10802 var prevProps = current$$1.memoizedProps;
10803 var prevState = current$$1.memoizedState;
10804 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
10805 var instance = finishedWork.stateNode;
10806 // We could update instance props and state here,
10807 // but instead we rely on them being set during last render.
10808 // TODO: revisit this when we implement resuming.
10809 {
10810 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
10811 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, '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') : void 0;
10812 !(instance.state === finishedWork.memoizedState) ? warning$1(false, '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') : void 0;
10813 }
10814 }
10815 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
10816 {
10817 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
10818 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
10819 didWarnSet.add(finishedWork.type);
10820 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
10821 }
10822 }
10823 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
10824 stopPhaseTimer();
10825 }
10826 }
10827 return;
10828 }
10829 case HostRoot:
10830 case HostComponent:
10831 case HostText:
10832 case HostPortal:
10833 case IncompleteClassComponent:
10834 // Nothing to do for these component types
10835 return;
10836 default:
10837 {
10838 (function () {
10839 {
10840 {
10841 throw ReactError(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.'));
10842 }
10843 }
10844 })();
10845 }
10846 }
10847}
10848
10849function commitHookEffectList(unmountTag, mountTag, finishedWork) {
10850 var updateQueue = finishedWork.updateQueue;
10851 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
10852 if (lastEffect !== null) {
10853 var firstEffect = lastEffect.next;
10854 var effect = firstEffect;
10855 do {
10856 if ((effect.tag & unmountTag) !== NoEffect$1) {
10857 // Unmount
10858 var destroy = effect.destroy;
10859 effect.destroy = undefined;
10860 if (destroy !== undefined) {
10861 destroy();
10862 }
10863 }
10864 if ((effect.tag & mountTag) !== NoEffect$1) {
10865 // Mount
10866 var create = effect.create;
10867 effect.destroy = create();
10868
10869 {
10870 var _destroy = effect.destroy;
10871 if (_destroy !== undefined && typeof _destroy !== 'function') {
10872 var addendum = void 0;
10873 if (_destroy === null) {
10874 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
10875 } else if (typeof _destroy.then === 'function') {
10876 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';
10877 } else {
10878 addendum = ' You returned: ' + _destroy;
10879 }
10880 warningWithoutStack$1(false, 'An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
10881 }
10882 }
10883 }
10884 effect = effect.next;
10885 } while (effect !== firstEffect);
10886 }
10887}
10888
10889function commitPassiveHookEffects(finishedWork) {
10890 if ((finishedWork.effectTag & Passive) !== NoEffect) {
10891 switch (finishedWork.tag) {
10892 case FunctionComponent:
10893 case ForwardRef:
10894 case SimpleMemoComponent:
10895 {
10896 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
10897 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
10898 break;
10899 }
10900 default:
10901 break;
10902 }
10903 }
10904}
10905
10906function commitLifeCycles(finishedRoot, current$$1, finishedWork, committedExpirationTime) {
10907 switch (finishedWork.tag) {
10908 case FunctionComponent:
10909 case ForwardRef:
10910 case SimpleMemoComponent:
10911 {
10912 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
10913 break;
10914 }
10915 case ClassComponent:
10916 {
10917 var instance = finishedWork.stateNode;
10918 if (finishedWork.effectTag & Update) {
10919 if (current$$1 === null) {
10920 startPhaseTimer(finishedWork, 'componentDidMount');
10921 // We could update instance props and state here,
10922 // but instead we rely on them being set during last render.
10923 // TODO: revisit this when we implement resuming.
10924 {
10925 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
10926 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, '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') : void 0;
10927 !(instance.state === finishedWork.memoizedState) ? warning$1(false, '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') : void 0;
10928 }
10929 }
10930 instance.componentDidMount();
10931 stopPhaseTimer();
10932 } else {
10933 var prevProps = finishedWork.elementType === finishedWork.type ? current$$1.memoizedProps : resolveDefaultProps(finishedWork.type, current$$1.memoizedProps);
10934 var prevState = current$$1.memoizedState;
10935 startPhaseTimer(finishedWork, 'componentDidUpdate');
10936 // We could update instance props and state here,
10937 // but instead we rely on them being set during last render.
10938 // TODO: revisit this when we implement resuming.
10939 {
10940 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
10941 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, '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') : void 0;
10942 !(instance.state === finishedWork.memoizedState) ? warning$1(false, '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') : void 0;
10943 }
10944 }
10945 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
10946 stopPhaseTimer();
10947 }
10948 }
10949 var updateQueue = finishedWork.updateQueue;
10950 if (updateQueue !== null) {
10951 {
10952 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
10953 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, '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') : void 0;
10954 !(instance.state === finishedWork.memoizedState) ? warning$1(false, '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') : void 0;
10955 }
10956 }
10957 // We could update instance props and state here,
10958 // but instead we rely on them being set during last render.
10959 // TODO: revisit this when we implement resuming.
10960 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
10961 }
10962 return;
10963 }
10964 case HostRoot:
10965 {
10966 var _updateQueue = finishedWork.updateQueue;
10967 if (_updateQueue !== null) {
10968 var _instance = null;
10969 if (finishedWork.child !== null) {
10970 switch (finishedWork.child.tag) {
10971 case HostComponent:
10972 _instance = getPublicInstance(finishedWork.child.stateNode);
10973 break;
10974 case ClassComponent:
10975 _instance = finishedWork.child.stateNode;
10976 break;
10977 }
10978 }
10979 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
10980 }
10981 return;
10982 }
10983 case HostComponent:
10984 {
10985 var _instance2 = finishedWork.stateNode;
10986
10987 // Renderers may schedule work to be done after host components are mounted
10988 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
10989 // These effects should only be committed when components are first mounted,
10990 // aka when there is no current/alternate.
10991 if (current$$1 === null && finishedWork.effectTag & Update) {
10992 var type = finishedWork.type;
10993 var props = finishedWork.memoizedProps;
10994
10995 }
10996
10997 return;
10998 }
10999 case HostText:
11000 {
11001 // We have no life-cycles associated with text.
11002 return;
11003 }
11004 case HostPortal:
11005 {
11006 // We have no life-cycles associated with portals.
11007 return;
11008 }
11009 case Profiler:
11010 {
11011 if (enableProfilerTimer) {
11012 var onRender = finishedWork.memoizedProps.onRender;
11013
11014 if (typeof onRender === 'function') {
11015 if (enableSchedulerTracing) {
11016 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
11017 } else {
11018 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
11019 }
11020 }
11021 }
11022 return;
11023 }
11024 case SuspenseComponent:
11025 case SuspenseListComponent:
11026 case IncompleteClassComponent:
11027 case FundamentalComponent:
11028 return;
11029 default:
11030 {
11031 (function () {
11032 {
11033 {
11034 throw ReactError(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.'));
11035 }
11036 }
11037 })();
11038 }
11039 }
11040}
11041
11042function hideOrUnhideAllChildren(finishedWork, isHidden) {
11043 if (supportsMutation) {
11044 // We only have the top Fiber that was inserted but we need to recurse down its
11045 var node = finishedWork;
11046 while (true) {
11047 if (node.tag === HostComponent) {
11048 var instance = node.stateNode;
11049 if (isHidden) {
11050 hideInstance(instance);
11051 } else {
11052 unhideInstance(node.stateNode, node.memoizedProps);
11053 }
11054 } else if (node.tag === HostText) {
11055 var _instance3 = node.stateNode;
11056 if (isHidden) {
11057 hideTextInstance(_instance3);
11058 } else {
11059 unhideTextInstance(_instance3, node.memoizedProps);
11060 }
11061 } else if (node.tag === SuspenseComponent && node.memoizedState !== null) {
11062 // Found a nested Suspense component that timed out. Skip over the
11063 var fallbackChildFragment = node.child.sibling;
11064 fallbackChildFragment.return = node;
11065 node = fallbackChildFragment;
11066 continue;
11067 } else if (node.child !== null) {
11068 node.child.return = node;
11069 node = node.child;
11070 continue;
11071 }
11072 if (node === finishedWork) {
11073 return;
11074 }
11075 while (node.sibling === null) {
11076 if (node.return === null || node.return === finishedWork) {
11077 return;
11078 }
11079 node = node.return;
11080 }
11081 node.sibling.return = node.return;
11082 node = node.sibling;
11083 }
11084 }
11085}
11086
11087function commitAttachRef(finishedWork) {
11088 var ref = finishedWork.ref;
11089 if (ref !== null) {
11090 var instance = finishedWork.stateNode;
11091 var instanceToUse = void 0;
11092 switch (finishedWork.tag) {
11093 case HostComponent:
11094 instanceToUse = getPublicInstance(instance);
11095 break;
11096 default:
11097 instanceToUse = instance;
11098 }
11099 if (typeof ref === 'function') {
11100 ref(instanceToUse);
11101 } else {
11102 {
11103 if (!ref.hasOwnProperty('current')) {
11104 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
11105 }
11106 }
11107
11108 ref.current = instanceToUse;
11109 }
11110 }
11111}
11112
11113function commitDetachRef(current$$1) {
11114 var currentRef = current$$1.ref;
11115 if (currentRef !== null) {
11116 if (typeof currentRef === 'function') {
11117 currentRef(null);
11118 } else {
11119 currentRef.current = null;
11120 }
11121 }
11122}
11123
11124// User-originating errors (lifecycles and refs) should not interrupt
11125// deletion, so don't let them throw. Host-originating errors should
11126// interrupt deletion, so it's okay
11127function commitUnmount(current$$1, renderPriorityLevel) {
11128 onCommitUnmount(current$$1);
11129
11130 switch (current$$1.tag) {
11131 case FunctionComponent:
11132 case ForwardRef:
11133 case MemoComponent:
11134 case SimpleMemoComponent:
11135 {
11136 var updateQueue = current$$1.updateQueue;
11137 if (updateQueue !== null) {
11138 var lastEffect = updateQueue.lastEffect;
11139 if (lastEffect !== null) {
11140 var firstEffect = lastEffect.next;
11141
11142 // When the owner fiber is deleted, the destroy function of a passive
11143 // effect hook is called during the synchronous commit phase. This is
11144 // a concession to implementation complexity. Calling it in the
11145 // passive effect phase (like they usually are, when dependencies
11146 // change during an update) would require either traversing the
11147 // children of the deleted fiber again, or including unmount effects
11148 // as part of the fiber effect list.
11149 //
11150 // Because this is during the sync commit phase, we need to change
11151 // the priority.
11152 //
11153 // TODO: Reconsider this implementation trade off.
11154 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
11155 runWithPriority(priorityLevel, function () {
11156 var effect = firstEffect;
11157 do {
11158 var destroy = effect.destroy;
11159 if (destroy !== undefined) {
11160 safelyCallDestroy(current$$1, destroy);
11161 }
11162 effect = effect.next;
11163 } while (effect !== firstEffect);
11164 });
11165 }
11166 }
11167 break;
11168 }
11169 case ClassComponent:
11170 {
11171 safelyDetachRef(current$$1);
11172 var instance = current$$1.stateNode;
11173 if (typeof instance.componentWillUnmount === 'function') {
11174 safelyCallComponentWillUnmount(current$$1, instance);
11175 }
11176 return;
11177 }
11178 case HostComponent:
11179 {
11180 if (enableFlareAPI) {
11181 var dependencies = current$$1.dependencies;
11182
11183 if (dependencies !== null) {
11184 var respondersMap = dependencies.responders;
11185 if (respondersMap !== null) {
11186 var responderInstances = Array.from(respondersMap.values());
11187 for (var i = 0, length = responderInstances.length; i < length; i++) {
11188 var responderInstance = responderInstances[i];
11189
11190 }
11191 dependencies.responders = null;
11192 }
11193 }
11194 }
11195 safelyDetachRef(current$$1);
11196 return;
11197 }
11198 case HostPortal:
11199 {
11200 // TODO: this is recursive.
11201 // We are also not using this parent because
11202 // the portal will get pushed immediately.
11203 if (supportsMutation) {
11204 unmountHostComponents(current$$1, renderPriorityLevel);
11205 } else if (supportsPersistence) {
11206 emptyPortalContainer(current$$1);
11207 }
11208 return;
11209 }
11210 case FundamentalComponent:
11211 {
11212 if (enableFundamentalAPI) {
11213 var fundamentalInstance = current$$1.stateNode;
11214 if (fundamentalInstance !== null) {
11215 unmountFundamentalComponent(fundamentalInstance);
11216 current$$1.stateNode = null;
11217 }
11218 }
11219 }
11220 }
11221}
11222
11223function commitNestedUnmounts(root, renderPriorityLevel) {
11224 // While we're inside a removed host node we don't want to call
11225 // removeChild on the inner nodes because they're removed by the top
11226 // call anyway. We also want to call componentWillUnmount on all
11227 // composites before this host node is removed from the tree. Therefore
11228 var node = root;
11229 while (true) {
11230 commitUnmount(node, renderPriorityLevel);
11231 // Visit children because they may contain more composite or host nodes.
11232 // Skip portals because commitUnmount() currently visits them recursively.
11233 if (node.child !== null && (
11234 // If we use mutation we drill down into portals using commitUnmount above.
11235 // If we don't use mutation we drill down into portals here instead.
11236 !supportsMutation || node.tag !== HostPortal)) {
11237 node.child.return = node;
11238 node = node.child;
11239 continue;
11240 }
11241 if (node === root) {
11242 return;
11243 }
11244 while (node.sibling === null) {
11245 if (node.return === null || node.return === root) {
11246 return;
11247 }
11248 node = node.return;
11249 }
11250 node.sibling.return = node.return;
11251 node = node.sibling;
11252 }
11253}
11254
11255function detachFiber(current$$1) {
11256 // Cut off the return pointers to disconnect it from the tree. Ideally, we
11257 // should clear the child pointer of the parent alternate to let this
11258 // get GC:ed but we don't know which for sure which parent is the current
11259 // one so we'll settle for GC:ing the subtree of this child. This child
11260 // itself will be GC:ed when the parent updates the next time.
11261 current$$1.return = null;
11262 current$$1.child = null;
11263 current$$1.memoizedState = null;
11264 current$$1.updateQueue = null;
11265 current$$1.dependencies = null;
11266 var alternate = current$$1.alternate;
11267 if (alternate !== null) {
11268 alternate.return = null;
11269 alternate.child = null;
11270 alternate.memoizedState = null;
11271 alternate.updateQueue = null;
11272 alternate.dependencies = null;
11273 }
11274}
11275
11276function emptyPortalContainer(current$$1) {
11277 if (!supportsPersistence) {
11278 return;
11279 }
11280
11281 var portal = current$$1.stateNode;
11282 var containerInfo = portal.containerInfo;
11283
11284 var emptyChildSet = createContainerChildSet(containerInfo);
11285 replaceContainerChildren(containerInfo, emptyChildSet);
11286}
11287
11288function commitContainer(finishedWork) {
11289 if (!supportsPersistence) {
11290 return;
11291 }
11292
11293 switch (finishedWork.tag) {
11294 case ClassComponent:
11295 case HostComponent:
11296 case HostText:
11297 case FundamentalComponent:
11298 {
11299 return;
11300 }
11301 case HostRoot:
11302 case HostPortal:
11303 {
11304 var portalOrRoot = finishedWork.stateNode;
11305 var containerInfo = portalOrRoot.containerInfo,
11306 _pendingChildren = portalOrRoot.pendingChildren;
11307
11308 replaceContainerChildren(containerInfo, _pendingChildren);
11309 return;
11310 }
11311 default:
11312 {
11313 (function () {
11314 {
11315 {
11316 throw ReactError(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.'));
11317 }
11318 }
11319 })();
11320 }
11321 }
11322}
11323
11324function getHostParentFiber(fiber) {
11325 var parent = fiber.return;
11326 while (parent !== null) {
11327 if (isHostParent(parent)) {
11328 return parent;
11329 }
11330 parent = parent.return;
11331 }
11332 (function () {
11333 {
11334 {
11335 throw ReactError(Error('Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.'));
11336 }
11337 }
11338 })();
11339}
11340
11341function isHostParent(fiber) {
11342 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
11343}
11344
11345function getHostSibling(fiber) {
11346 // We're going to search forward into the tree until we find a sibling host
11347 // node. Unfortunately, if multiple insertions are done in a row we have to
11348 // search past them. This leads to exponential search for the next sibling.
11349 var node = fiber;
11350 siblings: while (true) {
11351 // If we didn't find anything, let's try the next sibling.
11352 while (node.sibling === null) {
11353 if (node.return === null || isHostParent(node.return)) {
11354 // If we pop out of the root or hit the parent the fiber we are the
11355 // last sibling.
11356 return null;
11357 }
11358 node = node.return;
11359 }
11360 node.sibling.return = node.return;
11361 node = node.sibling;
11362 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedSuspenseComponent) {
11363 // If it is not host node and, we might have a host node inside it.
11364 // Try to search down until we find one.
11365 if (node.effectTag & Placement) {
11366 // If we don't have a child, try the siblings instead.
11367 continue siblings;
11368 }
11369 // If we don't have a child, try the siblings instead.
11370 // We also skip portals because they are not part of this host tree.
11371 if (node.child === null || node.tag === HostPortal) {
11372 continue siblings;
11373 } else {
11374 node.child.return = node;
11375 node = node.child;
11376 }
11377 }
11378 // Check if this host node is stable or about to be placed.
11379 if (!(node.effectTag & Placement)) {
11380 // Found it!
11381 return node.stateNode;
11382 }
11383 }
11384}
11385
11386function commitPlacement(finishedWork) {
11387 if (!supportsMutation) {
11388 return;
11389 }
11390
11391 // Recursively insert all host nodes into the parent.
11392 var parentFiber = getHostParentFiber(finishedWork);
11393
11394 // Note: these two variables *must* always be updated together.
11395 var parent = void 0;
11396 var isContainer = void 0;
11397 var parentStateNode = parentFiber.stateNode;
11398 switch (parentFiber.tag) {
11399 case HostComponent:
11400 parent = parentStateNode;
11401 isContainer = false;
11402 break;
11403 case HostRoot:
11404 parent = parentStateNode.containerInfo;
11405 isContainer = true;
11406 break;
11407 case HostPortal:
11408 parent = parentStateNode.containerInfo;
11409 isContainer = true;
11410 break;
11411 case FundamentalComponent:
11412 if (enableFundamentalAPI) {
11413 parent = parentStateNode.instance;
11414 isContainer = false;
11415 }
11416 // eslint-disable-next-line-no-fallthrough
11417 default:
11418 (function () {
11419 {
11420 {
11421 throw ReactError(Error('Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.'));
11422 }
11423 }
11424 })();
11425 }
11426 if (parentFiber.effectTag & ContentReset) {
11427 // Reset the text content of the parent before doing any insertions
11428 parentFiber.effectTag &= ~ContentReset;
11429 }
11430
11431 var before = getHostSibling(finishedWork);
11432 // We only have the top Fiber that was inserted but we need to recurse down its
11433 // children to find all the terminal nodes.
11434 var node = finishedWork;
11435 while (true) {
11436 var isHost = node.tag === HostComponent || node.tag === HostText;
11437 if (isHost || node.tag === FundamentalComponent) {
11438 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
11439 if (before) {
11440 if (isContainer) {
11441 insertInContainerBefore(parent, stateNode, before);
11442 } else {
11443 insertBefore(parent, stateNode, before);
11444 }
11445 } else {
11446 if (isContainer) {
11447 appendChildToContainer(parent, stateNode);
11448 } else {
11449 appendChild(parent, stateNode);
11450 }
11451 }
11452 } else if (node.tag === HostPortal) {
11453 // If the insertion itself is a portal, then we don't want to traverse
11454 // down its children. Instead, we'll get insertions from each child in
11455 // the portal directly.
11456 } else if (node.child !== null) {
11457 node.child.return = node;
11458 node = node.child;
11459 continue;
11460 }
11461 if (node === finishedWork) {
11462 return;
11463 }
11464 while (node.sibling === null) {
11465 if (node.return === null || node.return === finishedWork) {
11466 return;
11467 }
11468 node = node.return;
11469 }
11470 node.sibling.return = node.return;
11471 node = node.sibling;
11472 }
11473}
11474
11475function unmountHostComponents(current$$1, renderPriorityLevel) {
11476 // We only have the top Fiber that was deleted but we need to recurse down its
11477 var node = current$$1;
11478
11479 // Each iteration, currentParent is populated with node's host parent if not
11480 // currentParentIsValid.
11481 var currentParentIsValid = false;
11482
11483 // Note: these two variables *must* always be updated together.
11484 var currentParent = void 0;
11485 var currentParentIsContainer = void 0;
11486
11487 while (true) {
11488 if (!currentParentIsValid) {
11489 var parent = node.return;
11490 findParent: while (true) {
11491 (function () {
11492 if (!(parent !== null)) {
11493 {
11494 throw ReactError(Error('Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.'));
11495 }
11496 }
11497 })();
11498 var parentStateNode = parent.stateNode;
11499 switch (parent.tag) {
11500 case HostComponent:
11501 currentParent = parentStateNode;
11502 currentParentIsContainer = false;
11503 break findParent;
11504 case HostRoot:
11505 currentParent = parentStateNode.containerInfo;
11506 currentParentIsContainer = true;
11507 break findParent;
11508 case HostPortal:
11509 currentParent = parentStateNode.containerInfo;
11510 currentParentIsContainer = true;
11511 break findParent;
11512 case FundamentalComponent:
11513 if (enableFundamentalAPI) {
11514 currentParent = parentStateNode.instance;
11515 currentParentIsContainer = false;
11516 }
11517 }
11518 parent = parent.return;
11519 }
11520 currentParentIsValid = true;
11521 }
11522
11523 if (node.tag === HostComponent || node.tag === HostText) {
11524 commitNestedUnmounts(node, renderPriorityLevel);
11525 // After all the children have unmounted, it is now safe to remove the
11526 // node from the tree.
11527 if (currentParentIsContainer) {
11528 removeChildFromContainer(currentParent, node.stateNode);
11529 } else {
11530 removeChild(currentParent, node.stateNode);
11531 }
11532 // Don't visit children because we already visited them.
11533 } else if (node.tag === FundamentalComponent) {
11534 var fundamentalNode = node.stateNode.instance;
11535 commitNestedUnmounts(node, renderPriorityLevel);
11536 // After all the children have unmounted, it is now safe to remove the
11537 // node from the tree.
11538 if (currentParentIsContainer) {
11539 removeChildFromContainer(currentParent, fundamentalNode);
11540 } else {
11541 removeChild(currentParent, fundamentalNode);
11542 }
11543 } else if (enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent) {
11544 // Delete the dehydrated suspense boundary and all of its content.
11545 if (currentParentIsContainer) {
11546 clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
11547 } else {
11548 clearSuspenseBoundary(currentParent, node.stateNode);
11549 }
11550 } else if (node.tag === HostPortal) {
11551 if (node.child !== null) {
11552 // When we go into a portal, it becomes the parent to remove from.
11553 // We will reassign it back when we pop the portal on the way up.
11554 currentParent = node.stateNode.containerInfo;
11555 currentParentIsContainer = true;
11556 // Visit children because portals might contain host components.
11557 node.child.return = node;
11558 node = node.child;
11559 continue;
11560 }
11561 } else {
11562 commitUnmount(node, renderPriorityLevel);
11563 // Visit children because we may find more host components below.
11564 if (node.child !== null) {
11565 node.child.return = node;
11566 node = node.child;
11567 continue;
11568 }
11569 }
11570 if (node === current$$1) {
11571 return;
11572 }
11573 while (node.sibling === null) {
11574 if (node.return === null || node.return === current$$1) {
11575 return;
11576 }
11577 node = node.return;
11578 if (node.tag === HostPortal) {
11579 // When we go out of the portal, we need to restore the parent.
11580 // Since we don't keep a stack of them, we will search for it.
11581 currentParentIsValid = false;
11582 }
11583 }
11584 node.sibling.return = node.return;
11585 node = node.sibling;
11586 }
11587}
11588
11589function commitDeletion(current$$1, renderPriorityLevel) {
11590 if (supportsMutation) {
11591 // Recursively delete all host nodes from the parent.
11592 // Detach refs and call componentWillUnmount() on the whole subtree.
11593 unmountHostComponents(current$$1, renderPriorityLevel);
11594 } else {
11595 // Detach refs and call componentWillUnmount() on the whole subtree.
11596 commitNestedUnmounts(current$$1, renderPriorityLevel);
11597 }
11598 detachFiber(current$$1);
11599}
11600
11601function commitWork(current$$1, finishedWork) {
11602 if (!supportsMutation) {
11603 switch (finishedWork.tag) {
11604 case FunctionComponent:
11605 case ForwardRef:
11606 case MemoComponent:
11607 case SimpleMemoComponent:
11608 {
11609 // Note: We currently never use MountMutation, but useLayout uses
11610 // UnmountMutation.
11611 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
11612 return;
11613 }
11614 case Profiler:
11615 {
11616 return;
11617 }
11618 case SuspenseComponent:
11619 {
11620 commitSuspenseComponent(finishedWork);
11621 attachSuspenseRetryListeners(finishedWork);
11622 return;
11623 }
11624 case SuspenseListComponent:
11625 {
11626 attachSuspenseRetryListeners(finishedWork);
11627 return;
11628 }
11629 }
11630
11631 commitContainer(finishedWork);
11632 return;
11633 }
11634
11635 switch (finishedWork.tag) {
11636 case FunctionComponent:
11637 case ForwardRef:
11638 case MemoComponent:
11639 case SimpleMemoComponent:
11640 {
11641 // Note: We currently never use MountMutation, but useLayout uses
11642 // UnmountMutation.
11643 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
11644 return;
11645 }
11646 case ClassComponent:
11647 {
11648 return;
11649 }
11650 case HostComponent:
11651 {
11652 var instance = finishedWork.stateNode;
11653 if (instance != null) {
11654 // Commit the work prepared earlier.
11655 var newProps = finishedWork.memoizedProps;
11656 // For hydration we reuse the update path but we treat the oldProps
11657 // as the newProps. The updatePayload will contain the real change in
11658 // this case.
11659 var oldProps = current$$1 !== null ? current$$1.memoizedProps : newProps;
11660 var type = finishedWork.type;
11661 // TODO: Type the updateQueue to be specific to host components.
11662 var updatePayload = finishedWork.updateQueue;
11663 finishedWork.updateQueue = null;
11664 if (updatePayload !== null) {
11665 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
11666 }
11667 }
11668 return;
11669 }
11670 case HostText:
11671 {
11672 (function () {
11673 if (!(finishedWork.stateNode !== null)) {
11674 {
11675 throw ReactError(Error('This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue.'));
11676 }
11677 }
11678 })();
11679 var textInstance = finishedWork.stateNode;
11680 var newText = finishedWork.memoizedProps;
11681 // For hydration we reuse the update path but we treat the oldProps
11682 // as the newProps. The updatePayload will contain the real change in
11683 // this case.
11684 var oldText = current$$1 !== null ? current$$1.memoizedProps : newText;
11685 commitTextUpdate(textInstance, oldText, newText);
11686 return;
11687 }
11688 case HostRoot:
11689 {
11690 return;
11691 }
11692 case Profiler:
11693 {
11694 return;
11695 }
11696 case SuspenseComponent:
11697 {
11698 commitSuspenseComponent(finishedWork);
11699 attachSuspenseRetryListeners(finishedWork);
11700 return;
11701 }
11702 case SuspenseListComponent:
11703 {
11704 attachSuspenseRetryListeners(finishedWork);
11705 return;
11706 }
11707 case IncompleteClassComponent:
11708 {
11709 return;
11710 }
11711 case FundamentalComponent:
11712 {
11713 if (enableFundamentalAPI) {
11714 var fundamentalInstance = finishedWork.stateNode;
11715 updateFundamentalComponent(fundamentalInstance);
11716 }
11717 return;
11718 }
11719 default:
11720 {
11721 (function () {
11722 {
11723 {
11724 throw ReactError(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.'));
11725 }
11726 }
11727 })();
11728 }
11729 }
11730}
11731
11732function commitSuspenseComponent(finishedWork) {
11733 var newState = finishedWork.memoizedState;
11734
11735 var newDidTimeout = void 0;
11736 var primaryChildParent = finishedWork;
11737 if (newState === null) {
11738 newDidTimeout = false;
11739 } else {
11740 newDidTimeout = true;
11741 primaryChildParent = finishedWork.child;
11742 markCommitTimeOfFallback();
11743 }
11744
11745 if (supportsMutation && primaryChildParent !== null) {
11746 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
11747 }
11748
11749 if (enableSuspenseCallback && newState !== null) {
11750 var suspenseCallback = finishedWork.memoizedProps.suspenseCallback;
11751 if (typeof suspenseCallback === 'function') {
11752 var thenables = finishedWork.updateQueue;
11753 if (thenables !== null) {
11754 suspenseCallback(new Set(thenables));
11755 }
11756 } else {
11757 if (suspenseCallback !== undefined) {
11758 warning$1(false, 'Unexpected type for suspenseCallback.');
11759 }
11760 }
11761 }
11762}
11763
11764function attachSuspenseRetryListeners(finishedWork) {
11765 // If this boundary just timed out, then it will have a set of thenables.
11766 // For each thenable, attach a listener so that when it resolves, React
11767 var thenables = finishedWork.updateQueue;
11768 if (thenables !== null) {
11769 finishedWork.updateQueue = null;
11770 var retryCache = finishedWork.stateNode;
11771 if (retryCache === null) {
11772 retryCache = finishedWork.stateNode = new PossiblyWeakSet$1();
11773 }
11774 thenables.forEach(function (thenable) {
11775 // Memoize using the boundary fiber to prevent redundant listeners.
11776 var retry = resolveRetryThenable.bind(null, finishedWork, thenable);
11777 if (!retryCache.has(thenable)) {
11778 if (enableSchedulerTracing) {
11779 retry = tracing.unstable_wrap(retry);
11780 }
11781 retryCache.add(thenable);
11782 thenable.then(retry, retry);
11783 }
11784 });
11785 }
11786}
11787
11788function commitResetTextContent(current$$1) {
11789 if (!supportsMutation) {
11790 return;
11791 }
11792 resetTextContent(current$$1.stateNode);
11793}
11794
11795var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
11796var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
11797
11798function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
11799 var update = createUpdate(expirationTime, null);
11800 // Unmount the root by rendering null.
11801 update.tag = CaptureUpdate;
11802 // Caution: React DevTools currently depends on this property
11803 // being called "element".
11804 update.payload = { element: null };
11805 var error = errorInfo.value;
11806 update.callback = function () {
11807 onUncaughtError(error);
11808 logError(fiber, errorInfo);
11809 };
11810 return update;
11811}
11812
11813function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
11814 var update = createUpdate(expirationTime, null);
11815 update.tag = CaptureUpdate;
11816 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
11817 if (typeof getDerivedStateFromError === 'function') {
11818 var error = errorInfo.value;
11819 update.payload = function () {
11820 logError(fiber, errorInfo);
11821 return getDerivedStateFromError(error);
11822 };
11823 }
11824
11825 var inst = fiber.stateNode;
11826 if (inst !== null && typeof inst.componentDidCatch === 'function') {
11827 update.callback = function callback() {
11828 {
11829 markFailedErrorBoundaryForHotReloading(fiber);
11830 }
11831 if (typeof getDerivedStateFromError !== 'function') {
11832 // To preserve the preexisting retry behavior of error boundaries,
11833 // we keep track of which ones already failed during this batch.
11834 // This gets reset before we yield back to the browser.
11835 // TODO: Warn in strict mode if getDerivedStateFromError is
11836 // not defined.
11837 markLegacyErrorBoundaryAsFailed(this);
11838
11839 // Only log here if componentDidCatch is the only error boundary method defined
11840 logError(fiber, errorInfo);
11841 }
11842 var error = errorInfo.value;
11843 var stack = errorInfo.stack;
11844 this.componentDidCatch(error, {
11845 componentStack: stack !== null ? stack : ''
11846 });
11847 {
11848 if (typeof getDerivedStateFromError !== 'function') {
11849 // If componentDidCatch is the only error boundary method defined,
11850 // then it needs to call setState to recover from errors.
11851 // If no state update is scheduled then the boundary will swallow the error.
11852 !(fiber.expirationTime === Sync) ? warningWithoutStack$1(false, '%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') : void 0;
11853 }
11854 }
11855 };
11856 } else {
11857 update.callback = function () {
11858 markFailedErrorBoundaryForHotReloading(fiber);
11859 };
11860 }
11861 return update;
11862}
11863
11864function attachPingListener(root, renderExpirationTime, thenable) {
11865 // Attach a listener to the promise to "ping" the root and retry. But
11866 // only if one does not already exist for the current render expiration
11867 // time (which acts like a "thread ID" here).
11868 var pingCache = root.pingCache;
11869 var threadIDs = void 0;
11870 if (pingCache === null) {
11871 pingCache = root.pingCache = new PossiblyWeakMap();
11872 threadIDs = new Set();
11873 pingCache.set(thenable, threadIDs);
11874 } else {
11875 threadIDs = pingCache.get(thenable);
11876 if (threadIDs === undefined) {
11877 threadIDs = new Set();
11878 pingCache.set(thenable, threadIDs);
11879 }
11880 }
11881 if (!threadIDs.has(renderExpirationTime)) {
11882 // Memoize using the thread ID to prevent redundant listeners.
11883 threadIDs.add(renderExpirationTime);
11884 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
11885 if (enableSchedulerTracing) {
11886 ping = tracing.unstable_wrap(ping);
11887 }
11888 thenable.then(ping, ping);
11889 }
11890}
11891
11892function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
11893 // The source fiber did not complete.
11894 sourceFiber.effectTag |= Incomplete;
11895 // Its effect list is no longer valid.
11896 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
11897
11898 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
11899 // This is a thenable.
11900 var thenable = value;
11901
11902 checkForWrongSuspensePriorityInDEV(sourceFiber);
11903
11904 var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext);
11905
11906 // Schedule the nearest Suspense to re-render the timed out view.
11907 var _workInProgress = returnFiber;
11908 do {
11909 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) {
11910 // Found the nearest boundary.
11911
11912 // Stash the promise on the boundary fiber. If the boundary times out, we'll
11913 var thenables = _workInProgress.updateQueue;
11914 if (thenables === null) {
11915 var updateQueue = new Set();
11916 updateQueue.add(thenable);
11917 _workInProgress.updateQueue = updateQueue;
11918 } else {
11919 thenables.add(thenable);
11920 }
11921
11922 // If the boundary is outside of batched mode, we should *not*
11923 // suspend the commit. Pretend as if the suspended component rendered
11924 // null and keep rendering. In the commit phase, we'll schedule a
11925 // subsequent synchronous update to re-render the Suspense.
11926 //
11927 // Note: It doesn't matter whether the component that suspended was
11928 // inside a batched mode tree. If the Suspense is outside of it, we
11929 // should *not* suspend the commit.
11930 if ((_workInProgress.mode & BatchedMode) === NoMode) {
11931 _workInProgress.effectTag |= DidCapture;
11932
11933 // We're going to commit this fiber even though it didn't complete.
11934 // But we shouldn't call any lifecycle methods or callbacks. Remove
11935 // all lifecycle effect tags.
11936 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
11937
11938 if (sourceFiber.tag === ClassComponent) {
11939 var currentSourceFiber = sourceFiber.alternate;
11940 if (currentSourceFiber === null) {
11941 // This is a new mount. Change the tag so it's not mistaken for a
11942 // completed class component. For example, we should not call
11943 // componentWillUnmount if it is deleted.
11944 sourceFiber.tag = IncompleteClassComponent;
11945 } else {
11946 // When we try rendering again, we should not reuse the current fiber,
11947 // since it's known to be in an inconsistent state. Use a force update to
11948 // prevent a bail out.
11949 var update = createUpdate(Sync, null);
11950 update.tag = ForceUpdate;
11951 enqueueUpdate(sourceFiber, update);
11952 }
11953 }
11954
11955 // The source fiber did not complete. Mark it with Sync priority to
11956 // indicate that it still has pending work.
11957 sourceFiber.expirationTime = Sync;
11958
11959 // Exit without suspending.
11960 return;
11961 }
11962
11963 // Confirmed that the boundary is in a concurrent mode tree. Continue
11964 // with the normal suspend path.
11965 //
11966 // After this we'll use a set of heuristics to determine whether this
11967 // render pass will run to completion or restart or "suspend" the commit.
11968 // The actual logic for this is spread out in different places.
11969 //
11970 // This first principle is that if we're going to suspend when we complete
11971 // a root, then we should also restart if we get an update or ping that
11972 // might unsuspend it, and vice versa. The only reason to suspend is
11973 // because you think you might want to restart before committing. However,
11974 // it doesn't make sense to restart only while in the period we're suspended.
11975 //
11976 // Restarting too aggressively is also not good because it starves out any
11977 // intermediate loading state. So we use heuristics to determine when.
11978
11979 // Suspense Heuristics
11980 //
11981 // If nothing threw a Promise or all the same fallbacks are already showing,
11982 // then don't suspend/restart.
11983 //
11984 // If this is an initial render of a new tree of Suspense boundaries and
11985 // those trigger a fallback, then don't suspend/restart. We want to ensure
11986 // that we can show the initial loading state as quickly as possible.
11987 //
11988 // If we hit a "Delayed" case, such as when we'd switch from content back into
11989 // a fallback, then we should always suspend/restart. SuspenseConfig applies to
11990 // this case. If none is defined, JND is used instead.
11991 //
11992 // If we're already showing a fallback and it gets "retried", allowing us to show
11993 // another level, but there's still an inner boundary that would show a fallback,
11994 // then we suspend/restart for 500ms since the last time we showed a fallback
11995 // anywhere in the tree. This effectively throttles progressive loading into a
11996 // consistent train of commits. This also gives us an opportunity to restart to
11997 // get to the completed state slightly earlier.
11998 //
11999 // If there's ambiguity due to batching it's resolved in preference of:
12000 // 1) "delayed", 2) "initial render", 3) "retry".
12001 //
12002 // We want to ensure that a "busy" state doesn't get force committed. We want to
12003 // ensure that new initial loading states can commit as soon as possible.
12004
12005 attachPingListener(root, renderExpirationTime, thenable);
12006
12007 _workInProgress.effectTag |= ShouldCapture;
12008 _workInProgress.expirationTime = renderExpirationTime;
12009
12010 return;
12011 } else if (enableSuspenseServerRenderer && _workInProgress.tag === DehydratedSuspenseComponent) {
12012 attachPingListener(root, renderExpirationTime, thenable);
12013
12014 // Since we already have a current fiber, we can eagerly add a retry listener.
12015 var retryCache = _workInProgress.memoizedState;
12016 if (retryCache === null) {
12017 retryCache = _workInProgress.memoizedState = new PossiblyWeakSet();
12018 var current$$1 = _workInProgress.alternate;
12019 (function () {
12020 if (!current$$1) {
12021 {
12022 throw ReactError(Error('A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React.'));
12023 }
12024 }
12025 })();
12026 current$$1.memoizedState = retryCache;
12027 }
12028 // Memoize using the boundary fiber to prevent redundant listeners.
12029 if (!retryCache.has(thenable)) {
12030 retryCache.add(thenable);
12031 var retry = resolveRetryThenable.bind(null, _workInProgress, thenable);
12032 if (enableSchedulerTracing) {
12033 retry = tracing.unstable_wrap(retry);
12034 }
12035 thenable.then(retry, retry);
12036 }
12037 _workInProgress.effectTag |= ShouldCapture;
12038 _workInProgress.expirationTime = renderExpirationTime;
12039 return;
12040 }
12041 // This boundary already captured during this render. Continue to the next
12042 // boundary.
12043 _workInProgress = _workInProgress.return;
12044 } while (_workInProgress !== null);
12045 // No boundary was found. Fallthrough to error mode.
12046 // TODO: Use invariant so the message is stripped in prod?
12047 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));
12048 }
12049
12050 // We didn't find a boundary that could handle this type of exception. Start
12051 // over and traverse parent path again, this time treating the exception
12052 // as an error.
12053 renderDidError();
12054 value = createCapturedValue(value, sourceFiber);
12055 var workInProgress = returnFiber;
12056 do {
12057 switch (workInProgress.tag) {
12058 case HostRoot:
12059 {
12060 var _errorInfo = value;
12061 workInProgress.effectTag |= ShouldCapture;
12062 workInProgress.expirationTime = renderExpirationTime;
12063 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
12064 enqueueCapturedUpdate(workInProgress, _update);
12065 return;
12066 }
12067 case ClassComponent:
12068 // Capture and retry
12069 var errorInfo = value;
12070 var ctor = workInProgress.type;
12071 var instance = workInProgress.stateNode;
12072 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
12073 workInProgress.effectTag |= ShouldCapture;
12074 workInProgress.expirationTime = renderExpirationTime;
12075 // Schedule the error boundary to re-render using updated state
12076 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
12077 enqueueCapturedUpdate(workInProgress, _update2);
12078 return;
12079 }
12080 break;
12081 default:
12082 break;
12083 }
12084 workInProgress = workInProgress.return;
12085 } while (workInProgress !== null);
12086}
12087
12088// The scheduler is imported here *only* to detect whether it's been mocked
12089// DEV stuff
12090var ceil = Math.ceil;
12091
12092var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
12093var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
12094var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;
12095
12096
12097var NoContext = /* */0;
12098var BatchedContext = /* */1;
12099var DiscreteEventContext = /* */4;
12100var LegacyUnbatchedContext = /* */8;
12101var RenderContext = /* */16;
12102var CommitContext = /* */32;
12103
12104var RootIncomplete = 0;
12105var RootErrored = 1;
12106var RootSuspended = 2;
12107var RootSuspendedWithDelay = 3;
12108var RootCompleted = 4;
12109
12110// Describes where we are in the React execution stack
12111var executionContext = NoContext;
12112// The root we're working on
12113var workInProgressRoot = null;
12114// The fiber we're working on
12115var workInProgress = null;
12116// The expiration time we're rendering
12117var renderExpirationTime = NoWork;
12118// Whether to root completed, errored, suspended, etc.
12119var workInProgressRootExitStatus = RootIncomplete;
12120// Most recent event time among processed updates during this render.
12121// This is conceptually a time stamp but expressed in terms of an ExpirationTime
12122// because we deal mostly with expiration times in the hot path, so this avoids
12123// the conversion happening in the hot path.
12124var workInProgressRootLatestProcessedExpirationTime = Sync;
12125var workInProgressRootLatestSuspenseTimeout = Sync;
12126var workInProgressRootCanSuspendUsingConfig = null;
12127// If we're pinged while rendering we don't always restart immediately.
12128// This flag determines if it might be worthwhile to restart if an opportunity
12129// happens latere.
12130var workInProgressRootHasPendingPing = false;
12131// The most recent time we committed a fallback. This lets us ensure a train
12132// model where we don't commit new loading states in too quick succession.
12133var globalMostRecentFallbackTime = 0;
12134var FALLBACK_THROTTLE_MS = 500;
12135
12136var nextEffect = null;
12137var hasUncaughtError = false;
12138var firstUncaughtError = null;
12139var legacyErrorBoundariesThatAlreadyFailed = null;
12140
12141var rootDoesHavePassiveEffects = false;
12142var rootWithPendingPassiveEffects = null;
12143var pendingPassiveEffectsRenderPriority = NoPriority;
12144var pendingPassiveEffectsExpirationTime = NoWork;
12145
12146var rootsWithPendingDiscreteUpdates = null;
12147
12148// Use these to prevent an infinite loop of nested updates
12149var NESTED_UPDATE_LIMIT = 50;
12150var nestedUpdateCount = 0;
12151var rootWithNestedUpdates = null;
12152
12153var NESTED_PASSIVE_UPDATE_LIMIT = 50;
12154var nestedPassiveUpdateCount = 0;
12155
12156var interruptedBy = null;
12157
12158// Marks the need to reschedule pending interactions at these expiration times
12159// during the commit phase. This enables them to be traced across components
12160// that spawn new work during render. E.g. hidden boundaries, suspended SSR
12161// hydration or SuspenseList.
12162var spawnedWorkDuringRender = null;
12163
12164// Expiration times are computed by adding to the current time (the start
12165// time). However, if two updates are scheduled within the same event, we
12166// should treat their start times as simultaneous, even if the actual clock
12167// time has advanced between the first and second call.
12168
12169// In other words, because expiration times determine how updates are batched,
12170// we want all updates of like priority that occur within the same event to
12171// receive the same expiration time. Otherwise we get tearing.
12172var currentEventTime = NoWork;
12173
12174function requestCurrentTime() {
12175 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
12176 // We're inside React, so it's fine to read the actual time.
12177 return msToExpirationTime(now());
12178 }
12179 // We're not inside React, so we may be in the middle of a browser event.
12180 if (currentEventTime !== NoWork) {
12181 // Use the same start time for all updates until we enter React again.
12182 return currentEventTime;
12183 }
12184 // This is the first update since React yielded. Compute a new start time.
12185 currentEventTime = msToExpirationTime(now());
12186 return currentEventTime;
12187}
12188
12189function computeExpirationForFiber(currentTime, fiber, suspenseConfig) {
12190 var mode = fiber.mode;
12191 if ((mode & BatchedMode) === NoMode) {
12192 return Sync;
12193 }
12194
12195 var priorityLevel = getCurrentPriorityLevel();
12196 if ((mode & ConcurrentMode) === NoMode) {
12197 return priorityLevel === ImmediatePriority ? Sync : Batched;
12198 }
12199
12200 if ((executionContext & RenderContext) !== NoContext) {
12201 // Use whatever time we're already rendering
12202 return renderExpirationTime;
12203 }
12204
12205 var expirationTime = void 0;
12206 if (suspenseConfig !== null) {
12207 // Compute an expiration time based on the Suspense timeout.
12208 expirationTime = computeSuspenseExpiration(currentTime, suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
12209 } else {
12210 // Compute an expiration time based on the Scheduler priority.
12211 switch (priorityLevel) {
12212 case ImmediatePriority:
12213 expirationTime = Sync;
12214 break;
12215 case UserBlockingPriority:
12216 // TODO: Rename this to computeUserBlockingExpiration
12217 expirationTime = computeInteractiveExpiration(currentTime);
12218 break;
12219 case NormalPriority:
12220 case LowPriority:
12221 // TODO: Handle LowPriority
12222 // TODO: Rename this to... something better.
12223 expirationTime = computeAsyncExpiration(currentTime);
12224 break;
12225 case IdlePriority:
12226 expirationTime = Never;
12227 break;
12228 default:
12229 (function () {
12230 {
12231 {
12232 throw ReactError(Error('Expected a valid priority level'));
12233 }
12234 }
12235 })();
12236 }
12237 }
12238
12239 // If we're in the middle of rendering a tree, do not update at the same
12240 // expiration time that is already rendering.
12241 // TODO: We shouldn't have to do this if the update is on a different root.
12242 // Refactor computeExpirationForFiber + scheduleUpdate so we have access to
12243 // the root when we check for this condition.
12244 if (workInProgressRoot !== null && expirationTime === renderExpirationTime) {
12245 // This is a trick to move this update into a separate batch
12246 expirationTime -= 1;
12247 }
12248
12249 return expirationTime;
12250}
12251
12252
12253
12254function scheduleUpdateOnFiber(fiber, expirationTime) {
12255 checkForNestedUpdates();
12256 warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber);
12257
12258 var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);
12259 if (root === null) {
12260 warnAboutUpdateOnUnmountedFiberInDEV(fiber);
12261 return;
12262 }
12263
12264 root.pingTime = NoWork;
12265
12266 checkForInterruption(fiber, expirationTime);
12267 recordScheduleUpdate();
12268
12269 // TODO: computeExpirationForFiber also reads the priority. Pass the
12270 // priority as an argument to that function and this one.
12271 var priorityLevel = getCurrentPriorityLevel();
12272
12273 if (expirationTime === Sync) {
12274 if (
12275 // Check if we're inside unbatchedUpdates
12276 (executionContext & LegacyUnbatchedContext) !== NoContext &&
12277 // Check if we're not already rendering
12278 (executionContext & (RenderContext | CommitContext)) === NoContext) {
12279 // Register pending interactions on the root to avoid losing traced interaction data.
12280 schedulePendingInteractions(root, expirationTime);
12281
12282 // This is a legacy edge case. The initial mount of a ReactDOM.render-ed
12283 // root inside of batchedUpdates should be synchronous, but layout updates
12284 // should be deferred until the end of the batch.
12285 var callback = renderRoot(root, Sync, true);
12286 while (callback !== null) {
12287 callback = callback(true);
12288 }
12289 } else {
12290 scheduleCallbackForRoot(root, ImmediatePriority, Sync);
12291 if (executionContext === NoContext) {
12292 // Flush the synchronous work now, wnless we're already working or inside
12293 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
12294 // scheduleCallbackForFiber to preserve the ability to schedule a callback
12295 // without immediately flushing it. We only do this for user-initiated
12296 // updates, to preserve historical behavior of sync mode.
12297 flushSyncCallbackQueue();
12298 }
12299 }
12300 } else {
12301 scheduleCallbackForRoot(root, priorityLevel, expirationTime);
12302 }
12303
12304 if ((executionContext & DiscreteEventContext) !== NoContext && (
12305 // Only updates at user-blocking priority or greater are considered
12306 // discrete, even inside a discrete event.
12307 priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority)) {
12308 // This is the result of a discrete event. Track the lowest priority
12309 // discrete update per root so we can flush them early, if needed.
12310 if (rootsWithPendingDiscreteUpdates === null) {
12311 rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);
12312 } else {
12313 var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);
12314 if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {
12315 rootsWithPendingDiscreteUpdates.set(root, expirationTime);
12316 }
12317 }
12318 }
12319}
12320var scheduleWork = scheduleUpdateOnFiber;
12321
12322// This is split into a separate function so we can mark a fiber with pending
12323// work without treating it as a typical update that originates from an event;
12324// e.g. retrying a Suspense boundary isn't an update, but it does schedule work
12325// on a fiber.
12326function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
12327 // Update the source fiber's expiration time
12328 if (fiber.expirationTime < expirationTime) {
12329 fiber.expirationTime = expirationTime;
12330 }
12331 var alternate = fiber.alternate;
12332 if (alternate !== null && alternate.expirationTime < expirationTime) {
12333 alternate.expirationTime = expirationTime;
12334 }
12335 // Walk the parent path to the root and update the child expiration time.
12336 var node = fiber.return;
12337 var root = null;
12338 if (node === null && fiber.tag === HostRoot) {
12339 root = fiber.stateNode;
12340 } else {
12341 while (node !== null) {
12342 alternate = node.alternate;
12343 if (node.childExpirationTime < expirationTime) {
12344 node.childExpirationTime = expirationTime;
12345 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
12346 alternate.childExpirationTime = expirationTime;
12347 }
12348 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
12349 alternate.childExpirationTime = expirationTime;
12350 }
12351 if (node.return === null && node.tag === HostRoot) {
12352 root = node.stateNode;
12353 break;
12354 }
12355 node = node.return;
12356 }
12357 }
12358
12359 if (root !== null) {
12360 // Update the first and last pending expiration times in this root
12361 var firstPendingTime = root.firstPendingTime;
12362 if (expirationTime > firstPendingTime) {
12363 root.firstPendingTime = expirationTime;
12364 }
12365 var lastPendingTime = root.lastPendingTime;
12366 if (lastPendingTime === NoWork || expirationTime < lastPendingTime) {
12367 root.lastPendingTime = expirationTime;
12368 }
12369 }
12370
12371 return root;
12372}
12373
12374// Use this function, along with runRootCallback, to ensure that only a single
12375// callback per root is scheduled. It's still possible to call renderRoot
12376// directly, but scheduling via this function helps avoid excessive callbacks.
12377// It works by storing the callback node and expiration time on the root. When a
12378// new callback comes in, it compares the expiration time to determine if it
12379// should cancel the previous one. It also relies on commitRoot scheduling a
12380// callback to render the next level, because that means we don't need a
12381// separate callback per expiration time.
12382function scheduleCallbackForRoot(root, priorityLevel, expirationTime) {
12383 var existingCallbackExpirationTime = root.callbackExpirationTime;
12384 if (existingCallbackExpirationTime < expirationTime) {
12385 // New callback has higher priority than the existing one.
12386 var existingCallbackNode = root.callbackNode;
12387 if (existingCallbackNode !== null) {
12388 cancelCallback(existingCallbackNode);
12389 }
12390 root.callbackExpirationTime = expirationTime;
12391
12392 if (expirationTime === Sync) {
12393 // Sync React callbacks are scheduled on a special internal queue
12394 root.callbackNode = scheduleSyncCallback(runRootCallback.bind(null, root, renderRoot.bind(null, root, expirationTime)));
12395 } else {
12396 var options = null;
12397 if (!disableSchedulerTimeoutBasedOnReactExpirationTime && expirationTime !== Never) {
12398 var timeout = expirationTimeToMs(expirationTime) - now();
12399 options = { timeout: timeout };
12400 }
12401
12402 root.callbackNode = scheduleCallback(priorityLevel, runRootCallback.bind(null, root, renderRoot.bind(null, root, expirationTime)), options);
12403 if (enableUserTimingAPI && expirationTime !== Sync && (executionContext & (RenderContext | CommitContext)) === NoContext) {
12404 // Scheduled an async callback, and we're not already working. Add an
12405 // entry to the flamegraph that shows we're waiting for a callback
12406 // to fire.
12407 startRequestCallbackTimer();
12408 }
12409 }
12410 }
12411
12412 // Associate the current interactions with this new root+priority.
12413 schedulePendingInteractions(root, expirationTime);
12414}
12415
12416function runRootCallback(root, callback, isSync) {
12417 var prevCallbackNode = root.callbackNode;
12418 var continuation = null;
12419 try {
12420 continuation = callback(isSync);
12421 if (continuation !== null) {
12422 return runRootCallback.bind(null, root, continuation);
12423 } else {
12424 return null;
12425 }
12426 } finally {
12427 // If the callback exits without returning a continuation, remove the
12428 // corresponding callback node from the root. Unless the callback node
12429 // has changed, which implies that it was already cancelled by a high
12430 // priority update.
12431 if (continuation === null && prevCallbackNode === root.callbackNode) {
12432 root.callbackNode = null;
12433 root.callbackExpirationTime = NoWork;
12434 }
12435 }
12436}
12437
12438
12439
12440
12441
12442function resolveLocksOnRoot(root, expirationTime) {
12443 var firstBatch = root.firstBatch;
12444 if (firstBatch !== null && firstBatch._defer && firstBatch._expirationTime >= expirationTime) {
12445 scheduleCallback(NormalPriority, function () {
12446 firstBatch._onComplete();
12447 return null;
12448 });
12449 return true;
12450 } else {
12451 return false;
12452 }
12453}
12454
12455
12456
12457
12458
12459function batchedUpdates(fn, a) {
12460 var prevExecutionContext = executionContext;
12461 executionContext |= BatchedContext;
12462 try {
12463 return fn(a);
12464 } finally {
12465 executionContext = prevExecutionContext;
12466 if (executionContext === NoContext) {
12467 // Flush the immediate callbacks that were scheduled during this batch
12468 flushSyncCallbackQueue();
12469 }
12470 }
12471}
12472
12473
12474
12475
12476
12477
12478
12479function flushSync(fn, a) {
12480 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
12481 (function () {
12482 {
12483 {
12484 throw ReactError(Error('flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.'));
12485 }
12486 }
12487 })();
12488 }
12489 var prevExecutionContext = executionContext;
12490 executionContext |= BatchedContext;
12491 try {
12492 return runWithPriority(ImmediatePriority, fn.bind(null, a));
12493 } finally {
12494 executionContext = prevExecutionContext;
12495 // Flush the immediate callbacks that were scheduled during this batch.
12496 // Note that this will happen even if batchedUpdates is higher up
12497 // the stack.
12498 flushSyncCallbackQueue();
12499 }
12500}
12501
12502
12503
12504function prepareFreshStack(root, expirationTime) {
12505 root.finishedWork = null;
12506 root.finishedExpirationTime = NoWork;
12507
12508 var timeoutHandle = root.timeoutHandle;
12509 if (timeoutHandle !== noTimeout) {
12510 // The root previous suspended and scheduled a timeout to commit a fallback
12511 // state. Now that we have additional work, cancel the timeout.
12512 root.timeoutHandle = noTimeout;
12513 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
12514 cancelTimeout(timeoutHandle);
12515 }
12516
12517 if (workInProgress !== null) {
12518 var interruptedWork = workInProgress.return;
12519 while (interruptedWork !== null) {
12520 unwindInterruptedWork(interruptedWork);
12521 interruptedWork = interruptedWork.return;
12522 }
12523 }
12524 workInProgressRoot = root;
12525 workInProgress = createWorkInProgress(root.current, null, expirationTime);
12526 renderExpirationTime = expirationTime;
12527 workInProgressRootExitStatus = RootIncomplete;
12528 workInProgressRootLatestProcessedExpirationTime = Sync;
12529 workInProgressRootLatestSuspenseTimeout = Sync;
12530 workInProgressRootCanSuspendUsingConfig = null;
12531 workInProgressRootHasPendingPing = false;
12532
12533 if (enableSchedulerTracing) {
12534 spawnedWorkDuringRender = null;
12535 }
12536
12537 {
12538 ReactStrictModeWarnings.discardPendingWarnings();
12539 componentsThatTriggeredHighPriSuspend = null;
12540 }
12541}
12542
12543function renderRoot(root, expirationTime, isSync) {
12544 (function () {
12545 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
12546 {
12547 throw ReactError(Error('Should not already be working.'));
12548 }
12549 }
12550 })();
12551
12552 if (enableUserTimingAPI && expirationTime !== Sync) {
12553 var didExpire = isSync;
12554 stopRequestCallbackTimer(didExpire);
12555 }
12556
12557 if (root.firstPendingTime < expirationTime) {
12558 // If there's no work left at this expiration time, exit immediately. This
12559 // happens when multiple callbacks are scheduled for a single root, but an
12560 // earlier callback flushes the work of a later one.
12561 return null;
12562 }
12563
12564 if (isSync && root.finishedExpirationTime === expirationTime) {
12565 // There's already a pending commit at this expiration time.
12566 // TODO: This is poorly factored. This case only exists for the
12567 // batch.commit() API.
12568 return commitRoot.bind(null, root);
12569 }
12570
12571 flushPassiveEffects();
12572
12573 // If the root or expiration time have changed, throw out the existing stack
12574 // and prepare a fresh one. Otherwise we'll continue where we left off.
12575 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) {
12576 prepareFreshStack(root, expirationTime);
12577 startWorkOnPendingInteractions(root, expirationTime);
12578 } else if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
12579 // We could've received an update at a lower priority while we yielded.
12580 // We're suspended in a delayed state. Once we complete this render we're
12581 // just going to try to recover at the last pending time anyway so we might
12582 // as well start doing that eagerly.
12583 // Ideally we should be able to do this even for retries but we don't yet
12584 // know if we're going to process an update which wants to commit earlier,
12585 // and this path happens very early so it would happen too often. Instead,
12586 // for that case, we'll wait until we complete.
12587 if (workInProgressRootHasPendingPing) {
12588 // We have a ping at this expiration. Let's restart to see if we get unblocked.
12589 prepareFreshStack(root, expirationTime);
12590 } else {
12591 var lastPendingTime = root.lastPendingTime;
12592 if (lastPendingTime < expirationTime) {
12593 // There's lower priority work. It might be unsuspended. Try rendering
12594 // at that level immediately, while preserving the position in the queue.
12595 return renderRoot.bind(null, root, lastPendingTime);
12596 }
12597 }
12598 }
12599
12600 // If we have a work-in-progress fiber, it means there's still work to do
12601 // in this root.
12602 if (workInProgress !== null) {
12603 var prevExecutionContext = executionContext;
12604 executionContext |= RenderContext;
12605 var prevDispatcher = ReactCurrentDispatcher.current;
12606 if (prevDispatcher === null) {
12607 // The React isomorphic package does not include a default dispatcher.
12608 // Instead the first renderer will lazily attach one, in order to give
12609 // nicer error messages.
12610 prevDispatcher = ContextOnlyDispatcher;
12611 }
12612 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
12613 var prevInteractions = null;
12614 if (enableSchedulerTracing) {
12615 prevInteractions = tracing.__interactionsRef.current;
12616 tracing.__interactionsRef.current = root.memoizedInteractions;
12617 }
12618
12619 startWorkLoopTimer(workInProgress);
12620
12621 // TODO: Fork renderRoot into renderRootSync and renderRootAsync
12622 if (isSync) {
12623 if (expirationTime !== Sync) {
12624 // An async update expired. There may be other expired updates on
12625 // this root. We should render all the expired work in a
12626 // single batch.
12627 var currentTime = requestCurrentTime();
12628 if (currentTime < expirationTime) {
12629 // Restart at the current time.
12630 executionContext = prevExecutionContext;
12631 resetContextDependencies();
12632 ReactCurrentDispatcher.current = prevDispatcher;
12633 if (enableSchedulerTracing) {
12634 tracing.__interactionsRef.current = prevInteractions;
12635 }
12636 return renderRoot.bind(null, root, currentTime);
12637 }
12638 }
12639 } else {
12640 // Since we know we're in a React event, we can clear the current
12641 // event time. The next update will compute a new event time.
12642 currentEventTime = NoWork;
12643 }
12644
12645 do {
12646 try {
12647 if (isSync) {
12648 workLoopSync();
12649 } else {
12650 workLoop();
12651 }
12652 break;
12653 } catch (thrownValue) {
12654 // Reset module-level state that was set during the render phase.
12655 resetContextDependencies();
12656 resetHooks();
12657
12658 var sourceFiber = workInProgress;
12659 if (sourceFiber === null || sourceFiber.return === null) {
12660 // Expected to be working on a non-root fiber. This is a fatal error
12661 // because there's no ancestor that can handle it; the root is
12662 // supposed to capture all errors that weren't caught by an error
12663 // boundary.
12664 prepareFreshStack(root, expirationTime);
12665 executionContext = prevExecutionContext;
12666 throw thrownValue;
12667 }
12668
12669 if (enableProfilerTimer && sourceFiber.mode & ProfileMode) {
12670 // Record the time spent rendering before an error was thrown. This
12671 // avoids inaccurate Profiler durations in the case of a
12672 // suspended render.
12673 stopProfilerTimerIfRunningAndRecordDelta(sourceFiber, true);
12674 }
12675
12676 var returnFiber = sourceFiber.return;
12677 throwException(root, returnFiber, sourceFiber, thrownValue, renderExpirationTime);
12678 workInProgress = completeUnitOfWork(sourceFiber);
12679 }
12680 } while (true);
12681
12682 executionContext = prevExecutionContext;
12683 resetContextDependencies();
12684 ReactCurrentDispatcher.current = prevDispatcher;
12685 if (enableSchedulerTracing) {
12686 tracing.__interactionsRef.current = prevInteractions;
12687 }
12688
12689 if (workInProgress !== null) {
12690 // There's still work left over. Return a continuation.
12691 stopInterruptedWorkLoopTimer();
12692 if (expirationTime !== Sync) {
12693 startRequestCallbackTimer();
12694 }
12695 return renderRoot.bind(null, root, expirationTime);
12696 }
12697 }
12698
12699 // We now have a consistent tree. The next step is either to commit it, or, if
12700 // something suspended, wait to commit it after a timeout.
12701 stopFinishedWorkLoopTimer();
12702
12703 root.finishedWork = root.current.alternate;
12704 root.finishedExpirationTime = expirationTime;
12705
12706 var isLocked = resolveLocksOnRoot(root, expirationTime);
12707 if (isLocked) {
12708 // This root has a lock that prevents it from committing. Exit. If we begin
12709 // work on the root again, without any intervening updates, it will finish
12710 // without doing additional work.
12711 return null;
12712 }
12713
12714 // Set this to null to indicate there's no in-progress render.
12715 workInProgressRoot = null;
12716
12717 switch (workInProgressRootExitStatus) {
12718 case RootIncomplete:
12719 {
12720 (function () {
12721 {
12722 {
12723 throw ReactError(Error('Should have a work-in-progress.'));
12724 }
12725 }
12726 })();
12727 }
12728 // Flow knows about invariant, so it complains if I add a break statement,
12729 // but eslint doesn't know about invariant, so it complains if I do.
12730 // eslint-disable-next-line no-fallthrough
12731 case RootErrored:
12732 {
12733 // An error was thrown. First check if there is lower priority work
12734 // scheduled on this root.
12735 var _lastPendingTime = root.lastPendingTime;
12736 if (_lastPendingTime < expirationTime) {
12737 // There's lower priority work. Before raising the error, try rendering
12738 // at the lower priority to see if it fixes it. Use a continuation to
12739 // maintain the existing priority and position in the queue.
12740 return renderRoot.bind(null, root, _lastPendingTime);
12741 }
12742 if (!isSync) {
12743 // If we're rendering asynchronously, it's possible the error was
12744 // caused by tearing due to a mutation during an event. Try rendering
12745 // one more time without yiedling to events.
12746 prepareFreshStack(root, expirationTime);
12747 scheduleSyncCallback(renderRoot.bind(null, root, expirationTime));
12748 return null;
12749 }
12750 // If we're already rendering synchronously, commit the root in its
12751 // errored state.
12752 return commitRoot.bind(null, root);
12753 }
12754 case RootSuspended:
12755 {
12756 flushSuspensePriorityWarningInDEV();
12757
12758 // We have an acceptable loading state. We need to figure out if we should
12759 // immediately commit it or wait a bit.
12760
12761 // If we have processed new updates during this render, we may now have a
12762 // new loading state ready. We want to ensure that we commit that as soon as
12763 // possible.
12764 var hasNotProcessedNewUpdates = workInProgressRootLatestProcessedExpirationTime === Sync;
12765 if (hasNotProcessedNewUpdates && !isSync &&
12766 // do not delay if we're inside an act() scope
12767 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current)) {
12768 // If we have not processed any new updates during this pass, then this is
12769 // either a retry of an existing fallback state or a hidden tree.
12770 // Hidden trees shouldn't be batched with other work and after that's
12771 // fixed it can only be a retry.
12772 // We're going to throttle committing retries so that we don't show too
12773 // many loading states too quickly.
12774 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now();
12775 // Don't bother with a very short suspense time.
12776 if (msUntilTimeout > 10) {
12777 if (workInProgressRootHasPendingPing) {
12778 // This render was pinged but we didn't get to restart earlier so try
12779 // restarting now instead.
12780 prepareFreshStack(root, expirationTime);
12781 return renderRoot.bind(null, root, expirationTime);
12782 }
12783 var _lastPendingTime2 = root.lastPendingTime;
12784 if (_lastPendingTime2 < expirationTime) {
12785 // There's lower priority work. It might be unsuspended. Try rendering
12786 // at that level.
12787 return renderRoot.bind(null, root, _lastPendingTime2);
12788 }
12789 // The render is suspended, it hasn't timed out, and there's no lower
12790 // priority work to do. Instead of committing the fallback
12791 // immediately, wait for more data to arrive.
12792 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);
12793 return null;
12794 }
12795 }
12796 // The work expired. Commit immediately.
12797 return commitRoot.bind(null, root);
12798 }
12799 case RootSuspendedWithDelay:
12800 {
12801 flushSuspensePriorityWarningInDEV();
12802
12803 if (!isSync &&
12804 // do not delay if we're inside an act() scope
12805 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current)) {
12806 // We're suspended in a state that should be avoided. We'll try to avoid committing
12807 // it for as long as the timeouts let us.
12808 if (workInProgressRootHasPendingPing) {
12809 // This render was pinged but we didn't get to restart earlier so try
12810 // restarting now instead.
12811 prepareFreshStack(root, expirationTime);
12812 return renderRoot.bind(null, root, expirationTime);
12813 }
12814 var _lastPendingTime3 = root.lastPendingTime;
12815 if (_lastPendingTime3 < expirationTime) {
12816 // There's lower priority work. It might be unsuspended. Try rendering
12817 // at that level immediately.
12818 return renderRoot.bind(null, root, _lastPendingTime3);
12819 }
12820
12821 var _msUntilTimeout = void 0;
12822 if (workInProgressRootLatestSuspenseTimeout !== Sync) {
12823 // We have processed a suspense config whose expiration time we can use as
12824 // the timeout.
12825 _msUntilTimeout = expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now();
12826 } else if (workInProgressRootLatestProcessedExpirationTime === Sync) {
12827 // This should never normally happen because only new updates cause
12828 // delayed states, so we should have processed something. However,
12829 // this could also happen in an offscreen tree.
12830 _msUntilTimeout = 0;
12831 } else {
12832 // If we don't have a suspense config, we're going to use a heuristic to
12833 var eventTimeMs = inferTimeFromExpirationTime(workInProgressRootLatestProcessedExpirationTime);
12834 var currentTimeMs = now();
12835 var timeUntilExpirationMs = expirationTimeToMs(expirationTime) - currentTimeMs;
12836 var timeElapsed = currentTimeMs - eventTimeMs;
12837 if (timeElapsed < 0) {
12838 // We get this wrong some time since we estimate the time.
12839 timeElapsed = 0;
12840 }
12841
12842 _msUntilTimeout = jnd(timeElapsed) - timeElapsed;
12843
12844 // Clamp the timeout to the expiration time.
12845 // TODO: Once the event time is exact instead of inferred from expiration time
12846 // we don't need this.
12847 if (timeUntilExpirationMs < _msUntilTimeout) {
12848 _msUntilTimeout = timeUntilExpirationMs;
12849 }
12850 }
12851
12852 // Don't bother with a very short suspense time.
12853 if (_msUntilTimeout > 10) {
12854 // The render is suspended, it hasn't timed out, and there's no lower
12855 // priority work to do. Instead of committing the fallback
12856 // immediately, wait for more data to arrive.
12857 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);
12858 return null;
12859 }
12860 }
12861 // The work expired. Commit immediately.
12862 return commitRoot.bind(null, root);
12863 }
12864 case RootCompleted:
12865 {
12866 // The work completed. Ready to commit.
12867 if (!isSync &&
12868 // do not delay if we're inside an act() scope
12869 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) && workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null) {
12870 // If we have exceeded the minimum loading delay, which probably
12871 // means we have shown a spinner already, we might have to suspend
12872 // a bit longer to ensure that the spinner is shown for enough time.
12873 var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay(workInProgressRootLatestProcessedExpirationTime, expirationTime, workInProgressRootCanSuspendUsingConfig);
12874 if (_msUntilTimeout2 > 10) {
12875 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout2);
12876 return null;
12877 }
12878 }
12879 return commitRoot.bind(null, root);
12880 }
12881 default:
12882 {
12883 (function () {
12884 {
12885 {
12886 throw ReactError(Error('Unknown root exit status.'));
12887 }
12888 }
12889 })();
12890 }
12891 }
12892}
12893
12894function markCommitTimeOfFallback() {
12895 globalMostRecentFallbackTime = now();
12896}
12897
12898function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) {
12899 if (expirationTime < workInProgressRootLatestProcessedExpirationTime && expirationTime > Never) {
12900 workInProgressRootLatestProcessedExpirationTime = expirationTime;
12901 }
12902 if (suspenseConfig !== null) {
12903 if (expirationTime < workInProgressRootLatestSuspenseTimeout && expirationTime > Never) {
12904 workInProgressRootLatestSuspenseTimeout = expirationTime;
12905 // Most of the time we only have one config and getting wrong is not bad.
12906 workInProgressRootCanSuspendUsingConfig = suspenseConfig;
12907 }
12908 }
12909}
12910
12911function renderDidSuspend() {
12912 if (workInProgressRootExitStatus === RootIncomplete) {
12913 workInProgressRootExitStatus = RootSuspended;
12914 }
12915}
12916
12917function renderDidSuspendDelayIfPossible() {
12918 if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {
12919 workInProgressRootExitStatus = RootSuspendedWithDelay;
12920 }
12921}
12922
12923function renderDidError() {
12924 if (workInProgressRootExitStatus !== RootCompleted) {
12925 workInProgressRootExitStatus = RootErrored;
12926 }
12927}
12928
12929// Called during render to determine if anything has suspended.
12930// Returns false if we're not sure.
12931function renderHasNotSuspendedYet() {
12932 // If something errored or completed, we can't really be sure,
12933 // so those are false.
12934 return workInProgressRootExitStatus === RootIncomplete;
12935}
12936
12937function inferTimeFromExpirationTime(expirationTime) {
12938 // We don't know exactly when the update was scheduled, but we can infer an
12939 // approximate start time from the expiration time.
12940 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
12941 return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
12942}
12943
12944function inferTimeFromExpirationTimeWithSuspenseConfig(expirationTime, suspenseConfig) {
12945 // We don't know exactly when the update was scheduled, but we can infer an
12946 // approximate start time from the expiration time by subtracting the timeout
12947 // that was added to the event time.
12948 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
12949 return earliestExpirationTimeMs - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
12950}
12951
12952function workLoopSync() {
12953 // Already timed out, so perform work without checking if we need to yield.
12954 while (workInProgress !== null) {
12955 workInProgress = performUnitOfWork(workInProgress);
12956 }
12957}
12958
12959function workLoop() {
12960 // Perform work until Scheduler asks us to yield
12961 while (workInProgress !== null && !shouldYield()) {
12962 workInProgress = performUnitOfWork(workInProgress);
12963 }
12964}
12965
12966function performUnitOfWork(unitOfWork) {
12967 // The current, flushed, state of this fiber is the alternate. Ideally
12968 // nothing should rely on this, but relying on it here means that we don't
12969 // need an additional field on the work in progress.
12970 var current$$1 = unitOfWork.alternate;
12971
12972 startWorkTimer(unitOfWork);
12973 setCurrentFiber(unitOfWork);
12974
12975 var next = void 0;
12976 if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) {
12977 startProfilerTimer(unitOfWork);
12978 next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime);
12979 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
12980 } else {
12981 next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime);
12982 }
12983
12984 resetCurrentFiber();
12985 unitOfWork.memoizedProps = unitOfWork.pendingProps;
12986 if (next === null) {
12987 // If this doesn't spawn new work, complete the current work.
12988 next = completeUnitOfWork(unitOfWork);
12989 }
12990
12991 ReactCurrentOwner$1.current = null;
12992 return next;
12993}
12994
12995function completeUnitOfWork(unitOfWork) {
12996 // Attempt to complete the current unit of work, then move to the next
12997 // sibling. If there are no more siblings, return to the parent fiber.
12998 workInProgress = unitOfWork;
12999 do {
13000 // The current, flushed, state of this fiber is the alternate. Ideally
13001 // nothing should rely on this, but relying on it here means that we don't
13002 // need an additional field on the work in progress.
13003 var current$$1 = workInProgress.alternate;
13004 var returnFiber = workInProgress.return;
13005
13006 // Check if the work completed or if something threw.
13007 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
13008 setCurrentFiber(workInProgress);
13009 var next = void 0;
13010 if (!enableProfilerTimer || (workInProgress.mode & ProfileMode) === NoMode) {
13011 next = completeWork(current$$1, workInProgress, renderExpirationTime);
13012 } else {
13013 startProfilerTimer(workInProgress);
13014 next = completeWork(current$$1, workInProgress, renderExpirationTime);
13015 // Update render duration assuming we didn't error.
13016 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
13017 }
13018 stopWorkTimer(workInProgress);
13019 resetCurrentFiber();
13020 resetChildExpirationTime(workInProgress);
13021
13022 if (next !== null) {
13023 // Completing this fiber spawned new work. Work on that next.
13024 return next;
13025 }
13026
13027 if (returnFiber !== null &&
13028 // Do not append effects to parents if a sibling failed to complete
13029 (returnFiber.effectTag & Incomplete) === NoEffect) {
13030 // Append all the effects of the subtree and this fiber onto the effect
13031 // list of the parent. The completion order of the children affects the
13032 // side-effect order.
13033 if (returnFiber.firstEffect === null) {
13034 returnFiber.firstEffect = workInProgress.firstEffect;
13035 }
13036 if (workInProgress.lastEffect !== null) {
13037 if (returnFiber.lastEffect !== null) {
13038 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
13039 }
13040 returnFiber.lastEffect = workInProgress.lastEffect;
13041 }
13042
13043 // If this fiber had side-effects, we append it AFTER the children's
13044 // side-effects. We can perform certain side-effects earlier if needed,
13045 // by doing multiple passes over the effect list. We don't want to
13046 // schedule our own side-effect on our own list because if end up
13047 // reusing children we'll schedule this effect onto itself since we're
13048 // at the end.
13049 var effectTag = workInProgress.effectTag;
13050
13051 // Skip both NoWork and PerformedWork tags when creating the effect
13052 // list. PerformedWork effect is read by React DevTools but shouldn't be
13053 // committed.
13054 if (effectTag > PerformedWork) {
13055 if (returnFiber.lastEffect !== null) {
13056 returnFiber.lastEffect.nextEffect = workInProgress;
13057 } else {
13058 returnFiber.firstEffect = workInProgress;
13059 }
13060 returnFiber.lastEffect = workInProgress;
13061 }
13062 }
13063 } else {
13064 // This fiber did not complete because something threw. Pop values off
13065 // the stack without entering the complete phase. If this is a boundary,
13066 // capture values if possible.
13067 var _next = unwindWork(workInProgress, renderExpirationTime);
13068
13069 // Because this fiber did not complete, don't reset its expiration time.
13070
13071 if (enableProfilerTimer && (workInProgress.mode & ProfileMode) !== NoMode) {
13072 // Record the render duration for the fiber that errored.
13073 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
13074
13075 // Include the time spent working on failed children before continuing.
13076 var actualDuration = workInProgress.actualDuration;
13077 var child = workInProgress.child;
13078 while (child !== null) {
13079 actualDuration += child.actualDuration;
13080 child = child.sibling;
13081 }
13082 workInProgress.actualDuration = actualDuration;
13083 }
13084
13085 if (_next !== null) {
13086 // If completing this work spawned new work, do that next. We'll come
13087 // back here again.
13088 // Since we're restarting, remove anything that is not a host effect
13089 // from the effect tag.
13090 // TODO: The name stopFailedWorkTimer is misleading because Suspense
13091 // also captures and restarts.
13092 stopFailedWorkTimer(workInProgress);
13093 _next.effectTag &= HostEffectMask;
13094 return _next;
13095 }
13096 stopWorkTimer(workInProgress);
13097
13098 if (returnFiber !== null) {
13099 // Mark the parent fiber as incomplete and clear its effect list.
13100 returnFiber.firstEffect = returnFiber.lastEffect = null;
13101 returnFiber.effectTag |= Incomplete;
13102 }
13103 }
13104
13105 var siblingFiber = workInProgress.sibling;
13106 if (siblingFiber !== null) {
13107 // If there is more work to do in this returnFiber, do that next.
13108 return siblingFiber;
13109 }
13110 // Otherwise, return to the parent
13111 workInProgress = returnFiber;
13112 } while (workInProgress !== null);
13113
13114 // We've reached the root.
13115 if (workInProgressRootExitStatus === RootIncomplete) {
13116 workInProgressRootExitStatus = RootCompleted;
13117 }
13118 return null;
13119}
13120
13121function resetChildExpirationTime(completedWork) {
13122 if (renderExpirationTime !== Never && completedWork.childExpirationTime === Never) {
13123 // The children of this component are hidden. Don't bubble their
13124 // expiration times.
13125 return;
13126 }
13127
13128 var newChildExpirationTime = NoWork;
13129
13130 // Bubble up the earliest expiration time.
13131 if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) {
13132 // In profiling mode, resetChildExpirationTime is also used to reset
13133 // profiler durations.
13134 var actualDuration = completedWork.actualDuration;
13135 var treeBaseDuration = completedWork.selfBaseDuration;
13136
13137 // When a fiber is cloned, its actualDuration is reset to 0. This value will
13138 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
13139 // When work is done, it should bubble to the parent's actualDuration. If
13140 // the fiber has not been cloned though, (meaning no work was done), then
13141 // this value will reflect the amount of time spent working on a previous
13142 // render. In that case it should not bubble. We determine whether it was
13143 // cloned by comparing the child pointer.
13144 var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;
13145
13146 var child = completedWork.child;
13147 while (child !== null) {
13148 var childUpdateExpirationTime = child.expirationTime;
13149 var childChildExpirationTime = child.childExpirationTime;
13150 if (childUpdateExpirationTime > newChildExpirationTime) {
13151 newChildExpirationTime = childUpdateExpirationTime;
13152 }
13153 if (childChildExpirationTime > newChildExpirationTime) {
13154 newChildExpirationTime = childChildExpirationTime;
13155 }
13156 if (shouldBubbleActualDurations) {
13157 actualDuration += child.actualDuration;
13158 }
13159 treeBaseDuration += child.treeBaseDuration;
13160 child = child.sibling;
13161 }
13162 completedWork.actualDuration = actualDuration;
13163 completedWork.treeBaseDuration = treeBaseDuration;
13164 } else {
13165 var _child = completedWork.child;
13166 while (_child !== null) {
13167 var _childUpdateExpirationTime = _child.expirationTime;
13168 var _childChildExpirationTime = _child.childExpirationTime;
13169 if (_childUpdateExpirationTime > newChildExpirationTime) {
13170 newChildExpirationTime = _childUpdateExpirationTime;
13171 }
13172 if (_childChildExpirationTime > newChildExpirationTime) {
13173 newChildExpirationTime = _childChildExpirationTime;
13174 }
13175 _child = _child.sibling;
13176 }
13177 }
13178
13179 completedWork.childExpirationTime = newChildExpirationTime;
13180}
13181
13182function commitRoot(root) {
13183 var renderPriorityLevel = getCurrentPriorityLevel();
13184 runWithPriority(ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel));
13185 // If there are passive effects, schedule a callback to flush them. This goes
13186 // outside commitRootImpl so that it inherits the priority of the render.
13187 if (rootWithPendingPassiveEffects !== null) {
13188 scheduleCallback(NormalPriority, function () {
13189 flushPassiveEffects();
13190 return null;
13191 });
13192 }
13193 return null;
13194}
13195
13196function commitRootImpl(root, renderPriorityLevel) {
13197 flushPassiveEffects();
13198 flushRenderPhaseStrictModeWarningsInDEV();
13199
13200 (function () {
13201 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
13202 {
13203 throw ReactError(Error('Should not already be working.'));
13204 }
13205 }
13206 })();
13207
13208 var finishedWork = root.finishedWork;
13209 var expirationTime = root.finishedExpirationTime;
13210 if (finishedWork === null) {
13211 return null;
13212 }
13213 root.finishedWork = null;
13214 root.finishedExpirationTime = NoWork;
13215
13216 (function () {
13217 if (!(finishedWork !== root.current)) {
13218 {
13219 throw ReactError(Error('Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue.'));
13220 }
13221 }
13222 })();
13223
13224 // commitRoot never returns a continuation; it always finishes synchronously.
13225 // So we can clear these now to allow a new callback to be scheduled.
13226 root.callbackNode = null;
13227 root.callbackExpirationTime = NoWork;
13228
13229 startCommitTimer();
13230
13231 // Update the first and last pending times on this root. The new first
13232 // pending time is whatever is left on the root fiber.
13233 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime;
13234 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;
13235 var firstPendingTimeBeforeCommit = childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit ? childExpirationTimeBeforeCommit : updateExpirationTimeBeforeCommit;
13236 root.firstPendingTime = firstPendingTimeBeforeCommit;
13237 if (firstPendingTimeBeforeCommit < root.lastPendingTime) {
13238 // This usually means we've finished all the work, but it can also happen
13239 // when something gets downprioritized during render, like a hidden tree.
13240 root.lastPendingTime = firstPendingTimeBeforeCommit;
13241 }
13242
13243 if (root === workInProgressRoot) {
13244 // We can reset these now that they are finished.
13245 workInProgressRoot = null;
13246 workInProgress = null;
13247 renderExpirationTime = NoWork;
13248 } else {}
13249 // This indicates that the last root we worked on is not the same one that
13250 // we're committing now. This most commonly happens when a suspended root
13251 // times out.
13252
13253
13254 // Get the list of effects.
13255 var firstEffect = void 0;
13256 if (finishedWork.effectTag > PerformedWork) {
13257 // A fiber's effect list consists only of its children, not itself. So if
13258 // the root has an effect, we need to add it to the end of the list. The
13259 // resulting list is the set that would belong to the root's parent, if it
13260 // had one; that is, all the effects in the tree including the root.
13261 if (finishedWork.lastEffect !== null) {
13262 finishedWork.lastEffect.nextEffect = finishedWork;
13263 firstEffect = finishedWork.firstEffect;
13264 } else {
13265 firstEffect = finishedWork;
13266 }
13267 } else {
13268 // There is no effect on the root.
13269 firstEffect = finishedWork.firstEffect;
13270 }
13271
13272 if (firstEffect !== null) {
13273 var prevExecutionContext = executionContext;
13274 executionContext |= CommitContext;
13275 var prevInteractions = null;
13276 if (enableSchedulerTracing) {
13277 prevInteractions = tracing.__interactionsRef.current;
13278 tracing.__interactionsRef.current = root.memoizedInteractions;
13279 }
13280
13281 // Reset this to null before calling lifecycles
13282 ReactCurrentOwner$1.current = null;
13283
13284 // The commit phase is broken into several sub-phases. We do a separate pass
13285 // of the effect list for each phase: all mutation effects come before all
13286 // layout effects, and so on.
13287
13288 // The first phase a "before mutation" phase. We use this phase to read the
13289 // state of the host tree right before we mutate it. This is where
13290 // getSnapshotBeforeUpdate is called.
13291 startCommitSnapshotEffectsTimer();
13292 prepareForCommit(root.containerInfo);
13293 nextEffect = firstEffect;
13294 do {
13295 {
13296 invokeGuardedCallback(null, commitBeforeMutationEffects, null);
13297 if (hasCaughtError()) {
13298 (function () {
13299 if (!(nextEffect !== null)) {
13300 {
13301 throw ReactError(Error('Should be working on an effect.'));
13302 }
13303 }
13304 })();
13305 var error = clearCaughtError();
13306 captureCommitPhaseError(nextEffect, error);
13307 nextEffect = nextEffect.nextEffect;
13308 }
13309 }
13310 } while (nextEffect !== null);
13311 stopCommitSnapshotEffectsTimer();
13312
13313 if (enableProfilerTimer) {
13314 // Mark the current commit time to be shared by all Profilers in this
13315 // batch. This enables them to be grouped later.
13316 recordCommitTime();
13317 }
13318
13319 // The next phase is the mutation phase, where we mutate the host tree.
13320 startCommitHostEffectsTimer();
13321 nextEffect = firstEffect;
13322 do {
13323 {
13324 invokeGuardedCallback(null, commitMutationEffects, null, renderPriorityLevel);
13325 if (hasCaughtError()) {
13326 (function () {
13327 if (!(nextEffect !== null)) {
13328 {
13329 throw ReactError(Error('Should be working on an effect.'));
13330 }
13331 }
13332 })();
13333 var _error = clearCaughtError();
13334 captureCommitPhaseError(nextEffect, _error);
13335 nextEffect = nextEffect.nextEffect;
13336 }
13337 }
13338 } while (nextEffect !== null);
13339 stopCommitHostEffectsTimer();
13340 resetAfterCommit(root.containerInfo);
13341
13342 // The work-in-progress tree is now the current tree. This must come after
13343 // the mutation phase, so that the previous tree is still current during
13344 // componentWillUnmount, but before the layout phase, so that the finished
13345 // work is current during componentDidMount/Update.
13346 root.current = finishedWork;
13347
13348 // The next phase is the layout phase, where we call effects that read
13349 // the host tree after it's been mutated. The idiomatic use case for this is
13350 // layout, but class component lifecycles also fire here for legacy reasons.
13351 startCommitLifeCyclesTimer();
13352 nextEffect = firstEffect;
13353 do {
13354 {
13355 invokeGuardedCallback(null, commitLayoutEffects, null, root, expirationTime);
13356 if (hasCaughtError()) {
13357 (function () {
13358 if (!(nextEffect !== null)) {
13359 {
13360 throw ReactError(Error('Should be working on an effect.'));
13361 }
13362 }
13363 })();
13364 var _error2 = clearCaughtError();
13365 captureCommitPhaseError(nextEffect, _error2);
13366 nextEffect = nextEffect.nextEffect;
13367 }
13368 }
13369 } while (nextEffect !== null);
13370 stopCommitLifeCyclesTimer();
13371
13372 nextEffect = null;
13373
13374 // Tell Scheduler to yield at the end of the frame, so the browser has an
13375 // opportunity to paint.
13376 requestPaint();
13377
13378 if (enableSchedulerTracing) {
13379 tracing.__interactionsRef.current = prevInteractions;
13380 }
13381 executionContext = prevExecutionContext;
13382 } else {
13383 // No effects.
13384 root.current = finishedWork;
13385 // Measure these anyway so the flamegraph explicitly shows that there were
13386 // no effects.
13387 // TODO: Maybe there's a better way to report this.
13388 startCommitSnapshotEffectsTimer();
13389 stopCommitSnapshotEffectsTimer();
13390 if (enableProfilerTimer) {
13391 recordCommitTime();
13392 }
13393 startCommitHostEffectsTimer();
13394 stopCommitHostEffectsTimer();
13395 startCommitLifeCyclesTimer();
13396 stopCommitLifeCyclesTimer();
13397 }
13398
13399 stopCommitTimer();
13400
13401 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
13402
13403 if (rootDoesHavePassiveEffects) {
13404 // This commit has passive effects. Stash a reference to them. But don't
13405 // schedule a callback until after flushing layout work.
13406 rootDoesHavePassiveEffects = false;
13407 rootWithPendingPassiveEffects = root;
13408 pendingPassiveEffectsExpirationTime = expirationTime;
13409 pendingPassiveEffectsRenderPriority = renderPriorityLevel;
13410 } else {
13411 // We are done with the effect chain at this point so let's clear the
13412 // nextEffect pointers to assist with GC. If we have passive effects, we'll
13413 // clear this in flushPassiveEffects.
13414 nextEffect = firstEffect;
13415 while (nextEffect !== null) {
13416 var nextNextEffect = nextEffect.nextEffect;
13417 nextEffect.nextEffect = null;
13418 nextEffect = nextNextEffect;
13419 }
13420 }
13421
13422 // Check if there's remaining work on this root
13423 var remainingExpirationTime = root.firstPendingTime;
13424 if (remainingExpirationTime !== NoWork) {
13425 var currentTime = requestCurrentTime();
13426 var priorityLevel = inferPriorityFromExpirationTime(currentTime, remainingExpirationTime);
13427
13428 if (enableSchedulerTracing) {
13429 if (spawnedWorkDuringRender !== null) {
13430 var expirationTimes = spawnedWorkDuringRender;
13431 spawnedWorkDuringRender = null;
13432 for (var i = 0; i < expirationTimes.length; i++) {
13433 scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);
13434 }
13435 }
13436 }
13437
13438 scheduleCallbackForRoot(root, priorityLevel, remainingExpirationTime);
13439 } else {
13440 // If there's no remaining work, we can clear the set of already failed
13441 // error boundaries.
13442 legacyErrorBoundariesThatAlreadyFailed = null;
13443 }
13444
13445 if (enableSchedulerTracing) {
13446 if (!rootDidHavePassiveEffects) {
13447 // If there are no passive effects, then we can complete the pending interactions.
13448 // Otherwise, we'll wait until after the passive effects are flushed.
13449 // Wait to do this until after remaining work has been scheduled,
13450 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.
13451 finishPendingInteractions(root, expirationTime);
13452 }
13453 }
13454
13455 onCommitRoot(finishedWork.stateNode, expirationTime);
13456
13457 if (remainingExpirationTime === Sync) {
13458 // Count the number of times the root synchronously re-renders without
13459 // finishing. If there are too many, it indicates an infinite update loop.
13460 if (root === rootWithNestedUpdates) {
13461 nestedUpdateCount++;
13462 } else {
13463 nestedUpdateCount = 0;
13464 rootWithNestedUpdates = root;
13465 }
13466 } else {
13467 nestedUpdateCount = 0;
13468 }
13469
13470 if (hasUncaughtError) {
13471 hasUncaughtError = false;
13472 var _error3 = firstUncaughtError;
13473 firstUncaughtError = null;
13474 throw _error3;
13475 }
13476
13477 if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
13478 // This is a legacy edge case. We just committed the initial mount of
13479 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
13480 // synchronously, but layout updates should be deferred until the end
13481 // of the batch.
13482 return null;
13483 }
13484
13485 // If layout work was scheduled, flush it now.
13486 flushSyncCallbackQueue();
13487 return null;
13488}
13489
13490function commitBeforeMutationEffects() {
13491 while (nextEffect !== null) {
13492 if ((nextEffect.effectTag & Snapshot) !== NoEffect) {
13493 setCurrentFiber(nextEffect);
13494 recordEffect();
13495
13496 var current$$1 = nextEffect.alternate;
13497 commitBeforeMutationLifeCycles(current$$1, nextEffect);
13498
13499 resetCurrentFiber();
13500 }
13501 nextEffect = nextEffect.nextEffect;
13502 }
13503}
13504
13505function commitMutationEffects(renderPriorityLevel) {
13506 // TODO: Should probably move the bulk of this function to commitWork.
13507 while (nextEffect !== null) {
13508 setCurrentFiber(nextEffect);
13509
13510 var effectTag = nextEffect.effectTag;
13511
13512 if (effectTag & ContentReset) {
13513 commitResetTextContent(nextEffect);
13514 }
13515
13516 if (effectTag & Ref) {
13517 var current$$1 = nextEffect.alternate;
13518 if (current$$1 !== null) {
13519 commitDetachRef(current$$1);
13520 }
13521 }
13522
13523 // The following switch statement is only concerned about placement,
13524 // updates, and deletions. To avoid needing to add a case for every possible
13525 // bitmap value, we remove the secondary effects from the effect tag and
13526 // switch on that value.
13527 var primaryEffectTag = effectTag & (Placement | Update | Deletion);
13528 switch (primaryEffectTag) {
13529 case Placement:
13530 {
13531 commitPlacement(nextEffect);
13532 // Clear the "placement" from effect tag so that we know that this is
13533 // inserted, before any life-cycles like componentDidMount gets called.
13534 // TODO: findDOMNode doesn't rely on this any more but isMounted does
13535 // and isMounted is deprecated anyway so we should be able to kill this.
13536 nextEffect.effectTag &= ~Placement;
13537 break;
13538 }
13539 case PlacementAndUpdate:
13540 {
13541 // Placement
13542 commitPlacement(nextEffect);
13543 // Clear the "placement" from effect tag so that we know that this is
13544 // inserted, before any life-cycles like componentDidMount gets called.
13545 nextEffect.effectTag &= ~Placement;
13546
13547 // Update
13548 var _current = nextEffect.alternate;
13549 commitWork(_current, nextEffect);
13550 break;
13551 }
13552 case Update:
13553 {
13554 var _current2 = nextEffect.alternate;
13555 commitWork(_current2, nextEffect);
13556 break;
13557 }
13558 case Deletion:
13559 {
13560 commitDeletion(nextEffect, renderPriorityLevel);
13561 break;
13562 }
13563 }
13564
13565 // TODO: Only record a mutation effect if primaryEffectTag is non-zero.
13566 recordEffect();
13567
13568 resetCurrentFiber();
13569 nextEffect = nextEffect.nextEffect;
13570 }
13571}
13572
13573function commitLayoutEffects(root, committedExpirationTime) {
13574 // TODO: Should probably move the bulk of this function to commitWork.
13575 while (nextEffect !== null) {
13576 setCurrentFiber(nextEffect);
13577
13578 var effectTag = nextEffect.effectTag;
13579
13580 if (effectTag & (Update | Callback)) {
13581 recordEffect();
13582 var current$$1 = nextEffect.alternate;
13583 commitLifeCycles(root, current$$1, nextEffect, committedExpirationTime);
13584 }
13585
13586 if (effectTag & Ref) {
13587 recordEffect();
13588 commitAttachRef(nextEffect);
13589 }
13590
13591 if (effectTag & Passive) {
13592 rootDoesHavePassiveEffects = true;
13593 }
13594
13595 resetCurrentFiber();
13596 nextEffect = nextEffect.nextEffect;
13597 }
13598}
13599
13600function flushPassiveEffects() {
13601 if (rootWithPendingPassiveEffects === null) {
13602 return false;
13603 }
13604 var root = rootWithPendingPassiveEffects;
13605 var expirationTime = pendingPassiveEffectsExpirationTime;
13606 var renderPriorityLevel = pendingPassiveEffectsRenderPriority;
13607 rootWithPendingPassiveEffects = null;
13608 pendingPassiveEffectsExpirationTime = NoWork;
13609 pendingPassiveEffectsRenderPriority = NoPriority;
13610 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
13611 return runWithPriority(priorityLevel, flushPassiveEffectsImpl.bind(null, root, expirationTime));
13612}
13613
13614function flushPassiveEffectsImpl(root, expirationTime) {
13615 var prevInteractions = null;
13616 if (enableSchedulerTracing) {
13617 prevInteractions = tracing.__interactionsRef.current;
13618 tracing.__interactionsRef.current = root.memoizedInteractions;
13619 }
13620
13621 (function () {
13622 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
13623 {
13624 throw ReactError(Error('Cannot flush passive effects while already rendering.'));
13625 }
13626 }
13627 })();
13628 var prevExecutionContext = executionContext;
13629 executionContext |= CommitContext;
13630
13631 // Note: This currently assumes there are no passive effects on the root
13632 // fiber, because the root is not part of its own effect list. This could
13633 // change in the future.
13634 var effect = root.current.firstEffect;
13635 while (effect !== null) {
13636 {
13637 setCurrentFiber(effect);
13638 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
13639 if (hasCaughtError()) {
13640 (function () {
13641 if (!(effect !== null)) {
13642 {
13643 throw ReactError(Error('Should be working on an effect.'));
13644 }
13645 }
13646 })();
13647 var error = clearCaughtError();
13648 captureCommitPhaseError(effect, error);
13649 }
13650 resetCurrentFiber();
13651 }
13652 var nextNextEffect = effect.nextEffect;
13653 // Remove nextEffect pointer to assist GC
13654 effect.nextEffect = null;
13655 effect = nextNextEffect;
13656 }
13657
13658 if (enableSchedulerTracing) {
13659 tracing.__interactionsRef.current = prevInteractions;
13660 finishPendingInteractions(root, expirationTime);
13661 }
13662
13663 executionContext = prevExecutionContext;
13664 flushSyncCallbackQueue();
13665
13666 // If additional passive effects were scheduled, increment a counter. If this
13667 // exceeds the limit, we'll fire a warning.
13668 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
13669
13670 return true;
13671}
13672
13673function isAlreadyFailedLegacyErrorBoundary(instance) {
13674 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
13675}
13676
13677function markLegacyErrorBoundaryAsFailed(instance) {
13678 if (legacyErrorBoundariesThatAlreadyFailed === null) {
13679 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
13680 } else {
13681 legacyErrorBoundariesThatAlreadyFailed.add(instance);
13682 }
13683}
13684
13685function prepareToThrowUncaughtError(error) {
13686 if (!hasUncaughtError) {
13687 hasUncaughtError = true;
13688 firstUncaughtError = error;
13689 }
13690}
13691var onUncaughtError = prepareToThrowUncaughtError;
13692
13693function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
13694 var errorInfo = createCapturedValue(error, sourceFiber);
13695 var update = createRootErrorUpdate(rootFiber, errorInfo, Sync);
13696 enqueueUpdate(rootFiber, update);
13697 var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);
13698 if (root !== null) {
13699 scheduleCallbackForRoot(root, ImmediatePriority, Sync);
13700 }
13701}
13702
13703function captureCommitPhaseError(sourceFiber, error) {
13704 if (sourceFiber.tag === HostRoot) {
13705 // Error was thrown at the root. There is no parent, so the root
13706 // itself should capture it.
13707 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);
13708 return;
13709 }
13710
13711 var fiber = sourceFiber.return;
13712 while (fiber !== null) {
13713 if (fiber.tag === HostRoot) {
13714 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);
13715 return;
13716 } else if (fiber.tag === ClassComponent) {
13717 var ctor = fiber.type;
13718 var instance = fiber.stateNode;
13719 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
13720 var errorInfo = createCapturedValue(error, sourceFiber);
13721 var update = createClassErrorUpdate(fiber, errorInfo,
13722 // TODO: This is always sync
13723 Sync);
13724 enqueueUpdate(fiber, update);
13725 var root = markUpdateTimeFromFiberToRoot(fiber, Sync);
13726 if (root !== null) {
13727 scheduleCallbackForRoot(root, ImmediatePriority, Sync);
13728 }
13729 return;
13730 }
13731 }
13732 fiber = fiber.return;
13733 }
13734}
13735
13736function pingSuspendedRoot(root, thenable, suspendedTime) {
13737 var pingCache = root.pingCache;
13738 if (pingCache !== null) {
13739 // The thenable resolved, so we no longer need to memoize, because it will
13740 // never be thrown again.
13741 pingCache.delete(thenable);
13742 }
13743
13744 if (workInProgressRoot === root && renderExpirationTime === suspendedTime) {
13745 // Received a ping at the same priority level at which we're currently
13746 // rendering. We might want to restart this render. This should mirror
13747 // the logic of whether or not a root suspends once it completes.
13748
13749 // TODO: If we're rendering sync either due to Sync, Batched or expired,
13750 // we should probably never restart.
13751
13752 // If we're suspended with delay, we'll always suspend so we can always
13753 // restart. If we're suspended without any updates, it might be a retry.
13754 // If it's early in the retry we can restart. We can't know for sure
13755 // whether we'll eventually process an update during this render pass,
13756 // but it's somewhat unlikely that we get to a ping before that, since
13757 // getting to the root most update is usually very fast.
13758 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && workInProgressRootLatestProcessedExpirationTime === Sync && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
13759 // Restart from the root. Don't need to schedule a ping because
13760 // we're already working on this tree.
13761 prepareFreshStack(root, renderExpirationTime);
13762 } else {
13763 // Even though we can't restart right now, we might get an
13764 // opportunity later. So we mark this render as having a ping.
13765 workInProgressRootHasPendingPing = true;
13766 }
13767 return;
13768 }
13769
13770 var lastPendingTime = root.lastPendingTime;
13771 if (lastPendingTime < suspendedTime) {
13772 // The root is no longer suspended at this time.
13773 return;
13774 }
13775
13776 var pingTime = root.pingTime;
13777 if (pingTime !== NoWork && pingTime < suspendedTime) {
13778 // There's already a lower priority ping scheduled.
13779 return;
13780 }
13781
13782 // Mark the time at which this ping was scheduled.
13783 root.pingTime = suspendedTime;
13784
13785 if (root.finishedExpirationTime === suspendedTime) {
13786 // If there's a pending fallback waiting to commit, throw it away.
13787 root.finishedExpirationTime = NoWork;
13788 root.finishedWork = null;
13789 }
13790
13791 var currentTime = requestCurrentTime();
13792 var priorityLevel = inferPriorityFromExpirationTime(currentTime, suspendedTime);
13793 scheduleCallbackForRoot(root, priorityLevel, suspendedTime);
13794}
13795
13796function retryTimedOutBoundary(boundaryFiber) {
13797 // The boundary fiber (a Suspense component or SuspenseList component)
13798 // previously was rendered in its fallback state. One of the promises that
13799 // suspended it has resolved, which means at least part of the tree was
13800 // likely unblocked. Try rendering again, at a new expiration time.
13801 var currentTime = requestCurrentTime();
13802 var suspenseConfig = null; // Retries don't carry over the already committed update.
13803 var retryTime = computeExpirationForFiber(currentTime, boundaryFiber, suspenseConfig);
13804 // TODO: Special case idle priority?
13805 var priorityLevel = inferPriorityFromExpirationTime(currentTime, retryTime);
13806 var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);
13807 if (root !== null) {
13808 scheduleCallbackForRoot(root, priorityLevel, retryTime);
13809 }
13810}
13811
13812function resolveRetryThenable(boundaryFiber, thenable) {
13813 var retryCache = void 0;
13814 if (enableSuspenseServerRenderer) {
13815 switch (boundaryFiber.tag) {
13816 case SuspenseComponent:
13817 retryCache = boundaryFiber.stateNode;
13818 break;
13819 case DehydratedSuspenseComponent:
13820 retryCache = boundaryFiber.memoizedState;
13821 break;
13822 default:
13823 (function () {
13824 {
13825 {
13826 throw ReactError(Error('Pinged unknown suspense boundary type. This is probably a bug in React.'));
13827 }
13828 }
13829 })();
13830 }
13831 } else {
13832 retryCache = boundaryFiber.stateNode;
13833 }
13834
13835 if (retryCache !== null) {
13836 // The thenable resolved, so we no longer need to memoize, because it will
13837 // never be thrown again.
13838 retryCache.delete(thenable);
13839 }
13840
13841 retryTimedOutBoundary(boundaryFiber);
13842}
13843
13844// Computes the next Just Noticeable Difference (JND) boundary.
13845// The theory is that a person can't tell the difference between small differences in time.
13846// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
13847// difference in the experience. However, waiting for longer might mean that we can avoid
13848// showing an intermediate loading state. The longer we have already waited, the harder it
13849// is to tell small differences in time. Therefore, the longer we've already waited,
13850// the longer we can wait additionally. At some point we have to give up though.
13851// We pick a train model where the next boundary commits at a consistent schedule.
13852// These particular numbers are vague estimates. We expect to adjust them based on research.
13853function jnd(timeElapsed) {
13854 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
13855}
13856
13857function computeMsUntilSuspenseLoadingDelay(mostRecentEventTime, committedExpirationTime, suspenseConfig) {
13858 var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0;
13859 if (busyMinDurationMs <= 0) {
13860 return 0;
13861 }
13862 var busyDelayMs = suspenseConfig.busyDelayMs | 0;
13863
13864 // Compute the time until this render pass would expire.
13865 var currentTimeMs = now();
13866 var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig(mostRecentEventTime, suspenseConfig);
13867 var timeElapsed = currentTimeMs - eventTimeMs;
13868 if (timeElapsed <= busyDelayMs) {
13869 // If we haven't yet waited longer than the initial delay, we don't
13870 // have to wait any additional time.
13871 return 0;
13872 }
13873 var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed;
13874 // This is the value that is passed to `setTimeout`.
13875 return msUntilTimeout;
13876}
13877
13878function checkForNestedUpdates() {
13879 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
13880 nestedUpdateCount = 0;
13881 rootWithNestedUpdates = null;
13882 (function () {
13883 {
13884 {
13885 throw ReactError(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.'));
13886 }
13887 }
13888 })();
13889 }
13890
13891 {
13892 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
13893 nestedPassiveUpdateCount = 0;
13894 warning$1(false, '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.');
13895 }
13896 }
13897}
13898
13899function flushRenderPhaseStrictModeWarningsInDEV() {
13900 {
13901 ReactStrictModeWarnings.flushLegacyContextWarning();
13902
13903 if (warnAboutDeprecatedLifecycles) {
13904 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
13905 }
13906 }
13907}
13908
13909function stopFinishedWorkLoopTimer() {
13910 var didCompleteRoot = true;
13911 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
13912 interruptedBy = null;
13913}
13914
13915function stopInterruptedWorkLoopTimer() {
13916 // TODO: Track which fiber caused the interruption.
13917 var didCompleteRoot = false;
13918 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
13919 interruptedBy = null;
13920}
13921
13922function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) {
13923 if (enableUserTimingAPI && workInProgressRoot !== null && updateExpirationTime > renderExpirationTime) {
13924 interruptedBy = fiberThatReceivedUpdate;
13925 }
13926}
13927
13928var didWarnStateUpdateForUnmountedComponent = null;
13929function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
13930 {
13931 var tag = fiber.tag;
13932 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent) {
13933 // Only warn for user-defined components, not internal ones like Suspense.
13934 return;
13935 }
13936 // We show the whole stack but dedupe on the top component's name because
13937 // the problematic code almost always lies inside that component.
13938 var componentName = getComponentName(fiber.type) || 'ReactComponent';
13939 if (didWarnStateUpdateForUnmountedComponent !== null) {
13940 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {
13941 return;
13942 }
13943 didWarnStateUpdateForUnmountedComponent.add(componentName);
13944 } else {
13945 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);
13946 }
13947 warningWithoutStack$1(false, "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));
13948 }
13949}
13950
13951var beginWork$$1 = void 0;
13952if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
13953 var dummyFiber = null;
13954 beginWork$$1 = function (current$$1, unitOfWork, expirationTime) {
13955 // If a component throws an error, we replay it again in a synchronously
13956 // dispatched event, so that the debugger will treat it as an uncaught
13957 // error See ReactErrorUtils for more information.
13958
13959 // Before entering the begin phase, copy the work-in-progress onto a dummy
13960 // fiber. If beginWork throws, we'll use this to reset the state.
13961 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
13962 try {
13963 return beginWork$1(current$$1, unitOfWork, expirationTime);
13964 } catch (originalError) {
13965 if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {
13966 // Don't replay promises. Treat everything else like an error.
13967 throw originalError;
13968 }
13969
13970 // Keep this code in sync with renderRoot; any changes here must have
13971 // corresponding changes there.
13972 resetContextDependencies();
13973 resetHooks();
13974
13975 // Unwind the failed stack frame
13976 unwindInterruptedWork(unitOfWork);
13977
13978 // Restore the original properties of the fiber.
13979 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
13980
13981 if (enableProfilerTimer && unitOfWork.mode & ProfileMode) {
13982 // Reset the profiler timer.
13983 startProfilerTimer(unitOfWork);
13984 }
13985
13986 // Run beginWork again.
13987 invokeGuardedCallback(null, beginWork$1, null, current$$1, unitOfWork, expirationTime);
13988
13989 if (hasCaughtError()) {
13990 var replayError = clearCaughtError();
13991 // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`.
13992 // Rethrow this error instead of the original one.
13993 throw replayError;
13994 } else {
13995 // This branch is reachable if the render phase is impure.
13996 throw originalError;
13997 }
13998 }
13999 };
14000} else {
14001 beginWork$$1 = beginWork$1;
14002}
14003
14004var didWarnAboutUpdateInRender = false;
14005var didWarnAboutUpdateInGetChildContext = false;
14006function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) {
14007 {
14008 if (fiber.tag === ClassComponent) {
14009 switch (phase) {
14010 case 'getChildContext':
14011 if (didWarnAboutUpdateInGetChildContext) {
14012 return;
14013 }
14014 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
14015 didWarnAboutUpdateInGetChildContext = true;
14016 break;
14017 case 'render':
14018 if (didWarnAboutUpdateInRender) {
14019 return;
14020 }
14021 warningWithoutStack$1(false, 'Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure function of ' + 'props and state.');
14022 didWarnAboutUpdateInRender = true;
14023 break;
14024 }
14025 }
14026 }
14027}
14028
14029// a 'shared' variable that changes when act() opens/closes in tests.
14030var IsThisRendererActing = { current: false };
14031
14032function warnIfNotScopedWithMatchingAct(fiber) {
14033 {
14034 if (warnsIfNotActing === true && IsSomeRendererActing.current === true && IsThisRendererActing.current !== true) {
14035 warningWithoutStack$1(false, "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));
14036 }
14037 }
14038}
14039
14040function warnIfNotCurrentlyActingEffectsInDEV(fiber) {
14041 {
14042 if (warnsIfNotActing === true && (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
14043 warningWithoutStack$1(false, '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));
14044 }
14045 }
14046}
14047
14048function warnIfNotCurrentlyActingUpdatesInDEV(fiber) {
14049 {
14050 if (warnsIfNotActing === true && executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
14051 warningWithoutStack$1(false, '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));
14052 }
14053 }
14054}
14055
14056var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV;
14057
14058// In tests, we want to enforce a mocked scheduler.
14059var didWarnAboutUnmockedScheduler = false;
14060// TODO Before we release concurrent mode, revisit this and decide whether a mocked
14061// scheduler is the actual recommendation. The alternative could be a testing build,
14062// a new lib, or whatever; we dunno just yet. This message is for early adopters
14063// to get their tests right.
14064
14065function warnIfUnmockedScheduler(fiber) {
14066 {
14067 if (didWarnAboutUnmockedScheduler === false && Scheduler$1.unstable_flushAllWithoutAsserting === undefined) {
14068 if (fiber.mode & BatchedMode || fiber.mode & ConcurrentMode) {
14069 didWarnAboutUnmockedScheduler = true;
14070 warningWithoutStack$1(false, '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');
14071 } else if (warnAboutUnmockedScheduler === true) {
14072 didWarnAboutUnmockedScheduler = true;
14073 warningWithoutStack$1(false, 'Starting from React v17, the "scheduler" module will need 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');
14074 }
14075 }
14076 }
14077}
14078
14079var componentsThatTriggeredHighPriSuspend = null;
14080function checkForWrongSuspensePriorityInDEV(sourceFiber) {
14081 {
14082 var currentPriorityLevel = getCurrentPriorityLevel();
14083 if ((sourceFiber.mode & ConcurrentMode) !== NoEffect && (currentPriorityLevel === UserBlockingPriority || currentPriorityLevel === ImmediatePriority)) {
14084 var workInProgressNode = sourceFiber;
14085 while (workInProgressNode !== null) {
14086 // Add the component that triggered the suspense
14087 var current$$1 = workInProgressNode.alternate;
14088 if (current$$1 !== null) {
14089 // TODO: warn component that triggers the high priority
14090 // suspend is the HostRoot
14091 switch (workInProgressNode.tag) {
14092 case ClassComponent:
14093 // Loop through the component's update queue and see whether the component
14094 // has triggered any high priority updates
14095 var updateQueue = current$$1.updateQueue;
14096 if (updateQueue !== null) {
14097 var update = updateQueue.firstUpdate;
14098 while (update !== null) {
14099 var priorityLevel = update.priority;
14100 if (priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority) {
14101 if (componentsThatTriggeredHighPriSuspend === null) {
14102 componentsThatTriggeredHighPriSuspend = new Set([getComponentName(workInProgressNode.type)]);
14103 } else {
14104 componentsThatTriggeredHighPriSuspend.add(getComponentName(workInProgressNode.type));
14105 }
14106 break;
14107 }
14108 update = update.next;
14109 }
14110 }
14111 break;
14112 case FunctionComponent:
14113 case ForwardRef:
14114 case SimpleMemoComponent:
14115 if (workInProgressNode.memoizedState !== null && workInProgressNode.memoizedState.baseUpdate !== null) {
14116 var _update = workInProgressNode.memoizedState.baseUpdate;
14117 // Loop through the functional component's memoized state to see whether
14118 // the component has triggered any high pri updates
14119 while (_update !== null) {
14120 var priority = _update.priority;
14121 if (priority === UserBlockingPriority || priority === ImmediatePriority) {
14122 if (componentsThatTriggeredHighPriSuspend === null) {
14123 componentsThatTriggeredHighPriSuspend = new Set([getComponentName(workInProgressNode.type)]);
14124 } else {
14125 componentsThatTriggeredHighPriSuspend.add(getComponentName(workInProgressNode.type));
14126 }
14127 break;
14128 }
14129 if (_update.next === workInProgressNode.memoizedState.baseUpdate) {
14130 break;
14131 }
14132 _update = _update.next;
14133 }
14134 }
14135 break;
14136 default:
14137 break;
14138 }
14139 }
14140 workInProgressNode = workInProgressNode.return;
14141 }
14142 }
14143 }
14144}
14145
14146function flushSuspensePriorityWarningInDEV() {
14147 {
14148 if (componentsThatTriggeredHighPriSuspend !== null) {
14149 var componentNames = [];
14150 componentsThatTriggeredHighPriSuspend.forEach(function (name) {
14151 return componentNames.push(name);
14152 });
14153 componentsThatTriggeredHighPriSuspend = null;
14154
14155 if (componentNames.length > 0) {
14156 warningWithoutStack$1(false, '%s triggered a user-blocking update that suspended.' + '\n\n' + 'The fix is to split the update into multiple parts: a user-blocking ' + 'update to provide immediate feedback, and another update that ' + 'triggers the bulk of the changes.' + '\n\n' + 'Refer to the documentation for useSuspenseTransition to learn how ' + 'to implement this pattern.',
14157 // TODO: Add link to React docs with more information, once it exists
14158 componentNames.sort().join(', '));
14159 }
14160 }
14161 }
14162}
14163
14164function computeThreadID(root, expirationTime) {
14165 // Interaction threads are unique per root and expiration time.
14166 return expirationTime * 1000 + root.interactionThreadID;
14167}
14168
14169function markSpawnedWork(expirationTime) {
14170 if (!enableSchedulerTracing) {
14171 return;
14172 }
14173 if (spawnedWorkDuringRender === null) {
14174 spawnedWorkDuringRender = [expirationTime];
14175 } else {
14176 spawnedWorkDuringRender.push(expirationTime);
14177 }
14178}
14179
14180function scheduleInteractions(root, expirationTime, interactions) {
14181 if (!enableSchedulerTracing) {
14182 return;
14183 }
14184
14185 if (interactions.size > 0) {
14186 var pendingInteractionMap = root.pendingInteractionMap;
14187 var pendingInteractions = pendingInteractionMap.get(expirationTime);
14188 if (pendingInteractions != null) {
14189 interactions.forEach(function (interaction) {
14190 if (!pendingInteractions.has(interaction)) {
14191 // Update the pending async work count for previously unscheduled interaction.
14192 interaction.__count++;
14193 }
14194
14195 pendingInteractions.add(interaction);
14196 });
14197 } else {
14198 pendingInteractionMap.set(expirationTime, new Set(interactions));
14199
14200 // Update the pending async work count for the current interactions.
14201 interactions.forEach(function (interaction) {
14202 interaction.__count++;
14203 });
14204 }
14205
14206 var subscriber = tracing.__subscriberRef.current;
14207 if (subscriber !== null) {
14208 var threadID = computeThreadID(root, expirationTime);
14209 subscriber.onWorkScheduled(interactions, threadID);
14210 }
14211 }
14212}
14213
14214function schedulePendingInteractions(root, expirationTime) {
14215 // This is called when work is scheduled on a root.
14216 // It associates the current interactions with the newly-scheduled expiration.
14217 // They will be restored when that expiration is later committed.
14218 if (!enableSchedulerTracing) {
14219 return;
14220 }
14221
14222 scheduleInteractions(root, expirationTime, tracing.__interactionsRef.current);
14223}
14224
14225function startWorkOnPendingInteractions(root, expirationTime) {
14226 // This is called when new work is started on a root.
14227 if (!enableSchedulerTracing) {
14228 return;
14229 }
14230
14231 // Determine which interactions this batch of work currently includes, So that
14232 // we can accurately attribute time spent working on it, And so that cascading
14233 // work triggered during the render phase will be associated with it.
14234 var interactions = new Set();
14235 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
14236 if (scheduledExpirationTime >= expirationTime) {
14237 scheduledInteractions.forEach(function (interaction) {
14238 return interactions.add(interaction);
14239 });
14240 }
14241 });
14242
14243 // Store the current set of interactions on the FiberRoot for a few reasons:
14244 // We can re-use it in hot functions like renderRoot() without having to
14245 // recalculate it. We will also use it in commitWork() to pass to any Profiler
14246 // onRender() hooks. This also provides DevTools with a way to access it when
14247 // the onCommitRoot() hook is called.
14248 root.memoizedInteractions = interactions;
14249
14250 if (interactions.size > 0) {
14251 var subscriber = tracing.__subscriberRef.current;
14252 if (subscriber !== null) {
14253 var threadID = computeThreadID(root, expirationTime);
14254 try {
14255 subscriber.onWorkStarted(interactions, threadID);
14256 } catch (error) {
14257 // If the subscriber throws, rethrow it in a separate task
14258 scheduleCallback(ImmediatePriority, function () {
14259 throw error;
14260 });
14261 }
14262 }
14263 }
14264}
14265
14266function finishPendingInteractions(root, committedExpirationTime) {
14267 if (!enableSchedulerTracing) {
14268 return;
14269 }
14270
14271 var earliestRemainingTimeAfterCommit = root.firstPendingTime;
14272
14273 var subscriber = void 0;
14274
14275 try {
14276 subscriber = tracing.__subscriberRef.current;
14277 if (subscriber !== null && root.memoizedInteractions.size > 0) {
14278 var threadID = computeThreadID(root, committedExpirationTime);
14279 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
14280 }
14281 } catch (error) {
14282 // If the subscriber throws, rethrow it in a separate task
14283 scheduleCallback(ImmediatePriority, function () {
14284 throw error;
14285 });
14286 } finally {
14287 // Clear completed interactions from the pending Map.
14288 // Unless the render was suspended or cascading work was scheduled,
14289 // In which case– leave pending interactions until the subsequent render.
14290 var pendingInteractionMap = root.pendingInteractionMap;
14291 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
14292 // Only decrement the pending interaction count if we're done.
14293 // If there's still work at the current priority,
14294 // That indicates that we are waiting for suspense data.
14295 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
14296 pendingInteractionMap.delete(scheduledExpirationTime);
14297
14298 scheduledInteractions.forEach(function (interaction) {
14299 interaction.__count--;
14300
14301 if (subscriber !== null && interaction.__count === 0) {
14302 try {
14303 subscriber.onInteractionScheduledWorkCompleted(interaction);
14304 } catch (error) {
14305 // If the subscriber throws, rethrow it in a separate task
14306 scheduleCallback(ImmediatePriority, function () {
14307 throw error;
14308 });
14309 }
14310 }
14311 });
14312 }
14313 });
14314 }
14315}
14316
14317var onCommitFiberRoot = null;
14318var onCommitFiberUnmount = null;
14319var hasLoggedError = false;
14320
14321var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
14322
14323function injectInternals(internals) {
14324 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
14325 // No DevTools
14326 return false;
14327 }
14328 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
14329 if (hook.isDisabled) {
14330 // This isn't a real property on the hook, but it can be set to opt out
14331 // of DevTools integration and associated warnings and logs.
14332 // https://github.com/facebook/react/issues/3877
14333 return true;
14334 }
14335 if (!hook.supportsFiber) {
14336 {
14337 warningWithoutStack$1(false, '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');
14338 }
14339 // DevTools exists, even though it doesn't support Fiber.
14340 return true;
14341 }
14342 try {
14343 var rendererID = hook.inject(internals);
14344 // We have successfully injected, so now it is safe to set up hooks.
14345 onCommitFiberRoot = function (root, expirationTime) {
14346 try {
14347 var didError = (root.current.effectTag & DidCapture) === DidCapture;
14348 if (enableProfilerTimer) {
14349 var currentTime = requestCurrentTime();
14350 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime);
14351 hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
14352 } else {
14353 hook.onCommitFiberRoot(rendererID, root, undefined, didError);
14354 }
14355 } catch (err) {
14356 if (true && !hasLoggedError) {
14357 hasLoggedError = true;
14358 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
14359 }
14360 }
14361 };
14362 onCommitFiberUnmount = function (fiber) {
14363 try {
14364 hook.onCommitFiberUnmount(rendererID, fiber);
14365 } catch (err) {
14366 if (true && !hasLoggedError) {
14367 hasLoggedError = true;
14368 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
14369 }
14370 }
14371 };
14372 } catch (err) {
14373 // Catch all errors because it is unsafe to throw during initialization.
14374 {
14375 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err);
14376 }
14377 }
14378 // DevTools exists
14379 return true;
14380}
14381
14382function onCommitRoot(root, expirationTime) {
14383 if (typeof onCommitFiberRoot === 'function') {
14384 onCommitFiberRoot(root, expirationTime);
14385 }
14386}
14387
14388function onCommitUnmount(fiber) {
14389 if (typeof onCommitFiberUnmount === 'function') {
14390 onCommitFiberUnmount(fiber);
14391 }
14392}
14393
14394var hasBadMapPolyfill = void 0;
14395
14396{
14397 hasBadMapPolyfill = false;
14398 try {
14399 var nonExtensibleObject = Object.preventExtensions({});
14400 var testMap = new Map([[nonExtensibleObject, null]]);
14401 var testSet = new Set([nonExtensibleObject]);
14402 // This is necessary for Rollup to not consider these unused.
14403 // https://github.com/rollup/rollup/issues/1771
14404 // TODO: we can remove these if Rollup fixes the bug.
14405 testMap.set(0, 0);
14406 testSet.add(0);
14407 } catch (e) {
14408 // TODO: Consider warning about bad polyfills
14409 hasBadMapPolyfill = true;
14410 }
14411}
14412
14413// A Fiber is work on a Component that needs to be done or was done. There can
14414// be more than one per component.
14415
14416
14417var debugCounter = void 0;
14418
14419{
14420 debugCounter = 1;
14421}
14422
14423function FiberNode(tag, pendingProps, key, mode) {
14424 // Instance
14425 this.tag = tag;
14426 this.key = key;
14427 this.elementType = null;
14428 this.type = null;
14429 this.stateNode = null;
14430
14431 // Fiber
14432 this.return = null;
14433 this.child = null;
14434 this.sibling = null;
14435 this.index = 0;
14436
14437 this.ref = null;
14438
14439 this.pendingProps = pendingProps;
14440 this.memoizedProps = null;
14441 this.updateQueue = null;
14442 this.memoizedState = null;
14443 this.dependencies = null;
14444
14445 this.mode = mode;
14446
14447 // Effects
14448 this.effectTag = NoEffect;
14449 this.nextEffect = null;
14450
14451 this.firstEffect = null;
14452 this.lastEffect = null;
14453
14454 this.expirationTime = NoWork;
14455 this.childExpirationTime = NoWork;
14456
14457 this.alternate = null;
14458
14459 if (enableProfilerTimer) {
14460 // Note: The following is done to avoid a v8 performance cliff.
14461 //
14462 // Initializing the fields below to smis and later updating them with
14463 // double values will cause Fibers to end up having separate shapes.
14464 // This behavior/bug has something to do with Object.preventExtension().
14465 // Fortunately this only impacts DEV builds.
14466 // Unfortunately it makes React unusably slow for some applications.
14467 // To work around this, initialize the fields below with doubles.
14468 //
14469 // Learn more about this here:
14470 // https://github.com/facebook/react/issues/14365
14471 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
14472 this.actualDuration = Number.NaN;
14473 this.actualStartTime = Number.NaN;
14474 this.selfBaseDuration = Number.NaN;
14475 this.treeBaseDuration = Number.NaN;
14476
14477 // It's okay to replace the initial doubles with smis after initialization.
14478 // This won't trigger the performance cliff mentioned above,
14479 // and it simplifies other profiler code (including DevTools).
14480 this.actualDuration = 0;
14481 this.actualStartTime = -1;
14482 this.selfBaseDuration = 0;
14483 this.treeBaseDuration = 0;
14484 }
14485
14486 {
14487 this._debugID = debugCounter++;
14488 this._debugSource = null;
14489 this._debugOwner = null;
14490 this._debugIsCurrentlyTiming = false;
14491 this._debugNeedsRemount = false;
14492 this._debugHookTypes = null;
14493 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
14494 Object.preventExtensions(this);
14495 }
14496 }
14497}
14498
14499// This is a constructor function, rather than a POJO constructor, still
14500// please ensure we do the following:
14501// 1) Nobody should add any instance methods on this. Instance methods can be
14502// more difficult to predict when they get optimized and they are almost
14503// never inlined properly in static compilers.
14504// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
14505// always know when it is a fiber.
14506// 3) We might want to experiment with using numeric keys since they are easier
14507// to optimize in a non-JIT environment.
14508// 4) We can easily go from a constructor to a createFiber object literal if that
14509// is faster.
14510// 5) It should be easy to port this to a C struct and keep a C implementation
14511// compatible.
14512var createFiber = function (tag, pendingProps, key, mode) {
14513 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
14514 return new FiberNode(tag, pendingProps, key, mode);
14515};
14516
14517function shouldConstruct(Component) {
14518 var prototype = Component.prototype;
14519 return !!(prototype && prototype.isReactComponent);
14520}
14521
14522function isSimpleFunctionComponent(type) {
14523 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
14524}
14525
14526function resolveLazyComponentTag(Component) {
14527 if (typeof Component === 'function') {
14528 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
14529 } else if (Component !== undefined && Component !== null) {
14530 var $$typeof = Component.$$typeof;
14531 if ($$typeof === REACT_FORWARD_REF_TYPE) {
14532 return ForwardRef;
14533 }
14534 if ($$typeof === REACT_MEMO_TYPE) {
14535 return MemoComponent;
14536 }
14537 }
14538 return IndeterminateComponent;
14539}
14540
14541// This is used to create an alternate fiber to do work on.
14542function createWorkInProgress(current, pendingProps, expirationTime) {
14543 var workInProgress = current.alternate;
14544 if (workInProgress === null) {
14545 // We use a double buffering pooling technique because we know that we'll
14546 // only ever need at most two versions of a tree. We pool the "other" unused
14547 // node that we're free to reuse. This is lazily created to avoid allocating
14548 // extra objects for things that are never updated. It also allow us to
14549 // reclaim the extra memory if needed.
14550 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
14551 workInProgress.elementType = current.elementType;
14552 workInProgress.type = current.type;
14553 workInProgress.stateNode = current.stateNode;
14554
14555 {
14556 // DEV-only fields
14557 workInProgress._debugID = current._debugID;
14558 workInProgress._debugSource = current._debugSource;
14559 workInProgress._debugOwner = current._debugOwner;
14560 workInProgress._debugHookTypes = current._debugHookTypes;
14561 }
14562
14563 workInProgress.alternate = current;
14564 current.alternate = workInProgress;
14565 } else {
14566 workInProgress.pendingProps = pendingProps;
14567
14568 // We already have an alternate.
14569 // Reset the effect tag.
14570 workInProgress.effectTag = NoEffect;
14571
14572 // The effect list is no longer valid.
14573 workInProgress.nextEffect = null;
14574 workInProgress.firstEffect = null;
14575 workInProgress.lastEffect = null;
14576
14577 if (enableProfilerTimer) {
14578 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
14579 // This prevents time from endlessly accumulating in new commits.
14580 // This has the downside of resetting values for different priority renders,
14581 // But works for yielding (the common case) and should support resuming.
14582 workInProgress.actualDuration = 0;
14583 workInProgress.actualStartTime = -1;
14584 }
14585 }
14586
14587 workInProgress.childExpirationTime = current.childExpirationTime;
14588 workInProgress.expirationTime = current.expirationTime;
14589
14590 workInProgress.child = current.child;
14591 workInProgress.memoizedProps = current.memoizedProps;
14592 workInProgress.memoizedState = current.memoizedState;
14593 workInProgress.updateQueue = current.updateQueue;
14594
14595 // Clone the dependencies object. This is mutated during the render phase, so
14596 // it cannot be shared with the current fiber.
14597 var currentDependencies = current.dependencies;
14598 workInProgress.dependencies = currentDependencies === null ? null : {
14599 expirationTime: currentDependencies.expirationTime,
14600 firstContext: currentDependencies.firstContext,
14601 responders: currentDependencies.responders
14602 };
14603
14604 // These will be overridden during the parent's reconciliation
14605 workInProgress.sibling = current.sibling;
14606 workInProgress.index = current.index;
14607 workInProgress.ref = current.ref;
14608
14609 if (enableProfilerTimer) {
14610 workInProgress.selfBaseDuration = current.selfBaseDuration;
14611 workInProgress.treeBaseDuration = current.treeBaseDuration;
14612 }
14613
14614 {
14615 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
14616 switch (workInProgress.tag) {
14617 case IndeterminateComponent:
14618 case FunctionComponent:
14619 case SimpleMemoComponent:
14620 workInProgress.type = resolveFunctionForHotReloading(current.type);
14621 break;
14622 case ClassComponent:
14623 workInProgress.type = resolveClassForHotReloading(current.type);
14624 break;
14625 case ForwardRef:
14626 workInProgress.type = resolveForwardRefForHotReloading(current.type);
14627 break;
14628 default:
14629 break;
14630 }
14631 }
14632
14633 return workInProgress;
14634}
14635
14636// Used to reuse a Fiber for a second pass.
14637function resetWorkInProgress(workInProgress, renderExpirationTime) {
14638 // This resets the Fiber to what createFiber or createWorkInProgress would
14639 // have set the values to before during the first pass. Ideally this wouldn't
14640 // be necessary but unfortunately many code paths reads from the workInProgress
14641 // when they should be reading from current and writing to workInProgress.
14642
14643 // We assume pendingProps, index, key, ref, return are still untouched to
14644 // avoid doing another reconciliation.
14645
14646 // Reset the effect tag but keep any Placement tags, since that's something
14647 // that child fiber is setting, not the reconciliation.
14648 workInProgress.effectTag &= Placement;
14649
14650 // The effect list is no longer valid.
14651 workInProgress.nextEffect = null;
14652 workInProgress.firstEffect = null;
14653 workInProgress.lastEffect = null;
14654
14655 var current = workInProgress.alternate;
14656 if (current === null) {
14657 // Reset to createFiber's initial values.
14658 workInProgress.childExpirationTime = NoWork;
14659 workInProgress.expirationTime = renderExpirationTime;
14660
14661 workInProgress.child = null;
14662 workInProgress.memoizedProps = null;
14663 workInProgress.memoizedState = null;
14664 workInProgress.updateQueue = null;
14665
14666 workInProgress.dependencies = null;
14667
14668 if (enableProfilerTimer) {
14669 // Note: We don't reset the actualTime counts. It's useful to accumulate
14670 // actual time across multiple render passes.
14671 workInProgress.selfBaseDuration = 0;
14672 workInProgress.treeBaseDuration = 0;
14673 }
14674 } else {
14675 // Reset to the cloned values that createWorkInProgress would've.
14676 workInProgress.childExpirationTime = current.childExpirationTime;
14677 workInProgress.expirationTime = current.expirationTime;
14678
14679 workInProgress.child = current.child;
14680 workInProgress.memoizedProps = current.memoizedProps;
14681 workInProgress.memoizedState = current.memoizedState;
14682 workInProgress.updateQueue = current.updateQueue;
14683
14684 // Clone the dependencies object. This is mutated during the render phase, so
14685 // it cannot be shared with the current fiber.
14686 var currentDependencies = current.dependencies;
14687 workInProgress.dependencies = currentDependencies === null ? null : {
14688 expirationTime: currentDependencies.expirationTime,
14689 firstContext: currentDependencies.firstContext,
14690 responders: currentDependencies.responders
14691 };
14692
14693 if (enableProfilerTimer) {
14694 // Note: We don't reset the actualTime counts. It's useful to accumulate
14695 // actual time across multiple render passes.
14696 workInProgress.selfBaseDuration = current.selfBaseDuration;
14697 workInProgress.treeBaseDuration = current.treeBaseDuration;
14698 }
14699 }
14700
14701 return workInProgress;
14702}
14703
14704function createHostRootFiber(tag) {
14705 var mode = void 0;
14706 if (tag === ConcurrentRoot) {
14707 mode = ConcurrentMode | BatchedMode | StrictMode;
14708 } else if (tag === BatchedRoot) {
14709 mode = BatchedMode | StrictMode;
14710 } else {
14711 mode = NoMode;
14712 }
14713
14714 if (enableProfilerTimer && isDevToolsPresent) {
14715 // Always collect profile timings when DevTools are present.
14716 // This enables DevTools to start capturing timing at any point–
14717 // Without some nodes in the tree having empty base times.
14718 mode |= ProfileMode;
14719 }
14720
14721 return createFiber(HostRoot, null, null, mode);
14722}
14723
14724function createFiberFromTypeAndProps(type, // React$ElementType
14725key, pendingProps, owner, mode, expirationTime) {
14726 var fiber = void 0;
14727
14728 var fiberTag = IndeterminateComponent;
14729 // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
14730 var resolvedType = type;
14731 if (typeof type === 'function') {
14732 if (shouldConstruct(type)) {
14733 fiberTag = ClassComponent;
14734 {
14735 resolvedType = resolveClassForHotReloading(resolvedType);
14736 }
14737 } else {
14738 {
14739 resolvedType = resolveFunctionForHotReloading(resolvedType);
14740 }
14741 }
14742 } else if (typeof type === 'string') {
14743 fiberTag = HostComponent;
14744 } else {
14745 getTag: switch (type) {
14746 case REACT_FRAGMENT_TYPE:
14747 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
14748 case REACT_CONCURRENT_MODE_TYPE:
14749 fiberTag = Mode;
14750 mode |= ConcurrentMode | BatchedMode | StrictMode;
14751 break;
14752 case REACT_STRICT_MODE_TYPE:
14753 fiberTag = Mode;
14754 mode |= StrictMode;
14755 break;
14756 case REACT_PROFILER_TYPE:
14757 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
14758 case REACT_SUSPENSE_TYPE:
14759 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
14760 case REACT_SUSPENSE_LIST_TYPE:
14761 return createFiberFromSuspenseList(pendingProps, mode, expirationTime, key);
14762 default:
14763 {
14764 if (typeof type === 'object' && type !== null) {
14765 switch (type.$$typeof) {
14766 case REACT_PROVIDER_TYPE:
14767 fiberTag = ContextProvider;
14768 break getTag;
14769 case REACT_CONTEXT_TYPE:
14770 // This is a consumer
14771 fiberTag = ContextConsumer;
14772 break getTag;
14773 case REACT_FORWARD_REF_TYPE:
14774 fiberTag = ForwardRef;
14775 {
14776 resolvedType = resolveForwardRefForHotReloading(resolvedType);
14777 }
14778 break getTag;
14779 case REACT_MEMO_TYPE:
14780 fiberTag = MemoComponent;
14781 break getTag;
14782 case REACT_LAZY_TYPE:
14783 fiberTag = LazyComponent;
14784 resolvedType = null;
14785 break getTag;
14786 case REACT_FUNDAMENTAL_TYPE:
14787 if (enableFundamentalAPI) {
14788 return createFiberFromFundamental(type, pendingProps, mode, expirationTime, key);
14789 }
14790 break;
14791 }
14792 }
14793 var info = '';
14794 {
14795 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
14796 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.';
14797 }
14798 var ownerName = owner ? getComponentName(owner.type) : null;
14799 if (ownerName) {
14800 info += '\n\nCheck the render method of `' + ownerName + '`.';
14801 }
14802 }
14803 (function () {
14804 {
14805 {
14806 throw ReactError(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));
14807 }
14808 }
14809 })();
14810 }
14811 }
14812 }
14813
14814 fiber = createFiber(fiberTag, pendingProps, key, mode);
14815 fiber.elementType = type;
14816 fiber.type = resolvedType;
14817 fiber.expirationTime = expirationTime;
14818
14819 return fiber;
14820}
14821
14822function createFiberFromElement(element, mode, expirationTime) {
14823 var owner = null;
14824 {
14825 owner = element._owner;
14826 }
14827 var type = element.type;
14828 var key = element.key;
14829 var pendingProps = element.props;
14830 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
14831 {
14832 fiber._debugSource = element._source;
14833 fiber._debugOwner = element._owner;
14834 }
14835 return fiber;
14836}
14837
14838function createFiberFromFragment(elements, mode, expirationTime, key) {
14839 var fiber = createFiber(Fragment, elements, key, mode);
14840 fiber.expirationTime = expirationTime;
14841 return fiber;
14842}
14843
14844function createFiberFromFundamental(fundamentalComponent, pendingProps, mode, expirationTime, key) {
14845 var fiber = createFiber(FundamentalComponent, pendingProps, key, mode);
14846 fiber.elementType = fundamentalComponent;
14847 fiber.type = fundamentalComponent;
14848 fiber.expirationTime = expirationTime;
14849 return fiber;
14850}
14851
14852function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
14853 {
14854 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
14855 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
14856 }
14857 }
14858
14859 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
14860 // TODO: The Profiler fiber shouldn't have a type. It has a tag.
14861 fiber.elementType = REACT_PROFILER_TYPE;
14862 fiber.type = REACT_PROFILER_TYPE;
14863 fiber.expirationTime = expirationTime;
14864
14865 return fiber;
14866}
14867
14868function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
14869 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
14870
14871 // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
14872 // This needs to be fixed in getComponentName so that it relies on the tag
14873 // instead.
14874 fiber.type = REACT_SUSPENSE_TYPE;
14875 fiber.elementType = REACT_SUSPENSE_TYPE;
14876
14877 fiber.expirationTime = expirationTime;
14878 return fiber;
14879}
14880
14881function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) {
14882 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
14883 {
14884 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.
14885 // This needs to be fixed in getComponentName so that it relies on the tag
14886 // instead.
14887 fiber.type = REACT_SUSPENSE_LIST_TYPE;
14888 }
14889 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
14890 fiber.expirationTime = expirationTime;
14891 return fiber;
14892}
14893
14894function createFiberFromText(content, mode, expirationTime) {
14895 var fiber = createFiber(HostText, content, null, mode);
14896 fiber.expirationTime = expirationTime;
14897 return fiber;
14898}
14899
14900function createFiberFromHostInstanceForDeletion() {
14901 var fiber = createFiber(HostComponent, null, null, NoMode);
14902 // TODO: These should not need a type.
14903 fiber.elementType = 'DELETED';
14904 fiber.type = 'DELETED';
14905 return fiber;
14906}
14907
14908function createFiberFromPortal(portal, mode, expirationTime) {
14909 var pendingProps = portal.children !== null ? portal.children : [];
14910 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
14911 fiber.expirationTime = expirationTime;
14912 fiber.stateNode = {
14913 containerInfo: portal.containerInfo,
14914 pendingChildren: null, // Used by persistent updates
14915 implementation: portal.implementation
14916 };
14917 return fiber;
14918}
14919
14920// Used for stashing WIP properties to replay failed work in DEV.
14921function assignFiberPropertiesInDEV(target, source) {
14922 if (target === null) {
14923 // This Fiber's initial properties will always be overwritten.
14924 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
14925 target = createFiber(IndeterminateComponent, null, null, NoMode);
14926 }
14927
14928 // This is intentionally written as a list of all properties.
14929 // We tried to use Object.assign() instead but this is called in
14930 // the hottest path, and Object.assign() was too slow:
14931 // https://github.com/facebook/react/issues/12502
14932 // This code is DEV-only so size is not a concern.
14933
14934 target.tag = source.tag;
14935 target.key = source.key;
14936 target.elementType = source.elementType;
14937 target.type = source.type;
14938 target.stateNode = source.stateNode;
14939 target.return = source.return;
14940 target.child = source.child;
14941 target.sibling = source.sibling;
14942 target.index = source.index;
14943 target.ref = source.ref;
14944 target.pendingProps = source.pendingProps;
14945 target.memoizedProps = source.memoizedProps;
14946 target.updateQueue = source.updateQueue;
14947 target.memoizedState = source.memoizedState;
14948 target.dependencies = source.dependencies;
14949 target.mode = source.mode;
14950 target.effectTag = source.effectTag;
14951 target.nextEffect = source.nextEffect;
14952 target.firstEffect = source.firstEffect;
14953 target.lastEffect = source.lastEffect;
14954 target.expirationTime = source.expirationTime;
14955 target.childExpirationTime = source.childExpirationTime;
14956 target.alternate = source.alternate;
14957 if (enableProfilerTimer) {
14958 target.actualDuration = source.actualDuration;
14959 target.actualStartTime = source.actualStartTime;
14960 target.selfBaseDuration = source.selfBaseDuration;
14961 target.treeBaseDuration = source.treeBaseDuration;
14962 }
14963 target._debugID = source._debugID;
14964 target._debugSource = source._debugSource;
14965 target._debugOwner = source._debugOwner;
14966 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
14967 target._debugNeedsRemount = source._debugNeedsRemount;
14968 target._debugHookTypes = source._debugHookTypes;
14969 return target;
14970}
14971
14972// TODO: This should be lifted into the renderer.
14973
14974
14975// The following attributes are only used by interaction tracing builds.
14976// They enable interactions to be associated with their async work,
14977// And expose interaction metadata to the React DevTools Profiler plugin.
14978// Note that these attributes are only defined when the enableSchedulerTracing flag is enabled.
14979
14980
14981// Exported FiberRoot type includes all properties,
14982// To avoid requiring potentially error-prone :any casts throughout the project.
14983// Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true).
14984// The types are defined separately within this file to ensure they stay in sync.
14985// (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.)
14986
14987
14988function FiberRootNode(containerInfo, tag, hydrate) {
14989 this.tag = tag;
14990 this.current = null;
14991 this.containerInfo = containerInfo;
14992 this.pendingChildren = null;
14993 this.pingCache = null;
14994 this.finishedExpirationTime = NoWork;
14995 this.finishedWork = null;
14996 this.timeoutHandle = noTimeout;
14997 this.context = null;
14998 this.pendingContext = null;
14999 this.hydrate = hydrate;
15000 this.firstBatch = null;
15001 this.callbackNode = null;
15002 this.callbackExpirationTime = NoWork;
15003 this.firstPendingTime = NoWork;
15004 this.lastPendingTime = NoWork;
15005 this.pingTime = NoWork;
15006
15007 if (enableSchedulerTracing) {
15008 this.interactionThreadID = tracing.unstable_getThreadID();
15009 this.memoizedInteractions = new Set();
15010 this.pendingInteractionMap = new Map();
15011 }
15012}
15013
15014function createFiberRoot(containerInfo, tag, hydrate) {
15015 var root = new FiberRootNode(containerInfo, tag, hydrate);
15016
15017 // Cyclic construction. This cheats the type system right now because
15018 // stateNode is any.
15019 var uninitializedFiber = createHostRootFiber(tag);
15020 root.current = uninitializedFiber;
15021 uninitializedFiber.stateNode = root;
15022
15023 return root;
15024}
15025
15026// This lets us hook into Fiber to debug what it's doing.
15027// See https://github.com/facebook/react/pull/8033.
15028// This is not part of the public API, not even for React DevTools.
15029// You may only inject a debugTool if you work on React Fiber itself.
15030var ReactFiberInstrumentation = {
15031 debugTool: null
15032};
15033
15034var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
15035
15036// 0 is PROD, 1 is DEV.
15037// Might add PROFILE later.
15038
15039
15040var didWarnAboutNestedUpdates = void 0;
15041{
15042 didWarnAboutNestedUpdates = false;
15043
15044}
15045
15046function getContextForSubtree(parentComponent) {
15047 if (!parentComponent) {
15048 return emptyContextObject;
15049 }
15050
15051 var fiber = get(parentComponent);
15052 var parentContext = findCurrentUnmaskedContext(fiber);
15053
15054 if (fiber.tag === ClassComponent) {
15055 var Component = fiber.type;
15056 if (isContextProvider(Component)) {
15057 return processChildContext(fiber, Component, parentContext);
15058 }
15059 }
15060
15061 return parentContext;
15062}
15063
15064function scheduleRootUpdate(current$$1, element, expirationTime, suspenseConfig, callback) {
15065 {
15066 if (phase === 'render' && current !== null && !didWarnAboutNestedUpdates) {
15067 didWarnAboutNestedUpdates = true;
15068 warningWithoutStack$1(false, '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');
15069 }
15070 }
15071
15072 var update = createUpdate(expirationTime, suspenseConfig);
15073 // Caution: React DevTools currently depends on this property
15074 // being called "element".
15075 update.payload = { element: element };
15076
15077 callback = callback === undefined ? null : callback;
15078 if (callback !== null) {
15079 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
15080 update.callback = callback;
15081 }
15082
15083 if (revertPassiveEffectsChange) {
15084 flushPassiveEffects();
15085 }
15086 enqueueUpdate(current$$1, update);
15087 scheduleWork(current$$1, expirationTime);
15088
15089 return expirationTime;
15090}
15091
15092function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, suspenseConfig, callback) {
15093 // TODO: If this is a nested container, this won't be the root.
15094 var current$$1 = container.current;
15095
15096 {
15097 if (ReactFiberInstrumentation_1.debugTool) {
15098 if (current$$1.alternate === null) {
15099 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
15100 } else if (element === null) {
15101 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
15102 } else {
15103 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
15104 }
15105 }
15106 }
15107
15108 var context = getContextForSubtree(parentComponent);
15109 if (container.context === null) {
15110 container.context = context;
15111 } else {
15112 container.pendingContext = context;
15113 }
15114
15115 return scheduleRootUpdate(current$$1, element, expirationTime, suspenseConfig, callback);
15116}
15117
15118function createContainer(containerInfo, tag, hydrate) {
15119 return createFiberRoot(containerInfo, tag, hydrate);
15120}
15121
15122function updateContainer(element, container, parentComponent, callback) {
15123 var current$$1 = container.current;
15124 var currentTime = requestCurrentTime();
15125 {
15126 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15127 if ('undefined' !== typeof jest) {
15128 warnIfUnmockedScheduler(current$$1);
15129 warnIfNotScopedWithMatchingAct(current$$1);
15130 }
15131 }
15132 var suspenseConfig = requestCurrentSuspenseConfig();
15133 var expirationTime = computeExpirationForFiber(currentTime, current$$1, suspenseConfig);
15134 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, suspenseConfig, callback);
15135}
15136
15137function getPublicRootInstance(container) {
15138 var containerFiber = container.current;
15139 if (!containerFiber.child) {
15140 return null;
15141 }
15142 switch (containerFiber.child.tag) {
15143 case HostComponent:
15144 return getPublicInstance(containerFiber.child.stateNode);
15145 default:
15146 return containerFiber.child.stateNode;
15147 }
15148}
15149
15150
15151
15152var shouldSuspendImpl = function (fiber) {
15153 return false;
15154};
15155
15156function shouldSuspend(fiber) {
15157 return shouldSuspendImpl(fiber);
15158}
15159
15160var overrideHookState = null;
15161var overrideProps = null;
15162var scheduleUpdate = null;
15163var setSuspenseHandler = null;
15164
15165{
15166 var copyWithSetImpl = function (obj, path, idx, value) {
15167 if (idx >= path.length) {
15168 return value;
15169 }
15170 var key = path[idx];
15171 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
15172 // $FlowFixMe number or string is fine here
15173 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
15174 return updated;
15175 };
15176
15177 var copyWithSet = function (obj, path, value) {
15178 return copyWithSetImpl(obj, path, 0, value);
15179 };
15180
15181 // Support DevTools editable values for useState and useReducer.
15182 overrideHookState = function (fiber, id, path, value) {
15183 // For now, the "id" of stateful hooks is just the stateful hook index.
15184 // This may change in the future with e.g. nested hooks.
15185 var currentHook = fiber.memoizedState;
15186 while (currentHook !== null && id > 0) {
15187 currentHook = currentHook.next;
15188 id--;
15189 }
15190 if (currentHook !== null) {
15191 if (revertPassiveEffectsChange) {
15192 flushPassiveEffects();
15193 }
15194
15195 var newState = copyWithSet(currentHook.memoizedState, path, value);
15196 currentHook.memoizedState = newState;
15197 currentHook.baseState = newState;
15198
15199 // We aren't actually adding an update to the queue,
15200 // because there is no update we can add for useReducer hooks that won't trigger an error.
15201 // (There's no appropriate action type for DevTools overrides.)
15202 // As a result though, React will see the scheduled update as a noop and bailout.
15203 // Shallow cloning props works as a workaround for now to bypass the bailout check.
15204 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
15205
15206 scheduleWork(fiber, Sync);
15207 }
15208 };
15209
15210 // Support DevTools props for function components, forwardRef, memo, host components, etc.
15211 overrideProps = function (fiber, path, value) {
15212 if (revertPassiveEffectsChange) {
15213 flushPassiveEffects();
15214 }
15215 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
15216 if (fiber.alternate) {
15217 fiber.alternate.pendingProps = fiber.pendingProps;
15218 }
15219 scheduleWork(fiber, Sync);
15220 };
15221
15222 scheduleUpdate = function (fiber) {
15223 if (revertPassiveEffectsChange) {
15224 flushPassiveEffects();
15225 }
15226 scheduleWork(fiber, Sync);
15227 };
15228
15229 setSuspenseHandler = function (newShouldSuspendImpl) {
15230 shouldSuspendImpl = newShouldSuspendImpl;
15231 };
15232}
15233
15234function injectIntoDevTools(devToolsConfig) {
15235 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
15236 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
15237
15238
15239 return injectInternals(_assign({}, devToolsConfig, {
15240 overrideHookState: overrideHookState,
15241 overrideProps: overrideProps,
15242 setSuspenseHandler: setSuspenseHandler,
15243 scheduleUpdate: scheduleUpdate,
15244 currentDispatcherRef: ReactCurrentDispatcher,
15245 findHostInstanceByFiber: function (fiber) {
15246 var hostFiber = findCurrentHostFiber(fiber);
15247 if (hostFiber === null) {
15248 return null;
15249 }
15250 return hostFiber.stateNode;
15251 },
15252 findFiberByHostInstance: function (instance) {
15253 if (!findFiberByHostInstance) {
15254 // Might not be implemented by the renderer.
15255 return null;
15256 }
15257 return findFiberByHostInstance(instance);
15258 },
15259
15260 // React Refresh
15261 findHostInstancesForRefresh: findHostInstancesForRefresh,
15262 scheduleRefresh: scheduleRefresh,
15263 scheduleRoot: scheduleRoot,
15264 setRefreshHandler: setRefreshHandler,
15265 // Enables DevTools to append owner stacks to error messages in DEV mode.
15266 getCurrentFiber: function () {
15267 return current;
15268 }
15269 }));
15270}
15271
15272// This file intentionally does *not* have the Flow annotation.
15273// Don't add it. See `./inline-typed.js` for an explanation.
15274
15275// TODO: this is special because it gets imported during build.
15276
15277var ReactVersion = '16.9.0-rc.0';
15278
15279var didWarnAboutMessageChannel = false;
15280var enqueueTask = void 0;
15281try {
15282 // read require off the module object to get around the bundlers.
15283 // we don't want them to detect a require and bundle a Node polyfill.
15284 var requireString = ('require' + Math.random()).slice(0, 7);
15285 var nodeRequire = module && module[requireString];
15286 // assuming we're in node, let's try to get node's
15287 // version of setImmediate, bypassing fake timers if any.
15288 enqueueTask = nodeRequire('timers').setImmediate;
15289} catch (_err) {
15290 // we're in a browser
15291 // we can't use regular timers because they may still be faked
15292 // so we try MessageChannel+postMessage instead
15293 enqueueTask = function (callback) {
15294 {
15295 if (didWarnAboutMessageChannel === false) {
15296 didWarnAboutMessageChannel = true;
15297 !(typeof MessageChannel !== 'undefined') ? warningWithoutStack$1(false, '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.') : void 0;
15298 }
15299 }
15300 var channel = new MessageChannel();
15301 channel.port1.onmessage = callback;
15302 channel.port2.postMessage(undefined);
15303 };
15304}
15305
15306var enqueueTask$1 = enqueueTask;
15307
15308var IsSomeRendererActing$1 = ReactSharedInternals.IsSomeRendererActing;
15309
15310// this implementation should be exactly the same in
15311// ReactTestUtilsAct.js, ReactTestRendererAct.js, createReactNoop.js
15312
15313var isSchedulerMocked = typeof Scheduler$1.unstable_flushAllWithoutAsserting === 'function';
15314var flushWork = Scheduler$1.unstable_flushAllWithoutAsserting || function () {
15315 var didFlushWork = false;
15316 while (flushPassiveEffects()) {
15317 didFlushWork = true;
15318 }
15319
15320 return didFlushWork;
15321};
15322
15323function flushWorkAndMicroTasks(onDone) {
15324 try {
15325 flushWork();
15326 enqueueTask$1(function () {
15327 if (flushWork()) {
15328 flushWorkAndMicroTasks(onDone);
15329 } else {
15330 onDone();
15331 }
15332 });
15333 } catch (err) {
15334 onDone(err);
15335 }
15336}
15337
15338// we track the 'depth' of the act() calls with this counter,
15339// so we can tell if any async act() calls try to run in parallel.
15340
15341var actingUpdatesScopeDepth = 0;
15342function act(callback) {
15343 var previousActingUpdatesScopeDepth = actingUpdatesScopeDepth;
15344 var previousIsSomeRendererActing = void 0;
15345 var previousIsThisRendererActing = void 0;
15346 actingUpdatesScopeDepth++;
15347
15348 previousIsSomeRendererActing = IsSomeRendererActing$1.current;
15349 previousIsThisRendererActing = IsThisRendererActing.current;
15350 IsSomeRendererActing$1.current = true;
15351 IsThisRendererActing.current = true;
15352
15353 function onDone() {
15354 actingUpdatesScopeDepth--;
15355 IsSomeRendererActing$1.current = previousIsSomeRendererActing;
15356 IsThisRendererActing.current = previousIsThisRendererActing;
15357 {
15358 if (actingUpdatesScopeDepth > previousActingUpdatesScopeDepth) {
15359 // if it's _less than_ previousActingUpdatesScopeDepth, then we can assume the 'other' one has warned
15360 warningWithoutStack$1(false, 'You seem to have overlapping act() calls, this is not supported. ' + 'Be sure to await previous act() calls before making a new one. ');
15361 }
15362 }
15363 }
15364
15365 var result = void 0;
15366 try {
15367 result = batchedUpdates(callback);
15368 } catch (error) {
15369 // on sync errors, we still want to 'cleanup' and decrement actingUpdatesScopeDepth
15370 onDone();
15371 throw error;
15372 }
15373
15374 if (result !== null && typeof result === 'object' && typeof result.then === 'function') {
15375 // setup a boolean that gets set to true only
15376 // once this act() call is await-ed
15377 var called = false;
15378 {
15379 if (typeof Promise !== 'undefined') {
15380 //eslint-disable-next-line no-undef
15381 Promise.resolve().then(function () {}).then(function () {
15382 if (called === false) {
15383 warningWithoutStack$1(false, '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 () => ...);');
15384 }
15385 });
15386 }
15387 }
15388
15389 // in the async case, the returned thenable runs the callback, flushes
15390 // effects and microtasks in a loop until flushPassiveEffects() === false,
15391 // and cleans up
15392 return {
15393 then: function (resolve, reject) {
15394 called = true;
15395 result.then(function () {
15396 if (actingUpdatesScopeDepth > 1 || isSchedulerMocked === true && previousIsSomeRendererActing === true) {
15397 onDone();
15398 resolve();
15399 return;
15400 }
15401 // we're about to exit the act() scope,
15402 // now's the time to flush tasks/effects
15403 flushWorkAndMicroTasks(function (err) {
15404 onDone();
15405 if (err) {
15406 reject(err);
15407 } else {
15408 resolve();
15409 }
15410 });
15411 }, function (err) {
15412 onDone();
15413 reject(err);
15414 });
15415 }
15416 };
15417 } else {
15418 {
15419 !(result === undefined) ? warningWithoutStack$1(false, 'The callback passed to act(...) function ' + 'must return undefined, or a Promise. You returned %s', result) : void 0;
15420 }
15421
15422 // flush effects until none remain, and cleanup
15423 try {
15424 if (actingUpdatesScopeDepth === 1 && (isSchedulerMocked === false || previousIsSomeRendererActing === false)) {
15425 // we're about to exit the act() scope,
15426 // now's the time to flush effects
15427 flushWork();
15428 }
15429 onDone();
15430 } catch (err) {
15431 onDone();
15432 throw err;
15433 }
15434
15435 // in the sync case, the returned thenable only warns *if* await-ed
15436 return {
15437 then: function (resolve) {
15438 {
15439 warningWithoutStack$1(false, 'Do not await the result of calling act(...) with sync logic, it is not a Promise.');
15440 }
15441 resolve();
15442 }
15443 };
15444 }
15445}
15446
15447var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
15448
15449function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
15450
15451function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
15452
15453var defaultTestOptions = {
15454 createNodeMock: function () {
15455 return null;
15456 }
15457};
15458
15459function toJSON(inst) {
15460 if (inst.isHidden) {
15461 // Omit timed out children from output entirely. This seems like the least
15462 // surprising behavior. We could perhaps add a separate API that includes
15463 // them, if it turns out people need it.
15464 return null;
15465 }
15466 switch (inst.tag) {
15467 case 'TEXT':
15468 return inst.text;
15469 case 'INSTANCE':
15470 {
15471 /* eslint-disable no-unused-vars */
15472 // We don't include the `children` prop in JSON.
15473 // Instead, we will include the actual rendered children.
15474 var _inst$props = inst.props,
15475 _children = _inst$props.children,
15476 _props = _objectWithoutProperties(_inst$props, ['children']);
15477 /* eslint-enable */
15478
15479
15480 var renderedChildren = null;
15481 if (inst.children && inst.children.length) {
15482 for (var i = 0; i < inst.children.length; i++) {
15483 var renderedChild = toJSON(inst.children[i]);
15484 if (renderedChild !== null) {
15485 if (renderedChildren === null) {
15486 renderedChildren = [renderedChild];
15487 } else {
15488 renderedChildren.push(renderedChild);
15489 }
15490 }
15491 }
15492 }
15493 var json = {
15494 type: inst.type,
15495 props: _props,
15496 children: renderedChildren
15497 };
15498 Object.defineProperty(json, '$$typeof', {
15499 value: Symbol.for('react.test.json')
15500 });
15501 return json;
15502 }
15503 default:
15504 throw new Error('Unexpected node type in toJSON: ' + inst.tag);
15505 }
15506}
15507
15508function childrenToTree(node) {
15509 if (!node) {
15510 return null;
15511 }
15512 var children = nodeAndSiblingsArray(node);
15513 if (children.length === 0) {
15514 return null;
15515 } else if (children.length === 1) {
15516 return toTree(children[0]);
15517 }
15518 return flatten(children.map(toTree));
15519}
15520
15521function nodeAndSiblingsArray(nodeWithSibling) {
15522 var array = [];
15523 var node = nodeWithSibling;
15524 while (node != null) {
15525 array.push(node);
15526 node = node.sibling;
15527 }
15528 return array;
15529}
15530
15531function flatten(arr) {
15532 var result = [];
15533 var stack = [{ i: 0, array: arr }];
15534 while (stack.length) {
15535 var n = stack.pop();
15536 while (n.i < n.array.length) {
15537 var el = n.array[n.i];
15538 n.i += 1;
15539 if (Array.isArray(el)) {
15540 stack.push(n);
15541 stack.push({ i: 0, array: el });
15542 break;
15543 }
15544 result.push(el);
15545 }
15546 }
15547 return result;
15548}
15549
15550function toTree(node) {
15551 if (node == null) {
15552 return null;
15553 }
15554 switch (node.tag) {
15555 case HostRoot:
15556 return childrenToTree(node.child);
15557 case HostPortal:
15558 return childrenToTree(node.child);
15559 case ClassComponent:
15560 return {
15561 nodeType: 'component',
15562 type: node.type,
15563 props: _assign({}, node.memoizedProps),
15564 instance: node.stateNode,
15565 rendered: childrenToTree(node.child)
15566 };
15567 case FunctionComponent:
15568 case SimpleMemoComponent:
15569 return {
15570 nodeType: 'component',
15571 type: node.type,
15572 props: _assign({}, node.memoizedProps),
15573 instance: null,
15574 rendered: childrenToTree(node.child)
15575 };
15576 case HostComponent:
15577 {
15578 return {
15579 nodeType: 'host',
15580 type: node.type,
15581 props: _assign({}, node.memoizedProps),
15582 instance: null, // TODO: use createNodeMock here somehow?
15583 rendered: flatten(nodeAndSiblingsArray(node.child).map(toTree))
15584 };
15585 }
15586 case HostText:
15587 return node.stateNode.text;
15588 case Fragment:
15589 case ContextProvider:
15590 case ContextConsumer:
15591 case Mode:
15592 case Profiler:
15593 case ForwardRef:
15594 case MemoComponent:
15595 case IncompleteClassComponent:
15596 return childrenToTree(node.child);
15597 default:
15598 (function () {
15599 {
15600 {
15601 throw ReactError(Error('toTree() does not yet know how to handle nodes with tag=' + node.tag));
15602 }
15603 }
15604 })();
15605 }
15606}
15607
15608var validWrapperTypes = new Set([FunctionComponent, ClassComponent, HostComponent, ForwardRef, MemoComponent, SimpleMemoComponent,
15609// Normally skipped, but used when there's more than one root child.
15610HostRoot]);
15611
15612function getChildren(parent) {
15613 var children = [];
15614 var startingNode = parent;
15615 var node = startingNode;
15616 if (node.child === null) {
15617 return children;
15618 }
15619 node.child.return = node;
15620 node = node.child;
15621 outer: while (true) {
15622 var descend = false;
15623 if (validWrapperTypes.has(node.tag)) {
15624 children.push(wrapFiber(node));
15625 } else if (node.tag === HostText) {
15626 children.push('' + node.memoizedProps);
15627 } else {
15628 descend = true;
15629 }
15630 if (descend && node.child !== null) {
15631 node.child.return = node;
15632 node = node.child;
15633 continue;
15634 }
15635 while (node.sibling === null) {
15636 if (node.return === startingNode) {
15637 break outer;
15638 }
15639 node = node.return;
15640 }
15641 node.sibling.return = node.return;
15642 node = node.sibling;
15643 }
15644 return children;
15645}
15646
15647var ReactTestInstance = function () {
15648 ReactTestInstance.prototype._currentFiber = function _currentFiber() {
15649 // Throws if this component has been unmounted.
15650 var fiber = findCurrentFiberUsingSlowPath(this._fiber);
15651 (function () {
15652 if (!(fiber !== null)) {
15653 {
15654 throw ReactError(Error('Can\'t read from currently-mounting component. This error is likely caused by a bug in React. Please file an issue.'));
15655 }
15656 }
15657 })();
15658 return fiber;
15659 };
15660
15661 function ReactTestInstance(fiber) {
15662 _classCallCheck(this, ReactTestInstance);
15663
15664 (function () {
15665 if (!validWrapperTypes.has(fiber.tag)) {
15666 {
15667 throw ReactError(Error('Unexpected object passed to ReactTestInstance constructor (tag: ' + fiber.tag + '). This is probably a bug in React.'));
15668 }
15669 }
15670 })();
15671 this._fiber = fiber;
15672 }
15673
15674 // Custom search functions
15675 ReactTestInstance.prototype.find = function find(predicate) {
15676 return expectOne(this.findAll(predicate, { deep: false }), 'matching custom predicate: ' + predicate.toString());
15677 };
15678
15679 ReactTestInstance.prototype.findByType = function findByType(type) {
15680 return expectOne(this.findAllByType(type, { deep: false }), 'with node type: "' + (type.displayName || type.name) + '"');
15681 };
15682
15683 ReactTestInstance.prototype.findByProps = function findByProps(props) {
15684 return expectOne(this.findAllByProps(props, { deep: false }), 'with props: ' + JSON.stringify(props));
15685 };
15686
15687 ReactTestInstance.prototype.findAll = function findAll(predicate) {
15688 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
15689
15690 return _findAll(this, predicate, options);
15691 };
15692
15693 ReactTestInstance.prototype.findAllByType = function findAllByType(type) {
15694 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
15695
15696 return _findAll(this, function (node) {
15697 return node.type === type;
15698 }, options);
15699 };
15700
15701 ReactTestInstance.prototype.findAllByProps = function findAllByProps(props) {
15702 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
15703
15704 return _findAll(this, function (node) {
15705 return node.props && propsMatch(node.props, props);
15706 }, options);
15707 };
15708
15709 _createClass(ReactTestInstance, [{
15710 key: 'instance',
15711 get: function () {
15712 if (this._fiber.tag === HostComponent) {
15713 return getPublicInstance(this._fiber.stateNode);
15714 } else {
15715 return this._fiber.stateNode;
15716 }
15717 }
15718 }, {
15719 key: 'type',
15720 get: function () {
15721 return this._fiber.type;
15722 }
15723 }, {
15724 key: 'props',
15725 get: function () {
15726 return this._currentFiber().memoizedProps;
15727 }
15728 }, {
15729 key: 'parent',
15730 get: function () {
15731 var parent = this._fiber.return;
15732 while (parent !== null) {
15733 if (validWrapperTypes.has(parent.tag)) {
15734 if (parent.tag === HostRoot) {
15735 // Special case: we only "materialize" instances for roots
15736 // if they have more than a single child. So we'll check that now.
15737 if (getChildren(parent).length < 2) {
15738 return null;
15739 }
15740 }
15741 return wrapFiber(parent);
15742 }
15743 parent = parent.return;
15744 }
15745 return null;
15746 }
15747 }, {
15748 key: 'children',
15749 get: function () {
15750 return getChildren(this._currentFiber());
15751 }
15752 }]);
15753
15754 return ReactTestInstance;
15755}();
15756
15757function _findAll(root, predicate, options) {
15758 var deep = options ? options.deep : true;
15759 var results = [];
15760
15761 if (predicate(root)) {
15762 results.push(root);
15763 if (!deep) {
15764 return results;
15765 }
15766 }
15767
15768 root.children.forEach(function (child) {
15769 if (typeof child === 'string') {
15770 return;
15771 }
15772 results.push.apply(results, _findAll(child, predicate, options));
15773 });
15774
15775 return results;
15776}
15777
15778function expectOne(all, message) {
15779 if (all.length === 1) {
15780 return all[0];
15781 }
15782
15783 var prefix = all.length === 0 ? 'No instances found ' : 'Expected 1 but found ' + all.length + ' instances ';
15784
15785 throw new Error(prefix + message);
15786}
15787
15788function propsMatch(props, filter) {
15789 for (var key in filter) {
15790 if (props[key] !== filter[key]) {
15791 return false;
15792 }
15793 }
15794 return true;
15795}
15796
15797var ReactTestRendererFiber = {
15798 _Scheduler: Scheduler,
15799
15800 create: function (element, options) {
15801 var createNodeMock = defaultTestOptions.createNodeMock;
15802 var isConcurrent = false;
15803 if (typeof options === 'object' && options !== null) {
15804 if (typeof options.createNodeMock === 'function') {
15805 createNodeMock = options.createNodeMock;
15806 }
15807 if (options.unstable_isConcurrent === true) {
15808 isConcurrent = true;
15809 }
15810 }
15811 var container = {
15812 children: [],
15813 createNodeMock: createNodeMock,
15814 tag: 'CONTAINER'
15815 };
15816 var root = createContainer(container, isConcurrent ? ConcurrentRoot : LegacyRoot, false);
15817 (function () {
15818 if (!(root != null)) {
15819 {
15820 throw ReactError(Error('something went wrong'));
15821 }
15822 }
15823 })();
15824 updateContainer(element, root, null, null);
15825
15826 var entry = {
15827 _Scheduler: Scheduler,
15828
15829 root: undefined, // makes flow happy
15830 // we define a 'getter' for 'root' below using 'Object.defineProperty'
15831 toJSON: function () {
15832 if (root == null || root.current == null || container == null) {
15833 return null;
15834 }
15835 if (container.children.length === 0) {
15836 return null;
15837 }
15838 if (container.children.length === 1) {
15839 return toJSON(container.children[0]);
15840 }
15841 if (container.children.length === 2 && container.children[0].isHidden === true && container.children[1].isHidden === false) {
15842 // Omit timed out children from output entirely, including the fact that we
15843 // temporarily wrap fallback and timed out children in an array.
15844 return toJSON(container.children[1]);
15845 }
15846 var renderedChildren = null;
15847 if (container.children && container.children.length) {
15848 for (var i = 0; i < container.children.length; i++) {
15849 var renderedChild = toJSON(container.children[i]);
15850 if (renderedChild !== null) {
15851 if (renderedChildren === null) {
15852 renderedChildren = [renderedChild];
15853 } else {
15854 renderedChildren.push(renderedChild);
15855 }
15856 }
15857 }
15858 }
15859 return renderedChildren;
15860 },
15861 toTree: function () {
15862 if (root == null || root.current == null) {
15863 return null;
15864 }
15865 return toTree(root.current);
15866 },
15867 update: function (newElement) {
15868 if (root == null || root.current == null) {
15869 return;
15870 }
15871 updateContainer(newElement, root, null, null);
15872 },
15873 unmount: function () {
15874 if (root == null || root.current == null) {
15875 return;
15876 }
15877 updateContainer(null, root, null, null);
15878 container = null;
15879 root = null;
15880 },
15881 getInstance: function () {
15882 if (root == null || root.current == null) {
15883 return null;
15884 }
15885 return getPublicRootInstance(root);
15886 },
15887 unstable_flushSync: function (fn) {
15888 return flushSync(fn);
15889 }
15890 };
15891
15892 Object.defineProperty(entry, 'root', {
15893 configurable: true,
15894 enumerable: true,
15895 get: function () {
15896 if (root === null) {
15897 throw new Error("Can't access .root on unmounted test renderer");
15898 }
15899 var children = getChildren(root.current);
15900 if (children.length === 0) {
15901 throw new Error("Can't access .root on unmounted test renderer");
15902 } else if (children.length === 1) {
15903 // Normally, we skip the root and just give you the child.
15904 return children[0];
15905 } else {
15906 // However, we give you the root if there's more than one root child.
15907 // We could make this the behavior for all cases but it would be a breaking change.
15908 return wrapFiber(root.current);
15909 }
15910 }
15911 });
15912
15913 return entry;
15914 },
15915
15916
15917 /* eslint-disable-next-line camelcase */
15918 unstable_batchedUpdates: batchedUpdates,
15919
15920 act: act
15921};
15922
15923var fiberToWrapper = new WeakMap();
15924function wrapFiber(fiber) {
15925 var wrapper = fiberToWrapper.get(fiber);
15926 if (wrapper === undefined && fiber.alternate !== null) {
15927 wrapper = fiberToWrapper.get(fiber.alternate);
15928 }
15929 if (wrapper === undefined) {
15930 wrapper = new ReactTestInstance(fiber);
15931 fiberToWrapper.set(fiber, wrapper);
15932 }
15933 return wrapper;
15934}
15935
15936// Enable ReactTestRenderer to be used to test DevTools integration.
15937injectIntoDevTools({
15938 findFiberByHostInstance: function () {
15939 throw new Error('TestRenderer does not support findFiberByHostInstance()');
15940 },
15941 bundleType: 1,
15942 version: ReactVersion,
15943 rendererPackageName: 'react-test-renderer'
15944});
15945
15946
15947
15948var ReactTestRenderer = Object.freeze({
15949 default: ReactTestRendererFiber
15950});
15951
15952var ReactTestRenderer$1 = ( ReactTestRenderer && ReactTestRendererFiber ) || ReactTestRenderer;
15953
15954// TODO: decide on the top-level export form.
15955// This is hacky but makes it work with both Rollup and Jest.
15956var reactTestRenderer = ReactTestRenderer$1.default || ReactTestRenderer$1;
15957
15958module.exports = reactTestRenderer;
15959 })();
15960}