UNPKG

604 kBJavaScriptView Raw
1/** @license React v16.9.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(function (global, factory) {
13 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react'), require('scheduler/unstable_mock'), require('scheduler')) :
14 typeof define === 'function' && define.amd ? define(['react', 'scheduler/unstable_mock', 'scheduler'], factory) :
15 (global.ReactTestRenderer = factory(global.React,global.SchedulerMock,global.Scheduler));
16}(this, (function (React,Scheduler,Scheduler$1) { 'use strict';
17
18// Do not require this module directly! Use normal `invariant` calls with
19// template literal strings. The messages will be converted to ReactError during
20// build, and in production they will be minified.
21
22// Do not require this module directly! Use normal `invariant` calls with
23// template literal strings. The messages will be converted to ReactError during
24// build, and in production they will be minified.
25
26function ReactError(error) {
27 error.name = 'Invariant Violation';
28 return error;
29}
30
31var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
32
33var _assign = ReactInternals.assign;
34
35var FunctionComponent = 0;
36var ClassComponent = 1;
37var IndeterminateComponent = 2; // Before we know whether it is function or class
38var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
39var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
40var HostComponent = 5;
41var HostText = 6;
42var Fragment = 7;
43var Mode = 8;
44var ContextConsumer = 9;
45var ContextProvider = 10;
46var ForwardRef = 11;
47var Profiler = 12;
48var SuspenseComponent = 13;
49var MemoComponent = 14;
50var SimpleMemoComponent = 15;
51var LazyComponent = 16;
52var IncompleteClassComponent = 17;
53var DehydratedSuspenseComponent = 18;
54var SuspenseListComponent = 19;
55var FundamentalComponent = 20;
56
57/**
58 * Use invariant() to assert state which your program assumes to be true.
59 *
60 * Provide sprintf-style format (only %s is supported) and arguments
61 * to provide information about what broke and what you were
62 * expecting.
63 *
64 * The invariant message will be stripped in production, but the invariant
65 * will remain to ensure logic does not differ in production.
66 */
67
68/**
69 * Similar to invariant but only logs a warning if the condition is not met.
70 * This can be used to log issues in development environments in critical
71 * paths. Removing the logging code for production environments will keep the
72 * same logic and follow the same code paths.
73 */
74
75var warningWithoutStack = function () {};
76
77{
78 warningWithoutStack = function (condition, format) {
79 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
80 args[_key - 2] = arguments[_key];
81 }
82
83 if (format === undefined) {
84 throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
85 }
86 if (args.length > 8) {
87 // Check before the condition to catch violations early.
88 throw new Error('warningWithoutStack() currently supports at most 8 arguments.');
89 }
90 if (condition) {
91 return;
92 }
93 if (typeof console !== 'undefined') {
94 var argsWithFormat = args.map(function (item) {
95 return '' + item;
96 });
97 argsWithFormat.unshift('Warning: ' + format);
98
99 // We intentionally don't use spread (or .apply) directly because it
100 // breaks IE9: https://github.com/facebook/react/issues/13610
101 Function.prototype.apply.call(console.error, console, argsWithFormat);
102 }
103 try {
104 // --- Welcome to debugging React ---
105 // This error was thrown as a convenience so that you can use this stack
106 // to find the callsite that caused this warning to fire.
107 var argIndex = 0;
108 var message = 'Warning: ' + format.replace(/%s/g, function () {
109 return args[argIndex++];
110 });
111 throw new Error(message);
112 } catch (x) {}
113 };
114}
115
116var warningWithoutStack$1 = warningWithoutStack;
117
118/**
119 * `ReactInstanceMap` maintains a mapping from a public facing stateful
120 * instance (key) and the internal representation (value). This allows public
121 * methods to accept the user facing instance as an argument and map them back
122 * to internal methods.
123 *
124 * Note that this module is currently shared and assumed to be stateless.
125 * If this becomes an actual Map, that will break.
126 */
127
128/**
129 * This API should be called `delete` but we'd have to make sure to always
130 * transform these to strings for IE support. When this transform is fully
131 * supported we can rename it.
132 */
133
134
135function get(key) {
136 return key._reactInternalFiber;
137}
138
139
140
141function set(key, value) {
142 key._reactInternalFiber = value;
143}
144
145var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
146
147// Prevent newer renderers from RTE when used with older react package versions.
148// Current owner and dispatcher used to share the same ref,
149// but PR #14548 split them out to better support the react-debug-tools package.
150if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
151 ReactSharedInternals.ReactCurrentDispatcher = {
152 current: null
153 };
154}
155if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {
156 ReactSharedInternals.ReactCurrentBatchConfig = {
157 suspense: null
158 };
159}
160
161// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
162// nor polyfill, then a plain number is used for performance.
163var hasSymbol = typeof Symbol === 'function' && Symbol.for;
164
165var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
166var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
167var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
168var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
169var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
170var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
171var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace;
172// TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
173// (unstable) APIs that have been removed. Can we remove the symbols?
174
175var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
176var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
177var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
178var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
179var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
180var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
181var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for('react.fundamental') : 0xead5;
182var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for('react.responder') : 0xead6;
183
184var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
185var FAUX_ITERATOR_SYMBOL = '@@iterator';
186
187function getIteratorFn(maybeIterable) {
188 if (maybeIterable === null || typeof maybeIterable !== 'object') {
189 return null;
190 }
191 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
192 if (typeof maybeIterator === 'function') {
193 return maybeIterator;
194 }
195 return null;
196}
197
198var Pending = 0;
199var Resolved = 1;
200var Rejected = 2;
201
202function refineResolvedLazyComponent(lazyComponent) {
203 return lazyComponent._status === Resolved ? lazyComponent._result : null;
204}
205
206function getWrappedName(outerType, innerType, wrapperName) {
207 var functionName = innerType.displayName || innerType.name || '';
208 return outerType.displayName || (functionName !== '' ? wrapperName + '(' + functionName + ')' : wrapperName);
209}
210
211function getComponentName(type) {
212 if (type == null) {
213 // Host root, text node or just invalid type.
214 return null;
215 }
216 {
217 if (typeof type.tag === 'number') {
218 warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
219 }
220 }
221 if (typeof type === 'function') {
222 return type.displayName || type.name || null;
223 }
224 if (typeof type === 'string') {
225 return type;
226 }
227 switch (type) {
228 case REACT_FRAGMENT_TYPE:
229 return 'Fragment';
230 case REACT_PORTAL_TYPE:
231 return 'Portal';
232 case REACT_PROFILER_TYPE:
233 return 'Profiler';
234 case REACT_STRICT_MODE_TYPE:
235 return 'StrictMode';
236 case REACT_SUSPENSE_TYPE:
237 return 'Suspense';
238 case REACT_SUSPENSE_LIST_TYPE:
239 return 'SuspenseList';
240 }
241 if (typeof type === 'object') {
242 switch (type.$$typeof) {
243 case REACT_CONTEXT_TYPE:
244 return 'Context.Consumer';
245 case REACT_PROVIDER_TYPE:
246 return 'Context.Provider';
247 case REACT_FORWARD_REF_TYPE:
248 return getWrappedName(type, type.render, 'ForwardRef');
249 case REACT_MEMO_TYPE:
250 return getComponentName(type.type);
251 case REACT_LAZY_TYPE:
252 {
253 var thenable = type;
254 var resolvedThenable = refineResolvedLazyComponent(thenable);
255 if (resolvedThenable) {
256 return getComponentName(resolvedThenable);
257 }
258 break;
259 }
260 }
261 }
262 return null;
263}
264
265// Don't change these two values. They're used by React Dev Tools.
266var NoEffect = /* */0;
267var PerformedWork = /* */1;
268
269// You can change the rest (and add more).
270var Placement = /* */2;
271var Update = /* */4;
272var PlacementAndUpdate = /* */6;
273var Deletion = /* */8;
274var ContentReset = /* */16;
275var Callback = /* */32;
276var DidCapture = /* */64;
277var Ref = /* */128;
278var Snapshot = /* */256;
279var Passive = /* */512;
280
281// Passive & Update & Callback & Ref & Snapshot
282var LifecycleEffectMask = /* */932;
283
284// Union of all host effects
285var HostEffectMask = /* */1023;
286
287var Incomplete = /* */1024;
288var ShouldCapture = /* */2048;
289
290var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
291
292var MOUNTING = 1;
293var MOUNTED = 2;
294var UNMOUNTED = 3;
295
296function isFiberMountedImpl(fiber) {
297 var node = fiber;
298 if (!fiber.alternate) {
299 // If there is no alternate, this might be a new tree that isn't inserted
300 // yet. If it is, then it will have a pending insertion effect on it.
301 if ((node.effectTag & Placement) !== NoEffect) {
302 return MOUNTING;
303 }
304 while (node.return) {
305 node = node.return;
306 if ((node.effectTag & Placement) !== NoEffect) {
307 return MOUNTING;
308 }
309 }
310 } else {
311 while (node.return) {
312 node = node.return;
313 }
314 }
315 if (node.tag === HostRoot) {
316 // TODO: Check if this was a nested HostRoot when used with
317 // renderContainerIntoSubtree.
318 return MOUNTED;
319 }
320 // If we didn't hit the root, that means that we're in an disconnected tree
321 // that has been unmounted.
322 return UNMOUNTED;
323}
324
325function isFiberMounted(fiber) {
326 return isFiberMountedImpl(fiber) === MOUNTED;
327}
328
329function isMounted(component) {
330 {
331 var owner = ReactCurrentOwner.current;
332 if (owner !== null && owner.tag === ClassComponent) {
333 var ownerFiber = owner;
334 var instance = ownerFiber.stateNode;
335 !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;
336 instance._warnedAboutRefsInRender = true;
337 }
338 }
339
340 var fiber = get(component);
341 if (!fiber) {
342 return false;
343 }
344 return isFiberMountedImpl(fiber) === MOUNTED;
345}
346
347function assertIsMounted(fiber) {
348 (function () {
349 if (!(isFiberMountedImpl(fiber) === MOUNTED)) {
350 {
351 throw ReactError(Error('Unable to find node on an unmounted component.'));
352 }
353 }
354 })();
355}
356
357function findCurrentFiberUsingSlowPath(fiber) {
358 var alternate = fiber.alternate;
359 if (!alternate) {
360 // If there is no alternate, then we only need to check if it is mounted.
361 var state = isFiberMountedImpl(fiber);
362 (function () {
363 if (!(state !== UNMOUNTED)) {
364 {
365 throw ReactError(Error('Unable to find node on an unmounted component.'));
366 }
367 }
368 })();
369 if (state === MOUNTING) {
370 return null;
371 }
372 return fiber;
373 }
374 // If we have two possible branches, we'll walk backwards up to the root
375 // to see what path the root points to. On the way we may hit one of the
376 // special cases and we'll deal with them.
377 var a = fiber;
378 var b = alternate;
379 while (true) {
380 var parentA = a.return;
381 if (parentA === null) {
382 // We're at the root.
383 break;
384 }
385 var parentB = parentA.alternate;
386 if (parentB === null) {
387 // There is no alternate. This is an unusual case. Currently, it only
388 // happens when a Suspense component is hidden. An extra fragment fiber
389 // is inserted in between the Suspense fiber and its children. Skip
390 // over this extra fragment fiber and proceed to the next parent.
391 var nextParent = parentA.return;
392 if (nextParent !== null) {
393 a = b = nextParent;
394 continue;
395 }
396 // If there's no parent, we're at the root.
397 break;
398 }
399
400 // If both copies of the parent fiber point to the same child, we can
401 // assume that the child is current. This happens when we bailout on low
402 // priority: the bailed out fiber's child reuses the current child.
403 if (parentA.child === parentB.child) {
404 var child = parentA.child;
405 while (child) {
406 if (child === a) {
407 // We've determined that A is the current branch.
408 assertIsMounted(parentA);
409 return fiber;
410 }
411 if (child === b) {
412 // We've determined that B is the current branch.
413 assertIsMounted(parentA);
414 return alternate;
415 }
416 child = child.sibling;
417 }
418 // We should never have an alternate for any mounting node. So the only
419 // way this could possibly happen is if this was unmounted, if at all.
420 (function () {
421 {
422 {
423 throw ReactError(Error('Unable to find node on an unmounted component.'));
424 }
425 }
426 })();
427 }
428
429 if (a.return !== b.return) {
430 // The return pointer of A and the return pointer of B point to different
431 // fibers. We assume that return pointers never criss-cross, so A must
432 // belong to the child set of A.return, and B must belong to the child
433 // set of B.return.
434 a = parentA;
435 b = parentB;
436 } else {
437 // The return pointers point to the same fiber. We'll have to use the
438 // default, slow path: scan the child sets of each parent alternate to see
439 // which child belongs to which set.
440 //
441 // Search parent A's child set
442 var didFindChild = false;
443 var _child = parentA.child;
444 while (_child) {
445 if (_child === a) {
446 didFindChild = true;
447 a = parentA;
448 b = parentB;
449 break;
450 }
451 if (_child === b) {
452 didFindChild = true;
453 b = parentA;
454 a = parentB;
455 break;
456 }
457 _child = _child.sibling;
458 }
459 if (!didFindChild) {
460 // Search parent B's child set
461 _child = parentB.child;
462 while (_child) {
463 if (_child === a) {
464 didFindChild = true;
465 a = parentB;
466 b = parentA;
467 break;
468 }
469 if (_child === b) {
470 didFindChild = true;
471 b = parentB;
472 a = parentA;
473 break;
474 }
475 _child = _child.sibling;
476 }
477 (function () {
478 if (!didFindChild) {
479 {
480 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.'));
481 }
482 }
483 })();
484 }
485 }
486
487 (function () {
488 if (!(a.alternate === b)) {
489 {
490 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.'));
491 }
492 }
493 })();
494 }
495 // If the root is not a host container, we're in a disconnected tree. I.e.
496 // unmounted.
497 (function () {
498 if (!(a.tag === HostRoot)) {
499 {
500 throw ReactError(Error('Unable to find node on an unmounted component.'));
501 }
502 }
503 })();
504 if (a.stateNode.current === a) {
505 // We've determined that A is the current branch.
506 return fiber;
507 }
508 // Otherwise B has to be current branch.
509 return alternate;
510}
511
512function findCurrentHostFiber(parent) {
513 var currentParent = findCurrentFiberUsingSlowPath(parent);
514 if (!currentParent) {
515 return null;
516 }
517
518 // Next we'll drill down this component to find the first HostComponent/Text.
519 var node = currentParent;
520 while (true) {
521 if (node.tag === HostComponent || node.tag === HostText) {
522 return node;
523 } else if (node.child) {
524 node.child.return = node;
525 node = node.child;
526 continue;
527 }
528 if (node === currentParent) {
529 return null;
530 }
531 while (!node.sibling) {
532 if (!node.return || node.return === currentParent) {
533 return null;
534 }
535 node = node.return;
536 }
537 node.sibling.return = node.return;
538 node = node.sibling;
539 }
540 // Flow needs the return null here, but ESLint complains about it.
541 // eslint-disable-next-line no-unreachable
542 return null;
543}
544
545/**
546 * Similar to invariant but only logs a warning if the condition is not met.
547 * This can be used to log issues in development environments in critical
548 * paths. Removing the logging code for production environments will keep the
549 * same logic and follow the same code paths.
550 */
551
552var warning = warningWithoutStack$1;
553
554{
555 warning = function (condition, format) {
556 if (condition) {
557 return;
558 }
559 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
560 var stack = ReactDebugCurrentFrame.getStackAddendum();
561 // eslint-disable-next-line react-internal/warning-and-invariant-args
562
563 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
564 args[_key - 2] = arguments[_key];
565 }
566
567 warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack]));
568 };
569}
570
571var warning$1 = warning;
572
573var debugRenderPhaseSideEffects = false;
574var debugRenderPhaseSideEffectsForStrictMode = false;
575var enableUserTimingAPI = true;
576var warnAboutDeprecatedLifecycles = true;
577var replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
578var enableProfilerTimer = true;
579var enableSchedulerTracing = true;
580var enableSuspenseServerRenderer = false;
581
582
583
584
585
586
587var enableFlareAPI = false;
588var enableFundamentalAPI = false;
589
590var warnAboutUnmockedScheduler = false;
591var revertPassiveEffectsChange = false;
592var flushSuspenseFallbacksInTests = true;
593
594var enableSuspenseCallback = false;
595var warnAboutDefaultPropsOnFunctionComponents = false;
596var disableLegacyContext = false;
597var disableSchedulerTimeoutBasedOnReactExpirationTime = false;
598
599// Only used in www builds.
600
601// Renderers that don't support persistence
602// can re-export everything from this module.
603
604function shim() {
605 (function () {
606 {
607 {
608 throw ReactError(Error('The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue.'));
609 }
610 }
611 })();
612}
613
614// Persistence (when unsupported)
615var supportsPersistence = false;
616var cloneInstance = shim;
617var cloneFundamentalInstance = shim;
618var createContainerChildSet = shim;
619var appendChildToContainerChildSet = shim;
620var finalizeContainerChildren = shim;
621var replaceContainerChildren = shim;
622var cloneHiddenInstance = shim;
623var cloneHiddenTextInstance = shim;
624
625// Renderers that don't support hydration
626// can re-export everything from this module.
627
628function shim$1() {
629 (function () {
630 {
631 {
632 throw ReactError(Error('The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue.'));
633 }
634 }
635 })();
636}
637
638// Hydration (when unsupported)
639
640var supportsHydration = false;
641var canHydrateInstance = shim$1;
642var canHydrateTextInstance = shim$1;
643var canHydrateSuspenseInstance = shim$1;
644var isSuspenseInstancePending = shim$1;
645var isSuspenseInstanceFallback = shim$1;
646var registerSuspenseInstanceRetry = shim$1;
647var getNextHydratableSibling = shim$1;
648var getFirstHydratableChild = shim$1;
649var hydrateInstance = shim$1;
650var hydrateTextInstance = shim$1;
651var getNextHydratableInstanceAfterSuspenseInstance = shim$1;
652var clearSuspenseBoundary = shim$1;
653var clearSuspenseBoundaryFromContainer = shim$1;
654var didNotMatchHydratedContainerTextInstance = shim$1;
655var didNotMatchHydratedTextInstance = shim$1;
656var didNotHydrateContainerInstance = shim$1;
657var didNotHydrateInstance = shim$1;
658var didNotFindHydratableContainerInstance = shim$1;
659var didNotFindHydratableContainerTextInstance = shim$1;
660var didNotFindHydratableContainerSuspenseInstance = shim$1;
661var didNotFindHydratableInstance = shim$1;
662var didNotFindHydratableTextInstance = shim$1;
663var didNotFindHydratableSuspenseInstance = shim$1;
664
665function _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; }
666
667var EVENT_COMPONENT_CONTEXT = {};
668var NO_CONTEXT = {};
669var UPDATE_SIGNAL = {};
670{
671 Object.freeze(NO_CONTEXT);
672 Object.freeze(UPDATE_SIGNAL);
673}
674
675function getPublicInstance(inst) {
676 switch (inst.tag) {
677 case 'INSTANCE':
678 var _createNodeMock = inst.rootContainerInstance.createNodeMock;
679 return _createNodeMock({
680 type: inst.type,
681 props: inst.props
682 });
683 default:
684 return inst;
685 }
686}
687
688function appendChild(parentInstance, child) {
689 {
690 !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;
691 }
692 var index = parentInstance.children.indexOf(child);
693 if (index !== -1) {
694 parentInstance.children.splice(index, 1);
695 }
696 parentInstance.children.push(child);
697}
698
699function insertBefore(parentInstance, child, beforeChild) {
700 var index = parentInstance.children.indexOf(child);
701 if (index !== -1) {
702 parentInstance.children.splice(index, 1);
703 }
704 var beforeIndex = parentInstance.children.indexOf(beforeChild);
705 parentInstance.children.splice(beforeIndex, 0, child);
706}
707
708function removeChild(parentInstance, child) {
709 var index = parentInstance.children.indexOf(child);
710 parentInstance.children.splice(index, 1);
711}
712
713function getRootHostContext(rootContainerInstance) {
714 return NO_CONTEXT;
715}
716
717function getChildHostContext(parentHostContext, type, rootContainerInstance) {
718 return NO_CONTEXT;
719}
720
721function prepareForCommit(containerInfo) {
722 // noop
723}
724
725function resetAfterCommit(containerInfo) {
726 // noop
727}
728
729function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
730 var propsToUse = props;
731 if (enableFlareAPI) {
732 if (props.listeners != null) {
733 // We want to remove the "listeners" prop
734 // as we don't want it in the test renderer's
735 // instance props.
736 var listeners = props.listeners,
737 otherProps = _objectWithoutProperties$1(props, ['listeners']); // eslint-disable-line
738
739
740 propsToUse = otherProps;
741 }
742 }
743 return {
744 type: type,
745 props: propsToUse,
746 isHidden: false,
747 children: [],
748 rootContainerInstance: rootContainerInstance,
749 tag: 'INSTANCE'
750 };
751}
752
753function appendInitialChild(parentInstance, child) {
754 var index = parentInstance.children.indexOf(child);
755 if (index !== -1) {
756 parentInstance.children.splice(index, 1);
757 }
758 parentInstance.children.push(child);
759}
760
761function finalizeInitialChildren(testElement, type, props, rootContainerInstance, hostContext) {
762 return false;
763}
764
765function prepareUpdate(testElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
766 return UPDATE_SIGNAL;
767}
768
769function shouldSetTextContent(type, props) {
770 return false;
771}
772
773function shouldDeprioritizeSubtree(type, props) {
774 return false;
775}
776
777function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
778 if (true && enableFlareAPI) {
779 !(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;
780 }
781 return {
782 text: text,
783 isHidden: false,
784 tag: 'TEXT'
785 };
786}
787
788var isPrimaryRenderer = false;
789var warnsIfNotActing = true;
790
791var scheduleTimeout = setTimeout;
792var cancelTimeout = clearTimeout;
793var noTimeout = -1;
794
795// -------------------
796// Mutation
797// -------------------
798
799var supportsMutation = true;
800
801function commitUpdate(instance, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
802 instance.type = type;
803 instance.props = newProps;
804}
805
806
807
808function commitTextUpdate(textInstance, oldText, newText) {
809 textInstance.text = newText;
810}
811
812function resetTextContent(testElement) {
813 // noop
814}
815
816var appendChildToContainer = appendChild;
817var insertInContainerBefore = insertBefore;
818var removeChildFromContainer = removeChild;
819
820function hideInstance(instance) {
821 instance.isHidden = true;
822}
823
824function hideTextInstance(textInstance) {
825 textInstance.isHidden = true;
826}
827
828function unhideInstance(instance, props) {
829 instance.isHidden = false;
830}
831
832function unhideTextInstance(textInstance, text) {
833 textInstance.isHidden = false;
834}
835
836
837
838
839
840function getFundamentalComponentInstance(fundamentalInstance) {
841 var impl = fundamentalInstance.impl,
842 props = fundamentalInstance.props,
843 state = fundamentalInstance.state;
844
845 return impl.getInstance(null, props, state);
846}
847
848function mountFundamentalComponent(fundamentalInstance) {
849 var impl = fundamentalInstance.impl,
850 instance = fundamentalInstance.instance,
851 props = fundamentalInstance.props,
852 state = fundamentalInstance.state;
853
854 var onMount = impl.onMount;
855 if (onMount !== undefined) {
856 onMount(null, instance, props, state);
857 }
858}
859
860function shouldUpdateFundamentalComponent(fundamentalInstance) {
861 var impl = fundamentalInstance.impl,
862 prevProps = fundamentalInstance.prevProps,
863 props = fundamentalInstance.props,
864 state = fundamentalInstance.state;
865
866 var shouldUpdate = impl.shouldUpdate;
867 if (shouldUpdate !== undefined) {
868 return shouldUpdate(null, prevProps, props, state);
869 }
870 return true;
871}
872
873function updateFundamentalComponent(fundamentalInstance) {
874 var impl = fundamentalInstance.impl,
875 instance = fundamentalInstance.instance,
876 prevProps = fundamentalInstance.prevProps,
877 props = fundamentalInstance.props,
878 state = fundamentalInstance.state;
879
880 var onUpdate = impl.onUpdate;
881 if (onUpdate !== undefined) {
882 onUpdate(null, instance, prevProps, props, state);
883 }
884}
885
886function unmountFundamentalComponent(fundamentalInstance) {
887 var impl = fundamentalInstance.impl,
888 instance = fundamentalInstance.instance,
889 props = fundamentalInstance.props,
890 state = fundamentalInstance.state;
891
892 var onUnmount = impl.onUnmount;
893 if (onUnmount !== undefined) {
894 onUnmount(null, instance, props, state);
895 }
896}
897
898/**
899 * Copyright (c) 2013-present, Facebook, Inc.
900 *
901 * This source code is licensed under the MIT license found in the
902 * LICENSE file in the root directory of this source tree.
903 */
904
905
906
907var ReactPropTypesSecret$1 = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
908
909var ReactPropTypesSecret_1 = ReactPropTypesSecret$1;
910
911/**
912 * Copyright (c) 2013-present, Facebook, Inc.
913 *
914 * This source code is licensed under the MIT license found in the
915 * LICENSE file in the root directory of this source tree.
916 */
917
918
919
920var printWarning = function() {};
921
922{
923 var ReactPropTypesSecret = ReactPropTypesSecret_1;
924 var loggedTypeFailures = {};
925
926 printWarning = function(text) {
927 var message = 'Warning: ' + text;
928 if (typeof console !== 'undefined') {
929 console.error(message);
930 }
931 try {
932 // --- Welcome to debugging React ---
933 // This error was thrown as a convenience so that you can use this stack
934 // to find the callsite that caused this warning to fire.
935 throw new Error(message);
936 } catch (x) {}
937 };
938}
939
940/**
941 * Assert that the values match with the type specs.
942 * Error messages are memorized and will only be shown once.
943 *
944 * @param {object} typeSpecs Map of name to a ReactPropType
945 * @param {object} values Runtime values that need to be type-checked
946 * @param {string} location e.g. "prop", "context", "child context"
947 * @param {string} componentName Name of the component for error messages.
948 * @param {?Function} getStack Returns the component stack.
949 * @private
950 */
951function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
952 {
953 for (var typeSpecName in typeSpecs) {
954 if (typeSpecs.hasOwnProperty(typeSpecName)) {
955 var error;
956 // Prop type validation may throw. In case they do, we don't want to
957 // fail the render phase where it didn't fail before. So we log it.
958 // After these have been cleaned up, we'll let them throw.
959 try {
960 // This is intentionally an invariant that gets caught. It's the same
961 // behavior as without this statement except with a better message.
962 if (typeof typeSpecs[typeSpecName] !== 'function') {
963 var err = Error(
964 (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +
965 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'
966 );
967 err.name = 'Invariant Violation';
968 throw err;
969 }
970 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
971 } catch (ex) {
972 error = ex;
973 }
974 if (error && !(error instanceof Error)) {
975 printWarning(
976 (componentName || 'React class') + ': type specification of ' +
977 location + ' `' + typeSpecName + '` is invalid; the type checker ' +
978 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +
979 'You may have forgotten to pass an argument to the type checker ' +
980 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
981 'shape all require an argument).'
982 );
983
984 }
985 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
986 // Only monitor this failure once because there tends to be a lot of the
987 // same error.
988 loggedTypeFailures[error.message] = true;
989
990 var stack = getStack ? getStack() : '';
991
992 printWarning(
993 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')
994 );
995 }
996 }
997 }
998 }
999}
1000
1001var checkPropTypes_1 = checkPropTypes;
1002
1003var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
1004
1005var describeComponentFrame = function (name, source, ownerName) {
1006 var sourceInfo = '';
1007 if (source) {
1008 var path = source.fileName;
1009 var fileName = path.replace(BEFORE_SLASH_RE, '');
1010 {
1011 // In DEV, include code for a common special case:
1012 // prefer "folder/index.js" instead of just "index.js".
1013 if (/^index\./.test(fileName)) {
1014 var match = path.match(BEFORE_SLASH_RE);
1015 if (match) {
1016 var pathBeforeSlash = match[1];
1017 if (pathBeforeSlash) {
1018 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
1019 fileName = folderName + '/' + fileName;
1020 }
1021 }
1022 }
1023 }
1024 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
1025 } else if (ownerName) {
1026 sourceInfo = ' (created by ' + ownerName + ')';
1027 }
1028 return '\n in ' + (name || 'Unknown') + sourceInfo;
1029};
1030
1031var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1032
1033function describeFiber(fiber) {
1034 switch (fiber.tag) {
1035 case HostRoot:
1036 case HostPortal:
1037 case HostText:
1038 case Fragment:
1039 case ContextProvider:
1040 case ContextConsumer:
1041 return '';
1042 default:
1043 var owner = fiber._debugOwner;
1044 var source = fiber._debugSource;
1045 var name = getComponentName(fiber.type);
1046 var ownerName = null;
1047 if (owner) {
1048 ownerName = getComponentName(owner.type);
1049 }
1050 return describeComponentFrame(name, source, ownerName);
1051 }
1052}
1053
1054function getStackByFiberInDevAndProd(workInProgress) {
1055 var info = '';
1056 var node = workInProgress;
1057 do {
1058 info += describeFiber(node);
1059 node = node.return;
1060 } while (node);
1061 return info;
1062}
1063
1064var current = null;
1065var phase = null;
1066
1067function getCurrentFiberOwnerNameInDevOrNull() {
1068 {
1069 if (current === null) {
1070 return null;
1071 }
1072 var owner = current._debugOwner;
1073 if (owner !== null && typeof owner !== 'undefined') {
1074 return getComponentName(owner.type);
1075 }
1076 }
1077 return null;
1078}
1079
1080function getCurrentFiberStackInDev() {
1081 {
1082 if (current === null) {
1083 return '';
1084 }
1085 // Safe because if current fiber exists, we are reconciling,
1086 // and it is guaranteed to be the work-in-progress version.
1087 return getStackByFiberInDevAndProd(current);
1088 }
1089 return '';
1090}
1091
1092function resetCurrentFiber() {
1093 {
1094 ReactDebugCurrentFrame.getCurrentStack = null;
1095 current = null;
1096 phase = null;
1097 }
1098}
1099
1100function setCurrentFiber(fiber) {
1101 {
1102 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
1103 current = fiber;
1104 phase = null;
1105 }
1106}
1107
1108function setCurrentPhase(lifeCyclePhase) {
1109 {
1110 phase = lifeCyclePhase;
1111 }
1112}
1113
1114// Prefix measurements so that it's possible to filter them.
1115// Longer prefixes are hard to read in DevTools.
1116var reactEmoji = '\u269B';
1117var warningEmoji = '\u26D4';
1118var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
1119
1120// Keep track of current fiber so that we know the path to unwind on pause.
1121// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
1122var currentFiber = null;
1123// If we're in the middle of user code, which fiber and method is it?
1124// Reusing `currentFiber` would be confusing for this because user code fiber
1125// can change during commit phase too, but we don't need to unwind it (since
1126// lifecycles in the commit phase don't resemble a tree).
1127var currentPhase = null;
1128var currentPhaseFiber = null;
1129// Did lifecycle hook schedule an update? This is often a performance problem,
1130// so we will keep track of it, and include it in the report.
1131// Track commits caused by cascading updates.
1132var isCommitting = false;
1133var hasScheduledUpdateInCurrentCommit = false;
1134var hasScheduledUpdateInCurrentPhase = false;
1135var commitCountInCurrentWorkLoop = 0;
1136var effectCountInCurrentCommit = 0;
1137var isWaitingForCallback = false;
1138// During commits, we only show a measurement once per method name
1139// to avoid stretch the commit phase with measurement overhead.
1140var labelsInCurrentCommit = new Set();
1141
1142var formatMarkName = function (markName) {
1143 return reactEmoji + ' ' + markName;
1144};
1145
1146var formatLabel = function (label, warning) {
1147 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
1148 var suffix = warning ? ' Warning: ' + warning : '';
1149 return '' + prefix + label + suffix;
1150};
1151
1152var beginMark = function (markName) {
1153 performance.mark(formatMarkName(markName));
1154};
1155
1156var clearMark = function (markName) {
1157 performance.clearMarks(formatMarkName(markName));
1158};
1159
1160var endMark = function (label, markName, warning) {
1161 var formattedMarkName = formatMarkName(markName);
1162 var formattedLabel = formatLabel(label, warning);
1163 try {
1164 performance.measure(formattedLabel, formattedMarkName);
1165 } catch (err) {}
1166 // If previous mark was missing for some reason, this will throw.
1167 // This could only happen if React crashed in an unexpected place earlier.
1168 // Don't pile on with more errors.
1169
1170 // Clear marks immediately to avoid growing buffer.
1171 performance.clearMarks(formattedMarkName);
1172 performance.clearMeasures(formattedLabel);
1173};
1174
1175var getFiberMarkName = function (label, debugID) {
1176 return label + ' (#' + debugID + ')';
1177};
1178
1179var getFiberLabel = function (componentName, isMounted, phase) {
1180 if (phase === null) {
1181 // These are composite component total time measurements.
1182 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
1183 } else {
1184 // Composite component methods.
1185 return componentName + '.' + phase;
1186 }
1187};
1188
1189var beginFiberMark = function (fiber, phase) {
1190 var componentName = getComponentName(fiber.type) || 'Unknown';
1191 var debugID = fiber._debugID;
1192 var isMounted = fiber.alternate !== null;
1193 var label = getFiberLabel(componentName, isMounted, phase);
1194
1195 if (isCommitting && labelsInCurrentCommit.has(label)) {
1196 // During the commit phase, we don't show duplicate labels because
1197 // there is a fixed overhead for every measurement, and we don't
1198 // want to stretch the commit phase beyond necessary.
1199 return false;
1200 }
1201 labelsInCurrentCommit.add(label);
1202
1203 var markName = getFiberMarkName(label, debugID);
1204 beginMark(markName);
1205 return true;
1206};
1207
1208var clearFiberMark = function (fiber, phase) {
1209 var componentName = getComponentName(fiber.type) || 'Unknown';
1210 var debugID = fiber._debugID;
1211 var isMounted = fiber.alternate !== null;
1212 var label = getFiberLabel(componentName, isMounted, phase);
1213 var markName = getFiberMarkName(label, debugID);
1214 clearMark(markName);
1215};
1216
1217var endFiberMark = function (fiber, phase, warning) {
1218 var componentName = getComponentName(fiber.type) || 'Unknown';
1219 var debugID = fiber._debugID;
1220 var isMounted = fiber.alternate !== null;
1221 var label = getFiberLabel(componentName, isMounted, phase);
1222 var markName = getFiberMarkName(label, debugID);
1223 endMark(label, markName, warning);
1224};
1225
1226var shouldIgnoreFiber = function (fiber) {
1227 // Host components should be skipped in the timeline.
1228 // We could check typeof fiber.type, but does this work with RN?
1229 switch (fiber.tag) {
1230 case HostRoot:
1231 case HostComponent:
1232 case HostText:
1233 case HostPortal:
1234 case Fragment:
1235 case ContextProvider:
1236 case ContextConsumer:
1237 case Mode:
1238 return true;
1239 default:
1240 return false;
1241 }
1242};
1243
1244var clearPendingPhaseMeasurement = function () {
1245 if (currentPhase !== null && currentPhaseFiber !== null) {
1246 clearFiberMark(currentPhaseFiber, currentPhase);
1247 }
1248 currentPhaseFiber = null;
1249 currentPhase = null;
1250 hasScheduledUpdateInCurrentPhase = false;
1251};
1252
1253var pauseTimers = function () {
1254 // Stops all currently active measurements so that they can be resumed
1255 // if we continue in a later deferred loop from the same unit of work.
1256 var fiber = currentFiber;
1257 while (fiber) {
1258 if (fiber._debugIsCurrentlyTiming) {
1259 endFiberMark(fiber, null, null);
1260 }
1261 fiber = fiber.return;
1262 }
1263};
1264
1265var resumeTimersRecursively = function (fiber) {
1266 if (fiber.return !== null) {
1267 resumeTimersRecursively(fiber.return);
1268 }
1269 if (fiber._debugIsCurrentlyTiming) {
1270 beginFiberMark(fiber, null);
1271 }
1272};
1273
1274var resumeTimers = function () {
1275 // Resumes all measurements that were active during the last deferred loop.
1276 if (currentFiber !== null) {
1277 resumeTimersRecursively(currentFiber);
1278 }
1279};
1280
1281function recordEffect() {
1282 if (enableUserTimingAPI) {
1283 effectCountInCurrentCommit++;
1284 }
1285}
1286
1287function recordScheduleUpdate() {
1288 if (enableUserTimingAPI) {
1289 if (isCommitting) {
1290 hasScheduledUpdateInCurrentCommit = true;
1291 }
1292 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
1293 hasScheduledUpdateInCurrentPhase = true;
1294 }
1295 }
1296}
1297
1298function startRequestCallbackTimer() {
1299 if (enableUserTimingAPI) {
1300 if (supportsUserTiming && !isWaitingForCallback) {
1301 isWaitingForCallback = true;
1302 beginMark('(Waiting for async callback...)');
1303 }
1304 }
1305}
1306
1307function stopRequestCallbackTimer(didExpire) {
1308 if (enableUserTimingAPI) {
1309 if (supportsUserTiming) {
1310 isWaitingForCallback = false;
1311 var warning = didExpire ? 'Update expired; will flush synchronously' : null;
1312 endMark('(Waiting for async callback...)', '(Waiting for async callback...)', warning);
1313 }
1314 }
1315}
1316
1317function startWorkTimer(fiber) {
1318 if (enableUserTimingAPI) {
1319 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1320 return;
1321 }
1322 // If we pause, this is the fiber to unwind from.
1323 currentFiber = fiber;
1324 if (!beginFiberMark(fiber, null)) {
1325 return;
1326 }
1327 fiber._debugIsCurrentlyTiming = true;
1328 }
1329}
1330
1331function cancelWorkTimer(fiber) {
1332 if (enableUserTimingAPI) {
1333 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1334 return;
1335 }
1336 // Remember we shouldn't complete measurement for this fiber.
1337 // Otherwise flamechart will be deep even for small updates.
1338 fiber._debugIsCurrentlyTiming = false;
1339 clearFiberMark(fiber, null);
1340 }
1341}
1342
1343function stopWorkTimer(fiber) {
1344 if (enableUserTimingAPI) {
1345 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1346 return;
1347 }
1348 // If we pause, its parent is the fiber to unwind from.
1349 currentFiber = fiber.return;
1350 if (!fiber._debugIsCurrentlyTiming) {
1351 return;
1352 }
1353 fiber._debugIsCurrentlyTiming = false;
1354 endFiberMark(fiber, null, null);
1355 }
1356}
1357
1358function stopFailedWorkTimer(fiber) {
1359 if (enableUserTimingAPI) {
1360 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1361 return;
1362 }
1363 // If we pause, its parent is the fiber to unwind from.
1364 currentFiber = fiber.return;
1365 if (!fiber._debugIsCurrentlyTiming) {
1366 return;
1367 }
1368 fiber._debugIsCurrentlyTiming = false;
1369 var warning = fiber.tag === SuspenseComponent || fiber.tag === DehydratedSuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
1370 endFiberMark(fiber, null, warning);
1371 }
1372}
1373
1374function startPhaseTimer(fiber, phase) {
1375 if (enableUserTimingAPI) {
1376 if (!supportsUserTiming) {
1377 return;
1378 }
1379 clearPendingPhaseMeasurement();
1380 if (!beginFiberMark(fiber, phase)) {
1381 return;
1382 }
1383 currentPhaseFiber = fiber;
1384 currentPhase = phase;
1385 }
1386}
1387
1388function stopPhaseTimer() {
1389 if (enableUserTimingAPI) {
1390 if (!supportsUserTiming) {
1391 return;
1392 }
1393 if (currentPhase !== null && currentPhaseFiber !== null) {
1394 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
1395 endFiberMark(currentPhaseFiber, currentPhase, warning);
1396 }
1397 currentPhase = null;
1398 currentPhaseFiber = null;
1399 }
1400}
1401
1402function startWorkLoopTimer(nextUnitOfWork) {
1403 if (enableUserTimingAPI) {
1404 currentFiber = nextUnitOfWork;
1405 if (!supportsUserTiming) {
1406 return;
1407 }
1408 commitCountInCurrentWorkLoop = 0;
1409 // This is top level call.
1410 // Any other measurements are performed within.
1411 beginMark('(React Tree Reconciliation)');
1412 // Resume any measurements that were in progress during the last loop.
1413 resumeTimers();
1414 }
1415}
1416
1417function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
1418 if (enableUserTimingAPI) {
1419 if (!supportsUserTiming) {
1420 return;
1421 }
1422 var warning = null;
1423 if (interruptedBy !== null) {
1424 if (interruptedBy.tag === HostRoot) {
1425 warning = 'A top-level update interrupted the previous render';
1426 } else {
1427 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
1428 warning = 'An update to ' + componentName + ' interrupted the previous render';
1429 }
1430 } else if (commitCountInCurrentWorkLoop > 1) {
1431 warning = 'There were cascading updates';
1432 }
1433 commitCountInCurrentWorkLoop = 0;
1434 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)';
1435 // Pause any measurements until the next loop.
1436 pauseTimers();
1437 endMark(label, '(React Tree Reconciliation)', warning);
1438 }
1439}
1440
1441function startCommitTimer() {
1442 if (enableUserTimingAPI) {
1443 if (!supportsUserTiming) {
1444 return;
1445 }
1446 isCommitting = true;
1447 hasScheduledUpdateInCurrentCommit = false;
1448 labelsInCurrentCommit.clear();
1449 beginMark('(Committing Changes)');
1450 }
1451}
1452
1453function stopCommitTimer() {
1454 if (enableUserTimingAPI) {
1455 if (!supportsUserTiming) {
1456 return;
1457 }
1458
1459 var warning = null;
1460 if (hasScheduledUpdateInCurrentCommit) {
1461 warning = 'Lifecycle hook scheduled a cascading update';
1462 } else if (commitCountInCurrentWorkLoop > 0) {
1463 warning = 'Caused by a cascading update in earlier commit';
1464 }
1465 hasScheduledUpdateInCurrentCommit = false;
1466 commitCountInCurrentWorkLoop++;
1467 isCommitting = false;
1468 labelsInCurrentCommit.clear();
1469
1470 endMark('(Committing Changes)', '(Committing Changes)', warning);
1471 }
1472}
1473
1474function startCommitSnapshotEffectsTimer() {
1475 if (enableUserTimingAPI) {
1476 if (!supportsUserTiming) {
1477 return;
1478 }
1479 effectCountInCurrentCommit = 0;
1480 beginMark('(Committing Snapshot Effects)');
1481 }
1482}
1483
1484function stopCommitSnapshotEffectsTimer() {
1485 if (enableUserTimingAPI) {
1486 if (!supportsUserTiming) {
1487 return;
1488 }
1489 var count = effectCountInCurrentCommit;
1490 effectCountInCurrentCommit = 0;
1491 endMark('(Committing Snapshot Effects: ' + count + ' Total)', '(Committing Snapshot Effects)', null);
1492 }
1493}
1494
1495function startCommitHostEffectsTimer() {
1496 if (enableUserTimingAPI) {
1497 if (!supportsUserTiming) {
1498 return;
1499 }
1500 effectCountInCurrentCommit = 0;
1501 beginMark('(Committing Host Effects)');
1502 }
1503}
1504
1505function stopCommitHostEffectsTimer() {
1506 if (enableUserTimingAPI) {
1507 if (!supportsUserTiming) {
1508 return;
1509 }
1510 var count = effectCountInCurrentCommit;
1511 effectCountInCurrentCommit = 0;
1512 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
1513 }
1514}
1515
1516function startCommitLifeCyclesTimer() {
1517 if (enableUserTimingAPI) {
1518 if (!supportsUserTiming) {
1519 return;
1520 }
1521 effectCountInCurrentCommit = 0;
1522 beginMark('(Calling Lifecycle Methods)');
1523 }
1524}
1525
1526function stopCommitLifeCyclesTimer() {
1527 if (enableUserTimingAPI) {
1528 if (!supportsUserTiming) {
1529 return;
1530 }
1531 var count = effectCountInCurrentCommit;
1532 effectCountInCurrentCommit = 0;
1533 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
1534 }
1535}
1536
1537var valueStack = [];
1538
1539var fiberStack = void 0;
1540
1541{
1542 fiberStack = [];
1543}
1544
1545var index = -1;
1546
1547function createCursor(defaultValue) {
1548 return {
1549 current: defaultValue
1550 };
1551}
1552
1553function pop(cursor, fiber) {
1554 if (index < 0) {
1555 {
1556 warningWithoutStack$1(false, 'Unexpected pop.');
1557 }
1558 return;
1559 }
1560
1561 {
1562 if (fiber !== fiberStack[index]) {
1563 warningWithoutStack$1(false, 'Unexpected Fiber popped.');
1564 }
1565 }
1566
1567 cursor.current = valueStack[index];
1568
1569 valueStack[index] = null;
1570
1571 {
1572 fiberStack[index] = null;
1573 }
1574
1575 index--;
1576}
1577
1578function push(cursor, value, fiber) {
1579 index++;
1580
1581 valueStack[index] = cursor.current;
1582
1583 {
1584 fiberStack[index] = fiber;
1585 }
1586
1587 cursor.current = value;
1588}
1589
1590var warnedAboutMissingGetChildContext = void 0;
1591
1592{
1593 warnedAboutMissingGetChildContext = {};
1594}
1595
1596var emptyContextObject = {};
1597{
1598 Object.freeze(emptyContextObject);
1599}
1600
1601// A cursor to the current merged context object on the stack.
1602var contextStackCursor = createCursor(emptyContextObject);
1603// A cursor to a boolean indicating whether the context has changed.
1604var didPerformWorkStackCursor = createCursor(false);
1605// Keep track of the previous context object that was on the stack.
1606// We use this to get access to the parent context after we have already
1607// pushed the next context provider, and now need to merge their contexts.
1608var previousContext = emptyContextObject;
1609
1610function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
1611 if (disableLegacyContext) {
1612 return emptyContextObject;
1613 } else {
1614 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
1615 // If the fiber is a context provider itself, when we read its context
1616 // we may have already pushed its own child context on the stack. A context
1617 // provider should not "see" its own child context. Therefore we read the
1618 // previous (parent) context instead for a context provider.
1619 return previousContext;
1620 }
1621 return contextStackCursor.current;
1622 }
1623}
1624
1625function cacheContext(workInProgress, unmaskedContext, maskedContext) {
1626 if (disableLegacyContext) {
1627 return;
1628 } else {
1629 var instance = workInProgress.stateNode;
1630 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
1631 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
1632 }
1633}
1634
1635function getMaskedContext(workInProgress, unmaskedContext) {
1636 if (disableLegacyContext) {
1637 return emptyContextObject;
1638 } else {
1639 var type = workInProgress.type;
1640 var contextTypes = type.contextTypes;
1641 if (!contextTypes) {
1642 return emptyContextObject;
1643 }
1644
1645 // Avoid recreating masked context unless unmasked context has changed.
1646 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
1647 // This may trigger infinite loops if componentWillReceiveProps calls setState.
1648 var instance = workInProgress.stateNode;
1649 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
1650 return instance.__reactInternalMemoizedMaskedChildContext;
1651 }
1652
1653 var context = {};
1654 for (var key in contextTypes) {
1655 context[key] = unmaskedContext[key];
1656 }
1657
1658 {
1659 var name = getComponentName(type) || 'Unknown';
1660 checkPropTypes_1(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
1661 }
1662
1663 // Cache unmasked context so we can avoid recreating masked context unless necessary.
1664 // Context is created before the class component is instantiated so check for instance.
1665 if (instance) {
1666 cacheContext(workInProgress, unmaskedContext, context);
1667 }
1668
1669 return context;
1670 }
1671}
1672
1673function hasContextChanged() {
1674 if (disableLegacyContext) {
1675 return false;
1676 } else {
1677 return didPerformWorkStackCursor.current;
1678 }
1679}
1680
1681function isContextProvider(type) {
1682 if (disableLegacyContext) {
1683 return false;
1684 } else {
1685 var childContextTypes = type.childContextTypes;
1686 return childContextTypes !== null && childContextTypes !== undefined;
1687 }
1688}
1689
1690function popContext(fiber) {
1691 if (disableLegacyContext) {
1692 return;
1693 } else {
1694 pop(didPerformWorkStackCursor, fiber);
1695 pop(contextStackCursor, fiber);
1696 }
1697}
1698
1699function popTopLevelContextObject(fiber) {
1700 if (disableLegacyContext) {
1701 return;
1702 } else {
1703 pop(didPerformWorkStackCursor, fiber);
1704 pop(contextStackCursor, fiber);
1705 }
1706}
1707
1708function pushTopLevelContextObject(fiber, context, didChange) {
1709 if (disableLegacyContext) {
1710 return;
1711 } else {
1712 (function () {
1713 if (!(contextStackCursor.current === emptyContextObject)) {
1714 {
1715 throw ReactError(Error('Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue.'));
1716 }
1717 }
1718 })();
1719
1720 push(contextStackCursor, context, fiber);
1721 push(didPerformWorkStackCursor, didChange, fiber);
1722 }
1723}
1724
1725function processChildContext(fiber, type, parentContext) {
1726 if (disableLegacyContext) {
1727 return parentContext;
1728 } else {
1729 var instance = fiber.stateNode;
1730 var childContextTypes = type.childContextTypes;
1731
1732 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
1733 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
1734 if (typeof instance.getChildContext !== 'function') {
1735 {
1736 var componentName = getComponentName(type) || 'Unknown';
1737
1738 if (!warnedAboutMissingGetChildContext[componentName]) {
1739 warnedAboutMissingGetChildContext[componentName] = true;
1740 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);
1741 }
1742 }
1743 return parentContext;
1744 }
1745
1746 var childContext = void 0;
1747 {
1748 setCurrentPhase('getChildContext');
1749 }
1750 startPhaseTimer(fiber, 'getChildContext');
1751 childContext = instance.getChildContext();
1752 stopPhaseTimer();
1753 {
1754 setCurrentPhase(null);
1755 }
1756 for (var contextKey in childContext) {
1757 (function () {
1758 if (!(contextKey in childContextTypes)) {
1759 {
1760 throw ReactError(Error((getComponentName(type) || 'Unknown') + '.getChildContext(): key "' + contextKey + '" is not defined in childContextTypes.'));
1761 }
1762 }
1763 })();
1764 }
1765 {
1766 var name = getComponentName(type) || 'Unknown';
1767 checkPropTypes_1(childContextTypes, childContext, 'child context', name,
1768 // In practice, there is one case in which we won't get a stack. It's when
1769 // somebody calls unstable_renderSubtreeIntoContainer() and we process
1770 // context from the parent component instance. The stack will be missing
1771 // because it's outside of the reconciliation, and so the pointer has not
1772 // been set. This is rare and doesn't matter. We'll also remove that API.
1773 getCurrentFiberStackInDev);
1774 }
1775
1776 return _assign({}, parentContext, childContext);
1777 }
1778}
1779
1780function pushContextProvider(workInProgress) {
1781 if (disableLegacyContext) {
1782 return false;
1783 } else {
1784 var instance = workInProgress.stateNode;
1785 // We push the context as early as possible to ensure stack integrity.
1786 // If the instance does not exist yet, we will push null at first,
1787 // and replace it on the stack later when invalidating the context.
1788 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject;
1789
1790 // Remember the parent context so we can merge with it later.
1791 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
1792 previousContext = contextStackCursor.current;
1793 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
1794 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
1795
1796 return true;
1797 }
1798}
1799
1800function invalidateContextProvider(workInProgress, type, didChange) {
1801 if (disableLegacyContext) {
1802 return;
1803 } else {
1804 var instance = workInProgress.stateNode;
1805 (function () {
1806 if (!instance) {
1807 {
1808 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.'));
1809 }
1810 }
1811 })();
1812
1813 if (didChange) {
1814 // Merge parent and own context.
1815 // Skip this if we're not updating due to sCU.
1816 // This avoids unnecessarily recomputing memoized values.
1817 var mergedContext = processChildContext(workInProgress, type, previousContext);
1818 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
1819
1820 // Replace the old (or empty) context with the new one.
1821 // It is important to unwind the context in the reverse order.
1822 pop(didPerformWorkStackCursor, workInProgress);
1823 pop(contextStackCursor, workInProgress);
1824 // Now push the new context and mark that it has changed.
1825 push(contextStackCursor, mergedContext, workInProgress);
1826 push(didPerformWorkStackCursor, didChange, workInProgress);
1827 } else {
1828 pop(didPerformWorkStackCursor, workInProgress);
1829 push(didPerformWorkStackCursor, didChange, workInProgress);
1830 }
1831 }
1832}
1833
1834function findCurrentUnmaskedContext(fiber) {
1835 if (disableLegacyContext) {
1836 return emptyContextObject;
1837 } else {
1838 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
1839 // makes sense elsewhere
1840 (function () {
1841 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {
1842 {
1843 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.'));
1844 }
1845 }
1846 })();
1847
1848 var node = fiber;
1849 do {
1850 switch (node.tag) {
1851 case HostRoot:
1852 return node.stateNode.context;
1853 case ClassComponent:
1854 {
1855 var Component = node.type;
1856 if (isContextProvider(Component)) {
1857 return node.stateNode.__reactInternalMemoizedMergedChildContext;
1858 }
1859 break;
1860 }
1861 }
1862 node = node.return;
1863 } while (node !== null);
1864 (function () {
1865 {
1866 {
1867 throw ReactError(Error('Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.'));
1868 }
1869 }
1870 })();
1871 }
1872}
1873
1874var LegacyRoot = 0;
1875var BatchedRoot = 1;
1876var ConcurrentRoot = 2;
1877
1878var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
1879
1880var _ReactInternals$Sched = ReactInternals$1.SchedulerTracing;
1881var __interactionsRef = _ReactInternals$Sched.__interactionsRef;
1882var __subscriberRef = _ReactInternals$Sched.__subscriberRef;
1883var unstable_clear = _ReactInternals$Sched.unstable_clear;
1884var unstable_getCurrent = _ReactInternals$Sched.unstable_getCurrent;
1885var unstable_getThreadID = _ReactInternals$Sched.unstable_getThreadID;
1886var unstable_subscribe = _ReactInternals$Sched.unstable_subscribe;
1887var unstable_trace = _ReactInternals$Sched.unstable_trace;
1888var unstable_unsubscribe = _ReactInternals$Sched.unstable_unsubscribe;
1889var unstable_wrap = _ReactInternals$Sched.unstable_wrap;
1890
1891// Intentionally not named imports because Rollup would use dynamic dispatch for
1892// CommonJS interop named imports.
1893var Scheduler_runWithPriority = Scheduler$1.unstable_runWithPriority;
1894var Scheduler_scheduleCallback = Scheduler$1.unstable_scheduleCallback;
1895var Scheduler_cancelCallback = Scheduler$1.unstable_cancelCallback;
1896var Scheduler_shouldYield = Scheduler$1.unstable_shouldYield;
1897var Scheduler_requestPaint = Scheduler$1.unstable_requestPaint;
1898var Scheduler_now = Scheduler$1.unstable_now;
1899var Scheduler_getCurrentPriorityLevel = Scheduler$1.unstable_getCurrentPriorityLevel;
1900var Scheduler_ImmediatePriority = Scheduler$1.unstable_ImmediatePriority;
1901var Scheduler_UserBlockingPriority = Scheduler$1.unstable_UserBlockingPriority;
1902var Scheduler_NormalPriority = Scheduler$1.unstable_NormalPriority;
1903var Scheduler_LowPriority = Scheduler$1.unstable_LowPriority;
1904var Scheduler_IdlePriority = Scheduler$1.unstable_IdlePriority;
1905
1906
1907if (enableSchedulerTracing) {
1908 // Provide explicit error message when production+profiling bundle of e.g.
1909 // react-dom is used with production (non-profiling) bundle of
1910 // scheduler/tracing
1911 (function () {
1912 if (!(__interactionsRef != null && __interactionsRef.current != null)) {
1913 {
1914 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'));
1915 }
1916 }
1917 })();
1918}
1919
1920var fakeCallbackNode = {};
1921
1922// Except for NoPriority, these correspond to Scheduler priorities. We use
1923// ascending numbers so we can compare them like numbers. They start at 90 to
1924// avoid clashing with Scheduler's priorities.
1925var ImmediatePriority = 99;
1926var UserBlockingPriority = 98;
1927var NormalPriority = 97;
1928var LowPriority = 96;
1929var IdlePriority = 95;
1930// NoPriority is the absence of priority. Also React-only.
1931var NoPriority = 90;
1932
1933var shouldYield = Scheduler_shouldYield;
1934var requestPaint =
1935// Fall back gracefully if we're running an older version of Scheduler.
1936Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {};
1937
1938var syncQueue = null;
1939var immediateQueueCallbackNode = null;
1940var isFlushingSyncQueue = false;
1941var initialTimeMs = Scheduler_now();
1942
1943// If the initial timestamp is reasonably small, use Scheduler's `now` directly.
1944// This will be the case for modern browsers that support `performance.now`. In
1945// older browsers, Scheduler falls back to `Date.now`, which returns a Unix
1946// timestamp. In that case, subtract the module initialization time to simulate
1947// the behavior of performance.now and keep our times small enough to fit
1948// within 32 bits.
1949// TODO: Consider lifting this into Scheduler.
1950var now = initialTimeMs < 10000 ? Scheduler_now : function () {
1951 return Scheduler_now() - initialTimeMs;
1952};
1953
1954function getCurrentPriorityLevel() {
1955 switch (Scheduler_getCurrentPriorityLevel()) {
1956 case Scheduler_ImmediatePriority:
1957 return ImmediatePriority;
1958 case Scheduler_UserBlockingPriority:
1959 return UserBlockingPriority;
1960 case Scheduler_NormalPriority:
1961 return NormalPriority;
1962 case Scheduler_LowPriority:
1963 return LowPriority;
1964 case Scheduler_IdlePriority:
1965 return IdlePriority;
1966 default:
1967 (function () {
1968 {
1969 {
1970 throw ReactError(Error('Unknown priority level.'));
1971 }
1972 }
1973 })();
1974 }
1975}
1976
1977function reactPriorityToSchedulerPriority(reactPriorityLevel) {
1978 switch (reactPriorityLevel) {
1979 case ImmediatePriority:
1980 return Scheduler_ImmediatePriority;
1981 case UserBlockingPriority:
1982 return Scheduler_UserBlockingPriority;
1983 case NormalPriority:
1984 return Scheduler_NormalPriority;
1985 case LowPriority:
1986 return Scheduler_LowPriority;
1987 case IdlePriority:
1988 return Scheduler_IdlePriority;
1989 default:
1990 (function () {
1991 {
1992 {
1993 throw ReactError(Error('Unknown priority level.'));
1994 }
1995 }
1996 })();
1997 }
1998}
1999
2000function runWithPriority(reactPriorityLevel, fn) {
2001 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
2002 return Scheduler_runWithPriority(priorityLevel, fn);
2003}
2004
2005function scheduleCallback(reactPriorityLevel, callback, options) {
2006 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
2007 return Scheduler_scheduleCallback(priorityLevel, callback, options);
2008}
2009
2010function scheduleSyncCallback(callback) {
2011 // Push this callback into an internal queue. We'll flush these either in
2012 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
2013 if (syncQueue === null) {
2014 syncQueue = [callback];
2015 // Flush the queue in the next tick, at the earliest.
2016 immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl);
2017 } else {
2018 // Push onto existing queue. Don't need to schedule a callback because
2019 // we already scheduled one when we created the queue.
2020 syncQueue.push(callback);
2021 }
2022 return fakeCallbackNode;
2023}
2024
2025function cancelCallback(callbackNode) {
2026 if (callbackNode !== fakeCallbackNode) {
2027 Scheduler_cancelCallback(callbackNode);
2028 }
2029}
2030
2031function flushSyncCallbackQueue() {
2032 if (immediateQueueCallbackNode !== null) {
2033 Scheduler_cancelCallback(immediateQueueCallbackNode);
2034 }
2035 flushSyncCallbackQueueImpl();
2036}
2037
2038function flushSyncCallbackQueueImpl() {
2039 if (!isFlushingSyncQueue && syncQueue !== null) {
2040 // Prevent re-entrancy.
2041 isFlushingSyncQueue = true;
2042 var i = 0;
2043 try {
2044 var _isSync = true;
2045 var queue = syncQueue;
2046 runWithPriority(ImmediatePriority, function () {
2047 for (; i < queue.length; i++) {
2048 var callback = queue[i];
2049 do {
2050 callback = callback(_isSync);
2051 } while (callback !== null);
2052 }
2053 });
2054 syncQueue = null;
2055 } catch (error) {
2056 // If something throws, leave the remaining callbacks on the queue.
2057 if (syncQueue !== null) {
2058 syncQueue = syncQueue.slice(i + 1);
2059 }
2060 // Resume flushing in the next tick
2061 Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue);
2062 throw error;
2063 } finally {
2064 isFlushingSyncQueue = false;
2065 }
2066 }
2067}
2068
2069var NoMode = 0;
2070var StrictMode = 1;
2071// TODO: Remove BatchedMode and ConcurrentMode by reading from the root
2072// tag instead
2073var BatchedMode = 2;
2074var ConcurrentMode = 4;
2075var ProfileMode = 8;
2076
2077// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
2078// Math.pow(2, 30) - 1
2079// 0b111111111111111111111111111111
2080var MAX_SIGNED_31_BIT_INT = 1073741823;
2081
2082var NoWork = 0;
2083var Never = 1;
2084var Sync = MAX_SIGNED_31_BIT_INT;
2085var Batched = Sync - 1;
2086
2087var UNIT_SIZE = 10;
2088var MAGIC_NUMBER_OFFSET = Batched - 1;
2089
2090// 1 unit of expiration time represents 10ms.
2091function msToExpirationTime(ms) {
2092 // Always add an offset so that we don't clash with the magic number for NoWork.
2093 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
2094}
2095
2096function expirationTimeToMs(expirationTime) {
2097 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
2098}
2099
2100function ceiling(num, precision) {
2101 return ((num / precision | 0) + 1) * precision;
2102}
2103
2104function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
2105 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
2106}
2107
2108// TODO: This corresponds to Scheduler's NormalPriority, not LowPriority. Update
2109// the names to reflect.
2110var LOW_PRIORITY_EXPIRATION = 5000;
2111var LOW_PRIORITY_BATCH_SIZE = 250;
2112
2113function computeAsyncExpiration(currentTime) {
2114 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
2115}
2116
2117function computeSuspenseExpiration(currentTime, timeoutMs) {
2118 // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time?
2119 return computeExpirationBucket(currentTime, timeoutMs, LOW_PRIORITY_BATCH_SIZE);
2120}
2121
2122// We intentionally set a higher expiration time for interactive updates in
2123// dev than in production.
2124//
2125// If the main thread is being blocked so long that you hit the expiration,
2126// it's a problem that could be solved with better scheduling.
2127//
2128// People will be more likely to notice this and fix it with the long
2129// expiration time in development.
2130//
2131// In production we opt for better UX at the risk of masking scheduling
2132// problems, by expiring fast.
2133var HIGH_PRIORITY_EXPIRATION = 500;
2134var HIGH_PRIORITY_BATCH_SIZE = 100;
2135
2136function computeInteractiveExpiration(currentTime) {
2137 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
2138}
2139
2140function inferPriorityFromExpirationTime(currentTime, expirationTime) {
2141 if (expirationTime === Sync) {
2142 return ImmediatePriority;
2143 }
2144 if (expirationTime === Never) {
2145 return IdlePriority;
2146 }
2147 var msUntil = expirationTimeToMs(expirationTime) - expirationTimeToMs(currentTime);
2148 if (msUntil <= 0) {
2149 return ImmediatePriority;
2150 }
2151 if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) {
2152 return UserBlockingPriority;
2153 }
2154 if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) {
2155 return NormalPriority;
2156 }
2157
2158 // TODO: Handle LowPriority
2159
2160 // Assume anything lower has idle priority
2161 return IdlePriority;
2162}
2163
2164/**
2165 * inlined Object.is polyfill to avoid requiring consumers ship their own
2166 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
2167 */
2168function is(x, y) {
2169 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
2170 ;
2171}
2172
2173var hasOwnProperty = Object.prototype.hasOwnProperty;
2174
2175/**
2176 * Performs equality by iterating through keys on an object and returning false
2177 * when any key has values which are not strictly equal between the arguments.
2178 * Returns true when the values of all keys are strictly equal.
2179 */
2180function shallowEqual(objA, objB) {
2181 if (is(objA, objB)) {
2182 return true;
2183 }
2184
2185 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
2186 return false;
2187 }
2188
2189 var keysA = Object.keys(objA);
2190 var keysB = Object.keys(objB);
2191
2192 if (keysA.length !== keysB.length) {
2193 return false;
2194 }
2195
2196 // Test for A's keys different from B.
2197 for (var i = 0; i < keysA.length; i++) {
2198 if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
2199 return false;
2200 }
2201 }
2202
2203 return true;
2204}
2205
2206/**
2207 * Forked from fbjs/warning:
2208 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
2209 *
2210 * Only change is we use console.warn instead of console.error,
2211 * and do nothing when 'console' is not supported.
2212 * This really simplifies the code.
2213 * ---
2214 * Similar to invariant but only logs a warning if the condition is not met.
2215 * This can be used to log issues in development environments in critical
2216 * paths. Removing the logging code for production environments will keep the
2217 * same logic and follow the same code paths.
2218 */
2219
2220var lowPriorityWarning = function () {};
2221
2222{
2223 var printWarning$1 = function (format) {
2224 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
2225 args[_key - 1] = arguments[_key];
2226 }
2227
2228 var argIndex = 0;
2229 var message = 'Warning: ' + format.replace(/%s/g, function () {
2230 return args[argIndex++];
2231 });
2232 if (typeof console !== 'undefined') {
2233 console.warn(message);
2234 }
2235 try {
2236 // --- Welcome to debugging React ---
2237 // This error was thrown as a convenience so that you can use this stack
2238 // to find the callsite that caused this warning to fire.
2239 throw new Error(message);
2240 } catch (x) {}
2241 };
2242
2243 lowPriorityWarning = function (condition, format) {
2244 if (format === undefined) {
2245 throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument');
2246 }
2247 if (!condition) {
2248 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
2249 args[_key2 - 2] = arguments[_key2];
2250 }
2251
2252 printWarning$1.apply(undefined, [format].concat(args));
2253 }
2254 };
2255}
2256
2257var lowPriorityWarning$1 = lowPriorityWarning;
2258
2259var ReactStrictModeWarnings = {
2260 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
2261 flushPendingUnsafeLifecycleWarnings: function () {},
2262 recordLegacyContextWarning: function (fiber, instance) {},
2263 flushLegacyContextWarning: function () {},
2264 discardPendingWarnings: function () {}
2265};
2266
2267{
2268 var findStrictRoot = function (fiber) {
2269 var maybeStrictRoot = null;
2270
2271 var node = fiber;
2272 while (node !== null) {
2273 if (node.mode & StrictMode) {
2274 maybeStrictRoot = node;
2275 }
2276 node = node.return;
2277 }
2278
2279 return maybeStrictRoot;
2280 };
2281
2282 var setToSortedString = function (set) {
2283 var array = [];
2284 set.forEach(function (value) {
2285 array.push(value);
2286 });
2287 return array.sort().join(', ');
2288 };
2289
2290 var pendingComponentWillMountWarnings = [];
2291 var pendingUNSAFE_ComponentWillMountWarnings = [];
2292 var pendingComponentWillReceivePropsWarnings = [];
2293 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2294 var pendingComponentWillUpdateWarnings = [];
2295 var pendingUNSAFE_ComponentWillUpdateWarnings = [];
2296
2297 // Tracks components we have already warned about.
2298 var didWarnAboutUnsafeLifecycles = new Set();
2299
2300 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
2301 // Dedup strategy: Warn once per component.
2302 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
2303 return;
2304 }
2305
2306 if (typeof instance.componentWillMount === 'function' &&
2307 // Don't warn about react-lifecycles-compat polyfilled components.
2308 instance.componentWillMount.__suppressDeprecationWarning !== true) {
2309 pendingComponentWillMountWarnings.push(fiber);
2310 }
2311
2312 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') {
2313 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
2314 }
2315
2316 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
2317 pendingComponentWillReceivePropsWarnings.push(fiber);
2318 }
2319
2320 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
2321 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
2322 }
2323
2324 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
2325 pendingComponentWillUpdateWarnings.push(fiber);
2326 }
2327
2328 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
2329 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
2330 }
2331 };
2332
2333 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
2334 // We do an initial pass to gather component names
2335 var componentWillMountUniqueNames = new Set();
2336 if (pendingComponentWillMountWarnings.length > 0) {
2337 pendingComponentWillMountWarnings.forEach(function (fiber) {
2338 componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2339 didWarnAboutUnsafeLifecycles.add(fiber.type);
2340 });
2341 pendingComponentWillMountWarnings = [];
2342 }
2343
2344 var UNSAFE_componentWillMountUniqueNames = new Set();
2345 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
2346 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
2347 UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2348 didWarnAboutUnsafeLifecycles.add(fiber.type);
2349 });
2350 pendingUNSAFE_ComponentWillMountWarnings = [];
2351 }
2352
2353 var componentWillReceivePropsUniqueNames = new Set();
2354 if (pendingComponentWillReceivePropsWarnings.length > 0) {
2355 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
2356 componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2357 didWarnAboutUnsafeLifecycles.add(fiber.type);
2358 });
2359
2360 pendingComponentWillReceivePropsWarnings = [];
2361 }
2362
2363 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
2364 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
2365 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
2366 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2367 didWarnAboutUnsafeLifecycles.add(fiber.type);
2368 });
2369
2370 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2371 }
2372
2373 var componentWillUpdateUniqueNames = new Set();
2374 if (pendingComponentWillUpdateWarnings.length > 0) {
2375 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
2376 componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
2377 didWarnAboutUnsafeLifecycles.add(fiber.type);
2378 });
2379
2380 pendingComponentWillUpdateWarnings = [];
2381 }
2382
2383 var UNSAFE_componentWillUpdateUniqueNames = new Set();
2384 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
2385 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
2386 UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
2387 didWarnAboutUnsafeLifecycles.add(fiber.type);
2388 });
2389
2390 pendingUNSAFE_ComponentWillUpdateWarnings = [];
2391 }
2392
2393 // Finally, we flush all the warnings
2394 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
2395 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
2396 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
2397 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);
2398 }
2399
2400 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
2401 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
2402 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);
2403 }
2404
2405 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
2406 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
2407 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);
2408 }
2409
2410 if (componentWillMountUniqueNames.size > 0) {
2411 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
2412
2413 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);
2414 }
2415
2416 if (componentWillReceivePropsUniqueNames.size > 0) {
2417 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
2418
2419 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);
2420 }
2421
2422 if (componentWillUpdateUniqueNames.size > 0) {
2423 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
2424
2425 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);
2426 }
2427 };
2428
2429 var pendingLegacyContextWarning = new Map();
2430
2431 // Tracks components we have already warned about.
2432 var didWarnAboutLegacyContext = new Set();
2433
2434 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
2435 var strictRoot = findStrictRoot(fiber);
2436 if (strictRoot === null) {
2437 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.');
2438 return;
2439 }
2440
2441 // Dedup strategy: Warn once per component.
2442 if (didWarnAboutLegacyContext.has(fiber.type)) {
2443 return;
2444 }
2445
2446 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
2447
2448 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
2449 if (warningsForRoot === undefined) {
2450 warningsForRoot = [];
2451 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
2452 }
2453 warningsForRoot.push(fiber);
2454 }
2455 };
2456
2457 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
2458 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
2459 var uniqueNames = new Set();
2460 fiberArray.forEach(function (fiber) {
2461 uniqueNames.add(getComponentName(fiber.type) || 'Component');
2462 didWarnAboutLegacyContext.add(fiber.type);
2463 });
2464
2465 var sortedNames = setToSortedString(uniqueNames);
2466 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
2467
2468 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);
2469 });
2470 };
2471
2472 ReactStrictModeWarnings.discardPendingWarnings = function () {
2473 pendingComponentWillMountWarnings = [];
2474 pendingUNSAFE_ComponentWillMountWarnings = [];
2475 pendingComponentWillReceivePropsWarnings = [];
2476 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2477 pendingComponentWillUpdateWarnings = [];
2478 pendingUNSAFE_ComponentWillUpdateWarnings = [];
2479 pendingLegacyContextWarning = new Map();
2480 };
2481}
2482
2483// Resolves type to a family.
2484
2485
2486// Used by React Refresh runtime through DevTools Global Hook.
2487
2488
2489var resolveFamily = null;
2490// $FlowFixMe Flow gets confused by a WeakSet feature check below.
2491var failedBoundaries = null;
2492
2493var setRefreshHandler = function (handler) {
2494 {
2495 resolveFamily = handler;
2496 }
2497};
2498
2499function resolveFunctionForHotReloading(type) {
2500 {
2501 if (resolveFamily === null) {
2502 // Hot reloading is disabled.
2503 return type;
2504 }
2505 var family = resolveFamily(type);
2506 if (family === undefined) {
2507 return type;
2508 }
2509 // Use the latest known implementation.
2510 return family.current;
2511 }
2512}
2513
2514function resolveClassForHotReloading(type) {
2515 // No implementation differences.
2516 return resolveFunctionForHotReloading(type);
2517}
2518
2519function resolveForwardRefForHotReloading(type) {
2520 {
2521 if (resolveFamily === null) {
2522 // Hot reloading is disabled.
2523 return type;
2524 }
2525 var family = resolveFamily(type);
2526 if (family === undefined) {
2527 // Check if we're dealing with a real forwardRef. Don't want to crash early.
2528 if (type !== null && type !== undefined && typeof type.render === 'function') {
2529 // ForwardRef is special because its resolved .type is an object,
2530 // but it's possible that we only have its inner render function in the map.
2531 // If that inner render function is different, we'll build a new forwardRef type.
2532 var currentRender = resolveFunctionForHotReloading(type.render);
2533 if (type.render !== currentRender) {
2534 var syntheticType = {
2535 $$typeof: REACT_FORWARD_REF_TYPE,
2536 render: currentRender
2537 };
2538 if (type.displayName !== undefined) {
2539 syntheticType.displayName = type.displayName;
2540 }
2541 return syntheticType;
2542 }
2543 }
2544 return type;
2545 }
2546 // Use the latest known implementation.
2547 return family.current;
2548 }
2549}
2550
2551function isCompatibleFamilyForHotReloading(fiber, element) {
2552 {
2553 if (resolveFamily === null) {
2554 // Hot reloading is disabled.
2555 return false;
2556 }
2557
2558 var prevType = fiber.elementType;
2559 var nextType = element.type;
2560
2561 // If we got here, we know types aren't === equal.
2562 var needsCompareFamilies = false;
2563
2564 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
2565
2566 switch (fiber.tag) {
2567 case ClassComponent:
2568 {
2569 if (typeof nextType === 'function') {
2570 needsCompareFamilies = true;
2571 }
2572 break;
2573 }
2574 case FunctionComponent:
2575 {
2576 if (typeof nextType === 'function') {
2577 needsCompareFamilies = true;
2578 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2579 // We don't know the inner type yet.
2580 // We're going to assume that the lazy inner type is stable,
2581 // and so it is sufficient to avoid reconciling it away.
2582 // We're not going to unwrap or actually use the new lazy type.
2583 needsCompareFamilies = true;
2584 }
2585 break;
2586 }
2587 case ForwardRef:
2588 {
2589 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
2590 needsCompareFamilies = true;
2591 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2592 needsCompareFamilies = true;
2593 }
2594 break;
2595 }
2596 case MemoComponent:
2597 case SimpleMemoComponent:
2598 {
2599 if ($$typeofNextType === REACT_MEMO_TYPE) {
2600 // TODO: if it was but can no longer be simple,
2601 // we shouldn't set this.
2602 needsCompareFamilies = true;
2603 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2604 needsCompareFamilies = true;
2605 }
2606 break;
2607 }
2608 default:
2609 return false;
2610 }
2611
2612 // Check if both types have a family and it's the same one.
2613 if (needsCompareFamilies) {
2614 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
2615 // This means both of them need to be registered to preserve state.
2616 // If we unwrapped and compared the inner types for wrappers instead,
2617 // then we would risk falsely saying two separate memo(Foo)
2618 // calls are equivalent because they wrap the same Foo function.
2619 var prevFamily = resolveFamily(prevType);
2620 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
2621 return true;
2622 }
2623 }
2624 return false;
2625 }
2626}
2627
2628function markFailedErrorBoundaryForHotReloading(fiber) {
2629 {
2630 if (resolveFamily === null) {
2631 // Hot reloading is disabled.
2632 return;
2633 }
2634 if (typeof WeakSet !== 'function') {
2635 return;
2636 }
2637 if (failedBoundaries === null) {
2638 failedBoundaries = new WeakSet();
2639 }
2640 failedBoundaries.add(fiber);
2641 }
2642}
2643
2644var scheduleRefresh = function (root, update) {
2645 {
2646 if (resolveFamily === null) {
2647 // Hot reloading is disabled.
2648 return;
2649 }
2650 var _staleFamilies = update.staleFamilies,
2651 _updatedFamilies = update.updatedFamilies;
2652
2653 flushPassiveEffects();
2654 flushSync(function () {
2655 scheduleFibersWithFamiliesRecursively(root.current, _updatedFamilies, _staleFamilies);
2656 });
2657 }
2658};
2659
2660var scheduleRoot = function (root, element) {
2661 {
2662 if (root.context !== emptyContextObject) {
2663 // Super edge case: root has a legacy _renderSubtree context
2664 // but we don't know the parentComponent so we can't pass it.
2665 // Just ignore. We'll delete this with _renderSubtree code path later.
2666 return;
2667 }
2668 flushPassiveEffects();
2669 updateContainerAtExpirationTime(element, root, null, Sync, null);
2670 }
2671};
2672
2673function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
2674 {
2675 var alternate = fiber.alternate,
2676 child = fiber.child,
2677 sibling = fiber.sibling,
2678 tag = fiber.tag,
2679 type = fiber.type;
2680
2681
2682 var candidateType = null;
2683 switch (tag) {
2684 case FunctionComponent:
2685 case SimpleMemoComponent:
2686 case ClassComponent:
2687 candidateType = type;
2688 break;
2689 case ForwardRef:
2690 candidateType = type.render;
2691 break;
2692 default:
2693 break;
2694 }
2695
2696 if (resolveFamily === null) {
2697 throw new Error('Expected resolveFamily to be set during hot reload.');
2698 }
2699
2700 var needsRender = false;
2701 var needsRemount = false;
2702 if (candidateType !== null) {
2703 var family = resolveFamily(candidateType);
2704 if (family !== undefined) {
2705 if (staleFamilies.has(family)) {
2706 needsRemount = true;
2707 } else if (updatedFamilies.has(family)) {
2708 needsRender = true;
2709 }
2710 }
2711 }
2712 if (failedBoundaries !== null) {
2713 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
2714 needsRemount = true;
2715 }
2716 }
2717
2718 if (needsRemount) {
2719 fiber._debugNeedsRemount = true;
2720 }
2721 if (needsRemount || needsRender) {
2722 scheduleWork(fiber, Sync);
2723 }
2724 if (child !== null && !needsRemount) {
2725 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
2726 }
2727 if (sibling !== null) {
2728 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
2729 }
2730 }
2731}
2732
2733var findHostInstancesForRefresh = function (root, families) {
2734 {
2735 var hostInstances = new Set();
2736 var types = new Set(families.map(function (family) {
2737 return family.current;
2738 }));
2739 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
2740 return hostInstances;
2741 }
2742};
2743
2744function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
2745 {
2746 var child = fiber.child,
2747 sibling = fiber.sibling,
2748 tag = fiber.tag,
2749 type = fiber.type;
2750
2751
2752 var candidateType = null;
2753 switch (tag) {
2754 case FunctionComponent:
2755 case SimpleMemoComponent:
2756 case ClassComponent:
2757 candidateType = type;
2758 break;
2759 case ForwardRef:
2760 candidateType = type.render;
2761 break;
2762 default:
2763 break;
2764 }
2765
2766 var didMatch = false;
2767 if (candidateType !== null) {
2768 if (types.has(candidateType)) {
2769 didMatch = true;
2770 }
2771 }
2772
2773 if (didMatch) {
2774 // We have a match. This only drills down to the closest host components.
2775 // There's no need to search deeper because for the purpose of giving
2776 // visual feedback, "flashing" outermost parent rectangles is sufficient.
2777 findHostInstancesForFiberShallowly(fiber, hostInstances);
2778 } else {
2779 // If there's no match, maybe there will be one further down in the child tree.
2780 if (child !== null) {
2781 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
2782 }
2783 }
2784
2785 if (sibling !== null) {
2786 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
2787 }
2788 }
2789}
2790
2791function findHostInstancesForFiberShallowly(fiber, hostInstances) {
2792 {
2793 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
2794 if (foundHostInstances) {
2795 return;
2796 }
2797 // If we didn't find any host children, fallback to closest host parent.
2798 var node = fiber;
2799 while (true) {
2800 switch (node.tag) {
2801 case HostComponent:
2802 hostInstances.add(node.stateNode);
2803 return;
2804 case HostPortal:
2805 hostInstances.add(node.stateNode.containerInfo);
2806 return;
2807 case HostRoot:
2808 hostInstances.add(node.stateNode.containerInfo);
2809 return;
2810 }
2811 if (node.return === null) {
2812 throw new Error('Expected to reach root first.');
2813 }
2814 node = node.return;
2815 }
2816 }
2817}
2818
2819function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
2820 {
2821 var node = fiber;
2822 var foundHostInstances = false;
2823 while (true) {
2824 if (node.tag === HostComponent) {
2825 // We got a match.
2826 foundHostInstances = true;
2827 hostInstances.add(node.stateNode);
2828 // There may still be more, so keep searching.
2829 } else if (node.child !== null) {
2830 node.child.return = node;
2831 node = node.child;
2832 continue;
2833 }
2834 if (node === fiber) {
2835 return foundHostInstances;
2836 }
2837 while (node.sibling === null) {
2838 if (node.return === null || node.return === fiber) {
2839 return foundHostInstances;
2840 }
2841 node = node.return;
2842 }
2843 node.sibling.return = node.return;
2844 node = node.sibling;
2845 }
2846 }
2847 return false;
2848}
2849
2850function resolveDefaultProps(Component, baseProps) {
2851 if (Component && Component.defaultProps) {
2852 // Resolve default props. Taken from ReactElement
2853 var props = _assign({}, baseProps);
2854 var defaultProps = Component.defaultProps;
2855 for (var propName in defaultProps) {
2856 if (props[propName] === undefined) {
2857 props[propName] = defaultProps[propName];
2858 }
2859 }
2860 return props;
2861 }
2862 return baseProps;
2863}
2864
2865function readLazyComponentType(lazyComponent) {
2866 var status = lazyComponent._status;
2867 var result = lazyComponent._result;
2868 switch (status) {
2869 case Resolved:
2870 {
2871 var Component = result;
2872 return Component;
2873 }
2874 case Rejected:
2875 {
2876 var error = result;
2877 throw error;
2878 }
2879 case Pending:
2880 {
2881 var thenable = result;
2882 throw thenable;
2883 }
2884 default:
2885 {
2886 lazyComponent._status = Pending;
2887 var ctor = lazyComponent._ctor;
2888 var _thenable = ctor();
2889 _thenable.then(function (moduleObject) {
2890 if (lazyComponent._status === Pending) {
2891 var defaultExport = moduleObject.default;
2892 {
2893 if (defaultExport === undefined) {
2894 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);
2895 }
2896 }
2897 lazyComponent._status = Resolved;
2898 lazyComponent._result = defaultExport;
2899 }
2900 }, function (error) {
2901 if (lazyComponent._status === Pending) {
2902 lazyComponent._status = Rejected;
2903 lazyComponent._result = error;
2904 }
2905 });
2906 // Handle synchronous thenables.
2907 switch (lazyComponent._status) {
2908 case Resolved:
2909 return lazyComponent._result;
2910 case Rejected:
2911 throw lazyComponent._result;
2912 }
2913 lazyComponent._result = _thenable;
2914 throw _thenable;
2915 }
2916 }
2917}
2918
2919var valueCursor = createCursor(null);
2920
2921var rendererSigil = void 0;
2922{
2923 // Use this to detect multiple renderers using the same context
2924 rendererSigil = {};
2925}
2926
2927var currentlyRenderingFiber = null;
2928var lastContextDependency = null;
2929var lastContextWithAllBitsObserved = null;
2930
2931var isDisallowedContextReadInDEV = false;
2932
2933function resetContextDependencies() {
2934 // This is called right before React yields execution, to ensure `readContext`
2935 // cannot be called outside the render phase.
2936 currentlyRenderingFiber = null;
2937 lastContextDependency = null;
2938 lastContextWithAllBitsObserved = null;
2939 {
2940 isDisallowedContextReadInDEV = false;
2941 }
2942}
2943
2944function enterDisallowedContextReadInDEV() {
2945 {
2946 isDisallowedContextReadInDEV = true;
2947 }
2948}
2949
2950function exitDisallowedContextReadInDEV() {
2951 {
2952 isDisallowedContextReadInDEV = false;
2953 }
2954}
2955
2956function pushProvider(providerFiber, nextValue) {
2957 var context = providerFiber.type._context;
2958
2959 if (isPrimaryRenderer) {
2960 push(valueCursor, context._currentValue, providerFiber);
2961
2962 context._currentValue = nextValue;
2963 {
2964 !(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;
2965 context._currentRenderer = rendererSigil;
2966 }
2967 } else {
2968 push(valueCursor, context._currentValue2, providerFiber);
2969
2970 context._currentValue2 = nextValue;
2971 {
2972 !(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;
2973 context._currentRenderer2 = rendererSigil;
2974 }
2975 }
2976}
2977
2978function popProvider(providerFiber) {
2979 var currentValue = valueCursor.current;
2980
2981 pop(valueCursor, providerFiber);
2982
2983 var context = providerFiber.type._context;
2984 if (isPrimaryRenderer) {
2985 context._currentValue = currentValue;
2986 } else {
2987 context._currentValue2 = currentValue;
2988 }
2989}
2990
2991function calculateChangedBits(context, newValue, oldValue) {
2992 if (is(oldValue, newValue)) {
2993 // No change
2994 return 0;
2995 } else {
2996 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
2997
2998 {
2999 !((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;
3000 }
3001 return changedBits | 0;
3002 }
3003}
3004
3005function scheduleWorkOnParentPath(parent, renderExpirationTime) {
3006 // Update the child expiration time of all the ancestors, including
3007 // the alternates.
3008 var node = parent;
3009 while (node !== null) {
3010 var alternate = node.alternate;
3011 if (node.childExpirationTime < renderExpirationTime) {
3012 node.childExpirationTime = renderExpirationTime;
3013 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
3014 alternate.childExpirationTime = renderExpirationTime;
3015 }
3016 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
3017 alternate.childExpirationTime = renderExpirationTime;
3018 } else {
3019 // Neither alternate was updated, which means the rest of the
3020 // ancestor path already has sufficient priority.
3021 break;
3022 }
3023 node = node.return;
3024 }
3025}
3026
3027function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
3028 var fiber = workInProgress.child;
3029 if (fiber !== null) {
3030 // Set the return pointer of the child to the work-in-progress fiber.
3031 fiber.return = workInProgress;
3032 }
3033 while (fiber !== null) {
3034 var nextFiber = void 0;
3035
3036 // Visit this fiber.
3037 var list = fiber.dependencies;
3038 if (list !== null) {
3039 nextFiber = fiber.child;
3040
3041 var dependency = list.firstContext;
3042 while (dependency !== null) {
3043 // Check if the context matches.
3044 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
3045 // Match! Schedule an update on this fiber.
3046
3047 if (fiber.tag === ClassComponent) {
3048 // Schedule a force update on the work-in-progress.
3049 var update = createUpdate(renderExpirationTime, null);
3050 update.tag = ForceUpdate;
3051 // TODO: Because we don't have a work-in-progress, this will add the
3052 // update to the current fiber, too, which means it will persist even if
3053 // this render is thrown away. Since it's a race condition, not sure it's
3054 // worth fixing.
3055 enqueueUpdate(fiber, update);
3056 }
3057
3058 if (fiber.expirationTime < renderExpirationTime) {
3059 fiber.expirationTime = renderExpirationTime;
3060 }
3061 var alternate = fiber.alternate;
3062 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
3063 alternate.expirationTime = renderExpirationTime;
3064 }
3065
3066 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
3067
3068 // Mark the expiration time on the list, too.
3069 if (list.expirationTime < renderExpirationTime) {
3070 list.expirationTime = renderExpirationTime;
3071 }
3072
3073 // Since we already found a match, we can stop traversing the
3074 // dependency list.
3075 break;
3076 }
3077 dependency = dependency.next;
3078 }
3079 } else if (fiber.tag === ContextProvider) {
3080 // Don't scan deeper if this is a matching provider
3081 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
3082 } else if (enableSuspenseServerRenderer && fiber.tag === DehydratedSuspenseComponent) {
3083 // If a dehydrated suspense component is in this subtree, we don't know
3084 // if it will have any context consumers in it. The best we can do is
3085 // mark it as having updates on its children.
3086 if (fiber.expirationTime < renderExpirationTime) {
3087 fiber.expirationTime = renderExpirationTime;
3088 }
3089 var _alternate = fiber.alternate;
3090 if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) {
3091 _alternate.expirationTime = renderExpirationTime;
3092 }
3093 // This is intentionally passing this fiber as the parent
3094 // because we want to schedule this fiber as having work
3095 // on its children. We'll use the childExpirationTime on
3096 // this fiber to indicate that a context has changed.
3097 scheduleWorkOnParentPath(fiber, renderExpirationTime);
3098 nextFiber = fiber.sibling;
3099 } else {
3100 // Traverse down.
3101 nextFiber = fiber.child;
3102 }
3103
3104 if (nextFiber !== null) {
3105 // Set the return pointer of the child to the work-in-progress fiber.
3106 nextFiber.return = fiber;
3107 } else {
3108 // No child. Traverse to next sibling.
3109 nextFiber = fiber;
3110 while (nextFiber !== null) {
3111 if (nextFiber === workInProgress) {
3112 // We're back to the root of this subtree. Exit.
3113 nextFiber = null;
3114 break;
3115 }
3116 var sibling = nextFiber.sibling;
3117 if (sibling !== null) {
3118 // Set the return pointer of the sibling to the work-in-progress fiber.
3119 sibling.return = nextFiber.return;
3120 nextFiber = sibling;
3121 break;
3122 }
3123 // No more siblings. Traverse up.
3124 nextFiber = nextFiber.return;
3125 }
3126 }
3127 fiber = nextFiber;
3128 }
3129}
3130
3131function prepareToReadContext(workInProgress, renderExpirationTime) {
3132 currentlyRenderingFiber = workInProgress;
3133 lastContextDependency = null;
3134 lastContextWithAllBitsObserved = null;
3135
3136 var dependencies = workInProgress.dependencies;
3137 if (dependencies !== null) {
3138 var firstContext = dependencies.firstContext;
3139 if (firstContext !== null) {
3140 if (dependencies.expirationTime >= renderExpirationTime) {
3141 // Context list has a pending update. Mark that this fiber performed work.
3142 markWorkInProgressReceivedUpdate();
3143 }
3144 // Reset the work-in-progress list
3145 dependencies.firstContext = null;
3146 }
3147 }
3148}
3149
3150function readContext(context, observedBits) {
3151 {
3152 // This warning would fire if you read context inside a Hook like useMemo.
3153 // Unlike the class check below, it's not enforced in production for perf.
3154 !!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;
3155 }
3156
3157 if (lastContextWithAllBitsObserved === context) {
3158 // Nothing to do. We already observe everything in this context.
3159 } else if (observedBits === false || observedBits === 0) {
3160 // Do not observe any updates.
3161 } else {
3162 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types.
3163 if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) {
3164 // Observe all updates.
3165 lastContextWithAllBitsObserved = context;
3166 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
3167 } else {
3168 resolvedObservedBits = observedBits;
3169 }
3170
3171 var contextItem = {
3172 context: context,
3173 observedBits: resolvedObservedBits,
3174 next: null
3175 };
3176
3177 if (lastContextDependency === null) {
3178 (function () {
3179 if (!(currentlyRenderingFiber !== null)) {
3180 {
3181 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().'));
3182 }
3183 }
3184 })();
3185
3186 // This is the first dependency for this component. Create a new list.
3187 lastContextDependency = contextItem;
3188 currentlyRenderingFiber.dependencies = {
3189 expirationTime: NoWork,
3190 firstContext: contextItem,
3191 responders: null
3192 };
3193 } else {
3194 // Append a new context item.
3195 lastContextDependency = lastContextDependency.next = contextItem;
3196 }
3197 }
3198 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
3199}
3200
3201// UpdateQueue is a linked list of prioritized updates.
3202//
3203// Like fibers, update queues come in pairs: a current queue, which represents
3204// the visible state of the screen, and a work-in-progress queue, which can be
3205// mutated and processed asynchronously before it is committed — a form of
3206// double buffering. If a work-in-progress render is discarded before finishing,
3207// we create a new work-in-progress by cloning the current queue.
3208//
3209// Both queues share a persistent, singly-linked list structure. To schedule an
3210// update, we append it to the end of both queues. Each queue maintains a
3211// pointer to first update in the persistent list that hasn't been processed.
3212// The work-in-progress pointer always has a position equal to or greater than
3213// the current queue, since we always work on that one. The current queue's
3214// pointer is only updated during the commit phase, when we swap in the
3215// work-in-progress.
3216//
3217// For example:
3218//
3219// Current pointer: A - B - C - D - E - F
3220// Work-in-progress pointer: D - E - F
3221// ^
3222// The work-in-progress queue has
3223// processed more updates than current.
3224//
3225// The reason we append to both queues is because otherwise we might drop
3226// updates without ever processing them. For example, if we only add updates to
3227// the work-in-progress queue, some updates could be lost whenever a work-in
3228// -progress render restarts by cloning from current. Similarly, if we only add
3229// updates to the current queue, the updates will be lost whenever an already
3230// in-progress queue commits and swaps with the current queue. However, by
3231// adding to both queues, we guarantee that the update will be part of the next
3232// work-in-progress. (And because the work-in-progress queue becomes the
3233// current queue once it commits, there's no danger of applying the same
3234// update twice.)
3235//
3236// Prioritization
3237// --------------
3238//
3239// Updates are not sorted by priority, but by insertion; new updates are always
3240// appended to the end of the list.
3241//
3242// The priority is still important, though. When processing the update queue
3243// during the render phase, only the updates with sufficient priority are
3244// included in the result. If we skip an update because it has insufficient
3245// priority, it remains in the queue to be processed later, during a lower
3246// priority render. Crucially, all updates subsequent to a skipped update also
3247// remain in the queue *regardless of their priority*. That means high priority
3248// updates are sometimes processed twice, at two separate priorities. We also
3249// keep track of a base state, that represents the state before the first
3250// update in the queue is applied.
3251//
3252// For example:
3253//
3254// Given a base state of '', and the following queue of updates
3255//
3256// A1 - B2 - C1 - D2
3257//
3258// where the number indicates the priority, and the update is applied to the
3259// previous state by appending a letter, React will process these updates as
3260// two separate renders, one per distinct priority level:
3261//
3262// First render, at priority 1:
3263// Base state: ''
3264// Updates: [A1, C1]
3265// Result state: 'AC'
3266//
3267// Second render, at priority 2:
3268// Base state: 'A' <- The base state does not include C1,
3269// because B2 was skipped.
3270// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
3271// Result state: 'ABCD'
3272//
3273// Because we process updates in insertion order, and rebase high priority
3274// updates when preceding updates are skipped, the final result is deterministic
3275// regardless of priority. Intermediate state may vary according to system
3276// resources, but the final state is always the same.
3277
3278var UpdateState = 0;
3279var ReplaceState = 1;
3280var ForceUpdate = 2;
3281var CaptureUpdate = 3;
3282
3283// Global state that is reset at the beginning of calling `processUpdateQueue`.
3284// It should only be read right after calling `processUpdateQueue`, via
3285// `checkHasForceUpdateAfterProcessing`.
3286var hasForceUpdate = false;
3287
3288var didWarnUpdateInsideUpdate = void 0;
3289var currentlyProcessingQueue = void 0;
3290
3291{
3292 didWarnUpdateInsideUpdate = false;
3293 currentlyProcessingQueue = null;
3294
3295}
3296
3297function createUpdateQueue(baseState) {
3298 var queue = {
3299 baseState: baseState,
3300 firstUpdate: null,
3301 lastUpdate: null,
3302 firstCapturedUpdate: null,
3303 lastCapturedUpdate: null,
3304 firstEffect: null,
3305 lastEffect: null,
3306 firstCapturedEffect: null,
3307 lastCapturedEffect: null
3308 };
3309 return queue;
3310}
3311
3312function cloneUpdateQueue(currentQueue) {
3313 var queue = {
3314 baseState: currentQueue.baseState,
3315 firstUpdate: currentQueue.firstUpdate,
3316 lastUpdate: currentQueue.lastUpdate,
3317
3318 // TODO: With resuming, if we bail out and resuse the child tree, we should
3319 // keep these effects.
3320 firstCapturedUpdate: null,
3321 lastCapturedUpdate: null,
3322
3323 firstEffect: null,
3324 lastEffect: null,
3325
3326 firstCapturedEffect: null,
3327 lastCapturedEffect: null
3328 };
3329 return queue;
3330}
3331
3332function createUpdate(expirationTime, suspenseConfig) {
3333 var update = {
3334 expirationTime: expirationTime,
3335 suspenseConfig: suspenseConfig,
3336
3337 tag: UpdateState,
3338 payload: null,
3339 callback: null,
3340
3341 next: null,
3342 nextEffect: null
3343 };
3344 {
3345 update.priority = getCurrentPriorityLevel();
3346 }
3347 return update;
3348}
3349
3350function appendUpdateToQueue(queue, update) {
3351 // Append the update to the end of the list.
3352 if (queue.lastUpdate === null) {
3353 // Queue is empty
3354 queue.firstUpdate = queue.lastUpdate = update;
3355 } else {
3356 queue.lastUpdate.next = update;
3357 queue.lastUpdate = update;
3358 }
3359}
3360
3361function enqueueUpdate(fiber, update) {
3362 // Update queues are created lazily.
3363 var alternate = fiber.alternate;
3364 var queue1 = void 0;
3365 var queue2 = void 0;
3366 if (alternate === null) {
3367 // There's only one fiber.
3368 queue1 = fiber.updateQueue;
3369 queue2 = null;
3370 if (queue1 === null) {
3371 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
3372 }
3373 } else {
3374 // There are two owners.
3375 queue1 = fiber.updateQueue;
3376 queue2 = alternate.updateQueue;
3377 if (queue1 === null) {
3378 if (queue2 === null) {
3379 // Neither fiber has an update queue. Create new ones.
3380 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
3381 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
3382 } else {
3383 // Only one fiber has an update queue. Clone to create a new one.
3384 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
3385 }
3386 } else {
3387 if (queue2 === null) {
3388 // Only one fiber has an update queue. Clone to create a new one.
3389 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
3390 } else {
3391 // Both owners have an update queue.
3392 }
3393 }
3394 }
3395 if (queue2 === null || queue1 === queue2) {
3396 // There's only a single queue.
3397 appendUpdateToQueue(queue1, update);
3398 } else {
3399 // There are two queues. We need to append the update to both queues,
3400 // while accounting for the persistent structure of the list — we don't
3401 // want the same update to be added multiple times.
3402 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
3403 // One of the queues is not empty. We must add the update to both queues.
3404 appendUpdateToQueue(queue1, update);
3405 appendUpdateToQueue(queue2, update);
3406 } else {
3407 // Both queues are non-empty. The last update is the same in both lists,
3408 // because of structural sharing. So, only append to one of the lists.
3409 appendUpdateToQueue(queue1, update);
3410 // But we still need to update the `lastUpdate` pointer of queue2.
3411 queue2.lastUpdate = update;
3412 }
3413 }
3414
3415 {
3416 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
3417 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.');
3418 didWarnUpdateInsideUpdate = true;
3419 }
3420 }
3421}
3422
3423function enqueueCapturedUpdate(workInProgress, update) {
3424 // Captured updates go into a separate list, and only on the work-in-
3425 // progress queue.
3426 var workInProgressQueue = workInProgress.updateQueue;
3427 if (workInProgressQueue === null) {
3428 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
3429 } else {
3430 // TODO: I put this here rather than createWorkInProgress so that we don't
3431 // clone the queue unnecessarily. There's probably a better way to
3432 // structure this.
3433 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
3434 }
3435
3436 // Append the update to the end of the list.
3437 if (workInProgressQueue.lastCapturedUpdate === null) {
3438 // This is the first render phase update
3439 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
3440 } else {
3441 workInProgressQueue.lastCapturedUpdate.next = update;
3442 workInProgressQueue.lastCapturedUpdate = update;
3443 }
3444}
3445
3446function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
3447 var current = workInProgress.alternate;
3448 if (current !== null) {
3449 // If the work-in-progress queue is equal to the current queue,
3450 // we need to clone it first.
3451 if (queue === current.updateQueue) {
3452 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
3453 }
3454 }
3455 return queue;
3456}
3457
3458function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
3459 switch (update.tag) {
3460 case ReplaceState:
3461 {
3462 var _payload = update.payload;
3463 if (typeof _payload === 'function') {
3464 // Updater function
3465 {
3466 enterDisallowedContextReadInDEV();
3467 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
3468 _payload.call(instance, prevState, nextProps);
3469 }
3470 }
3471 var nextState = _payload.call(instance, prevState, nextProps);
3472 {
3473 exitDisallowedContextReadInDEV();
3474 }
3475 return nextState;
3476 }
3477 // State object
3478 return _payload;
3479 }
3480 case CaptureUpdate:
3481 {
3482 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
3483 }
3484 // Intentional fallthrough
3485 case UpdateState:
3486 {
3487 var _payload2 = update.payload;
3488 var partialState = void 0;
3489 if (typeof _payload2 === 'function') {
3490 // Updater function
3491 {
3492 enterDisallowedContextReadInDEV();
3493 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
3494 _payload2.call(instance, prevState, nextProps);
3495 }
3496 }
3497 partialState = _payload2.call(instance, prevState, nextProps);
3498 {
3499 exitDisallowedContextReadInDEV();
3500 }
3501 } else {
3502 // Partial state object
3503 partialState = _payload2;
3504 }
3505 if (partialState === null || partialState === undefined) {
3506 // Null and undefined are treated as no-ops.
3507 return prevState;
3508 }
3509 // Merge the partial state and the previous state.
3510 return _assign({}, prevState, partialState);
3511 }
3512 case ForceUpdate:
3513 {
3514 hasForceUpdate = true;
3515 return prevState;
3516 }
3517 }
3518 return prevState;
3519}
3520
3521function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
3522 hasForceUpdate = false;
3523
3524 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
3525
3526 {
3527 currentlyProcessingQueue = queue;
3528 }
3529
3530 // These values may change as we process the queue.
3531 var newBaseState = queue.baseState;
3532 var newFirstUpdate = null;
3533 var newExpirationTime = NoWork;
3534
3535 // Iterate through the list of updates to compute the result.
3536 var update = queue.firstUpdate;
3537 var resultState = newBaseState;
3538 while (update !== null) {
3539 var updateExpirationTime = update.expirationTime;
3540 if (updateExpirationTime < renderExpirationTime) {
3541 // This update does not have sufficient priority. Skip it.
3542 if (newFirstUpdate === null) {
3543 // This is the first skipped update. It will be the first update in
3544 // the new list.
3545 newFirstUpdate = update;
3546 // Since this is the first update that was skipped, the current result
3547 // is the new base state.
3548 newBaseState = resultState;
3549 }
3550 // Since this update will remain in the list, update the remaining
3551 // expiration time.
3552 if (newExpirationTime < updateExpirationTime) {
3553 newExpirationTime = updateExpirationTime;
3554 }
3555 } else {
3556 // This update does have sufficient priority.
3557
3558 // Mark the event time of this update as relevant to this render pass.
3559 // TODO: This should ideally use the true event time of this update rather than
3560 // its priority which is a derived and not reverseable value.
3561 // TODO: We should skip this update if it was already committed but currently
3562 // we have no way of detecting the difference between a committed and suspended
3563 // update here.
3564 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig);
3565
3566 // Process it and compute a new result.
3567 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
3568 var _callback = update.callback;
3569 if (_callback !== null) {
3570 workInProgress.effectTag |= Callback;
3571 // Set this to null, in case it was mutated during an aborted render.
3572 update.nextEffect = null;
3573 if (queue.lastEffect === null) {
3574 queue.firstEffect = queue.lastEffect = update;
3575 } else {
3576 queue.lastEffect.nextEffect = update;
3577 queue.lastEffect = update;
3578 }
3579 }
3580 }
3581 // Continue to the next update.
3582 update = update.next;
3583 }
3584
3585 // Separately, iterate though the list of captured updates.
3586 var newFirstCapturedUpdate = null;
3587 update = queue.firstCapturedUpdate;
3588 while (update !== null) {
3589 var _updateExpirationTime = update.expirationTime;
3590 if (_updateExpirationTime < renderExpirationTime) {
3591 // This update does not have sufficient priority. Skip it.
3592 if (newFirstCapturedUpdate === null) {
3593 // This is the first skipped captured update. It will be the first
3594 // update in the new list.
3595 newFirstCapturedUpdate = update;
3596 // If this is the first update that was skipped, the current result is
3597 // the new base state.
3598 if (newFirstUpdate === null) {
3599 newBaseState = resultState;
3600 }
3601 }
3602 // Since this update will remain in the list, update the remaining
3603 // expiration time.
3604 if (newExpirationTime < _updateExpirationTime) {
3605 newExpirationTime = _updateExpirationTime;
3606 }
3607 } else {
3608 // This update does have sufficient priority. Process it and compute
3609 // a new result.
3610 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
3611 var _callback2 = update.callback;
3612 if (_callback2 !== null) {
3613 workInProgress.effectTag |= Callback;
3614 // Set this to null, in case it was mutated during an aborted render.
3615 update.nextEffect = null;
3616 if (queue.lastCapturedEffect === null) {
3617 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
3618 } else {
3619 queue.lastCapturedEffect.nextEffect = update;
3620 queue.lastCapturedEffect = update;
3621 }
3622 }
3623 }
3624 update = update.next;
3625 }
3626
3627 if (newFirstUpdate === null) {
3628 queue.lastUpdate = null;
3629 }
3630 if (newFirstCapturedUpdate === null) {
3631 queue.lastCapturedUpdate = null;
3632 } else {
3633 workInProgress.effectTag |= Callback;
3634 }
3635 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
3636 // We processed every update, without skipping. That means the new base
3637 // state is the same as the result state.
3638 newBaseState = resultState;
3639 }
3640
3641 queue.baseState = newBaseState;
3642 queue.firstUpdate = newFirstUpdate;
3643 queue.firstCapturedUpdate = newFirstCapturedUpdate;
3644
3645 // Set the remaining expiration time to be whatever is remaining in the queue.
3646 // This should be fine because the only two other things that contribute to
3647 // expiration time are props and context. We're already in the middle of the
3648 // begin phase by the time we start processing the queue, so we've already
3649 // dealt with the props. Context in components that specify
3650 // shouldComponentUpdate is tricky; but we'll have to account for
3651 // that regardless.
3652 workInProgress.expirationTime = newExpirationTime;
3653 workInProgress.memoizedState = resultState;
3654
3655 {
3656 currentlyProcessingQueue = null;
3657 }
3658}
3659
3660function callCallback(callback, context) {
3661 (function () {
3662 if (!(typeof callback === 'function')) {
3663 {
3664 throw ReactError(Error('Invalid argument passed as callback. Expected a function. Instead received: ' + callback));
3665 }
3666 }
3667 })();
3668 callback.call(context);
3669}
3670
3671function resetHasForceUpdateBeforeProcessing() {
3672 hasForceUpdate = false;
3673}
3674
3675function checkHasForceUpdateAfterProcessing() {
3676 return hasForceUpdate;
3677}
3678
3679function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
3680 // If the finished render included captured updates, and there are still
3681 // lower priority updates left over, we need to keep the captured updates
3682 // in the queue so that they are rebased and not dropped once we process the
3683 // queue again at the lower priority.
3684 if (finishedQueue.firstCapturedUpdate !== null) {
3685 // Join the captured update list to the end of the normal list.
3686 if (finishedQueue.lastUpdate !== null) {
3687 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
3688 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
3689 }
3690 // Clear the list of captured updates.
3691 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
3692 }
3693
3694 // Commit the effects
3695 commitUpdateEffects(finishedQueue.firstEffect, instance);
3696 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
3697
3698 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
3699 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
3700}
3701
3702function commitUpdateEffects(effect, instance) {
3703 while (effect !== null) {
3704 var _callback3 = effect.callback;
3705 if (_callback3 !== null) {
3706 effect.callback = null;
3707 callCallback(_callback3, instance);
3708 }
3709 effect = effect.nextEffect;
3710 }
3711}
3712
3713var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
3714
3715
3716function requestCurrentSuspenseConfig() {
3717 return ReactCurrentBatchConfig.suspense;
3718}
3719
3720var fakeInternalInstance = {};
3721var isArray$1 = Array.isArray;
3722
3723// React.Component uses a shared frozen object by default.
3724// We'll use it to determine whether we need to initialize legacy refs.
3725var emptyRefsObject = new React.Component().refs;
3726
3727var didWarnAboutStateAssignmentForComponent = void 0;
3728var didWarnAboutUninitializedState = void 0;
3729var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0;
3730var didWarnAboutLegacyLifecyclesAndDerivedState = void 0;
3731var didWarnAboutUndefinedDerivedState = void 0;
3732var warnOnUndefinedDerivedState = void 0;
3733var warnOnInvalidCallback = void 0;
3734var didWarnAboutDirectlyAssigningPropsToState = void 0;
3735var didWarnAboutContextTypeAndContextTypes = void 0;
3736var didWarnAboutInvalidateContextType = void 0;
3737
3738{
3739 didWarnAboutStateAssignmentForComponent = new Set();
3740 didWarnAboutUninitializedState = new Set();
3741 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
3742 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
3743 didWarnAboutDirectlyAssigningPropsToState = new Set();
3744 didWarnAboutUndefinedDerivedState = new Set();
3745 didWarnAboutContextTypeAndContextTypes = new Set();
3746 didWarnAboutInvalidateContextType = new Set();
3747
3748 var didWarnOnInvalidCallback = new Set();
3749
3750 warnOnInvalidCallback = function (callback, callerName) {
3751 if (callback === null || typeof callback === 'function') {
3752 return;
3753 }
3754 var key = callerName + '_' + callback;
3755 if (!didWarnOnInvalidCallback.has(key)) {
3756 didWarnOnInvalidCallback.add(key);
3757 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
3758 }
3759 };
3760
3761 warnOnUndefinedDerivedState = function (type, partialState) {
3762 if (partialState === undefined) {
3763 var componentName = getComponentName(type) || 'Component';
3764 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
3765 didWarnAboutUndefinedDerivedState.add(componentName);
3766 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
3767 }
3768 }
3769 };
3770
3771 // This is so gross but it's at least non-critical and can be removed if
3772 // it causes problems. This is meant to give a nicer error message for
3773 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
3774 // ...)) which otherwise throws a "_processChildContext is not a function"
3775 // exception.
3776 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
3777 enumerable: false,
3778 value: function () {
3779 (function () {
3780 {
3781 {
3782 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).'));
3783 }
3784 }
3785 })();
3786 }
3787 });
3788 Object.freeze(fakeInternalInstance);
3789}
3790
3791function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
3792 var prevState = workInProgress.memoizedState;
3793
3794 {
3795 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
3796 // Invoke the function an extra time to help detect side-effects.
3797 getDerivedStateFromProps(nextProps, prevState);
3798 }
3799 }
3800
3801 var partialState = getDerivedStateFromProps(nextProps, prevState);
3802
3803 {
3804 warnOnUndefinedDerivedState(ctor, partialState);
3805 }
3806 // Merge the partial state and the previous state.
3807 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
3808 workInProgress.memoizedState = memoizedState;
3809
3810 // Once the update queue is empty, persist the derived state onto the
3811 // base state.
3812 var updateQueue = workInProgress.updateQueue;
3813 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
3814 updateQueue.baseState = memoizedState;
3815 }
3816}
3817
3818var classComponentUpdater = {
3819 isMounted: isMounted,
3820 enqueueSetState: function (inst, payload, callback) {
3821 var fiber = get(inst);
3822 var currentTime = requestCurrentTime();
3823 var suspenseConfig = requestCurrentSuspenseConfig();
3824 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3825
3826 var update = createUpdate(expirationTime, suspenseConfig);
3827 update.payload = payload;
3828 if (callback !== undefined && callback !== null) {
3829 {
3830 warnOnInvalidCallback(callback, 'setState');
3831 }
3832 update.callback = callback;
3833 }
3834
3835 if (revertPassiveEffectsChange) {
3836 flushPassiveEffects();
3837 }
3838 enqueueUpdate(fiber, update);
3839 scheduleWork(fiber, expirationTime);
3840 },
3841 enqueueReplaceState: function (inst, payload, callback) {
3842 var fiber = get(inst);
3843 var currentTime = requestCurrentTime();
3844 var suspenseConfig = requestCurrentSuspenseConfig();
3845 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3846
3847 var update = createUpdate(expirationTime, suspenseConfig);
3848 update.tag = ReplaceState;
3849 update.payload = payload;
3850
3851 if (callback !== undefined && callback !== null) {
3852 {
3853 warnOnInvalidCallback(callback, 'replaceState');
3854 }
3855 update.callback = callback;
3856 }
3857
3858 if (revertPassiveEffectsChange) {
3859 flushPassiveEffects();
3860 }
3861 enqueueUpdate(fiber, update);
3862 scheduleWork(fiber, expirationTime);
3863 },
3864 enqueueForceUpdate: function (inst, callback) {
3865 var fiber = get(inst);
3866 var currentTime = requestCurrentTime();
3867 var suspenseConfig = requestCurrentSuspenseConfig();
3868 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3869
3870 var update = createUpdate(expirationTime, suspenseConfig);
3871 update.tag = ForceUpdate;
3872
3873 if (callback !== undefined && callback !== null) {
3874 {
3875 warnOnInvalidCallback(callback, 'forceUpdate');
3876 }
3877 update.callback = callback;
3878 }
3879
3880 if (revertPassiveEffectsChange) {
3881 flushPassiveEffects();
3882 }
3883 enqueueUpdate(fiber, update);
3884 scheduleWork(fiber, expirationTime);
3885 }
3886};
3887
3888function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
3889 var instance = workInProgress.stateNode;
3890 if (typeof instance.shouldComponentUpdate === 'function') {
3891 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
3892 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
3893 stopPhaseTimer();
3894
3895 {
3896 !(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;
3897 }
3898
3899 return shouldUpdate;
3900 }
3901
3902 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
3903 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
3904 }
3905
3906 return true;
3907}
3908
3909function checkClassInstance(workInProgress, ctor, newProps) {
3910 var instance = workInProgress.stateNode;
3911 {
3912 var name = getComponentName(ctor) || 'Component';
3913 var renderPresent = instance.render;
3914
3915 if (!renderPresent) {
3916 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
3917 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
3918 } else {
3919 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
3920 }
3921 }
3922
3923 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
3924 !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;
3925 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
3926 !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;
3927 var noInstancePropTypes = !instance.propTypes;
3928 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
3929 var noInstanceContextType = !instance.contextType;
3930 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
3931
3932 if (disableLegacyContext) {
3933 if (ctor.childContextTypes) {
3934 warningWithoutStack$1(false, '%s uses the legacy childContextTypes API which is no longer supported. ' + 'Use React.createContext() instead.', name);
3935 }
3936 if (ctor.contextTypes) {
3937 warningWithoutStack$1(false, '%s uses the legacy contextTypes API which is no longer supported. ' + 'Use React.createContext() with static contextType instead.', name);
3938 }
3939 } else {
3940 var noInstanceContextTypes = !instance.contextTypes;
3941 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
3942
3943 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
3944 didWarnAboutContextTypeAndContextTypes.add(ctor);
3945 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
3946 }
3947 }
3948
3949 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
3950 !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;
3951 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
3952 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');
3953 }
3954 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
3955 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
3956 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
3957 !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;
3958 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
3959 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
3960 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
3961 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
3962 var hasMutatedProps = instance.props !== newProps;
3963 !(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;
3964 var noInstanceDefaultProps = !instance.defaultProps;
3965 !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;
3966
3967 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
3968 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
3969 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
3970 }
3971
3972 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
3973 !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;
3974 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
3975 !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;
3976 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
3977 !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;
3978 var _state = instance.state;
3979 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
3980 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
3981 }
3982 if (typeof instance.getChildContext === 'function') {
3983 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
3984 }
3985 }
3986}
3987
3988function adoptClassInstance(workInProgress, instance) {
3989 instance.updater = classComponentUpdater;
3990 workInProgress.stateNode = instance;
3991 // The instance needs access to the fiber so that it can schedule updates
3992 set(instance, workInProgress);
3993 {
3994 instance._reactInternalInstance = fakeInternalInstance;
3995 }
3996}
3997
3998function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
3999 var isLegacyContextConsumer = false;
4000 var unmaskedContext = emptyContextObject;
4001 var context = emptyContextObject;
4002 var contextType = ctor.contextType;
4003
4004 {
4005 if ('contextType' in ctor) {
4006 var isValid =
4007 // Allow null for conditional declaration
4008 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
4009
4010 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
4011 didWarnAboutInvalidateContextType.add(ctor);
4012
4013 var addendum = '';
4014 if (contextType === undefined) {
4015 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.';
4016 } else if (typeof contextType !== 'object') {
4017 addendum = ' However, it is set to a ' + typeof contextType + '.';
4018 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
4019 addendum = ' Did you accidentally pass the Context.Provider instead?';
4020 } else if (contextType._context !== undefined) {
4021 // <Context.Consumer>
4022 addendum = ' Did you accidentally pass the Context.Consumer instead?';
4023 } else {
4024 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
4025 }
4026 warningWithoutStack$1(false, '%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
4027 }
4028 }
4029 }
4030
4031 if (typeof contextType === 'object' && contextType !== null) {
4032 context = readContext(contextType);
4033 } else if (!disableLegacyContext) {
4034 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4035 var contextTypes = ctor.contextTypes;
4036 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
4037 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
4038 }
4039
4040 // Instantiate twice to help detect side-effects.
4041 {
4042 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
4043 new ctor(props, context); // eslint-disable-line no-new
4044 }
4045 }
4046
4047 var instance = new ctor(props, context);
4048 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
4049 adoptClassInstance(workInProgress, instance);
4050
4051 {
4052 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
4053 var componentName = getComponentName(ctor) || 'Component';
4054 if (!didWarnAboutUninitializedState.has(componentName)) {
4055 didWarnAboutUninitializedState.add(componentName);
4056 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);
4057 }
4058 }
4059
4060 // If new component APIs are defined, "unsafe" lifecycles won't be called.
4061 // Warn about these lifecycles if they are present.
4062 // Don't warn about react-lifecycles-compat polyfilled methods though.
4063 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
4064 var foundWillMountName = null;
4065 var foundWillReceivePropsName = null;
4066 var foundWillUpdateName = null;
4067 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
4068 foundWillMountName = 'componentWillMount';
4069 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
4070 foundWillMountName = 'UNSAFE_componentWillMount';
4071 }
4072 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
4073 foundWillReceivePropsName = 'componentWillReceiveProps';
4074 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4075 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
4076 }
4077 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
4078 foundWillUpdateName = 'componentWillUpdate';
4079 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4080 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
4081 }
4082 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
4083 var _componentName = getComponentName(ctor) || 'Component';
4084 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
4085 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
4086 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
4087 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 : '');
4088 }
4089 }
4090 }
4091 }
4092
4093 // Cache unmasked context so we can avoid recreating masked context unless necessary.
4094 // ReactFiberContext usually updates this cache but can't for newly-created instances.
4095 if (isLegacyContextConsumer) {
4096 cacheContext(workInProgress, unmaskedContext, context);
4097 }
4098
4099 return instance;
4100}
4101
4102function callComponentWillMount(workInProgress, instance) {
4103 startPhaseTimer(workInProgress, 'componentWillMount');
4104 var oldState = instance.state;
4105
4106 if (typeof instance.componentWillMount === 'function') {
4107 instance.componentWillMount();
4108 }
4109 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4110 instance.UNSAFE_componentWillMount();
4111 }
4112
4113 stopPhaseTimer();
4114
4115 if (oldState !== instance.state) {
4116 {
4117 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');
4118 }
4119 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4120 }
4121}
4122
4123function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
4124 var oldState = instance.state;
4125 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
4126 if (typeof instance.componentWillReceiveProps === 'function') {
4127 instance.componentWillReceiveProps(newProps, nextContext);
4128 }
4129 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4130 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
4131 }
4132 stopPhaseTimer();
4133
4134 if (instance.state !== oldState) {
4135 {
4136 var componentName = getComponentName(workInProgress.type) || 'Component';
4137 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
4138 didWarnAboutStateAssignmentForComponent.add(componentName);
4139 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
4140 }
4141 }
4142 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4143 }
4144}
4145
4146// Invokes the mount life-cycles on a previously never rendered instance.
4147function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4148 {
4149 checkClassInstance(workInProgress, ctor, newProps);
4150 }
4151
4152 var instance = workInProgress.stateNode;
4153 instance.props = newProps;
4154 instance.state = workInProgress.memoizedState;
4155 instance.refs = emptyRefsObject;
4156
4157 var contextType = ctor.contextType;
4158 if (typeof contextType === 'object' && contextType !== null) {
4159 instance.context = readContext(contextType);
4160 } else if (disableLegacyContext) {
4161 instance.context = emptyContextObject;
4162 } else {
4163 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4164 instance.context = getMaskedContext(workInProgress, unmaskedContext);
4165 }
4166
4167 {
4168 if (instance.state === newProps) {
4169 var componentName = getComponentName(ctor) || 'Component';
4170 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
4171 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
4172 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);
4173 }
4174 }
4175
4176 if (workInProgress.mode & StrictMode) {
4177 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
4178 }
4179
4180 if (warnAboutDeprecatedLifecycles) {
4181 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
4182 }
4183 }
4184
4185 var updateQueue = workInProgress.updateQueue;
4186 if (updateQueue !== null) {
4187 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4188 instance.state = workInProgress.memoizedState;
4189 }
4190
4191 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4192 if (typeof getDerivedStateFromProps === 'function') {
4193 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4194 instance.state = workInProgress.memoizedState;
4195 }
4196
4197 // In order to support react-lifecycles-compat polyfilled components,
4198 // Unsafe lifecycles should not be invoked for components using the new APIs.
4199 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4200 callComponentWillMount(workInProgress, instance);
4201 // If we had additional state updates during this life-cycle, let's
4202 // process them now.
4203 updateQueue = workInProgress.updateQueue;
4204 if (updateQueue !== null) {
4205 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4206 instance.state = workInProgress.memoizedState;
4207 }
4208 }
4209
4210 if (typeof instance.componentDidMount === 'function') {
4211 workInProgress.effectTag |= Update;
4212 }
4213}
4214
4215function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4216 var instance = workInProgress.stateNode;
4217
4218 var oldProps = workInProgress.memoizedProps;
4219 instance.props = oldProps;
4220
4221 var oldContext = instance.context;
4222 var contextType = ctor.contextType;
4223 var nextContext = emptyContextObject;
4224 if (typeof contextType === 'object' && contextType !== null) {
4225 nextContext = readContext(contextType);
4226 } else if (!disableLegacyContext) {
4227 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4228 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
4229 }
4230
4231 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4232 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
4233
4234 // Note: During these life-cycles, instance.props/instance.state are what
4235 // ever the previously attempted to render - not the "current". However,
4236 // during componentDidUpdate we pass the "current" props.
4237
4238 // In order to support react-lifecycles-compat polyfilled components,
4239 // Unsafe lifecycles should not be invoked for components using the new APIs.
4240 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4241 if (oldProps !== newProps || oldContext !== nextContext) {
4242 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4243 }
4244 }
4245
4246 resetHasForceUpdateBeforeProcessing();
4247
4248 var oldState = workInProgress.memoizedState;
4249 var newState = instance.state = oldState;
4250 var updateQueue = workInProgress.updateQueue;
4251 if (updateQueue !== null) {
4252 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4253 newState = workInProgress.memoizedState;
4254 }
4255 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4256 // If an update was already in progress, we should schedule an Update
4257 // effect even though we're bailing out, so that cWU/cDU are called.
4258 if (typeof instance.componentDidMount === 'function') {
4259 workInProgress.effectTag |= Update;
4260 }
4261 return false;
4262 }
4263
4264 if (typeof getDerivedStateFromProps === 'function') {
4265 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4266 newState = workInProgress.memoizedState;
4267 }
4268
4269 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4270
4271 if (shouldUpdate) {
4272 // In order to support react-lifecycles-compat polyfilled components,
4273 // Unsafe lifecycles should not be invoked for components using the new APIs.
4274 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4275 startPhaseTimer(workInProgress, 'componentWillMount');
4276 if (typeof instance.componentWillMount === 'function') {
4277 instance.componentWillMount();
4278 }
4279 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4280 instance.UNSAFE_componentWillMount();
4281 }
4282 stopPhaseTimer();
4283 }
4284 if (typeof instance.componentDidMount === 'function') {
4285 workInProgress.effectTag |= Update;
4286 }
4287 } else {
4288 // If an update was already in progress, we should schedule an Update
4289 // effect even though we're bailing out, so that cWU/cDU are called.
4290 if (typeof instance.componentDidMount === 'function') {
4291 workInProgress.effectTag |= Update;
4292 }
4293
4294 // If shouldComponentUpdate returned false, we should still update the
4295 // memoized state to indicate that this work can be reused.
4296 workInProgress.memoizedProps = newProps;
4297 workInProgress.memoizedState = newState;
4298 }
4299
4300 // Update the existing instance's state, props, and context pointers even
4301 // if shouldComponentUpdate returns false.
4302 instance.props = newProps;
4303 instance.state = newState;
4304 instance.context = nextContext;
4305
4306 return shouldUpdate;
4307}
4308
4309// Invokes the update life-cycles and returns false if it shouldn't rerender.
4310function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
4311 var instance = workInProgress.stateNode;
4312
4313 var oldProps = workInProgress.memoizedProps;
4314 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
4315
4316 var oldContext = instance.context;
4317 var contextType = ctor.contextType;
4318 var nextContext = emptyContextObject;
4319 if (typeof contextType === 'object' && contextType !== null) {
4320 nextContext = readContext(contextType);
4321 } else if (!disableLegacyContext) {
4322 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4323 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
4324 }
4325
4326 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4327 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
4328
4329 // Note: During these life-cycles, instance.props/instance.state are what
4330 // ever the previously attempted to render - not the "current". However,
4331 // during componentDidUpdate we pass the "current" props.
4332
4333 // In order to support react-lifecycles-compat polyfilled components,
4334 // Unsafe lifecycles should not be invoked for components using the new APIs.
4335 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4336 if (oldProps !== newProps || oldContext !== nextContext) {
4337 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4338 }
4339 }
4340
4341 resetHasForceUpdateBeforeProcessing();
4342
4343 var oldState = workInProgress.memoizedState;
4344 var newState = instance.state = oldState;
4345 var updateQueue = workInProgress.updateQueue;
4346 if (updateQueue !== null) {
4347 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4348 newState = workInProgress.memoizedState;
4349 }
4350
4351 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4352 // If an update was already in progress, we should schedule an Update
4353 // effect even though we're bailing out, so that cWU/cDU are called.
4354 if (typeof instance.componentDidUpdate === 'function') {
4355 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4356 workInProgress.effectTag |= Update;
4357 }
4358 }
4359 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4360 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4361 workInProgress.effectTag |= Snapshot;
4362 }
4363 }
4364 return false;
4365 }
4366
4367 if (typeof getDerivedStateFromProps === 'function') {
4368 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4369 newState = workInProgress.memoizedState;
4370 }
4371
4372 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4373
4374 if (shouldUpdate) {
4375 // In order to support react-lifecycles-compat polyfilled components,
4376 // Unsafe lifecycles should not be invoked for components using the new APIs.
4377 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
4378 startPhaseTimer(workInProgress, 'componentWillUpdate');
4379 if (typeof instance.componentWillUpdate === 'function') {
4380 instance.componentWillUpdate(newProps, newState, nextContext);
4381 }
4382 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4383 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
4384 }
4385 stopPhaseTimer();
4386 }
4387 if (typeof instance.componentDidUpdate === 'function') {
4388 workInProgress.effectTag |= Update;
4389 }
4390 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4391 workInProgress.effectTag |= Snapshot;
4392 }
4393 } else {
4394 // If an update was already in progress, we should schedule an Update
4395 // effect even though we're bailing out, so that cWU/cDU are called.
4396 if (typeof instance.componentDidUpdate === 'function') {
4397 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4398 workInProgress.effectTag |= Update;
4399 }
4400 }
4401 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4402 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4403 workInProgress.effectTag |= Snapshot;
4404 }
4405 }
4406
4407 // If shouldComponentUpdate returned false, we should still update the
4408 // memoized props/state to indicate that this work can be reused.
4409 workInProgress.memoizedProps = newProps;
4410 workInProgress.memoizedState = newState;
4411 }
4412
4413 // Update the existing instance's state, props, and context pointers even
4414 // if shouldComponentUpdate returns false.
4415 instance.props = newProps;
4416 instance.state = newState;
4417 instance.context = nextContext;
4418
4419 return shouldUpdate;
4420}
4421
4422var didWarnAboutMaps = void 0;
4423var didWarnAboutGenerators = void 0;
4424var didWarnAboutStringRefInStrictMode = void 0;
4425var ownerHasKeyUseWarning = void 0;
4426var ownerHasFunctionTypeWarning = void 0;
4427var warnForMissingKey = function (child) {};
4428
4429{
4430 didWarnAboutMaps = false;
4431 didWarnAboutGenerators = false;
4432 didWarnAboutStringRefInStrictMode = {};
4433
4434 /**
4435 * Warn if there's no key explicitly set on dynamic arrays of children or
4436 * object keys are not valid. This allows us to keep track of children between
4437 * updates.
4438 */
4439 ownerHasKeyUseWarning = {};
4440 ownerHasFunctionTypeWarning = {};
4441
4442 warnForMissingKey = function (child) {
4443 if (child === null || typeof child !== 'object') {
4444 return;
4445 }
4446 if (!child._store || child._store.validated || child.key != null) {
4447 return;
4448 }
4449 (function () {
4450 if (!(typeof child._store === 'object')) {
4451 {
4452 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.'));
4453 }
4454 }
4455 })();
4456 child._store.validated = true;
4457
4458 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
4459 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
4460 return;
4461 }
4462 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
4463
4464 warning$1(false, 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
4465 };
4466}
4467
4468var isArray = Array.isArray;
4469
4470function coerceRef(returnFiber, current$$1, element) {
4471 var mixedRef = element.ref;
4472 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
4473 {
4474 if (returnFiber.mode & StrictMode) {
4475 var componentName = getComponentName(returnFiber.type) || 'Component';
4476 if (!didWarnAboutStringRefInStrictMode[componentName]) {
4477 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));
4478 didWarnAboutStringRefInStrictMode[componentName] = true;
4479 }
4480 }
4481 }
4482
4483 if (element._owner) {
4484 var owner = element._owner;
4485 var inst = void 0;
4486 if (owner) {
4487 var ownerFiber = owner;
4488 (function () {
4489 if (!(ownerFiber.tag === ClassComponent)) {
4490 {
4491 throw ReactError(Error('Function components cannot have refs. Did you mean to use React.forwardRef()?'));
4492 }
4493 }
4494 })();
4495 inst = ownerFiber.stateNode;
4496 }
4497 (function () {
4498 if (!inst) {
4499 {
4500 throw ReactError(Error('Missing owner for string ref ' + mixedRef + '. This error is likely caused by a bug in React. Please file an issue.'));
4501 }
4502 }
4503 })();
4504 var stringRef = '' + mixedRef;
4505 // Check if previous string ref matches new string ref
4506 if (current$$1 !== null && current$$1.ref !== null && typeof current$$1.ref === 'function' && current$$1.ref._stringRef === stringRef) {
4507 return current$$1.ref;
4508 }
4509 var ref = function (value) {
4510 var refs = inst.refs;
4511 if (refs === emptyRefsObject) {
4512 // This is a lazy pooled frozen object, so we need to initialize.
4513 refs = inst.refs = {};
4514 }
4515 if (value === null) {
4516 delete refs[stringRef];
4517 } else {
4518 refs[stringRef] = value;
4519 }
4520 };
4521 ref._stringRef = stringRef;
4522 return ref;
4523 } else {
4524 (function () {
4525 if (!(typeof mixedRef === 'string')) {
4526 {
4527 throw ReactError(Error('Expected ref to be a function, a string, an object returned by React.createRef(), or null.'));
4528 }
4529 }
4530 })();
4531 (function () {
4532 if (!element._owner) {
4533 {
4534 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.'));
4535 }
4536 }
4537 })();
4538 }
4539 }
4540 return mixedRef;
4541}
4542
4543function throwOnInvalidObjectType(returnFiber, newChild) {
4544 if (returnFiber.type !== 'textarea') {
4545 var addendum = '';
4546 {
4547 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
4548 }
4549 (function () {
4550 {
4551 {
4552 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));
4553 }
4554 }
4555 })();
4556 }
4557}
4558
4559function warnOnFunctionType() {
4560 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();
4561
4562 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
4563 return;
4564 }
4565 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
4566
4567 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.');
4568}
4569
4570// This wrapper function exists because I expect to clone the code in each path
4571// to be able to optimize each path individually by branching early. This needs
4572// a compiler or we can do it manually. Helpers that don't need this branching
4573// live outside of this function.
4574function ChildReconciler(shouldTrackSideEffects) {
4575 function deleteChild(returnFiber, childToDelete) {
4576 if (!shouldTrackSideEffects) {
4577 // Noop.
4578 return;
4579 }
4580 // Deletions are added in reversed order so we add it to the front.
4581 // At this point, the return fiber's effect list is empty except for
4582 // deletions, so we can just append the deletion to the list. The remaining
4583 // effects aren't added until the complete phase. Once we implement
4584 // resuming, this may not be true.
4585 var last = returnFiber.lastEffect;
4586 if (last !== null) {
4587 last.nextEffect = childToDelete;
4588 returnFiber.lastEffect = childToDelete;
4589 } else {
4590 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
4591 }
4592 childToDelete.nextEffect = null;
4593 childToDelete.effectTag = Deletion;
4594 }
4595
4596 function deleteRemainingChildren(returnFiber, currentFirstChild) {
4597 if (!shouldTrackSideEffects) {
4598 // Noop.
4599 return null;
4600 }
4601
4602 // TODO: For the shouldClone case, this could be micro-optimized a bit by
4603 // assuming that after the first child we've already added everything.
4604 var childToDelete = currentFirstChild;
4605 while (childToDelete !== null) {
4606 deleteChild(returnFiber, childToDelete);
4607 childToDelete = childToDelete.sibling;
4608 }
4609 return null;
4610 }
4611
4612 function mapRemainingChildren(returnFiber, currentFirstChild) {
4613 // Add the remaining children to a temporary map so that we can find them by
4614 // keys quickly. Implicit (null) keys get added to this set with their index
4615 var existingChildren = new Map();
4616
4617 var existingChild = currentFirstChild;
4618 while (existingChild !== null) {
4619 if (existingChild.key !== null) {
4620 existingChildren.set(existingChild.key, existingChild);
4621 } else {
4622 existingChildren.set(existingChild.index, existingChild);
4623 }
4624 existingChild = existingChild.sibling;
4625 }
4626 return existingChildren;
4627 }
4628
4629 function useFiber(fiber, pendingProps, expirationTime) {
4630 // We currently set sibling to null and index to 0 here because it is easy
4631 // to forget to do before returning it. E.g. for the single child case.
4632 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
4633 clone.index = 0;
4634 clone.sibling = null;
4635 return clone;
4636 }
4637
4638 function placeChild(newFiber, lastPlacedIndex, newIndex) {
4639 newFiber.index = newIndex;
4640 if (!shouldTrackSideEffects) {
4641 // Noop.
4642 return lastPlacedIndex;
4643 }
4644 var current$$1 = newFiber.alternate;
4645 if (current$$1 !== null) {
4646 var oldIndex = current$$1.index;
4647 if (oldIndex < lastPlacedIndex) {
4648 // This is a move.
4649 newFiber.effectTag = Placement;
4650 return lastPlacedIndex;
4651 } else {
4652 // This item can stay in place.
4653 return oldIndex;
4654 }
4655 } else {
4656 // This is an insertion.
4657 newFiber.effectTag = Placement;
4658 return lastPlacedIndex;
4659 }
4660 }
4661
4662 function placeSingleChild(newFiber) {
4663 // This is simpler for the single child case. We only need to do a
4664 // placement for inserting new children.
4665 if (shouldTrackSideEffects && newFiber.alternate === null) {
4666 newFiber.effectTag = Placement;
4667 }
4668 return newFiber;
4669 }
4670
4671 function updateTextNode(returnFiber, current$$1, textContent, expirationTime) {
4672 if (current$$1 === null || current$$1.tag !== HostText) {
4673 // Insert
4674 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
4675 created.return = returnFiber;
4676 return created;
4677 } else {
4678 // Update
4679 var existing = useFiber(current$$1, textContent, expirationTime);
4680 existing.return = returnFiber;
4681 return existing;
4682 }
4683 }
4684
4685 function updateElement(returnFiber, current$$1, element, expirationTime) {
4686 if (current$$1 !== null && (current$$1.elementType === element.type || (
4687 // Keep this check inline so it only runs on the false path:
4688 isCompatibleFamilyForHotReloading(current$$1, element)))) {
4689 // Move based on index
4690 var existing = useFiber(current$$1, element.props, expirationTime);
4691 existing.ref = coerceRef(returnFiber, current$$1, element);
4692 existing.return = returnFiber;
4693 {
4694 existing._debugSource = element._source;
4695 existing._debugOwner = element._owner;
4696 }
4697 return existing;
4698 } else {
4699 // Insert
4700 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
4701 created.ref = coerceRef(returnFiber, current$$1, element);
4702 created.return = returnFiber;
4703 return created;
4704 }
4705 }
4706
4707 function updatePortal(returnFiber, current$$1, portal, expirationTime) {
4708 if (current$$1 === null || current$$1.tag !== HostPortal || current$$1.stateNode.containerInfo !== portal.containerInfo || current$$1.stateNode.implementation !== portal.implementation) {
4709 // Insert
4710 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
4711 created.return = returnFiber;
4712 return created;
4713 } else {
4714 // Update
4715 var existing = useFiber(current$$1, portal.children || [], expirationTime);
4716 existing.return = returnFiber;
4717 return existing;
4718 }
4719 }
4720
4721 function updateFragment(returnFiber, current$$1, fragment, expirationTime, key) {
4722 if (current$$1 === null || current$$1.tag !== Fragment) {
4723 // Insert
4724 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
4725 created.return = returnFiber;
4726 return created;
4727 } else {
4728 // Update
4729 var existing = useFiber(current$$1, fragment, expirationTime);
4730 existing.return = returnFiber;
4731 return existing;
4732 }
4733 }
4734
4735 function createChild(returnFiber, newChild, expirationTime) {
4736 if (typeof newChild === 'string' || typeof newChild === 'number') {
4737 // Text nodes don't have keys. If the previous node is implicitly keyed
4738 // we can continue to replace it without aborting even if it is not a text
4739 // node.
4740 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
4741 created.return = returnFiber;
4742 return created;
4743 }
4744
4745 if (typeof newChild === 'object' && newChild !== null) {
4746 switch (newChild.$$typeof) {
4747 case REACT_ELEMENT_TYPE:
4748 {
4749 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
4750 _created.ref = coerceRef(returnFiber, null, newChild);
4751 _created.return = returnFiber;
4752 return _created;
4753 }
4754 case REACT_PORTAL_TYPE:
4755 {
4756 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
4757 _created2.return = returnFiber;
4758 return _created2;
4759 }
4760 }
4761
4762 if (isArray(newChild) || getIteratorFn(newChild)) {
4763 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
4764 _created3.return = returnFiber;
4765 return _created3;
4766 }
4767
4768 throwOnInvalidObjectType(returnFiber, newChild);
4769 }
4770
4771 {
4772 if (typeof newChild === 'function') {
4773 warnOnFunctionType();
4774 }
4775 }
4776
4777 return null;
4778 }
4779
4780 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
4781 // Update the fiber if the keys match, otherwise return null.
4782
4783 var key = oldFiber !== null ? oldFiber.key : null;
4784
4785 if (typeof newChild === 'string' || typeof newChild === 'number') {
4786 // Text nodes don't have keys. If the previous node is implicitly keyed
4787 // we can continue to replace it without aborting even if it is not a text
4788 // node.
4789 if (key !== null) {
4790 return null;
4791 }
4792 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
4793 }
4794
4795 if (typeof newChild === 'object' && newChild !== null) {
4796 switch (newChild.$$typeof) {
4797 case REACT_ELEMENT_TYPE:
4798 {
4799 if (newChild.key === key) {
4800 if (newChild.type === REACT_FRAGMENT_TYPE) {
4801 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
4802 }
4803 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
4804 } else {
4805 return null;
4806 }
4807 }
4808 case REACT_PORTAL_TYPE:
4809 {
4810 if (newChild.key === key) {
4811 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
4812 } else {
4813 return null;
4814 }
4815 }
4816 }
4817
4818 if (isArray(newChild) || getIteratorFn(newChild)) {
4819 if (key !== null) {
4820 return null;
4821 }
4822
4823 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
4824 }
4825
4826 throwOnInvalidObjectType(returnFiber, newChild);
4827 }
4828
4829 {
4830 if (typeof newChild === 'function') {
4831 warnOnFunctionType();
4832 }
4833 }
4834
4835 return null;
4836 }
4837
4838 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
4839 if (typeof newChild === 'string' || typeof newChild === 'number') {
4840 // Text nodes don't have keys, so we neither have to check the old nor
4841 // new node for the key. If both are text nodes, they match.
4842 var matchedFiber = existingChildren.get(newIdx) || null;
4843 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
4844 }
4845
4846 if (typeof newChild === 'object' && newChild !== null) {
4847 switch (newChild.$$typeof) {
4848 case REACT_ELEMENT_TYPE:
4849 {
4850 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4851 if (newChild.type === REACT_FRAGMENT_TYPE) {
4852 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
4853 }
4854 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
4855 }
4856 case REACT_PORTAL_TYPE:
4857 {
4858 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4859 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
4860 }
4861 }
4862
4863 if (isArray(newChild) || getIteratorFn(newChild)) {
4864 var _matchedFiber3 = existingChildren.get(newIdx) || null;
4865 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
4866 }
4867
4868 throwOnInvalidObjectType(returnFiber, newChild);
4869 }
4870
4871 {
4872 if (typeof newChild === 'function') {
4873 warnOnFunctionType();
4874 }
4875 }
4876
4877 return null;
4878 }
4879
4880 /**
4881 * Warns if there is a duplicate or missing key
4882 */
4883 function warnOnInvalidKey(child, knownKeys) {
4884 {
4885 if (typeof child !== 'object' || child === null) {
4886 return knownKeys;
4887 }
4888 switch (child.$$typeof) {
4889 case REACT_ELEMENT_TYPE:
4890 case REACT_PORTAL_TYPE:
4891 warnForMissingKey(child);
4892 var key = child.key;
4893 if (typeof key !== 'string') {
4894 break;
4895 }
4896 if (knownKeys === null) {
4897 knownKeys = new Set();
4898 knownKeys.add(key);
4899 break;
4900 }
4901 if (!knownKeys.has(key)) {
4902 knownKeys.add(key);
4903 break;
4904 }
4905 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);
4906 break;
4907 default:
4908 break;
4909 }
4910 }
4911 return knownKeys;
4912 }
4913
4914 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
4915 // This algorithm can't optimize by searching from both ends since we
4916 // don't have backpointers on fibers. I'm trying to see how far we can get
4917 // with that model. If it ends up not being worth the tradeoffs, we can
4918 // add it later.
4919
4920 // Even with a two ended optimization, we'd want to optimize for the case
4921 // where there are few changes and brute force the comparison instead of
4922 // going for the Map. It'd like to explore hitting that path first in
4923 // forward-only mode and only go for the Map once we notice that we need
4924 // lots of look ahead. This doesn't handle reversal as well as two ended
4925 // search but that's unusual. Besides, for the two ended optimization to
4926 // work on Iterables, we'd need to copy the whole set.
4927
4928 // In this first iteration, we'll just live with hitting the bad case
4929 // (adding everything to a Map) in for every insert/move.
4930
4931 // If you change this code, also update reconcileChildrenIterator() which
4932 // uses the same algorithm.
4933
4934 {
4935 // First, validate keys.
4936 var knownKeys = null;
4937 for (var i = 0; i < newChildren.length; i++) {
4938 var child = newChildren[i];
4939 knownKeys = warnOnInvalidKey(child, knownKeys);
4940 }
4941 }
4942
4943 var resultingFirstChild = null;
4944 var previousNewFiber = null;
4945
4946 var oldFiber = currentFirstChild;
4947 var lastPlacedIndex = 0;
4948 var newIdx = 0;
4949 var nextOldFiber = null;
4950 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
4951 if (oldFiber.index > newIdx) {
4952 nextOldFiber = oldFiber;
4953 oldFiber = null;
4954 } else {
4955 nextOldFiber = oldFiber.sibling;
4956 }
4957 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
4958 if (newFiber === null) {
4959 // TODO: This breaks on empty slots like null children. That's
4960 // unfortunate because it triggers the slow path all the time. We need
4961 // a better way to communicate whether this was a miss or null,
4962 // boolean, undefined, etc.
4963 if (oldFiber === null) {
4964 oldFiber = nextOldFiber;
4965 }
4966 break;
4967 }
4968 if (shouldTrackSideEffects) {
4969 if (oldFiber && newFiber.alternate === null) {
4970 // We matched the slot, but we didn't reuse the existing fiber, so we
4971 // need to delete the existing child.
4972 deleteChild(returnFiber, oldFiber);
4973 }
4974 }
4975 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
4976 if (previousNewFiber === null) {
4977 // TODO: Move out of the loop. This only happens for the first run.
4978 resultingFirstChild = newFiber;
4979 } else {
4980 // TODO: Defer siblings if we're not at the right index for this slot.
4981 // I.e. if we had null values before, then we want to defer this
4982 // for each null value. However, we also don't want to call updateSlot
4983 // with the previous one.
4984 previousNewFiber.sibling = newFiber;
4985 }
4986 previousNewFiber = newFiber;
4987 oldFiber = nextOldFiber;
4988 }
4989
4990 if (newIdx === newChildren.length) {
4991 // We've reached the end of the new children. We can delete the rest.
4992 deleteRemainingChildren(returnFiber, oldFiber);
4993 return resultingFirstChild;
4994 }
4995
4996 if (oldFiber === null) {
4997 // If we don't have any more existing children we can choose a fast path
4998 // since the rest will all be insertions.
4999 for (; newIdx < newChildren.length; newIdx++) {
5000 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
5001 if (_newFiber === null) {
5002 continue;
5003 }
5004 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
5005 if (previousNewFiber === null) {
5006 // TODO: Move out of the loop. This only happens for the first run.
5007 resultingFirstChild = _newFiber;
5008 } else {
5009 previousNewFiber.sibling = _newFiber;
5010 }
5011 previousNewFiber = _newFiber;
5012 }
5013 return resultingFirstChild;
5014 }
5015
5016 // Add all children to a key map for quick lookups.
5017 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
5018
5019 // Keep scanning and use the map to restore deleted items as moves.
5020 for (; newIdx < newChildren.length; newIdx++) {
5021 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
5022 if (_newFiber2 !== null) {
5023 if (shouldTrackSideEffects) {
5024 if (_newFiber2.alternate !== null) {
5025 // The new fiber is a work in progress, but if there exists a
5026 // current, that means that we reused the fiber. We need to delete
5027 // it from the child list so that we don't add it to the deletion
5028 // list.
5029 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
5030 }
5031 }
5032 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
5033 if (previousNewFiber === null) {
5034 resultingFirstChild = _newFiber2;
5035 } else {
5036 previousNewFiber.sibling = _newFiber2;
5037 }
5038 previousNewFiber = _newFiber2;
5039 }
5040 }
5041
5042 if (shouldTrackSideEffects) {
5043 // Any existing children that weren't consumed above were deleted. We need
5044 // to add them to the deletion list.
5045 existingChildren.forEach(function (child) {
5046 return deleteChild(returnFiber, child);
5047 });
5048 }
5049
5050 return resultingFirstChild;
5051 }
5052
5053 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
5054 // This is the same implementation as reconcileChildrenArray(),
5055 // but using the iterator instead.
5056
5057 var iteratorFn = getIteratorFn(newChildrenIterable);
5058 (function () {
5059 if (!(typeof iteratorFn === 'function')) {
5060 {
5061 throw ReactError(Error('An object is not an iterable. This error is likely caused by a bug in React. Please file an issue.'));
5062 }
5063 }
5064 })();
5065
5066 {
5067 // We don't support rendering Generators because it's a mutation.
5068 // See https://github.com/facebook/react/issues/12995
5069 if (typeof Symbol === 'function' &&
5070 // $FlowFixMe Flow doesn't know about toStringTag
5071 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
5072 !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;
5073 didWarnAboutGenerators = true;
5074 }
5075
5076 // Warn about using Maps as children
5077 if (newChildrenIterable.entries === iteratorFn) {
5078 !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;
5079 didWarnAboutMaps = true;
5080 }
5081
5082 // First, validate keys.
5083 // We'll get a different iterator later for the main pass.
5084 var _newChildren = iteratorFn.call(newChildrenIterable);
5085 if (_newChildren) {
5086 var knownKeys = null;
5087 var _step = _newChildren.next();
5088 for (; !_step.done; _step = _newChildren.next()) {
5089 var child = _step.value;
5090 knownKeys = warnOnInvalidKey(child, knownKeys);
5091 }
5092 }
5093 }
5094
5095 var newChildren = iteratorFn.call(newChildrenIterable);
5096 (function () {
5097 if (!(newChildren != null)) {
5098 {
5099 throw ReactError(Error('An iterable object provided no iterator.'));
5100 }
5101 }
5102 })();
5103
5104 var resultingFirstChild = null;
5105 var previousNewFiber = null;
5106
5107 var oldFiber = currentFirstChild;
5108 var lastPlacedIndex = 0;
5109 var newIdx = 0;
5110 var nextOldFiber = null;
5111
5112 var step = newChildren.next();
5113 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
5114 if (oldFiber.index > newIdx) {
5115 nextOldFiber = oldFiber;
5116 oldFiber = null;
5117 } else {
5118 nextOldFiber = oldFiber.sibling;
5119 }
5120 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
5121 if (newFiber === null) {
5122 // TODO: This breaks on empty slots like null children. That's
5123 // unfortunate because it triggers the slow path all the time. We need
5124 // a better way to communicate whether this was a miss or null,
5125 // boolean, undefined, etc.
5126 if (oldFiber === null) {
5127 oldFiber = nextOldFiber;
5128 }
5129 break;
5130 }
5131 if (shouldTrackSideEffects) {
5132 if (oldFiber && newFiber.alternate === null) {
5133 // We matched the slot, but we didn't reuse the existing fiber, so we
5134 // need to delete the existing child.
5135 deleteChild(returnFiber, oldFiber);
5136 }
5137 }
5138 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
5139 if (previousNewFiber === null) {
5140 // TODO: Move out of the loop. This only happens for the first run.
5141 resultingFirstChild = newFiber;
5142 } else {
5143 // TODO: Defer siblings if we're not at the right index for this slot.
5144 // I.e. if we had null values before, then we want to defer this
5145 // for each null value. However, we also don't want to call updateSlot
5146 // with the previous one.
5147 previousNewFiber.sibling = newFiber;
5148 }
5149 previousNewFiber = newFiber;
5150 oldFiber = nextOldFiber;
5151 }
5152
5153 if (step.done) {
5154 // We've reached the end of the new children. We can delete the rest.
5155 deleteRemainingChildren(returnFiber, oldFiber);
5156 return resultingFirstChild;
5157 }
5158
5159 if (oldFiber === null) {
5160 // If we don't have any more existing children we can choose a fast path
5161 // since the rest will all be insertions.
5162 for (; !step.done; newIdx++, step = newChildren.next()) {
5163 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
5164 if (_newFiber3 === null) {
5165 continue;
5166 }
5167 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
5168 if (previousNewFiber === null) {
5169 // TODO: Move out of the loop. This only happens for the first run.
5170 resultingFirstChild = _newFiber3;
5171 } else {
5172 previousNewFiber.sibling = _newFiber3;
5173 }
5174 previousNewFiber = _newFiber3;
5175 }
5176 return resultingFirstChild;
5177 }
5178
5179 // Add all children to a key map for quick lookups.
5180 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
5181
5182 // Keep scanning and use the map to restore deleted items as moves.
5183 for (; !step.done; newIdx++, step = newChildren.next()) {
5184 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
5185 if (_newFiber4 !== null) {
5186 if (shouldTrackSideEffects) {
5187 if (_newFiber4.alternate !== null) {
5188 // The new fiber is a work in progress, but if there exists a
5189 // current, that means that we reused the fiber. We need to delete
5190 // it from the child list so that we don't add it to the deletion
5191 // list.
5192 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
5193 }
5194 }
5195 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
5196 if (previousNewFiber === null) {
5197 resultingFirstChild = _newFiber4;
5198 } else {
5199 previousNewFiber.sibling = _newFiber4;
5200 }
5201 previousNewFiber = _newFiber4;
5202 }
5203 }
5204
5205 if (shouldTrackSideEffects) {
5206 // Any existing children that weren't consumed above were deleted. We need
5207 // to add them to the deletion list.
5208 existingChildren.forEach(function (child) {
5209 return deleteChild(returnFiber, child);
5210 });
5211 }
5212
5213 return resultingFirstChild;
5214 }
5215
5216 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
5217 // There's no need to check for keys on text nodes since we don't have a
5218 // way to define them.
5219 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
5220 // We already have an existing node so let's just update it and delete
5221 // the rest.
5222 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
5223 var existing = useFiber(currentFirstChild, textContent, expirationTime);
5224 existing.return = returnFiber;
5225 return existing;
5226 }
5227 // The existing first child is not a text node so we need to create one
5228 // and delete the existing ones.
5229 deleteRemainingChildren(returnFiber, currentFirstChild);
5230 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
5231 created.return = returnFiber;
5232 return created;
5233 }
5234
5235 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
5236 var key = element.key;
5237 var child = currentFirstChild;
5238 while (child !== null) {
5239 // TODO: If key === null and child.key === null, then this only applies to
5240 // the first item in the list.
5241 if (child.key === key) {
5242 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type || (
5243 // Keep this check inline so it only runs on the false path:
5244 isCompatibleFamilyForHotReloading(child, element))) {
5245 deleteRemainingChildren(returnFiber, child.sibling);
5246 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
5247 existing.ref = coerceRef(returnFiber, child, element);
5248 existing.return = returnFiber;
5249 {
5250 existing._debugSource = element._source;
5251 existing._debugOwner = element._owner;
5252 }
5253 return existing;
5254 } else {
5255 deleteRemainingChildren(returnFiber, child);
5256 break;
5257 }
5258 } else {
5259 deleteChild(returnFiber, child);
5260 }
5261 child = child.sibling;
5262 }
5263
5264 if (element.type === REACT_FRAGMENT_TYPE) {
5265 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
5266 created.return = returnFiber;
5267 return created;
5268 } else {
5269 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
5270 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
5271 _created4.return = returnFiber;
5272 return _created4;
5273 }
5274 }
5275
5276 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
5277 var key = portal.key;
5278 var child = currentFirstChild;
5279 while (child !== null) {
5280 // TODO: If key === null and child.key === null, then this only applies to
5281 // the first item in the list.
5282 if (child.key === key) {
5283 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
5284 deleteRemainingChildren(returnFiber, child.sibling);
5285 var existing = useFiber(child, portal.children || [], expirationTime);
5286 existing.return = returnFiber;
5287 return existing;
5288 } else {
5289 deleteRemainingChildren(returnFiber, child);
5290 break;
5291 }
5292 } else {
5293 deleteChild(returnFiber, child);
5294 }
5295 child = child.sibling;
5296 }
5297
5298 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
5299 created.return = returnFiber;
5300 return created;
5301 }
5302
5303 // This API will tag the children with the side-effect of the reconciliation
5304 // itself. They will be added to the side-effect list as we pass through the
5305 // children and the parent.
5306 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
5307 // This function is not recursive.
5308 // If the top level item is an array, we treat it as a set of children,
5309 // not as a fragment. Nested arrays on the other hand will be treated as
5310 // fragment nodes. Recursion happens at the normal flow.
5311
5312 // Handle top level unkeyed fragments as if they were arrays.
5313 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
5314 // We treat the ambiguous cases above the same.
5315 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
5316 if (isUnkeyedTopLevelFragment) {
5317 newChild = newChild.props.children;
5318 }
5319
5320 // Handle object types
5321 var isObject = typeof newChild === 'object' && newChild !== null;
5322
5323 if (isObject) {
5324 switch (newChild.$$typeof) {
5325 case REACT_ELEMENT_TYPE:
5326 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
5327 case REACT_PORTAL_TYPE:
5328 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
5329 }
5330 }
5331
5332 if (typeof newChild === 'string' || typeof newChild === 'number') {
5333 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
5334 }
5335
5336 if (isArray(newChild)) {
5337 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
5338 }
5339
5340 if (getIteratorFn(newChild)) {
5341 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
5342 }
5343
5344 if (isObject) {
5345 throwOnInvalidObjectType(returnFiber, newChild);
5346 }
5347
5348 {
5349 if (typeof newChild === 'function') {
5350 warnOnFunctionType();
5351 }
5352 }
5353 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
5354 // If the new child is undefined, and the return fiber is a composite
5355 // component, throw an error. If Fiber return types are disabled,
5356 // we already threw above.
5357 switch (returnFiber.tag) {
5358 case ClassComponent:
5359 {
5360 {
5361 var instance = returnFiber.stateNode;
5362 if (instance.render._isMockFunction) {
5363 // We allow auto-mocks to proceed as if they're returning null.
5364 break;
5365 }
5366 }
5367 }
5368 // Intentionally fall through to the next case, which handles both
5369 // functions and classes
5370 // eslint-disable-next-lined no-fallthrough
5371 case FunctionComponent:
5372 {
5373 var Component = returnFiber.type;
5374 (function () {
5375 {
5376 {
5377 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.'));
5378 }
5379 }
5380 })();
5381 }
5382 }
5383 }
5384
5385 // Remaining cases are all treated as empty.
5386 return deleteRemainingChildren(returnFiber, currentFirstChild);
5387 }
5388
5389 return reconcileChildFibers;
5390}
5391
5392var reconcileChildFibers = ChildReconciler(true);
5393var mountChildFibers = ChildReconciler(false);
5394
5395function cloneChildFibers(current$$1, workInProgress) {
5396 (function () {
5397 if (!(current$$1 === null || workInProgress.child === current$$1.child)) {
5398 {
5399 throw ReactError(Error('Resuming work not yet implemented.'));
5400 }
5401 }
5402 })();
5403
5404 if (workInProgress.child === null) {
5405 return;
5406 }
5407
5408 var currentChild = workInProgress.child;
5409 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
5410 workInProgress.child = newChild;
5411
5412 newChild.return = workInProgress;
5413 while (currentChild.sibling !== null) {
5414 currentChild = currentChild.sibling;
5415 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
5416 newChild.return = workInProgress;
5417 }
5418 newChild.sibling = null;
5419}
5420
5421// Reset a workInProgress child set to prepare it for a second pass.
5422function resetChildFibers(workInProgress, renderExpirationTime) {
5423 var child = workInProgress.child;
5424 while (child !== null) {
5425 resetWorkInProgress(child, renderExpirationTime);
5426 child = child.sibling;
5427 }
5428}
5429
5430var NO_CONTEXT$1 = {};
5431
5432var contextStackCursor$1 = createCursor(NO_CONTEXT$1);
5433var contextFiberStackCursor = createCursor(NO_CONTEXT$1);
5434var rootInstanceStackCursor = createCursor(NO_CONTEXT$1);
5435
5436function requiredContext(c) {
5437 (function () {
5438 if (!(c !== NO_CONTEXT$1)) {
5439 {
5440 throw ReactError(Error('Expected host context to exist. This error is likely caused by a bug in React. Please file an issue.'));
5441 }
5442 }
5443 })();
5444 return c;
5445}
5446
5447function getRootHostContainer() {
5448 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5449 return rootInstance;
5450}
5451
5452function pushHostContainer(fiber, nextRootInstance) {
5453 // Push current root instance onto the stack;
5454 // This allows us to reset root when portals are popped.
5455 push(rootInstanceStackCursor, nextRootInstance, fiber);
5456 // Track the context and the Fiber that provided it.
5457 // This enables us to pop only Fibers that provide unique contexts.
5458 push(contextFiberStackCursor, fiber, fiber);
5459
5460 // Finally, we need to push the host context to the stack.
5461 // However, we can't just call getRootHostContext() and push it because
5462 // we'd have a different number of entries on the stack depending on
5463 // whether getRootHostContext() throws somewhere in renderer code or not.
5464 // So we push an empty value first. This lets us safely unwind on errors.
5465 push(contextStackCursor$1, NO_CONTEXT$1, fiber);
5466 var nextRootContext = getRootHostContext(nextRootInstance);
5467 // Now that we know this function doesn't throw, replace it.
5468 pop(contextStackCursor$1, fiber);
5469 push(contextStackCursor$1, nextRootContext, fiber);
5470}
5471
5472function popHostContainer(fiber) {
5473 pop(contextStackCursor$1, fiber);
5474 pop(contextFiberStackCursor, fiber);
5475 pop(rootInstanceStackCursor, fiber);
5476}
5477
5478function getHostContext() {
5479 var context = requiredContext(contextStackCursor$1.current);
5480 return context;
5481}
5482
5483function pushHostContext(fiber) {
5484 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5485 var context = requiredContext(contextStackCursor$1.current);
5486 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
5487
5488 // Don't push this Fiber's context unless it's unique.
5489 if (context === nextContext) {
5490 return;
5491 }
5492
5493 // Track the context and the Fiber that provided it.
5494 // This enables us to pop only Fibers that provide unique contexts.
5495 push(contextFiberStackCursor, fiber, fiber);
5496 push(contextStackCursor$1, nextContext, fiber);
5497}
5498
5499function popHostContext(fiber) {
5500 // Do not pop unless this Fiber provided the current context.
5501 // pushHostContext() only pushes Fibers that provide unique contexts.
5502 if (contextFiberStackCursor.current !== fiber) {
5503 return;
5504 }
5505
5506 pop(contextStackCursor$1, fiber);
5507 pop(contextFiberStackCursor, fiber);
5508}
5509
5510var DefaultSuspenseContext = 0;
5511
5512// The Suspense Context is split into two parts. The lower bits is
5513// inherited deeply down the subtree. The upper bits only affect
5514// this immediate suspense boundary and gets reset each new
5515// boundary or suspense list.
5516var SubtreeSuspenseContextMask = 1;
5517
5518// Subtree Flags:
5519
5520// InvisibleParentSuspenseContext indicates that one of our parent Suspense
5521// boundaries is not currently showing visible main content.
5522// Either because it is already showing a fallback or is not mounted at all.
5523// We can use this to determine if it is desirable to trigger a fallback at
5524// the parent. If not, then we might need to trigger undesirable boundaries
5525// and/or suspend the commit to avoid hiding the parent content.
5526var InvisibleParentSuspenseContext = 1;
5527
5528// Shallow Flags:
5529
5530// ForceSuspenseFallback can be used by SuspenseList to force newly added
5531// items into their fallback state during one of the render passes.
5532var ForceSuspenseFallback = 2;
5533
5534var suspenseStackCursor = createCursor(DefaultSuspenseContext);
5535
5536function hasSuspenseContext(parentContext, flag) {
5537 return (parentContext & flag) !== 0;
5538}
5539
5540function setDefaultShallowSuspenseContext(parentContext) {
5541 return parentContext & SubtreeSuspenseContextMask;
5542}
5543
5544function setShallowSuspenseContext(parentContext, shallowContext) {
5545 return parentContext & SubtreeSuspenseContextMask | shallowContext;
5546}
5547
5548function addSubtreeSuspenseContext(parentContext, subtreeContext) {
5549 return parentContext | subtreeContext;
5550}
5551
5552function pushSuspenseContext(fiber, newContext) {
5553 push(suspenseStackCursor, newContext, fiber);
5554}
5555
5556function popSuspenseContext(fiber) {
5557 pop(suspenseStackCursor, fiber);
5558}
5559
5560// TODO: This is now an empty object. Should we switch this to a boolean?
5561// Alternatively we can make this use an effect tag similar to SuspenseList.
5562
5563
5564function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
5565 // If it was the primary children that just suspended, capture and render the
5566 var nextState = workInProgress.memoizedState;
5567 if (nextState !== null) {
5568 return false;
5569 }
5570 var props = workInProgress.memoizedProps;
5571 // In order to capture, the Suspense component must have a fallback prop.
5572 if (props.fallback === undefined) {
5573 return false;
5574 }
5575 // Regular boundaries always capture.
5576 if (props.unstable_avoidThisFallback !== true) {
5577 return true;
5578 }
5579 // If it's a boundary we should avoid, then we prefer to bubble up to the
5580 // parent boundary if it is currently invisible.
5581 if (hasInvisibleParent) {
5582 return false;
5583 }
5584 // If the parent is not able to handle it, we must handle it.
5585 return true;
5586}
5587
5588function findFirstSuspended(row) {
5589 var node = row;
5590 while (node !== null) {
5591 if (node.tag === SuspenseComponent) {
5592 var state = node.memoizedState;
5593 if (state !== null) {
5594 return node;
5595 }
5596 } else if (node.tag === SuspenseListComponent &&
5597 // revealOrder undefined can't be trusted because it don't
5598 // keep track of whether it suspended or not.
5599 node.memoizedProps.revealOrder !== undefined) {
5600 var didSuspend = (node.effectTag & DidCapture) !== NoEffect;
5601 if (didSuspend) {
5602 return node;
5603 }
5604 } else if (node.child !== null) {
5605 node.child.return = node;
5606 node = node.child;
5607 continue;
5608 }
5609 if (node === row) {
5610 return null;
5611 }
5612 while (node.sibling === null) {
5613 if (node.return === null || node.return === row) {
5614 return null;
5615 }
5616 node = node.return;
5617 }
5618 node.sibling.return = node.return;
5619 node = node.sibling;
5620 }
5621 return null;
5622}
5623
5624function createResponderListener(responder, props) {
5625 var eventResponderListener = {
5626 responder: responder,
5627 props: props
5628 };
5629 {
5630 Object.freeze(eventResponderListener);
5631 }
5632 return eventResponderListener;
5633}
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643function createResponderInstance(responder, responderProps, responderState, target, fiber) {
5644 return {
5645 fiber: fiber,
5646 props: responderProps,
5647 responder: responder,
5648 rootEventTypes: null,
5649 state: responderState,
5650 target: target
5651 };
5652}
5653
5654var NoEffect$1 = /* */0;
5655var UnmountSnapshot = /* */2;
5656var UnmountMutation = /* */4;
5657var MountMutation = /* */8;
5658var UnmountLayout = /* */16;
5659var MountLayout = /* */32;
5660var MountPassive = /* */64;
5661var UnmountPassive = /* */128;
5662
5663var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
5664
5665
5666var didWarnAboutMismatchedHooksForComponent = void 0;
5667{
5668 didWarnAboutMismatchedHooksForComponent = new Set();
5669}
5670
5671// These are set right before calling the component.
5672var renderExpirationTime$1 = NoWork;
5673// The work-in-progress fiber. I've named it differently to distinguish it from
5674// the work-in-progress hook.
5675var currentlyRenderingFiber$1 = null;
5676
5677// Hooks are stored as a linked list on the fiber's memoizedState field. The
5678// current hook list is the list that belongs to the current fiber. The
5679// work-in-progress hook list is a new list that will be added to the
5680// work-in-progress fiber.
5681var currentHook = null;
5682var nextCurrentHook = null;
5683var firstWorkInProgressHook = null;
5684var workInProgressHook = null;
5685var nextWorkInProgressHook = null;
5686
5687var remainingExpirationTime = NoWork;
5688var componentUpdateQueue = null;
5689var sideEffectTag = 0;
5690
5691// Updates scheduled during render will trigger an immediate re-render at the
5692// end of the current pass. We can't store these updates on the normal queue,
5693// because if the work is aborted, they should be discarded. Because this is
5694// a relatively rare case, we also don't want to add an additional field to
5695// either the hook or queue object types. So we store them in a lazily create
5696// map of queue -> render-phase updates, which are discarded once the component
5697// completes without re-rendering.
5698
5699// Whether an update was scheduled during the currently executing render pass.
5700var didScheduleRenderPhaseUpdate = false;
5701// Lazily created map of render-phase updates
5702var renderPhaseUpdates = null;
5703// Counter to prevent infinite loops.
5704var numberOfReRenders = 0;
5705var RE_RENDER_LIMIT = 25;
5706
5707// In DEV, this is the name of the currently executing primitive hook
5708var currentHookNameInDev = null;
5709
5710// In DEV, this list ensures that hooks are called in the same order between renders.
5711// The list stores the order of hooks used during the initial render (mount).
5712// Subsequent renders (updates) reference this list.
5713var hookTypesDev = null;
5714var hookTypesUpdateIndexDev = -1;
5715
5716// In DEV, this tracks whether currently rendering component needs to ignore
5717// the dependencies for Hooks that need them (e.g. useEffect or useMemo).
5718// When true, such Hooks will always be "remounted". Only used during hot reload.
5719var ignorePreviousDependencies = false;
5720
5721function mountHookTypesDev() {
5722 {
5723 var hookName = currentHookNameInDev;
5724
5725 if (hookTypesDev === null) {
5726 hookTypesDev = [hookName];
5727 } else {
5728 hookTypesDev.push(hookName);
5729 }
5730 }
5731}
5732
5733function updateHookTypesDev() {
5734 {
5735 var hookName = currentHookNameInDev;
5736
5737 if (hookTypesDev !== null) {
5738 hookTypesUpdateIndexDev++;
5739 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
5740 warnOnHookMismatchInDev(hookName);
5741 }
5742 }
5743 }
5744}
5745
5746function checkDepsAreArrayDev(deps) {
5747 {
5748 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
5749 // Verify deps, but only on mount to avoid extra checks.
5750 // It's unlikely their type would change as usually you define them inline.
5751 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);
5752 }
5753 }
5754}
5755
5756function warnOnHookMismatchInDev(currentHookName) {
5757 {
5758 var componentName = getComponentName(currentlyRenderingFiber$1.type);
5759 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
5760 didWarnAboutMismatchedHooksForComponent.add(componentName);
5761
5762 if (hookTypesDev !== null) {
5763 var table = '';
5764
5765 var secondColumnStart = 30;
5766
5767 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
5768 var oldHookName = hookTypesDev[i];
5769 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
5770
5771 var row = i + 1 + '. ' + oldHookName;
5772
5773 // Extra space so second column lines up
5774 // lol @ IE not supporting String#repeat
5775 while (row.length < secondColumnStart) {
5776 row += ' ';
5777 }
5778
5779 row += newHookName + '\n';
5780
5781 table += row;
5782 }
5783
5784 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);
5785 }
5786 }
5787 }
5788}
5789
5790function throwInvalidHookError() {
5791 (function () {
5792 {
5793 {
5794 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.'));
5795 }
5796 }
5797 })();
5798}
5799
5800function areHookInputsEqual(nextDeps, prevDeps) {
5801 {
5802 if (ignorePreviousDependencies) {
5803 // Only true when this component is being hot reloaded.
5804 return false;
5805 }
5806 }
5807
5808 if (prevDeps === null) {
5809 {
5810 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);
5811 }
5812 return false;
5813 }
5814
5815 {
5816 // Don't bother comparing lengths in prod because these arrays should be
5817 // passed inline.
5818 if (nextDeps.length !== prevDeps.length) {
5819 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(', ') + ']');
5820 }
5821 }
5822 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
5823 if (is(nextDeps[i], prevDeps[i])) {
5824 continue;
5825 }
5826 return false;
5827 }
5828 return true;
5829}
5830
5831function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
5832 renderExpirationTime$1 = nextRenderExpirationTime;
5833 currentlyRenderingFiber$1 = workInProgress;
5834 nextCurrentHook = current !== null ? current.memoizedState : null;
5835
5836 {
5837 hookTypesDev = current !== null ? current._debugHookTypes : null;
5838 hookTypesUpdateIndexDev = -1;
5839 // Used for hot reloading:
5840 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
5841 }
5842
5843 // The following should have already been reset
5844 // currentHook = null;
5845 // workInProgressHook = null;
5846
5847 // remainingExpirationTime = NoWork;
5848 // componentUpdateQueue = null;
5849
5850 // didScheduleRenderPhaseUpdate = false;
5851 // renderPhaseUpdates = null;
5852 // numberOfReRenders = 0;
5853 // sideEffectTag = 0;
5854
5855 // TODO Warn if no hooks are used at all during mount, then some are used during update.
5856 // Currently we will identify the update render as a mount because nextCurrentHook === null.
5857 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
5858
5859 // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used.
5860 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
5861 // so nextCurrentHook would be null during updates and mounts.
5862 {
5863 if (nextCurrentHook !== null) {
5864 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
5865 } else if (hookTypesDev !== null) {
5866 // This dispatcher handles an edge case where a component is updating,
5867 // but no stateful hooks have been used.
5868 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
5869 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
5870 // This dispatcher does that.
5871 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
5872 } else {
5873 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
5874 }
5875 }
5876
5877 var children = Component(props, refOrContext);
5878
5879 if (didScheduleRenderPhaseUpdate) {
5880 do {
5881 didScheduleRenderPhaseUpdate = false;
5882 numberOfReRenders += 1;
5883
5884 // Start over from the beginning of the list
5885 nextCurrentHook = current !== null ? current.memoizedState : null;
5886 nextWorkInProgressHook = firstWorkInProgressHook;
5887
5888 currentHook = null;
5889 workInProgressHook = null;
5890 componentUpdateQueue = null;
5891
5892 {
5893 // Also validate hook order for cascading updates.
5894 hookTypesUpdateIndexDev = -1;
5895 }
5896
5897 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
5898
5899 children = Component(props, refOrContext);
5900 } while (didScheduleRenderPhaseUpdate);
5901
5902 renderPhaseUpdates = null;
5903 numberOfReRenders = 0;
5904 }
5905
5906 // We can assume the previous dispatcher is always this one, since we set it
5907 // at the beginning of the render phase and there's no re-entrancy.
5908 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
5909
5910 var renderedWork = currentlyRenderingFiber$1;
5911
5912 renderedWork.memoizedState = firstWorkInProgressHook;
5913 renderedWork.expirationTime = remainingExpirationTime;
5914 renderedWork.updateQueue = componentUpdateQueue;
5915 renderedWork.effectTag |= sideEffectTag;
5916
5917 {
5918 renderedWork._debugHookTypes = hookTypesDev;
5919 }
5920
5921 // This check uses currentHook so that it works the same in DEV and prod bundles.
5922 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
5923 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
5924
5925 renderExpirationTime$1 = NoWork;
5926 currentlyRenderingFiber$1 = null;
5927
5928 currentHook = null;
5929 nextCurrentHook = null;
5930 firstWorkInProgressHook = null;
5931 workInProgressHook = null;
5932 nextWorkInProgressHook = null;
5933
5934 {
5935 currentHookNameInDev = null;
5936 hookTypesDev = null;
5937 hookTypesUpdateIndexDev = -1;
5938 }
5939
5940 remainingExpirationTime = NoWork;
5941 componentUpdateQueue = null;
5942 sideEffectTag = 0;
5943
5944 // These were reset above
5945 // didScheduleRenderPhaseUpdate = false;
5946 // renderPhaseUpdates = null;
5947 // numberOfReRenders = 0;
5948
5949 (function () {
5950 if (!!didRenderTooFewHooks) {
5951 {
5952 throw ReactError(Error('Rendered fewer hooks than expected. This may be caused by an accidental early return statement.'));
5953 }
5954 }
5955 })();
5956
5957 return children;
5958}
5959
5960function bailoutHooks(current, workInProgress, expirationTime) {
5961 workInProgress.updateQueue = current.updateQueue;
5962 workInProgress.effectTag &= ~(Passive | Update);
5963 if (current.expirationTime <= expirationTime) {
5964 current.expirationTime = NoWork;
5965 }
5966}
5967
5968function resetHooks() {
5969 // We can assume the previous dispatcher is always this one, since we set it
5970 // at the beginning of the render phase and there's no re-entrancy.
5971 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
5972
5973 // This is used to reset the state of this module when a component throws.
5974 // It's also called inside mountIndeterminateComponent if we determine the
5975 // component is a module-style component.
5976 renderExpirationTime$1 = NoWork;
5977 currentlyRenderingFiber$1 = null;
5978
5979 currentHook = null;
5980 nextCurrentHook = null;
5981 firstWorkInProgressHook = null;
5982 workInProgressHook = null;
5983 nextWorkInProgressHook = null;
5984
5985 {
5986 hookTypesDev = null;
5987 hookTypesUpdateIndexDev = -1;
5988
5989 currentHookNameInDev = null;
5990 }
5991
5992 remainingExpirationTime = NoWork;
5993 componentUpdateQueue = null;
5994 sideEffectTag = 0;
5995
5996 didScheduleRenderPhaseUpdate = false;
5997 renderPhaseUpdates = null;
5998 numberOfReRenders = 0;
5999}
6000
6001function mountWorkInProgressHook() {
6002 var hook = {
6003 memoizedState: null,
6004
6005 baseState: null,
6006 queue: null,
6007 baseUpdate: null,
6008
6009 next: null
6010 };
6011
6012 if (workInProgressHook === null) {
6013 // This is the first hook in the list
6014 firstWorkInProgressHook = workInProgressHook = hook;
6015 } else {
6016 // Append to the end of the list
6017 workInProgressHook = workInProgressHook.next = hook;
6018 }
6019 return workInProgressHook;
6020}
6021
6022function updateWorkInProgressHook() {
6023 // This function is used both for updates and for re-renders triggered by a
6024 // render phase update. It assumes there is either a current hook we can
6025 // clone, or a work-in-progress hook from a previous render pass that we can
6026 // use as a base. When we reach the end of the base list, we must switch to
6027 // the dispatcher used for mounts.
6028 if (nextWorkInProgressHook !== null) {
6029 // There's already a work-in-progress. Reuse it.
6030 workInProgressHook = nextWorkInProgressHook;
6031 nextWorkInProgressHook = workInProgressHook.next;
6032
6033 currentHook = nextCurrentHook;
6034 nextCurrentHook = currentHook !== null ? currentHook.next : null;
6035 } else {
6036 // Clone from the current hook.
6037 (function () {
6038 if (!(nextCurrentHook !== null)) {
6039 {
6040 throw ReactError(Error('Rendered more hooks than during the previous render.'));
6041 }
6042 }
6043 })();
6044 currentHook = nextCurrentHook;
6045
6046 var newHook = {
6047 memoizedState: currentHook.memoizedState,
6048
6049 baseState: currentHook.baseState,
6050 queue: currentHook.queue,
6051 baseUpdate: currentHook.baseUpdate,
6052
6053 next: null
6054 };
6055
6056 if (workInProgressHook === null) {
6057 // This is the first hook in the list.
6058 workInProgressHook = firstWorkInProgressHook = newHook;
6059 } else {
6060 // Append to the end of the list.
6061 workInProgressHook = workInProgressHook.next = newHook;
6062 }
6063 nextCurrentHook = currentHook.next;
6064 }
6065 return workInProgressHook;
6066}
6067
6068function createFunctionComponentUpdateQueue() {
6069 return {
6070 lastEffect: null
6071 };
6072}
6073
6074function basicStateReducer(state, action) {
6075 return typeof action === 'function' ? action(state) : action;
6076}
6077
6078function mountReducer(reducer, initialArg, init) {
6079 var hook = mountWorkInProgressHook();
6080 var initialState = void 0;
6081 if (init !== undefined) {
6082 initialState = init(initialArg);
6083 } else {
6084 initialState = initialArg;
6085 }
6086 hook.memoizedState = hook.baseState = initialState;
6087 var queue = hook.queue = {
6088 last: null,
6089 dispatch: null,
6090 lastRenderedReducer: reducer,
6091 lastRenderedState: initialState
6092 };
6093 var dispatch = queue.dispatch = dispatchAction.bind(null,
6094 // Flow doesn't know this is non-null, but we do.
6095 currentlyRenderingFiber$1, queue);
6096 return [hook.memoizedState, dispatch];
6097}
6098
6099function updateReducer(reducer, initialArg, init) {
6100 var hook = updateWorkInProgressHook();
6101 var queue = hook.queue;
6102 (function () {
6103 if (!(queue !== null)) {
6104 {
6105 throw ReactError(Error('Should have a queue. This is likely a bug in React. Please file an issue.'));
6106 }
6107 }
6108 })();
6109
6110 queue.lastRenderedReducer = reducer;
6111
6112 if (numberOfReRenders > 0) {
6113 // This is a re-render. Apply the new render phase updates to the previous
6114 var _dispatch = queue.dispatch;
6115 if (renderPhaseUpdates !== null) {
6116 // Render phase updates are stored in a map of queue -> linked list
6117 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
6118 if (firstRenderPhaseUpdate !== undefined) {
6119 renderPhaseUpdates.delete(queue);
6120 var newState = hook.memoizedState;
6121 var update = firstRenderPhaseUpdate;
6122 do {
6123 // Process this render phase update. We don't have to check the
6124 // priority because it will always be the same as the current
6125 // render's.
6126 var _action = update.action;
6127 newState = reducer(newState, _action);
6128 update = update.next;
6129 } while (update !== null);
6130
6131 // Mark that the fiber performed work, but only if the new state is
6132 // different from the current state.
6133 if (!is(newState, hook.memoizedState)) {
6134 markWorkInProgressReceivedUpdate();
6135 }
6136
6137 hook.memoizedState = newState;
6138 // Don't persist the state accumulated from the render phase updates to
6139 // the base state unless the queue is empty.
6140 // TODO: Not sure if this is the desired semantics, but it's what we
6141 // do for gDSFP. I can't remember why.
6142 if (hook.baseUpdate === queue.last) {
6143 hook.baseState = newState;
6144 }
6145
6146 queue.lastRenderedState = newState;
6147
6148 return [newState, _dispatch];
6149 }
6150 }
6151 return [hook.memoizedState, _dispatch];
6152 }
6153
6154 // The last update in the entire queue
6155 var last = queue.last;
6156 // The last update that is part of the base state.
6157 var baseUpdate = hook.baseUpdate;
6158 var baseState = hook.baseState;
6159
6160 // Find the first unprocessed update.
6161 var first = void 0;
6162 if (baseUpdate !== null) {
6163 if (last !== null) {
6164 // For the first update, the queue is a circular linked list where
6165 // `queue.last.next = queue.first`. Once the first update commits, and
6166 // the `baseUpdate` is no longer empty, we can unravel the list.
6167 last.next = null;
6168 }
6169 first = baseUpdate.next;
6170 } else {
6171 first = last !== null ? last.next : null;
6172 }
6173 if (first !== null) {
6174 var _newState = baseState;
6175 var newBaseState = null;
6176 var newBaseUpdate = null;
6177 var prevUpdate = baseUpdate;
6178 var _update = first;
6179 var didSkip = false;
6180 do {
6181 var updateExpirationTime = _update.expirationTime;
6182 if (updateExpirationTime < renderExpirationTime$1) {
6183 // Priority is insufficient. Skip this update. If this is the first
6184 // skipped update, the previous update/state is the new base
6185 // update/state.
6186 if (!didSkip) {
6187 didSkip = true;
6188 newBaseUpdate = prevUpdate;
6189 newBaseState = _newState;
6190 }
6191 // Update the remaining priority in the queue.
6192 if (updateExpirationTime > remainingExpirationTime) {
6193 remainingExpirationTime = updateExpirationTime;
6194 }
6195 } else {
6196 // This update does have sufficient priority.
6197
6198 // Mark the event time of this update as relevant to this render pass.
6199 // TODO: This should ideally use the true event time of this update rather than
6200 // its priority which is a derived and not reverseable value.
6201 // TODO: We should skip this update if it was already committed but currently
6202 // we have no way of detecting the difference between a committed and suspended
6203 // update here.
6204 markRenderEventTimeAndConfig(updateExpirationTime, _update.suspenseConfig);
6205
6206 // Process this update.
6207 if (_update.eagerReducer === reducer) {
6208 // If this update was processed eagerly, and its reducer matches the
6209 // current reducer, we can use the eagerly computed state.
6210 _newState = _update.eagerState;
6211 } else {
6212 var _action2 = _update.action;
6213 _newState = reducer(_newState, _action2);
6214 }
6215 }
6216 prevUpdate = _update;
6217 _update = _update.next;
6218 } while (_update !== null && _update !== first);
6219
6220 if (!didSkip) {
6221 newBaseUpdate = prevUpdate;
6222 newBaseState = _newState;
6223 }
6224
6225 // Mark that the fiber performed work, but only if the new state is
6226 // different from the current state.
6227 if (!is(_newState, hook.memoizedState)) {
6228 markWorkInProgressReceivedUpdate();
6229 }
6230
6231 hook.memoizedState = _newState;
6232 hook.baseUpdate = newBaseUpdate;
6233 hook.baseState = newBaseState;
6234
6235 queue.lastRenderedState = _newState;
6236 }
6237
6238 var dispatch = queue.dispatch;
6239 return [hook.memoizedState, dispatch];
6240}
6241
6242function mountState(initialState) {
6243 var hook = mountWorkInProgressHook();
6244 if (typeof initialState === 'function') {
6245 initialState = initialState();
6246 }
6247 hook.memoizedState = hook.baseState = initialState;
6248 var queue = hook.queue = {
6249 last: null,
6250 dispatch: null,
6251 lastRenderedReducer: basicStateReducer,
6252 lastRenderedState: initialState
6253 };
6254 var dispatch = queue.dispatch = dispatchAction.bind(null,
6255 // Flow doesn't know this is non-null, but we do.
6256 currentlyRenderingFiber$1, queue);
6257 return [hook.memoizedState, dispatch];
6258}
6259
6260function updateState(initialState) {
6261 return updateReducer(basicStateReducer, initialState);
6262}
6263
6264function pushEffect(tag, create, destroy, deps) {
6265 var effect = {
6266 tag: tag,
6267 create: create,
6268 destroy: destroy,
6269 deps: deps,
6270 // Circular
6271 next: null
6272 };
6273 if (componentUpdateQueue === null) {
6274 componentUpdateQueue = createFunctionComponentUpdateQueue();
6275 componentUpdateQueue.lastEffect = effect.next = effect;
6276 } else {
6277 var _lastEffect = componentUpdateQueue.lastEffect;
6278 if (_lastEffect === null) {
6279 componentUpdateQueue.lastEffect = effect.next = effect;
6280 } else {
6281 var firstEffect = _lastEffect.next;
6282 _lastEffect.next = effect;
6283 effect.next = firstEffect;
6284 componentUpdateQueue.lastEffect = effect;
6285 }
6286 }
6287 return effect;
6288}
6289
6290function mountRef(initialValue) {
6291 var hook = mountWorkInProgressHook();
6292 var ref = { current: initialValue };
6293 {
6294 Object.seal(ref);
6295 }
6296 hook.memoizedState = ref;
6297 return ref;
6298}
6299
6300function updateRef(initialValue) {
6301 var hook = updateWorkInProgressHook();
6302 return hook.memoizedState;
6303}
6304
6305function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
6306 var hook = mountWorkInProgressHook();
6307 var nextDeps = deps === undefined ? null : deps;
6308 sideEffectTag |= fiberEffectTag;
6309 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);
6310}
6311
6312function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
6313 var hook = updateWorkInProgressHook();
6314 var nextDeps = deps === undefined ? null : deps;
6315 var destroy = undefined;
6316
6317 if (currentHook !== null) {
6318 var prevEffect = currentHook.memoizedState;
6319 destroy = prevEffect.destroy;
6320 if (nextDeps !== null) {
6321 var prevDeps = prevEffect.deps;
6322 if (areHookInputsEqual(nextDeps, prevDeps)) {
6323 pushEffect(NoEffect$1, create, destroy, nextDeps);
6324 return;
6325 }
6326 }
6327 }
6328
6329 sideEffectTag |= fiberEffectTag;
6330 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);
6331}
6332
6333function mountEffect(create, deps) {
6334 {
6335 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
6336 if ('undefined' !== typeof jest) {
6337 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
6338 }
6339 }
6340 return mountEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
6341}
6342
6343function updateEffect(create, deps) {
6344 {
6345 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
6346 if ('undefined' !== typeof jest) {
6347 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
6348 }
6349 }
6350 return updateEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
6351}
6352
6353function mountLayoutEffect(create, deps) {
6354 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
6355}
6356
6357function updateLayoutEffect(create, deps) {
6358 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
6359}
6360
6361function imperativeHandleEffect(create, ref) {
6362 if (typeof ref === 'function') {
6363 var refCallback = ref;
6364 var _inst = create();
6365 refCallback(_inst);
6366 return function () {
6367 refCallback(null);
6368 };
6369 } else if (ref !== null && ref !== undefined) {
6370 var refObject = ref;
6371 {
6372 !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;
6373 }
6374 var _inst2 = create();
6375 refObject.current = _inst2;
6376 return function () {
6377 refObject.current = null;
6378 };
6379 }
6380}
6381
6382function mountImperativeHandle(ref, create, deps) {
6383 {
6384 !(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;
6385 }
6386
6387 // TODO: If deps are provided, should we skip comparing the ref itself?
6388 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6389
6390 return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6391}
6392
6393function updateImperativeHandle(ref, create, deps) {
6394 {
6395 !(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;
6396 }
6397
6398 // TODO: If deps are provided, should we skip comparing the ref itself?
6399 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6400
6401 return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6402}
6403
6404function mountDebugValue(value, formatterFn) {
6405 // This hook is normally a no-op.
6406 // The react-debug-hooks package injects its own implementation
6407 // so that e.g. DevTools can display custom hook values.
6408}
6409
6410var updateDebugValue = mountDebugValue;
6411
6412function mountCallback(callback, deps) {
6413 var hook = mountWorkInProgressHook();
6414 var nextDeps = deps === undefined ? null : deps;
6415 hook.memoizedState = [callback, nextDeps];
6416 return callback;
6417}
6418
6419function updateCallback(callback, deps) {
6420 var hook = updateWorkInProgressHook();
6421 var nextDeps = deps === undefined ? null : deps;
6422 var prevState = hook.memoizedState;
6423 if (prevState !== null) {
6424 if (nextDeps !== null) {
6425 var prevDeps = prevState[1];
6426 if (areHookInputsEqual(nextDeps, prevDeps)) {
6427 return prevState[0];
6428 }
6429 }
6430 }
6431 hook.memoizedState = [callback, nextDeps];
6432 return callback;
6433}
6434
6435function mountMemo(nextCreate, deps) {
6436 var hook = mountWorkInProgressHook();
6437 var nextDeps = deps === undefined ? null : deps;
6438 var nextValue = nextCreate();
6439 hook.memoizedState = [nextValue, nextDeps];
6440 return nextValue;
6441}
6442
6443function updateMemo(nextCreate, deps) {
6444 var hook = updateWorkInProgressHook();
6445 var nextDeps = deps === undefined ? null : deps;
6446 var prevState = hook.memoizedState;
6447 if (prevState !== null) {
6448 // Assume these are defined. If they're not, areHookInputsEqual will warn.
6449 if (nextDeps !== null) {
6450 var prevDeps = prevState[1];
6451 if (areHookInputsEqual(nextDeps, prevDeps)) {
6452 return prevState[0];
6453 }
6454 }
6455 }
6456 var nextValue = nextCreate();
6457 hook.memoizedState = [nextValue, nextDeps];
6458 return nextValue;
6459}
6460
6461function dispatchAction(fiber, queue, action) {
6462 (function () {
6463 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {
6464 {
6465 throw ReactError(Error('Too many re-renders. React limits the number of renders to prevent an infinite loop.'));
6466 }
6467 }
6468 })();
6469
6470 {
6471 !(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;
6472 }
6473
6474 var alternate = fiber.alternate;
6475 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
6476 // This is a render phase update. Stash it in a lazily-created map of
6477 // queue -> linked list of updates. After this render pass, we'll restart
6478 // and apply the stashed updates on top of the work-in-progress hook.
6479 didScheduleRenderPhaseUpdate = true;
6480 var update = {
6481 expirationTime: renderExpirationTime$1,
6482 suspenseConfig: null,
6483 action: action,
6484 eagerReducer: null,
6485 eagerState: null,
6486 next: null
6487 };
6488 {
6489 update.priority = getCurrentPriorityLevel();
6490 }
6491 if (renderPhaseUpdates === null) {
6492 renderPhaseUpdates = new Map();
6493 }
6494 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
6495 if (firstRenderPhaseUpdate === undefined) {
6496 renderPhaseUpdates.set(queue, update);
6497 } else {
6498 // Append the update to the end of the list.
6499 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
6500 while (lastRenderPhaseUpdate.next !== null) {
6501 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
6502 }
6503 lastRenderPhaseUpdate.next = update;
6504 }
6505 } else {
6506 if (revertPassiveEffectsChange) {
6507 flushPassiveEffects();
6508 }
6509
6510 var currentTime = requestCurrentTime();
6511 var _suspenseConfig = requestCurrentSuspenseConfig();
6512 var _expirationTime = computeExpirationForFiber(currentTime, fiber, _suspenseConfig);
6513
6514 var _update2 = {
6515 expirationTime: _expirationTime,
6516 suspenseConfig: _suspenseConfig,
6517 action: action,
6518 eagerReducer: null,
6519 eagerState: null,
6520 next: null
6521 };
6522
6523 {
6524 _update2.priority = getCurrentPriorityLevel();
6525 }
6526
6527 // Append the update to the end of the list.
6528 var _last = queue.last;
6529 if (_last === null) {
6530 // This is the first update. Create a circular list.
6531 _update2.next = _update2;
6532 } else {
6533 var first = _last.next;
6534 if (first !== null) {
6535 // Still circular.
6536 _update2.next = first;
6537 }
6538 _last.next = _update2;
6539 }
6540 queue.last = _update2;
6541
6542 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
6543 // The queue is currently empty, which means we can eagerly compute the
6544 // next state before entering the render phase. If the new state is the
6545 // same as the current state, we may be able to bail out entirely.
6546 var _lastRenderedReducer = queue.lastRenderedReducer;
6547 if (_lastRenderedReducer !== null) {
6548 var prevDispatcher = void 0;
6549 {
6550 prevDispatcher = ReactCurrentDispatcher$1.current;
6551 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6552 }
6553 try {
6554 var currentState = queue.lastRenderedState;
6555 var _eagerState = _lastRenderedReducer(currentState, action);
6556 // Stash the eagerly computed state, and the reducer used to compute
6557 // it, on the update object. If the reducer hasn't changed by the
6558 // time we enter the render phase, then the eager state can be used
6559 // without calling the reducer again.
6560 _update2.eagerReducer = _lastRenderedReducer;
6561 _update2.eagerState = _eagerState;
6562 if (is(_eagerState, currentState)) {
6563 // Fast path. We can bail out without scheduling React to re-render.
6564 // It's still possible that we'll need to rebase this update later,
6565 // if the component re-renders for a different reason and by that
6566 // time the reducer has changed.
6567 return;
6568 }
6569 } catch (error) {
6570 // Suppress the error. It will throw again in the render phase.
6571 } finally {
6572 {
6573 ReactCurrentDispatcher$1.current = prevDispatcher;
6574 }
6575 }
6576 }
6577 }
6578 {
6579 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
6580 if ('undefined' !== typeof jest) {
6581 warnIfNotScopedWithMatchingAct(fiber);
6582 warnIfNotCurrentlyActingUpdatesInDev(fiber);
6583 }
6584 }
6585 scheduleWork(fiber, _expirationTime);
6586 }
6587}
6588
6589var ContextOnlyDispatcher = {
6590 readContext: readContext,
6591
6592 useCallback: throwInvalidHookError,
6593 useContext: throwInvalidHookError,
6594 useEffect: throwInvalidHookError,
6595 useImperativeHandle: throwInvalidHookError,
6596 useLayoutEffect: throwInvalidHookError,
6597 useMemo: throwInvalidHookError,
6598 useReducer: throwInvalidHookError,
6599 useRef: throwInvalidHookError,
6600 useState: throwInvalidHookError,
6601 useDebugValue: throwInvalidHookError,
6602 useResponder: throwInvalidHookError
6603};
6604
6605var HooksDispatcherOnMountInDEV = null;
6606var HooksDispatcherOnMountWithHookTypesInDEV = null;
6607var HooksDispatcherOnUpdateInDEV = null;
6608var InvalidNestedHooksDispatcherOnMountInDEV = null;
6609var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
6610
6611{
6612 var warnInvalidContextAccess = function () {
6613 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().');
6614 };
6615
6616 var warnInvalidHookAccess = function () {
6617 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');
6618 };
6619
6620 HooksDispatcherOnMountInDEV = {
6621 readContext: function (context, observedBits) {
6622 return readContext(context, observedBits);
6623 },
6624 useCallback: function (callback, deps) {
6625 currentHookNameInDev = 'useCallback';
6626 mountHookTypesDev();
6627 checkDepsAreArrayDev(deps);
6628 return mountCallback(callback, deps);
6629 },
6630 useContext: function (context, observedBits) {
6631 currentHookNameInDev = 'useContext';
6632 mountHookTypesDev();
6633 return readContext(context, observedBits);
6634 },
6635 useEffect: function (create, deps) {
6636 currentHookNameInDev = 'useEffect';
6637 mountHookTypesDev();
6638 checkDepsAreArrayDev(deps);
6639 return mountEffect(create, deps);
6640 },
6641 useImperativeHandle: function (ref, create, deps) {
6642 currentHookNameInDev = 'useImperativeHandle';
6643 mountHookTypesDev();
6644 checkDepsAreArrayDev(deps);
6645 return mountImperativeHandle(ref, create, deps);
6646 },
6647 useLayoutEffect: function (create, deps) {
6648 currentHookNameInDev = 'useLayoutEffect';
6649 mountHookTypesDev();
6650 checkDepsAreArrayDev(deps);
6651 return mountLayoutEffect(create, deps);
6652 },
6653 useMemo: function (create, deps) {
6654 currentHookNameInDev = 'useMemo';
6655 mountHookTypesDev();
6656 checkDepsAreArrayDev(deps);
6657 var prevDispatcher = ReactCurrentDispatcher$1.current;
6658 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6659 try {
6660 return mountMemo(create, deps);
6661 } finally {
6662 ReactCurrentDispatcher$1.current = prevDispatcher;
6663 }
6664 },
6665 useReducer: function (reducer, initialArg, init) {
6666 currentHookNameInDev = 'useReducer';
6667 mountHookTypesDev();
6668 var prevDispatcher = ReactCurrentDispatcher$1.current;
6669 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6670 try {
6671 return mountReducer(reducer, initialArg, init);
6672 } finally {
6673 ReactCurrentDispatcher$1.current = prevDispatcher;
6674 }
6675 },
6676 useRef: function (initialValue) {
6677 currentHookNameInDev = 'useRef';
6678 mountHookTypesDev();
6679 return mountRef(initialValue);
6680 },
6681 useState: function (initialState) {
6682 currentHookNameInDev = 'useState';
6683 mountHookTypesDev();
6684 var prevDispatcher = ReactCurrentDispatcher$1.current;
6685 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6686 try {
6687 return mountState(initialState);
6688 } finally {
6689 ReactCurrentDispatcher$1.current = prevDispatcher;
6690 }
6691 },
6692 useDebugValue: function (value, formatterFn) {
6693 currentHookNameInDev = 'useDebugValue';
6694 mountHookTypesDev();
6695 return mountDebugValue(value, formatterFn);
6696 },
6697 useResponder: function (responder, props) {
6698 currentHookNameInDev = 'useResponder';
6699 mountHookTypesDev();
6700 return createResponderListener(responder, props);
6701 }
6702 };
6703
6704 HooksDispatcherOnMountWithHookTypesInDEV = {
6705 readContext: function (context, observedBits) {
6706 return readContext(context, observedBits);
6707 },
6708 useCallback: function (callback, deps) {
6709 currentHookNameInDev = 'useCallback';
6710 updateHookTypesDev();
6711 return mountCallback(callback, deps);
6712 },
6713 useContext: function (context, observedBits) {
6714 currentHookNameInDev = 'useContext';
6715 updateHookTypesDev();
6716 return readContext(context, observedBits);
6717 },
6718 useEffect: function (create, deps) {
6719 currentHookNameInDev = 'useEffect';
6720 updateHookTypesDev();
6721 return mountEffect(create, deps);
6722 },
6723 useImperativeHandle: function (ref, create, deps) {
6724 currentHookNameInDev = 'useImperativeHandle';
6725 updateHookTypesDev();
6726 return mountImperativeHandle(ref, create, deps);
6727 },
6728 useLayoutEffect: function (create, deps) {
6729 currentHookNameInDev = 'useLayoutEffect';
6730 updateHookTypesDev();
6731 return mountLayoutEffect(create, deps);
6732 },
6733 useMemo: function (create, deps) {
6734 currentHookNameInDev = 'useMemo';
6735 updateHookTypesDev();
6736 var prevDispatcher = ReactCurrentDispatcher$1.current;
6737 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6738 try {
6739 return mountMemo(create, deps);
6740 } finally {
6741 ReactCurrentDispatcher$1.current = prevDispatcher;
6742 }
6743 },
6744 useReducer: function (reducer, initialArg, init) {
6745 currentHookNameInDev = 'useReducer';
6746 updateHookTypesDev();
6747 var prevDispatcher = ReactCurrentDispatcher$1.current;
6748 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6749 try {
6750 return mountReducer(reducer, initialArg, init);
6751 } finally {
6752 ReactCurrentDispatcher$1.current = prevDispatcher;
6753 }
6754 },
6755 useRef: function (initialValue) {
6756 currentHookNameInDev = 'useRef';
6757 updateHookTypesDev();
6758 return mountRef(initialValue);
6759 },
6760 useState: function (initialState) {
6761 currentHookNameInDev = 'useState';
6762 updateHookTypesDev();
6763 var prevDispatcher = ReactCurrentDispatcher$1.current;
6764 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6765 try {
6766 return mountState(initialState);
6767 } finally {
6768 ReactCurrentDispatcher$1.current = prevDispatcher;
6769 }
6770 },
6771 useDebugValue: function (value, formatterFn) {
6772 currentHookNameInDev = 'useDebugValue';
6773 updateHookTypesDev();
6774 return mountDebugValue(value, formatterFn);
6775 },
6776 useResponder: function (responder, props) {
6777 currentHookNameInDev = 'useResponder';
6778 updateHookTypesDev();
6779 return createResponderListener(responder, props);
6780 }
6781 };
6782
6783 HooksDispatcherOnUpdateInDEV = {
6784 readContext: function (context, observedBits) {
6785 return readContext(context, observedBits);
6786 },
6787 useCallback: function (callback, deps) {
6788 currentHookNameInDev = 'useCallback';
6789 updateHookTypesDev();
6790 return updateCallback(callback, deps);
6791 },
6792 useContext: function (context, observedBits) {
6793 currentHookNameInDev = 'useContext';
6794 updateHookTypesDev();
6795 return readContext(context, observedBits);
6796 },
6797 useEffect: function (create, deps) {
6798 currentHookNameInDev = 'useEffect';
6799 updateHookTypesDev();
6800 return updateEffect(create, deps);
6801 },
6802 useImperativeHandle: function (ref, create, deps) {
6803 currentHookNameInDev = 'useImperativeHandle';
6804 updateHookTypesDev();
6805 return updateImperativeHandle(ref, create, deps);
6806 },
6807 useLayoutEffect: function (create, deps) {
6808 currentHookNameInDev = 'useLayoutEffect';
6809 updateHookTypesDev();
6810 return updateLayoutEffect(create, deps);
6811 },
6812 useMemo: function (create, deps) {
6813 currentHookNameInDev = 'useMemo';
6814 updateHookTypesDev();
6815 var prevDispatcher = ReactCurrentDispatcher$1.current;
6816 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6817 try {
6818 return updateMemo(create, deps);
6819 } finally {
6820 ReactCurrentDispatcher$1.current = prevDispatcher;
6821 }
6822 },
6823 useReducer: function (reducer, initialArg, init) {
6824 currentHookNameInDev = 'useReducer';
6825 updateHookTypesDev();
6826 var prevDispatcher = ReactCurrentDispatcher$1.current;
6827 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6828 try {
6829 return updateReducer(reducer, initialArg, init);
6830 } finally {
6831 ReactCurrentDispatcher$1.current = prevDispatcher;
6832 }
6833 },
6834 useRef: function (initialValue) {
6835 currentHookNameInDev = 'useRef';
6836 updateHookTypesDev();
6837 return updateRef(initialValue);
6838 },
6839 useState: function (initialState) {
6840 currentHookNameInDev = 'useState';
6841 updateHookTypesDev();
6842 var prevDispatcher = ReactCurrentDispatcher$1.current;
6843 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6844 try {
6845 return updateState(initialState);
6846 } finally {
6847 ReactCurrentDispatcher$1.current = prevDispatcher;
6848 }
6849 },
6850 useDebugValue: function (value, formatterFn) {
6851 currentHookNameInDev = 'useDebugValue';
6852 updateHookTypesDev();
6853 return updateDebugValue(value, formatterFn);
6854 },
6855 useResponder: function (responder, props) {
6856 currentHookNameInDev = 'useResponder';
6857 updateHookTypesDev();
6858 return createResponderListener(responder, props);
6859 }
6860 };
6861
6862 InvalidNestedHooksDispatcherOnMountInDEV = {
6863 readContext: function (context, observedBits) {
6864 warnInvalidContextAccess();
6865 return readContext(context, observedBits);
6866 },
6867 useCallback: function (callback, deps) {
6868 currentHookNameInDev = 'useCallback';
6869 warnInvalidHookAccess();
6870 mountHookTypesDev();
6871 return mountCallback(callback, deps);
6872 },
6873 useContext: function (context, observedBits) {
6874 currentHookNameInDev = 'useContext';
6875 warnInvalidHookAccess();
6876 mountHookTypesDev();
6877 return readContext(context, observedBits);
6878 },
6879 useEffect: function (create, deps) {
6880 currentHookNameInDev = 'useEffect';
6881 warnInvalidHookAccess();
6882 mountHookTypesDev();
6883 return mountEffect(create, deps);
6884 },
6885 useImperativeHandle: function (ref, create, deps) {
6886 currentHookNameInDev = 'useImperativeHandle';
6887 warnInvalidHookAccess();
6888 mountHookTypesDev();
6889 return mountImperativeHandle(ref, create, deps);
6890 },
6891 useLayoutEffect: function (create, deps) {
6892 currentHookNameInDev = 'useLayoutEffect';
6893 warnInvalidHookAccess();
6894 mountHookTypesDev();
6895 return mountLayoutEffect(create, deps);
6896 },
6897 useMemo: function (create, deps) {
6898 currentHookNameInDev = 'useMemo';
6899 warnInvalidHookAccess();
6900 mountHookTypesDev();
6901 var prevDispatcher = ReactCurrentDispatcher$1.current;
6902 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6903 try {
6904 return mountMemo(create, deps);
6905 } finally {
6906 ReactCurrentDispatcher$1.current = prevDispatcher;
6907 }
6908 },
6909 useReducer: function (reducer, initialArg, init) {
6910 currentHookNameInDev = 'useReducer';
6911 warnInvalidHookAccess();
6912 mountHookTypesDev();
6913 var prevDispatcher = ReactCurrentDispatcher$1.current;
6914 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6915 try {
6916 return mountReducer(reducer, initialArg, init);
6917 } finally {
6918 ReactCurrentDispatcher$1.current = prevDispatcher;
6919 }
6920 },
6921 useRef: function (initialValue) {
6922 currentHookNameInDev = 'useRef';
6923 warnInvalidHookAccess();
6924 mountHookTypesDev();
6925 return mountRef(initialValue);
6926 },
6927 useState: function (initialState) {
6928 currentHookNameInDev = 'useState';
6929 warnInvalidHookAccess();
6930 mountHookTypesDev();
6931 var prevDispatcher = ReactCurrentDispatcher$1.current;
6932 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6933 try {
6934 return mountState(initialState);
6935 } finally {
6936 ReactCurrentDispatcher$1.current = prevDispatcher;
6937 }
6938 },
6939 useDebugValue: function (value, formatterFn) {
6940 currentHookNameInDev = 'useDebugValue';
6941 warnInvalidHookAccess();
6942 mountHookTypesDev();
6943 return mountDebugValue(value, formatterFn);
6944 },
6945 useResponder: function (responder, props) {
6946 currentHookNameInDev = 'useResponder';
6947 warnInvalidHookAccess();
6948 mountHookTypesDev();
6949 return createResponderListener(responder, props);
6950 }
6951 };
6952
6953 InvalidNestedHooksDispatcherOnUpdateInDEV = {
6954 readContext: function (context, observedBits) {
6955 warnInvalidContextAccess();
6956 return readContext(context, observedBits);
6957 },
6958 useCallback: function (callback, deps) {
6959 currentHookNameInDev = 'useCallback';
6960 warnInvalidHookAccess();
6961 updateHookTypesDev();
6962 return updateCallback(callback, deps);
6963 },
6964 useContext: function (context, observedBits) {
6965 currentHookNameInDev = 'useContext';
6966 warnInvalidHookAccess();
6967 updateHookTypesDev();
6968 return readContext(context, observedBits);
6969 },
6970 useEffect: function (create, deps) {
6971 currentHookNameInDev = 'useEffect';
6972 warnInvalidHookAccess();
6973 updateHookTypesDev();
6974 return updateEffect(create, deps);
6975 },
6976 useImperativeHandle: function (ref, create, deps) {
6977 currentHookNameInDev = 'useImperativeHandle';
6978 warnInvalidHookAccess();
6979 updateHookTypesDev();
6980 return updateImperativeHandle(ref, create, deps);
6981 },
6982 useLayoutEffect: function (create, deps) {
6983 currentHookNameInDev = 'useLayoutEffect';
6984 warnInvalidHookAccess();
6985 updateHookTypesDev();
6986 return updateLayoutEffect(create, deps);
6987 },
6988 useMemo: function (create, deps) {
6989 currentHookNameInDev = 'useMemo';
6990 warnInvalidHookAccess();
6991 updateHookTypesDev();
6992 var prevDispatcher = ReactCurrentDispatcher$1.current;
6993 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6994 try {
6995 return updateMemo(create, deps);
6996 } finally {
6997 ReactCurrentDispatcher$1.current = prevDispatcher;
6998 }
6999 },
7000 useReducer: function (reducer, initialArg, init) {
7001 currentHookNameInDev = 'useReducer';
7002 warnInvalidHookAccess();
7003 updateHookTypesDev();
7004 var prevDispatcher = ReactCurrentDispatcher$1.current;
7005 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7006 try {
7007 return updateReducer(reducer, initialArg, init);
7008 } finally {
7009 ReactCurrentDispatcher$1.current = prevDispatcher;
7010 }
7011 },
7012 useRef: function (initialValue) {
7013 currentHookNameInDev = 'useRef';
7014 warnInvalidHookAccess();
7015 updateHookTypesDev();
7016 return updateRef(initialValue);
7017 },
7018 useState: function (initialState) {
7019 currentHookNameInDev = 'useState';
7020 warnInvalidHookAccess();
7021 updateHookTypesDev();
7022 var prevDispatcher = ReactCurrentDispatcher$1.current;
7023 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7024 try {
7025 return updateState(initialState);
7026 } finally {
7027 ReactCurrentDispatcher$1.current = prevDispatcher;
7028 }
7029 },
7030 useDebugValue: function (value, formatterFn) {
7031 currentHookNameInDev = 'useDebugValue';
7032 warnInvalidHookAccess();
7033 updateHookTypesDev();
7034 return updateDebugValue(value, formatterFn);
7035 },
7036 useResponder: function (responder, props) {
7037 currentHookNameInDev = 'useResponder';
7038 warnInvalidHookAccess();
7039 updateHookTypesDev();
7040 return createResponderListener(responder, props);
7041 }
7042 };
7043}
7044
7045// Intentionally not named imports because Rollup would use dynamic dispatch for
7046// CommonJS interop named imports.
7047var now$1 = Scheduler$1.unstable_now;
7048
7049
7050var commitTime = 0;
7051var profilerStartTime = -1;
7052
7053function getCommitTime() {
7054 return commitTime;
7055}
7056
7057function recordCommitTime() {
7058 if (!enableProfilerTimer) {
7059 return;
7060 }
7061 commitTime = now$1();
7062}
7063
7064function startProfilerTimer(fiber) {
7065 if (!enableProfilerTimer) {
7066 return;
7067 }
7068
7069 profilerStartTime = now$1();
7070
7071 if (fiber.actualStartTime < 0) {
7072 fiber.actualStartTime = now$1();
7073 }
7074}
7075
7076function stopProfilerTimerIfRunning(fiber) {
7077 if (!enableProfilerTimer) {
7078 return;
7079 }
7080 profilerStartTime = -1;
7081}
7082
7083function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
7084 if (!enableProfilerTimer) {
7085 return;
7086 }
7087
7088 if (profilerStartTime >= 0) {
7089 var elapsedTime = now$1() - profilerStartTime;
7090 fiber.actualDuration += elapsedTime;
7091 if (overrideBaseTime) {
7092 fiber.selfBaseDuration = elapsedTime;
7093 }
7094 profilerStartTime = -1;
7095 }
7096}
7097
7098// The deepest Fiber on the stack involved in a hydration context.
7099// This may have been an insertion or a hydration.
7100var hydrationParentFiber = null;
7101var nextHydratableInstance = null;
7102var isHydrating = false;
7103
7104function enterHydrationState(fiber) {
7105 if (!supportsHydration) {
7106 return false;
7107 }
7108
7109 var parentInstance = fiber.stateNode.containerInfo;
7110 nextHydratableInstance = getFirstHydratableChild(parentInstance);
7111 hydrationParentFiber = fiber;
7112 isHydrating = true;
7113 return true;
7114}
7115
7116function reenterHydrationStateFromDehydratedSuspenseInstance(fiber) {
7117 if (!supportsHydration) {
7118 return false;
7119 }
7120
7121 var suspenseInstance = fiber.stateNode;
7122 nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
7123 popToNextHostParent(fiber);
7124 isHydrating = true;
7125 return true;
7126}
7127
7128function deleteHydratableInstance(returnFiber, instance) {
7129 {
7130 switch (returnFiber.tag) {
7131 case HostRoot:
7132 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
7133 break;
7134 case HostComponent:
7135 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
7136 break;
7137 }
7138 }
7139
7140 var childToDelete = createFiberFromHostInstanceForDeletion();
7141 childToDelete.stateNode = instance;
7142 childToDelete.return = returnFiber;
7143 childToDelete.effectTag = Deletion;
7144
7145 // This might seem like it belongs on progressedFirstDeletion. However,
7146 // these children are not part of the reconciliation list of children.
7147 // Even if we abort and rereconcile the children, that will try to hydrate
7148 // again and the nodes are still in the host tree so these will be
7149 // recreated.
7150 if (returnFiber.lastEffect !== null) {
7151 returnFiber.lastEffect.nextEffect = childToDelete;
7152 returnFiber.lastEffect = childToDelete;
7153 } else {
7154 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
7155 }
7156}
7157
7158function insertNonHydratedInstance(returnFiber, fiber) {
7159 fiber.effectTag |= Placement;
7160 {
7161 switch (returnFiber.tag) {
7162 case HostRoot:
7163 {
7164 var parentContainer = returnFiber.stateNode.containerInfo;
7165 switch (fiber.tag) {
7166 case HostComponent:
7167 var type = fiber.type;
7168 var props = fiber.pendingProps;
7169 didNotFindHydratableContainerInstance(parentContainer, type, props);
7170 break;
7171 case HostText:
7172 var text = fiber.pendingProps;
7173 didNotFindHydratableContainerTextInstance(parentContainer, text);
7174 break;
7175 case SuspenseComponent:
7176 didNotFindHydratableContainerSuspenseInstance(parentContainer);
7177 break;
7178 }
7179 break;
7180 }
7181 case HostComponent:
7182 {
7183 var parentType = returnFiber.type;
7184 var parentProps = returnFiber.memoizedProps;
7185 var parentInstance = returnFiber.stateNode;
7186 switch (fiber.tag) {
7187 case HostComponent:
7188 var _type = fiber.type;
7189 var _props = fiber.pendingProps;
7190 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
7191 break;
7192 case HostText:
7193 var _text = fiber.pendingProps;
7194 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
7195 break;
7196 case SuspenseComponent:
7197 didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance);
7198 break;
7199 }
7200 break;
7201 }
7202 default:
7203 return;
7204 }
7205 }
7206}
7207
7208function tryHydrate(fiber, nextInstance) {
7209 switch (fiber.tag) {
7210 case HostComponent:
7211 {
7212 var type = fiber.type;
7213 var props = fiber.pendingProps;
7214 var instance = canHydrateInstance(nextInstance, type, props);
7215 if (instance !== null) {
7216 fiber.stateNode = instance;
7217 return true;
7218 }
7219 return false;
7220 }
7221 case HostText:
7222 {
7223 var text = fiber.pendingProps;
7224 var textInstance = canHydrateTextInstance(nextInstance, text);
7225 if (textInstance !== null) {
7226 fiber.stateNode = textInstance;
7227 return true;
7228 }
7229 return false;
7230 }
7231 case SuspenseComponent:
7232 {
7233 if (enableSuspenseServerRenderer) {
7234 var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
7235 if (suspenseInstance !== null) {
7236 // Downgrade the tag to a dehydrated component until we've hydrated it.
7237 fiber.tag = DehydratedSuspenseComponent;
7238 fiber.stateNode = suspenseInstance;
7239 return true;
7240 }
7241 }
7242 return false;
7243 }
7244 default:
7245 return false;
7246 }
7247}
7248
7249function tryToClaimNextHydratableInstance(fiber) {
7250 if (!isHydrating) {
7251 return;
7252 }
7253 var nextInstance = nextHydratableInstance;
7254 if (!nextInstance) {
7255 // Nothing to hydrate. Make it an insertion.
7256 insertNonHydratedInstance(hydrationParentFiber, fiber);
7257 isHydrating = false;
7258 hydrationParentFiber = fiber;
7259 return;
7260 }
7261 var firstAttemptedInstance = nextInstance;
7262 if (!tryHydrate(fiber, nextInstance)) {
7263 // If we can't hydrate this instance let's try the next one.
7264 // We use this as a heuristic. It's based on intuition and not data so it
7265 // might be flawed or unnecessary.
7266 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
7267 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
7268 // Nothing to hydrate. Make it an insertion.
7269 insertNonHydratedInstance(hydrationParentFiber, fiber);
7270 isHydrating = false;
7271 hydrationParentFiber = fiber;
7272 return;
7273 }
7274 // We matched the next one, we'll now assume that the first one was
7275 // superfluous and we'll delete it. Since we can't eagerly delete it
7276 // we'll have to schedule a deletion. To do that, this node needs a dummy
7277 // fiber associated with it.
7278 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
7279 }
7280 hydrationParentFiber = fiber;
7281 nextHydratableInstance = getFirstHydratableChild(nextInstance);
7282}
7283
7284function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
7285 if (!supportsHydration) {
7286 (function () {
7287 {
7288 {
7289 throw ReactError(Error('Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'));
7290 }
7291 }
7292 })();
7293 }
7294
7295 var instance = fiber.stateNode;
7296 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
7297 // TODO: Type this specific to this type of component.
7298 fiber.updateQueue = updatePayload;
7299 // If the update payload indicates that there is a change or if there
7300 // is a new ref we mark this as an update.
7301 if (updatePayload !== null) {
7302 return true;
7303 }
7304 return false;
7305}
7306
7307function prepareToHydrateHostTextInstance(fiber) {
7308 if (!supportsHydration) {
7309 (function () {
7310 {
7311 {
7312 throw ReactError(Error('Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'));
7313 }
7314 }
7315 })();
7316 }
7317
7318 var textInstance = fiber.stateNode;
7319 var textContent = fiber.memoizedProps;
7320 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
7321 {
7322 if (shouldUpdate) {
7323 // We assume that prepareToHydrateHostTextInstance is called in a context where the
7324 // hydration parent is the parent host component of this host text.
7325 var returnFiber = hydrationParentFiber;
7326 if (returnFiber !== null) {
7327 switch (returnFiber.tag) {
7328 case HostRoot:
7329 {
7330 var parentContainer = returnFiber.stateNode.containerInfo;
7331 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
7332 break;
7333 }
7334 case HostComponent:
7335 {
7336 var parentType = returnFiber.type;
7337 var parentProps = returnFiber.memoizedProps;
7338 var parentInstance = returnFiber.stateNode;
7339 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
7340 break;
7341 }
7342 }
7343 }
7344 }
7345 }
7346 return shouldUpdate;
7347}
7348
7349function skipPastDehydratedSuspenseInstance(fiber) {
7350 if (!supportsHydration) {
7351 (function () {
7352 {
7353 {
7354 throw ReactError(Error('Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'));
7355 }
7356 }
7357 })();
7358 }
7359 var suspenseInstance = fiber.stateNode;
7360 (function () {
7361 if (!suspenseInstance) {
7362 {
7363 throw ReactError(Error('Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.'));
7364 }
7365 }
7366 })();
7367 nextHydratableInstance = getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
7368}
7369
7370function popToNextHostParent(fiber) {
7371 var parent = fiber.return;
7372 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== DehydratedSuspenseComponent) {
7373 parent = parent.return;
7374 }
7375 hydrationParentFiber = parent;
7376}
7377
7378function popHydrationState(fiber) {
7379 if (!supportsHydration) {
7380 return false;
7381 }
7382 if (fiber !== hydrationParentFiber) {
7383 // We're deeper than the current hydration context, inside an inserted
7384 // tree.
7385 return false;
7386 }
7387 if (!isHydrating) {
7388 // If we're not currently hydrating but we're in a hydration context, then
7389 // we were an insertion and now need to pop up reenter hydration of our
7390 // siblings.
7391 popToNextHostParent(fiber);
7392 isHydrating = true;
7393 return false;
7394 }
7395
7396 var type = fiber.type;
7397
7398 // If we have any remaining hydratable nodes, we need to delete them now.
7399 // We only do this deeper than head and body since they tend to have random
7400 // other nodes in them. We also ignore components with pure text content in
7401 // side of them.
7402 // TODO: Better heuristic.
7403 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
7404 var nextInstance = nextHydratableInstance;
7405 while (nextInstance) {
7406 deleteHydratableInstance(fiber, nextInstance);
7407 nextInstance = getNextHydratableSibling(nextInstance);
7408 }
7409 }
7410
7411 popToNextHostParent(fiber);
7412 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
7413 return true;
7414}
7415
7416function resetHydrationState() {
7417 if (!supportsHydration) {
7418 return;
7419 }
7420
7421 hydrationParentFiber = null;
7422 nextHydratableInstance = null;
7423 isHydrating = false;
7424}
7425
7426var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
7427
7428var didReceiveUpdate = false;
7429
7430var didWarnAboutBadClass = void 0;
7431var didWarnAboutModulePatternComponent = void 0;
7432var didWarnAboutContextTypeOnFunctionComponent = void 0;
7433var didWarnAboutGetDerivedStateOnFunctionComponent = void 0;
7434var didWarnAboutFunctionRefs = void 0;
7435var didWarnAboutReassigningProps = void 0;
7436var didWarnAboutMaxDuration = void 0;
7437var didWarnAboutRevealOrder = void 0;
7438var didWarnAboutTailOptions = void 0;
7439var didWarnAboutDefaultPropsOnFunctionComponent = void 0;
7440
7441{
7442 didWarnAboutBadClass = {};
7443 didWarnAboutModulePatternComponent = {};
7444 didWarnAboutContextTypeOnFunctionComponent = {};
7445 didWarnAboutGetDerivedStateOnFunctionComponent = {};
7446 didWarnAboutFunctionRefs = {};
7447 didWarnAboutReassigningProps = false;
7448 didWarnAboutMaxDuration = false;
7449 didWarnAboutRevealOrder = {};
7450 didWarnAboutTailOptions = {};
7451 didWarnAboutDefaultPropsOnFunctionComponent = {};
7452}
7453
7454function reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime) {
7455 if (current$$1 === null) {
7456 // If this is a fresh new component that hasn't been rendered yet, we
7457 // won't update its child set by applying minimal side-effects. Instead,
7458 // we will add them all to the child before it gets rendered. That means
7459 // we can optimize this reconciliation pass by not tracking side-effects.
7460 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7461 } else {
7462 // If the current child is the same as the work in progress, it means that
7463 // we haven't yet started any work on these children. Therefore, we use
7464 // the clone algorithm to create a copy of all the current children.
7465
7466 // If we had any progressed work already, that is invalid at this point so
7467 // let's throw it out.
7468 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, nextChildren, renderExpirationTime);
7469 }
7470}
7471
7472function forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime) {
7473 // This function is fork of reconcileChildren. It's used in cases where we
7474 // want to reconcile without matching against the existing set. This has the
7475 // effect of all current children being unmounted; even if the type and key
7476 // are the same, the old child is unmounted and a new child is created.
7477 //
7478 // To do this, we're going to go through the reconcile algorithm twice. In
7479 // the first pass, we schedule a deletion for all the current children by
7480 // passing null.
7481 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, null, renderExpirationTime);
7482 // In the second pass, we mount the new children. The trick here is that we
7483 // pass null in place of where we usually pass the current child set. This has
7484 // the effect of remounting all children regardless of whether their their
7485 // identity matches.
7486 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7487}
7488
7489function updateForwardRef(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
7490 // TODO: current can be non-null here even if the component
7491 // hasn't yet mounted. This happens after the first render suspends.
7492 // We'll need to figure out if this is fine or can cause issues.
7493
7494 {
7495 if (workInProgress.type !== workInProgress.elementType) {
7496 // Lazy component props can't be validated in createElement
7497 // because they're only guaranteed to be resolved here.
7498 var innerPropTypes = Component.propTypes;
7499 if (innerPropTypes) {
7500 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
7501 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7502 }
7503 }
7504 }
7505
7506 var render = Component.render;
7507 var ref = workInProgress.ref;
7508
7509 // The rest is a fork of updateFunctionComponent
7510 var nextChildren = void 0;
7511 prepareToReadContext(workInProgress, renderExpirationTime);
7512 {
7513 ReactCurrentOwner$2.current = workInProgress;
7514 setCurrentPhase('render');
7515 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
7516 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7517 // Only double-render components with Hooks
7518 if (workInProgress.memoizedState !== null) {
7519 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
7520 }
7521 }
7522 setCurrentPhase(null);
7523 }
7524
7525 if (current$$1 !== null && !didReceiveUpdate) {
7526 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
7527 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
7528 }
7529
7530 // React DevTools reads this flag.
7531 workInProgress.effectTag |= PerformedWork;
7532 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
7533 return workInProgress.child;
7534}
7535
7536function updateMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
7537 if (current$$1 === null) {
7538 var type = Component.type;
7539 if (isSimpleFunctionComponent(type) && Component.compare === null &&
7540 // SimpleMemoComponent codepath doesn't resolve outer props either.
7541 Component.defaultProps === undefined) {
7542 var resolvedType = type;
7543 {
7544 resolvedType = resolveFunctionForHotReloading(type);
7545 }
7546 // If this is a plain function component without default props,
7547 // and with only the default shallow comparison, we upgrade it
7548 // to a SimpleMemoComponent to allow fast path updates.
7549 workInProgress.tag = SimpleMemoComponent;
7550 workInProgress.type = resolvedType;
7551 {
7552 validateFunctionComponentInDev(workInProgress, type);
7553 }
7554 return updateSimpleMemoComponent(current$$1, workInProgress, resolvedType, nextProps, updateExpirationTime, renderExpirationTime);
7555 }
7556 {
7557 var innerPropTypes = type.propTypes;
7558 if (innerPropTypes) {
7559 // Inner memo component props aren't currently validated in createElement.
7560 // We could move it there, but we'd still need this for lazy code path.
7561 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
7562 'prop', getComponentName(type), getCurrentFiberStackInDev);
7563 }
7564 }
7565 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
7566 child.ref = workInProgress.ref;
7567 child.return = workInProgress;
7568 workInProgress.child = child;
7569 return child;
7570 }
7571 {
7572 var _type = Component.type;
7573 var _innerPropTypes = _type.propTypes;
7574 if (_innerPropTypes) {
7575 // Inner memo component props aren't currently validated in createElement.
7576 // We could move it there, but we'd still need this for lazy code path.
7577 checkPropTypes_1(_innerPropTypes, nextProps, // Resolved props
7578 'prop', getComponentName(_type), getCurrentFiberStackInDev);
7579 }
7580 }
7581 var currentChild = current$$1.child; // This is always exactly one child
7582 if (updateExpirationTime < renderExpirationTime) {
7583 // This will be the props with resolved defaultProps,
7584 // unlike current.memoizedProps which will be the unresolved ones.
7585 var prevProps = currentChild.memoizedProps;
7586 // Default to shallow comparison
7587 var compare = Component.compare;
7588 compare = compare !== null ? compare : shallowEqual;
7589 if (compare(prevProps, nextProps) && current$$1.ref === workInProgress.ref) {
7590 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
7591 }
7592 }
7593 // React DevTools reads this flag.
7594 workInProgress.effectTag |= PerformedWork;
7595 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
7596 newChild.ref = workInProgress.ref;
7597 newChild.return = workInProgress;
7598 workInProgress.child = newChild;
7599 return newChild;
7600}
7601
7602function updateSimpleMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
7603 // TODO: current can be non-null here even if the component
7604 // hasn't yet mounted. This happens when the inner render suspends.
7605 // We'll need to figure out if this is fine or can cause issues.
7606
7607 {
7608 if (workInProgress.type !== workInProgress.elementType) {
7609 // Lazy component props can't be validated in createElement
7610 // because they're only guaranteed to be resolved here.
7611 var outerMemoType = workInProgress.elementType;
7612 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
7613 // We warn when you define propTypes on lazy()
7614 // so let's just skip over it to find memo() outer wrapper.
7615 // Inner props for memo are validated later.
7616 outerMemoType = refineResolvedLazyComponent(outerMemoType);
7617 }
7618 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
7619 if (outerPropTypes) {
7620 checkPropTypes_1(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
7621 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
7622 }
7623 // Inner propTypes will be validated in the function component path.
7624 }
7625 }
7626 if (current$$1 !== null) {
7627 var prevProps = current$$1.memoizedProps;
7628 if (shallowEqual(prevProps, nextProps) && current$$1.ref === workInProgress.ref && (
7629 // Prevent bailout if the implementation changed due to hot reload:
7630 workInProgress.type === current$$1.type)) {
7631 didReceiveUpdate = false;
7632 if (updateExpirationTime < renderExpirationTime) {
7633 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
7634 }
7635 }
7636 }
7637 return updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
7638}
7639
7640function updateFragment(current$$1, workInProgress, renderExpirationTime) {
7641 var nextChildren = workInProgress.pendingProps;
7642 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
7643 return workInProgress.child;
7644}
7645
7646function updateMode(current$$1, workInProgress, renderExpirationTime) {
7647 var nextChildren = workInProgress.pendingProps.children;
7648 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
7649 return workInProgress.child;
7650}
7651
7652function updateProfiler(current$$1, workInProgress, renderExpirationTime) {
7653 if (enableProfilerTimer) {
7654 workInProgress.effectTag |= Update;
7655 }
7656 var nextProps = workInProgress.pendingProps;
7657 var nextChildren = nextProps.children;
7658 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
7659 return workInProgress.child;
7660}
7661
7662function markRef(current$$1, workInProgress) {
7663 var ref = workInProgress.ref;
7664 if (current$$1 === null && ref !== null || current$$1 !== null && current$$1.ref !== ref) {
7665 // Schedule a Ref effect
7666 workInProgress.effectTag |= Ref;
7667 }
7668}
7669
7670function updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
7671 {
7672 if (workInProgress.type !== workInProgress.elementType) {
7673 // Lazy component props can't be validated in createElement
7674 // because they're only guaranteed to be resolved here.
7675 var innerPropTypes = Component.propTypes;
7676 if (innerPropTypes) {
7677 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
7678 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7679 }
7680 }
7681 }
7682
7683 var context = void 0;
7684 if (!disableLegacyContext) {
7685 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
7686 context = getMaskedContext(workInProgress, unmaskedContext);
7687 }
7688
7689 var nextChildren = void 0;
7690 prepareToReadContext(workInProgress, renderExpirationTime);
7691 {
7692 ReactCurrentOwner$2.current = workInProgress;
7693 setCurrentPhase('render');
7694 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
7695 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7696 // Only double-render components with Hooks
7697 if (workInProgress.memoizedState !== null) {
7698 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
7699 }
7700 }
7701 setCurrentPhase(null);
7702 }
7703
7704 if (current$$1 !== null && !didReceiveUpdate) {
7705 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
7706 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
7707 }
7708
7709 // React DevTools reads this flag.
7710 workInProgress.effectTag |= PerformedWork;
7711 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
7712 return workInProgress.child;
7713}
7714
7715function updateClassComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
7716 {
7717 if (workInProgress.type !== workInProgress.elementType) {
7718 // Lazy component props can't be validated in createElement
7719 // because they're only guaranteed to be resolved here.
7720 var innerPropTypes = Component.propTypes;
7721 if (innerPropTypes) {
7722 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
7723 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7724 }
7725 }
7726 }
7727
7728 // Push context providers early to prevent context stack mismatches.
7729 // During mounting we don't know the child context yet as the instance doesn't exist.
7730 // We will invalidate the child context in finishClassComponent() right after rendering.
7731 var hasContext = void 0;
7732 if (isContextProvider(Component)) {
7733 hasContext = true;
7734 pushContextProvider(workInProgress);
7735 } else {
7736 hasContext = false;
7737 }
7738 prepareToReadContext(workInProgress, renderExpirationTime);
7739
7740 var instance = workInProgress.stateNode;
7741 var shouldUpdate = void 0;
7742 if (instance === null) {
7743 if (current$$1 !== null) {
7744 // An class component without an instance only mounts if it suspended
7745 // inside a non- concurrent tree, in an inconsistent state. We want to
7746 // tree it like a new mount, even though an empty version of it already
7747 // committed. Disconnect the alternate pointers.
7748 current$$1.alternate = null;
7749 workInProgress.alternate = null;
7750 // Since this is conceptually a new fiber, schedule a Placement effect
7751 workInProgress.effectTag |= Placement;
7752 }
7753 // In the initial pass we might need to construct the instance.
7754 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7755 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7756 shouldUpdate = true;
7757 } else if (current$$1 === null) {
7758 // In a resume, we'll already have an instance we can reuse.
7759 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7760 } else {
7761 shouldUpdate = updateClassInstance(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
7762 }
7763 var nextUnitOfWork = finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
7764 {
7765 var inst = workInProgress.stateNode;
7766 if (inst.props !== nextProps) {
7767 !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;
7768 didWarnAboutReassigningProps = true;
7769 }
7770 }
7771 return nextUnitOfWork;
7772}
7773
7774function finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
7775 // Refs should update even if shouldComponentUpdate returns false
7776 markRef(current$$1, workInProgress);
7777
7778 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
7779
7780 if (!shouldUpdate && !didCaptureError) {
7781 // Context providers should defer to sCU for rendering
7782 if (hasContext) {
7783 invalidateContextProvider(workInProgress, Component, false);
7784 }
7785
7786 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
7787 }
7788
7789 var instance = workInProgress.stateNode;
7790
7791 // Rerender
7792 ReactCurrentOwner$2.current = workInProgress;
7793 var nextChildren = void 0;
7794 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
7795 // If we captured an error, but getDerivedStateFrom catch is not defined,
7796 // unmount all the children. componentDidCatch will schedule an update to
7797 // re-render a fallback. This is temporary until we migrate everyone to
7798 // the new API.
7799 // TODO: Warn in a future release.
7800 nextChildren = null;
7801
7802 if (enableProfilerTimer) {
7803 stopProfilerTimerIfRunning(workInProgress);
7804 }
7805 } else {
7806 {
7807 setCurrentPhase('render');
7808 nextChildren = instance.render();
7809 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7810 instance.render();
7811 }
7812 setCurrentPhase(null);
7813 }
7814 }
7815
7816 // React DevTools reads this flag.
7817 workInProgress.effectTag |= PerformedWork;
7818 if (current$$1 !== null && didCaptureError) {
7819 // If we're recovering from an error, reconcile without reusing any of
7820 // the existing children. Conceptually, the normal children and the children
7821 // that are shown on error are two different sets, so we shouldn't reuse
7822 // normal children even if their identities match.
7823 forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime);
7824 } else {
7825 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
7826 }
7827
7828 // Memoize state using the values we just used to render.
7829 // TODO: Restructure so we never read values from the instance.
7830 workInProgress.memoizedState = instance.state;
7831
7832 // The context might have changed so we need to recalculate it.
7833 if (hasContext) {
7834 invalidateContextProvider(workInProgress, Component, true);
7835 }
7836
7837 return workInProgress.child;
7838}
7839
7840function pushHostRootContext(workInProgress) {
7841 var root = workInProgress.stateNode;
7842 if (root.pendingContext) {
7843 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
7844 } else if (root.context) {
7845 // Should always be set
7846 pushTopLevelContextObject(workInProgress, root.context, false);
7847 }
7848 pushHostContainer(workInProgress, root.containerInfo);
7849}
7850
7851function updateHostRoot(current$$1, workInProgress, renderExpirationTime) {
7852 pushHostRootContext(workInProgress);
7853 var updateQueue = workInProgress.updateQueue;
7854 (function () {
7855 if (!(updateQueue !== null)) {
7856 {
7857 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.'));
7858 }
7859 }
7860 })();
7861 var nextProps = workInProgress.pendingProps;
7862 var prevState = workInProgress.memoizedState;
7863 var prevChildren = prevState !== null ? prevState.element : null;
7864 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
7865 var nextState = workInProgress.memoizedState;
7866 // Caution: React DevTools currently depends on this property
7867 // being called "element".
7868 var nextChildren = nextState.element;
7869 if (nextChildren === prevChildren) {
7870 // If the state is the same as before, that's a bailout because we had
7871 // no work that expires at this time.
7872 resetHydrationState();
7873 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
7874 }
7875 var root = workInProgress.stateNode;
7876 if ((current$$1 === null || current$$1.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
7877 // If we don't have any current children this might be the first pass.
7878 // We always try to hydrate. If this isn't a hydration pass there won't
7879 // be any children to hydrate which is effectively the same thing as
7880 // not hydrating.
7881
7882 // This is a bit of a hack. We track the host root as a placement to
7883 // know that we're currently in a mounting state. That way isMounted
7884 // works as expected. We must reset this before committing.
7885 // TODO: Delete this when we delete isMounted and findDOMNode.
7886 workInProgress.effectTag |= Placement;
7887
7888 // Ensure that children mount into this root without tracking
7889 // side-effects. This ensures that we don't store Placement effects on
7890 // nodes that will be hydrated.
7891 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7892 } else {
7893 // Otherwise reset hydration state in case we aborted and resumed another
7894 // root.
7895 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
7896 resetHydrationState();
7897 }
7898 return workInProgress.child;
7899}
7900
7901function updateHostComponent(current$$1, workInProgress, renderExpirationTime) {
7902 pushHostContext(workInProgress);
7903
7904 if (current$$1 === null) {
7905 tryToClaimNextHydratableInstance(workInProgress);
7906 }
7907
7908 var type = workInProgress.type;
7909 var nextProps = workInProgress.pendingProps;
7910 var prevProps = current$$1 !== null ? current$$1.memoizedProps : null;
7911
7912 var nextChildren = nextProps.children;
7913 var isDirectTextChild = shouldSetTextContent(type, nextProps);
7914
7915 if (isDirectTextChild) {
7916 // We special case a direct text child of a host node. This is a common
7917 // case. We won't handle it as a reified child. We will instead handle
7918 // this in the host environment that also have access to this prop. That
7919 // avoids allocating another HostText fiber and traversing it.
7920 nextChildren = null;
7921 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
7922 // If we're switching from a direct text child to a normal child, or to
7923 // empty, we need to schedule the text content to be reset.
7924 workInProgress.effectTag |= ContentReset;
7925 }
7926
7927 markRef(current$$1, workInProgress);
7928
7929 // Check the host config to see if the children are offscreen/hidden.
7930 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(type, nextProps)) {
7931 if (enableSchedulerTracing) {
7932 markSpawnedWork(Never);
7933 }
7934 // Schedule this fiber to re-render at offscreen priority. Then bailout.
7935 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
7936 return null;
7937 }
7938
7939 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
7940 return workInProgress.child;
7941}
7942
7943function updateHostText(current$$1, workInProgress) {
7944 if (current$$1 === null) {
7945 tryToClaimNextHydratableInstance(workInProgress);
7946 }
7947 // Nothing to do here. This is terminal. We'll do the completion step
7948 // immediately after.
7949 return null;
7950}
7951
7952function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
7953 if (_current !== null) {
7954 // An lazy component only mounts if it suspended inside a non-
7955 // concurrent tree, in an inconsistent state. We want to treat it like
7956 // a new mount, even though an empty version of it already committed.
7957 // Disconnect the alternate pointers.
7958 _current.alternate = null;
7959 workInProgress.alternate = null;
7960 // Since this is conceptually a new fiber, schedule a Placement effect
7961 workInProgress.effectTag |= Placement;
7962 }
7963
7964 var props = workInProgress.pendingProps;
7965 // We can't start a User Timing measurement with correct label yet.
7966 // Cancel and resume right after we know the tag.
7967 cancelWorkTimer(workInProgress);
7968 var Component = readLazyComponentType(elementType);
7969 // Store the unwrapped component in the type.
7970 workInProgress.type = Component;
7971 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
7972 startWorkTimer(workInProgress);
7973 var resolvedProps = resolveDefaultProps(Component, props);
7974 var child = void 0;
7975 switch (resolvedTag) {
7976 case FunctionComponent:
7977 {
7978 {
7979 validateFunctionComponentInDev(workInProgress, Component);
7980 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
7981 }
7982 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7983 break;
7984 }
7985 case ClassComponent:
7986 {
7987 {
7988 workInProgress.type = Component = resolveClassForHotReloading(Component);
7989 }
7990 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7991 break;
7992 }
7993 case ForwardRef:
7994 {
7995 {
7996 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
7997 }
7998 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7999 break;
8000 }
8001 case MemoComponent:
8002 {
8003 {
8004 if (workInProgress.type !== workInProgress.elementType) {
8005 var outerPropTypes = Component.propTypes;
8006 if (outerPropTypes) {
8007 checkPropTypes_1(outerPropTypes, resolvedProps, // Resolved for outer only
8008 'prop', getComponentName(Component), getCurrentFiberStackInDev);
8009 }
8010 }
8011 }
8012 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
8013 updateExpirationTime, renderExpirationTime);
8014 break;
8015 }
8016 default:
8017 {
8018 var hint = '';
8019 {
8020 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
8021 hint = ' Did you wrap a component in React.lazy() more than once?';
8022 }
8023 }
8024 // This message intentionally doesn't mention ForwardRef or MemoComponent
8025 // because the fact that it's a separate type of work is an
8026 // implementation detail.
8027 (function () {
8028 {
8029 {
8030 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));
8031 }
8032 }
8033 })();
8034 }
8035 }
8036 return child;
8037}
8038
8039function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
8040 if (_current !== null) {
8041 // An incomplete component only mounts if it suspended inside a non-
8042 // concurrent tree, in an inconsistent state. We want to treat it like
8043 // a new mount, even though an empty version of it already committed.
8044 // Disconnect the alternate pointers.
8045 _current.alternate = null;
8046 workInProgress.alternate = null;
8047 // Since this is conceptually a new fiber, schedule a Placement effect
8048 workInProgress.effectTag |= Placement;
8049 }
8050
8051 // Promote the fiber to a class and try rendering again.
8052 workInProgress.tag = ClassComponent;
8053
8054 // The rest of this function is a fork of `updateClassComponent`
8055
8056 // Push context providers early to prevent context stack mismatches.
8057 // During mounting we don't know the child context yet as the instance doesn't exist.
8058 // We will invalidate the child context in finishClassComponent() right after rendering.
8059 var hasContext = void 0;
8060 if (isContextProvider(Component)) {
8061 hasContext = true;
8062 pushContextProvider(workInProgress);
8063 } else {
8064 hasContext = false;
8065 }
8066 prepareToReadContext(workInProgress, renderExpirationTime);
8067
8068 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8069 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8070
8071 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
8072}
8073
8074function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
8075 if (_current !== null) {
8076 // An indeterminate component only mounts if it suspended inside a non-
8077 // concurrent tree, in an inconsistent state. We want to treat it like
8078 // a new mount, even though an empty version of it already committed.
8079 // Disconnect the alternate pointers.
8080 _current.alternate = null;
8081 workInProgress.alternate = null;
8082 // Since this is conceptually a new fiber, schedule a Placement effect
8083 workInProgress.effectTag |= Placement;
8084 }
8085
8086 var props = workInProgress.pendingProps;
8087 var context = void 0;
8088 if (!disableLegacyContext) {
8089 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
8090 context = getMaskedContext(workInProgress, unmaskedContext);
8091 }
8092
8093 prepareToReadContext(workInProgress, renderExpirationTime);
8094 var value = void 0;
8095
8096 {
8097 if (Component.prototype && typeof Component.prototype.render === 'function') {
8098 var componentName = getComponentName(Component) || 'Unknown';
8099
8100 if (!didWarnAboutBadClass[componentName]) {
8101 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);
8102 didWarnAboutBadClass[componentName] = true;
8103 }
8104 }
8105
8106 if (workInProgress.mode & StrictMode) {
8107 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
8108 }
8109
8110 ReactCurrentOwner$2.current = workInProgress;
8111 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
8112 }
8113 // React DevTools reads this flag.
8114 workInProgress.effectTag |= PerformedWork;
8115
8116 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
8117 {
8118 var _componentName = getComponentName(Component) || 'Unknown';
8119 if (!didWarnAboutModulePatternComponent[_componentName]) {
8120 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);
8121 didWarnAboutModulePatternComponent[_componentName] = true;
8122 }
8123 }
8124
8125 // Proceed under the assumption that this is a class instance
8126 workInProgress.tag = ClassComponent;
8127
8128 // Throw out any hooks that were used.
8129 resetHooks();
8130
8131 // Push context providers early to prevent context stack mismatches.
8132 // During mounting we don't know the child context yet as the instance doesn't exist.
8133 // We will invalidate the child context in finishClassComponent() right after rendering.
8134 var hasContext = false;
8135 if (isContextProvider(Component)) {
8136 hasContext = true;
8137 pushContextProvider(workInProgress);
8138 } else {
8139 hasContext = false;
8140 }
8141
8142 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
8143
8144 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
8145 if (typeof getDerivedStateFromProps === 'function') {
8146 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
8147 }
8148
8149 adoptClassInstance(workInProgress, value);
8150 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
8151 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
8152 } else {
8153 // Proceed under the assumption that this is a function component
8154 workInProgress.tag = FunctionComponent;
8155 {
8156 if (disableLegacyContext && Component.contextTypes) {
8157 warningWithoutStack$1(false, '%s uses the legacy contextTypes API which is no longer supported. ' + 'Use React.createContext() with React.useContext() instead.', getComponentName(Component) || 'Unknown');
8158 }
8159
8160 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8161 // Only double-render components with Hooks
8162 if (workInProgress.memoizedState !== null) {
8163 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
8164 }
8165 }
8166 }
8167 reconcileChildren(null, workInProgress, value, renderExpirationTime);
8168 {
8169 validateFunctionComponentInDev(workInProgress, Component);
8170 }
8171 return workInProgress.child;
8172 }
8173}
8174
8175function validateFunctionComponentInDev(workInProgress, Component) {
8176 if (Component) {
8177 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
8178 }
8179 if (workInProgress.ref !== null) {
8180 var info = '';
8181 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
8182 if (ownerName) {
8183 info += '\n\nCheck the render method of `' + ownerName + '`.';
8184 }
8185
8186 var warningKey = ownerName || workInProgress._debugID || '';
8187 var debugSource = workInProgress._debugSource;
8188 if (debugSource) {
8189 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
8190 }
8191 if (!didWarnAboutFunctionRefs[warningKey]) {
8192 didWarnAboutFunctionRefs[warningKey] = true;
8193 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);
8194 }
8195 }
8196
8197 if (warnAboutDefaultPropsOnFunctionComponents && Component.defaultProps !== undefined) {
8198 var componentName = getComponentName(Component) || 'Unknown';
8199
8200 if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) {
8201 warningWithoutStack$1(false, '%s: Support for defaultProps will be removed from function components ' + 'in a future major release. Use JavaScript default parameters instead.', componentName);
8202 didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true;
8203 }
8204 }
8205
8206 if (typeof Component.getDerivedStateFromProps === 'function') {
8207 var _componentName2 = getComponentName(Component) || 'Unknown';
8208
8209 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) {
8210 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', _componentName2);
8211 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true;
8212 }
8213 }
8214
8215 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
8216 var _componentName3 = getComponentName(Component) || 'Unknown';
8217
8218 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) {
8219 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName3);
8220 didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true;
8221 }
8222 }
8223}
8224
8225// TODO: This is now an empty object. Should we just make it a boolean?
8226var SUSPENDED_MARKER = {};
8227
8228function shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) {
8229 // If the context is telling us that we should show a fallback, and we're not
8230 // already showing content, then we should show the fallback instead.
8231 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && (current$$1 === null || current$$1.memoizedState !== null);
8232}
8233
8234function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
8235 var mode = workInProgress.mode;
8236 var nextProps = workInProgress.pendingProps;
8237
8238 // This is used by DevTools to force a boundary to suspend.
8239 {
8240 if (shouldSuspend(workInProgress)) {
8241 workInProgress.effectTag |= DidCapture;
8242 }
8243 }
8244
8245 var suspenseContext = suspenseStackCursor.current;
8246
8247 var nextState = null;
8248 var nextDidTimeout = false;
8249
8250 if ((workInProgress.effectTag & DidCapture) !== NoEffect || shouldRemainOnFallback(suspenseContext, current$$1, workInProgress)) {
8251 // Something in this boundary's subtree already suspended. Switch to
8252 // rendering the fallback children.
8253 nextState = SUSPENDED_MARKER;
8254 nextDidTimeout = true;
8255 workInProgress.effectTag &= ~DidCapture;
8256 } else {
8257 // Attempting the main content
8258 if (current$$1 === null || current$$1.memoizedState !== null) {
8259 // This is a new mount or this boundary is already showing a fallback state.
8260 // Mark this subtree context as having at least one invisible parent that could
8261 // handle the fallback state.
8262 // Boundaries without fallbacks or should be avoided are not considered since
8263 // they cannot handle preferred fallback states.
8264 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {
8265 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
8266 }
8267 }
8268 }
8269
8270 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
8271
8272 pushSuspenseContext(workInProgress, suspenseContext);
8273
8274 {
8275 if ('maxDuration' in nextProps) {
8276 if (!didWarnAboutMaxDuration) {
8277 didWarnAboutMaxDuration = true;
8278 warning$1(false, 'maxDuration has been removed from React. ' + 'Remove the maxDuration prop.');
8279 }
8280 }
8281 }
8282
8283 // This next part is a bit confusing. If the children timeout, we switch to
8284 // showing the fallback children in place of the "primary" children.
8285 // However, we don't want to delete the primary children because then their
8286 // state will be lost (both the React state and the host state, e.g.
8287 // uncontrolled form inputs). Instead we keep them mounted and hide them.
8288 // Both the fallback children AND the primary children are rendered at the
8289 // same time. Once the primary children are un-suspended, we can delete
8290 // the fallback children — don't need to preserve their state.
8291 //
8292 // The two sets of children are siblings in the host environment, but
8293 // semantically, for purposes of reconciliation, they are two separate sets.
8294 // So we store them using two fragment fibers.
8295 //
8296 // However, we want to avoid allocating extra fibers for every placeholder.
8297 // They're only necessary when the children time out, because that's the
8298 // only time when both sets are mounted.
8299 //
8300 // So, the extra fragment fibers are only used if the children time out.
8301 // Otherwise, we render the primary children directly. This requires some
8302 // custom reconciliation logic to preserve the state of the primary
8303 // children. It's essentially a very basic form of re-parenting.
8304
8305 // `child` points to the child fiber. In the normal case, this is the first
8306 // fiber of the primary children set. In the timed-out case, it's a
8307 // a fragment fiber containing the primary children.
8308 var child = void 0;
8309 // `next` points to the next fiber React should render. In the normal case,
8310 // it's the same as `child`: the first fiber of the primary children set.
8311 // In the timed-out case, it's a fragment fiber containing the *fallback*
8312 // children -- we skip over the primary children entirely.
8313 var next = void 0;
8314 if (current$$1 === null) {
8315 if (enableSuspenseServerRenderer) {
8316 // If we're currently hydrating, try to hydrate this boundary.
8317 // But only if this has a fallback.
8318 if (nextProps.fallback !== undefined) {
8319 tryToClaimNextHydratableInstance(workInProgress);
8320 // This could've changed the tag if this was a dehydrated suspense component.
8321 if (workInProgress.tag === DehydratedSuspenseComponent) {
8322 popSuspenseContext(workInProgress);
8323 return updateDehydratedSuspenseComponent(null, workInProgress, renderExpirationTime);
8324 }
8325 }
8326 }
8327
8328 // This is the initial mount. This branch is pretty simple because there's
8329 // no previous state that needs to be preserved.
8330 if (nextDidTimeout) {
8331 // Mount separate fragments for primary and fallback children.
8332 var nextFallbackChildren = nextProps.fallback;
8333 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
8334 primaryChildFragment.return = workInProgress;
8335
8336 if ((workInProgress.mode & BatchedMode) === NoMode) {
8337 // Outside of batched mode, we commit the effects from the
8338 var progressedState = workInProgress.memoizedState;
8339 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
8340 primaryChildFragment.child = progressedPrimaryChild;
8341 var progressedChild = progressedPrimaryChild;
8342 while (progressedChild !== null) {
8343 progressedChild.return = primaryChildFragment;
8344 progressedChild = progressedChild.sibling;
8345 }
8346 }
8347
8348 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
8349 fallbackChildFragment.return = workInProgress;
8350 primaryChildFragment.sibling = fallbackChildFragment;
8351 child = primaryChildFragment;
8352 // Skip the primary children, and continue working on the
8353 // fallback children.
8354 next = fallbackChildFragment;
8355 } else {
8356 // Mount the primary children without an intermediate fragment fiber.
8357 var nextPrimaryChildren = nextProps.children;
8358 child = next = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
8359 }
8360 } else {
8361 // This is an update. This branch is more complicated because we need to
8362 // ensure the state of the primary children is preserved.
8363 var prevState = current$$1.memoizedState;
8364 var prevDidTimeout = prevState !== null;
8365 if (prevDidTimeout) {
8366 // The current tree already timed out. That means each child set is
8367 var currentPrimaryChildFragment = current$$1.child;
8368 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
8369 if (nextDidTimeout) {
8370 // Still timed out. Reuse the current primary children by cloning
8371 // its fragment. We're going to skip over these entirely.
8372 var _nextFallbackChildren = nextProps.fallback;
8373 var _primaryChildFragment = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
8374 _primaryChildFragment.return = workInProgress;
8375
8376 if ((workInProgress.mode & BatchedMode) === NoMode) {
8377 // Outside of batched mode, we commit the effects from the
8378 var _progressedState = workInProgress.memoizedState;
8379 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
8380 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
8381 _primaryChildFragment.child = _progressedPrimaryChild;
8382 var _progressedChild = _progressedPrimaryChild;
8383 while (_progressedChild !== null) {
8384 _progressedChild.return = _primaryChildFragment;
8385 _progressedChild = _progressedChild.sibling;
8386 }
8387 }
8388 }
8389
8390 // Because primaryChildFragment is a new fiber that we're inserting as the
8391 // parent of a new tree, we need to set its treeBaseDuration.
8392 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
8393 // treeBaseDuration is the sum of all the child tree base durations.
8394 var treeBaseDuration = 0;
8395 var hiddenChild = _primaryChildFragment.child;
8396 while (hiddenChild !== null) {
8397 treeBaseDuration += hiddenChild.treeBaseDuration;
8398 hiddenChild = hiddenChild.sibling;
8399 }
8400 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
8401 }
8402
8403 // Clone the fallback child fragment, too. These we'll continue
8404 // working on.
8405 var _fallbackChildFragment = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime);
8406 _fallbackChildFragment.return = workInProgress;
8407 _primaryChildFragment.sibling = _fallbackChildFragment;
8408 child = _primaryChildFragment;
8409 _primaryChildFragment.childExpirationTime = NoWork;
8410 // Skip the primary children, and continue working on the
8411 // fallback children.
8412 next = _fallbackChildFragment;
8413 } else {
8414 // No longer suspended. Switch back to showing the primary children,
8415 // and remove the intermediate fragment fiber.
8416 var _nextPrimaryChildren = nextProps.children;
8417 var currentPrimaryChild = currentPrimaryChildFragment.child;
8418 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime);
8419
8420 // If this render doesn't suspend, we need to delete the fallback
8421 // children. Wait until the complete phase, after we've confirmed the
8422 // fallback is no longer needed.
8423 // TODO: Would it be better to store the fallback fragment on
8424 // the stateNode?
8425
8426 // Continue rendering the children, like we normally do.
8427 child = next = primaryChild;
8428 }
8429 } else {
8430 // The current tree has not already timed out. That means the primary
8431 // children are not wrapped in a fragment fiber.
8432 var _currentPrimaryChild = current$$1.child;
8433 if (nextDidTimeout) {
8434 // Timed out. Wrap the children in a fragment fiber to keep them
8435 // separate from the fallback children.
8436 var _nextFallbackChildren2 = nextProps.fallback;
8437 var _primaryChildFragment2 = createFiberFromFragment(
8438 // It shouldn't matter what the pending props are because we aren't
8439 // going to render this fragment.
8440 null, mode, NoWork, null);
8441 _primaryChildFragment2.return = workInProgress;
8442 _primaryChildFragment2.child = _currentPrimaryChild;
8443 if (_currentPrimaryChild !== null) {
8444 _currentPrimaryChild.return = _primaryChildFragment2;
8445 }
8446
8447 // Even though we're creating a new fiber, there are no new children,
8448 // because we're reusing an already mounted tree. So we don't need to
8449 // schedule a placement.
8450 // primaryChildFragment.effectTag |= Placement;
8451
8452 if ((workInProgress.mode & BatchedMode) === NoMode) {
8453 // Outside of batched mode, we commit the effects from the
8454 var _progressedState2 = workInProgress.memoizedState;
8455 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
8456 _primaryChildFragment2.child = _progressedPrimaryChild2;
8457 var _progressedChild2 = _progressedPrimaryChild2;
8458 while (_progressedChild2 !== null) {
8459 _progressedChild2.return = _primaryChildFragment2;
8460 _progressedChild2 = _progressedChild2.sibling;
8461 }
8462 }
8463
8464 // Because primaryChildFragment is a new fiber that we're inserting as the
8465 // parent of a new tree, we need to set its treeBaseDuration.
8466 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
8467 // treeBaseDuration is the sum of all the child tree base durations.
8468 var _treeBaseDuration = 0;
8469 var _hiddenChild = _primaryChildFragment2.child;
8470 while (_hiddenChild !== null) {
8471 _treeBaseDuration += _hiddenChild.treeBaseDuration;
8472 _hiddenChild = _hiddenChild.sibling;
8473 }
8474 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
8475 }
8476
8477 // Create a fragment from the fallback children, too.
8478 var _fallbackChildFragment2 = createFiberFromFragment(_nextFallbackChildren2, mode, renderExpirationTime, null);
8479 _fallbackChildFragment2.return = workInProgress;
8480 _primaryChildFragment2.sibling = _fallbackChildFragment2;
8481 _fallbackChildFragment2.effectTag |= Placement;
8482 child = _primaryChildFragment2;
8483 _primaryChildFragment2.childExpirationTime = NoWork;
8484 // Skip the primary children, and continue working on the
8485 // fallback children.
8486 next = _fallbackChildFragment2;
8487 } else {
8488 // Still haven't timed out. Continue rendering the children, like we
8489 // normally do.
8490 var _nextPrimaryChildren2 = nextProps.children;
8491 next = child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
8492 }
8493 }
8494 workInProgress.stateNode = current$$1.stateNode;
8495 }
8496
8497 workInProgress.memoizedState = nextState;
8498 workInProgress.child = child;
8499 return next;
8500}
8501
8502function retrySuspenseComponentWithoutHydrating(current$$1, workInProgress, renderExpirationTime) {
8503 // Detach from the current dehydrated boundary.
8504 current$$1.alternate = null;
8505 workInProgress.alternate = null;
8506
8507 // Insert a deletion in the effect list.
8508 var returnFiber = workInProgress.return;
8509 (function () {
8510 if (!(returnFiber !== null)) {
8511 {
8512 throw ReactError(Error('Suspense boundaries are never on the root. This is probably a bug in React.'));
8513 }
8514 }
8515 })();
8516 var last = returnFiber.lastEffect;
8517 if (last !== null) {
8518 last.nextEffect = current$$1;
8519 returnFiber.lastEffect = current$$1;
8520 } else {
8521 returnFiber.firstEffect = returnFiber.lastEffect = current$$1;
8522 }
8523 current$$1.nextEffect = null;
8524 current$$1.effectTag = Deletion;
8525
8526 popSuspenseContext(workInProgress);
8527
8528 // Upgrade this work in progress to a real Suspense component.
8529 workInProgress.tag = SuspenseComponent;
8530 workInProgress.stateNode = null;
8531 workInProgress.memoizedState = null;
8532 // This is now an insertion.
8533 workInProgress.effectTag |= Placement;
8534 // Retry as a real Suspense component.
8535 return updateSuspenseComponent(null, workInProgress, renderExpirationTime);
8536}
8537
8538function updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
8539 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
8540 var suspenseInstance = workInProgress.stateNode;
8541 if (current$$1 === null) {
8542 // During the first pass, we'll bail out and not drill into the children.
8543 // Instead, we'll leave the content in place and try to hydrate it later.
8544 if (isSuspenseInstanceFallback(suspenseInstance)) {
8545 // This is a client-only boundary. Since we won't get any content from the server
8546 // for this, we need to schedule that at a higher priority based on when it would
8547 // have timed out. In theory we could render it in this pass but it would have the
8548 // wrong priority associated with it and will prevent hydration of parent path.
8549 // Instead, we'll leave work left on it to render it in a separate commit.
8550
8551 // TODO This time should be the time at which the server rendered response that is
8552 // a parent to this boundary was displayed. However, since we currently don't have
8553 // a protocol to transfer that time, we'll just estimate it by using the current
8554 // time. This will mean that Suspense timeouts are slightly shifted to later than
8555 // they should be.
8556 var serverDisplayTime = requestCurrentTime();
8557 // Schedule a normal pri update to render this content.
8558 workInProgress.expirationTime = computeAsyncExpiration(serverDisplayTime);
8559 } else {
8560 // We'll continue hydrating the rest at offscreen priority since we'll already
8561 // be showing the right content coming from the server, it is no rush.
8562 workInProgress.expirationTime = Never;
8563 }
8564 return null;
8565 }
8566 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
8567 // Something suspended. Leave the existing children in place.
8568 // TODO: In non-concurrent mode, should we commit the nodes we have hydrated so far?
8569 workInProgress.child = null;
8570 return null;
8571 }
8572 if (isSuspenseInstanceFallback(suspenseInstance)) {
8573 // This boundary is in a permanent fallback state. In this case, we'll never
8574 // get an update and we'll never be able to hydrate the final content. Let's just try the
8575 // client side render instead.
8576 return retrySuspenseComponentWithoutHydrating(current$$1, workInProgress, renderExpirationTime);
8577 }
8578 // We use childExpirationTime to indicate that a child might depend on context, so if
8579 // any context has changed, we need to treat is as if the input might have changed.
8580 var hasContextChanged$$1 = current$$1.childExpirationTime >= renderExpirationTime;
8581 if (didReceiveUpdate || hasContextChanged$$1) {
8582 // This boundary has changed since the first render. This means that we are now unable to
8583 // hydrate it. We might still be able to hydrate it using an earlier expiration time but
8584 // during this render we can't. Instead, we're going to delete the whole subtree and
8585 // instead inject a new real Suspense boundary to take its place, which may render content
8586 // or fallback. The real Suspense boundary will suspend for a while so we have some time
8587 // to ensure it can produce real content, but all state and pending events will be lost.
8588 return retrySuspenseComponentWithoutHydrating(current$$1, workInProgress, renderExpirationTime);
8589 } else if (isSuspenseInstancePending(suspenseInstance)) {
8590 // This component is still pending more data from the server, so we can't hydrate its
8591 // content. We treat it as if this component suspended itself. It might seem as if
8592 // we could just try to render it client-side instead. However, this will perform a
8593 // lot of unnecessary work and is unlikely to complete since it often will suspend
8594 // on missing data anyway. Additionally, the server might be able to render more
8595 // than we can on the client yet. In that case we'd end up with more fallback states
8596 // on the client than if we just leave it alone. If the server times out or errors
8597 // these should update this boundary to the permanent Fallback state instead.
8598 // Mark it as having captured (i.e. suspended).
8599 workInProgress.effectTag |= DidCapture;
8600 // Leave the children in place. I.e. empty.
8601 workInProgress.child = null;
8602 // Register a callback to retry this boundary once the server has sent the result.
8603 registerSuspenseInstanceRetry(suspenseInstance, retryTimedOutBoundary.bind(null, current$$1));
8604 return null;
8605 } else {
8606 // This is the first attempt.
8607 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress);
8608 var nextProps = workInProgress.pendingProps;
8609 var nextChildren = nextProps.children;
8610 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8611 return workInProgress.child;
8612 }
8613}
8614
8615function propagateSuspenseContextChange(workInProgress, firstChild, renderExpirationTime) {
8616 // Mark any Suspense boundaries with fallbacks as having work to do.
8617 // If they were previously forced into fallbacks, they may now be able
8618 // to unblock.
8619 var node = firstChild;
8620 while (node !== null) {
8621 if (node.tag === SuspenseComponent) {
8622 var state = node.memoizedState;
8623 if (state !== null) {
8624 if (node.expirationTime < renderExpirationTime) {
8625 node.expirationTime = renderExpirationTime;
8626 }
8627 var alternate = node.alternate;
8628 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
8629 alternate.expirationTime = renderExpirationTime;
8630 }
8631 scheduleWorkOnParentPath(node.return, renderExpirationTime);
8632 }
8633 } else if (node.child !== null) {
8634 node.child.return = node;
8635 node = node.child;
8636 continue;
8637 }
8638 if (node === workInProgress) {
8639 return;
8640 }
8641 while (node.sibling === null) {
8642 if (node.return === null || node.return === workInProgress) {
8643 return;
8644 }
8645 node = node.return;
8646 }
8647 node.sibling.return = node.return;
8648 node = node.sibling;
8649 }
8650}
8651
8652function findLastContentRow(firstChild) {
8653 // This is going to find the last row among these children that is already
8654 // showing content on the screen, as opposed to being in fallback state or
8655 // new. If a row has multiple Suspense boundaries, any of them being in the
8656 // fallback state, counts as the whole row being in a fallback state.
8657 // Note that the "rows" will be workInProgress, but any nested children
8658 // will still be current since we haven't rendered them yet. The mounted
8659 // order may not be the same as the new order. We use the new order.
8660 var row = firstChild;
8661 var lastContentRow = null;
8662 while (row !== null) {
8663 var currentRow = row.alternate;
8664 // New rows can't be content rows.
8665 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
8666 lastContentRow = row;
8667 }
8668 row = row.sibling;
8669 }
8670 return lastContentRow;
8671}
8672
8673function validateRevealOrder(revealOrder) {
8674 {
8675 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
8676 didWarnAboutRevealOrder[revealOrder] = true;
8677 if (typeof revealOrder === 'string') {
8678 switch (revealOrder.toLowerCase()) {
8679 case 'together':
8680 case 'forwards':
8681 case 'backwards':
8682 {
8683 warning$1(false, '"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
8684 break;
8685 }
8686 case 'forward':
8687 case 'backward':
8688 {
8689 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());
8690 break;
8691 }
8692 default:
8693 warning$1(false, '"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
8694 break;
8695 }
8696 } else {
8697 warning$1(false, '%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
8698 }
8699 }
8700 }
8701}
8702
8703function validateTailOptions(tailMode, revealOrder) {
8704 {
8705 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
8706 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
8707 didWarnAboutTailOptions[tailMode] = true;
8708 warning$1(false, '"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
8709 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
8710 didWarnAboutTailOptions[tailMode] = true;
8711 warning$1(false, '<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
8712 }
8713 }
8714 }
8715}
8716
8717function validateSuspenseListNestedChild(childSlot, index) {
8718 {
8719 var isArray = Array.isArray(childSlot);
8720 var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function';
8721 if (isArray || isIterable) {
8722 var type = isArray ? 'array' : 'iterable';
8723 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);
8724 return false;
8725 }
8726 }
8727 return true;
8728}
8729
8730function validateSuspenseListChildren(children, revealOrder) {
8731 {
8732 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
8733 if (Array.isArray(children)) {
8734 for (var i = 0; i < children.length; i++) {
8735 if (!validateSuspenseListNestedChild(children[i], i)) {
8736 return;
8737 }
8738 }
8739 } else {
8740 var iteratorFn = getIteratorFn(children);
8741 if (typeof iteratorFn === 'function') {
8742 var childrenIterator = iteratorFn.call(children);
8743 if (childrenIterator) {
8744 var step = childrenIterator.next();
8745 var _i = 0;
8746 for (; !step.done; step = childrenIterator.next()) {
8747 if (!validateSuspenseListNestedChild(step.value, _i)) {
8748 return;
8749 }
8750 _i++;
8751 }
8752 }
8753 } else {
8754 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);
8755 }
8756 }
8757 }
8758 }
8759}
8760
8761function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode) {
8762 var renderState = workInProgress.memoizedState;
8763 if (renderState === null) {
8764 workInProgress.memoizedState = {
8765 isBackwards: isBackwards,
8766 rendering: null,
8767 last: lastContentRow,
8768 tail: tail,
8769 tailExpiration: 0,
8770 tailMode: tailMode
8771 };
8772 } else {
8773 // We can reuse the existing object from previous renders.
8774 renderState.isBackwards = isBackwards;
8775 renderState.rendering = null;
8776 renderState.last = lastContentRow;
8777 renderState.tail = tail;
8778 renderState.tailExpiration = 0;
8779 renderState.tailMode = tailMode;
8780 }
8781}
8782
8783// This can end up rendering this component multiple passes.
8784// The first pass splits the children fibers into two sets. A head and tail.
8785// We first render the head. If anything is in fallback state, we do another
8786// pass through beginWork to rerender all children (including the tail) with
8787// the force suspend context. If the first render didn't have anything in
8788// in fallback state. Then we render each row in the tail one-by-one.
8789// That happens in the completeWork phase without going back to beginWork.
8790function updateSuspenseListComponent(current$$1, workInProgress, renderExpirationTime) {
8791 var nextProps = workInProgress.pendingProps;
8792 var revealOrder = nextProps.revealOrder;
8793 var tailMode = nextProps.tail;
8794 var newChildren = nextProps.children;
8795
8796 validateRevealOrder(revealOrder);
8797 validateTailOptions(tailMode, revealOrder);
8798 validateSuspenseListChildren(newChildren, revealOrder);
8799
8800 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
8801
8802 var suspenseContext = suspenseStackCursor.current;
8803
8804 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
8805 if (shouldForceFallback) {
8806 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
8807 workInProgress.effectTag |= DidCapture;
8808 } else {
8809 var didSuspendBefore = current$$1 !== null && (current$$1.effectTag & DidCapture) !== NoEffect;
8810 if (didSuspendBefore) {
8811 // If we previously forced a fallback, we need to schedule work
8812 // on any nested boundaries to let them know to try to render
8813 // again. This is the same as context updating.
8814 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderExpirationTime);
8815 }
8816 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
8817 }
8818 pushSuspenseContext(workInProgress, suspenseContext);
8819
8820 if ((workInProgress.mode & BatchedMode) === NoMode) {
8821 // Outside of batched mode, SuspenseList doesn't work so we just
8822 // use make it a noop by treating it as the default revealOrder.
8823 workInProgress.memoizedState = null;
8824 } else {
8825 switch (revealOrder) {
8826 case 'forwards':
8827 {
8828 var lastContentRow = findLastContentRow(workInProgress.child);
8829 var tail = void 0;
8830 if (lastContentRow === null) {
8831 // The whole list is part of the tail.
8832 // TODO: We could fast path by just rendering the tail now.
8833 tail = workInProgress.child;
8834 workInProgress.child = null;
8835 } else {
8836 // Disconnect the tail rows after the content row.
8837 // We're going to render them separately later.
8838 tail = lastContentRow.sibling;
8839 lastContentRow.sibling = null;
8840 }
8841 initSuspenseListRenderState(workInProgress, false, // isBackwards
8842 tail, lastContentRow, tailMode);
8843 break;
8844 }
8845 case 'backwards':
8846 {
8847 // We're going to find the first row that has existing content.
8848 // At the same time we're going to reverse the list of everything
8849 // we pass in the meantime. That's going to be our tail in reverse
8850 // order.
8851 var _tail = null;
8852 var row = workInProgress.child;
8853 workInProgress.child = null;
8854 while (row !== null) {
8855 var currentRow = row.alternate;
8856 // New rows can't be content rows.
8857 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
8858 // This is the beginning of the main content.
8859 workInProgress.child = row;
8860 break;
8861 }
8862 var nextRow = row.sibling;
8863 row.sibling = _tail;
8864 _tail = row;
8865 row = nextRow;
8866 }
8867 // TODO: If workInProgress.child is null, we can continue on the tail immediately.
8868 initSuspenseListRenderState(workInProgress, true, // isBackwards
8869 _tail, null, // last
8870 tailMode);
8871 break;
8872 }
8873 case 'together':
8874 {
8875 initSuspenseListRenderState(workInProgress, false, // isBackwards
8876 null, // tail
8877 null, // last
8878 undefined);
8879 break;
8880 }
8881 default:
8882 {
8883 // The default reveal order is the same as not having
8884 // a boundary.
8885 workInProgress.memoizedState = null;
8886 }
8887 }
8888 }
8889 return workInProgress.child;
8890}
8891
8892function updatePortalComponent(current$$1, workInProgress, renderExpirationTime) {
8893 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
8894 var nextChildren = workInProgress.pendingProps;
8895 if (current$$1 === null) {
8896 // Portals are special because we don't append the children during mount
8897 // but at commit. Therefore we need to track insertions which the normal
8898 // flow doesn't do during mount. This doesn't happen at the root because
8899 // the root always starts with a "current" with a null child.
8900 // TODO: Consider unifying this with how the root works.
8901 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8902 } else {
8903 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
8904 }
8905 return workInProgress.child;
8906}
8907
8908function updateContextProvider(current$$1, workInProgress, renderExpirationTime) {
8909 var providerType = workInProgress.type;
8910 var context = providerType._context;
8911
8912 var newProps = workInProgress.pendingProps;
8913 var oldProps = workInProgress.memoizedProps;
8914
8915 var newValue = newProps.value;
8916
8917 {
8918 var providerPropTypes = workInProgress.type.propTypes;
8919
8920 if (providerPropTypes) {
8921 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
8922 }
8923 }
8924
8925 pushProvider(workInProgress, newValue);
8926
8927 if (oldProps !== null) {
8928 var oldValue = oldProps.value;
8929 var changedBits = calculateChangedBits(context, newValue, oldValue);
8930 if (changedBits === 0) {
8931 // No change. Bailout early if children are the same.
8932 if (oldProps.children === newProps.children && !hasContextChanged()) {
8933 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
8934 }
8935 } else {
8936 // The context value changed. Search for matching consumers and schedule
8937 // them to update.
8938 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
8939 }
8940 }
8941
8942 var newChildren = newProps.children;
8943 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
8944 return workInProgress.child;
8945}
8946
8947var hasWarnedAboutUsingContextAsConsumer = false;
8948
8949function updateContextConsumer(current$$1, workInProgress, renderExpirationTime) {
8950 var context = workInProgress.type;
8951 // The logic below for Context differs depending on PROD or DEV mode. In
8952 // DEV mode, we create a separate object for Context.Consumer that acts
8953 // like a proxy to Context. This proxy object adds unnecessary code in PROD
8954 // so we use the old behaviour (Context.Consumer references Context) to
8955 // reduce size and overhead. The separate object references context via
8956 // a property called "_context", which also gives us the ability to check
8957 // in DEV mode if this property exists or not and warn if it does not.
8958 {
8959 if (context._context === undefined) {
8960 // This may be because it's a Context (rather than a Consumer).
8961 // Or it may be because it's older React where they're the same thing.
8962 // We only want to warn if we're sure it's a new React.
8963 if (context !== context.Consumer) {
8964 if (!hasWarnedAboutUsingContextAsConsumer) {
8965 hasWarnedAboutUsingContextAsConsumer = true;
8966 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?');
8967 }
8968 }
8969 } else {
8970 context = context._context;
8971 }
8972 }
8973 var newProps = workInProgress.pendingProps;
8974 var render = newProps.children;
8975
8976 {
8977 !(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;
8978 }
8979
8980 prepareToReadContext(workInProgress, renderExpirationTime);
8981 var newValue = readContext(context, newProps.unstable_observedBits);
8982 var newChildren = void 0;
8983 {
8984 ReactCurrentOwner$2.current = workInProgress;
8985 setCurrentPhase('render');
8986 newChildren = render(newValue);
8987 setCurrentPhase(null);
8988 }
8989
8990 // React DevTools reads this flag.
8991 workInProgress.effectTag |= PerformedWork;
8992 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
8993 return workInProgress.child;
8994}
8995
8996function updateFundamentalComponent$1(current$$1, workInProgress, renderExpirationTime) {
8997 var fundamentalImpl = workInProgress.type.impl;
8998 if (fundamentalImpl.reconcileChildren === false) {
8999 return null;
9000 }
9001 var nextProps = workInProgress.pendingProps;
9002 var nextChildren = nextProps.children;
9003
9004 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
9005 return workInProgress.child;
9006}
9007
9008function markWorkInProgressReceivedUpdate() {
9009 didReceiveUpdate = true;
9010}
9011
9012function bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime) {
9013 cancelWorkTimer(workInProgress);
9014
9015 if (current$$1 !== null) {
9016 // Reuse previous dependencies
9017 workInProgress.dependencies = current$$1.dependencies;
9018 }
9019
9020 if (enableProfilerTimer) {
9021 // Don't update "base" render times for bailouts.
9022 stopProfilerTimerIfRunning(workInProgress);
9023 }
9024
9025 // Check if the children have any pending work.
9026 var childExpirationTime = workInProgress.childExpirationTime;
9027 if (childExpirationTime < renderExpirationTime) {
9028 // The children don't have any work either. We can skip them.
9029 // TODO: Once we add back resuming, we should check if the children are
9030 // a work-in-progress set. If so, we need to transfer their effects.
9031 return null;
9032 } else {
9033 // This fiber doesn't have work, but its subtree does. Clone the child
9034 // fibers and continue.
9035 cloneChildFibers(current$$1, workInProgress);
9036 return workInProgress.child;
9037 }
9038}
9039
9040function remountFiber(current$$1, oldWorkInProgress, newWorkInProgress) {
9041 {
9042 var returnFiber = oldWorkInProgress.return;
9043 if (returnFiber === null) {
9044 throw new Error('Cannot swap the root fiber.');
9045 }
9046
9047 // Disconnect from the old current.
9048 // It will get deleted.
9049 current$$1.alternate = null;
9050 oldWorkInProgress.alternate = null;
9051
9052 // Connect to the new tree.
9053 newWorkInProgress.index = oldWorkInProgress.index;
9054 newWorkInProgress.sibling = oldWorkInProgress.sibling;
9055 newWorkInProgress.return = oldWorkInProgress.return;
9056 newWorkInProgress.ref = oldWorkInProgress.ref;
9057
9058 // Replace the child/sibling pointers above it.
9059 if (oldWorkInProgress === returnFiber.child) {
9060 returnFiber.child = newWorkInProgress;
9061 } else {
9062 var prevSibling = returnFiber.child;
9063 if (prevSibling === null) {
9064 throw new Error('Expected parent to have a child.');
9065 }
9066 while (prevSibling.sibling !== oldWorkInProgress) {
9067 prevSibling = prevSibling.sibling;
9068 if (prevSibling === null) {
9069 throw new Error('Expected to find the previous sibling.');
9070 }
9071 }
9072 prevSibling.sibling = newWorkInProgress;
9073 }
9074
9075 // Delete the old fiber and place the new one.
9076 // Since the old fiber is disconnected, we have to schedule it manually.
9077 var last = returnFiber.lastEffect;
9078 if (last !== null) {
9079 last.nextEffect = current$$1;
9080 returnFiber.lastEffect = current$$1;
9081 } else {
9082 returnFiber.firstEffect = returnFiber.lastEffect = current$$1;
9083 }
9084 current$$1.nextEffect = null;
9085 current$$1.effectTag = Deletion;
9086
9087 newWorkInProgress.effectTag |= Placement;
9088
9089 // Restart work from the new fiber.
9090 return newWorkInProgress;
9091 }
9092}
9093
9094function beginWork$1(current$$1, workInProgress, renderExpirationTime) {
9095 var updateExpirationTime = workInProgress.expirationTime;
9096
9097 {
9098 if (workInProgress._debugNeedsRemount && current$$1 !== null) {
9099 // This will restart the begin phase with a new fiber.
9100 return remountFiber(current$$1, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.expirationTime));
9101 }
9102 }
9103
9104 if (current$$1 !== null) {
9105 var oldProps = current$$1.memoizedProps;
9106 var newProps = workInProgress.pendingProps;
9107
9108 if (oldProps !== newProps || hasContextChanged() || (
9109 // Force a re-render if the implementation changed due to hot reload:
9110 workInProgress.type !== current$$1.type)) {
9111 // If props or context changed, mark the fiber as having performed work.
9112 // This may be unset if the props are determined to be equal later (memo).
9113 didReceiveUpdate = true;
9114 } else if (updateExpirationTime < renderExpirationTime) {
9115 didReceiveUpdate = false;
9116 // This fiber does not have any pending work. Bailout without entering
9117 // the begin phase. There's still some bookkeeping we that needs to be done
9118 // in this optimized path, mostly pushing stuff onto the stack.
9119 switch (workInProgress.tag) {
9120 case HostRoot:
9121 pushHostRootContext(workInProgress);
9122 resetHydrationState();
9123 break;
9124 case HostComponent:
9125 pushHostContext(workInProgress);
9126 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(workInProgress.type, newProps)) {
9127 if (enableSchedulerTracing) {
9128 markSpawnedWork(Never);
9129 }
9130 // Schedule this fiber to re-render at offscreen priority. Then bailout.
9131 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
9132 return null;
9133 }
9134 break;
9135 case ClassComponent:
9136 {
9137 var Component = workInProgress.type;
9138 if (isContextProvider(Component)) {
9139 pushContextProvider(workInProgress);
9140 }
9141 break;
9142 }
9143 case HostPortal:
9144 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
9145 break;
9146 case ContextProvider:
9147 {
9148 var newValue = workInProgress.memoizedProps.value;
9149 pushProvider(workInProgress, newValue);
9150 break;
9151 }
9152 case Profiler:
9153 if (enableProfilerTimer) {
9154 workInProgress.effectTag |= Update;
9155 }
9156 break;
9157 case SuspenseComponent:
9158 {
9159 var state = workInProgress.memoizedState;
9160 var didTimeout = state !== null;
9161 if (didTimeout) {
9162 // If this boundary is currently timed out, we need to decide
9163 // whether to retry the primary children, or to skip over it and
9164 // go straight to the fallback. Check the priority of the primary
9165 var primaryChildFragment = workInProgress.child;
9166 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
9167 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
9168 // The primary children have pending work. Use the normal path
9169 // to attempt to render the primary children again.
9170 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
9171 } else {
9172 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
9173 // The primary children do not have pending work with sufficient
9174 // priority. Bailout.
9175 var child = bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
9176 if (child !== null) {
9177 // The fallback children have pending work. Skip over the
9178 // primary children and work on the fallback.
9179 return child.sibling;
9180 } else {
9181 return null;
9182 }
9183 }
9184 } else {
9185 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
9186 }
9187 break;
9188 }
9189 case DehydratedSuspenseComponent:
9190 {
9191 if (enableSuspenseServerRenderer) {
9192 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
9193 // We know that this component will suspend again because if it has
9194 // been unsuspended it has committed as a regular Suspense component.
9195 // If it needs to be retried, it should have work scheduled on it.
9196 workInProgress.effectTag |= DidCapture;
9197 }
9198 break;
9199 }
9200 case SuspenseListComponent:
9201 {
9202 var didSuspendBefore = (current$$1.effectTag & DidCapture) !== NoEffect;
9203
9204 var hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
9205
9206 if (didSuspendBefore) {
9207 if (hasChildWork) {
9208 // If something was in fallback state last time, and we have all the
9209 // same children then we're still in progressive loading state.
9210 // Something might get unblocked by state updates or retries in the
9211 // tree which will affect the tail. So we need to use the normal
9212 // path to compute the correct tail.
9213 return updateSuspenseListComponent(current$$1, workInProgress, renderExpirationTime);
9214 }
9215 // If none of the children had any work, that means that none of
9216 // them got retried so they'll still be blocked in the same way
9217 // as before. We can fast bail out.
9218 workInProgress.effectTag |= DidCapture;
9219 }
9220
9221 // If nothing suspended before and we're rendering the same children,
9222 // then the tail doesn't matter. Anything new that suspends will work
9223 // in the "together" mode, so we can continue from the state we had.
9224 var renderState = workInProgress.memoizedState;
9225 if (renderState !== null) {
9226 // Reset to the "together" mode in case we've started a different
9227 // update in the past but didn't complete it.
9228 renderState.rendering = null;
9229 renderState.tail = null;
9230 }
9231 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
9232
9233 if (hasChildWork) {
9234 break;
9235 } else {
9236 // If none of the children had any work, that means that none of
9237 // them got retried so they'll still be blocked in the same way
9238 // as before. We can fast bail out.
9239 return null;
9240 }
9241 }
9242 }
9243 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
9244 }
9245 } else {
9246 didReceiveUpdate = false;
9247 }
9248
9249 // Before entering the begin phase, clear the expiration time.
9250 workInProgress.expirationTime = NoWork;
9251
9252 switch (workInProgress.tag) {
9253 case IndeterminateComponent:
9254 {
9255 return mountIndeterminateComponent(current$$1, workInProgress, workInProgress.type, renderExpirationTime);
9256 }
9257 case LazyComponent:
9258 {
9259 var elementType = workInProgress.elementType;
9260 return mountLazyComponent(current$$1, workInProgress, elementType, updateExpirationTime, renderExpirationTime);
9261 }
9262 case FunctionComponent:
9263 {
9264 var _Component = workInProgress.type;
9265 var unresolvedProps = workInProgress.pendingProps;
9266 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
9267 return updateFunctionComponent(current$$1, workInProgress, _Component, resolvedProps, renderExpirationTime);
9268 }
9269 case ClassComponent:
9270 {
9271 var _Component2 = workInProgress.type;
9272 var _unresolvedProps = workInProgress.pendingProps;
9273 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
9274 return updateClassComponent(current$$1, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
9275 }
9276 case HostRoot:
9277 return updateHostRoot(current$$1, workInProgress, renderExpirationTime);
9278 case HostComponent:
9279 return updateHostComponent(current$$1, workInProgress, renderExpirationTime);
9280 case HostText:
9281 return updateHostText(current$$1, workInProgress);
9282 case SuspenseComponent:
9283 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
9284 case HostPortal:
9285 return updatePortalComponent(current$$1, workInProgress, renderExpirationTime);
9286 case ForwardRef:
9287 {
9288 var type = workInProgress.type;
9289 var _unresolvedProps2 = workInProgress.pendingProps;
9290 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
9291 return updateForwardRef(current$$1, workInProgress, type, _resolvedProps2, renderExpirationTime);
9292 }
9293 case Fragment:
9294 return updateFragment(current$$1, workInProgress, renderExpirationTime);
9295 case Mode:
9296 return updateMode(current$$1, workInProgress, renderExpirationTime);
9297 case Profiler:
9298 return updateProfiler(current$$1, workInProgress, renderExpirationTime);
9299 case ContextProvider:
9300 return updateContextProvider(current$$1, workInProgress, renderExpirationTime);
9301 case ContextConsumer:
9302 return updateContextConsumer(current$$1, workInProgress, renderExpirationTime);
9303 case MemoComponent:
9304 {
9305 var _type2 = workInProgress.type;
9306 var _unresolvedProps3 = workInProgress.pendingProps;
9307 // Resolve outer props first, then resolve inner props.
9308 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
9309 {
9310 if (workInProgress.type !== workInProgress.elementType) {
9311 var outerPropTypes = _type2.propTypes;
9312 if (outerPropTypes) {
9313 checkPropTypes_1(outerPropTypes, _resolvedProps3, // Resolved for outer only
9314 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
9315 }
9316 }
9317 }
9318 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
9319 return updateMemoComponent(current$$1, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
9320 }
9321 case SimpleMemoComponent:
9322 {
9323 return updateSimpleMemoComponent(current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
9324 }
9325 case IncompleteClassComponent:
9326 {
9327 var _Component3 = workInProgress.type;
9328 var _unresolvedProps4 = workInProgress.pendingProps;
9329 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
9330 return mountIncompleteClassComponent(current$$1, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
9331 }
9332 case DehydratedSuspenseComponent:
9333 {
9334 if (enableSuspenseServerRenderer) {
9335 return updateDehydratedSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
9336 }
9337 break;
9338 }
9339 case SuspenseListComponent:
9340 {
9341 return updateSuspenseListComponent(current$$1, workInProgress, renderExpirationTime);
9342 }
9343 case FundamentalComponent:
9344 {
9345 if (enableFundamentalAPI) {
9346 return updateFundamentalComponent$1(current$$1, workInProgress, renderExpirationTime);
9347 }
9348 break;
9349 }
9350 }
9351 (function () {
9352 {
9353 {
9354 throw ReactError(Error('Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.'));
9355 }
9356 }
9357 })();
9358}
9359
9360function createFundamentalStateInstance(currentFiber, props, impl, state) {
9361 return {
9362 currentFiber: currentFiber,
9363 impl: impl,
9364 instance: null,
9365 prevProps: null,
9366 props: props,
9367 state: state
9368 };
9369}
9370
9371var emptyObject = {};
9372var isArray$2 = Array.isArray;
9373
9374function markUpdate(workInProgress) {
9375 // Tag the fiber with an update effect. This turns a Placement into
9376 // a PlacementAndUpdate.
9377 workInProgress.effectTag |= Update;
9378}
9379
9380function markRef$1(workInProgress) {
9381 workInProgress.effectTag |= Ref;
9382}
9383
9384var appendAllChildren = void 0;
9385var updateHostContainer = void 0;
9386var updateHostComponent$1 = void 0;
9387var updateHostText$1 = void 0;
9388if (supportsMutation) {
9389 // Mutation mode
9390
9391 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
9392 // We only have the top Fiber that was created but we need recurse down its
9393 // children to find all the terminal nodes.
9394 var node = workInProgress.child;
9395 while (node !== null) {
9396 if (node.tag === HostComponent || node.tag === HostText) {
9397 appendInitialChild(parent, node.stateNode);
9398 } else if (node.tag === FundamentalComponent) {
9399 appendInitialChild(parent, node.stateNode.instance);
9400 } else if (node.tag === HostPortal) {
9401 // If we have a portal child, then we don't want to traverse
9402 // down its children. Instead, we'll get insertions from each child in
9403 // the portal directly.
9404 } else if (node.child !== null) {
9405 node.child.return = node;
9406 node = node.child;
9407 continue;
9408 }
9409 if (node === workInProgress) {
9410 return;
9411 }
9412 while (node.sibling === null) {
9413 if (node.return === null || node.return === workInProgress) {
9414 return;
9415 }
9416 node = node.return;
9417 }
9418 node.sibling.return = node.return;
9419 node = node.sibling;
9420 }
9421 };
9422
9423 updateHostContainer = function (workInProgress) {
9424 // Noop
9425 };
9426 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9427 // If we have an alternate, that means this is an update and we need to
9428 // schedule a side-effect to do the updates.
9429 var oldProps = current.memoizedProps;
9430 if (oldProps === newProps) {
9431 // In mutation mode, this is sufficient for a bailout because
9432 // we won't touch this node even if children changed.
9433 return;
9434 }
9435
9436 // If we get updated because one of our children updated, we don't
9437 // have newProps so we'll have to reuse them.
9438 // TODO: Split the update API as separate for the props vs. children.
9439 // Even better would be if children weren't special cased at all tho.
9440 var instance = workInProgress.stateNode;
9441 var currentHostContext = getHostContext();
9442 // TODO: Experiencing an error where oldProps is null. Suggests a host
9443 // component is hitting the resume path. Figure out why. Possibly
9444 // related to `hidden`.
9445 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9446 // TODO: Type this specific to this type of component.
9447 workInProgress.updateQueue = updatePayload;
9448 // If the update payload indicates that there is a change or if there
9449 // is a new ref we mark this as an update. All the work is done in commitWork.
9450 if (updatePayload) {
9451 markUpdate(workInProgress);
9452 }
9453 };
9454 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9455 // If the text differs, mark it as an update. All the work in done in commitWork.
9456 if (oldText !== newText) {
9457 markUpdate(workInProgress);
9458 }
9459 };
9460} else if (supportsPersistence) {
9461 // Persistent host tree mode
9462
9463 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
9464 // We only have the top Fiber that was created but we need recurse down its
9465 // children to find all the terminal nodes.
9466 var node = workInProgress.child;
9467 while (node !== null) {
9468 // eslint-disable-next-line no-labels
9469 branches: if (node.tag === HostComponent) {
9470 var instance = node.stateNode;
9471 if (needsVisibilityToggle && isHidden) {
9472 // This child is inside a timed out tree. Hide it.
9473 var props = node.memoizedProps;
9474 var type = node.type;
9475 instance = cloneHiddenInstance(instance, type, props, node);
9476 }
9477 appendInitialChild(parent, instance);
9478 } else if (node.tag === HostText) {
9479 var _instance = node.stateNode;
9480 if (needsVisibilityToggle && isHidden) {
9481 // This child is inside a timed out tree. Hide it.
9482 var text = node.memoizedProps;
9483 _instance = cloneHiddenTextInstance(_instance, text, node);
9484 }
9485 appendInitialChild(parent, _instance);
9486 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
9487 var _instance2 = node.stateNode.instance;
9488 if (needsVisibilityToggle && isHidden) {
9489 // This child is inside a timed out tree. Hide it.
9490 var _props = node.memoizedProps;
9491 var _type = node.type;
9492 _instance2 = cloneHiddenInstance(_instance2, _type, _props, node);
9493 }
9494 appendInitialChild(parent, _instance2);
9495 } else if (node.tag === HostPortal) {
9496 // If we have a portal child, then we don't want to traverse
9497 // down its children. Instead, we'll get insertions from each child in
9498 // the portal directly.
9499 } else if (node.tag === SuspenseComponent) {
9500 if ((node.effectTag & Update) !== NoEffect) {
9501 // Need to toggle the visibility of the primary children.
9502 var newIsHidden = node.memoizedState !== null;
9503 if (newIsHidden) {
9504 var primaryChildParent = node.child;
9505 if (primaryChildParent !== null) {
9506 if (primaryChildParent.child !== null) {
9507 primaryChildParent.child.return = primaryChildParent;
9508 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
9509 }
9510 var fallbackChildParent = primaryChildParent.sibling;
9511 if (fallbackChildParent !== null) {
9512 fallbackChildParent.return = node;
9513 node = fallbackChildParent;
9514 continue;
9515 }
9516 }
9517 }
9518 }
9519 if (node.child !== null) {
9520 // Continue traversing like normal
9521 node.child.return = node;
9522 node = node.child;
9523 continue;
9524 }
9525 } else if (node.child !== null) {
9526 node.child.return = node;
9527 node = node.child;
9528 continue;
9529 }
9530 // $FlowFixMe This is correct but Flow is confused by the labeled break.
9531 node = node;
9532 if (node === workInProgress) {
9533 return;
9534 }
9535 while (node.sibling === null) {
9536 if (node.return === null || node.return === workInProgress) {
9537 return;
9538 }
9539 node = node.return;
9540 }
9541 node.sibling.return = node.return;
9542 node = node.sibling;
9543 }
9544 };
9545
9546 // An unfortunate fork of appendAllChildren because we have two different parent types.
9547 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
9548 // We only have the top Fiber that was created but we need recurse down its
9549 // children to find all the terminal nodes.
9550 var node = workInProgress.child;
9551 while (node !== null) {
9552 // eslint-disable-next-line no-labels
9553 branches: if (node.tag === HostComponent) {
9554 var instance = node.stateNode;
9555 if (needsVisibilityToggle && isHidden) {
9556 // This child is inside a timed out tree. Hide it.
9557 var props = node.memoizedProps;
9558 var type = node.type;
9559 instance = cloneHiddenInstance(instance, type, props, node);
9560 }
9561 appendChildToContainerChildSet(containerChildSet, instance);
9562 } else if (node.tag === HostText) {
9563 var _instance3 = node.stateNode;
9564 if (needsVisibilityToggle && isHidden) {
9565 // This child is inside a timed out tree. Hide it.
9566 var text = node.memoizedProps;
9567 _instance3 = cloneHiddenTextInstance(_instance3, text, node);
9568 }
9569 appendChildToContainerChildSet(containerChildSet, _instance3);
9570 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
9571 var _instance4 = node.stateNode.instance;
9572 if (needsVisibilityToggle && isHidden) {
9573 // This child is inside a timed out tree. Hide it.
9574 var _props2 = node.memoizedProps;
9575 var _type2 = node.type;
9576 _instance4 = cloneHiddenInstance(_instance4, _type2, _props2, node);
9577 }
9578 appendChildToContainerChildSet(containerChildSet, _instance4);
9579 } else if (node.tag === HostPortal) {
9580 // If we have a portal child, then we don't want to traverse
9581 // down its children. Instead, we'll get insertions from each child in
9582 // the portal directly.
9583 } else if (node.tag === SuspenseComponent) {
9584 if ((node.effectTag & Update) !== NoEffect) {
9585 // Need to toggle the visibility of the primary children.
9586 var newIsHidden = node.memoizedState !== null;
9587 if (newIsHidden) {
9588 var primaryChildParent = node.child;
9589 if (primaryChildParent !== null) {
9590 if (primaryChildParent.child !== null) {
9591 primaryChildParent.child.return = primaryChildParent;
9592 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
9593 }
9594 var fallbackChildParent = primaryChildParent.sibling;
9595 if (fallbackChildParent !== null) {
9596 fallbackChildParent.return = node;
9597 node = fallbackChildParent;
9598 continue;
9599 }
9600 }
9601 }
9602 }
9603 if (node.child !== null) {
9604 // Continue traversing like normal
9605 node.child.return = node;
9606 node = node.child;
9607 continue;
9608 }
9609 } else if (node.child !== null) {
9610 node.child.return = node;
9611 node = node.child;
9612 continue;
9613 }
9614 // $FlowFixMe This is correct but Flow is confused by the labeled break.
9615 node = node;
9616 if (node === workInProgress) {
9617 return;
9618 }
9619 while (node.sibling === null) {
9620 if (node.return === null || node.return === workInProgress) {
9621 return;
9622 }
9623 node = node.return;
9624 }
9625 node.sibling.return = node.return;
9626 node = node.sibling;
9627 }
9628 };
9629 updateHostContainer = function (workInProgress) {
9630 var portalOrRoot = workInProgress.stateNode;
9631 var childrenUnchanged = workInProgress.firstEffect === null;
9632 if (childrenUnchanged) {
9633 // No changes, just reuse the existing instance.
9634 } else {
9635 var container = portalOrRoot.containerInfo;
9636 var newChildSet = createContainerChildSet(container);
9637 // If children might have changed, we have to add them all to the set.
9638 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
9639 portalOrRoot.pendingChildren = newChildSet;
9640 // Schedule an update on the container to swap out the container.
9641 markUpdate(workInProgress);
9642 finalizeContainerChildren(container, newChildSet);
9643 }
9644 };
9645 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9646 var currentInstance = current.stateNode;
9647 var oldProps = current.memoizedProps;
9648 // If there are no effects associated with this node, then none of our children had any updates.
9649 // This guarantees that we can reuse all of them.
9650 var childrenUnchanged = workInProgress.firstEffect === null;
9651 if (childrenUnchanged && oldProps === newProps) {
9652 // No changes, just reuse the existing instance.
9653 // Note that this might release a previous clone.
9654 workInProgress.stateNode = currentInstance;
9655 return;
9656 }
9657 var recyclableInstance = workInProgress.stateNode;
9658 var currentHostContext = getHostContext();
9659 var updatePayload = null;
9660 if (oldProps !== newProps) {
9661 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9662 }
9663 if (childrenUnchanged && updatePayload === null) {
9664 // No changes, just reuse the existing instance.
9665 // Note that this might release a previous clone.
9666 workInProgress.stateNode = currentInstance;
9667 return;
9668 }
9669 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
9670 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
9671 markUpdate(workInProgress);
9672 }
9673 workInProgress.stateNode = newInstance;
9674 if (childrenUnchanged) {
9675 // If there are no other effects in this tree, we need to flag this node as having one.
9676 // Even though we're not going to use it for anything.
9677 // Otherwise parents won't know that there are new children to propagate upwards.
9678 markUpdate(workInProgress);
9679 } else {
9680 // If children might have changed, we have to add them all to the set.
9681 appendAllChildren(newInstance, workInProgress, false, false);
9682 }
9683 };
9684 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9685 if (oldText !== newText) {
9686 // If the text content differs, we'll create a new text instance for it.
9687 var rootContainerInstance = getRootHostContainer();
9688 var currentHostContext = getHostContext();
9689 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
9690 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
9691 // This lets the parents know that at least one of their children has changed.
9692 markUpdate(workInProgress);
9693 }
9694 };
9695} else {
9696 // No host operations
9697 updateHostContainer = function (workInProgress) {
9698 // Noop
9699 };
9700 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9701 // Noop
9702 };
9703 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9704 // Noop
9705 };
9706}
9707
9708function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
9709 switch (renderState.tailMode) {
9710 case 'hidden':
9711 {
9712 // Any insertions at the end of the tail list after this point
9713 // should be invisible. If there are already mounted boundaries
9714 // anything before them are not considered for collapsing.
9715 // Therefore we need to go through the whole tail to find if
9716 // there are any.
9717 var tailNode = renderState.tail;
9718 var lastTailNode = null;
9719 while (tailNode !== null) {
9720 if (tailNode.alternate !== null) {
9721 lastTailNode = tailNode;
9722 }
9723 tailNode = tailNode.sibling;
9724 }
9725 // Next we're simply going to delete all insertions after the
9726 // last rendered item.
9727 if (lastTailNode === null) {
9728 // All remaining items in the tail are insertions.
9729 renderState.tail = null;
9730 } else {
9731 // Detach the insertion after the last node that was already
9732 // inserted.
9733 lastTailNode.sibling = null;
9734 }
9735 break;
9736 }
9737 case 'collapsed':
9738 {
9739 // Any insertions at the end of the tail list after this point
9740 // should be invisible. If there are already mounted boundaries
9741 // anything before them are not considered for collapsing.
9742 // Therefore we need to go through the whole tail to find if
9743 // there are any.
9744 var _tailNode = renderState.tail;
9745 var _lastTailNode = null;
9746 while (_tailNode !== null) {
9747 if (_tailNode.alternate !== null) {
9748 _lastTailNode = _tailNode;
9749 }
9750 _tailNode = _tailNode.sibling;
9751 }
9752 // Next we're simply going to delete all insertions after the
9753 // last rendered item.
9754 if (_lastTailNode === null) {
9755 // All remaining items in the tail are insertions.
9756 if (!hasRenderedATailFallback && renderState.tail !== null) {
9757 // We suspended during the head. We want to show at least one
9758 // row at the tail. So we'll keep on and cut off the rest.
9759 renderState.tail.sibling = null;
9760 } else {
9761 renderState.tail = null;
9762 }
9763 } else {
9764 // Detach the insertion after the last node that was already
9765 // inserted.
9766 _lastTailNode.sibling = null;
9767 }
9768 break;
9769 }
9770 }
9771}
9772
9773function completeWork(current, workInProgress, renderExpirationTime) {
9774 var newProps = workInProgress.pendingProps;
9775
9776 switch (workInProgress.tag) {
9777 case IndeterminateComponent:
9778 break;
9779 case LazyComponent:
9780 break;
9781 case SimpleMemoComponent:
9782 case FunctionComponent:
9783 break;
9784 case ClassComponent:
9785 {
9786 var Component = workInProgress.type;
9787 if (isContextProvider(Component)) {
9788 popContext(workInProgress);
9789 }
9790 break;
9791 }
9792 case HostRoot:
9793 {
9794 popHostContainer(workInProgress);
9795 popTopLevelContextObject(workInProgress);
9796 var fiberRoot = workInProgress.stateNode;
9797 if (fiberRoot.pendingContext) {
9798 fiberRoot.context = fiberRoot.pendingContext;
9799 fiberRoot.pendingContext = null;
9800 }
9801 if (current === null || current.child === null) {
9802 // If we hydrated, pop so that we can delete any remaining children
9803 // that weren't hydrated.
9804 popHydrationState(workInProgress);
9805 // This resets the hacky state to fix isMounted before committing.
9806 // TODO: Delete this when we delete isMounted and findDOMNode.
9807 workInProgress.effectTag &= ~Placement;
9808 }
9809 updateHostContainer(workInProgress);
9810 break;
9811 }
9812 case HostComponent:
9813 {
9814 popHostContext(workInProgress);
9815 var rootContainerInstance = getRootHostContainer();
9816 var type = workInProgress.type;
9817 if (current !== null && workInProgress.stateNode != null) {
9818 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
9819
9820 if (enableFlareAPI) {
9821 var prevListeners = current.memoizedProps.listeners;
9822 var nextListeners = newProps.listeners;
9823 var instance = workInProgress.stateNode;
9824 if (prevListeners !== nextListeners) {
9825 updateEventListeners(nextListeners, instance, rootContainerInstance, workInProgress);
9826 }
9827 }
9828
9829 if (current.ref !== workInProgress.ref) {
9830 markRef$1(workInProgress);
9831 }
9832 } else {
9833 if (!newProps) {
9834 (function () {
9835 if (!(workInProgress.stateNode !== null)) {
9836 {
9837 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.'));
9838 }
9839 }
9840 })();
9841 // This can happen when we abort work.
9842 break;
9843 }
9844
9845 var currentHostContext = getHostContext();
9846 // TODO: Move createInstance to beginWork and keep it on a context
9847 // "stack" as the parent. Then append children as we go in beginWork
9848 // or completeWork depending on we want to add then top->down or
9849 // bottom->up. Top->down is faster in IE11.
9850 var wasHydrated = popHydrationState(workInProgress);
9851 if (wasHydrated) {
9852 // TODO: Move this and createInstance step into the beginPhase
9853 // to consolidate.
9854 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
9855 // If changes to the hydrated node needs to be applied at the
9856 // commit-phase we mark this as such.
9857 markUpdate(workInProgress);
9858 }
9859 } else {
9860 var _instance5 = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
9861
9862 appendAllChildren(_instance5, workInProgress, false, false);
9863
9864 if (enableFlareAPI) {
9865 var listeners = newProps.listeners;
9866 if (listeners != null) {
9867 updateEventListeners(listeners, _instance5, rootContainerInstance, workInProgress);
9868 }
9869 }
9870
9871 // Certain renderers require commit-time effects for initial mount.
9872 // (eg DOM renderer supports auto-focus for certain elements).
9873 // Make sure such renderers get scheduled for later work.
9874 if (finalizeInitialChildren(_instance5, type, newProps, rootContainerInstance, currentHostContext)) {
9875 markUpdate(workInProgress);
9876 }
9877 workInProgress.stateNode = _instance5;
9878 }
9879
9880 if (workInProgress.ref !== null) {
9881 // If there is a ref on a host node we need to schedule a callback
9882 markRef$1(workInProgress);
9883 }
9884 }
9885 break;
9886 }
9887 case HostText:
9888 {
9889 var newText = newProps;
9890 if (current && workInProgress.stateNode != null) {
9891 var oldText = current.memoizedProps;
9892 // If we have an alternate, that means this is an update and we need
9893 // to schedule a side-effect to do the updates.
9894 updateHostText$1(current, workInProgress, oldText, newText);
9895 } else {
9896 if (typeof newText !== 'string') {
9897 (function () {
9898 if (!(workInProgress.stateNode !== null)) {
9899 {
9900 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.'));
9901 }
9902 }
9903 })();
9904 // This can happen when we abort work.
9905 }
9906 var _rootContainerInstance = getRootHostContainer();
9907 var _currentHostContext = getHostContext();
9908 var _wasHydrated = popHydrationState(workInProgress);
9909 if (_wasHydrated) {
9910 if (prepareToHydrateHostTextInstance(workInProgress)) {
9911 markUpdate(workInProgress);
9912 }
9913 } else {
9914 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
9915 }
9916 }
9917 break;
9918 }
9919 case ForwardRef:
9920 break;
9921 case SuspenseComponent:
9922 {
9923 popSuspenseContext(workInProgress);
9924 var nextState = workInProgress.memoizedState;
9925 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
9926 // Something suspended. Re-render with the fallback children.
9927 workInProgress.expirationTime = renderExpirationTime;
9928 // Do not reset the effect list.
9929 return workInProgress;
9930 }
9931
9932 var nextDidTimeout = nextState !== null;
9933 var prevDidTimeout = false;
9934 if (current === null) {
9935 // In cases where we didn't find a suitable hydration boundary we never
9936 // downgraded this to a DehydratedSuspenseComponent, but we still need to
9937 // pop the hydration state since we might be inside the insertion tree.
9938 popHydrationState(workInProgress);
9939 } else {
9940 var prevState = current.memoizedState;
9941 prevDidTimeout = prevState !== null;
9942 if (!nextDidTimeout && prevState !== null) {
9943 // We just switched from the fallback to the normal children.
9944 // Delete the fallback.
9945 // TODO: Would it be better to store the fallback fragment on
9946 var currentFallbackChild = current.child.sibling;
9947 if (currentFallbackChild !== null) {
9948 // Deletions go at the beginning of the return fiber's effect list
9949 var first = workInProgress.firstEffect;
9950 if (first !== null) {
9951 workInProgress.firstEffect = currentFallbackChild;
9952 currentFallbackChild.nextEffect = first;
9953 } else {
9954 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
9955 currentFallbackChild.nextEffect = null;
9956 }
9957 currentFallbackChild.effectTag = Deletion;
9958 }
9959 }
9960 }
9961
9962 if (nextDidTimeout && !prevDidTimeout) {
9963 // If this subtreee is running in batched mode we can suspend,
9964 // otherwise we won't suspend.
9965 // TODO: This will still suspend a synchronous tree if anything
9966 // in the concurrent tree already suspended during this render.
9967 // This is a known bug.
9968 if ((workInProgress.mode & BatchedMode) !== NoMode) {
9969 // TODO: Move this back to throwException because this is too late
9970 // if this is a large tree which is common for initial loads. We
9971 // don't know if we should restart a render or not until we get
9972 // this marker, and this is too late.
9973 // If this render already had a ping or lower pri updates,
9974 // and this is the first time we know we're going to suspend we
9975 // should be able to immediately restart from within throwException.
9976 var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true;
9977 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
9978 // If this was in an invisible tree or a new render, then showing
9979 // this boundary is ok.
9980 renderDidSuspend();
9981 } else {
9982 // Otherwise, we're going to have to hide content so we should
9983 // suspend for longer if possible.
9984 renderDidSuspendDelayIfPossible();
9985 }
9986 }
9987 }
9988
9989 if (supportsPersistence) {
9990 // TODO: Only schedule updates if not prevDidTimeout.
9991 if (nextDidTimeout) {
9992 // If this boundary just timed out, schedule an effect to attach a
9993 // retry listener to the proimse. This flag is also used to hide the
9994 // primary children.
9995 workInProgress.effectTag |= Update;
9996 }
9997 }
9998 if (supportsMutation) {
9999 // TODO: Only schedule updates if these values are non equal, i.e. it changed.
10000 if (nextDidTimeout || prevDidTimeout) {
10001 // If this boundary just timed out, schedule an effect to attach a
10002 // retry listener to the proimse. This flag is also used to hide the
10003 // primary children. In mutation mode, we also need the flag to
10004 // *unhide* children that were previously hidden, so check if the
10005 // is currently timed out, too.
10006 workInProgress.effectTag |= Update;
10007 }
10008 }
10009 if (enableSuspenseCallback && workInProgress.updateQueue !== null && workInProgress.memoizedProps.suspenseCallback != null) {
10010 // Always notify the callback
10011 workInProgress.effectTag |= Update;
10012 }
10013 break;
10014 }
10015 case Fragment:
10016 break;
10017 case Mode:
10018 break;
10019 case Profiler:
10020 break;
10021 case HostPortal:
10022 popHostContainer(workInProgress);
10023 updateHostContainer(workInProgress);
10024 break;
10025 case ContextProvider:
10026 // Pop provider fiber
10027 popProvider(workInProgress);
10028 break;
10029 case ContextConsumer:
10030 break;
10031 case MemoComponent:
10032 break;
10033 case IncompleteClassComponent:
10034 {
10035 // Same as class component case. I put it down here so that the tags are
10036 // sequential to ensure this switch is compiled to a jump table.
10037 var _Component = workInProgress.type;
10038 if (isContextProvider(_Component)) {
10039 popContext(workInProgress);
10040 }
10041 break;
10042 }
10043 case DehydratedSuspenseComponent:
10044 {
10045 if (enableSuspenseServerRenderer) {
10046 popSuspenseContext(workInProgress);
10047 if (current === null) {
10048 var _wasHydrated2 = popHydrationState(workInProgress);
10049 (function () {
10050 if (!_wasHydrated2) {
10051 {
10052 throw ReactError(Error('A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.'));
10053 }
10054 }
10055 })();
10056 if (enableSchedulerTracing) {
10057 markSpawnedWork(Never);
10058 }
10059 skipPastDehydratedSuspenseInstance(workInProgress);
10060 } else if ((workInProgress.effectTag & DidCapture) === NoEffect) {
10061 // This boundary did not suspend so it's now hydrated.
10062 // To handle any future suspense cases, we're going to now upgrade it
10063 // to a Suspense component. We detach it from the existing current fiber.
10064 current.alternate = null;
10065 workInProgress.alternate = null;
10066 workInProgress.tag = SuspenseComponent;
10067 workInProgress.memoizedState = null;
10068 workInProgress.stateNode = null;
10069 }
10070 }
10071 break;
10072 }
10073 case SuspenseListComponent:
10074 {
10075 popSuspenseContext(workInProgress);
10076
10077 var renderState = workInProgress.memoizedState;
10078
10079 if (renderState === null) {
10080 // We're running in the default, "independent" mode. We don't do anything
10081 // in this mode.
10082 break;
10083 }
10084
10085 var didSuspendAlready = (workInProgress.effectTag & DidCapture) !== NoEffect;
10086
10087 var renderedTail = renderState.rendering;
10088 if (renderedTail === null) {
10089 // We just rendered the head.
10090 if (!didSuspendAlready) {
10091 // This is the first pass. We need to figure out if anything is still
10092 // suspended in the rendered set.
10093
10094 // If new content unsuspended, but there's still some content that
10095 // didn't. Then we need to do a second pass that forces everything
10096 // to keep showing their fallbacks.
10097
10098 // We might be suspended if something in this render pass suspended, or
10099 // something in the previous committed pass suspended. Otherwise,
10100 // there's no chance so we can skip the expensive call to
10101 // findFirstSuspended.
10102 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.effectTag & DidCapture) === NoEffect);
10103 if (!cannotBeSuspended) {
10104 var row = workInProgress.child;
10105 while (row !== null) {
10106 var suspended = findFirstSuspended(row);
10107 if (suspended !== null) {
10108 didSuspendAlready = true;
10109 workInProgress.effectTag |= DidCapture;
10110 cutOffTailIfNeeded(renderState, false);
10111
10112 // If this is a newly suspended tree, it might not get committed as
10113 // part of the second pass. In that case nothing will subscribe to
10114 // its thennables. Instead, we'll transfer its thennables to the
10115 // SuspenseList so that it can retry if they resolve.
10116 // There might be multiple of these in the list but since we're
10117 // going to wait for all of them anyway, it doesn't really matter
10118 // which ones gets to ping. In theory we could get clever and keep
10119 // track of how many dependencies remain but it gets tricky because
10120 // in the meantime, we can add/remove/change items and dependencies.
10121 // We might bail out of the loop before finding any but that
10122 // doesn't matter since that means that the other boundaries that
10123 // we did find already has their listeners attached.
10124 var newThennables = suspended.updateQueue;
10125 if (newThennables !== null) {
10126 workInProgress.updateQueue = newThennables;
10127 workInProgress.effectTag |= Update;
10128 }
10129
10130 // Rerender the whole list, but this time, we'll force fallbacks
10131 // to stay in place.
10132 // Reset the effect list before doing the second pass since that's now invalid.
10133 workInProgress.firstEffect = workInProgress.lastEffect = null;
10134 // Reset the child fibers to their original state.
10135 resetChildFibers(workInProgress, renderExpirationTime);
10136
10137 // Set up the Suspense Context to force suspense and immediately
10138 // rerender the children.
10139 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
10140 return workInProgress.child;
10141 }
10142 row = row.sibling;
10143 }
10144 }
10145 } else {
10146 cutOffTailIfNeeded(renderState, false);
10147 }
10148 // Next we're going to render the tail.
10149 } else {
10150 // Append the rendered row to the child list.
10151 if (!didSuspendAlready) {
10152 var _suspended = findFirstSuspended(renderedTail);
10153 if (_suspended !== null) {
10154 workInProgress.effectTag |= DidCapture;
10155 didSuspendAlready = true;
10156 cutOffTailIfNeeded(renderState, true);
10157 // This might have been modified.
10158 if (renderState.tail === null && renderState.tailMode === 'hidden') {
10159 // We need to delete the row we just rendered.
10160 // Ensure we transfer the update queue to the parent.
10161 var _newThennables = _suspended.updateQueue;
10162 if (_newThennables !== null) {
10163 workInProgress.updateQueue = _newThennables;
10164 workInProgress.effectTag |= Update;
10165 }
10166 // Reset the effect list to what it w as before we rendered this
10167 // child. The nested children have already appended themselves.
10168 var lastEffect = workInProgress.lastEffect = renderState.lastEffect;
10169 // Remove any effects that were appended after this point.
10170 if (lastEffect !== null) {
10171 lastEffect.nextEffect = null;
10172 }
10173 // We're done.
10174 return null;
10175 }
10176 } else if (now() > renderState.tailExpiration && renderExpirationTime > Never) {
10177 // We have now passed our CPU deadline and we'll just give up further
10178 // attempts to render the main content and only render fallbacks.
10179 // The assumption is that this is usually faster.
10180 workInProgress.effectTag |= DidCapture;
10181 didSuspendAlready = true;
10182
10183 cutOffTailIfNeeded(renderState, false);
10184
10185 // Since nothing actually suspended, there will nothing to ping this
10186 // to get it started back up to attempt the next item. If we can show
10187 // them, then they really have the same priority as this render.
10188 // So we'll pick it back up the very next render pass once we've had
10189 // an opportunity to yield for paint.
10190
10191 var nextPriority = renderExpirationTime - 1;
10192 workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority;
10193 if (enableSchedulerTracing) {
10194 markSpawnedWork(nextPriority);
10195 }
10196 }
10197 }
10198 if (renderState.isBackwards) {
10199 // The effect list of the backwards tail will have been added
10200 // to the end. This breaks the guarantee that life-cycles fire in
10201 // sibling order but that isn't a strong guarantee promised by React.
10202 // Especially since these might also just pop in during future commits.
10203 // Append to the beginning of the list.
10204 renderedTail.sibling = workInProgress.child;
10205 workInProgress.child = renderedTail;
10206 } else {
10207 var previousSibling = renderState.last;
10208 if (previousSibling !== null) {
10209 previousSibling.sibling = renderedTail;
10210 } else {
10211 workInProgress.child = renderedTail;
10212 }
10213 renderState.last = renderedTail;
10214 }
10215 }
10216
10217 if (renderState.tail !== null) {
10218 // We still have tail rows to render.
10219 if (renderState.tailExpiration === 0) {
10220 // Heuristic for how long we're willing to spend rendering rows
10221 // until we just give up and show what we have so far.
10222 var TAIL_EXPIRATION_TIMEOUT_MS = 500;
10223 renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS;
10224 }
10225 // Pop a row.
10226 var next = renderState.tail;
10227 renderState.rendering = next;
10228 renderState.tail = next.sibling;
10229 renderState.lastEffect = workInProgress.lastEffect;
10230 next.sibling = null;
10231
10232 // Restore the context.
10233 // TODO: We can probably just avoid popping it instead and only
10234 // setting it the first time we go from not suspended to suspended.
10235 var suspenseContext = suspenseStackCursor.current;
10236 if (didSuspendAlready) {
10237 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
10238 } else {
10239 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
10240 }
10241 pushSuspenseContext(workInProgress, suspenseContext);
10242 // Do a pass over the next row.
10243 return next;
10244 }
10245 break;
10246 }
10247 case FundamentalComponent:
10248 {
10249 if (enableFundamentalAPI) {
10250 var fundamentalImpl = workInProgress.type.impl;
10251 var fundamentalInstance = workInProgress.stateNode;
10252
10253 if (fundamentalInstance === null) {
10254 var getInitialState = fundamentalImpl.getInitialState;
10255 var fundamentalState = void 0;
10256 if (getInitialState !== undefined) {
10257 fundamentalState = getInitialState(newProps);
10258 }
10259 fundamentalInstance = workInProgress.stateNode = createFundamentalStateInstance(workInProgress, newProps, fundamentalImpl, fundamentalState || {});
10260 var _instance6 = getFundamentalComponentInstance(fundamentalInstance);
10261 fundamentalInstance.instance = _instance6;
10262 if (fundamentalImpl.reconcileChildren === false) {
10263 return null;
10264 }
10265 appendAllChildren(_instance6, workInProgress, false, false);
10266 mountFundamentalComponent(fundamentalInstance);
10267 } else {
10268 // We fire update in commit phase
10269 var prevProps = fundamentalInstance.props;
10270 fundamentalInstance.prevProps = prevProps;
10271 fundamentalInstance.props = newProps;
10272 fundamentalInstance.currentFiber = workInProgress;
10273 if (supportsPersistence) {
10274 var _instance7 = cloneFundamentalInstance(fundamentalInstance);
10275 fundamentalInstance.instance = _instance7;
10276 appendAllChildren(_instance7, workInProgress, false, false);
10277 }
10278 var shouldUpdate = shouldUpdateFundamentalComponent(fundamentalInstance);
10279 if (shouldUpdate) {
10280 markUpdate(workInProgress);
10281 }
10282 }
10283 }
10284 break;
10285 }
10286 default:
10287 (function () {
10288 {
10289 {
10290 throw ReactError(Error('Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.'));
10291 }
10292 }
10293 })();
10294 }
10295
10296 return null;
10297}
10298
10299function mountEventResponder(responder, responderProps, instance, rootContainerInstance, fiber, respondersMap) {
10300 var responderState = emptyObject;
10301 var getInitialState = responder.getInitialState;
10302 if (getInitialState !== null) {
10303 responderState = getInitialState(responderProps);
10304 }
10305 var responderInstance = createResponderInstance(responder, responderProps, responderState, instance, fiber);
10306 respondersMap.set(responder, responderInstance);
10307}
10308
10309function updateEventListener(listener, fiber, visistedResponders, respondersMap, instance, rootContainerInstance) {
10310 var responder = void 0;
10311 var props = void 0;
10312
10313 if (listener) {
10314 responder = listener.responder;
10315 props = listener.props;
10316 }
10317 (function () {
10318 if (!(responder && responder.$$typeof === REACT_RESPONDER_TYPE)) {
10319 {
10320 throw ReactError(Error('An invalid value was used as an event listener. Expect one or many event listeners created via React.unstable_useResponer().'));
10321 }
10322 }
10323 })();
10324 var listenerProps = props;
10325 if (visistedResponders.has(responder)) {
10326 // show warning
10327 {
10328 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);
10329 }
10330 return;
10331 }
10332 visistedResponders.add(responder);
10333 var responderInstance = respondersMap.get(responder);
10334
10335 if (responderInstance === undefined) {
10336 // Mount
10337 mountEventResponder(responder, listenerProps, instance, rootContainerInstance, fiber, respondersMap);
10338 } else {
10339 // Update
10340 responderInstance.props = listenerProps;
10341 responderInstance.fiber = fiber;
10342 }
10343}
10344
10345function updateEventListeners(listeners, instance, rootContainerInstance, fiber) {
10346 var visistedResponders = new Set();
10347 var dependencies = fiber.dependencies;
10348 if (listeners != null) {
10349 if (dependencies === null) {
10350 dependencies = fiber.dependencies = {
10351 expirationTime: NoWork,
10352 firstContext: null,
10353 responders: new Map()
10354 };
10355 }
10356 var respondersMap = dependencies.responders;
10357 if (respondersMap === null) {
10358 respondersMap = new Map();
10359 }
10360 if (isArray$2(listeners)) {
10361 for (var i = 0, length = listeners.length; i < length; i++) {
10362 var listener = listeners[i];
10363 updateEventListener(listener, fiber, visistedResponders, respondersMap, instance, rootContainerInstance);
10364 }
10365 } else {
10366 updateEventListener(listeners, fiber, visistedResponders, respondersMap, instance, rootContainerInstance);
10367 }
10368 }
10369 if (dependencies !== null) {
10370 var _respondersMap = dependencies.responders;
10371 if (_respondersMap !== null) {
10372 // Unmount
10373 var mountedResponders = Array.from(_respondersMap.keys());
10374 for (var _i = 0, _length = mountedResponders.length; _i < _length; _i++) {
10375 var mountedResponder = mountedResponders[_i];
10376 if (!visistedResponders.has(mountedResponder)) {
10377 var responderInstance = _respondersMap.get(mountedResponder);
10378 _respondersMap.delete(mountedResponder);
10379 }
10380 }
10381 }
10382 }
10383}
10384
10385function unwindWork(workInProgress, renderExpirationTime) {
10386 switch (workInProgress.tag) {
10387 case ClassComponent:
10388 {
10389 var Component = workInProgress.type;
10390 if (isContextProvider(Component)) {
10391 popContext(workInProgress);
10392 }
10393 var effectTag = workInProgress.effectTag;
10394 if (effectTag & ShouldCapture) {
10395 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
10396 return workInProgress;
10397 }
10398 return null;
10399 }
10400 case HostRoot:
10401 {
10402 popHostContainer(workInProgress);
10403 popTopLevelContextObject(workInProgress);
10404 var _effectTag = workInProgress.effectTag;
10405 (function () {
10406 if (!((_effectTag & DidCapture) === NoEffect)) {
10407 {
10408 throw ReactError(Error('The root failed to unmount after an error. This is likely a bug in React. Please file an issue.'));
10409 }
10410 }
10411 })();
10412 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
10413 return workInProgress;
10414 }
10415 case HostComponent:
10416 {
10417 // TODO: popHydrationState
10418 popHostContext(workInProgress);
10419 return null;
10420 }
10421 case SuspenseComponent:
10422 {
10423 popSuspenseContext(workInProgress);
10424 var _effectTag2 = workInProgress.effectTag;
10425 if (_effectTag2 & ShouldCapture) {
10426 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture;
10427 // Captured a suspense effect. Re-render the boundary.
10428 return workInProgress;
10429 }
10430 return null;
10431 }
10432 case DehydratedSuspenseComponent:
10433 {
10434 if (enableSuspenseServerRenderer) {
10435 // TODO: popHydrationState
10436 popSuspenseContext(workInProgress);
10437 var _effectTag3 = workInProgress.effectTag;
10438 if (_effectTag3 & ShouldCapture) {
10439 workInProgress.effectTag = _effectTag3 & ~ShouldCapture | DidCapture;
10440 // Captured a suspense effect. Re-render the boundary.
10441 return workInProgress;
10442 }
10443 }
10444 return null;
10445 }
10446 case SuspenseListComponent:
10447 {
10448 popSuspenseContext(workInProgress);
10449 // SuspenseList doesn't actually catch anything. It should've been
10450 // caught by a nested boundary. If not, it should bubble through.
10451 return null;
10452 }
10453 case HostPortal:
10454 popHostContainer(workInProgress);
10455 return null;
10456 case ContextProvider:
10457 popProvider(workInProgress);
10458 return null;
10459 default:
10460 return null;
10461 }
10462}
10463
10464function unwindInterruptedWork(interruptedWork) {
10465 switch (interruptedWork.tag) {
10466 case ClassComponent:
10467 {
10468 var childContextTypes = interruptedWork.type.childContextTypes;
10469 if (childContextTypes !== null && childContextTypes !== undefined) {
10470 popContext(interruptedWork);
10471 }
10472 break;
10473 }
10474 case HostRoot:
10475 {
10476 popHostContainer(interruptedWork);
10477 popTopLevelContextObject(interruptedWork);
10478 break;
10479 }
10480 case HostComponent:
10481 {
10482 popHostContext(interruptedWork);
10483 break;
10484 }
10485 case HostPortal:
10486 popHostContainer(interruptedWork);
10487 break;
10488 case SuspenseComponent:
10489 popSuspenseContext(interruptedWork);
10490 break;
10491 case DehydratedSuspenseComponent:
10492 if (enableSuspenseServerRenderer) {
10493 // TODO: popHydrationState
10494 popSuspenseContext(interruptedWork);
10495 }
10496 break;
10497 case SuspenseListComponent:
10498 popSuspenseContext(interruptedWork);
10499 break;
10500 case ContextProvider:
10501 popProvider(interruptedWork);
10502 break;
10503 default:
10504 break;
10505 }
10506}
10507
10508function createCapturedValue(value, source) {
10509 // If the value is an error, call this function immediately after it is thrown
10510 // so the stack is accurate.
10511 return {
10512 value: value,
10513 source: source,
10514 stack: getStackByFiberInDevAndProd(source)
10515 };
10516}
10517
10518var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
10519 var funcArgs = Array.prototype.slice.call(arguments, 3);
10520 try {
10521 func.apply(context, funcArgs);
10522 } catch (error) {
10523 this.onError(error);
10524 }
10525};
10526
10527{
10528 // In DEV mode, we swap out invokeGuardedCallback for a special version
10529 // that plays more nicely with the browser's DevTools. The idea is to preserve
10530 // "Pause on exceptions" behavior. Because React wraps all user-provided
10531 // functions in invokeGuardedCallback, and the production version of
10532 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
10533 // like caught exceptions, and the DevTools won't pause unless the developer
10534 // takes the extra step of enabling pause on caught exceptions. This is
10535 // unintuitive, though, because even though React has caught the error, from
10536 // the developer's perspective, the error is uncaught.
10537 //
10538 // To preserve the expected "Pause on exceptions" behavior, we don't use a
10539 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
10540 // DOM node, and call the user-provided callback from inside an event handler
10541 // for that fake event. If the callback throws, the error is "captured" using
10542 // a global event handler. But because the error happens in a different
10543 // event loop context, it does not interrupt the normal program flow.
10544 // Effectively, this gives us try-catch behavior without actually using
10545 // try-catch. Neat!
10546
10547 // Check that the browser supports the APIs we need to implement our special
10548 // DEV version of invokeGuardedCallback
10549 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
10550 var fakeNode = document.createElement('react');
10551
10552 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
10553 // If document doesn't exist we know for sure we will crash in this method
10554 // when we call document.createEvent(). However this can cause confusing
10555 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
10556 // So we preemptively throw with a better message instead.
10557 (function () {
10558 if (!(typeof document !== 'undefined')) {
10559 {
10560 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.'));
10561 }
10562 }
10563 })();
10564 var evt = document.createEvent('Event');
10565
10566 // Keeps track of whether the user-provided callback threw an error. We
10567 // set this to true at the beginning, then set it to false right after
10568 // calling the function. If the function errors, `didError` will never be
10569 // set to false. This strategy works even if the browser is flaky and
10570 // fails to call our global error handler, because it doesn't rely on
10571 // the error event at all.
10572 var didError = true;
10573
10574 // Keeps track of the value of window.event so that we can reset it
10575 // during the callback to let user code access window.event in the
10576 // browsers that support it.
10577 var windowEvent = window.event;
10578
10579 // Keeps track of the descriptor of window.event to restore it after event
10580 // dispatching: https://github.com/facebook/react/issues/13688
10581 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
10582
10583 // Create an event handler for our fake event. We will synchronously
10584 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
10585 // call the user-provided callback.
10586 var funcArgs = Array.prototype.slice.call(arguments, 3);
10587 function callCallback() {
10588 // We immediately remove the callback from event listeners so that
10589 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
10590 // nested call would trigger the fake event handlers of any call higher
10591 // in the stack.
10592 fakeNode.removeEventListener(evtType, callCallback, false);
10593
10594 // We check for window.hasOwnProperty('event') to prevent the
10595 // window.event assignment in both IE <= 10 as they throw an error
10596 // "Member not found" in strict mode, and in Firefox which does not
10597 // support window.event.
10598 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
10599 window.event = windowEvent;
10600 }
10601
10602 func.apply(context, funcArgs);
10603 didError = false;
10604 }
10605
10606 // Create a global error event handler. We use this to capture the value
10607 // that was thrown. It's possible that this error handler will fire more
10608 // than once; for example, if non-React code also calls `dispatchEvent`
10609 // and a handler for that event throws. We should be resilient to most of
10610 // those cases. Even if our error event handler fires more than once, the
10611 // last error event is always used. If the callback actually does error,
10612 // we know that the last error event is the correct one, because it's not
10613 // possible for anything else to have happened in between our callback
10614 // erroring and the code that follows the `dispatchEvent` call below. If
10615 // the callback doesn't error, but the error event was fired, we know to
10616 // ignore it because `didError` will be false, as described above.
10617 var error = void 0;
10618 // Use this to track whether the error event is ever called.
10619 var didSetError = false;
10620 var isCrossOriginError = false;
10621
10622 function handleWindowError(event) {
10623 error = event.error;
10624 didSetError = true;
10625 if (error === null && event.colno === 0 && event.lineno === 0) {
10626 isCrossOriginError = true;
10627 }
10628 if (event.defaultPrevented) {
10629 // Some other error handler has prevented default.
10630 // Browsers silence the error report if this happens.
10631 // We'll remember this to later decide whether to log it or not.
10632 if (error != null && typeof error === 'object') {
10633 try {
10634 error._suppressLogging = true;
10635 } catch (inner) {
10636 // Ignore.
10637 }
10638 }
10639 }
10640 }
10641
10642 // Create a fake event type.
10643 var evtType = 'react-' + (name ? name : 'invokeguardedcallback');
10644
10645 // Attach our event handlers
10646 window.addEventListener('error', handleWindowError);
10647 fakeNode.addEventListener(evtType, callCallback, false);
10648
10649 // Synchronously dispatch our fake event. If the user-provided function
10650 // errors, it will trigger our global error handler.
10651 evt.initEvent(evtType, false, false);
10652 fakeNode.dispatchEvent(evt);
10653
10654 if (windowEventDescriptor) {
10655 Object.defineProperty(window, 'event', windowEventDescriptor);
10656 }
10657
10658 if (didError) {
10659 if (!didSetError) {
10660 // The callback errored, but the error event never fired.
10661 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.');
10662 } else if (isCrossOriginError) {
10663 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.');
10664 }
10665 this.onError(error);
10666 }
10667
10668 // Remove our event listeners
10669 window.removeEventListener('error', handleWindowError);
10670 };
10671
10672 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
10673 }
10674}
10675
10676var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
10677
10678// Used by Fiber to simulate a try-catch.
10679var hasError = false;
10680var caughtError = null;
10681
10682var reporter = {
10683 onError: function (error) {
10684 hasError = true;
10685 caughtError = error;
10686 }
10687};
10688
10689/**
10690 * Call a function while guarding against errors that happens within it.
10691 * Returns an error if it throws, otherwise null.
10692 *
10693 * In production, this is implemented using a try-catch. The reason we don't
10694 * use a try-catch directly is so that we can swap out a different
10695 * implementation in DEV mode.
10696 *
10697 * @param {String} name of the guard to use for logging or debugging
10698 * @param {Function} func The function to invoke
10699 * @param {*} context The context to use when calling the function
10700 * @param {...*} args Arguments for function
10701 */
10702function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
10703 hasError = false;
10704 caughtError = null;
10705 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
10706}
10707
10708/**
10709 * Same as invokeGuardedCallback, but instead of returning an error, it stores
10710 * it in a global so it can be rethrown by `rethrowCaughtError` later.
10711 * TODO: See if caughtError and rethrowError can be unified.
10712 *
10713 * @param {String} name of the guard to use for logging or debugging
10714 * @param {Function} func The function to invoke
10715 * @param {*} context The context to use when calling the function
10716 * @param {...*} args Arguments for function
10717 */
10718
10719
10720/**
10721 * During execution of guarded functions we will capture the first error which
10722 * we will rethrow to be handled by the top level error handler.
10723 */
10724
10725
10726function hasCaughtError() {
10727 return hasError;
10728}
10729
10730function clearCaughtError() {
10731 if (hasError) {
10732 var error = caughtError;
10733 hasError = false;
10734 caughtError = null;
10735 return error;
10736 } else {
10737 (function () {
10738 {
10739 {
10740 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.'));
10741 }
10742 }
10743 })();
10744 }
10745}
10746
10747// This module is forked in different environments.
10748// By default, return `true` to log errors to the console.
10749// Forks can return `false` if this isn't desirable.
10750function showErrorDialog(capturedError) {
10751 return true;
10752}
10753
10754function logCapturedError(capturedError) {
10755 var logError = showErrorDialog(capturedError);
10756
10757 // Allow injected showErrorDialog() to prevent default console.error logging.
10758 // This enables renderers like ReactNative to better manage redbox behavior.
10759 if (logError === false) {
10760 return;
10761 }
10762
10763 var error = capturedError.error;
10764 {
10765 var componentName = capturedError.componentName,
10766 componentStack = capturedError.componentStack,
10767 errorBoundaryName = capturedError.errorBoundaryName,
10768 errorBoundaryFound = capturedError.errorBoundaryFound,
10769 willRetry = capturedError.willRetry;
10770
10771 // Browsers support silencing uncaught errors by calling
10772 // `preventDefault()` in window `error` handler.
10773 // We record this information as an expando on the error.
10774
10775 if (error != null && error._suppressLogging) {
10776 if (errorBoundaryFound && willRetry) {
10777 // The error is recoverable and was silenced.
10778 // Ignore it and don't print the stack addendum.
10779 // This is handy for testing error boundaries without noise.
10780 return;
10781 }
10782 // The error is fatal. Since the silencing might have
10783 // been accidental, we'll surface it anyway.
10784 // However, the browser would have silenced the original error
10785 // so we'll print it first, and then print the stack addendum.
10786 console.error(error);
10787 // For a more detailed description of this block, see:
10788 // https://github.com/facebook/react/pull/13384
10789 }
10790
10791 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
10792
10793 var errorBoundaryMessage = void 0;
10794 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
10795 if (errorBoundaryFound && errorBoundaryName) {
10796 if (willRetry) {
10797 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
10798 } else {
10799 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
10800 }
10801 } else {
10802 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.';
10803 }
10804 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
10805
10806 // In development, we provide our own message with just the component stack.
10807 // We don't include the original error message and JS stack because the browser
10808 // has already printed it. Even if the application swallows the error, it is still
10809 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
10810 console.error(combinedMessage);
10811 }
10812}
10813
10814var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
10815{
10816 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
10817}
10818
10819var PossiblyWeakSet$1 = typeof WeakSet === 'function' ? WeakSet : Set;
10820
10821function logError(boundary, errorInfo) {
10822 var source = errorInfo.source;
10823 var stack = errorInfo.stack;
10824 if (stack === null && source !== null) {
10825 stack = getStackByFiberInDevAndProd(source);
10826 }
10827
10828 var capturedError = {
10829 componentName: source !== null ? getComponentName(source.type) : null,
10830 componentStack: stack !== null ? stack : '',
10831 error: errorInfo.value,
10832 errorBoundary: null,
10833 errorBoundaryName: null,
10834 errorBoundaryFound: false,
10835 willRetry: false
10836 };
10837
10838 if (boundary !== null && boundary.tag === ClassComponent) {
10839 capturedError.errorBoundary = boundary.stateNode;
10840 capturedError.errorBoundaryName = getComponentName(boundary.type);
10841 capturedError.errorBoundaryFound = true;
10842 capturedError.willRetry = true;
10843 }
10844
10845 try {
10846 logCapturedError(capturedError);
10847 } catch (e) {
10848 // This method must not throw, or React internal state will get messed up.
10849 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
10850 // we want to report this error outside of the normal stack as a last resort.
10851 // https://github.com/facebook/react/issues/13188
10852 setTimeout(function () {
10853 throw e;
10854 });
10855 }
10856}
10857
10858var callComponentWillUnmountWithTimer = function (current$$1, instance) {
10859 startPhaseTimer(current$$1, 'componentWillUnmount');
10860 instance.props = current$$1.memoizedProps;
10861 instance.state = current$$1.memoizedState;
10862 instance.componentWillUnmount();
10863 stopPhaseTimer();
10864};
10865
10866// Capture errors so they don't interrupt unmounting.
10867function safelyCallComponentWillUnmount(current$$1, instance) {
10868 {
10869 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current$$1, instance);
10870 if (hasCaughtError()) {
10871 var unmountError = clearCaughtError();
10872 captureCommitPhaseError(current$$1, unmountError);
10873 }
10874 }
10875}
10876
10877function safelyDetachRef(current$$1) {
10878 var ref = current$$1.ref;
10879 if (ref !== null) {
10880 if (typeof ref === 'function') {
10881 {
10882 invokeGuardedCallback(null, ref, null, null);
10883 if (hasCaughtError()) {
10884 var refError = clearCaughtError();
10885 captureCommitPhaseError(current$$1, refError);
10886 }
10887 }
10888 } else {
10889 ref.current = null;
10890 }
10891 }
10892}
10893
10894function safelyCallDestroy(current$$1, destroy) {
10895 {
10896 invokeGuardedCallback(null, destroy, null);
10897 if (hasCaughtError()) {
10898 var error = clearCaughtError();
10899 captureCommitPhaseError(current$$1, error);
10900 }
10901 }
10902}
10903
10904function commitBeforeMutationLifeCycles(current$$1, finishedWork) {
10905 switch (finishedWork.tag) {
10906 case FunctionComponent:
10907 case ForwardRef:
10908 case SimpleMemoComponent:
10909 {
10910 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
10911 return;
10912 }
10913 case ClassComponent:
10914 {
10915 if (finishedWork.effectTag & Snapshot) {
10916 if (current$$1 !== null) {
10917 var prevProps = current$$1.memoizedProps;
10918 var prevState = current$$1.memoizedState;
10919 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
10920 var instance = finishedWork.stateNode;
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 ' + '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;
10927 !(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;
10928 }
10929 }
10930 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
10931 {
10932 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
10933 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
10934 didWarnSet.add(finishedWork.type);
10935 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
10936 }
10937 }
10938 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
10939 stopPhaseTimer();
10940 }
10941 }
10942 return;
10943 }
10944 case HostRoot:
10945 case HostComponent:
10946 case HostText:
10947 case HostPortal:
10948 case IncompleteClassComponent:
10949 // Nothing to do for these component types
10950 return;
10951 default:
10952 {
10953 (function () {
10954 {
10955 {
10956 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.'));
10957 }
10958 }
10959 })();
10960 }
10961 }
10962}
10963
10964function commitHookEffectList(unmountTag, mountTag, finishedWork) {
10965 var updateQueue = finishedWork.updateQueue;
10966 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
10967 if (lastEffect !== null) {
10968 var firstEffect = lastEffect.next;
10969 var effect = firstEffect;
10970 do {
10971 if ((effect.tag & unmountTag) !== NoEffect$1) {
10972 // Unmount
10973 var destroy = effect.destroy;
10974 effect.destroy = undefined;
10975 if (destroy !== undefined) {
10976 destroy();
10977 }
10978 }
10979 if ((effect.tag & mountTag) !== NoEffect$1) {
10980 // Mount
10981 var create = effect.create;
10982 effect.destroy = create();
10983
10984 {
10985 var _destroy = effect.destroy;
10986 if (_destroy !== undefined && typeof _destroy !== 'function') {
10987 var addendum = void 0;
10988 if (_destroy === null) {
10989 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
10990 } else if (typeof _destroy.then === 'function') {
10991 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';
10992 } else {
10993 addendum = ' You returned: ' + _destroy;
10994 }
10995 warningWithoutStack$1(false, 'An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
10996 }
10997 }
10998 }
10999 effect = effect.next;
11000 } while (effect !== firstEffect);
11001 }
11002}
11003
11004function commitPassiveHookEffects(finishedWork) {
11005 if ((finishedWork.effectTag & Passive) !== NoEffect) {
11006 switch (finishedWork.tag) {
11007 case FunctionComponent:
11008 case ForwardRef:
11009 case SimpleMemoComponent:
11010 {
11011 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
11012 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
11013 break;
11014 }
11015 default:
11016 break;
11017 }
11018 }
11019}
11020
11021function commitLifeCycles(finishedRoot, current$$1, finishedWork, committedExpirationTime) {
11022 switch (finishedWork.tag) {
11023 case FunctionComponent:
11024 case ForwardRef:
11025 case SimpleMemoComponent:
11026 {
11027 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
11028 break;
11029 }
11030 case ClassComponent:
11031 {
11032 var instance = finishedWork.stateNode;
11033 if (finishedWork.effectTag & Update) {
11034 if (current$$1 === null) {
11035 startPhaseTimer(finishedWork, 'componentDidMount');
11036 // We could update instance props and state here,
11037 // but instead we rely on them being set during last render.
11038 // TODO: revisit this when we implement resuming.
11039 {
11040 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
11041 !(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;
11042 !(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;
11043 }
11044 }
11045 instance.componentDidMount();
11046 stopPhaseTimer();
11047 } else {
11048 var prevProps = finishedWork.elementType === finishedWork.type ? current$$1.memoizedProps : resolveDefaultProps(finishedWork.type, current$$1.memoizedProps);
11049 var prevState = current$$1.memoizedState;
11050 startPhaseTimer(finishedWork, 'componentDidUpdate');
11051 // We could update instance props and state here,
11052 // but instead we rely on them being set during last render.
11053 // TODO: revisit this when we implement resuming.
11054 {
11055 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
11056 !(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;
11057 !(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;
11058 }
11059 }
11060 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
11061 stopPhaseTimer();
11062 }
11063 }
11064 var updateQueue = finishedWork.updateQueue;
11065 if (updateQueue !== null) {
11066 {
11067 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
11068 !(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;
11069 !(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;
11070 }
11071 }
11072 // We could update instance props and state here,
11073 // but instead we rely on them being set during last render.
11074 // TODO: revisit this when we implement resuming.
11075 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
11076 }
11077 return;
11078 }
11079 case HostRoot:
11080 {
11081 var _updateQueue = finishedWork.updateQueue;
11082 if (_updateQueue !== null) {
11083 var _instance = null;
11084 if (finishedWork.child !== null) {
11085 switch (finishedWork.child.tag) {
11086 case HostComponent:
11087 _instance = getPublicInstance(finishedWork.child.stateNode);
11088 break;
11089 case ClassComponent:
11090 _instance = finishedWork.child.stateNode;
11091 break;
11092 }
11093 }
11094 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
11095 }
11096 return;
11097 }
11098 case HostComponent:
11099 {
11100 var _instance2 = finishedWork.stateNode;
11101
11102 // Renderers may schedule work to be done after host components are mounted
11103 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
11104 // These effects should only be committed when components are first mounted,
11105 // aka when there is no current/alternate.
11106 if (current$$1 === null && finishedWork.effectTag & Update) {
11107 var type = finishedWork.type;
11108 var props = finishedWork.memoizedProps;
11109
11110 }
11111
11112 return;
11113 }
11114 case HostText:
11115 {
11116 // We have no life-cycles associated with text.
11117 return;
11118 }
11119 case HostPortal:
11120 {
11121 // We have no life-cycles associated with portals.
11122 return;
11123 }
11124 case Profiler:
11125 {
11126 if (enableProfilerTimer) {
11127 var onRender = finishedWork.memoizedProps.onRender;
11128
11129 if (typeof onRender === 'function') {
11130 if (enableSchedulerTracing) {
11131 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
11132 } else {
11133 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
11134 }
11135 }
11136 }
11137 return;
11138 }
11139 case SuspenseComponent:
11140 case SuspenseListComponent:
11141 case IncompleteClassComponent:
11142 case FundamentalComponent:
11143 return;
11144 default:
11145 {
11146 (function () {
11147 {
11148 {
11149 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.'));
11150 }
11151 }
11152 })();
11153 }
11154 }
11155}
11156
11157function hideOrUnhideAllChildren(finishedWork, isHidden) {
11158 if (supportsMutation) {
11159 // We only have the top Fiber that was inserted but we need to recurse down its
11160 var node = finishedWork;
11161 while (true) {
11162 if (node.tag === HostComponent) {
11163 var instance = node.stateNode;
11164 if (isHidden) {
11165 hideInstance(instance);
11166 } else {
11167 unhideInstance(node.stateNode, node.memoizedProps);
11168 }
11169 } else if (node.tag === HostText) {
11170 var _instance3 = node.stateNode;
11171 if (isHidden) {
11172 hideTextInstance(_instance3);
11173 } else {
11174 unhideTextInstance(_instance3, node.memoizedProps);
11175 }
11176 } else if (node.tag === SuspenseComponent && node.memoizedState !== null) {
11177 // Found a nested Suspense component that timed out. Skip over the
11178 var fallbackChildFragment = node.child.sibling;
11179 fallbackChildFragment.return = node;
11180 node = fallbackChildFragment;
11181 continue;
11182 } else if (node.child !== null) {
11183 node.child.return = node;
11184 node = node.child;
11185 continue;
11186 }
11187 if (node === finishedWork) {
11188 return;
11189 }
11190 while (node.sibling === null) {
11191 if (node.return === null || node.return === finishedWork) {
11192 return;
11193 }
11194 node = node.return;
11195 }
11196 node.sibling.return = node.return;
11197 node = node.sibling;
11198 }
11199 }
11200}
11201
11202function commitAttachRef(finishedWork) {
11203 var ref = finishedWork.ref;
11204 if (ref !== null) {
11205 var instance = finishedWork.stateNode;
11206 var instanceToUse = void 0;
11207 switch (finishedWork.tag) {
11208 case HostComponent:
11209 instanceToUse = getPublicInstance(instance);
11210 break;
11211 default:
11212 instanceToUse = instance;
11213 }
11214 if (typeof ref === 'function') {
11215 ref(instanceToUse);
11216 } else {
11217 {
11218 if (!ref.hasOwnProperty('current')) {
11219 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
11220 }
11221 }
11222
11223 ref.current = instanceToUse;
11224 }
11225 }
11226}
11227
11228function commitDetachRef(current$$1) {
11229 var currentRef = current$$1.ref;
11230 if (currentRef !== null) {
11231 if (typeof currentRef === 'function') {
11232 currentRef(null);
11233 } else {
11234 currentRef.current = null;
11235 }
11236 }
11237}
11238
11239// User-originating errors (lifecycles and refs) should not interrupt
11240// deletion, so don't let them throw. Host-originating errors should
11241// interrupt deletion, so it's okay
11242function commitUnmount(current$$1, renderPriorityLevel) {
11243 onCommitUnmount(current$$1);
11244
11245 switch (current$$1.tag) {
11246 case FunctionComponent:
11247 case ForwardRef:
11248 case MemoComponent:
11249 case SimpleMemoComponent:
11250 {
11251 var updateQueue = current$$1.updateQueue;
11252 if (updateQueue !== null) {
11253 var lastEffect = updateQueue.lastEffect;
11254 if (lastEffect !== null) {
11255 var firstEffect = lastEffect.next;
11256
11257 // When the owner fiber is deleted, the destroy function of a passive
11258 // effect hook is called during the synchronous commit phase. This is
11259 // a concession to implementation complexity. Calling it in the
11260 // passive effect phase (like they usually are, when dependencies
11261 // change during an update) would require either traversing the
11262 // children of the deleted fiber again, or including unmount effects
11263 // as part of the fiber effect list.
11264 //
11265 // Because this is during the sync commit phase, we need to change
11266 // the priority.
11267 //
11268 // TODO: Reconsider this implementation trade off.
11269 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
11270 runWithPriority(priorityLevel, function () {
11271 var effect = firstEffect;
11272 do {
11273 var destroy = effect.destroy;
11274 if (destroy !== undefined) {
11275 safelyCallDestroy(current$$1, destroy);
11276 }
11277 effect = effect.next;
11278 } while (effect !== firstEffect);
11279 });
11280 }
11281 }
11282 break;
11283 }
11284 case ClassComponent:
11285 {
11286 safelyDetachRef(current$$1);
11287 var instance = current$$1.stateNode;
11288 if (typeof instance.componentWillUnmount === 'function') {
11289 safelyCallComponentWillUnmount(current$$1, instance);
11290 }
11291 return;
11292 }
11293 case HostComponent:
11294 {
11295 if (enableFlareAPI) {
11296 var dependencies = current$$1.dependencies;
11297
11298 if (dependencies !== null) {
11299 var respondersMap = dependencies.responders;
11300 if (respondersMap !== null) {
11301 var responderInstances = Array.from(respondersMap.values());
11302 for (var i = 0, length = responderInstances.length; i < length; i++) {
11303 var responderInstance = responderInstances[i];
11304
11305 }
11306 dependencies.responders = null;
11307 }
11308 }
11309 }
11310 safelyDetachRef(current$$1);
11311 return;
11312 }
11313 case HostPortal:
11314 {
11315 // TODO: this is recursive.
11316 // We are also not using this parent because
11317 // the portal will get pushed immediately.
11318 if (supportsMutation) {
11319 unmountHostComponents(current$$1, renderPriorityLevel);
11320 } else if (supportsPersistence) {
11321 emptyPortalContainer(current$$1);
11322 }
11323 return;
11324 }
11325 case FundamentalComponent:
11326 {
11327 if (enableFundamentalAPI) {
11328 var fundamentalInstance = current$$1.stateNode;
11329 if (fundamentalInstance !== null) {
11330 unmountFundamentalComponent(fundamentalInstance);
11331 current$$1.stateNode = null;
11332 }
11333 }
11334 }
11335 }
11336}
11337
11338function commitNestedUnmounts(root, renderPriorityLevel) {
11339 // While we're inside a removed host node we don't want to call
11340 // removeChild on the inner nodes because they're removed by the top
11341 // call anyway. We also want to call componentWillUnmount on all
11342 // composites before this host node is removed from the tree. Therefore
11343 var node = root;
11344 while (true) {
11345 commitUnmount(node, renderPriorityLevel);
11346 // Visit children because they may contain more composite or host nodes.
11347 // Skip portals because commitUnmount() currently visits them recursively.
11348 if (node.child !== null && (
11349 // If we use mutation we drill down into portals using commitUnmount above.
11350 // If we don't use mutation we drill down into portals here instead.
11351 !supportsMutation || node.tag !== HostPortal)) {
11352 node.child.return = node;
11353 node = node.child;
11354 continue;
11355 }
11356 if (node === root) {
11357 return;
11358 }
11359 while (node.sibling === null) {
11360 if (node.return === null || node.return === root) {
11361 return;
11362 }
11363 node = node.return;
11364 }
11365 node.sibling.return = node.return;
11366 node = node.sibling;
11367 }
11368}
11369
11370function detachFiber(current$$1) {
11371 // Cut off the return pointers to disconnect it from the tree. Ideally, we
11372 // should clear the child pointer of the parent alternate to let this
11373 // get GC:ed but we don't know which for sure which parent is the current
11374 // one so we'll settle for GC:ing the subtree of this child. This child
11375 // itself will be GC:ed when the parent updates the next time.
11376 current$$1.return = null;
11377 current$$1.child = null;
11378 current$$1.memoizedState = null;
11379 current$$1.updateQueue = null;
11380 current$$1.dependencies = null;
11381 var alternate = current$$1.alternate;
11382 if (alternate !== null) {
11383 alternate.return = null;
11384 alternate.child = null;
11385 alternate.memoizedState = null;
11386 alternate.updateQueue = null;
11387 alternate.dependencies = null;
11388 }
11389}
11390
11391function emptyPortalContainer(current$$1) {
11392 if (!supportsPersistence) {
11393 return;
11394 }
11395
11396 var portal = current$$1.stateNode;
11397 var containerInfo = portal.containerInfo;
11398
11399 var emptyChildSet = createContainerChildSet(containerInfo);
11400 replaceContainerChildren(containerInfo, emptyChildSet);
11401}
11402
11403function commitContainer(finishedWork) {
11404 if (!supportsPersistence) {
11405 return;
11406 }
11407
11408 switch (finishedWork.tag) {
11409 case ClassComponent:
11410 case HostComponent:
11411 case HostText:
11412 case FundamentalComponent:
11413 {
11414 return;
11415 }
11416 case HostRoot:
11417 case HostPortal:
11418 {
11419 var portalOrRoot = finishedWork.stateNode;
11420 var containerInfo = portalOrRoot.containerInfo,
11421 _pendingChildren = portalOrRoot.pendingChildren;
11422
11423 replaceContainerChildren(containerInfo, _pendingChildren);
11424 return;
11425 }
11426 default:
11427 {
11428 (function () {
11429 {
11430 {
11431 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.'));
11432 }
11433 }
11434 })();
11435 }
11436 }
11437}
11438
11439function getHostParentFiber(fiber) {
11440 var parent = fiber.return;
11441 while (parent !== null) {
11442 if (isHostParent(parent)) {
11443 return parent;
11444 }
11445 parent = parent.return;
11446 }
11447 (function () {
11448 {
11449 {
11450 throw ReactError(Error('Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.'));
11451 }
11452 }
11453 })();
11454}
11455
11456function isHostParent(fiber) {
11457 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
11458}
11459
11460function getHostSibling(fiber) {
11461 // We're going to search forward into the tree until we find a sibling host
11462 // node. Unfortunately, if multiple insertions are done in a row we have to
11463 // search past them. This leads to exponential search for the next sibling.
11464 var node = fiber;
11465 siblings: while (true) {
11466 // If we didn't find anything, let's try the next sibling.
11467 while (node.sibling === null) {
11468 if (node.return === null || isHostParent(node.return)) {
11469 // If we pop out of the root or hit the parent the fiber we are the
11470 // last sibling.
11471 return null;
11472 }
11473 node = node.return;
11474 }
11475 node.sibling.return = node.return;
11476 node = node.sibling;
11477 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedSuspenseComponent) {
11478 // If it is not host node and, we might have a host node inside it.
11479 // Try to search down until we find one.
11480 if (node.effectTag & Placement) {
11481 // If we don't have a child, try the siblings instead.
11482 continue siblings;
11483 }
11484 // If we don't have a child, try the siblings instead.
11485 // We also skip portals because they are not part of this host tree.
11486 if (node.child === null || node.tag === HostPortal) {
11487 continue siblings;
11488 } else {
11489 node.child.return = node;
11490 node = node.child;
11491 }
11492 }
11493 // Check if this host node is stable or about to be placed.
11494 if (!(node.effectTag & Placement)) {
11495 // Found it!
11496 return node.stateNode;
11497 }
11498 }
11499}
11500
11501function commitPlacement(finishedWork) {
11502 if (!supportsMutation) {
11503 return;
11504 }
11505
11506 // Recursively insert all host nodes into the parent.
11507 var parentFiber = getHostParentFiber(finishedWork);
11508
11509 // Note: these two variables *must* always be updated together.
11510 var parent = void 0;
11511 var isContainer = void 0;
11512 var parentStateNode = parentFiber.stateNode;
11513 switch (parentFiber.tag) {
11514 case HostComponent:
11515 parent = parentStateNode;
11516 isContainer = false;
11517 break;
11518 case HostRoot:
11519 parent = parentStateNode.containerInfo;
11520 isContainer = true;
11521 break;
11522 case HostPortal:
11523 parent = parentStateNode.containerInfo;
11524 isContainer = true;
11525 break;
11526 case FundamentalComponent:
11527 if (enableFundamentalAPI) {
11528 parent = parentStateNode.instance;
11529 isContainer = false;
11530 }
11531 // eslint-disable-next-line-no-fallthrough
11532 default:
11533 (function () {
11534 {
11535 {
11536 throw ReactError(Error('Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.'));
11537 }
11538 }
11539 })();
11540 }
11541 if (parentFiber.effectTag & ContentReset) {
11542 // Reset the text content of the parent before doing any insertions
11543 parentFiber.effectTag &= ~ContentReset;
11544 }
11545
11546 var before = getHostSibling(finishedWork);
11547 // We only have the top Fiber that was inserted but we need to recurse down its
11548 // children to find all the terminal nodes.
11549 var node = finishedWork;
11550 while (true) {
11551 var isHost = node.tag === HostComponent || node.tag === HostText;
11552 if (isHost || node.tag === FundamentalComponent) {
11553 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
11554 if (before) {
11555 if (isContainer) {
11556 insertInContainerBefore(parent, stateNode, before);
11557 } else {
11558 insertBefore(parent, stateNode, before);
11559 }
11560 } else {
11561 if (isContainer) {
11562 appendChildToContainer(parent, stateNode);
11563 } else {
11564 appendChild(parent, stateNode);
11565 }
11566 }
11567 } else if (node.tag === HostPortal) {
11568 // If the insertion itself is a portal, then we don't want to traverse
11569 // down its children. Instead, we'll get insertions from each child in
11570 // the portal directly.
11571 } else if (node.child !== null) {
11572 node.child.return = node;
11573 node = node.child;
11574 continue;
11575 }
11576 if (node === finishedWork) {
11577 return;
11578 }
11579 while (node.sibling === null) {
11580 if (node.return === null || node.return === finishedWork) {
11581 return;
11582 }
11583 node = node.return;
11584 }
11585 node.sibling.return = node.return;
11586 node = node.sibling;
11587 }
11588}
11589
11590function unmountHostComponents(current$$1, renderPriorityLevel) {
11591 // We only have the top Fiber that was deleted but we need to recurse down its
11592 var node = current$$1;
11593
11594 // Each iteration, currentParent is populated with node's host parent if not
11595 // currentParentIsValid.
11596 var currentParentIsValid = false;
11597
11598 // Note: these two variables *must* always be updated together.
11599 var currentParent = void 0;
11600 var currentParentIsContainer = void 0;
11601
11602 while (true) {
11603 if (!currentParentIsValid) {
11604 var parent = node.return;
11605 findParent: while (true) {
11606 (function () {
11607 if (!(parent !== null)) {
11608 {
11609 throw ReactError(Error('Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.'));
11610 }
11611 }
11612 })();
11613 var parentStateNode = parent.stateNode;
11614 switch (parent.tag) {
11615 case HostComponent:
11616 currentParent = parentStateNode;
11617 currentParentIsContainer = false;
11618 break findParent;
11619 case HostRoot:
11620 currentParent = parentStateNode.containerInfo;
11621 currentParentIsContainer = true;
11622 break findParent;
11623 case HostPortal:
11624 currentParent = parentStateNode.containerInfo;
11625 currentParentIsContainer = true;
11626 break findParent;
11627 case FundamentalComponent:
11628 if (enableFundamentalAPI) {
11629 currentParent = parentStateNode.instance;
11630 currentParentIsContainer = false;
11631 }
11632 }
11633 parent = parent.return;
11634 }
11635 currentParentIsValid = true;
11636 }
11637
11638 if (node.tag === HostComponent || node.tag === HostText) {
11639 commitNestedUnmounts(node, renderPriorityLevel);
11640 // After all the children have unmounted, it is now safe to remove the
11641 // node from the tree.
11642 if (currentParentIsContainer) {
11643 removeChildFromContainer(currentParent, node.stateNode);
11644 } else {
11645 removeChild(currentParent, node.stateNode);
11646 }
11647 // Don't visit children because we already visited them.
11648 } else if (node.tag === FundamentalComponent) {
11649 var fundamentalNode = node.stateNode.instance;
11650 commitNestedUnmounts(node, renderPriorityLevel);
11651 // After all the children have unmounted, it is now safe to remove the
11652 // node from the tree.
11653 if (currentParentIsContainer) {
11654 removeChildFromContainer(currentParent, fundamentalNode);
11655 } else {
11656 removeChild(currentParent, fundamentalNode);
11657 }
11658 } else if (enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent) {
11659 // Delete the dehydrated suspense boundary and all of its content.
11660 if (currentParentIsContainer) {
11661 clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
11662 } else {
11663 clearSuspenseBoundary(currentParent, node.stateNode);
11664 }
11665 } else if (node.tag === HostPortal) {
11666 if (node.child !== null) {
11667 // When we go into a portal, it becomes the parent to remove from.
11668 // We will reassign it back when we pop the portal on the way up.
11669 currentParent = node.stateNode.containerInfo;
11670 currentParentIsContainer = true;
11671 // Visit children because portals might contain host components.
11672 node.child.return = node;
11673 node = node.child;
11674 continue;
11675 }
11676 } else {
11677 commitUnmount(node, renderPriorityLevel);
11678 // Visit children because we may find more host components below.
11679 if (node.child !== null) {
11680 node.child.return = node;
11681 node = node.child;
11682 continue;
11683 }
11684 }
11685 if (node === current$$1) {
11686 return;
11687 }
11688 while (node.sibling === null) {
11689 if (node.return === null || node.return === current$$1) {
11690 return;
11691 }
11692 node = node.return;
11693 if (node.tag === HostPortal) {
11694 // When we go out of the portal, we need to restore the parent.
11695 // Since we don't keep a stack of them, we will search for it.
11696 currentParentIsValid = false;
11697 }
11698 }
11699 node.sibling.return = node.return;
11700 node = node.sibling;
11701 }
11702}
11703
11704function commitDeletion(current$$1, renderPriorityLevel) {
11705 if (supportsMutation) {
11706 // Recursively delete all host nodes from the parent.
11707 // Detach refs and call componentWillUnmount() on the whole subtree.
11708 unmountHostComponents(current$$1, renderPriorityLevel);
11709 } else {
11710 // Detach refs and call componentWillUnmount() on the whole subtree.
11711 commitNestedUnmounts(current$$1, renderPriorityLevel);
11712 }
11713 detachFiber(current$$1);
11714}
11715
11716function commitWork(current$$1, finishedWork) {
11717 if (!supportsMutation) {
11718 switch (finishedWork.tag) {
11719 case FunctionComponent:
11720 case ForwardRef:
11721 case MemoComponent:
11722 case SimpleMemoComponent:
11723 {
11724 // Note: We currently never use MountMutation, but useLayout uses
11725 // UnmountMutation.
11726 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
11727 return;
11728 }
11729 case Profiler:
11730 {
11731 return;
11732 }
11733 case SuspenseComponent:
11734 {
11735 commitSuspenseComponent(finishedWork);
11736 attachSuspenseRetryListeners(finishedWork);
11737 return;
11738 }
11739 case SuspenseListComponent:
11740 {
11741 attachSuspenseRetryListeners(finishedWork);
11742 return;
11743 }
11744 }
11745
11746 commitContainer(finishedWork);
11747 return;
11748 }
11749
11750 switch (finishedWork.tag) {
11751 case FunctionComponent:
11752 case ForwardRef:
11753 case MemoComponent:
11754 case SimpleMemoComponent:
11755 {
11756 // Note: We currently never use MountMutation, but useLayout uses
11757 // UnmountMutation.
11758 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
11759 return;
11760 }
11761 case ClassComponent:
11762 {
11763 return;
11764 }
11765 case HostComponent:
11766 {
11767 var instance = finishedWork.stateNode;
11768 if (instance != null) {
11769 // Commit the work prepared earlier.
11770 var newProps = finishedWork.memoizedProps;
11771 // For hydration we reuse the update path but we treat the oldProps
11772 // as the newProps. The updatePayload will contain the real change in
11773 // this case.
11774 var oldProps = current$$1 !== null ? current$$1.memoizedProps : newProps;
11775 var type = finishedWork.type;
11776 // TODO: Type the updateQueue to be specific to host components.
11777 var updatePayload = finishedWork.updateQueue;
11778 finishedWork.updateQueue = null;
11779 if (updatePayload !== null) {
11780 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
11781 }
11782 }
11783 return;
11784 }
11785 case HostText:
11786 {
11787 (function () {
11788 if (!(finishedWork.stateNode !== null)) {
11789 {
11790 throw ReactError(Error('This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue.'));
11791 }
11792 }
11793 })();
11794 var textInstance = finishedWork.stateNode;
11795 var newText = finishedWork.memoizedProps;
11796 // For hydration we reuse the update path but we treat the oldProps
11797 // as the newProps. The updatePayload will contain the real change in
11798 // this case.
11799 var oldText = current$$1 !== null ? current$$1.memoizedProps : newText;
11800 commitTextUpdate(textInstance, oldText, newText);
11801 return;
11802 }
11803 case HostRoot:
11804 {
11805 return;
11806 }
11807 case Profiler:
11808 {
11809 return;
11810 }
11811 case SuspenseComponent:
11812 {
11813 commitSuspenseComponent(finishedWork);
11814 attachSuspenseRetryListeners(finishedWork);
11815 return;
11816 }
11817 case SuspenseListComponent:
11818 {
11819 attachSuspenseRetryListeners(finishedWork);
11820 return;
11821 }
11822 case IncompleteClassComponent:
11823 {
11824 return;
11825 }
11826 case FundamentalComponent:
11827 {
11828 if (enableFundamentalAPI) {
11829 var fundamentalInstance = finishedWork.stateNode;
11830 updateFundamentalComponent(fundamentalInstance);
11831 }
11832 return;
11833 }
11834 default:
11835 {
11836 (function () {
11837 {
11838 {
11839 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.'));
11840 }
11841 }
11842 })();
11843 }
11844 }
11845}
11846
11847function commitSuspenseComponent(finishedWork) {
11848 var newState = finishedWork.memoizedState;
11849
11850 var newDidTimeout = void 0;
11851 var primaryChildParent = finishedWork;
11852 if (newState === null) {
11853 newDidTimeout = false;
11854 } else {
11855 newDidTimeout = true;
11856 primaryChildParent = finishedWork.child;
11857 markCommitTimeOfFallback();
11858 }
11859
11860 if (supportsMutation && primaryChildParent !== null) {
11861 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
11862 }
11863
11864 if (enableSuspenseCallback && newState !== null) {
11865 var suspenseCallback = finishedWork.memoizedProps.suspenseCallback;
11866 if (typeof suspenseCallback === 'function') {
11867 var thenables = finishedWork.updateQueue;
11868 if (thenables !== null) {
11869 suspenseCallback(new Set(thenables));
11870 }
11871 } else {
11872 if (suspenseCallback !== undefined) {
11873 warning$1(false, 'Unexpected type for suspenseCallback.');
11874 }
11875 }
11876 }
11877}
11878
11879function attachSuspenseRetryListeners(finishedWork) {
11880 // If this boundary just timed out, then it will have a set of thenables.
11881 // For each thenable, attach a listener so that when it resolves, React
11882 var thenables = finishedWork.updateQueue;
11883 if (thenables !== null) {
11884 finishedWork.updateQueue = null;
11885 var retryCache = finishedWork.stateNode;
11886 if (retryCache === null) {
11887 retryCache = finishedWork.stateNode = new PossiblyWeakSet$1();
11888 }
11889 thenables.forEach(function (thenable) {
11890 // Memoize using the boundary fiber to prevent redundant listeners.
11891 var retry = resolveRetryThenable.bind(null, finishedWork, thenable);
11892 if (!retryCache.has(thenable)) {
11893 if (enableSchedulerTracing) {
11894 retry = unstable_wrap(retry);
11895 }
11896 retryCache.add(thenable);
11897 thenable.then(retry, retry);
11898 }
11899 });
11900 }
11901}
11902
11903function commitResetTextContent(current$$1) {
11904 if (!supportsMutation) {
11905 return;
11906 }
11907 resetTextContent(current$$1.stateNode);
11908}
11909
11910var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
11911var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
11912
11913function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
11914 var update = createUpdate(expirationTime, null);
11915 // Unmount the root by rendering null.
11916 update.tag = CaptureUpdate;
11917 // Caution: React DevTools currently depends on this property
11918 // being called "element".
11919 update.payload = { element: null };
11920 var error = errorInfo.value;
11921 update.callback = function () {
11922 onUncaughtError(error);
11923 logError(fiber, errorInfo);
11924 };
11925 return update;
11926}
11927
11928function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
11929 var update = createUpdate(expirationTime, null);
11930 update.tag = CaptureUpdate;
11931 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
11932 if (typeof getDerivedStateFromError === 'function') {
11933 var error = errorInfo.value;
11934 update.payload = function () {
11935 logError(fiber, errorInfo);
11936 return getDerivedStateFromError(error);
11937 };
11938 }
11939
11940 var inst = fiber.stateNode;
11941 if (inst !== null && typeof inst.componentDidCatch === 'function') {
11942 update.callback = function callback() {
11943 {
11944 markFailedErrorBoundaryForHotReloading(fiber);
11945 }
11946 if (typeof getDerivedStateFromError !== 'function') {
11947 // To preserve the preexisting retry behavior of error boundaries,
11948 // we keep track of which ones already failed during this batch.
11949 // This gets reset before we yield back to the browser.
11950 // TODO: Warn in strict mode if getDerivedStateFromError is
11951 // not defined.
11952 markLegacyErrorBoundaryAsFailed(this);
11953
11954 // Only log here if componentDidCatch is the only error boundary method defined
11955 logError(fiber, errorInfo);
11956 }
11957 var error = errorInfo.value;
11958 var stack = errorInfo.stack;
11959 this.componentDidCatch(error, {
11960 componentStack: stack !== null ? stack : ''
11961 });
11962 {
11963 if (typeof getDerivedStateFromError !== 'function') {
11964 // If componentDidCatch is the only error boundary method defined,
11965 // then it needs to call setState to recover from errors.
11966 // If no state update is scheduled then the boundary will swallow the error.
11967 !(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;
11968 }
11969 }
11970 };
11971 } else {
11972 update.callback = function () {
11973 markFailedErrorBoundaryForHotReloading(fiber);
11974 };
11975 }
11976 return update;
11977}
11978
11979function attachPingListener(root, renderExpirationTime, thenable) {
11980 // Attach a listener to the promise to "ping" the root and retry. But
11981 // only if one does not already exist for the current render expiration
11982 // time (which acts like a "thread ID" here).
11983 var pingCache = root.pingCache;
11984 var threadIDs = void 0;
11985 if (pingCache === null) {
11986 pingCache = root.pingCache = new PossiblyWeakMap();
11987 threadIDs = new Set();
11988 pingCache.set(thenable, threadIDs);
11989 } else {
11990 threadIDs = pingCache.get(thenable);
11991 if (threadIDs === undefined) {
11992 threadIDs = new Set();
11993 pingCache.set(thenable, threadIDs);
11994 }
11995 }
11996 if (!threadIDs.has(renderExpirationTime)) {
11997 // Memoize using the thread ID to prevent redundant listeners.
11998 threadIDs.add(renderExpirationTime);
11999 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
12000 if (enableSchedulerTracing) {
12001 ping = unstable_wrap(ping);
12002 }
12003 thenable.then(ping, ping);
12004 }
12005}
12006
12007function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
12008 // The source fiber did not complete.
12009 sourceFiber.effectTag |= Incomplete;
12010 // Its effect list is no longer valid.
12011 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
12012
12013 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
12014 // This is a thenable.
12015 var thenable = value;
12016
12017 checkForWrongSuspensePriorityInDEV(sourceFiber);
12018
12019 var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext);
12020
12021 // Schedule the nearest Suspense to re-render the timed out view.
12022 var _workInProgress = returnFiber;
12023 do {
12024 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) {
12025 // Found the nearest boundary.
12026
12027 // Stash the promise on the boundary fiber. If the boundary times out, we'll
12028 var thenables = _workInProgress.updateQueue;
12029 if (thenables === null) {
12030 var updateQueue = new Set();
12031 updateQueue.add(thenable);
12032 _workInProgress.updateQueue = updateQueue;
12033 } else {
12034 thenables.add(thenable);
12035 }
12036
12037 // If the boundary is outside of batched mode, we should *not*
12038 // suspend the commit. Pretend as if the suspended component rendered
12039 // null and keep rendering. In the commit phase, we'll schedule a
12040 // subsequent synchronous update to re-render the Suspense.
12041 //
12042 // Note: It doesn't matter whether the component that suspended was
12043 // inside a batched mode tree. If the Suspense is outside of it, we
12044 // should *not* suspend the commit.
12045 if ((_workInProgress.mode & BatchedMode) === NoMode) {
12046 _workInProgress.effectTag |= DidCapture;
12047
12048 // We're going to commit this fiber even though it didn't complete.
12049 // But we shouldn't call any lifecycle methods or callbacks. Remove
12050 // all lifecycle effect tags.
12051 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
12052
12053 if (sourceFiber.tag === ClassComponent) {
12054 var currentSourceFiber = sourceFiber.alternate;
12055 if (currentSourceFiber === null) {
12056 // This is a new mount. Change the tag so it's not mistaken for a
12057 // completed class component. For example, we should not call
12058 // componentWillUnmount if it is deleted.
12059 sourceFiber.tag = IncompleteClassComponent;
12060 } else {
12061 // When we try rendering again, we should not reuse the current fiber,
12062 // since it's known to be in an inconsistent state. Use a force update to
12063 // prevent a bail out.
12064 var update = createUpdate(Sync, null);
12065 update.tag = ForceUpdate;
12066 enqueueUpdate(sourceFiber, update);
12067 }
12068 }
12069
12070 // The source fiber did not complete. Mark it with Sync priority to
12071 // indicate that it still has pending work.
12072 sourceFiber.expirationTime = Sync;
12073
12074 // Exit without suspending.
12075 return;
12076 }
12077
12078 // Confirmed that the boundary is in a concurrent mode tree. Continue
12079 // with the normal suspend path.
12080 //
12081 // After this we'll use a set of heuristics to determine whether this
12082 // render pass will run to completion or restart or "suspend" the commit.
12083 // The actual logic for this is spread out in different places.
12084 //
12085 // This first principle is that if we're going to suspend when we complete
12086 // a root, then we should also restart if we get an update or ping that
12087 // might unsuspend it, and vice versa. The only reason to suspend is
12088 // because you think you might want to restart before committing. However,
12089 // it doesn't make sense to restart only while in the period we're suspended.
12090 //
12091 // Restarting too aggressively is also not good because it starves out any
12092 // intermediate loading state. So we use heuristics to determine when.
12093
12094 // Suspense Heuristics
12095 //
12096 // If nothing threw a Promise or all the same fallbacks are already showing,
12097 // then don't suspend/restart.
12098 //
12099 // If this is an initial render of a new tree of Suspense boundaries and
12100 // those trigger a fallback, then don't suspend/restart. We want to ensure
12101 // that we can show the initial loading state as quickly as possible.
12102 //
12103 // If we hit a "Delayed" case, such as when we'd switch from content back into
12104 // a fallback, then we should always suspend/restart. SuspenseConfig applies to
12105 // this case. If none is defined, JND is used instead.
12106 //
12107 // If we're already showing a fallback and it gets "retried", allowing us to show
12108 // another level, but there's still an inner boundary that would show a fallback,
12109 // then we suspend/restart for 500ms since the last time we showed a fallback
12110 // anywhere in the tree. This effectively throttles progressive loading into a
12111 // consistent train of commits. This also gives us an opportunity to restart to
12112 // get to the completed state slightly earlier.
12113 //
12114 // If there's ambiguity due to batching it's resolved in preference of:
12115 // 1) "delayed", 2) "initial render", 3) "retry".
12116 //
12117 // We want to ensure that a "busy" state doesn't get force committed. We want to
12118 // ensure that new initial loading states can commit as soon as possible.
12119
12120 attachPingListener(root, renderExpirationTime, thenable);
12121
12122 _workInProgress.effectTag |= ShouldCapture;
12123 _workInProgress.expirationTime = renderExpirationTime;
12124
12125 return;
12126 } else if (enableSuspenseServerRenderer && _workInProgress.tag === DehydratedSuspenseComponent) {
12127 attachPingListener(root, renderExpirationTime, thenable);
12128
12129 // Since we already have a current fiber, we can eagerly add a retry listener.
12130 var retryCache = _workInProgress.memoizedState;
12131 if (retryCache === null) {
12132 retryCache = _workInProgress.memoizedState = new PossiblyWeakSet();
12133 var current$$1 = _workInProgress.alternate;
12134 (function () {
12135 if (!current$$1) {
12136 {
12137 throw ReactError(Error('A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React.'));
12138 }
12139 }
12140 })();
12141 current$$1.memoizedState = retryCache;
12142 }
12143 // Memoize using the boundary fiber to prevent redundant listeners.
12144 if (!retryCache.has(thenable)) {
12145 retryCache.add(thenable);
12146 var retry = resolveRetryThenable.bind(null, _workInProgress, thenable);
12147 if (enableSchedulerTracing) {
12148 retry = unstable_wrap(retry);
12149 }
12150 thenable.then(retry, retry);
12151 }
12152 _workInProgress.effectTag |= ShouldCapture;
12153 _workInProgress.expirationTime = renderExpirationTime;
12154 return;
12155 }
12156 // This boundary already captured during this render. Continue to the next
12157 // boundary.
12158 _workInProgress = _workInProgress.return;
12159 } while (_workInProgress !== null);
12160 // No boundary was found. Fallthrough to error mode.
12161 // TODO: Use invariant so the message is stripped in prod?
12162 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));
12163 }
12164
12165 // We didn't find a boundary that could handle this type of exception. Start
12166 // over and traverse parent path again, this time treating the exception
12167 // as an error.
12168 renderDidError();
12169 value = createCapturedValue(value, sourceFiber);
12170 var workInProgress = returnFiber;
12171 do {
12172 switch (workInProgress.tag) {
12173 case HostRoot:
12174 {
12175 var _errorInfo = value;
12176 workInProgress.effectTag |= ShouldCapture;
12177 workInProgress.expirationTime = renderExpirationTime;
12178 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
12179 enqueueCapturedUpdate(workInProgress, _update);
12180 return;
12181 }
12182 case ClassComponent:
12183 // Capture and retry
12184 var errorInfo = value;
12185 var ctor = workInProgress.type;
12186 var instance = workInProgress.stateNode;
12187 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
12188 workInProgress.effectTag |= ShouldCapture;
12189 workInProgress.expirationTime = renderExpirationTime;
12190 // Schedule the error boundary to re-render using updated state
12191 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
12192 enqueueCapturedUpdate(workInProgress, _update2);
12193 return;
12194 }
12195 break;
12196 default:
12197 break;
12198 }
12199 workInProgress = workInProgress.return;
12200 } while (workInProgress !== null);
12201}
12202
12203// The scheduler is imported here *only* to detect whether it's been mocked
12204// DEV stuff
12205var ceil = Math.ceil;
12206
12207var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
12208var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
12209var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;
12210
12211
12212var NoContext = /* */0;
12213var BatchedContext = /* */1;
12214var DiscreteEventContext = /* */4;
12215var LegacyUnbatchedContext = /* */8;
12216var RenderContext = /* */16;
12217var CommitContext = /* */32;
12218
12219var RootIncomplete = 0;
12220var RootErrored = 1;
12221var RootSuspended = 2;
12222var RootSuspendedWithDelay = 3;
12223var RootCompleted = 4;
12224
12225// Describes where we are in the React execution stack
12226var executionContext = NoContext;
12227// The root we're working on
12228var workInProgressRoot = null;
12229// The fiber we're working on
12230var workInProgress = null;
12231// The expiration time we're rendering
12232var renderExpirationTime = NoWork;
12233// Whether to root completed, errored, suspended, etc.
12234var workInProgressRootExitStatus = RootIncomplete;
12235// Most recent event time among processed updates during this render.
12236// This is conceptually a time stamp but expressed in terms of an ExpirationTime
12237// because we deal mostly with expiration times in the hot path, so this avoids
12238// the conversion happening in the hot path.
12239var workInProgressRootLatestProcessedExpirationTime = Sync;
12240var workInProgressRootLatestSuspenseTimeout = Sync;
12241var workInProgressRootCanSuspendUsingConfig = null;
12242// If we're pinged while rendering we don't always restart immediately.
12243// This flag determines if it might be worthwhile to restart if an opportunity
12244// happens latere.
12245var workInProgressRootHasPendingPing = false;
12246// The most recent time we committed a fallback. This lets us ensure a train
12247// model where we don't commit new loading states in too quick succession.
12248var globalMostRecentFallbackTime = 0;
12249var FALLBACK_THROTTLE_MS = 500;
12250
12251var nextEffect = null;
12252var hasUncaughtError = false;
12253var firstUncaughtError = null;
12254var legacyErrorBoundariesThatAlreadyFailed = null;
12255
12256var rootDoesHavePassiveEffects = false;
12257var rootWithPendingPassiveEffects = null;
12258var pendingPassiveEffectsRenderPriority = NoPriority;
12259var pendingPassiveEffectsExpirationTime = NoWork;
12260
12261var rootsWithPendingDiscreteUpdates = null;
12262
12263// Use these to prevent an infinite loop of nested updates
12264var NESTED_UPDATE_LIMIT = 50;
12265var nestedUpdateCount = 0;
12266var rootWithNestedUpdates = null;
12267
12268var NESTED_PASSIVE_UPDATE_LIMIT = 50;
12269var nestedPassiveUpdateCount = 0;
12270
12271var interruptedBy = null;
12272
12273// Marks the need to reschedule pending interactions at these expiration times
12274// during the commit phase. This enables them to be traced across components
12275// that spawn new work during render. E.g. hidden boundaries, suspended SSR
12276// hydration or SuspenseList.
12277var spawnedWorkDuringRender = null;
12278
12279// Expiration times are computed by adding to the current time (the start
12280// time). However, if two updates are scheduled within the same event, we
12281// should treat their start times as simultaneous, even if the actual clock
12282// time has advanced between the first and second call.
12283
12284// In other words, because expiration times determine how updates are batched,
12285// we want all updates of like priority that occur within the same event to
12286// receive the same expiration time. Otherwise we get tearing.
12287var currentEventTime = NoWork;
12288
12289function requestCurrentTime() {
12290 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
12291 // We're inside React, so it's fine to read the actual time.
12292 return msToExpirationTime(now());
12293 }
12294 // We're not inside React, so we may be in the middle of a browser event.
12295 if (currentEventTime !== NoWork) {
12296 // Use the same start time for all updates until we enter React again.
12297 return currentEventTime;
12298 }
12299 // This is the first update since React yielded. Compute a new start time.
12300 currentEventTime = msToExpirationTime(now());
12301 return currentEventTime;
12302}
12303
12304function computeExpirationForFiber(currentTime, fiber, suspenseConfig) {
12305 var mode = fiber.mode;
12306 if ((mode & BatchedMode) === NoMode) {
12307 return Sync;
12308 }
12309
12310 var priorityLevel = getCurrentPriorityLevel();
12311 if ((mode & ConcurrentMode) === NoMode) {
12312 return priorityLevel === ImmediatePriority ? Sync : Batched;
12313 }
12314
12315 if ((executionContext & RenderContext) !== NoContext) {
12316 // Use whatever time we're already rendering
12317 return renderExpirationTime;
12318 }
12319
12320 var expirationTime = void 0;
12321 if (suspenseConfig !== null) {
12322 // Compute an expiration time based on the Suspense timeout.
12323 expirationTime = computeSuspenseExpiration(currentTime, suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
12324 } else {
12325 // Compute an expiration time based on the Scheduler priority.
12326 switch (priorityLevel) {
12327 case ImmediatePriority:
12328 expirationTime = Sync;
12329 break;
12330 case UserBlockingPriority:
12331 // TODO: Rename this to computeUserBlockingExpiration
12332 expirationTime = computeInteractiveExpiration(currentTime);
12333 break;
12334 case NormalPriority:
12335 case LowPriority:
12336 // TODO: Handle LowPriority
12337 // TODO: Rename this to... something better.
12338 expirationTime = computeAsyncExpiration(currentTime);
12339 break;
12340 case IdlePriority:
12341 expirationTime = Never;
12342 break;
12343 default:
12344 (function () {
12345 {
12346 {
12347 throw ReactError(Error('Expected a valid priority level'));
12348 }
12349 }
12350 })();
12351 }
12352 }
12353
12354 // If we're in the middle of rendering a tree, do not update at the same
12355 // expiration time that is already rendering.
12356 // TODO: We shouldn't have to do this if the update is on a different root.
12357 // Refactor computeExpirationForFiber + scheduleUpdate so we have access to
12358 // the root when we check for this condition.
12359 if (workInProgressRoot !== null && expirationTime === renderExpirationTime) {
12360 // This is a trick to move this update into a separate batch
12361 expirationTime -= 1;
12362 }
12363
12364 return expirationTime;
12365}
12366
12367
12368
12369function scheduleUpdateOnFiber(fiber, expirationTime) {
12370 checkForNestedUpdates();
12371 warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber);
12372
12373 var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);
12374 if (root === null) {
12375 warnAboutUpdateOnUnmountedFiberInDEV(fiber);
12376 return;
12377 }
12378
12379 root.pingTime = NoWork;
12380
12381 checkForInterruption(fiber, expirationTime);
12382 recordScheduleUpdate();
12383
12384 // TODO: computeExpirationForFiber also reads the priority. Pass the
12385 // priority as an argument to that function and this one.
12386 var priorityLevel = getCurrentPriorityLevel();
12387
12388 if (expirationTime === Sync) {
12389 if (
12390 // Check if we're inside unbatchedUpdates
12391 (executionContext & LegacyUnbatchedContext) !== NoContext &&
12392 // Check if we're not already rendering
12393 (executionContext & (RenderContext | CommitContext)) === NoContext) {
12394 // Register pending interactions on the root to avoid losing traced interaction data.
12395 schedulePendingInteractions(root, expirationTime);
12396
12397 // This is a legacy edge case. The initial mount of a ReactDOM.render-ed
12398 // root inside of batchedUpdates should be synchronous, but layout updates
12399 // should be deferred until the end of the batch.
12400 var callback = renderRoot(root, Sync, true);
12401 while (callback !== null) {
12402 callback = callback(true);
12403 }
12404 } else {
12405 scheduleCallbackForRoot(root, ImmediatePriority, Sync);
12406 if (executionContext === NoContext) {
12407 // Flush the synchronous work now, wnless we're already working or inside
12408 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
12409 // scheduleCallbackForFiber to preserve the ability to schedule a callback
12410 // without immediately flushing it. We only do this for user-initiated
12411 // updates, to preserve historical behavior of sync mode.
12412 flushSyncCallbackQueue();
12413 }
12414 }
12415 } else {
12416 scheduleCallbackForRoot(root, priorityLevel, expirationTime);
12417 }
12418
12419 if ((executionContext & DiscreteEventContext) !== NoContext && (
12420 // Only updates at user-blocking priority or greater are considered
12421 // discrete, even inside a discrete event.
12422 priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority)) {
12423 // This is the result of a discrete event. Track the lowest priority
12424 // discrete update per root so we can flush them early, if needed.
12425 if (rootsWithPendingDiscreteUpdates === null) {
12426 rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);
12427 } else {
12428 var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);
12429 if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {
12430 rootsWithPendingDiscreteUpdates.set(root, expirationTime);
12431 }
12432 }
12433 }
12434}
12435var scheduleWork = scheduleUpdateOnFiber;
12436
12437// This is split into a separate function so we can mark a fiber with pending
12438// work without treating it as a typical update that originates from an event;
12439// e.g. retrying a Suspense boundary isn't an update, but it does schedule work
12440// on a fiber.
12441function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
12442 // Update the source fiber's expiration time
12443 if (fiber.expirationTime < expirationTime) {
12444 fiber.expirationTime = expirationTime;
12445 }
12446 var alternate = fiber.alternate;
12447 if (alternate !== null && alternate.expirationTime < expirationTime) {
12448 alternate.expirationTime = expirationTime;
12449 }
12450 // Walk the parent path to the root and update the child expiration time.
12451 var node = fiber.return;
12452 var root = null;
12453 if (node === null && fiber.tag === HostRoot) {
12454 root = fiber.stateNode;
12455 } else {
12456 while (node !== null) {
12457 alternate = node.alternate;
12458 if (node.childExpirationTime < expirationTime) {
12459 node.childExpirationTime = expirationTime;
12460 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
12461 alternate.childExpirationTime = expirationTime;
12462 }
12463 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
12464 alternate.childExpirationTime = expirationTime;
12465 }
12466 if (node.return === null && node.tag === HostRoot) {
12467 root = node.stateNode;
12468 break;
12469 }
12470 node = node.return;
12471 }
12472 }
12473
12474 if (root !== null) {
12475 // Update the first and last pending expiration times in this root
12476 var firstPendingTime = root.firstPendingTime;
12477 if (expirationTime > firstPendingTime) {
12478 root.firstPendingTime = expirationTime;
12479 }
12480 var lastPendingTime = root.lastPendingTime;
12481 if (lastPendingTime === NoWork || expirationTime < lastPendingTime) {
12482 root.lastPendingTime = expirationTime;
12483 }
12484 }
12485
12486 return root;
12487}
12488
12489// Use this function, along with runRootCallback, to ensure that only a single
12490// callback per root is scheduled. It's still possible to call renderRoot
12491// directly, but scheduling via this function helps avoid excessive callbacks.
12492// It works by storing the callback node and expiration time on the root. When a
12493// new callback comes in, it compares the expiration time to determine if it
12494// should cancel the previous one. It also relies on commitRoot scheduling a
12495// callback to render the next level, because that means we don't need a
12496// separate callback per expiration time.
12497function scheduleCallbackForRoot(root, priorityLevel, expirationTime) {
12498 var existingCallbackExpirationTime = root.callbackExpirationTime;
12499 if (existingCallbackExpirationTime < expirationTime) {
12500 // New callback has higher priority than the existing one.
12501 var existingCallbackNode = root.callbackNode;
12502 if (existingCallbackNode !== null) {
12503 cancelCallback(existingCallbackNode);
12504 }
12505 root.callbackExpirationTime = expirationTime;
12506
12507 if (expirationTime === Sync) {
12508 // Sync React callbacks are scheduled on a special internal queue
12509 root.callbackNode = scheduleSyncCallback(runRootCallback.bind(null, root, renderRoot.bind(null, root, expirationTime)));
12510 } else {
12511 var options = null;
12512 if (!disableSchedulerTimeoutBasedOnReactExpirationTime && expirationTime !== Never) {
12513 var timeout = expirationTimeToMs(expirationTime) - now();
12514 options = { timeout: timeout };
12515 }
12516
12517 root.callbackNode = scheduleCallback(priorityLevel, runRootCallback.bind(null, root, renderRoot.bind(null, root, expirationTime)), options);
12518 if (enableUserTimingAPI && expirationTime !== Sync && (executionContext & (RenderContext | CommitContext)) === NoContext) {
12519 // Scheduled an async callback, and we're not already working. Add an
12520 // entry to the flamegraph that shows we're waiting for a callback
12521 // to fire.
12522 startRequestCallbackTimer();
12523 }
12524 }
12525 }
12526
12527 // Associate the current interactions with this new root+priority.
12528 schedulePendingInteractions(root, expirationTime);
12529}
12530
12531function runRootCallback(root, callback, isSync) {
12532 var prevCallbackNode = root.callbackNode;
12533 var continuation = null;
12534 try {
12535 continuation = callback(isSync);
12536 if (continuation !== null) {
12537 return runRootCallback.bind(null, root, continuation);
12538 } else {
12539 return null;
12540 }
12541 } finally {
12542 // If the callback exits without returning a continuation, remove the
12543 // corresponding callback node from the root. Unless the callback node
12544 // has changed, which implies that it was already cancelled by a high
12545 // priority update.
12546 if (continuation === null && prevCallbackNode === root.callbackNode) {
12547 root.callbackNode = null;
12548 root.callbackExpirationTime = NoWork;
12549 }
12550 }
12551}
12552
12553
12554
12555
12556
12557function resolveLocksOnRoot(root, expirationTime) {
12558 var firstBatch = root.firstBatch;
12559 if (firstBatch !== null && firstBatch._defer && firstBatch._expirationTime >= expirationTime) {
12560 scheduleCallback(NormalPriority, function () {
12561 firstBatch._onComplete();
12562 return null;
12563 });
12564 return true;
12565 } else {
12566 return false;
12567 }
12568}
12569
12570
12571
12572
12573
12574function batchedUpdates(fn, a) {
12575 var prevExecutionContext = executionContext;
12576 executionContext |= BatchedContext;
12577 try {
12578 return fn(a);
12579 } finally {
12580 executionContext = prevExecutionContext;
12581 if (executionContext === NoContext) {
12582 // Flush the immediate callbacks that were scheduled during this batch
12583 flushSyncCallbackQueue();
12584 }
12585 }
12586}
12587
12588
12589
12590
12591
12592
12593
12594function flushSync(fn, a) {
12595 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
12596 (function () {
12597 {
12598 {
12599 throw ReactError(Error('flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.'));
12600 }
12601 }
12602 })();
12603 }
12604 var prevExecutionContext = executionContext;
12605 executionContext |= BatchedContext;
12606 try {
12607 return runWithPriority(ImmediatePriority, fn.bind(null, a));
12608 } finally {
12609 executionContext = prevExecutionContext;
12610 // Flush the immediate callbacks that were scheduled during this batch.
12611 // Note that this will happen even if batchedUpdates is higher up
12612 // the stack.
12613 flushSyncCallbackQueue();
12614 }
12615}
12616
12617
12618
12619function prepareFreshStack(root, expirationTime) {
12620 root.finishedWork = null;
12621 root.finishedExpirationTime = NoWork;
12622
12623 var timeoutHandle = root.timeoutHandle;
12624 if (timeoutHandle !== noTimeout) {
12625 // The root previous suspended and scheduled a timeout to commit a fallback
12626 // state. Now that we have additional work, cancel the timeout.
12627 root.timeoutHandle = noTimeout;
12628 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
12629 cancelTimeout(timeoutHandle);
12630 }
12631
12632 if (workInProgress !== null) {
12633 var interruptedWork = workInProgress.return;
12634 while (interruptedWork !== null) {
12635 unwindInterruptedWork(interruptedWork);
12636 interruptedWork = interruptedWork.return;
12637 }
12638 }
12639 workInProgressRoot = root;
12640 workInProgress = createWorkInProgress(root.current, null, expirationTime);
12641 renderExpirationTime = expirationTime;
12642 workInProgressRootExitStatus = RootIncomplete;
12643 workInProgressRootLatestProcessedExpirationTime = Sync;
12644 workInProgressRootLatestSuspenseTimeout = Sync;
12645 workInProgressRootCanSuspendUsingConfig = null;
12646 workInProgressRootHasPendingPing = false;
12647
12648 if (enableSchedulerTracing) {
12649 spawnedWorkDuringRender = null;
12650 }
12651
12652 {
12653 ReactStrictModeWarnings.discardPendingWarnings();
12654 componentsThatTriggeredHighPriSuspend = null;
12655 }
12656}
12657
12658function renderRoot(root, expirationTime, isSync) {
12659 (function () {
12660 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
12661 {
12662 throw ReactError(Error('Should not already be working.'));
12663 }
12664 }
12665 })();
12666
12667 if (enableUserTimingAPI && expirationTime !== Sync) {
12668 var didExpire = isSync;
12669 stopRequestCallbackTimer(didExpire);
12670 }
12671
12672 if (root.firstPendingTime < expirationTime) {
12673 // If there's no work left at this expiration time, exit immediately. This
12674 // happens when multiple callbacks are scheduled for a single root, but an
12675 // earlier callback flushes the work of a later one.
12676 return null;
12677 }
12678
12679 if (isSync && root.finishedExpirationTime === expirationTime) {
12680 // There's already a pending commit at this expiration time.
12681 // TODO: This is poorly factored. This case only exists for the
12682 // batch.commit() API.
12683 return commitRoot.bind(null, root);
12684 }
12685
12686 flushPassiveEffects();
12687
12688 // If the root or expiration time have changed, throw out the existing stack
12689 // and prepare a fresh one. Otherwise we'll continue where we left off.
12690 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) {
12691 prepareFreshStack(root, expirationTime);
12692 startWorkOnPendingInteractions(root, expirationTime);
12693 } else if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
12694 // We could've received an update at a lower priority while we yielded.
12695 // We're suspended in a delayed state. Once we complete this render we're
12696 // just going to try to recover at the last pending time anyway so we might
12697 // as well start doing that eagerly.
12698 // Ideally we should be able to do this even for retries but we don't yet
12699 // know if we're going to process an update which wants to commit earlier,
12700 // and this path happens very early so it would happen too often. Instead,
12701 // for that case, we'll wait until we complete.
12702 if (workInProgressRootHasPendingPing) {
12703 // We have a ping at this expiration. Let's restart to see if we get unblocked.
12704 prepareFreshStack(root, expirationTime);
12705 } else {
12706 var lastPendingTime = root.lastPendingTime;
12707 if (lastPendingTime < expirationTime) {
12708 // There's lower priority work. It might be unsuspended. Try rendering
12709 // at that level immediately, while preserving the position in the queue.
12710 return renderRoot.bind(null, root, lastPendingTime);
12711 }
12712 }
12713 }
12714
12715 // If we have a work-in-progress fiber, it means there's still work to do
12716 // in this root.
12717 if (workInProgress !== null) {
12718 var prevExecutionContext = executionContext;
12719 executionContext |= RenderContext;
12720 var prevDispatcher = ReactCurrentDispatcher.current;
12721 if (prevDispatcher === null) {
12722 // The React isomorphic package does not include a default dispatcher.
12723 // Instead the first renderer will lazily attach one, in order to give
12724 // nicer error messages.
12725 prevDispatcher = ContextOnlyDispatcher;
12726 }
12727 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
12728 var prevInteractions = null;
12729 if (enableSchedulerTracing) {
12730 prevInteractions = __interactionsRef.current;
12731 __interactionsRef.current = root.memoizedInteractions;
12732 }
12733
12734 startWorkLoopTimer(workInProgress);
12735
12736 // TODO: Fork renderRoot into renderRootSync and renderRootAsync
12737 if (isSync) {
12738 if (expirationTime !== Sync) {
12739 // An async update expired. There may be other expired updates on
12740 // this root. We should render all the expired work in a
12741 // single batch.
12742 var currentTime = requestCurrentTime();
12743 if (currentTime < expirationTime) {
12744 // Restart at the current time.
12745 executionContext = prevExecutionContext;
12746 resetContextDependencies();
12747 ReactCurrentDispatcher.current = prevDispatcher;
12748 if (enableSchedulerTracing) {
12749 __interactionsRef.current = prevInteractions;
12750 }
12751 return renderRoot.bind(null, root, currentTime);
12752 }
12753 }
12754 } else {
12755 // Since we know we're in a React event, we can clear the current
12756 // event time. The next update will compute a new event time.
12757 currentEventTime = NoWork;
12758 }
12759
12760 do {
12761 try {
12762 if (isSync) {
12763 workLoopSync();
12764 } else {
12765 workLoop();
12766 }
12767 break;
12768 } catch (thrownValue) {
12769 // Reset module-level state that was set during the render phase.
12770 resetContextDependencies();
12771 resetHooks();
12772
12773 var sourceFiber = workInProgress;
12774 if (sourceFiber === null || sourceFiber.return === null) {
12775 // Expected to be working on a non-root fiber. This is a fatal error
12776 // because there's no ancestor that can handle it; the root is
12777 // supposed to capture all errors that weren't caught by an error
12778 // boundary.
12779 prepareFreshStack(root, expirationTime);
12780 executionContext = prevExecutionContext;
12781 throw thrownValue;
12782 }
12783
12784 if (enableProfilerTimer && sourceFiber.mode & ProfileMode) {
12785 // Record the time spent rendering before an error was thrown. This
12786 // avoids inaccurate Profiler durations in the case of a
12787 // suspended render.
12788 stopProfilerTimerIfRunningAndRecordDelta(sourceFiber, true);
12789 }
12790
12791 var returnFiber = sourceFiber.return;
12792 throwException(root, returnFiber, sourceFiber, thrownValue, renderExpirationTime);
12793 workInProgress = completeUnitOfWork(sourceFiber);
12794 }
12795 } while (true);
12796
12797 executionContext = prevExecutionContext;
12798 resetContextDependencies();
12799 ReactCurrentDispatcher.current = prevDispatcher;
12800 if (enableSchedulerTracing) {
12801 __interactionsRef.current = prevInteractions;
12802 }
12803
12804 if (workInProgress !== null) {
12805 // There's still work left over. Return a continuation.
12806 stopInterruptedWorkLoopTimer();
12807 if (expirationTime !== Sync) {
12808 startRequestCallbackTimer();
12809 }
12810 return renderRoot.bind(null, root, expirationTime);
12811 }
12812 }
12813
12814 // We now have a consistent tree. The next step is either to commit it, or, if
12815 // something suspended, wait to commit it after a timeout.
12816 stopFinishedWorkLoopTimer();
12817
12818 root.finishedWork = root.current.alternate;
12819 root.finishedExpirationTime = expirationTime;
12820
12821 var isLocked = resolveLocksOnRoot(root, expirationTime);
12822 if (isLocked) {
12823 // This root has a lock that prevents it from committing. Exit. If we begin
12824 // work on the root again, without any intervening updates, it will finish
12825 // without doing additional work.
12826 return null;
12827 }
12828
12829 // Set this to null to indicate there's no in-progress render.
12830 workInProgressRoot = null;
12831
12832 switch (workInProgressRootExitStatus) {
12833 case RootIncomplete:
12834 {
12835 (function () {
12836 {
12837 {
12838 throw ReactError(Error('Should have a work-in-progress.'));
12839 }
12840 }
12841 })();
12842 }
12843 // Flow knows about invariant, so it complains if I add a break statement,
12844 // but eslint doesn't know about invariant, so it complains if I do.
12845 // eslint-disable-next-line no-fallthrough
12846 case RootErrored:
12847 {
12848 // An error was thrown. First check if there is lower priority work
12849 // scheduled on this root.
12850 var _lastPendingTime = root.lastPendingTime;
12851 if (_lastPendingTime < expirationTime) {
12852 // There's lower priority work. Before raising the error, try rendering
12853 // at the lower priority to see if it fixes it. Use a continuation to
12854 // maintain the existing priority and position in the queue.
12855 return renderRoot.bind(null, root, _lastPendingTime);
12856 }
12857 if (!isSync) {
12858 // If we're rendering asynchronously, it's possible the error was
12859 // caused by tearing due to a mutation during an event. Try rendering
12860 // one more time without yiedling to events.
12861 prepareFreshStack(root, expirationTime);
12862 scheduleSyncCallback(renderRoot.bind(null, root, expirationTime));
12863 return null;
12864 }
12865 // If we're already rendering synchronously, commit the root in its
12866 // errored state.
12867 return commitRoot.bind(null, root);
12868 }
12869 case RootSuspended:
12870 {
12871 flushSuspensePriorityWarningInDEV();
12872
12873 // We have an acceptable loading state. We need to figure out if we should
12874 // immediately commit it or wait a bit.
12875
12876 // If we have processed new updates during this render, we may now have a
12877 // new loading state ready. We want to ensure that we commit that as soon as
12878 // possible.
12879 var hasNotProcessedNewUpdates = workInProgressRootLatestProcessedExpirationTime === Sync;
12880 if (hasNotProcessedNewUpdates && !isSync &&
12881 // do not delay if we're inside an act() scope
12882 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current)) {
12883 // If we have not processed any new updates during this pass, then this is
12884 // either a retry of an existing fallback state or a hidden tree.
12885 // Hidden trees shouldn't be batched with other work and after that's
12886 // fixed it can only be a retry.
12887 // We're going to throttle committing retries so that we don't show too
12888 // many loading states too quickly.
12889 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now();
12890 // Don't bother with a very short suspense time.
12891 if (msUntilTimeout > 10) {
12892 if (workInProgressRootHasPendingPing) {
12893 // This render was pinged but we didn't get to restart earlier so try
12894 // restarting now instead.
12895 prepareFreshStack(root, expirationTime);
12896 return renderRoot.bind(null, root, expirationTime);
12897 }
12898 var _lastPendingTime2 = root.lastPendingTime;
12899 if (_lastPendingTime2 < expirationTime) {
12900 // There's lower priority work. It might be unsuspended. Try rendering
12901 // at that level.
12902 return renderRoot.bind(null, root, _lastPendingTime2);
12903 }
12904 // The render is suspended, it hasn't timed out, and there's no lower
12905 // priority work to do. Instead of committing the fallback
12906 // immediately, wait for more data to arrive.
12907 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);
12908 return null;
12909 }
12910 }
12911 // The work expired. Commit immediately.
12912 return commitRoot.bind(null, root);
12913 }
12914 case RootSuspendedWithDelay:
12915 {
12916 flushSuspensePriorityWarningInDEV();
12917
12918 if (!isSync &&
12919 // do not delay if we're inside an act() scope
12920 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current)) {
12921 // We're suspended in a state that should be avoided. We'll try to avoid committing
12922 // it for as long as the timeouts let us.
12923 if (workInProgressRootHasPendingPing) {
12924 // This render was pinged but we didn't get to restart earlier so try
12925 // restarting now instead.
12926 prepareFreshStack(root, expirationTime);
12927 return renderRoot.bind(null, root, expirationTime);
12928 }
12929 var _lastPendingTime3 = root.lastPendingTime;
12930 if (_lastPendingTime3 < expirationTime) {
12931 // There's lower priority work. It might be unsuspended. Try rendering
12932 // at that level immediately.
12933 return renderRoot.bind(null, root, _lastPendingTime3);
12934 }
12935
12936 var _msUntilTimeout = void 0;
12937 if (workInProgressRootLatestSuspenseTimeout !== Sync) {
12938 // We have processed a suspense config whose expiration time we can use as
12939 // the timeout.
12940 _msUntilTimeout = expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now();
12941 } else if (workInProgressRootLatestProcessedExpirationTime === Sync) {
12942 // This should never normally happen because only new updates cause
12943 // delayed states, so we should have processed something. However,
12944 // this could also happen in an offscreen tree.
12945 _msUntilTimeout = 0;
12946 } else {
12947 // If we don't have a suspense config, we're going to use a heuristic to
12948 var eventTimeMs = inferTimeFromExpirationTime(workInProgressRootLatestProcessedExpirationTime);
12949 var currentTimeMs = now();
12950 var timeUntilExpirationMs = expirationTimeToMs(expirationTime) - currentTimeMs;
12951 var timeElapsed = currentTimeMs - eventTimeMs;
12952 if (timeElapsed < 0) {
12953 // We get this wrong some time since we estimate the time.
12954 timeElapsed = 0;
12955 }
12956
12957 _msUntilTimeout = jnd(timeElapsed) - timeElapsed;
12958
12959 // Clamp the timeout to the expiration time.
12960 // TODO: Once the event time is exact instead of inferred from expiration time
12961 // we don't need this.
12962 if (timeUntilExpirationMs < _msUntilTimeout) {
12963 _msUntilTimeout = timeUntilExpirationMs;
12964 }
12965 }
12966
12967 // Don't bother with a very short suspense time.
12968 if (_msUntilTimeout > 10) {
12969 // The render is suspended, it hasn't timed out, and there's no lower
12970 // priority work to do. Instead of committing the fallback
12971 // immediately, wait for more data to arrive.
12972 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);
12973 return null;
12974 }
12975 }
12976 // The work expired. Commit immediately.
12977 return commitRoot.bind(null, root);
12978 }
12979 case RootCompleted:
12980 {
12981 // The work completed. Ready to commit.
12982 if (!isSync &&
12983 // do not delay if we're inside an act() scope
12984 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) && workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null) {
12985 // If we have exceeded the minimum loading delay, which probably
12986 // means we have shown a spinner already, we might have to suspend
12987 // a bit longer to ensure that the spinner is shown for enough time.
12988 var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay(workInProgressRootLatestProcessedExpirationTime, expirationTime, workInProgressRootCanSuspendUsingConfig);
12989 if (_msUntilTimeout2 > 10) {
12990 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout2);
12991 return null;
12992 }
12993 }
12994 return commitRoot.bind(null, root);
12995 }
12996 default:
12997 {
12998 (function () {
12999 {
13000 {
13001 throw ReactError(Error('Unknown root exit status.'));
13002 }
13003 }
13004 })();
13005 }
13006 }
13007}
13008
13009function markCommitTimeOfFallback() {
13010 globalMostRecentFallbackTime = now();
13011}
13012
13013function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) {
13014 if (expirationTime < workInProgressRootLatestProcessedExpirationTime && expirationTime > Never) {
13015 workInProgressRootLatestProcessedExpirationTime = expirationTime;
13016 }
13017 if (suspenseConfig !== null) {
13018 if (expirationTime < workInProgressRootLatestSuspenseTimeout && expirationTime > Never) {
13019 workInProgressRootLatestSuspenseTimeout = expirationTime;
13020 // Most of the time we only have one config and getting wrong is not bad.
13021 workInProgressRootCanSuspendUsingConfig = suspenseConfig;
13022 }
13023 }
13024}
13025
13026function renderDidSuspend() {
13027 if (workInProgressRootExitStatus === RootIncomplete) {
13028 workInProgressRootExitStatus = RootSuspended;
13029 }
13030}
13031
13032function renderDidSuspendDelayIfPossible() {
13033 if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {
13034 workInProgressRootExitStatus = RootSuspendedWithDelay;
13035 }
13036}
13037
13038function renderDidError() {
13039 if (workInProgressRootExitStatus !== RootCompleted) {
13040 workInProgressRootExitStatus = RootErrored;
13041 }
13042}
13043
13044// Called during render to determine if anything has suspended.
13045// Returns false if we're not sure.
13046function renderHasNotSuspendedYet() {
13047 // If something errored or completed, we can't really be sure,
13048 // so those are false.
13049 return workInProgressRootExitStatus === RootIncomplete;
13050}
13051
13052function inferTimeFromExpirationTime(expirationTime) {
13053 // We don't know exactly when the update was scheduled, but we can infer an
13054 // approximate start time from the expiration time.
13055 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
13056 return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
13057}
13058
13059function inferTimeFromExpirationTimeWithSuspenseConfig(expirationTime, suspenseConfig) {
13060 // We don't know exactly when the update was scheduled, but we can infer an
13061 // approximate start time from the expiration time by subtracting the timeout
13062 // that was added to the event time.
13063 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
13064 return earliestExpirationTimeMs - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
13065}
13066
13067function workLoopSync() {
13068 // Already timed out, so perform work without checking if we need to yield.
13069 while (workInProgress !== null) {
13070 workInProgress = performUnitOfWork(workInProgress);
13071 }
13072}
13073
13074function workLoop() {
13075 // Perform work until Scheduler asks us to yield
13076 while (workInProgress !== null && !shouldYield()) {
13077 workInProgress = performUnitOfWork(workInProgress);
13078 }
13079}
13080
13081function performUnitOfWork(unitOfWork) {
13082 // The current, flushed, state of this fiber is the alternate. Ideally
13083 // nothing should rely on this, but relying on it here means that we don't
13084 // need an additional field on the work in progress.
13085 var current$$1 = unitOfWork.alternate;
13086
13087 startWorkTimer(unitOfWork);
13088 setCurrentFiber(unitOfWork);
13089
13090 var next = void 0;
13091 if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) {
13092 startProfilerTimer(unitOfWork);
13093 next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime);
13094 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
13095 } else {
13096 next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime);
13097 }
13098
13099 resetCurrentFiber();
13100 unitOfWork.memoizedProps = unitOfWork.pendingProps;
13101 if (next === null) {
13102 // If this doesn't spawn new work, complete the current work.
13103 next = completeUnitOfWork(unitOfWork);
13104 }
13105
13106 ReactCurrentOwner$1.current = null;
13107 return next;
13108}
13109
13110function completeUnitOfWork(unitOfWork) {
13111 // Attempt to complete the current unit of work, then move to the next
13112 // sibling. If there are no more siblings, return to the parent fiber.
13113 workInProgress = unitOfWork;
13114 do {
13115 // The current, flushed, state of this fiber is the alternate. Ideally
13116 // nothing should rely on this, but relying on it here means that we don't
13117 // need an additional field on the work in progress.
13118 var current$$1 = workInProgress.alternate;
13119 var returnFiber = workInProgress.return;
13120
13121 // Check if the work completed or if something threw.
13122 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
13123 setCurrentFiber(workInProgress);
13124 var next = void 0;
13125 if (!enableProfilerTimer || (workInProgress.mode & ProfileMode) === NoMode) {
13126 next = completeWork(current$$1, workInProgress, renderExpirationTime);
13127 } else {
13128 startProfilerTimer(workInProgress);
13129 next = completeWork(current$$1, workInProgress, renderExpirationTime);
13130 // Update render duration assuming we didn't error.
13131 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
13132 }
13133 stopWorkTimer(workInProgress);
13134 resetCurrentFiber();
13135 resetChildExpirationTime(workInProgress);
13136
13137 if (next !== null) {
13138 // Completing this fiber spawned new work. Work on that next.
13139 return next;
13140 }
13141
13142 if (returnFiber !== null &&
13143 // Do not append effects to parents if a sibling failed to complete
13144 (returnFiber.effectTag & Incomplete) === NoEffect) {
13145 // Append all the effects of the subtree and this fiber onto the effect
13146 // list of the parent. The completion order of the children affects the
13147 // side-effect order.
13148 if (returnFiber.firstEffect === null) {
13149 returnFiber.firstEffect = workInProgress.firstEffect;
13150 }
13151 if (workInProgress.lastEffect !== null) {
13152 if (returnFiber.lastEffect !== null) {
13153 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
13154 }
13155 returnFiber.lastEffect = workInProgress.lastEffect;
13156 }
13157
13158 // If this fiber had side-effects, we append it AFTER the children's
13159 // side-effects. We can perform certain side-effects earlier if needed,
13160 // by doing multiple passes over the effect list. We don't want to
13161 // schedule our own side-effect on our own list because if end up
13162 // reusing children we'll schedule this effect onto itself since we're
13163 // at the end.
13164 var effectTag = workInProgress.effectTag;
13165
13166 // Skip both NoWork and PerformedWork tags when creating the effect
13167 // list. PerformedWork effect is read by React DevTools but shouldn't be
13168 // committed.
13169 if (effectTag > PerformedWork) {
13170 if (returnFiber.lastEffect !== null) {
13171 returnFiber.lastEffect.nextEffect = workInProgress;
13172 } else {
13173 returnFiber.firstEffect = workInProgress;
13174 }
13175 returnFiber.lastEffect = workInProgress;
13176 }
13177 }
13178 } else {
13179 // This fiber did not complete because something threw. Pop values off
13180 // the stack without entering the complete phase. If this is a boundary,
13181 // capture values if possible.
13182 var _next = unwindWork(workInProgress, renderExpirationTime);
13183
13184 // Because this fiber did not complete, don't reset its expiration time.
13185
13186 if (enableProfilerTimer && (workInProgress.mode & ProfileMode) !== NoMode) {
13187 // Record the render duration for the fiber that errored.
13188 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
13189
13190 // Include the time spent working on failed children before continuing.
13191 var actualDuration = workInProgress.actualDuration;
13192 var child = workInProgress.child;
13193 while (child !== null) {
13194 actualDuration += child.actualDuration;
13195 child = child.sibling;
13196 }
13197 workInProgress.actualDuration = actualDuration;
13198 }
13199
13200 if (_next !== null) {
13201 // If completing this work spawned new work, do that next. We'll come
13202 // back here again.
13203 // Since we're restarting, remove anything that is not a host effect
13204 // from the effect tag.
13205 // TODO: The name stopFailedWorkTimer is misleading because Suspense
13206 // also captures and restarts.
13207 stopFailedWorkTimer(workInProgress);
13208 _next.effectTag &= HostEffectMask;
13209 return _next;
13210 }
13211 stopWorkTimer(workInProgress);
13212
13213 if (returnFiber !== null) {
13214 // Mark the parent fiber as incomplete and clear its effect list.
13215 returnFiber.firstEffect = returnFiber.lastEffect = null;
13216 returnFiber.effectTag |= Incomplete;
13217 }
13218 }
13219
13220 var siblingFiber = workInProgress.sibling;
13221 if (siblingFiber !== null) {
13222 // If there is more work to do in this returnFiber, do that next.
13223 return siblingFiber;
13224 }
13225 // Otherwise, return to the parent
13226 workInProgress = returnFiber;
13227 } while (workInProgress !== null);
13228
13229 // We've reached the root.
13230 if (workInProgressRootExitStatus === RootIncomplete) {
13231 workInProgressRootExitStatus = RootCompleted;
13232 }
13233 return null;
13234}
13235
13236function resetChildExpirationTime(completedWork) {
13237 if (renderExpirationTime !== Never && completedWork.childExpirationTime === Never) {
13238 // The children of this component are hidden. Don't bubble their
13239 // expiration times.
13240 return;
13241 }
13242
13243 var newChildExpirationTime = NoWork;
13244
13245 // Bubble up the earliest expiration time.
13246 if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) {
13247 // In profiling mode, resetChildExpirationTime is also used to reset
13248 // profiler durations.
13249 var actualDuration = completedWork.actualDuration;
13250 var treeBaseDuration = completedWork.selfBaseDuration;
13251
13252 // When a fiber is cloned, its actualDuration is reset to 0. This value will
13253 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
13254 // When work is done, it should bubble to the parent's actualDuration. If
13255 // the fiber has not been cloned though, (meaning no work was done), then
13256 // this value will reflect the amount of time spent working on a previous
13257 // render. In that case it should not bubble. We determine whether it was
13258 // cloned by comparing the child pointer.
13259 var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;
13260
13261 var child = completedWork.child;
13262 while (child !== null) {
13263 var childUpdateExpirationTime = child.expirationTime;
13264 var childChildExpirationTime = child.childExpirationTime;
13265 if (childUpdateExpirationTime > newChildExpirationTime) {
13266 newChildExpirationTime = childUpdateExpirationTime;
13267 }
13268 if (childChildExpirationTime > newChildExpirationTime) {
13269 newChildExpirationTime = childChildExpirationTime;
13270 }
13271 if (shouldBubbleActualDurations) {
13272 actualDuration += child.actualDuration;
13273 }
13274 treeBaseDuration += child.treeBaseDuration;
13275 child = child.sibling;
13276 }
13277 completedWork.actualDuration = actualDuration;
13278 completedWork.treeBaseDuration = treeBaseDuration;
13279 } else {
13280 var _child = completedWork.child;
13281 while (_child !== null) {
13282 var _childUpdateExpirationTime = _child.expirationTime;
13283 var _childChildExpirationTime = _child.childExpirationTime;
13284 if (_childUpdateExpirationTime > newChildExpirationTime) {
13285 newChildExpirationTime = _childUpdateExpirationTime;
13286 }
13287 if (_childChildExpirationTime > newChildExpirationTime) {
13288 newChildExpirationTime = _childChildExpirationTime;
13289 }
13290 _child = _child.sibling;
13291 }
13292 }
13293
13294 completedWork.childExpirationTime = newChildExpirationTime;
13295}
13296
13297function commitRoot(root) {
13298 var renderPriorityLevel = getCurrentPriorityLevel();
13299 runWithPriority(ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel));
13300 // If there are passive effects, schedule a callback to flush them. This goes
13301 // outside commitRootImpl so that it inherits the priority of the render.
13302 if (rootWithPendingPassiveEffects !== null) {
13303 scheduleCallback(NormalPriority, function () {
13304 flushPassiveEffects();
13305 return null;
13306 });
13307 }
13308 return null;
13309}
13310
13311function commitRootImpl(root, renderPriorityLevel) {
13312 flushPassiveEffects();
13313 flushRenderPhaseStrictModeWarningsInDEV();
13314
13315 (function () {
13316 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
13317 {
13318 throw ReactError(Error('Should not already be working.'));
13319 }
13320 }
13321 })();
13322
13323 var finishedWork = root.finishedWork;
13324 var expirationTime = root.finishedExpirationTime;
13325 if (finishedWork === null) {
13326 return null;
13327 }
13328 root.finishedWork = null;
13329 root.finishedExpirationTime = NoWork;
13330
13331 (function () {
13332 if (!(finishedWork !== root.current)) {
13333 {
13334 throw ReactError(Error('Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue.'));
13335 }
13336 }
13337 })();
13338
13339 // commitRoot never returns a continuation; it always finishes synchronously.
13340 // So we can clear these now to allow a new callback to be scheduled.
13341 root.callbackNode = null;
13342 root.callbackExpirationTime = NoWork;
13343
13344 startCommitTimer();
13345
13346 // Update the first and last pending times on this root. The new first
13347 // pending time is whatever is left on the root fiber.
13348 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime;
13349 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;
13350 var firstPendingTimeBeforeCommit = childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit ? childExpirationTimeBeforeCommit : updateExpirationTimeBeforeCommit;
13351 root.firstPendingTime = firstPendingTimeBeforeCommit;
13352 if (firstPendingTimeBeforeCommit < root.lastPendingTime) {
13353 // This usually means we've finished all the work, but it can also happen
13354 // when something gets downprioritized during render, like a hidden tree.
13355 root.lastPendingTime = firstPendingTimeBeforeCommit;
13356 }
13357
13358 if (root === workInProgressRoot) {
13359 // We can reset these now that they are finished.
13360 workInProgressRoot = null;
13361 workInProgress = null;
13362 renderExpirationTime = NoWork;
13363 } else {}
13364 // This indicates that the last root we worked on is not the same one that
13365 // we're committing now. This most commonly happens when a suspended root
13366 // times out.
13367
13368
13369 // Get the list of effects.
13370 var firstEffect = void 0;
13371 if (finishedWork.effectTag > PerformedWork) {
13372 // A fiber's effect list consists only of its children, not itself. So if
13373 // the root has an effect, we need to add it to the end of the list. The
13374 // resulting list is the set that would belong to the root's parent, if it
13375 // had one; that is, all the effects in the tree including the root.
13376 if (finishedWork.lastEffect !== null) {
13377 finishedWork.lastEffect.nextEffect = finishedWork;
13378 firstEffect = finishedWork.firstEffect;
13379 } else {
13380 firstEffect = finishedWork;
13381 }
13382 } else {
13383 // There is no effect on the root.
13384 firstEffect = finishedWork.firstEffect;
13385 }
13386
13387 if (firstEffect !== null) {
13388 var prevExecutionContext = executionContext;
13389 executionContext |= CommitContext;
13390 var prevInteractions = null;
13391 if (enableSchedulerTracing) {
13392 prevInteractions = __interactionsRef.current;
13393 __interactionsRef.current = root.memoizedInteractions;
13394 }
13395
13396 // Reset this to null before calling lifecycles
13397 ReactCurrentOwner$1.current = null;
13398
13399 // The commit phase is broken into several sub-phases. We do a separate pass
13400 // of the effect list for each phase: all mutation effects come before all
13401 // layout effects, and so on.
13402
13403 // The first phase a "before mutation" phase. We use this phase to read the
13404 // state of the host tree right before we mutate it. This is where
13405 // getSnapshotBeforeUpdate is called.
13406 startCommitSnapshotEffectsTimer();
13407 prepareForCommit(root.containerInfo);
13408 nextEffect = firstEffect;
13409 do {
13410 {
13411 invokeGuardedCallback(null, commitBeforeMutationEffects, null);
13412 if (hasCaughtError()) {
13413 (function () {
13414 if (!(nextEffect !== null)) {
13415 {
13416 throw ReactError(Error('Should be working on an effect.'));
13417 }
13418 }
13419 })();
13420 var error = clearCaughtError();
13421 captureCommitPhaseError(nextEffect, error);
13422 nextEffect = nextEffect.nextEffect;
13423 }
13424 }
13425 } while (nextEffect !== null);
13426 stopCommitSnapshotEffectsTimer();
13427
13428 if (enableProfilerTimer) {
13429 // Mark the current commit time to be shared by all Profilers in this
13430 // batch. This enables them to be grouped later.
13431 recordCommitTime();
13432 }
13433
13434 // The next phase is the mutation phase, where we mutate the host tree.
13435 startCommitHostEffectsTimer();
13436 nextEffect = firstEffect;
13437 do {
13438 {
13439 invokeGuardedCallback(null, commitMutationEffects, null, renderPriorityLevel);
13440 if (hasCaughtError()) {
13441 (function () {
13442 if (!(nextEffect !== null)) {
13443 {
13444 throw ReactError(Error('Should be working on an effect.'));
13445 }
13446 }
13447 })();
13448 var _error = clearCaughtError();
13449 captureCommitPhaseError(nextEffect, _error);
13450 nextEffect = nextEffect.nextEffect;
13451 }
13452 }
13453 } while (nextEffect !== null);
13454 stopCommitHostEffectsTimer();
13455 resetAfterCommit(root.containerInfo);
13456
13457 // The work-in-progress tree is now the current tree. This must come after
13458 // the mutation phase, so that the previous tree is still current during
13459 // componentWillUnmount, but before the layout phase, so that the finished
13460 // work is current during componentDidMount/Update.
13461 root.current = finishedWork;
13462
13463 // The next phase is the layout phase, where we call effects that read
13464 // the host tree after it's been mutated. The idiomatic use case for this is
13465 // layout, but class component lifecycles also fire here for legacy reasons.
13466 startCommitLifeCyclesTimer();
13467 nextEffect = firstEffect;
13468 do {
13469 {
13470 invokeGuardedCallback(null, commitLayoutEffects, null, root, expirationTime);
13471 if (hasCaughtError()) {
13472 (function () {
13473 if (!(nextEffect !== null)) {
13474 {
13475 throw ReactError(Error('Should be working on an effect.'));
13476 }
13477 }
13478 })();
13479 var _error2 = clearCaughtError();
13480 captureCommitPhaseError(nextEffect, _error2);
13481 nextEffect = nextEffect.nextEffect;
13482 }
13483 }
13484 } while (nextEffect !== null);
13485 stopCommitLifeCyclesTimer();
13486
13487 nextEffect = null;
13488
13489 // Tell Scheduler to yield at the end of the frame, so the browser has an
13490 // opportunity to paint.
13491 requestPaint();
13492
13493 if (enableSchedulerTracing) {
13494 __interactionsRef.current = prevInteractions;
13495 }
13496 executionContext = prevExecutionContext;
13497 } else {
13498 // No effects.
13499 root.current = finishedWork;
13500 // Measure these anyway so the flamegraph explicitly shows that there were
13501 // no effects.
13502 // TODO: Maybe there's a better way to report this.
13503 startCommitSnapshotEffectsTimer();
13504 stopCommitSnapshotEffectsTimer();
13505 if (enableProfilerTimer) {
13506 recordCommitTime();
13507 }
13508 startCommitHostEffectsTimer();
13509 stopCommitHostEffectsTimer();
13510 startCommitLifeCyclesTimer();
13511 stopCommitLifeCyclesTimer();
13512 }
13513
13514 stopCommitTimer();
13515
13516 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
13517
13518 if (rootDoesHavePassiveEffects) {
13519 // This commit has passive effects. Stash a reference to them. But don't
13520 // schedule a callback until after flushing layout work.
13521 rootDoesHavePassiveEffects = false;
13522 rootWithPendingPassiveEffects = root;
13523 pendingPassiveEffectsExpirationTime = expirationTime;
13524 pendingPassiveEffectsRenderPriority = renderPriorityLevel;
13525 } else {
13526 // We are done with the effect chain at this point so let's clear the
13527 // nextEffect pointers to assist with GC. If we have passive effects, we'll
13528 // clear this in flushPassiveEffects.
13529 nextEffect = firstEffect;
13530 while (nextEffect !== null) {
13531 var nextNextEffect = nextEffect.nextEffect;
13532 nextEffect.nextEffect = null;
13533 nextEffect = nextNextEffect;
13534 }
13535 }
13536
13537 // Check if there's remaining work on this root
13538 var remainingExpirationTime = root.firstPendingTime;
13539 if (remainingExpirationTime !== NoWork) {
13540 var currentTime = requestCurrentTime();
13541 var priorityLevel = inferPriorityFromExpirationTime(currentTime, remainingExpirationTime);
13542
13543 if (enableSchedulerTracing) {
13544 if (spawnedWorkDuringRender !== null) {
13545 var expirationTimes = spawnedWorkDuringRender;
13546 spawnedWorkDuringRender = null;
13547 for (var i = 0; i < expirationTimes.length; i++) {
13548 scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);
13549 }
13550 }
13551 }
13552
13553 scheduleCallbackForRoot(root, priorityLevel, remainingExpirationTime);
13554 } else {
13555 // If there's no remaining work, we can clear the set of already failed
13556 // error boundaries.
13557 legacyErrorBoundariesThatAlreadyFailed = null;
13558 }
13559
13560 if (enableSchedulerTracing) {
13561 if (!rootDidHavePassiveEffects) {
13562 // If there are no passive effects, then we can complete the pending interactions.
13563 // Otherwise, we'll wait until after the passive effects are flushed.
13564 // Wait to do this until after remaining work has been scheduled,
13565 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.
13566 finishPendingInteractions(root, expirationTime);
13567 }
13568 }
13569
13570 onCommitRoot(finishedWork.stateNode, expirationTime);
13571
13572 if (remainingExpirationTime === Sync) {
13573 // Count the number of times the root synchronously re-renders without
13574 // finishing. If there are too many, it indicates an infinite update loop.
13575 if (root === rootWithNestedUpdates) {
13576 nestedUpdateCount++;
13577 } else {
13578 nestedUpdateCount = 0;
13579 rootWithNestedUpdates = root;
13580 }
13581 } else {
13582 nestedUpdateCount = 0;
13583 }
13584
13585 if (hasUncaughtError) {
13586 hasUncaughtError = false;
13587 var _error3 = firstUncaughtError;
13588 firstUncaughtError = null;
13589 throw _error3;
13590 }
13591
13592 if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
13593 // This is a legacy edge case. We just committed the initial mount of
13594 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
13595 // synchronously, but layout updates should be deferred until the end
13596 // of the batch.
13597 return null;
13598 }
13599
13600 // If layout work was scheduled, flush it now.
13601 flushSyncCallbackQueue();
13602 return null;
13603}
13604
13605function commitBeforeMutationEffects() {
13606 while (nextEffect !== null) {
13607 if ((nextEffect.effectTag & Snapshot) !== NoEffect) {
13608 setCurrentFiber(nextEffect);
13609 recordEffect();
13610
13611 var current$$1 = nextEffect.alternate;
13612 commitBeforeMutationLifeCycles(current$$1, nextEffect);
13613
13614 resetCurrentFiber();
13615 }
13616 nextEffect = nextEffect.nextEffect;
13617 }
13618}
13619
13620function commitMutationEffects(renderPriorityLevel) {
13621 // TODO: Should probably move the bulk of this function to commitWork.
13622 while (nextEffect !== null) {
13623 setCurrentFiber(nextEffect);
13624
13625 var effectTag = nextEffect.effectTag;
13626
13627 if (effectTag & ContentReset) {
13628 commitResetTextContent(nextEffect);
13629 }
13630
13631 if (effectTag & Ref) {
13632 var current$$1 = nextEffect.alternate;
13633 if (current$$1 !== null) {
13634 commitDetachRef(current$$1);
13635 }
13636 }
13637
13638 // The following switch statement is only concerned about placement,
13639 // updates, and deletions. To avoid needing to add a case for every possible
13640 // bitmap value, we remove the secondary effects from the effect tag and
13641 // switch on that value.
13642 var primaryEffectTag = effectTag & (Placement | Update | Deletion);
13643 switch (primaryEffectTag) {
13644 case Placement:
13645 {
13646 commitPlacement(nextEffect);
13647 // Clear the "placement" from effect tag so that we know that this is
13648 // inserted, before any life-cycles like componentDidMount gets called.
13649 // TODO: findDOMNode doesn't rely on this any more but isMounted does
13650 // and isMounted is deprecated anyway so we should be able to kill this.
13651 nextEffect.effectTag &= ~Placement;
13652 break;
13653 }
13654 case PlacementAndUpdate:
13655 {
13656 // Placement
13657 commitPlacement(nextEffect);
13658 // Clear the "placement" from effect tag so that we know that this is
13659 // inserted, before any life-cycles like componentDidMount gets called.
13660 nextEffect.effectTag &= ~Placement;
13661
13662 // Update
13663 var _current = nextEffect.alternate;
13664 commitWork(_current, nextEffect);
13665 break;
13666 }
13667 case Update:
13668 {
13669 var _current2 = nextEffect.alternate;
13670 commitWork(_current2, nextEffect);
13671 break;
13672 }
13673 case Deletion:
13674 {
13675 commitDeletion(nextEffect, renderPriorityLevel);
13676 break;
13677 }
13678 }
13679
13680 // TODO: Only record a mutation effect if primaryEffectTag is non-zero.
13681 recordEffect();
13682
13683 resetCurrentFiber();
13684 nextEffect = nextEffect.nextEffect;
13685 }
13686}
13687
13688function commitLayoutEffects(root, committedExpirationTime) {
13689 // TODO: Should probably move the bulk of this function to commitWork.
13690 while (nextEffect !== null) {
13691 setCurrentFiber(nextEffect);
13692
13693 var effectTag = nextEffect.effectTag;
13694
13695 if (effectTag & (Update | Callback)) {
13696 recordEffect();
13697 var current$$1 = nextEffect.alternate;
13698 commitLifeCycles(root, current$$1, nextEffect, committedExpirationTime);
13699 }
13700
13701 if (effectTag & Ref) {
13702 recordEffect();
13703 commitAttachRef(nextEffect);
13704 }
13705
13706 if (effectTag & Passive) {
13707 rootDoesHavePassiveEffects = true;
13708 }
13709
13710 resetCurrentFiber();
13711 nextEffect = nextEffect.nextEffect;
13712 }
13713}
13714
13715function flushPassiveEffects() {
13716 if (rootWithPendingPassiveEffects === null) {
13717 return false;
13718 }
13719 var root = rootWithPendingPassiveEffects;
13720 var expirationTime = pendingPassiveEffectsExpirationTime;
13721 var renderPriorityLevel = pendingPassiveEffectsRenderPriority;
13722 rootWithPendingPassiveEffects = null;
13723 pendingPassiveEffectsExpirationTime = NoWork;
13724 pendingPassiveEffectsRenderPriority = NoPriority;
13725 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
13726 return runWithPriority(priorityLevel, flushPassiveEffectsImpl.bind(null, root, expirationTime));
13727}
13728
13729function flushPassiveEffectsImpl(root, expirationTime) {
13730 var prevInteractions = null;
13731 if (enableSchedulerTracing) {
13732 prevInteractions = __interactionsRef.current;
13733 __interactionsRef.current = root.memoizedInteractions;
13734 }
13735
13736 (function () {
13737 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
13738 {
13739 throw ReactError(Error('Cannot flush passive effects while already rendering.'));
13740 }
13741 }
13742 })();
13743 var prevExecutionContext = executionContext;
13744 executionContext |= CommitContext;
13745
13746 // Note: This currently assumes there are no passive effects on the root
13747 // fiber, because the root is not part of its own effect list. This could
13748 // change in the future.
13749 var effect = root.current.firstEffect;
13750 while (effect !== null) {
13751 {
13752 setCurrentFiber(effect);
13753 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
13754 if (hasCaughtError()) {
13755 (function () {
13756 if (!(effect !== null)) {
13757 {
13758 throw ReactError(Error('Should be working on an effect.'));
13759 }
13760 }
13761 })();
13762 var error = clearCaughtError();
13763 captureCommitPhaseError(effect, error);
13764 }
13765 resetCurrentFiber();
13766 }
13767 var nextNextEffect = effect.nextEffect;
13768 // Remove nextEffect pointer to assist GC
13769 effect.nextEffect = null;
13770 effect = nextNextEffect;
13771 }
13772
13773 if (enableSchedulerTracing) {
13774 __interactionsRef.current = prevInteractions;
13775 finishPendingInteractions(root, expirationTime);
13776 }
13777
13778 executionContext = prevExecutionContext;
13779 flushSyncCallbackQueue();
13780
13781 // If additional passive effects were scheduled, increment a counter. If this
13782 // exceeds the limit, we'll fire a warning.
13783 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
13784
13785 return true;
13786}
13787
13788function isAlreadyFailedLegacyErrorBoundary(instance) {
13789 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
13790}
13791
13792function markLegacyErrorBoundaryAsFailed(instance) {
13793 if (legacyErrorBoundariesThatAlreadyFailed === null) {
13794 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
13795 } else {
13796 legacyErrorBoundariesThatAlreadyFailed.add(instance);
13797 }
13798}
13799
13800function prepareToThrowUncaughtError(error) {
13801 if (!hasUncaughtError) {
13802 hasUncaughtError = true;
13803 firstUncaughtError = error;
13804 }
13805}
13806var onUncaughtError = prepareToThrowUncaughtError;
13807
13808function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
13809 var errorInfo = createCapturedValue(error, sourceFiber);
13810 var update = createRootErrorUpdate(rootFiber, errorInfo, Sync);
13811 enqueueUpdate(rootFiber, update);
13812 var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);
13813 if (root !== null) {
13814 scheduleCallbackForRoot(root, ImmediatePriority, Sync);
13815 }
13816}
13817
13818function captureCommitPhaseError(sourceFiber, error) {
13819 if (sourceFiber.tag === HostRoot) {
13820 // Error was thrown at the root. There is no parent, so the root
13821 // itself should capture it.
13822 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);
13823 return;
13824 }
13825
13826 var fiber = sourceFiber.return;
13827 while (fiber !== null) {
13828 if (fiber.tag === HostRoot) {
13829 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);
13830 return;
13831 } else if (fiber.tag === ClassComponent) {
13832 var ctor = fiber.type;
13833 var instance = fiber.stateNode;
13834 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
13835 var errorInfo = createCapturedValue(error, sourceFiber);
13836 var update = createClassErrorUpdate(fiber, errorInfo,
13837 // TODO: This is always sync
13838 Sync);
13839 enqueueUpdate(fiber, update);
13840 var root = markUpdateTimeFromFiberToRoot(fiber, Sync);
13841 if (root !== null) {
13842 scheduleCallbackForRoot(root, ImmediatePriority, Sync);
13843 }
13844 return;
13845 }
13846 }
13847 fiber = fiber.return;
13848 }
13849}
13850
13851function pingSuspendedRoot(root, thenable, suspendedTime) {
13852 var pingCache = root.pingCache;
13853 if (pingCache !== null) {
13854 // The thenable resolved, so we no longer need to memoize, because it will
13855 // never be thrown again.
13856 pingCache.delete(thenable);
13857 }
13858
13859 if (workInProgressRoot === root && renderExpirationTime === suspendedTime) {
13860 // Received a ping at the same priority level at which we're currently
13861 // rendering. We might want to restart this render. This should mirror
13862 // the logic of whether or not a root suspends once it completes.
13863
13864 // TODO: If we're rendering sync either due to Sync, Batched or expired,
13865 // we should probably never restart.
13866
13867 // If we're suspended with delay, we'll always suspend so we can always
13868 // restart. If we're suspended without any updates, it might be a retry.
13869 // If it's early in the retry we can restart. We can't know for sure
13870 // whether we'll eventually process an update during this render pass,
13871 // but it's somewhat unlikely that we get to a ping before that, since
13872 // getting to the root most update is usually very fast.
13873 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && workInProgressRootLatestProcessedExpirationTime === Sync && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
13874 // Restart from the root. Don't need to schedule a ping because
13875 // we're already working on this tree.
13876 prepareFreshStack(root, renderExpirationTime);
13877 } else {
13878 // Even though we can't restart right now, we might get an
13879 // opportunity later. So we mark this render as having a ping.
13880 workInProgressRootHasPendingPing = true;
13881 }
13882 return;
13883 }
13884
13885 var lastPendingTime = root.lastPendingTime;
13886 if (lastPendingTime < suspendedTime) {
13887 // The root is no longer suspended at this time.
13888 return;
13889 }
13890
13891 var pingTime = root.pingTime;
13892 if (pingTime !== NoWork && pingTime < suspendedTime) {
13893 // There's already a lower priority ping scheduled.
13894 return;
13895 }
13896
13897 // Mark the time at which this ping was scheduled.
13898 root.pingTime = suspendedTime;
13899
13900 if (root.finishedExpirationTime === suspendedTime) {
13901 // If there's a pending fallback waiting to commit, throw it away.
13902 root.finishedExpirationTime = NoWork;
13903 root.finishedWork = null;
13904 }
13905
13906 var currentTime = requestCurrentTime();
13907 var priorityLevel = inferPriorityFromExpirationTime(currentTime, suspendedTime);
13908 scheduleCallbackForRoot(root, priorityLevel, suspendedTime);
13909}
13910
13911function retryTimedOutBoundary(boundaryFiber) {
13912 // The boundary fiber (a Suspense component or SuspenseList component)
13913 // previously was rendered in its fallback state. One of the promises that
13914 // suspended it has resolved, which means at least part of the tree was
13915 // likely unblocked. Try rendering again, at a new expiration time.
13916 var currentTime = requestCurrentTime();
13917 var suspenseConfig = null; // Retries don't carry over the already committed update.
13918 var retryTime = computeExpirationForFiber(currentTime, boundaryFiber, suspenseConfig);
13919 // TODO: Special case idle priority?
13920 var priorityLevel = inferPriorityFromExpirationTime(currentTime, retryTime);
13921 var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);
13922 if (root !== null) {
13923 scheduleCallbackForRoot(root, priorityLevel, retryTime);
13924 }
13925}
13926
13927function resolveRetryThenable(boundaryFiber, thenable) {
13928 var retryCache = void 0;
13929 if (enableSuspenseServerRenderer) {
13930 switch (boundaryFiber.tag) {
13931 case SuspenseComponent:
13932 retryCache = boundaryFiber.stateNode;
13933 break;
13934 case DehydratedSuspenseComponent:
13935 retryCache = boundaryFiber.memoizedState;
13936 break;
13937 default:
13938 (function () {
13939 {
13940 {
13941 throw ReactError(Error('Pinged unknown suspense boundary type. This is probably a bug in React.'));
13942 }
13943 }
13944 })();
13945 }
13946 } else {
13947 retryCache = boundaryFiber.stateNode;
13948 }
13949
13950 if (retryCache !== null) {
13951 // The thenable resolved, so we no longer need to memoize, because it will
13952 // never be thrown again.
13953 retryCache.delete(thenable);
13954 }
13955
13956 retryTimedOutBoundary(boundaryFiber);
13957}
13958
13959// Computes the next Just Noticeable Difference (JND) boundary.
13960// The theory is that a person can't tell the difference between small differences in time.
13961// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
13962// difference in the experience. However, waiting for longer might mean that we can avoid
13963// showing an intermediate loading state. The longer we have already waited, the harder it
13964// is to tell small differences in time. Therefore, the longer we've already waited,
13965// the longer we can wait additionally. At some point we have to give up though.
13966// We pick a train model where the next boundary commits at a consistent schedule.
13967// These particular numbers are vague estimates. We expect to adjust them based on research.
13968function jnd(timeElapsed) {
13969 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
13970}
13971
13972function computeMsUntilSuspenseLoadingDelay(mostRecentEventTime, committedExpirationTime, suspenseConfig) {
13973 var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0;
13974 if (busyMinDurationMs <= 0) {
13975 return 0;
13976 }
13977 var busyDelayMs = suspenseConfig.busyDelayMs | 0;
13978
13979 // Compute the time until this render pass would expire.
13980 var currentTimeMs = now();
13981 var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig(mostRecentEventTime, suspenseConfig);
13982 var timeElapsed = currentTimeMs - eventTimeMs;
13983 if (timeElapsed <= busyDelayMs) {
13984 // If we haven't yet waited longer than the initial delay, we don't
13985 // have to wait any additional time.
13986 return 0;
13987 }
13988 var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed;
13989 // This is the value that is passed to `setTimeout`.
13990 return msUntilTimeout;
13991}
13992
13993function checkForNestedUpdates() {
13994 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
13995 nestedUpdateCount = 0;
13996 rootWithNestedUpdates = null;
13997 (function () {
13998 {
13999 {
14000 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.'));
14001 }
14002 }
14003 })();
14004 }
14005
14006 {
14007 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
14008 nestedPassiveUpdateCount = 0;
14009 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.');
14010 }
14011 }
14012}
14013
14014function flushRenderPhaseStrictModeWarningsInDEV() {
14015 {
14016 ReactStrictModeWarnings.flushLegacyContextWarning();
14017
14018 if (warnAboutDeprecatedLifecycles) {
14019 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
14020 }
14021 }
14022}
14023
14024function stopFinishedWorkLoopTimer() {
14025 var didCompleteRoot = true;
14026 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
14027 interruptedBy = null;
14028}
14029
14030function stopInterruptedWorkLoopTimer() {
14031 // TODO: Track which fiber caused the interruption.
14032 var didCompleteRoot = false;
14033 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
14034 interruptedBy = null;
14035}
14036
14037function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) {
14038 if (enableUserTimingAPI && workInProgressRoot !== null && updateExpirationTime > renderExpirationTime) {
14039 interruptedBy = fiberThatReceivedUpdate;
14040 }
14041}
14042
14043var didWarnStateUpdateForUnmountedComponent = null;
14044function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
14045 {
14046 var tag = fiber.tag;
14047 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent) {
14048 // Only warn for user-defined components, not internal ones like Suspense.
14049 return;
14050 }
14051 // We show the whole stack but dedupe on the top component's name because
14052 // the problematic code almost always lies inside that component.
14053 var componentName = getComponentName(fiber.type) || 'ReactComponent';
14054 if (didWarnStateUpdateForUnmountedComponent !== null) {
14055 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {
14056 return;
14057 }
14058 didWarnStateUpdateForUnmountedComponent.add(componentName);
14059 } else {
14060 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);
14061 }
14062 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));
14063 }
14064}
14065
14066var beginWork$$1 = void 0;
14067if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
14068 var dummyFiber = null;
14069 beginWork$$1 = function (current$$1, unitOfWork, expirationTime) {
14070 // If a component throws an error, we replay it again in a synchronously
14071 // dispatched event, so that the debugger will treat it as an uncaught
14072 // error See ReactErrorUtils for more information.
14073
14074 // Before entering the begin phase, copy the work-in-progress onto a dummy
14075 // fiber. If beginWork throws, we'll use this to reset the state.
14076 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
14077 try {
14078 return beginWork$1(current$$1, unitOfWork, expirationTime);
14079 } catch (originalError) {
14080 if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {
14081 // Don't replay promises. Treat everything else like an error.
14082 throw originalError;
14083 }
14084
14085 // Keep this code in sync with renderRoot; any changes here must have
14086 // corresponding changes there.
14087 resetContextDependencies();
14088 resetHooks();
14089
14090 // Unwind the failed stack frame
14091 unwindInterruptedWork(unitOfWork);
14092
14093 // Restore the original properties of the fiber.
14094 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
14095
14096 if (enableProfilerTimer && unitOfWork.mode & ProfileMode) {
14097 // Reset the profiler timer.
14098 startProfilerTimer(unitOfWork);
14099 }
14100
14101 // Run beginWork again.
14102 invokeGuardedCallback(null, beginWork$1, null, current$$1, unitOfWork, expirationTime);
14103
14104 if (hasCaughtError()) {
14105 var replayError = clearCaughtError();
14106 // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`.
14107 // Rethrow this error instead of the original one.
14108 throw replayError;
14109 } else {
14110 // This branch is reachable if the render phase is impure.
14111 throw originalError;
14112 }
14113 }
14114 };
14115} else {
14116 beginWork$$1 = beginWork$1;
14117}
14118
14119var didWarnAboutUpdateInRender = false;
14120var didWarnAboutUpdateInGetChildContext = false;
14121function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) {
14122 {
14123 if (fiber.tag === ClassComponent) {
14124 switch (phase) {
14125 case 'getChildContext':
14126 if (didWarnAboutUpdateInGetChildContext) {
14127 return;
14128 }
14129 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
14130 didWarnAboutUpdateInGetChildContext = true;
14131 break;
14132 case 'render':
14133 if (didWarnAboutUpdateInRender) {
14134 return;
14135 }
14136 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.');
14137 didWarnAboutUpdateInRender = true;
14138 break;
14139 }
14140 }
14141 }
14142}
14143
14144// a 'shared' variable that changes when act() opens/closes in tests.
14145var IsThisRendererActing = { current: false };
14146
14147function warnIfNotScopedWithMatchingAct(fiber) {
14148 {
14149 if (warnsIfNotActing === true && IsSomeRendererActing.current === true && IsThisRendererActing.current !== true) {
14150 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));
14151 }
14152 }
14153}
14154
14155function warnIfNotCurrentlyActingEffectsInDEV(fiber) {
14156 {
14157 if (warnsIfNotActing === true && (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
14158 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));
14159 }
14160 }
14161}
14162
14163function warnIfNotCurrentlyActingUpdatesInDEV(fiber) {
14164 {
14165 if (warnsIfNotActing === true && executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
14166 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));
14167 }
14168 }
14169}
14170
14171var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV;
14172
14173// In tests, we want to enforce a mocked scheduler.
14174var didWarnAboutUnmockedScheduler = false;
14175// TODO Before we release concurrent mode, revisit this and decide whether a mocked
14176// scheduler is the actual recommendation. The alternative could be a testing build,
14177// a new lib, or whatever; we dunno just yet. This message is for early adopters
14178// to get their tests right.
14179
14180function warnIfUnmockedScheduler(fiber) {
14181 {
14182 if (didWarnAboutUnmockedScheduler === false && Scheduler$1.unstable_flushAllWithoutAsserting === undefined) {
14183 if (fiber.mode & BatchedMode || fiber.mode & ConcurrentMode) {
14184 didWarnAboutUnmockedScheduler = true;
14185 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');
14186 } else if (warnAboutUnmockedScheduler === true) {
14187 didWarnAboutUnmockedScheduler = true;
14188 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');
14189 }
14190 }
14191 }
14192}
14193
14194var componentsThatTriggeredHighPriSuspend = null;
14195function checkForWrongSuspensePriorityInDEV(sourceFiber) {
14196 {
14197 var currentPriorityLevel = getCurrentPriorityLevel();
14198 if ((sourceFiber.mode & ConcurrentMode) !== NoEffect && (currentPriorityLevel === UserBlockingPriority || currentPriorityLevel === ImmediatePriority)) {
14199 var workInProgressNode = sourceFiber;
14200 while (workInProgressNode !== null) {
14201 // Add the component that triggered the suspense
14202 var current$$1 = workInProgressNode.alternate;
14203 if (current$$1 !== null) {
14204 // TODO: warn component that triggers the high priority
14205 // suspend is the HostRoot
14206 switch (workInProgressNode.tag) {
14207 case ClassComponent:
14208 // Loop through the component's update queue and see whether the component
14209 // has triggered any high priority updates
14210 var updateQueue = current$$1.updateQueue;
14211 if (updateQueue !== null) {
14212 var update = updateQueue.firstUpdate;
14213 while (update !== null) {
14214 var priorityLevel = update.priority;
14215 if (priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority) {
14216 if (componentsThatTriggeredHighPriSuspend === null) {
14217 componentsThatTriggeredHighPriSuspend = new Set([getComponentName(workInProgressNode.type)]);
14218 } else {
14219 componentsThatTriggeredHighPriSuspend.add(getComponentName(workInProgressNode.type));
14220 }
14221 break;
14222 }
14223 update = update.next;
14224 }
14225 }
14226 break;
14227 case FunctionComponent:
14228 case ForwardRef:
14229 case SimpleMemoComponent:
14230 if (workInProgressNode.memoizedState !== null && workInProgressNode.memoizedState.baseUpdate !== null) {
14231 var _update = workInProgressNode.memoizedState.baseUpdate;
14232 // Loop through the functional component's memoized state to see whether
14233 // the component has triggered any high pri updates
14234 while (_update !== null) {
14235 var priority = _update.priority;
14236 if (priority === UserBlockingPriority || priority === ImmediatePriority) {
14237 if (componentsThatTriggeredHighPriSuspend === null) {
14238 componentsThatTriggeredHighPriSuspend = new Set([getComponentName(workInProgressNode.type)]);
14239 } else {
14240 componentsThatTriggeredHighPriSuspend.add(getComponentName(workInProgressNode.type));
14241 }
14242 break;
14243 }
14244 if (_update.next === workInProgressNode.memoizedState.baseUpdate) {
14245 break;
14246 }
14247 _update = _update.next;
14248 }
14249 }
14250 break;
14251 default:
14252 break;
14253 }
14254 }
14255 workInProgressNode = workInProgressNode.return;
14256 }
14257 }
14258 }
14259}
14260
14261function flushSuspensePriorityWarningInDEV() {
14262 {
14263 if (componentsThatTriggeredHighPriSuspend !== null) {
14264 var componentNames = [];
14265 componentsThatTriggeredHighPriSuspend.forEach(function (name) {
14266 return componentNames.push(name);
14267 });
14268 componentsThatTriggeredHighPriSuspend = null;
14269
14270 if (componentNames.length > 0) {
14271 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.',
14272 // TODO: Add link to React docs with more information, once it exists
14273 componentNames.sort().join(', '));
14274 }
14275 }
14276 }
14277}
14278
14279function computeThreadID(root, expirationTime) {
14280 // Interaction threads are unique per root and expiration time.
14281 return expirationTime * 1000 + root.interactionThreadID;
14282}
14283
14284function markSpawnedWork(expirationTime) {
14285 if (!enableSchedulerTracing) {
14286 return;
14287 }
14288 if (spawnedWorkDuringRender === null) {
14289 spawnedWorkDuringRender = [expirationTime];
14290 } else {
14291 spawnedWorkDuringRender.push(expirationTime);
14292 }
14293}
14294
14295function scheduleInteractions(root, expirationTime, interactions) {
14296 if (!enableSchedulerTracing) {
14297 return;
14298 }
14299
14300 if (interactions.size > 0) {
14301 var pendingInteractionMap = root.pendingInteractionMap;
14302 var pendingInteractions = pendingInteractionMap.get(expirationTime);
14303 if (pendingInteractions != null) {
14304 interactions.forEach(function (interaction) {
14305 if (!pendingInteractions.has(interaction)) {
14306 // Update the pending async work count for previously unscheduled interaction.
14307 interaction.__count++;
14308 }
14309
14310 pendingInteractions.add(interaction);
14311 });
14312 } else {
14313 pendingInteractionMap.set(expirationTime, new Set(interactions));
14314
14315 // Update the pending async work count for the current interactions.
14316 interactions.forEach(function (interaction) {
14317 interaction.__count++;
14318 });
14319 }
14320
14321 var subscriber = __subscriberRef.current;
14322 if (subscriber !== null) {
14323 var threadID = computeThreadID(root, expirationTime);
14324 subscriber.onWorkScheduled(interactions, threadID);
14325 }
14326 }
14327}
14328
14329function schedulePendingInteractions(root, expirationTime) {
14330 // This is called when work is scheduled on a root.
14331 // It associates the current interactions with the newly-scheduled expiration.
14332 // They will be restored when that expiration is later committed.
14333 if (!enableSchedulerTracing) {
14334 return;
14335 }
14336
14337 scheduleInteractions(root, expirationTime, __interactionsRef.current);
14338}
14339
14340function startWorkOnPendingInteractions(root, expirationTime) {
14341 // This is called when new work is started on a root.
14342 if (!enableSchedulerTracing) {
14343 return;
14344 }
14345
14346 // Determine which interactions this batch of work currently includes, So that
14347 // we can accurately attribute time spent working on it, And so that cascading
14348 // work triggered during the render phase will be associated with it.
14349 var interactions = new Set();
14350 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
14351 if (scheduledExpirationTime >= expirationTime) {
14352 scheduledInteractions.forEach(function (interaction) {
14353 return interactions.add(interaction);
14354 });
14355 }
14356 });
14357
14358 // Store the current set of interactions on the FiberRoot for a few reasons:
14359 // We can re-use it in hot functions like renderRoot() without having to
14360 // recalculate it. We will also use it in commitWork() to pass to any Profiler
14361 // onRender() hooks. This also provides DevTools with a way to access it when
14362 // the onCommitRoot() hook is called.
14363 root.memoizedInteractions = interactions;
14364
14365 if (interactions.size > 0) {
14366 var subscriber = __subscriberRef.current;
14367 if (subscriber !== null) {
14368 var threadID = computeThreadID(root, expirationTime);
14369 try {
14370 subscriber.onWorkStarted(interactions, threadID);
14371 } catch (error) {
14372 // If the subscriber throws, rethrow it in a separate task
14373 scheduleCallback(ImmediatePriority, function () {
14374 throw error;
14375 });
14376 }
14377 }
14378 }
14379}
14380
14381function finishPendingInteractions(root, committedExpirationTime) {
14382 if (!enableSchedulerTracing) {
14383 return;
14384 }
14385
14386 var earliestRemainingTimeAfterCommit = root.firstPendingTime;
14387
14388 var subscriber = void 0;
14389
14390 try {
14391 subscriber = __subscriberRef.current;
14392 if (subscriber !== null && root.memoizedInteractions.size > 0) {
14393 var threadID = computeThreadID(root, committedExpirationTime);
14394 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
14395 }
14396 } catch (error) {
14397 // If the subscriber throws, rethrow it in a separate task
14398 scheduleCallback(ImmediatePriority, function () {
14399 throw error;
14400 });
14401 } finally {
14402 // Clear completed interactions from the pending Map.
14403 // Unless the render was suspended or cascading work was scheduled,
14404 // In which case– leave pending interactions until the subsequent render.
14405 var pendingInteractionMap = root.pendingInteractionMap;
14406 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
14407 // Only decrement the pending interaction count if we're done.
14408 // If there's still work at the current priority,
14409 // That indicates that we are waiting for suspense data.
14410 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
14411 pendingInteractionMap.delete(scheduledExpirationTime);
14412
14413 scheduledInteractions.forEach(function (interaction) {
14414 interaction.__count--;
14415
14416 if (subscriber !== null && interaction.__count === 0) {
14417 try {
14418 subscriber.onInteractionScheduledWorkCompleted(interaction);
14419 } catch (error) {
14420 // If the subscriber throws, rethrow it in a separate task
14421 scheduleCallback(ImmediatePriority, function () {
14422 throw error;
14423 });
14424 }
14425 }
14426 });
14427 }
14428 });
14429 }
14430}
14431
14432var onCommitFiberRoot = null;
14433var onCommitFiberUnmount = null;
14434var hasLoggedError = false;
14435
14436var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
14437
14438function injectInternals(internals) {
14439 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
14440 // No DevTools
14441 return false;
14442 }
14443 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
14444 if (hook.isDisabled) {
14445 // This isn't a real property on the hook, but it can be set to opt out
14446 // of DevTools integration and associated warnings and logs.
14447 // https://github.com/facebook/react/issues/3877
14448 return true;
14449 }
14450 if (!hook.supportsFiber) {
14451 {
14452 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');
14453 }
14454 // DevTools exists, even though it doesn't support Fiber.
14455 return true;
14456 }
14457 try {
14458 var rendererID = hook.inject(internals);
14459 // We have successfully injected, so now it is safe to set up hooks.
14460 onCommitFiberRoot = function (root, expirationTime) {
14461 try {
14462 var didError = (root.current.effectTag & DidCapture) === DidCapture;
14463 if (enableProfilerTimer) {
14464 var currentTime = requestCurrentTime();
14465 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime);
14466 hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
14467 } else {
14468 hook.onCommitFiberRoot(rendererID, root, undefined, didError);
14469 }
14470 } catch (err) {
14471 if (true && !hasLoggedError) {
14472 hasLoggedError = true;
14473 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
14474 }
14475 }
14476 };
14477 onCommitFiberUnmount = function (fiber) {
14478 try {
14479 hook.onCommitFiberUnmount(rendererID, fiber);
14480 } catch (err) {
14481 if (true && !hasLoggedError) {
14482 hasLoggedError = true;
14483 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
14484 }
14485 }
14486 };
14487 } catch (err) {
14488 // Catch all errors because it is unsafe to throw during initialization.
14489 {
14490 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err);
14491 }
14492 }
14493 // DevTools exists
14494 return true;
14495}
14496
14497function onCommitRoot(root, expirationTime) {
14498 if (typeof onCommitFiberRoot === 'function') {
14499 onCommitFiberRoot(root, expirationTime);
14500 }
14501}
14502
14503function onCommitUnmount(fiber) {
14504 if (typeof onCommitFiberUnmount === 'function') {
14505 onCommitFiberUnmount(fiber);
14506 }
14507}
14508
14509var hasBadMapPolyfill = void 0;
14510
14511{
14512 hasBadMapPolyfill = false;
14513 try {
14514 var nonExtensibleObject = Object.preventExtensions({});
14515 var testMap = new Map([[nonExtensibleObject, null]]);
14516 var testSet = new Set([nonExtensibleObject]);
14517 // This is necessary for Rollup to not consider these unused.
14518 // https://github.com/rollup/rollup/issues/1771
14519 // TODO: we can remove these if Rollup fixes the bug.
14520 testMap.set(0, 0);
14521 testSet.add(0);
14522 } catch (e) {
14523 // TODO: Consider warning about bad polyfills
14524 hasBadMapPolyfill = true;
14525 }
14526}
14527
14528// A Fiber is work on a Component that needs to be done or was done. There can
14529// be more than one per component.
14530
14531
14532var debugCounter = void 0;
14533
14534{
14535 debugCounter = 1;
14536}
14537
14538function FiberNode(tag, pendingProps, key, mode) {
14539 // Instance
14540 this.tag = tag;
14541 this.key = key;
14542 this.elementType = null;
14543 this.type = null;
14544 this.stateNode = null;
14545
14546 // Fiber
14547 this.return = null;
14548 this.child = null;
14549 this.sibling = null;
14550 this.index = 0;
14551
14552 this.ref = null;
14553
14554 this.pendingProps = pendingProps;
14555 this.memoizedProps = null;
14556 this.updateQueue = null;
14557 this.memoizedState = null;
14558 this.dependencies = null;
14559
14560 this.mode = mode;
14561
14562 // Effects
14563 this.effectTag = NoEffect;
14564 this.nextEffect = null;
14565
14566 this.firstEffect = null;
14567 this.lastEffect = null;
14568
14569 this.expirationTime = NoWork;
14570 this.childExpirationTime = NoWork;
14571
14572 this.alternate = null;
14573
14574 if (enableProfilerTimer) {
14575 // Note: The following is done to avoid a v8 performance cliff.
14576 //
14577 // Initializing the fields below to smis and later updating them with
14578 // double values will cause Fibers to end up having separate shapes.
14579 // This behavior/bug has something to do with Object.preventExtension().
14580 // Fortunately this only impacts DEV builds.
14581 // Unfortunately it makes React unusably slow for some applications.
14582 // To work around this, initialize the fields below with doubles.
14583 //
14584 // Learn more about this here:
14585 // https://github.com/facebook/react/issues/14365
14586 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
14587 this.actualDuration = Number.NaN;
14588 this.actualStartTime = Number.NaN;
14589 this.selfBaseDuration = Number.NaN;
14590 this.treeBaseDuration = Number.NaN;
14591
14592 // It's okay to replace the initial doubles with smis after initialization.
14593 // This won't trigger the performance cliff mentioned above,
14594 // and it simplifies other profiler code (including DevTools).
14595 this.actualDuration = 0;
14596 this.actualStartTime = -1;
14597 this.selfBaseDuration = 0;
14598 this.treeBaseDuration = 0;
14599 }
14600
14601 {
14602 this._debugID = debugCounter++;
14603 this._debugSource = null;
14604 this._debugOwner = null;
14605 this._debugIsCurrentlyTiming = false;
14606 this._debugNeedsRemount = false;
14607 this._debugHookTypes = null;
14608 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
14609 Object.preventExtensions(this);
14610 }
14611 }
14612}
14613
14614// This is a constructor function, rather than a POJO constructor, still
14615// please ensure we do the following:
14616// 1) Nobody should add any instance methods on this. Instance methods can be
14617// more difficult to predict when they get optimized and they are almost
14618// never inlined properly in static compilers.
14619// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
14620// always know when it is a fiber.
14621// 3) We might want to experiment with using numeric keys since they are easier
14622// to optimize in a non-JIT environment.
14623// 4) We can easily go from a constructor to a createFiber object literal if that
14624// is faster.
14625// 5) It should be easy to port this to a C struct and keep a C implementation
14626// compatible.
14627var createFiber = function (tag, pendingProps, key, mode) {
14628 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
14629 return new FiberNode(tag, pendingProps, key, mode);
14630};
14631
14632function shouldConstruct(Component) {
14633 var prototype = Component.prototype;
14634 return !!(prototype && prototype.isReactComponent);
14635}
14636
14637function isSimpleFunctionComponent(type) {
14638 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
14639}
14640
14641function resolveLazyComponentTag(Component) {
14642 if (typeof Component === 'function') {
14643 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
14644 } else if (Component !== undefined && Component !== null) {
14645 var $$typeof = Component.$$typeof;
14646 if ($$typeof === REACT_FORWARD_REF_TYPE) {
14647 return ForwardRef;
14648 }
14649 if ($$typeof === REACT_MEMO_TYPE) {
14650 return MemoComponent;
14651 }
14652 }
14653 return IndeterminateComponent;
14654}
14655
14656// This is used to create an alternate fiber to do work on.
14657function createWorkInProgress(current, pendingProps, expirationTime) {
14658 var workInProgress = current.alternate;
14659 if (workInProgress === null) {
14660 // We use a double buffering pooling technique because we know that we'll
14661 // only ever need at most two versions of a tree. We pool the "other" unused
14662 // node that we're free to reuse. This is lazily created to avoid allocating
14663 // extra objects for things that are never updated. It also allow us to
14664 // reclaim the extra memory if needed.
14665 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
14666 workInProgress.elementType = current.elementType;
14667 workInProgress.type = current.type;
14668 workInProgress.stateNode = current.stateNode;
14669
14670 {
14671 // DEV-only fields
14672 workInProgress._debugID = current._debugID;
14673 workInProgress._debugSource = current._debugSource;
14674 workInProgress._debugOwner = current._debugOwner;
14675 workInProgress._debugHookTypes = current._debugHookTypes;
14676 }
14677
14678 workInProgress.alternate = current;
14679 current.alternate = workInProgress;
14680 } else {
14681 workInProgress.pendingProps = pendingProps;
14682
14683 // We already have an alternate.
14684 // Reset the effect tag.
14685 workInProgress.effectTag = NoEffect;
14686
14687 // The effect list is no longer valid.
14688 workInProgress.nextEffect = null;
14689 workInProgress.firstEffect = null;
14690 workInProgress.lastEffect = null;
14691
14692 if (enableProfilerTimer) {
14693 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
14694 // This prevents time from endlessly accumulating in new commits.
14695 // This has the downside of resetting values for different priority renders,
14696 // But works for yielding (the common case) and should support resuming.
14697 workInProgress.actualDuration = 0;
14698 workInProgress.actualStartTime = -1;
14699 }
14700 }
14701
14702 workInProgress.childExpirationTime = current.childExpirationTime;
14703 workInProgress.expirationTime = current.expirationTime;
14704
14705 workInProgress.child = current.child;
14706 workInProgress.memoizedProps = current.memoizedProps;
14707 workInProgress.memoizedState = current.memoizedState;
14708 workInProgress.updateQueue = current.updateQueue;
14709
14710 // Clone the dependencies object. This is mutated during the render phase, so
14711 // it cannot be shared with the current fiber.
14712 var currentDependencies = current.dependencies;
14713 workInProgress.dependencies = currentDependencies === null ? null : {
14714 expirationTime: currentDependencies.expirationTime,
14715 firstContext: currentDependencies.firstContext,
14716 responders: currentDependencies.responders
14717 };
14718
14719 // These will be overridden during the parent's reconciliation
14720 workInProgress.sibling = current.sibling;
14721 workInProgress.index = current.index;
14722 workInProgress.ref = current.ref;
14723
14724 if (enableProfilerTimer) {
14725 workInProgress.selfBaseDuration = current.selfBaseDuration;
14726 workInProgress.treeBaseDuration = current.treeBaseDuration;
14727 }
14728
14729 {
14730 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
14731 switch (workInProgress.tag) {
14732 case IndeterminateComponent:
14733 case FunctionComponent:
14734 case SimpleMemoComponent:
14735 workInProgress.type = resolveFunctionForHotReloading(current.type);
14736 break;
14737 case ClassComponent:
14738 workInProgress.type = resolveClassForHotReloading(current.type);
14739 break;
14740 case ForwardRef:
14741 workInProgress.type = resolveForwardRefForHotReloading(current.type);
14742 break;
14743 default:
14744 break;
14745 }
14746 }
14747
14748 return workInProgress;
14749}
14750
14751// Used to reuse a Fiber for a second pass.
14752function resetWorkInProgress(workInProgress, renderExpirationTime) {
14753 // This resets the Fiber to what createFiber or createWorkInProgress would
14754 // have set the values to before during the first pass. Ideally this wouldn't
14755 // be necessary but unfortunately many code paths reads from the workInProgress
14756 // when they should be reading from current and writing to workInProgress.
14757
14758 // We assume pendingProps, index, key, ref, return are still untouched to
14759 // avoid doing another reconciliation.
14760
14761 // Reset the effect tag but keep any Placement tags, since that's something
14762 // that child fiber is setting, not the reconciliation.
14763 workInProgress.effectTag &= Placement;
14764
14765 // The effect list is no longer valid.
14766 workInProgress.nextEffect = null;
14767 workInProgress.firstEffect = null;
14768 workInProgress.lastEffect = null;
14769
14770 var current = workInProgress.alternate;
14771 if (current === null) {
14772 // Reset to createFiber's initial values.
14773 workInProgress.childExpirationTime = NoWork;
14774 workInProgress.expirationTime = renderExpirationTime;
14775
14776 workInProgress.child = null;
14777 workInProgress.memoizedProps = null;
14778 workInProgress.memoizedState = null;
14779 workInProgress.updateQueue = null;
14780
14781 workInProgress.dependencies = null;
14782
14783 if (enableProfilerTimer) {
14784 // Note: We don't reset the actualTime counts. It's useful to accumulate
14785 // actual time across multiple render passes.
14786 workInProgress.selfBaseDuration = 0;
14787 workInProgress.treeBaseDuration = 0;
14788 }
14789 } else {
14790 // Reset to the cloned values that createWorkInProgress would've.
14791 workInProgress.childExpirationTime = current.childExpirationTime;
14792 workInProgress.expirationTime = current.expirationTime;
14793
14794 workInProgress.child = current.child;
14795 workInProgress.memoizedProps = current.memoizedProps;
14796 workInProgress.memoizedState = current.memoizedState;
14797 workInProgress.updateQueue = current.updateQueue;
14798
14799 // Clone the dependencies object. This is mutated during the render phase, so
14800 // it cannot be shared with the current fiber.
14801 var currentDependencies = current.dependencies;
14802 workInProgress.dependencies = currentDependencies === null ? null : {
14803 expirationTime: currentDependencies.expirationTime,
14804 firstContext: currentDependencies.firstContext,
14805 responders: currentDependencies.responders
14806 };
14807
14808 if (enableProfilerTimer) {
14809 // Note: We don't reset the actualTime counts. It's useful to accumulate
14810 // actual time across multiple render passes.
14811 workInProgress.selfBaseDuration = current.selfBaseDuration;
14812 workInProgress.treeBaseDuration = current.treeBaseDuration;
14813 }
14814 }
14815
14816 return workInProgress;
14817}
14818
14819function createHostRootFiber(tag) {
14820 var mode = void 0;
14821 if (tag === ConcurrentRoot) {
14822 mode = ConcurrentMode | BatchedMode | StrictMode;
14823 } else if (tag === BatchedRoot) {
14824 mode = BatchedMode | StrictMode;
14825 } else {
14826 mode = NoMode;
14827 }
14828
14829 if (enableProfilerTimer && isDevToolsPresent) {
14830 // Always collect profile timings when DevTools are present.
14831 // This enables DevTools to start capturing timing at any point–
14832 // Without some nodes in the tree having empty base times.
14833 mode |= ProfileMode;
14834 }
14835
14836 return createFiber(HostRoot, null, null, mode);
14837}
14838
14839function createFiberFromTypeAndProps(type, // React$ElementType
14840key, pendingProps, owner, mode, expirationTime) {
14841 var fiber = void 0;
14842
14843 var fiberTag = IndeterminateComponent;
14844 // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
14845 var resolvedType = type;
14846 if (typeof type === 'function') {
14847 if (shouldConstruct(type)) {
14848 fiberTag = ClassComponent;
14849 {
14850 resolvedType = resolveClassForHotReloading(resolvedType);
14851 }
14852 } else {
14853 {
14854 resolvedType = resolveFunctionForHotReloading(resolvedType);
14855 }
14856 }
14857 } else if (typeof type === 'string') {
14858 fiberTag = HostComponent;
14859 } else {
14860 getTag: switch (type) {
14861 case REACT_FRAGMENT_TYPE:
14862 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
14863 case REACT_CONCURRENT_MODE_TYPE:
14864 fiberTag = Mode;
14865 mode |= ConcurrentMode | BatchedMode | StrictMode;
14866 break;
14867 case REACT_STRICT_MODE_TYPE:
14868 fiberTag = Mode;
14869 mode |= StrictMode;
14870 break;
14871 case REACT_PROFILER_TYPE:
14872 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
14873 case REACT_SUSPENSE_TYPE:
14874 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
14875 case REACT_SUSPENSE_LIST_TYPE:
14876 return createFiberFromSuspenseList(pendingProps, mode, expirationTime, key);
14877 default:
14878 {
14879 if (typeof type === 'object' && type !== null) {
14880 switch (type.$$typeof) {
14881 case REACT_PROVIDER_TYPE:
14882 fiberTag = ContextProvider;
14883 break getTag;
14884 case REACT_CONTEXT_TYPE:
14885 // This is a consumer
14886 fiberTag = ContextConsumer;
14887 break getTag;
14888 case REACT_FORWARD_REF_TYPE:
14889 fiberTag = ForwardRef;
14890 {
14891 resolvedType = resolveForwardRefForHotReloading(resolvedType);
14892 }
14893 break getTag;
14894 case REACT_MEMO_TYPE:
14895 fiberTag = MemoComponent;
14896 break getTag;
14897 case REACT_LAZY_TYPE:
14898 fiberTag = LazyComponent;
14899 resolvedType = null;
14900 break getTag;
14901 case REACT_FUNDAMENTAL_TYPE:
14902 if (enableFundamentalAPI) {
14903 return createFiberFromFundamental(type, pendingProps, mode, expirationTime, key);
14904 }
14905 break;
14906 }
14907 }
14908 var info = '';
14909 {
14910 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
14911 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.';
14912 }
14913 var ownerName = owner ? getComponentName(owner.type) : null;
14914 if (ownerName) {
14915 info += '\n\nCheck the render method of `' + ownerName + '`.';
14916 }
14917 }
14918 (function () {
14919 {
14920 {
14921 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));
14922 }
14923 }
14924 })();
14925 }
14926 }
14927 }
14928
14929 fiber = createFiber(fiberTag, pendingProps, key, mode);
14930 fiber.elementType = type;
14931 fiber.type = resolvedType;
14932 fiber.expirationTime = expirationTime;
14933
14934 return fiber;
14935}
14936
14937function createFiberFromElement(element, mode, expirationTime) {
14938 var owner = null;
14939 {
14940 owner = element._owner;
14941 }
14942 var type = element.type;
14943 var key = element.key;
14944 var pendingProps = element.props;
14945 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
14946 {
14947 fiber._debugSource = element._source;
14948 fiber._debugOwner = element._owner;
14949 }
14950 return fiber;
14951}
14952
14953function createFiberFromFragment(elements, mode, expirationTime, key) {
14954 var fiber = createFiber(Fragment, elements, key, mode);
14955 fiber.expirationTime = expirationTime;
14956 return fiber;
14957}
14958
14959function createFiberFromFundamental(fundamentalComponent, pendingProps, mode, expirationTime, key) {
14960 var fiber = createFiber(FundamentalComponent, pendingProps, key, mode);
14961 fiber.elementType = fundamentalComponent;
14962 fiber.type = fundamentalComponent;
14963 fiber.expirationTime = expirationTime;
14964 return fiber;
14965}
14966
14967function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
14968 {
14969 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
14970 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
14971 }
14972 }
14973
14974 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
14975 // TODO: The Profiler fiber shouldn't have a type. It has a tag.
14976 fiber.elementType = REACT_PROFILER_TYPE;
14977 fiber.type = REACT_PROFILER_TYPE;
14978 fiber.expirationTime = expirationTime;
14979
14980 return fiber;
14981}
14982
14983function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
14984 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
14985
14986 // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
14987 // This needs to be fixed in getComponentName so that it relies on the tag
14988 // instead.
14989 fiber.type = REACT_SUSPENSE_TYPE;
14990 fiber.elementType = REACT_SUSPENSE_TYPE;
14991
14992 fiber.expirationTime = expirationTime;
14993 return fiber;
14994}
14995
14996function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) {
14997 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
14998 {
14999 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.
15000 // This needs to be fixed in getComponentName so that it relies on the tag
15001 // instead.
15002 fiber.type = REACT_SUSPENSE_LIST_TYPE;
15003 }
15004 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
15005 fiber.expirationTime = expirationTime;
15006 return fiber;
15007}
15008
15009function createFiberFromText(content, mode, expirationTime) {
15010 var fiber = createFiber(HostText, content, null, mode);
15011 fiber.expirationTime = expirationTime;
15012 return fiber;
15013}
15014
15015function createFiberFromHostInstanceForDeletion() {
15016 var fiber = createFiber(HostComponent, null, null, NoMode);
15017 // TODO: These should not need a type.
15018 fiber.elementType = 'DELETED';
15019 fiber.type = 'DELETED';
15020 return fiber;
15021}
15022
15023function createFiberFromPortal(portal, mode, expirationTime) {
15024 var pendingProps = portal.children !== null ? portal.children : [];
15025 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
15026 fiber.expirationTime = expirationTime;
15027 fiber.stateNode = {
15028 containerInfo: portal.containerInfo,
15029 pendingChildren: null, // Used by persistent updates
15030 implementation: portal.implementation
15031 };
15032 return fiber;
15033}
15034
15035// Used for stashing WIP properties to replay failed work in DEV.
15036function assignFiberPropertiesInDEV(target, source) {
15037 if (target === null) {
15038 // This Fiber's initial properties will always be overwritten.
15039 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
15040 target = createFiber(IndeterminateComponent, null, null, NoMode);
15041 }
15042
15043 // This is intentionally written as a list of all properties.
15044 // We tried to use Object.assign() instead but this is called in
15045 // the hottest path, and Object.assign() was too slow:
15046 // https://github.com/facebook/react/issues/12502
15047 // This code is DEV-only so size is not a concern.
15048
15049 target.tag = source.tag;
15050 target.key = source.key;
15051 target.elementType = source.elementType;
15052 target.type = source.type;
15053 target.stateNode = source.stateNode;
15054 target.return = source.return;
15055 target.child = source.child;
15056 target.sibling = source.sibling;
15057 target.index = source.index;
15058 target.ref = source.ref;
15059 target.pendingProps = source.pendingProps;
15060 target.memoizedProps = source.memoizedProps;
15061 target.updateQueue = source.updateQueue;
15062 target.memoizedState = source.memoizedState;
15063 target.dependencies = source.dependencies;
15064 target.mode = source.mode;
15065 target.effectTag = source.effectTag;
15066 target.nextEffect = source.nextEffect;
15067 target.firstEffect = source.firstEffect;
15068 target.lastEffect = source.lastEffect;
15069 target.expirationTime = source.expirationTime;
15070 target.childExpirationTime = source.childExpirationTime;
15071 target.alternate = source.alternate;
15072 if (enableProfilerTimer) {
15073 target.actualDuration = source.actualDuration;
15074 target.actualStartTime = source.actualStartTime;
15075 target.selfBaseDuration = source.selfBaseDuration;
15076 target.treeBaseDuration = source.treeBaseDuration;
15077 }
15078 target._debugID = source._debugID;
15079 target._debugSource = source._debugSource;
15080 target._debugOwner = source._debugOwner;
15081 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
15082 target._debugNeedsRemount = source._debugNeedsRemount;
15083 target._debugHookTypes = source._debugHookTypes;
15084 return target;
15085}
15086
15087// TODO: This should be lifted into the renderer.
15088
15089
15090// The following attributes are only used by interaction tracing builds.
15091// They enable interactions to be associated with their async work,
15092// And expose interaction metadata to the React DevTools Profiler plugin.
15093// Note that these attributes are only defined when the enableSchedulerTracing flag is enabled.
15094
15095
15096// Exported FiberRoot type includes all properties,
15097// To avoid requiring potentially error-prone :any casts throughout the project.
15098// Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true).
15099// The types are defined separately within this file to ensure they stay in sync.
15100// (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.)
15101
15102
15103function FiberRootNode(containerInfo, tag, hydrate) {
15104 this.tag = tag;
15105 this.current = null;
15106 this.containerInfo = containerInfo;
15107 this.pendingChildren = null;
15108 this.pingCache = null;
15109 this.finishedExpirationTime = NoWork;
15110 this.finishedWork = null;
15111 this.timeoutHandle = noTimeout;
15112 this.context = null;
15113 this.pendingContext = null;
15114 this.hydrate = hydrate;
15115 this.firstBatch = null;
15116 this.callbackNode = null;
15117 this.callbackExpirationTime = NoWork;
15118 this.firstPendingTime = NoWork;
15119 this.lastPendingTime = NoWork;
15120 this.pingTime = NoWork;
15121
15122 if (enableSchedulerTracing) {
15123 this.interactionThreadID = unstable_getThreadID();
15124 this.memoizedInteractions = new Set();
15125 this.pendingInteractionMap = new Map();
15126 }
15127}
15128
15129function createFiberRoot(containerInfo, tag, hydrate) {
15130 var root = new FiberRootNode(containerInfo, tag, hydrate);
15131
15132 // Cyclic construction. This cheats the type system right now because
15133 // stateNode is any.
15134 var uninitializedFiber = createHostRootFiber(tag);
15135 root.current = uninitializedFiber;
15136 uninitializedFiber.stateNode = root;
15137
15138 return root;
15139}
15140
15141// This lets us hook into Fiber to debug what it's doing.
15142// See https://github.com/facebook/react/pull/8033.
15143// This is not part of the public API, not even for React DevTools.
15144// You may only inject a debugTool if you work on React Fiber itself.
15145var ReactFiberInstrumentation = {
15146 debugTool: null
15147};
15148
15149var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
15150
15151// 0 is PROD, 1 is DEV.
15152// Might add PROFILE later.
15153
15154
15155var didWarnAboutNestedUpdates = void 0;
15156{
15157 didWarnAboutNestedUpdates = false;
15158
15159}
15160
15161function getContextForSubtree(parentComponent) {
15162 if (!parentComponent) {
15163 return emptyContextObject;
15164 }
15165
15166 var fiber = get(parentComponent);
15167 var parentContext = findCurrentUnmaskedContext(fiber);
15168
15169 if (fiber.tag === ClassComponent) {
15170 var Component = fiber.type;
15171 if (isContextProvider(Component)) {
15172 return processChildContext(fiber, Component, parentContext);
15173 }
15174 }
15175
15176 return parentContext;
15177}
15178
15179function scheduleRootUpdate(current$$1, element, expirationTime, suspenseConfig, callback) {
15180 {
15181 if (phase === 'render' && current !== null && !didWarnAboutNestedUpdates) {
15182 didWarnAboutNestedUpdates = true;
15183 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');
15184 }
15185 }
15186
15187 var update = createUpdate(expirationTime, suspenseConfig);
15188 // Caution: React DevTools currently depends on this property
15189 // being called "element".
15190 update.payload = { element: element };
15191
15192 callback = callback === undefined ? null : callback;
15193 if (callback !== null) {
15194 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
15195 update.callback = callback;
15196 }
15197
15198 if (revertPassiveEffectsChange) {
15199 flushPassiveEffects();
15200 }
15201 enqueueUpdate(current$$1, update);
15202 scheduleWork(current$$1, expirationTime);
15203
15204 return expirationTime;
15205}
15206
15207function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, suspenseConfig, callback) {
15208 // TODO: If this is a nested container, this won't be the root.
15209 var current$$1 = container.current;
15210
15211 {
15212 if (ReactFiberInstrumentation_1.debugTool) {
15213 if (current$$1.alternate === null) {
15214 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
15215 } else if (element === null) {
15216 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
15217 } else {
15218 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
15219 }
15220 }
15221 }
15222
15223 var context = getContextForSubtree(parentComponent);
15224 if (container.context === null) {
15225 container.context = context;
15226 } else {
15227 container.pendingContext = context;
15228 }
15229
15230 return scheduleRootUpdate(current$$1, element, expirationTime, suspenseConfig, callback);
15231}
15232
15233function createContainer(containerInfo, tag, hydrate) {
15234 return createFiberRoot(containerInfo, tag, hydrate);
15235}
15236
15237function updateContainer(element, container, parentComponent, callback) {
15238 var current$$1 = container.current;
15239 var currentTime = requestCurrentTime();
15240 {
15241 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15242 if ('undefined' !== typeof jest) {
15243 warnIfUnmockedScheduler(current$$1);
15244 warnIfNotScopedWithMatchingAct(current$$1);
15245 }
15246 }
15247 var suspenseConfig = requestCurrentSuspenseConfig();
15248 var expirationTime = computeExpirationForFiber(currentTime, current$$1, suspenseConfig);
15249 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, suspenseConfig, callback);
15250}
15251
15252function getPublicRootInstance(container) {
15253 var containerFiber = container.current;
15254 if (!containerFiber.child) {
15255 return null;
15256 }
15257 switch (containerFiber.child.tag) {
15258 case HostComponent:
15259 return getPublicInstance(containerFiber.child.stateNode);
15260 default:
15261 return containerFiber.child.stateNode;
15262 }
15263}
15264
15265
15266
15267var shouldSuspendImpl = function (fiber) {
15268 return false;
15269};
15270
15271function shouldSuspend(fiber) {
15272 return shouldSuspendImpl(fiber);
15273}
15274
15275var overrideHookState = null;
15276var overrideProps = null;
15277var scheduleUpdate = null;
15278var setSuspenseHandler = null;
15279
15280{
15281 var copyWithSetImpl = function (obj, path, idx, value) {
15282 if (idx >= path.length) {
15283 return value;
15284 }
15285 var key = path[idx];
15286 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
15287 // $FlowFixMe number or string is fine here
15288 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
15289 return updated;
15290 };
15291
15292 var copyWithSet = function (obj, path, value) {
15293 return copyWithSetImpl(obj, path, 0, value);
15294 };
15295
15296 // Support DevTools editable values for useState and useReducer.
15297 overrideHookState = function (fiber, id, path, value) {
15298 // For now, the "id" of stateful hooks is just the stateful hook index.
15299 // This may change in the future with e.g. nested hooks.
15300 var currentHook = fiber.memoizedState;
15301 while (currentHook !== null && id > 0) {
15302 currentHook = currentHook.next;
15303 id--;
15304 }
15305 if (currentHook !== null) {
15306 if (revertPassiveEffectsChange) {
15307 flushPassiveEffects();
15308 }
15309
15310 var newState = copyWithSet(currentHook.memoizedState, path, value);
15311 currentHook.memoizedState = newState;
15312 currentHook.baseState = newState;
15313
15314 // We aren't actually adding an update to the queue,
15315 // because there is no update we can add for useReducer hooks that won't trigger an error.
15316 // (There's no appropriate action type for DevTools overrides.)
15317 // As a result though, React will see the scheduled update as a noop and bailout.
15318 // Shallow cloning props works as a workaround for now to bypass the bailout check.
15319 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
15320
15321 scheduleWork(fiber, Sync);
15322 }
15323 };
15324
15325 // Support DevTools props for function components, forwardRef, memo, host components, etc.
15326 overrideProps = function (fiber, path, value) {
15327 if (revertPassiveEffectsChange) {
15328 flushPassiveEffects();
15329 }
15330 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
15331 if (fiber.alternate) {
15332 fiber.alternate.pendingProps = fiber.pendingProps;
15333 }
15334 scheduleWork(fiber, Sync);
15335 };
15336
15337 scheduleUpdate = function (fiber) {
15338 if (revertPassiveEffectsChange) {
15339 flushPassiveEffects();
15340 }
15341 scheduleWork(fiber, Sync);
15342 };
15343
15344 setSuspenseHandler = function (newShouldSuspendImpl) {
15345 shouldSuspendImpl = newShouldSuspendImpl;
15346 };
15347}
15348
15349function injectIntoDevTools(devToolsConfig) {
15350 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
15351 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
15352
15353
15354 return injectInternals(_assign({}, devToolsConfig, {
15355 overrideHookState: overrideHookState,
15356 overrideProps: overrideProps,
15357 setSuspenseHandler: setSuspenseHandler,
15358 scheduleUpdate: scheduleUpdate,
15359 currentDispatcherRef: ReactCurrentDispatcher,
15360 findHostInstanceByFiber: function (fiber) {
15361 var hostFiber = findCurrentHostFiber(fiber);
15362 if (hostFiber === null) {
15363 return null;
15364 }
15365 return hostFiber.stateNode;
15366 },
15367 findFiberByHostInstance: function (instance) {
15368 if (!findFiberByHostInstance) {
15369 // Might not be implemented by the renderer.
15370 return null;
15371 }
15372 return findFiberByHostInstance(instance);
15373 },
15374
15375 // React Refresh
15376 findHostInstancesForRefresh: findHostInstancesForRefresh,
15377 scheduleRefresh: scheduleRefresh,
15378 scheduleRoot: scheduleRoot,
15379 setRefreshHandler: setRefreshHandler,
15380 // Enables DevTools to append owner stacks to error messages in DEV mode.
15381 getCurrentFiber: function () {
15382 return current;
15383 }
15384 }));
15385}
15386
15387// This file intentionally does *not* have the Flow annotation.
15388// Don't add it. See `./inline-typed.js` for an explanation.
15389
15390// TODO: this is special because it gets imported during build.
15391
15392var ReactVersion = '16.9.0';
15393
15394var didWarnAboutMessageChannel = false;
15395var enqueueTask = void 0;
15396try {
15397 // read require off the module object to get around the bundlers.
15398 // we don't want them to detect a require and bundle a Node polyfill.
15399 var requireString = ('require' + Math.random()).slice(0, 7);
15400 var nodeRequire = module && module[requireString];
15401 // assuming we're in node, let's try to get node's
15402 // version of setImmediate, bypassing fake timers if any.
15403 enqueueTask = nodeRequire('timers').setImmediate;
15404} catch (_err) {
15405 // we're in a browser
15406 // we can't use regular timers because they may still be faked
15407 // so we try MessageChannel+postMessage instead
15408 enqueueTask = function (callback) {
15409 {
15410 if (didWarnAboutMessageChannel === false) {
15411 didWarnAboutMessageChannel = true;
15412 !(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;
15413 }
15414 }
15415 var channel = new MessageChannel();
15416 channel.port1.onmessage = callback;
15417 channel.port2.postMessage(undefined);
15418 };
15419}
15420
15421var enqueueTask$1 = enqueueTask;
15422
15423var IsSomeRendererActing$1 = ReactSharedInternals.IsSomeRendererActing;
15424
15425// this implementation should be exactly the same in
15426// ReactTestUtilsAct.js, ReactTestRendererAct.js, createReactNoop.js
15427
15428var isSchedulerMocked = typeof Scheduler$1.unstable_flushAllWithoutAsserting === 'function';
15429var flushWork = Scheduler$1.unstable_flushAllWithoutAsserting || function () {
15430 var didFlushWork = false;
15431 while (flushPassiveEffects()) {
15432 didFlushWork = true;
15433 }
15434
15435 return didFlushWork;
15436};
15437
15438function flushWorkAndMicroTasks(onDone) {
15439 try {
15440 flushWork();
15441 enqueueTask$1(function () {
15442 if (flushWork()) {
15443 flushWorkAndMicroTasks(onDone);
15444 } else {
15445 onDone();
15446 }
15447 });
15448 } catch (err) {
15449 onDone(err);
15450 }
15451}
15452
15453// we track the 'depth' of the act() calls with this counter,
15454// so we can tell if any async act() calls try to run in parallel.
15455
15456var actingUpdatesScopeDepth = 0;
15457function act(callback) {
15458 var previousActingUpdatesScopeDepth = actingUpdatesScopeDepth;
15459 var previousIsSomeRendererActing = void 0;
15460 var previousIsThisRendererActing = void 0;
15461 actingUpdatesScopeDepth++;
15462
15463 previousIsSomeRendererActing = IsSomeRendererActing$1.current;
15464 previousIsThisRendererActing = IsThisRendererActing.current;
15465 IsSomeRendererActing$1.current = true;
15466 IsThisRendererActing.current = true;
15467
15468 function onDone() {
15469 actingUpdatesScopeDepth--;
15470 IsSomeRendererActing$1.current = previousIsSomeRendererActing;
15471 IsThisRendererActing.current = previousIsThisRendererActing;
15472 {
15473 if (actingUpdatesScopeDepth > previousActingUpdatesScopeDepth) {
15474 // if it's _less than_ previousActingUpdatesScopeDepth, then we can assume the 'other' one has warned
15475 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. ');
15476 }
15477 }
15478 }
15479
15480 var result = void 0;
15481 try {
15482 result = batchedUpdates(callback);
15483 } catch (error) {
15484 // on sync errors, we still want to 'cleanup' and decrement actingUpdatesScopeDepth
15485 onDone();
15486 throw error;
15487 }
15488
15489 if (result !== null && typeof result === 'object' && typeof result.then === 'function') {
15490 // setup a boolean that gets set to true only
15491 // once this act() call is await-ed
15492 var called = false;
15493 {
15494 if (typeof Promise !== 'undefined') {
15495 //eslint-disable-next-line no-undef
15496 Promise.resolve().then(function () {}).then(function () {
15497 if (called === false) {
15498 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 () => ...);');
15499 }
15500 });
15501 }
15502 }
15503
15504 // in the async case, the returned thenable runs the callback, flushes
15505 // effects and microtasks in a loop until flushPassiveEffects() === false,
15506 // and cleans up
15507 return {
15508 then: function (resolve, reject) {
15509 called = true;
15510 result.then(function () {
15511 if (actingUpdatesScopeDepth > 1 || isSchedulerMocked === true && previousIsSomeRendererActing === true) {
15512 onDone();
15513 resolve();
15514 return;
15515 }
15516 // we're about to exit the act() scope,
15517 // now's the time to flush tasks/effects
15518 flushWorkAndMicroTasks(function (err) {
15519 onDone();
15520 if (err) {
15521 reject(err);
15522 } else {
15523 resolve();
15524 }
15525 });
15526 }, function (err) {
15527 onDone();
15528 reject(err);
15529 });
15530 }
15531 };
15532 } else {
15533 {
15534 !(result === undefined) ? warningWithoutStack$1(false, 'The callback passed to act(...) function ' + 'must return undefined, or a Promise. You returned %s', result) : void 0;
15535 }
15536
15537 // flush effects until none remain, and cleanup
15538 try {
15539 if (actingUpdatesScopeDepth === 1 && (isSchedulerMocked === false || previousIsSomeRendererActing === false)) {
15540 // we're about to exit the act() scope,
15541 // now's the time to flush effects
15542 flushWork();
15543 }
15544 onDone();
15545 } catch (err) {
15546 onDone();
15547 throw err;
15548 }
15549
15550 // in the sync case, the returned thenable only warns *if* await-ed
15551 return {
15552 then: function (resolve) {
15553 {
15554 warningWithoutStack$1(false, 'Do not await the result of calling act(...) with sync logic, it is not a Promise.');
15555 }
15556 resolve();
15557 }
15558 };
15559 }
15560}
15561
15562var _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; }; }();
15563
15564function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
15565
15566function _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; }
15567
15568var defaultTestOptions = {
15569 createNodeMock: function () {
15570 return null;
15571 }
15572};
15573
15574function toJSON(inst) {
15575 if (inst.isHidden) {
15576 // Omit timed out children from output entirely. This seems like the least
15577 // surprising behavior. We could perhaps add a separate API that includes
15578 // them, if it turns out people need it.
15579 return null;
15580 }
15581 switch (inst.tag) {
15582 case 'TEXT':
15583 return inst.text;
15584 case 'INSTANCE':
15585 {
15586 /* eslint-disable no-unused-vars */
15587 // We don't include the `children` prop in JSON.
15588 // Instead, we will include the actual rendered children.
15589 var _inst$props = inst.props,
15590 _children = _inst$props.children,
15591 _props = _objectWithoutProperties(_inst$props, ['children']);
15592 /* eslint-enable */
15593
15594
15595 var renderedChildren = null;
15596 if (inst.children && inst.children.length) {
15597 for (var i = 0; i < inst.children.length; i++) {
15598 var renderedChild = toJSON(inst.children[i]);
15599 if (renderedChild !== null) {
15600 if (renderedChildren === null) {
15601 renderedChildren = [renderedChild];
15602 } else {
15603 renderedChildren.push(renderedChild);
15604 }
15605 }
15606 }
15607 }
15608 var json = {
15609 type: inst.type,
15610 props: _props,
15611 children: renderedChildren
15612 };
15613 Object.defineProperty(json, '$$typeof', {
15614 value: Symbol.for('react.test.json')
15615 });
15616 return json;
15617 }
15618 default:
15619 throw new Error('Unexpected node type in toJSON: ' + inst.tag);
15620 }
15621}
15622
15623function childrenToTree(node) {
15624 if (!node) {
15625 return null;
15626 }
15627 var children = nodeAndSiblingsArray(node);
15628 if (children.length === 0) {
15629 return null;
15630 } else if (children.length === 1) {
15631 return toTree(children[0]);
15632 }
15633 return flatten(children.map(toTree));
15634}
15635
15636function nodeAndSiblingsArray(nodeWithSibling) {
15637 var array = [];
15638 var node = nodeWithSibling;
15639 while (node != null) {
15640 array.push(node);
15641 node = node.sibling;
15642 }
15643 return array;
15644}
15645
15646function flatten(arr) {
15647 var result = [];
15648 var stack = [{ i: 0, array: arr }];
15649 while (stack.length) {
15650 var n = stack.pop();
15651 while (n.i < n.array.length) {
15652 var el = n.array[n.i];
15653 n.i += 1;
15654 if (Array.isArray(el)) {
15655 stack.push(n);
15656 stack.push({ i: 0, array: el });
15657 break;
15658 }
15659 result.push(el);
15660 }
15661 }
15662 return result;
15663}
15664
15665function toTree(node) {
15666 if (node == null) {
15667 return null;
15668 }
15669 switch (node.tag) {
15670 case HostRoot:
15671 return childrenToTree(node.child);
15672 case HostPortal:
15673 return childrenToTree(node.child);
15674 case ClassComponent:
15675 return {
15676 nodeType: 'component',
15677 type: node.type,
15678 props: _assign({}, node.memoizedProps),
15679 instance: node.stateNode,
15680 rendered: childrenToTree(node.child)
15681 };
15682 case FunctionComponent:
15683 case SimpleMemoComponent:
15684 return {
15685 nodeType: 'component',
15686 type: node.type,
15687 props: _assign({}, node.memoizedProps),
15688 instance: null,
15689 rendered: childrenToTree(node.child)
15690 };
15691 case HostComponent:
15692 {
15693 return {
15694 nodeType: 'host',
15695 type: node.type,
15696 props: _assign({}, node.memoizedProps),
15697 instance: null, // TODO: use createNodeMock here somehow?
15698 rendered: flatten(nodeAndSiblingsArray(node.child).map(toTree))
15699 };
15700 }
15701 case HostText:
15702 return node.stateNode.text;
15703 case Fragment:
15704 case ContextProvider:
15705 case ContextConsumer:
15706 case Mode:
15707 case Profiler:
15708 case ForwardRef:
15709 case MemoComponent:
15710 case IncompleteClassComponent:
15711 return childrenToTree(node.child);
15712 default:
15713 (function () {
15714 {
15715 {
15716 throw ReactError(Error('toTree() does not yet know how to handle nodes with tag=' + node.tag));
15717 }
15718 }
15719 })();
15720 }
15721}
15722
15723var validWrapperTypes = new Set([FunctionComponent, ClassComponent, HostComponent, ForwardRef, MemoComponent, SimpleMemoComponent,
15724// Normally skipped, but used when there's more than one root child.
15725HostRoot]);
15726
15727function getChildren(parent) {
15728 var children = [];
15729 var startingNode = parent;
15730 var node = startingNode;
15731 if (node.child === null) {
15732 return children;
15733 }
15734 node.child.return = node;
15735 node = node.child;
15736 outer: while (true) {
15737 var descend = false;
15738 if (validWrapperTypes.has(node.tag)) {
15739 children.push(wrapFiber(node));
15740 } else if (node.tag === HostText) {
15741 children.push('' + node.memoizedProps);
15742 } else {
15743 descend = true;
15744 }
15745 if (descend && node.child !== null) {
15746 node.child.return = node;
15747 node = node.child;
15748 continue;
15749 }
15750 while (node.sibling === null) {
15751 if (node.return === startingNode) {
15752 break outer;
15753 }
15754 node = node.return;
15755 }
15756 node.sibling.return = node.return;
15757 node = node.sibling;
15758 }
15759 return children;
15760}
15761
15762var ReactTestInstance = function () {
15763 ReactTestInstance.prototype._currentFiber = function _currentFiber() {
15764 // Throws if this component has been unmounted.
15765 var fiber = findCurrentFiberUsingSlowPath(this._fiber);
15766 (function () {
15767 if (!(fiber !== null)) {
15768 {
15769 throw ReactError(Error('Can\'t read from currently-mounting component. This error is likely caused by a bug in React. Please file an issue.'));
15770 }
15771 }
15772 })();
15773 return fiber;
15774 };
15775
15776 function ReactTestInstance(fiber) {
15777 _classCallCheck(this, ReactTestInstance);
15778
15779 (function () {
15780 if (!validWrapperTypes.has(fiber.tag)) {
15781 {
15782 throw ReactError(Error('Unexpected object passed to ReactTestInstance constructor (tag: ' + fiber.tag + '). This is probably a bug in React.'));
15783 }
15784 }
15785 })();
15786 this._fiber = fiber;
15787 }
15788
15789 // Custom search functions
15790 ReactTestInstance.prototype.find = function find(predicate) {
15791 return expectOne(this.findAll(predicate, { deep: false }), 'matching custom predicate: ' + predicate.toString());
15792 };
15793
15794 ReactTestInstance.prototype.findByType = function findByType(type) {
15795 return expectOne(this.findAllByType(type, { deep: false }), 'with node type: "' + (type.displayName || type.name) + '"');
15796 };
15797
15798 ReactTestInstance.prototype.findByProps = function findByProps(props) {
15799 return expectOne(this.findAllByProps(props, { deep: false }), 'with props: ' + JSON.stringify(props));
15800 };
15801
15802 ReactTestInstance.prototype.findAll = function findAll(predicate) {
15803 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
15804
15805 return _findAll(this, predicate, options);
15806 };
15807
15808 ReactTestInstance.prototype.findAllByType = function findAllByType(type) {
15809 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
15810
15811 return _findAll(this, function (node) {
15812 return node.type === type;
15813 }, options);
15814 };
15815
15816 ReactTestInstance.prototype.findAllByProps = function findAllByProps(props) {
15817 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
15818
15819 return _findAll(this, function (node) {
15820 return node.props && propsMatch(node.props, props);
15821 }, options);
15822 };
15823
15824 _createClass(ReactTestInstance, [{
15825 key: 'instance',
15826 get: function () {
15827 if (this._fiber.tag === HostComponent) {
15828 return getPublicInstance(this._fiber.stateNode);
15829 } else {
15830 return this._fiber.stateNode;
15831 }
15832 }
15833 }, {
15834 key: 'type',
15835 get: function () {
15836 return this._fiber.type;
15837 }
15838 }, {
15839 key: 'props',
15840 get: function () {
15841 return this._currentFiber().memoizedProps;
15842 }
15843 }, {
15844 key: 'parent',
15845 get: function () {
15846 var parent = this._fiber.return;
15847 while (parent !== null) {
15848 if (validWrapperTypes.has(parent.tag)) {
15849 if (parent.tag === HostRoot) {
15850 // Special case: we only "materialize" instances for roots
15851 // if they have more than a single child. So we'll check that now.
15852 if (getChildren(parent).length < 2) {
15853 return null;
15854 }
15855 }
15856 return wrapFiber(parent);
15857 }
15858 parent = parent.return;
15859 }
15860 return null;
15861 }
15862 }, {
15863 key: 'children',
15864 get: function () {
15865 return getChildren(this._currentFiber());
15866 }
15867 }]);
15868
15869 return ReactTestInstance;
15870}();
15871
15872function _findAll(root, predicate, options) {
15873 var deep = options ? options.deep : true;
15874 var results = [];
15875
15876 if (predicate(root)) {
15877 results.push(root);
15878 if (!deep) {
15879 return results;
15880 }
15881 }
15882
15883 root.children.forEach(function (child) {
15884 if (typeof child === 'string') {
15885 return;
15886 }
15887 results.push.apply(results, _findAll(child, predicate, options));
15888 });
15889
15890 return results;
15891}
15892
15893function expectOne(all, message) {
15894 if (all.length === 1) {
15895 return all[0];
15896 }
15897
15898 var prefix = all.length === 0 ? 'No instances found ' : 'Expected 1 but found ' + all.length + ' instances ';
15899
15900 throw new Error(prefix + message);
15901}
15902
15903function propsMatch(props, filter) {
15904 for (var key in filter) {
15905 if (props[key] !== filter[key]) {
15906 return false;
15907 }
15908 }
15909 return true;
15910}
15911
15912var ReactTestRendererFiber = {
15913 _Scheduler: Scheduler,
15914
15915 create: function (element, options) {
15916 var createNodeMock = defaultTestOptions.createNodeMock;
15917 var isConcurrent = false;
15918 if (typeof options === 'object' && options !== null) {
15919 if (typeof options.createNodeMock === 'function') {
15920 createNodeMock = options.createNodeMock;
15921 }
15922 if (options.unstable_isConcurrent === true) {
15923 isConcurrent = true;
15924 }
15925 }
15926 var container = {
15927 children: [],
15928 createNodeMock: createNodeMock,
15929 tag: 'CONTAINER'
15930 };
15931 var root = createContainer(container, isConcurrent ? ConcurrentRoot : LegacyRoot, false);
15932 (function () {
15933 if (!(root != null)) {
15934 {
15935 throw ReactError(Error('something went wrong'));
15936 }
15937 }
15938 })();
15939 updateContainer(element, root, null, null);
15940
15941 var entry = {
15942 _Scheduler: Scheduler,
15943
15944 root: undefined, // makes flow happy
15945 // we define a 'getter' for 'root' below using 'Object.defineProperty'
15946 toJSON: function () {
15947 if (root == null || root.current == null || container == null) {
15948 return null;
15949 }
15950 if (container.children.length === 0) {
15951 return null;
15952 }
15953 if (container.children.length === 1) {
15954 return toJSON(container.children[0]);
15955 }
15956 if (container.children.length === 2 && container.children[0].isHidden === true && container.children[1].isHidden === false) {
15957 // Omit timed out children from output entirely, including the fact that we
15958 // temporarily wrap fallback and timed out children in an array.
15959 return toJSON(container.children[1]);
15960 }
15961 var renderedChildren = null;
15962 if (container.children && container.children.length) {
15963 for (var i = 0; i < container.children.length; i++) {
15964 var renderedChild = toJSON(container.children[i]);
15965 if (renderedChild !== null) {
15966 if (renderedChildren === null) {
15967 renderedChildren = [renderedChild];
15968 } else {
15969 renderedChildren.push(renderedChild);
15970 }
15971 }
15972 }
15973 }
15974 return renderedChildren;
15975 },
15976 toTree: function () {
15977 if (root == null || root.current == null) {
15978 return null;
15979 }
15980 return toTree(root.current);
15981 },
15982 update: function (newElement) {
15983 if (root == null || root.current == null) {
15984 return;
15985 }
15986 updateContainer(newElement, root, null, null);
15987 },
15988 unmount: function () {
15989 if (root == null || root.current == null) {
15990 return;
15991 }
15992 updateContainer(null, root, null, null);
15993 container = null;
15994 root = null;
15995 },
15996 getInstance: function () {
15997 if (root == null || root.current == null) {
15998 return null;
15999 }
16000 return getPublicRootInstance(root);
16001 },
16002 unstable_flushSync: function (fn) {
16003 return flushSync(fn);
16004 }
16005 };
16006
16007 Object.defineProperty(entry, 'root', {
16008 configurable: true,
16009 enumerable: true,
16010 get: function () {
16011 if (root === null) {
16012 throw new Error("Can't access .root on unmounted test renderer");
16013 }
16014 var children = getChildren(root.current);
16015 if (children.length === 0) {
16016 throw new Error("Can't access .root on unmounted test renderer");
16017 } else if (children.length === 1) {
16018 // Normally, we skip the root and just give you the child.
16019 return children[0];
16020 } else {
16021 // However, we give you the root if there's more than one root child.
16022 // We could make this the behavior for all cases but it would be a breaking change.
16023 return wrapFiber(root.current);
16024 }
16025 }
16026 });
16027
16028 return entry;
16029 },
16030
16031
16032 /* eslint-disable-next-line camelcase */
16033 unstable_batchedUpdates: batchedUpdates,
16034
16035 act: act
16036};
16037
16038var fiberToWrapper = new WeakMap();
16039function wrapFiber(fiber) {
16040 var wrapper = fiberToWrapper.get(fiber);
16041 if (wrapper === undefined && fiber.alternate !== null) {
16042 wrapper = fiberToWrapper.get(fiber.alternate);
16043 }
16044 if (wrapper === undefined) {
16045 wrapper = new ReactTestInstance(fiber);
16046 fiberToWrapper.set(fiber, wrapper);
16047 }
16048 return wrapper;
16049}
16050
16051// Enable ReactTestRenderer to be used to test DevTools integration.
16052injectIntoDevTools({
16053 findFiberByHostInstance: function () {
16054 throw new Error('TestRenderer does not support findFiberByHostInstance()');
16055 },
16056 bundleType: 1,
16057 version: ReactVersion,
16058 rendererPackageName: 'react-test-renderer'
16059});
16060
16061
16062
16063var ReactTestRenderer = Object.freeze({
16064 default: ReactTestRendererFiber
16065});
16066
16067var ReactTestRenderer$1 = ( ReactTestRenderer && ReactTestRendererFiber ) || ReactTestRenderer;
16068
16069// TODO: decide on the top-level export form.
16070// This is hacky but makes it work with both Rollup and Jest.
16071var reactTestRenderer = ReactTestRenderer$1.default || ReactTestRenderer$1;
16072
16073return reactTestRenderer;
16074
16075})));