UNPKG

632 kBJavaScriptView Raw
1/** @license React v16.13.1
2 * react-art.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')) :
14 typeof define === 'function' && define.amd ? define(['react'], factory) :
15 (global = global || self, global.ReactART = factory(global.React));
16}(this, (function (React) { 'use strict';
17
18 function _extends() {
19 _extends = Object.assign || function (target) {
20 for (var i = 1; i < arguments.length; i++) {
21 var source = arguments[i];
22
23 for (var key in source) {
24 if (Object.prototype.hasOwnProperty.call(source, key)) {
25 target[key] = source[key];
26 }
27 }
28 }
29
30 return target;
31 };
32
33 return _extends.apply(this, arguments);
34 }
35
36 function _inheritsLoose(subClass, superClass) {
37 subClass.prototype = Object.create(superClass.prototype);
38 subClass.prototype.constructor = subClass;
39 subClass.__proto__ = superClass;
40 }
41
42 function _assertThisInitialized(self) {
43 if (self === void 0) {
44 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
45 }
46
47 return self;
48 }
49
50 var ReactVersion = '16.13.1';
51
52 var LegacyRoot = 0;
53 var BlockingRoot = 1;
54 var ConcurrentRoot = 2;
55
56 var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
57 var _assign = ReactInternals.assign;
58
59 var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions.
60 // Current owner and dispatcher used to share the same ref,
61 // but PR #14548 split them out to better support the react-debug-tools package.
62
63 if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
64 ReactSharedInternals.ReactCurrentDispatcher = {
65 current: null
66 };
67 }
68
69 if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {
70 ReactSharedInternals.ReactCurrentBatchConfig = {
71 suspense: null
72 };
73 }
74
75 // by calls to these methods by a Babel plugin.
76 //
77 // In PROD (or in packages without access to React internals),
78 // they are left as they are instead.
79
80 function warn(format) {
81 {
82 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
83 args[_key - 1] = arguments[_key];
84 }
85
86 printWarning('warn', format, args);
87 }
88 }
89 function error(format) {
90 {
91 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
92 args[_key2 - 1] = arguments[_key2];
93 }
94
95 printWarning('error', format, args);
96 }
97 }
98
99 function printWarning(level, format, args) {
100 // When changing this logic, you might want to also
101 // update consoleWithStackDev.www.js as well.
102 {
103 var hasExistingStack = args.length > 0 && typeof args[args.length - 1] === 'string' && args[args.length - 1].indexOf('\n in') === 0;
104
105 if (!hasExistingStack) {
106 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
107 var stack = ReactDebugCurrentFrame.getStackAddendum();
108
109 if (stack !== '') {
110 format += '%s';
111 args = args.concat([stack]);
112 }
113 }
114
115 var argsWithFormat = args.map(function (item) {
116 return '' + item;
117 }); // Careful: RN currently depends on this prefix
118
119 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
120 // breaks IE9: https://github.com/facebook/react/issues/13610
121 // eslint-disable-next-line react-internal/no-production-logging
122
123 Function.prototype.apply.call(console[level], console, argsWithFormat);
124
125 try {
126 // --- Welcome to debugging React ---
127 // This error was thrown as a convenience so that you can use this stack
128 // to find the callsite that caused this warning to fire.
129 var argIndex = 0;
130 var message = 'Warning: ' + format.replace(/%s/g, function () {
131 return args[argIndex++];
132 });
133 throw new Error(message);
134 } catch (x) {}
135 }
136 }
137
138 var FunctionComponent = 0;
139 var ClassComponent = 1;
140 var IndeterminateComponent = 2; // Before we know whether it is function or class
141
142 var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
143
144 var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
145
146 var HostComponent = 5;
147 var HostText = 6;
148 var Fragment = 7;
149 var Mode = 8;
150 var ContextConsumer = 9;
151 var ContextProvider = 10;
152 var ForwardRef = 11;
153 var Profiler = 12;
154 var SuspenseComponent = 13;
155 var MemoComponent = 14;
156 var SimpleMemoComponent = 15;
157 var LazyComponent = 16;
158 var IncompleteClassComponent = 17;
159 var DehydratedFragment = 18;
160 var SuspenseListComponent = 19;
161 var FundamentalComponent = 20;
162 var ScopeComponent = 21;
163 var Block = 22;
164
165 /**
166 * `ReactInstanceMap` maintains a mapping from a public facing stateful
167 * instance (key) and the internal representation (value). This allows public
168 * methods to accept the user facing instance as an argument and map them back
169 * to internal methods.
170 *
171 * Note that this module is currently shared and assumed to be stateless.
172 * If this becomes an actual Map, that will break.
173 */
174 function get(key) {
175 return key._reactInternalFiber;
176 }
177 function set(key, value) {
178 key._reactInternalFiber = value;
179 }
180
181 // The Symbol used to tag the ReactElement-like types. If there is no native Symbol
182 // nor polyfill, then a plain number is used for performance.
183 var hasSymbol = typeof Symbol === 'function' && Symbol.for;
184 var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
185 var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
186 var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
187 var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
188 var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
189 var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
190 var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
191 var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
192 var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
193 var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
194 var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
195 var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
196 var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
197 var REACT_BLOCK_TYPE = hasSymbol ? Symbol.for('react.block') : 0xead9;
198 var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
199 var FAUX_ITERATOR_SYMBOL = '@@iterator';
200 function getIteratorFn(maybeIterable) {
201 if (maybeIterable === null || typeof maybeIterable !== 'object') {
202 return null;
203 }
204
205 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
206
207 if (typeof maybeIterator === 'function') {
208 return maybeIterator;
209 }
210
211 return null;
212 }
213
214 var Uninitialized = -1;
215 var Pending = 0;
216 var Resolved = 1;
217 var Rejected = 2;
218 function refineResolvedLazyComponent(lazyComponent) {
219 return lazyComponent._status === Resolved ? lazyComponent._result : null;
220 }
221 function initializeLazyComponentType(lazyComponent) {
222 if (lazyComponent._status === Uninitialized) {
223 lazyComponent._status = Pending;
224 var ctor = lazyComponent._ctor;
225 var thenable = ctor();
226 lazyComponent._result = thenable;
227 thenable.then(function (moduleObject) {
228 if (lazyComponent._status === Pending) {
229 var defaultExport = moduleObject.default;
230
231 {
232 if (defaultExport === undefined) {
233 error('lazy: Expected the result of a dynamic import() call. ' + 'Instead received: %s\n\nYour code should look like: \n ' + "const MyComponent = lazy(() => import('./MyComponent'))", moduleObject);
234 }
235 }
236
237 lazyComponent._status = Resolved;
238 lazyComponent._result = defaultExport;
239 }
240 }, function (error) {
241 if (lazyComponent._status === Pending) {
242 lazyComponent._status = Rejected;
243 lazyComponent._result = error;
244 }
245 });
246 }
247 }
248
249 function getWrappedName(outerType, innerType, wrapperName) {
250 var functionName = innerType.displayName || innerType.name || '';
251 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
252 }
253
254 function getComponentName(type) {
255 if (type == null) {
256 // Host root, text node or just invalid type.
257 return null;
258 }
259
260 {
261 if (typeof type.tag === 'number') {
262 error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
263 }
264 }
265
266 if (typeof type === 'function') {
267 return type.displayName || type.name || null;
268 }
269
270 if (typeof type === 'string') {
271 return type;
272 }
273
274 switch (type) {
275 case REACT_FRAGMENT_TYPE:
276 return 'Fragment';
277
278 case REACT_PORTAL_TYPE:
279 return 'Portal';
280
281 case REACT_PROFILER_TYPE:
282 return "Profiler";
283
284 case REACT_STRICT_MODE_TYPE:
285 return 'StrictMode';
286
287 case REACT_SUSPENSE_TYPE:
288 return 'Suspense';
289
290 case REACT_SUSPENSE_LIST_TYPE:
291 return 'SuspenseList';
292 }
293
294 if (typeof type === 'object') {
295 switch (type.$$typeof) {
296 case REACT_CONTEXT_TYPE:
297 return 'Context.Consumer';
298
299 case REACT_PROVIDER_TYPE:
300 return 'Context.Provider';
301
302 case REACT_FORWARD_REF_TYPE:
303 return getWrappedName(type, type.render, 'ForwardRef');
304
305 case REACT_MEMO_TYPE:
306 return getComponentName(type.type);
307
308 case REACT_BLOCK_TYPE:
309 return getComponentName(type.render);
310
311 case REACT_LAZY_TYPE:
312 {
313 var thenable = type;
314 var resolvedThenable = refineResolvedLazyComponent(thenable);
315
316 if (resolvedThenable) {
317 return getComponentName(resolvedThenable);
318 }
319
320 break;
321 }
322 }
323 }
324
325 return null;
326 }
327
328 // Don't change these two values. They're used by React Dev Tools.
329 var NoEffect =
330 /* */
331 0;
332 var PerformedWork =
333 /* */
334 1; // You can change the rest (and add more).
335
336 var Placement =
337 /* */
338 2;
339 var Update =
340 /* */
341 4;
342 var PlacementAndUpdate =
343 /* */
344 6;
345 var Deletion =
346 /* */
347 8;
348 var ContentReset =
349 /* */
350 16;
351 var Callback =
352 /* */
353 32;
354 var DidCapture =
355 /* */
356 64;
357 var Ref =
358 /* */
359 128;
360 var Snapshot =
361 /* */
362 256;
363 var Passive =
364 /* */
365 512;
366 var Hydrating =
367 /* */
368 1024;
369 var HydratingAndUpdate =
370 /* */
371 1028; // Passive & Update & Callback & Ref & Snapshot
372
373 var LifecycleEffectMask =
374 /* */
375 932; // Union of all host effects
376
377 var HostEffectMask =
378 /* */
379 2047;
380 var Incomplete =
381 /* */
382 2048;
383 var ShouldCapture =
384 /* */
385 4096;
386
387 var enableProfilerTimer = true; // Trace which interactions trigger each commit.
388
389 var enableFundamentalAPI = false; // Experimental Scope support.
390 var warnAboutStringRefs = false;
391
392 var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
393 function getNearestMountedFiber(fiber) {
394 var node = fiber;
395 var nearestMounted = fiber;
396
397 if (!fiber.alternate) {
398 // If there is no alternate, this might be a new tree that isn't inserted
399 // yet. If it is, then it will have a pending insertion effect on it.
400 var nextNode = node;
401
402 do {
403 node = nextNode;
404
405 if ((node.effectTag & (Placement | Hydrating)) !== NoEffect) {
406 // This is an insertion or in-progress hydration. The nearest possible
407 // mounted fiber is the parent but we need to continue to figure out
408 // if that one is still mounted.
409 nearestMounted = node.return;
410 }
411
412 nextNode = node.return;
413 } while (nextNode);
414 } else {
415 while (node.return) {
416 node = node.return;
417 }
418 }
419
420 if (node.tag === HostRoot) {
421 // TODO: Check if this was a nested HostRoot when used with
422 // renderContainerIntoSubtree.
423 return nearestMounted;
424 } // If we didn't hit the root, that means that we're in an disconnected tree
425 // that has been unmounted.
426
427
428 return null;
429 }
430 function isFiberMounted(fiber) {
431 return getNearestMountedFiber(fiber) === fiber;
432 }
433 function isMounted(component) {
434 {
435 var owner = ReactCurrentOwner.current;
436
437 if (owner !== null && owner.tag === ClassComponent) {
438 var ownerFiber = owner;
439 var instance = ownerFiber.stateNode;
440
441 if (!instance._warnedAboutRefsInRender) {
442 error('%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(ownerFiber.type) || 'A component');
443 }
444
445 instance._warnedAboutRefsInRender = true;
446 }
447 }
448
449 var fiber = get(component);
450
451 if (!fiber) {
452 return false;
453 }
454
455 return getNearestMountedFiber(fiber) === fiber;
456 }
457
458 function assertIsMounted(fiber) {
459 if (!(getNearestMountedFiber(fiber) === fiber)) {
460 {
461 throw Error( "Unable to find node on an unmounted component." );
462 }
463 }
464 }
465
466 function findCurrentFiberUsingSlowPath(fiber) {
467 var alternate = fiber.alternate;
468
469 if (!alternate) {
470 // If there is no alternate, then we only need to check if it is mounted.
471 var nearestMounted = getNearestMountedFiber(fiber);
472
473 if (!(nearestMounted !== null)) {
474 {
475 throw Error( "Unable to find node on an unmounted component." );
476 }
477 }
478
479 if (nearestMounted !== fiber) {
480 return null;
481 }
482
483 return fiber;
484 } // If we have two possible branches, we'll walk backwards up to the root
485 // to see what path the root points to. On the way we may hit one of the
486 // special cases and we'll deal with them.
487
488
489 var a = fiber;
490 var b = alternate;
491
492 while (true) {
493 var parentA = a.return;
494
495 if (parentA === null) {
496 // We're at the root.
497 break;
498 }
499
500 var parentB = parentA.alternate;
501
502 if (parentB === null) {
503 // There is no alternate. This is an unusual case. Currently, it only
504 // happens when a Suspense component is hidden. An extra fragment fiber
505 // is inserted in between the Suspense fiber and its children. Skip
506 // over this extra fragment fiber and proceed to the next parent.
507 var nextParent = parentA.return;
508
509 if (nextParent !== null) {
510 a = b = nextParent;
511 continue;
512 } // If there's no parent, we're at the root.
513
514
515 break;
516 } // If both copies of the parent fiber point to the same child, we can
517 // assume that the child is current. This happens when we bailout on low
518 // priority: the bailed out fiber's child reuses the current child.
519
520
521 if (parentA.child === parentB.child) {
522 var child = parentA.child;
523
524 while (child) {
525 if (child === a) {
526 // We've determined that A is the current branch.
527 assertIsMounted(parentA);
528 return fiber;
529 }
530
531 if (child === b) {
532 // We've determined that B is the current branch.
533 assertIsMounted(parentA);
534 return alternate;
535 }
536
537 child = child.sibling;
538 } // We should never have an alternate for any mounting node. So the only
539 // way this could possibly happen is if this was unmounted, if at all.
540
541
542 {
543 {
544 throw Error( "Unable to find node on an unmounted component." );
545 }
546 }
547 }
548
549 if (a.return !== b.return) {
550 // The return pointer of A and the return pointer of B point to different
551 // fibers. We assume that return pointers never criss-cross, so A must
552 // belong to the child set of A.return, and B must belong to the child
553 // set of B.return.
554 a = parentA;
555 b = parentB;
556 } else {
557 // The return pointers point to the same fiber. We'll have to use the
558 // default, slow path: scan the child sets of each parent alternate to see
559 // which child belongs to which set.
560 //
561 // Search parent A's child set
562 var didFindChild = false;
563 var _child = parentA.child;
564
565 while (_child) {
566 if (_child === a) {
567 didFindChild = true;
568 a = parentA;
569 b = parentB;
570 break;
571 }
572
573 if (_child === b) {
574 didFindChild = true;
575 b = parentA;
576 a = parentB;
577 break;
578 }
579
580 _child = _child.sibling;
581 }
582
583 if (!didFindChild) {
584 // Search parent B's child set
585 _child = parentB.child;
586
587 while (_child) {
588 if (_child === a) {
589 didFindChild = true;
590 a = parentB;
591 b = parentA;
592 break;
593 }
594
595 if (_child === b) {
596 didFindChild = true;
597 b = parentB;
598 a = parentA;
599 break;
600 }
601
602 _child = _child.sibling;
603 }
604
605 if (!didFindChild) {
606 {
607 throw Error( "Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue." );
608 }
609 }
610 }
611 }
612
613 if (!(a.alternate === b)) {
614 {
615 throw Error( "Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue." );
616 }
617 }
618 } // If the root is not a host container, we're in a disconnected tree. I.e.
619 // unmounted.
620
621
622 if (!(a.tag === HostRoot)) {
623 {
624 throw Error( "Unable to find node on an unmounted component." );
625 }
626 }
627
628 if (a.stateNode.current === a) {
629 // We've determined that A is the current branch.
630 return fiber;
631 } // Otherwise B has to be current branch.
632
633
634 return alternate;
635 }
636 function findCurrentHostFiber(parent) {
637 var currentParent = findCurrentFiberUsingSlowPath(parent);
638
639 if (!currentParent) {
640 return null;
641 } // Next we'll drill down this component to find the first HostComponent/Text.
642
643
644 var node = currentParent;
645
646 while (true) {
647 if (node.tag === HostComponent || node.tag === HostText) {
648 return node;
649 } else if (node.child) {
650 node.child.return = node;
651 node = node.child;
652 continue;
653 }
654
655 if (node === currentParent) {
656 return null;
657 }
658
659 while (!node.sibling) {
660 if (!node.return || node.return === currentParent) {
661 return null;
662 }
663
664 node = node.return;
665 }
666
667 node.sibling.return = node.return;
668 node = node.sibling;
669 } // Flow needs the return null here, but ESLint complains about it.
670 // eslint-disable-next-line no-unreachable
671
672
673 return null;
674 }
675
676 var _class = function(mixins){
677 var proto = {};
678 for (var i = 0, l = arguments.length; i < l; i++){
679 var mixin = arguments[i];
680 if (typeof mixin == 'function') mixin = mixin.prototype;
681 for (var key in mixin) proto[key] = mixin[key];
682 }
683 if (!proto.initialize) proto.initialize = function(){};
684 proto.constructor = function(a,b,c,d,e,f,g,h){
685 return new proto.initialize(a,b,c,d,e,f,g,h);
686 };
687 proto.constructor.prototype = proto.initialize.prototype = proto;
688 return proto.constructor;
689 };
690
691 function Transform(xx, yx, xy, yy, x, y){
692 if (xx && typeof xx == 'object'){
693 yx = xx.yx; yy = xx.yy; y = xx.y;
694 xy = xx.xy; x = xx.x; xx = xx.xx;
695 }
696 this.xx = xx == null ? 1 : xx;
697 this.yx = yx || 0;
698 this.xy = xy || 0;
699 this.yy = yy == null ? 1 : yy;
700 this.x = (x == null ? this.x : x) || 0;
701 this.y = (y == null ? this.y : y) || 0;
702 this._transform();
703 return this;
704 }
705 var transform = _class({
706
707 initialize: Transform,
708
709 _transform: function(){},
710
711 xx: 1, yx: 0, x: 0,
712 xy: 0, yy: 1, y: 0,
713
714 transform: function(xx, yx, xy, yy, x, y){
715 var m = this;
716 if (xx && typeof xx == 'object'){
717 yx = xx.yx; yy = xx.yy; y = xx.y;
718 xy = xx.xy; x = xx.x; xx = xx.xx;
719 }
720 if (!x) x = 0;
721 if (!y) y = 0;
722 return this.transformTo(
723 m.xx * xx + m.xy * yx,
724 m.yx * xx + m.yy * yx,
725 m.xx * xy + m.xy * yy,
726 m.yx * xy + m.yy * yy,
727 m.xx * x + m.xy * y + m.x,
728 m.yx * x + m.yy * y + m.y
729 );
730 },
731
732 transformTo: Transform,
733
734 translate: function(x, y){
735 return this.transform(1, 0, 0, 1, x, y);
736 },
737
738 move: function(x, y){
739 this.x += x || 0;
740 this.y += y || 0;
741 this._transform();
742 return this;
743 },
744
745 scale: function(x, y){
746 if (y == null) y = x;
747 return this.transform(x, 0, 0, y, 0, 0);
748 },
749
750 rotate: function(deg, x, y){
751 if (x == null || y == null){
752 x = (this.left || 0) + (this.width || 0) / 2;
753 y = (this.top || 0) + (this.height || 0) / 2;
754 }
755
756 var rad = deg * Math.PI / 180, sin = Math.sin(rad), cos = Math.cos(rad);
757
758 this.transform(1, 0, 0, 1, x, y);
759 var m = this;
760
761 return this.transformTo(
762 cos * m.xx - sin * m.yx,
763 sin * m.xx + cos * m.yx,
764 cos * m.xy - sin * m.yy,
765 sin * m.xy + cos * m.yy,
766 m.x,
767 m.y
768 ).transform(1, 0, 0, 1, -x, -y);
769 },
770
771 moveTo: function(x, y){
772 var m = this;
773 return this.transformTo(m.xx, m.yx, m.xy, m.yy, x, y);
774 },
775
776 rotateTo: function(deg, x, y){
777 var m = this;
778 var flip = m.yx / m.xx > m.yy / m.xy ? -1 : 1;
779 if (m.xx < 0 ? m.xy >= 0 : m.xy < 0) flip = -flip;
780 return this.rotate(deg - Math.atan2(flip * m.yx, flip * m.xx) * 180 / Math.PI, x, y);
781 },
782
783 scaleTo: function(x, y){
784 // Normalize
785 var m = this;
786
787 var h = Math.sqrt(m.xx * m.xx + m.yx * m.yx);
788 m.xx /= h; m.yx /= h;
789
790 h = Math.sqrt(m.yy * m.yy + m.xy * m.xy);
791 m.yy /= h; m.xy /= h;
792
793 return this.scale(x, y);
794 },
795
796 resizeTo: function(width, height){
797 var w = this.width, h = this.height;
798 if (!w || !h) return this;
799 return this.scaleTo(width / w, height / h);
800 },
801
802 /*
803 inverse: function(){
804 var a = this.xx, b = this.yx,
805 c = this.xy, d = this.yy,
806 e = this.x, f = this.y;
807 if (a * d - b * c == 0) return null;
808 return new Transform(
809 d/(a * d-b * c), b/(b * c-a * d),
810 c/(b * c-a * d), a/(a * d-b * c),
811 (d * e-c * f)/(b * c-a * d), (b * e-a * f)/(a * d-b * c)
812 );
813 },
814 */
815
816 inversePoint: function(x, y){
817 var a = this.xx, b = this.yx,
818 c = this.xy, d = this.yy,
819 e = this.x, f = this.y;
820 var det = b * c - a * d;
821 if (det == 0) return null;
822 return {
823 x: (d * (e - x) + c * (y - f)) / det,
824 y: (a * (f - y) + b * (x - e)) / det
825 };
826 },
827
828 point: function(x, y){
829 var m = this;
830 return {
831 x: m.xx * x + m.xy * y + m.x,
832 y: m.yx * x + m.yy * y + m.y
833 };
834 }
835
836 });
837
838 var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
839
840 function createCommonjsModule(fn, module) {
841 return module = { exports: {} }, fn(module, module.exports), module.exports;
842 }
843
844 var current = createCommonjsModule(function (module, exports) {
845 function warning(){
846 throw new Error('You must require a mode before requiring anything else.');
847 }
848
849 exports.Surface = warning;
850 exports.Path = warning;
851 exports.Shape = warning;
852 exports.Group = warning;
853 exports.ClippingRectangle = warning;
854 exports.Text = warning;
855
856 exports.setCurrent = function(mode){
857 for (var key in mode){
858 exports[key] = mode[key];
859 }
860 };
861 });
862 var current_1 = current.Surface;
863 var current_2 = current.Path;
864 var current_3 = current.Shape;
865 var current_4 = current.Group;
866 var current_5 = current.ClippingRectangle;
867 var current_6 = current.Text;
868 var current_7 = current.setCurrent;
869
870 var TYPES = {
871 CLIPPING_RECTANGLE: 'ClippingRectangle',
872 GROUP: 'Group',
873 SHAPE: 'Shape',
874 TEXT: 'Text'
875 };
876 var EVENT_TYPES = {
877 onClick: 'click',
878 onMouseMove: 'mousemove',
879 onMouseOver: 'mouseover',
880 onMouseOut: 'mouseout',
881 onMouseUp: 'mouseup',
882 onMouseDown: 'mousedown'
883 };
884 function childrenAsString(children) {
885 if (!children) {
886 return '';
887 } else if (typeof children === 'string') {
888 return children;
889 } else if (children.length) {
890 return children.join('');
891 } else {
892 return '';
893 }
894 }
895
896 // can re-export everything from this module.
897
898 function shim() {
899 {
900 {
901 throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." );
902 }
903 }
904 } // Hydration (when unsupported)
905 var isSuspenseInstancePending = shim;
906 var isSuspenseInstanceFallback = shim;
907 var hydrateTextInstance = shim;
908
909 var pooledTransform = new transform();
910 var NO_CONTEXT = {};
911 var UPDATE_SIGNAL = {};
912
913 {
914 Object.freeze(NO_CONTEXT);
915 Object.freeze(UPDATE_SIGNAL);
916 }
917 /** Helper Methods */
918
919
920 function addEventListeners(instance, type, listener) {
921 // We need to explicitly unregister before unmount.
922 // For this reason we need to track subscriptions.
923 if (!instance._listeners) {
924 instance._listeners = {};
925 instance._subscriptions = {};
926 }
927
928 instance._listeners[type] = listener;
929
930 if (listener) {
931 if (!instance._subscriptions[type]) {
932 instance._subscriptions[type] = instance.subscribe(type, createEventHandler(instance), instance);
933 }
934 } else {
935 if (instance._subscriptions[type]) {
936 instance._subscriptions[type]();
937
938 delete instance._subscriptions[type];
939 }
940 }
941 }
942
943 function createEventHandler(instance) {
944 return function handleEvent(event) {
945 var listener = instance._listeners[event.type];
946
947 if (!listener) ; else if (typeof listener === 'function') {
948 listener.call(instance, event);
949 } else if (listener.handleEvent) {
950 listener.handleEvent(event);
951 }
952 };
953 }
954
955 function destroyEventListeners(instance) {
956 if (instance._subscriptions) {
957 for (var type in instance._subscriptions) {
958 instance._subscriptions[type]();
959 }
960 }
961
962 instance._subscriptions = null;
963 instance._listeners = null;
964 }
965
966 function getScaleX(props) {
967 if (props.scaleX != null) {
968 return props.scaleX;
969 } else if (props.scale != null) {
970 return props.scale;
971 } else {
972 return 1;
973 }
974 }
975
976 function getScaleY(props) {
977 if (props.scaleY != null) {
978 return props.scaleY;
979 } else if (props.scale != null) {
980 return props.scale;
981 } else {
982 return 1;
983 }
984 }
985
986 function isSameFont(oldFont, newFont) {
987 if (oldFont === newFont) {
988 return true;
989 } else if (typeof newFont === 'string' || typeof oldFont === 'string') {
990 return false;
991 } else {
992 return newFont.fontSize === oldFont.fontSize && newFont.fontStyle === oldFont.fontStyle && newFont.fontVariant === oldFont.fontVariant && newFont.fontWeight === oldFont.fontWeight && newFont.fontFamily === oldFont.fontFamily;
993 }
994 }
995 /** Render Methods */
996
997
998 function applyClippingRectangleProps(instance, props) {
999 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1000 applyNodeProps(instance, props, prevProps);
1001 instance.width = props.width;
1002 instance.height = props.height;
1003 }
1004
1005 function applyGroupProps(instance, props) {
1006 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1007 applyNodeProps(instance, props, prevProps);
1008 instance.width = props.width;
1009 instance.height = props.height;
1010 }
1011
1012 function applyNodeProps(instance, props) {
1013 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1014 var scaleX = getScaleX(props);
1015 var scaleY = getScaleY(props);
1016 pooledTransform.transformTo(1, 0, 0, 1, 0, 0).move(props.x || 0, props.y || 0).rotate(props.rotation || 0, props.originX, props.originY).scale(scaleX, scaleY, props.originX, props.originY);
1017
1018 if (props.transform != null) {
1019 pooledTransform.transform(props.transform);
1020 }
1021
1022 if (instance.xx !== pooledTransform.xx || instance.yx !== pooledTransform.yx || instance.xy !== pooledTransform.xy || instance.yy !== pooledTransform.yy || instance.x !== pooledTransform.x || instance.y !== pooledTransform.y) {
1023 instance.transformTo(pooledTransform);
1024 }
1025
1026 if (props.cursor !== prevProps.cursor || props.title !== prevProps.title) {
1027 instance.indicate(props.cursor, props.title);
1028 }
1029
1030 if (instance.blend && props.opacity !== prevProps.opacity) {
1031 instance.blend(props.opacity == null ? 1 : props.opacity);
1032 }
1033
1034 if (props.visible !== prevProps.visible) {
1035 if (props.visible == null || props.visible) {
1036 instance.show();
1037 } else {
1038 instance.hide();
1039 }
1040 }
1041
1042 for (var type in EVENT_TYPES) {
1043 addEventListeners(instance, EVENT_TYPES[type], props[type]);
1044 }
1045 }
1046
1047 function applyRenderableNodeProps(instance, props) {
1048 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1049 applyNodeProps(instance, props, prevProps);
1050
1051 if (prevProps.fill !== props.fill) {
1052 if (props.fill && props.fill.applyFill) {
1053 props.fill.applyFill(instance);
1054 } else {
1055 instance.fill(props.fill);
1056 }
1057 }
1058
1059 if (prevProps.stroke !== props.stroke || prevProps.strokeWidth !== props.strokeWidth || prevProps.strokeCap !== props.strokeCap || prevProps.strokeJoin !== props.strokeJoin || // TODO: Consider deep check of stokeDash; may benefit VML in IE.
1060 prevProps.strokeDash !== props.strokeDash) {
1061 instance.stroke(props.stroke, props.strokeWidth, props.strokeCap, props.strokeJoin, props.strokeDash);
1062 }
1063 }
1064
1065 function applyShapeProps(instance, props) {
1066 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1067 applyRenderableNodeProps(instance, props, prevProps);
1068 var path = props.d || childrenAsString(props.children);
1069 var prevDelta = instance._prevDelta;
1070 var prevPath = instance._prevPath;
1071
1072 if (path !== prevPath || path.delta !== prevDelta || prevProps.height !== props.height || prevProps.width !== props.width) {
1073 instance.draw(path, props.width, props.height);
1074 instance._prevDelta = path.delta;
1075 instance._prevPath = path;
1076 }
1077 }
1078
1079 function applyTextProps(instance, props) {
1080 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1081 applyRenderableNodeProps(instance, props, prevProps);
1082 var string = props.children;
1083
1084 if (instance._currentString !== string || !isSameFont(props.font, prevProps.font) || props.alignment !== prevProps.alignment || props.path !== prevProps.path) {
1085 instance.draw(string, props.font, props.alignment, props.path);
1086 instance._currentString = string;
1087 }
1088 }
1089 function appendInitialChild(parentInstance, child) {
1090 if (typeof child === 'string') {
1091 // Noop for string children of Text (eg <Text>{'foo'}{'bar'}</Text>)
1092 {
1093 {
1094 throw Error( "Text children should already be flattened." );
1095 }
1096 }
1097 }
1098
1099 child.inject(parentInstance);
1100 }
1101 function createInstance(type, props, internalInstanceHandle) {
1102 var instance;
1103
1104 switch (type) {
1105 case TYPES.CLIPPING_RECTANGLE:
1106 instance = current.ClippingRectangle();
1107 instance._applyProps = applyClippingRectangleProps;
1108 break;
1109
1110 case TYPES.GROUP:
1111 instance = current.Group();
1112 instance._applyProps = applyGroupProps;
1113 break;
1114
1115 case TYPES.SHAPE:
1116 instance = current.Shape();
1117 instance._applyProps = applyShapeProps;
1118 break;
1119
1120 case TYPES.TEXT:
1121 instance = current.Text(props.children, props.font, props.alignment, props.path);
1122 instance._applyProps = applyTextProps;
1123 break;
1124 }
1125
1126 if (!instance) {
1127 {
1128 throw Error( "ReactART does not support the type \"" + type + "\"" );
1129 }
1130 }
1131
1132 instance._applyProps(instance, props);
1133
1134 return instance;
1135 }
1136 function createTextInstance(text, rootContainerInstance, internalInstanceHandle) {
1137 return text;
1138 }
1139 function getPublicInstance(instance) {
1140 return instance;
1141 }
1142 function prepareForCommit() {// Noop
1143 }
1144 function prepareUpdate(domElement, type, oldProps, newProps) {
1145 return UPDATE_SIGNAL;
1146 }
1147 function resetAfterCommit() {// Noop
1148 }
1149 function resetTextContent(domElement) {// Noop
1150 }
1151 function shouldDeprioritizeSubtree(type, props) {
1152 return false;
1153 }
1154 function getRootHostContext() {
1155 return NO_CONTEXT;
1156 }
1157 function getChildHostContext() {
1158 return NO_CONTEXT;
1159 }
1160 var scheduleTimeout = setTimeout;
1161 var cancelTimeout = clearTimeout;
1162 var noTimeout = -1;
1163 function shouldSetTextContent(type, props) {
1164 return typeof props.children === 'string' || typeof props.children === 'number';
1165 } // The ART renderer is secondary to the React DOM renderer.
1166 function appendChild(parentInstance, child) {
1167 if (child.parentNode === parentInstance) {
1168 child.eject();
1169 }
1170
1171 child.inject(parentInstance);
1172 }
1173 function appendChildToContainer(parentInstance, child) {
1174 if (child.parentNode === parentInstance) {
1175 child.eject();
1176 }
1177
1178 child.inject(parentInstance);
1179 }
1180 function insertBefore(parentInstance, child, beforeChild) {
1181 if (!(child !== beforeChild)) {
1182 {
1183 throw Error( "ReactART: Can not insert node before itself" );
1184 }
1185 }
1186
1187 child.injectBefore(beforeChild);
1188 }
1189 function insertInContainerBefore(parentInstance, child, beforeChild) {
1190 if (!(child !== beforeChild)) {
1191 {
1192 throw Error( "ReactART: Can not insert node before itself" );
1193 }
1194 }
1195
1196 child.injectBefore(beforeChild);
1197 }
1198 function removeChild(parentInstance, child) {
1199 destroyEventListeners(child);
1200 child.eject();
1201 }
1202 function removeChildFromContainer(parentInstance, child) {
1203 destroyEventListeners(child);
1204 child.eject();
1205 }
1206 function commitUpdate(instance, updatePayload, type, oldProps, newProps) {
1207 instance._applyProps(instance, newProps, oldProps);
1208 }
1209 function hideInstance(instance) {
1210 instance.hide();
1211 }
1212 function unhideInstance(instance, props) {
1213 if (props.visible == null || props.visible) {
1214 instance.show();
1215 }
1216 }
1217 function unhideTextInstance(textInstance, text) {// Noop
1218 }
1219
1220 /**
1221 * Copyright (c) 2013-present, Facebook, Inc.
1222 *
1223 * This source code is licensed under the MIT license found in the
1224 * LICENSE file in the root directory of this source tree.
1225 */
1226
1227 var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
1228
1229 var ReactPropTypesSecret_1 = ReactPropTypesSecret;
1230
1231 var printWarning$1 = function() {};
1232
1233 {
1234 var ReactPropTypesSecret$1 = ReactPropTypesSecret_1;
1235 var loggedTypeFailures = {};
1236 var has = Function.call.bind(Object.prototype.hasOwnProperty);
1237
1238 printWarning$1 = function(text) {
1239 var message = 'Warning: ' + text;
1240 if (typeof console !== 'undefined') {
1241 console.error(message);
1242 }
1243 try {
1244 // --- Welcome to debugging React ---
1245 // This error was thrown as a convenience so that you can use this stack
1246 // to find the callsite that caused this warning to fire.
1247 throw new Error(message);
1248 } catch (x) {}
1249 };
1250 }
1251
1252 /**
1253 * Assert that the values match with the type specs.
1254 * Error messages are memorized and will only be shown once.
1255 *
1256 * @param {object} typeSpecs Map of name to a ReactPropType
1257 * @param {object} values Runtime values that need to be type-checked
1258 * @param {string} location e.g. "prop", "context", "child context"
1259 * @param {string} componentName Name of the component for error messages.
1260 * @param {?Function} getStack Returns the component stack.
1261 * @private
1262 */
1263 function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
1264 {
1265 for (var typeSpecName in typeSpecs) {
1266 if (has(typeSpecs, typeSpecName)) {
1267 var error;
1268 // Prop type validation may throw. In case they do, we don't want to
1269 // fail the render phase where it didn't fail before. So we log it.
1270 // After these have been cleaned up, we'll let them throw.
1271 try {
1272 // This is intentionally an invariant that gets caught. It's the same
1273 // behavior as without this statement except with a better message.
1274 if (typeof typeSpecs[typeSpecName] !== 'function') {
1275 var err = Error(
1276 (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +
1277 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'
1278 );
1279 err.name = 'Invariant Violation';
1280 throw err;
1281 }
1282 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret$1);
1283 } catch (ex) {
1284 error = ex;
1285 }
1286 if (error && !(error instanceof Error)) {
1287 printWarning$1(
1288 (componentName || 'React class') + ': type specification of ' +
1289 location + ' `' + typeSpecName + '` is invalid; the type checker ' +
1290 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +
1291 'You may have forgotten to pass an argument to the type checker ' +
1292 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
1293 'shape all require an argument).'
1294 );
1295 }
1296 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
1297 // Only monitor this failure once because there tends to be a lot of the
1298 // same error.
1299 loggedTypeFailures[error.message] = true;
1300
1301 var stack = getStack ? getStack() : '';
1302
1303 printWarning$1(
1304 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')
1305 );
1306 }
1307 }
1308 }
1309 }
1310 }
1311
1312 /**
1313 * Resets warning cache when testing.
1314 *
1315 * @private
1316 */
1317 checkPropTypes.resetWarningCache = function() {
1318 {
1319 loggedTypeFailures = {};
1320 }
1321 };
1322
1323 var checkPropTypes_1 = checkPropTypes;
1324
1325 var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
1326 function describeComponentFrame (name, source, ownerName) {
1327 var sourceInfo = '';
1328
1329 if (source) {
1330 var path = source.fileName;
1331 var fileName = path.replace(BEFORE_SLASH_RE, '');
1332
1333 {
1334 // In DEV, include code for a common special case:
1335 // prefer "folder/index.js" instead of just "index.js".
1336 if (/^index\./.test(fileName)) {
1337 var match = path.match(BEFORE_SLASH_RE);
1338
1339 if (match) {
1340 var pathBeforeSlash = match[1];
1341
1342 if (pathBeforeSlash) {
1343 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
1344 fileName = folderName + '/' + fileName;
1345 }
1346 }
1347 }
1348 }
1349
1350 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
1351 } else if (ownerName) {
1352 sourceInfo = ' (created by ' + ownerName + ')';
1353 }
1354
1355 return '\n in ' + (name || 'Unknown') + sourceInfo;
1356 }
1357
1358 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1359
1360 function describeFiber(fiber) {
1361 switch (fiber.tag) {
1362 case HostRoot:
1363 case HostPortal:
1364 case HostText:
1365 case Fragment:
1366 case ContextProvider:
1367 case ContextConsumer:
1368 return '';
1369
1370 default:
1371 var owner = fiber._debugOwner;
1372 var source = fiber._debugSource;
1373 var name = getComponentName(fiber.type);
1374 var ownerName = null;
1375
1376 if (owner) {
1377 ownerName = getComponentName(owner.type);
1378 }
1379
1380 return describeComponentFrame(name, source, ownerName);
1381 }
1382 }
1383
1384 function getStackByFiberInDevAndProd(workInProgress) {
1385 var info = '';
1386 var node = workInProgress;
1387
1388 do {
1389 info += describeFiber(node);
1390 node = node.return;
1391 } while (node);
1392
1393 return info;
1394 }
1395 var current$1 = null;
1396 var isRendering = false;
1397 function getCurrentFiberOwnerNameInDevOrNull() {
1398 {
1399 if (current$1 === null) {
1400 return null;
1401 }
1402
1403 var owner = current$1._debugOwner;
1404
1405 if (owner !== null && typeof owner !== 'undefined') {
1406 return getComponentName(owner.type);
1407 }
1408 }
1409
1410 return null;
1411 }
1412 function getCurrentFiberStackInDev() {
1413 {
1414 if (current$1 === null) {
1415 return '';
1416 } // Safe because if current fiber exists, we are reconciling,
1417 // and it is guaranteed to be the work-in-progress version.
1418
1419
1420 return getStackByFiberInDevAndProd(current$1);
1421 }
1422 }
1423 function resetCurrentFiber() {
1424 {
1425 ReactDebugCurrentFrame.getCurrentStack = null;
1426 current$1 = null;
1427 isRendering = false;
1428 }
1429 }
1430 function setCurrentFiber(fiber) {
1431 {
1432 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
1433 current$1 = fiber;
1434 isRendering = false;
1435 }
1436 }
1437 function setIsRendering(rendering) {
1438 {
1439 isRendering = rendering;
1440 }
1441 }
1442
1443 // Prefix measurements so that it's possible to filter them.
1444 // Longer prefixes are hard to read in DevTools.
1445 var reactEmoji = "\u269B";
1446 var warningEmoji = "\u26D4";
1447 var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function'; // Keep track of current fiber so that we know the path to unwind on pause.
1448 // TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
1449
1450 var currentFiber = null; // If we're in the middle of user code, which fiber and method is it?
1451 // Reusing `currentFiber` would be confusing for this because user code fiber
1452 // can change during commit phase too, but we don't need to unwind it (since
1453 // lifecycles in the commit phase don't resemble a tree).
1454
1455 var currentPhase = null;
1456 var currentPhaseFiber = null; // Did lifecycle hook schedule an update? This is often a performance problem,
1457 // so we will keep track of it, and include it in the report.
1458 // Track commits caused by cascading updates.
1459
1460 var isCommitting = false;
1461 var hasScheduledUpdateInCurrentCommit = false;
1462 var hasScheduledUpdateInCurrentPhase = false;
1463 var commitCountInCurrentWorkLoop = 0;
1464 var effectCountInCurrentCommit = 0;
1465 // to avoid stretch the commit phase with measurement overhead.
1466
1467 var labelsInCurrentCommit = new Set();
1468
1469 var formatMarkName = function (markName) {
1470 return reactEmoji + " " + markName;
1471 };
1472
1473 var formatLabel = function (label, warning) {
1474 var prefix = warning ? warningEmoji + " " : reactEmoji + " ";
1475 var suffix = warning ? " Warning: " + warning : '';
1476 return "" + prefix + label + suffix;
1477 };
1478
1479 var beginMark = function (markName) {
1480 performance.mark(formatMarkName(markName));
1481 };
1482
1483 var clearMark = function (markName) {
1484 performance.clearMarks(formatMarkName(markName));
1485 };
1486
1487 var endMark = function (label, markName, warning) {
1488 var formattedMarkName = formatMarkName(markName);
1489 var formattedLabel = formatLabel(label, warning);
1490
1491 try {
1492 performance.measure(formattedLabel, formattedMarkName);
1493 } catch (err) {} // If previous mark was missing for some reason, this will throw.
1494 // This could only happen if React crashed in an unexpected place earlier.
1495 // Don't pile on with more errors.
1496 // Clear marks immediately to avoid growing buffer.
1497
1498
1499 performance.clearMarks(formattedMarkName);
1500 performance.clearMeasures(formattedLabel);
1501 };
1502
1503 var getFiberMarkName = function (label, debugID) {
1504 return label + " (#" + debugID + ")";
1505 };
1506
1507 var getFiberLabel = function (componentName, isMounted, phase) {
1508 if (phase === null) {
1509 // These are composite component total time measurements.
1510 return componentName + " [" + (isMounted ? 'update' : 'mount') + "]";
1511 } else {
1512 // Composite component methods.
1513 return componentName + "." + phase;
1514 }
1515 };
1516
1517 var beginFiberMark = function (fiber, phase) {
1518 var componentName = getComponentName(fiber.type) || 'Unknown';
1519 var debugID = fiber._debugID;
1520 var isMounted = fiber.alternate !== null;
1521 var label = getFiberLabel(componentName, isMounted, phase);
1522
1523 if (isCommitting && labelsInCurrentCommit.has(label)) {
1524 // During the commit phase, we don't show duplicate labels because
1525 // there is a fixed overhead for every measurement, and we don't
1526 // want to stretch the commit phase beyond necessary.
1527 return false;
1528 }
1529
1530 labelsInCurrentCommit.add(label);
1531 var markName = getFiberMarkName(label, debugID);
1532 beginMark(markName);
1533 return true;
1534 };
1535
1536 var clearFiberMark = function (fiber, phase) {
1537 var componentName = getComponentName(fiber.type) || 'Unknown';
1538 var debugID = fiber._debugID;
1539 var isMounted = fiber.alternate !== null;
1540 var label = getFiberLabel(componentName, isMounted, phase);
1541 var markName = getFiberMarkName(label, debugID);
1542 clearMark(markName);
1543 };
1544
1545 var endFiberMark = function (fiber, phase, warning) {
1546 var componentName = getComponentName(fiber.type) || 'Unknown';
1547 var debugID = fiber._debugID;
1548 var isMounted = fiber.alternate !== null;
1549 var label = getFiberLabel(componentName, isMounted, phase);
1550 var markName = getFiberMarkName(label, debugID);
1551 endMark(label, markName, warning);
1552 };
1553
1554 var shouldIgnoreFiber = function (fiber) {
1555 // Host components should be skipped in the timeline.
1556 // We could check typeof fiber.type, but does this work with RN?
1557 switch (fiber.tag) {
1558 case HostRoot:
1559 case HostComponent:
1560 case HostText:
1561 case HostPortal:
1562 case Fragment:
1563 case ContextProvider:
1564 case ContextConsumer:
1565 case Mode:
1566 return true;
1567
1568 default:
1569 return false;
1570 }
1571 };
1572
1573 var clearPendingPhaseMeasurement = function () {
1574 if (currentPhase !== null && currentPhaseFiber !== null) {
1575 clearFiberMark(currentPhaseFiber, currentPhase);
1576 }
1577
1578 currentPhaseFiber = null;
1579 currentPhase = null;
1580 hasScheduledUpdateInCurrentPhase = false;
1581 };
1582
1583 var pauseTimers = function () {
1584 // Stops all currently active measurements so that they can be resumed
1585 // if we continue in a later deferred loop from the same unit of work.
1586 var fiber = currentFiber;
1587
1588 while (fiber) {
1589 if (fiber._debugIsCurrentlyTiming) {
1590 endFiberMark(fiber, null, null);
1591 }
1592
1593 fiber = fiber.return;
1594 }
1595 };
1596
1597 var resumeTimersRecursively = function (fiber) {
1598 if (fiber.return !== null) {
1599 resumeTimersRecursively(fiber.return);
1600 }
1601
1602 if (fiber._debugIsCurrentlyTiming) {
1603 beginFiberMark(fiber, null);
1604 }
1605 };
1606
1607 var resumeTimers = function () {
1608 // Resumes all measurements that were active during the last deferred loop.
1609 if (currentFiber !== null) {
1610 resumeTimersRecursively(currentFiber);
1611 }
1612 };
1613
1614 function recordEffect() {
1615 {
1616 effectCountInCurrentCommit++;
1617 }
1618 }
1619 function recordScheduleUpdate() {
1620 {
1621 if (isCommitting) {
1622 hasScheduledUpdateInCurrentCommit = true;
1623 }
1624
1625 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
1626 hasScheduledUpdateInCurrentPhase = true;
1627 }
1628 }
1629 }
1630 function startWorkTimer(fiber) {
1631 {
1632 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1633 return;
1634 } // If we pause, this is the fiber to unwind from.
1635
1636
1637 currentFiber = fiber;
1638
1639 if (!beginFiberMark(fiber, null)) {
1640 return;
1641 }
1642
1643 fiber._debugIsCurrentlyTiming = true;
1644 }
1645 }
1646 function cancelWorkTimer(fiber) {
1647 {
1648 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1649 return;
1650 } // Remember we shouldn't complete measurement for this fiber.
1651 // Otherwise flamechart will be deep even for small updates.
1652
1653
1654 fiber._debugIsCurrentlyTiming = false;
1655 clearFiberMark(fiber, null);
1656 }
1657 }
1658 function stopWorkTimer(fiber) {
1659 {
1660 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1661 return;
1662 } // If we pause, its parent is the fiber to unwind from.
1663
1664
1665 currentFiber = fiber.return;
1666
1667 if (!fiber._debugIsCurrentlyTiming) {
1668 return;
1669 }
1670
1671 fiber._debugIsCurrentlyTiming = false;
1672 endFiberMark(fiber, null, null);
1673 }
1674 }
1675 function stopFailedWorkTimer(fiber) {
1676 {
1677 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1678 return;
1679 } // If we pause, its parent is the fiber to unwind from.
1680
1681
1682 currentFiber = fiber.return;
1683
1684 if (!fiber._debugIsCurrentlyTiming) {
1685 return;
1686 }
1687
1688 fiber._debugIsCurrentlyTiming = false;
1689 var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
1690 endFiberMark(fiber, null, warning);
1691 }
1692 }
1693 function startPhaseTimer(fiber, phase) {
1694 {
1695 if (!supportsUserTiming) {
1696 return;
1697 }
1698
1699 clearPendingPhaseMeasurement();
1700
1701 if (!beginFiberMark(fiber, phase)) {
1702 return;
1703 }
1704
1705 currentPhaseFiber = fiber;
1706 currentPhase = phase;
1707 }
1708 }
1709 function stopPhaseTimer() {
1710 {
1711 if (!supportsUserTiming) {
1712 return;
1713 }
1714
1715 if (currentPhase !== null && currentPhaseFiber !== null) {
1716 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
1717 endFiberMark(currentPhaseFiber, currentPhase, warning);
1718 }
1719
1720 currentPhase = null;
1721 currentPhaseFiber = null;
1722 }
1723 }
1724 function startWorkLoopTimer(nextUnitOfWork) {
1725 {
1726 currentFiber = nextUnitOfWork;
1727
1728 if (!supportsUserTiming) {
1729 return;
1730 }
1731
1732 commitCountInCurrentWorkLoop = 0; // This is top level call.
1733 // Any other measurements are performed within.
1734
1735 beginMark('(React Tree Reconciliation)'); // Resume any measurements that were in progress during the last loop.
1736
1737 resumeTimers();
1738 }
1739 }
1740 function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
1741 {
1742 if (!supportsUserTiming) {
1743 return;
1744 }
1745
1746 var warning = null;
1747
1748 if (interruptedBy !== null) {
1749 if (interruptedBy.tag === HostRoot) {
1750 warning = 'A top-level update interrupted the previous render';
1751 } else {
1752 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
1753 warning = "An update to " + componentName + " interrupted the previous render";
1754 }
1755 } else if (commitCountInCurrentWorkLoop > 1) {
1756 warning = 'There were cascading updates';
1757 }
1758
1759 commitCountInCurrentWorkLoop = 0;
1760 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)'; // Pause any measurements until the next loop.
1761
1762 pauseTimers();
1763 endMark(label, '(React Tree Reconciliation)', warning);
1764 }
1765 }
1766 function startCommitTimer() {
1767 {
1768 if (!supportsUserTiming) {
1769 return;
1770 }
1771
1772 isCommitting = true;
1773 hasScheduledUpdateInCurrentCommit = false;
1774 labelsInCurrentCommit.clear();
1775 beginMark('(Committing Changes)');
1776 }
1777 }
1778 function stopCommitTimer() {
1779 {
1780 if (!supportsUserTiming) {
1781 return;
1782 }
1783
1784 var warning = null;
1785
1786 if (hasScheduledUpdateInCurrentCommit) {
1787 warning = 'Lifecycle hook scheduled a cascading update';
1788 } else if (commitCountInCurrentWorkLoop > 0) {
1789 warning = 'Caused by a cascading update in earlier commit';
1790 }
1791
1792 hasScheduledUpdateInCurrentCommit = false;
1793 commitCountInCurrentWorkLoop++;
1794 isCommitting = false;
1795 labelsInCurrentCommit.clear();
1796 endMark('(Committing Changes)', '(Committing Changes)', warning);
1797 }
1798 }
1799 function startCommitSnapshotEffectsTimer() {
1800 {
1801 if (!supportsUserTiming) {
1802 return;
1803 }
1804
1805 effectCountInCurrentCommit = 0;
1806 beginMark('(Committing Snapshot Effects)');
1807 }
1808 }
1809 function stopCommitSnapshotEffectsTimer() {
1810 {
1811 if (!supportsUserTiming) {
1812 return;
1813 }
1814
1815 var count = effectCountInCurrentCommit;
1816 effectCountInCurrentCommit = 0;
1817 endMark("(Committing Snapshot Effects: " + count + " Total)", '(Committing Snapshot Effects)', null);
1818 }
1819 }
1820 function startCommitHostEffectsTimer() {
1821 {
1822 if (!supportsUserTiming) {
1823 return;
1824 }
1825
1826 effectCountInCurrentCommit = 0;
1827 beginMark('(Committing Host Effects)');
1828 }
1829 }
1830 function stopCommitHostEffectsTimer() {
1831 {
1832 if (!supportsUserTiming) {
1833 return;
1834 }
1835
1836 var count = effectCountInCurrentCommit;
1837 effectCountInCurrentCommit = 0;
1838 endMark("(Committing Host Effects: " + count + " Total)", '(Committing Host Effects)', null);
1839 }
1840 }
1841 function startCommitLifeCyclesTimer() {
1842 {
1843 if (!supportsUserTiming) {
1844 return;
1845 }
1846
1847 effectCountInCurrentCommit = 0;
1848 beginMark('(Calling Lifecycle Methods)');
1849 }
1850 }
1851 function stopCommitLifeCyclesTimer() {
1852 {
1853 if (!supportsUserTiming) {
1854 return;
1855 }
1856
1857 var count = effectCountInCurrentCommit;
1858 effectCountInCurrentCommit = 0;
1859 endMark("(Calling Lifecycle Methods: " + count + " Total)", '(Calling Lifecycle Methods)', null);
1860 }
1861 }
1862
1863 var valueStack = [];
1864 var fiberStack;
1865
1866 {
1867 fiberStack = [];
1868 }
1869
1870 var index = -1;
1871
1872 function createCursor(defaultValue) {
1873 return {
1874 current: defaultValue
1875 };
1876 }
1877
1878 function pop(cursor, fiber) {
1879 if (index < 0) {
1880 {
1881 error('Unexpected pop.');
1882 }
1883
1884 return;
1885 }
1886
1887 {
1888 if (fiber !== fiberStack[index]) {
1889 error('Unexpected Fiber popped.');
1890 }
1891 }
1892
1893 cursor.current = valueStack[index];
1894 valueStack[index] = null;
1895
1896 {
1897 fiberStack[index] = null;
1898 }
1899
1900 index--;
1901 }
1902
1903 function push(cursor, value, fiber) {
1904 index++;
1905 valueStack[index] = cursor.current;
1906
1907 {
1908 fiberStack[index] = fiber;
1909 }
1910
1911 cursor.current = value;
1912 }
1913
1914 var warnedAboutMissingGetChildContext;
1915
1916 {
1917 warnedAboutMissingGetChildContext = {};
1918 }
1919
1920 var emptyContextObject = {};
1921
1922 {
1923 Object.freeze(emptyContextObject);
1924 } // A cursor to the current merged context object on the stack.
1925
1926
1927 var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.
1928
1929 var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.
1930 // We use this to get access to the parent context after we have already
1931 // pushed the next context provider, and now need to merge their contexts.
1932
1933 var previousContext = emptyContextObject;
1934
1935 function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
1936 {
1937 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
1938 // If the fiber is a context provider itself, when we read its context
1939 // we may have already pushed its own child context on the stack. A context
1940 // provider should not "see" its own child context. Therefore we read the
1941 // previous (parent) context instead for a context provider.
1942 return previousContext;
1943 }
1944
1945 return contextStackCursor.current;
1946 }
1947 }
1948
1949 function cacheContext(workInProgress, unmaskedContext, maskedContext) {
1950 {
1951 var instance = workInProgress.stateNode;
1952 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
1953 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
1954 }
1955 }
1956
1957 function getMaskedContext(workInProgress, unmaskedContext) {
1958 {
1959 var type = workInProgress.type;
1960 var contextTypes = type.contextTypes;
1961
1962 if (!contextTypes) {
1963 return emptyContextObject;
1964 } // Avoid recreating masked context unless unmasked context has changed.
1965 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
1966 // This may trigger infinite loops if componentWillReceiveProps calls setState.
1967
1968
1969 var instance = workInProgress.stateNode;
1970
1971 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
1972 return instance.__reactInternalMemoizedMaskedChildContext;
1973 }
1974
1975 var context = {};
1976
1977 for (var key in contextTypes) {
1978 context[key] = unmaskedContext[key];
1979 }
1980
1981 {
1982 var name = getComponentName(type) || 'Unknown';
1983 checkPropTypes_1(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
1984 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
1985 // Context is created before the class component is instantiated so check for instance.
1986
1987
1988 if (instance) {
1989 cacheContext(workInProgress, unmaskedContext, context);
1990 }
1991
1992 return context;
1993 }
1994 }
1995
1996 function hasContextChanged() {
1997 {
1998 return didPerformWorkStackCursor.current;
1999 }
2000 }
2001
2002 function isContextProvider(type) {
2003 {
2004 var childContextTypes = type.childContextTypes;
2005 return childContextTypes !== null && childContextTypes !== undefined;
2006 }
2007 }
2008
2009 function popContext(fiber) {
2010 {
2011 pop(didPerformWorkStackCursor, fiber);
2012 pop(contextStackCursor, fiber);
2013 }
2014 }
2015
2016 function popTopLevelContextObject(fiber) {
2017 {
2018 pop(didPerformWorkStackCursor, fiber);
2019 pop(contextStackCursor, fiber);
2020 }
2021 }
2022
2023 function pushTopLevelContextObject(fiber, context, didChange) {
2024 {
2025 if (!(contextStackCursor.current === emptyContextObject)) {
2026 {
2027 throw Error( "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." );
2028 }
2029 }
2030
2031 push(contextStackCursor, context, fiber);
2032 push(didPerformWorkStackCursor, didChange, fiber);
2033 }
2034 }
2035
2036 function processChildContext(fiber, type, parentContext) {
2037 {
2038 var instance = fiber.stateNode;
2039 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.
2040 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
2041
2042 if (typeof instance.getChildContext !== 'function') {
2043 {
2044 var componentName = getComponentName(type) || 'Unknown';
2045
2046 if (!warnedAboutMissingGetChildContext[componentName]) {
2047 warnedAboutMissingGetChildContext[componentName] = true;
2048
2049 error('%s.childContextTypes is specified but there is no getChildContext() method ' + 'on the instance. You can either define getChildContext() on %s or remove ' + 'childContextTypes from it.', componentName, componentName);
2050 }
2051 }
2052
2053 return parentContext;
2054 }
2055
2056 var childContext;
2057 startPhaseTimer(fiber, 'getChildContext');
2058 childContext = instance.getChildContext();
2059 stopPhaseTimer();
2060
2061 for (var contextKey in childContext) {
2062 if (!(contextKey in childContextTypes)) {
2063 {
2064 throw Error( (getComponentName(type) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes." );
2065 }
2066 }
2067 }
2068
2069 {
2070 var name = getComponentName(type) || 'Unknown';
2071 checkPropTypes_1(childContextTypes, childContext, 'child context', name, // In practice, there is one case in which we won't get a stack. It's when
2072 // somebody calls unstable_renderSubtreeIntoContainer() and we process
2073 // context from the parent component instance. The stack will be missing
2074 // because it's outside of the reconciliation, and so the pointer has not
2075 // been set. This is rare and doesn't matter. We'll also remove that API.
2076 getCurrentFiberStackInDev);
2077 }
2078
2079 return _assign({}, parentContext, {}, childContext);
2080 }
2081 }
2082
2083 function pushContextProvider(workInProgress) {
2084 {
2085 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.
2086 // If the instance does not exist yet, we will push null at first,
2087 // and replace it on the stack later when invalidating the context.
2088
2089 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.
2090 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
2091
2092 previousContext = contextStackCursor.current;
2093 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
2094 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
2095 return true;
2096 }
2097 }
2098
2099 function invalidateContextProvider(workInProgress, type, didChange) {
2100 {
2101 var instance = workInProgress.stateNode;
2102
2103 if (!instance) {
2104 {
2105 throw Error( "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." );
2106 }
2107 }
2108
2109 if (didChange) {
2110 // Merge parent and own context.
2111 // Skip this if we're not updating due to sCU.
2112 // This avoids unnecessarily recomputing memoized values.
2113 var mergedContext = processChildContext(workInProgress, type, previousContext);
2114 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.
2115 // It is important to unwind the context in the reverse order.
2116
2117 pop(didPerformWorkStackCursor, workInProgress);
2118 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.
2119
2120 push(contextStackCursor, mergedContext, workInProgress);
2121 push(didPerformWorkStackCursor, didChange, workInProgress);
2122 } else {
2123 pop(didPerformWorkStackCursor, workInProgress);
2124 push(didPerformWorkStackCursor, didChange, workInProgress);
2125 }
2126 }
2127 }
2128
2129 function findCurrentUnmaskedContext(fiber) {
2130 {
2131 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
2132 // makes sense elsewhere
2133 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {
2134 {
2135 throw Error( "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." );
2136 }
2137 }
2138
2139 var node = fiber;
2140
2141 do {
2142 switch (node.tag) {
2143 case HostRoot:
2144 return node.stateNode.context;
2145
2146 case ClassComponent:
2147 {
2148 var Component = node.type;
2149
2150 if (isContextProvider(Component)) {
2151 return node.stateNode.__reactInternalMemoizedMergedChildContext;
2152 }
2153
2154 break;
2155 }
2156 }
2157
2158 node = node.return;
2159 } while (node !== null);
2160
2161 {
2162 {
2163 throw Error( "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." );
2164 }
2165 }
2166 }
2167 }
2168
2169 var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2170 var _ReactInternals$Sched = ReactInternals$1.Scheduler,
2171 unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback,
2172 unstable_now = _ReactInternals$Sched.unstable_now,
2173 unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback,
2174 unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield,
2175 unstable_requestPaint = _ReactInternals$Sched.unstable_requestPaint,
2176 unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode,
2177 unstable_runWithPriority = _ReactInternals$Sched.unstable_runWithPriority,
2178 unstable_next = _ReactInternals$Sched.unstable_next,
2179 unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution,
2180 unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution,
2181 unstable_getCurrentPriorityLevel = _ReactInternals$Sched.unstable_getCurrentPriorityLevel,
2182 unstable_ImmediatePriority = _ReactInternals$Sched.unstable_ImmediatePriority,
2183 unstable_UserBlockingPriority = _ReactInternals$Sched.unstable_UserBlockingPriority,
2184 unstable_NormalPriority = _ReactInternals$Sched.unstable_NormalPriority,
2185 unstable_LowPriority = _ReactInternals$Sched.unstable_LowPriority,
2186 unstable_IdlePriority = _ReactInternals$Sched.unstable_IdlePriority,
2187 unstable_forceFrameRate = _ReactInternals$Sched.unstable_forceFrameRate,
2188 unstable_flushAllWithoutAsserting = _ReactInternals$Sched.unstable_flushAllWithoutAsserting;
2189
2190 var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2191 var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing,
2192 __interactionsRef = _ReactInternals$Sched$1.__interactionsRef,
2193 __subscriberRef = _ReactInternals$Sched$1.__subscriberRef,
2194 unstable_clear = _ReactInternals$Sched$1.unstable_clear,
2195 unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent,
2196 unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID,
2197 unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe,
2198 unstable_trace = _ReactInternals$Sched$1.unstable_trace,
2199 unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe,
2200 unstable_wrap = _ReactInternals$Sched$1.unstable_wrap;
2201
2202 var Scheduler_runWithPriority = unstable_runWithPriority,
2203 Scheduler_scheduleCallback = unstable_scheduleCallback,
2204 Scheduler_cancelCallback = unstable_cancelCallback,
2205 Scheduler_shouldYield = unstable_shouldYield,
2206 Scheduler_requestPaint = unstable_requestPaint,
2207 Scheduler_now = unstable_now,
2208 Scheduler_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel,
2209 Scheduler_ImmediatePriority = unstable_ImmediatePriority,
2210 Scheduler_UserBlockingPriority = unstable_UserBlockingPriority,
2211 Scheduler_NormalPriority = unstable_NormalPriority,
2212 Scheduler_LowPriority = unstable_LowPriority,
2213 Scheduler_IdlePriority = unstable_IdlePriority;
2214
2215 {
2216 // Provide explicit error message when production+profiling bundle of e.g.
2217 // react-dom is used with production (non-profiling) bundle of
2218 // scheduler/tracing
2219 if (!(__interactionsRef != null && __interactionsRef.current != null)) {
2220 {
2221 throw Error( "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at http://fb.me/react-profiling" );
2222 }
2223 }
2224 }
2225
2226 var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use
2227 // ascending numbers so we can compare them like numbers. They start at 90 to
2228 // avoid clashing with Scheduler's priorities.
2229
2230 var ImmediatePriority = 99;
2231 var UserBlockingPriority = 98;
2232 var NormalPriority = 97;
2233 var LowPriority = 96;
2234 var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only.
2235
2236 var NoPriority = 90;
2237 var shouldYield = Scheduler_shouldYield;
2238 var requestPaint = // Fall back gracefully if we're running an older version of Scheduler.
2239 Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {};
2240 var syncQueue = null;
2241 var immediateQueueCallbackNode = null;
2242 var isFlushingSyncQueue = false;
2243 var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly.
2244 // This will be the case for modern browsers that support `performance.now`. In
2245 // older browsers, Scheduler falls back to `Date.now`, which returns a Unix
2246 // timestamp. In that case, subtract the module initialization time to simulate
2247 // the behavior of performance.now and keep our times small enough to fit
2248 // within 32 bits.
2249 // TODO: Consider lifting this into Scheduler.
2250
2251 var now = initialTimeMs < 10000 ? Scheduler_now : function () {
2252 return Scheduler_now() - initialTimeMs;
2253 };
2254 function getCurrentPriorityLevel() {
2255 switch (Scheduler_getCurrentPriorityLevel()) {
2256 case Scheduler_ImmediatePriority:
2257 return ImmediatePriority;
2258
2259 case Scheduler_UserBlockingPriority:
2260 return UserBlockingPriority;
2261
2262 case Scheduler_NormalPriority:
2263 return NormalPriority;
2264
2265 case Scheduler_LowPriority:
2266 return LowPriority;
2267
2268 case Scheduler_IdlePriority:
2269 return IdlePriority;
2270
2271 default:
2272 {
2273 {
2274 throw Error( "Unknown priority level." );
2275 }
2276 }
2277
2278 }
2279 }
2280
2281 function reactPriorityToSchedulerPriority(reactPriorityLevel) {
2282 switch (reactPriorityLevel) {
2283 case ImmediatePriority:
2284 return Scheduler_ImmediatePriority;
2285
2286 case UserBlockingPriority:
2287 return Scheduler_UserBlockingPriority;
2288
2289 case NormalPriority:
2290 return Scheduler_NormalPriority;
2291
2292 case LowPriority:
2293 return Scheduler_LowPriority;
2294
2295 case IdlePriority:
2296 return Scheduler_IdlePriority;
2297
2298 default:
2299 {
2300 {
2301 throw Error( "Unknown priority level." );
2302 }
2303 }
2304
2305 }
2306 }
2307
2308 function runWithPriority(reactPriorityLevel, fn) {
2309 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
2310 return Scheduler_runWithPriority(priorityLevel, fn);
2311 }
2312 function scheduleCallback(reactPriorityLevel, callback, options) {
2313 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
2314 return Scheduler_scheduleCallback(priorityLevel, callback, options);
2315 }
2316 function scheduleSyncCallback(callback) {
2317 // Push this callback into an internal queue. We'll flush these either in
2318 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
2319 if (syncQueue === null) {
2320 syncQueue = [callback]; // Flush the queue in the next tick, at the earliest.
2321
2322 immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl);
2323 } else {
2324 // Push onto existing queue. Don't need to schedule a callback because
2325 // we already scheduled one when we created the queue.
2326 syncQueue.push(callback);
2327 }
2328
2329 return fakeCallbackNode;
2330 }
2331 function cancelCallback(callbackNode) {
2332 if (callbackNode !== fakeCallbackNode) {
2333 Scheduler_cancelCallback(callbackNode);
2334 }
2335 }
2336 function flushSyncCallbackQueue() {
2337 if (immediateQueueCallbackNode !== null) {
2338 var node = immediateQueueCallbackNode;
2339 immediateQueueCallbackNode = null;
2340 Scheduler_cancelCallback(node);
2341 }
2342
2343 flushSyncCallbackQueueImpl();
2344 }
2345
2346 function flushSyncCallbackQueueImpl() {
2347 if (!isFlushingSyncQueue && syncQueue !== null) {
2348 // Prevent re-entrancy.
2349 isFlushingSyncQueue = true;
2350 var i = 0;
2351
2352 try {
2353 var _isSync = true;
2354 var queue = syncQueue;
2355 runWithPriority(ImmediatePriority, function () {
2356 for (; i < queue.length; i++) {
2357 var callback = queue[i];
2358
2359 do {
2360 callback = callback(_isSync);
2361 } while (callback !== null);
2362 }
2363 });
2364 syncQueue = null;
2365 } catch (error) {
2366 // If something throws, leave the remaining callbacks on the queue.
2367 if (syncQueue !== null) {
2368 syncQueue = syncQueue.slice(i + 1);
2369 } // Resume flushing in the next tick
2370
2371
2372 Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue);
2373 throw error;
2374 } finally {
2375 isFlushingSyncQueue = false;
2376 }
2377 }
2378 }
2379
2380 var NoMode = 0;
2381 var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root
2382 // tag instead
2383
2384 var BlockingMode = 2;
2385 var ConcurrentMode = 4;
2386 var ProfileMode = 8;
2387
2388 // Max 31 bit integer. The max integer size in V8 for 32-bit systems.
2389 // Math.pow(2, 30) - 1
2390 // 0b111111111111111111111111111111
2391 var MAX_SIGNED_31_BIT_INT = 1073741823;
2392
2393 var NoWork = 0; // TODO: Think of a better name for Never. The key difference with Idle is that
2394 // Never work can be committed in an inconsistent state without tearing the UI.
2395 // The main example is offscreen content, like a hidden subtree. So one possible
2396 // name is Offscreen. However, it also includes dehydrated Suspense boundaries,
2397 // which are inconsistent in the sense that they haven't finished yet, but
2398 // aren't visibly inconsistent because the server rendered HTML matches what the
2399 // hydrated tree would look like.
2400
2401 var Never = 1; // Idle is slightly higher priority than Never. It must completely finish in
2402 // order to be consistent.
2403
2404 var Idle = 2; // Continuous Hydration is slightly higher than Idle and is used to increase
2405 var Sync = MAX_SIGNED_31_BIT_INT;
2406 var Batched = Sync - 1;
2407 var UNIT_SIZE = 10;
2408 var MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms.
2409
2410 function msToExpirationTime(ms) {
2411 // Always subtract from the offset so that we don't clash with the magic number for NoWork.
2412 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
2413 }
2414 function expirationTimeToMs(expirationTime) {
2415 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
2416 }
2417
2418 function ceiling(num, precision) {
2419 return ((num / precision | 0) + 1) * precision;
2420 }
2421
2422 function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
2423 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
2424 } // TODO: This corresponds to Scheduler's NormalPriority, not LowPriority. Update
2425 // the names to reflect.
2426
2427
2428 var LOW_PRIORITY_EXPIRATION = 5000;
2429 var LOW_PRIORITY_BATCH_SIZE = 250;
2430 function computeAsyncExpiration(currentTime) {
2431 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
2432 }
2433 function computeSuspenseExpiration(currentTime, timeoutMs) {
2434 // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time?
2435 return computeExpirationBucket(currentTime, timeoutMs, LOW_PRIORITY_BATCH_SIZE);
2436 } // We intentionally set a higher expiration time for interactive updates in
2437 // dev than in production.
2438 //
2439 // If the main thread is being blocked so long that you hit the expiration,
2440 // it's a problem that could be solved with better scheduling.
2441 //
2442 // People will be more likely to notice this and fix it with the long
2443 // expiration time in development.
2444 //
2445 // In production we opt for better UX at the risk of masking scheduling
2446 // problems, by expiring fast.
2447
2448 var HIGH_PRIORITY_EXPIRATION = 500 ;
2449 var HIGH_PRIORITY_BATCH_SIZE = 100;
2450 function computeInteractiveExpiration(currentTime) {
2451 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
2452 }
2453 function inferPriorityFromExpirationTime(currentTime, expirationTime) {
2454 if (expirationTime === Sync) {
2455 return ImmediatePriority;
2456 }
2457
2458 if (expirationTime === Never || expirationTime === Idle) {
2459 return IdlePriority;
2460 }
2461
2462 var msUntil = expirationTimeToMs(expirationTime) - expirationTimeToMs(currentTime);
2463
2464 if (msUntil <= 0) {
2465 return ImmediatePriority;
2466 }
2467
2468 if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) {
2469 return UserBlockingPriority;
2470 }
2471
2472 if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) {
2473 return NormalPriority;
2474 } // TODO: Handle LowPriority
2475 // Assume anything lower has idle priority
2476
2477
2478 return IdlePriority;
2479 }
2480
2481 /**
2482 * inlined Object.is polyfill to avoid requiring consumers ship their own
2483 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
2484 */
2485 function is(x, y) {
2486 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
2487 ;
2488 }
2489
2490 var objectIs = typeof Object.is === 'function' ? Object.is : is;
2491
2492 var hasOwnProperty = Object.prototype.hasOwnProperty;
2493 /**
2494 * Performs equality by iterating through keys on an object and returning false
2495 * when any key has values which are not strictly equal between the arguments.
2496 * Returns true when the values of all keys are strictly equal.
2497 */
2498
2499 function shallowEqual(objA, objB) {
2500 if (objectIs(objA, objB)) {
2501 return true;
2502 }
2503
2504 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
2505 return false;
2506 }
2507
2508 var keysA = Object.keys(objA);
2509 var keysB = Object.keys(objB);
2510
2511 if (keysA.length !== keysB.length) {
2512 return false;
2513 } // Test for A's keys different from B.
2514
2515
2516 for (var i = 0; i < keysA.length; i++) {
2517 if (!hasOwnProperty.call(objB, keysA[i]) || !objectIs(objA[keysA[i]], objB[keysA[i]])) {
2518 return false;
2519 }
2520 }
2521
2522 return true;
2523 }
2524
2525 var ReactStrictModeWarnings = {
2526 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
2527 flushPendingUnsafeLifecycleWarnings: function () {},
2528 recordLegacyContextWarning: function (fiber, instance) {},
2529 flushLegacyContextWarning: function () {},
2530 discardPendingWarnings: function () {}
2531 };
2532
2533 {
2534 var findStrictRoot = function (fiber) {
2535 var maybeStrictRoot = null;
2536 var node = fiber;
2537
2538 while (node !== null) {
2539 if (node.mode & StrictMode) {
2540 maybeStrictRoot = node;
2541 }
2542
2543 node = node.return;
2544 }
2545
2546 return maybeStrictRoot;
2547 };
2548
2549 var setToSortedString = function (set) {
2550 var array = [];
2551 set.forEach(function (value) {
2552 array.push(value);
2553 });
2554 return array.sort().join(', ');
2555 };
2556
2557 var pendingComponentWillMountWarnings = [];
2558 var pendingUNSAFE_ComponentWillMountWarnings = [];
2559 var pendingComponentWillReceivePropsWarnings = [];
2560 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2561 var pendingComponentWillUpdateWarnings = [];
2562 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
2563
2564 var didWarnAboutUnsafeLifecycles = new Set();
2565
2566 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
2567 // Dedup strategy: Warn once per component.
2568 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
2569 return;
2570 }
2571
2572 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.
2573 instance.componentWillMount.__suppressDeprecationWarning !== true) {
2574 pendingComponentWillMountWarnings.push(fiber);
2575 }
2576
2577 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') {
2578 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
2579 }
2580
2581 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
2582 pendingComponentWillReceivePropsWarnings.push(fiber);
2583 }
2584
2585 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
2586 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
2587 }
2588
2589 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
2590 pendingComponentWillUpdateWarnings.push(fiber);
2591 }
2592
2593 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
2594 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
2595 }
2596 };
2597
2598 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
2599 // We do an initial pass to gather component names
2600 var componentWillMountUniqueNames = new Set();
2601
2602 if (pendingComponentWillMountWarnings.length > 0) {
2603 pendingComponentWillMountWarnings.forEach(function (fiber) {
2604 componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2605 didWarnAboutUnsafeLifecycles.add(fiber.type);
2606 });
2607 pendingComponentWillMountWarnings = [];
2608 }
2609
2610 var UNSAFE_componentWillMountUniqueNames = new Set();
2611
2612 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
2613 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
2614 UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2615 didWarnAboutUnsafeLifecycles.add(fiber.type);
2616 });
2617 pendingUNSAFE_ComponentWillMountWarnings = [];
2618 }
2619
2620 var componentWillReceivePropsUniqueNames = new Set();
2621
2622 if (pendingComponentWillReceivePropsWarnings.length > 0) {
2623 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
2624 componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2625 didWarnAboutUnsafeLifecycles.add(fiber.type);
2626 });
2627 pendingComponentWillReceivePropsWarnings = [];
2628 }
2629
2630 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
2631
2632 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
2633 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
2634 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2635 didWarnAboutUnsafeLifecycles.add(fiber.type);
2636 });
2637 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2638 }
2639
2640 var componentWillUpdateUniqueNames = new Set();
2641
2642 if (pendingComponentWillUpdateWarnings.length > 0) {
2643 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
2644 componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
2645 didWarnAboutUnsafeLifecycles.add(fiber.type);
2646 });
2647 pendingComponentWillUpdateWarnings = [];
2648 }
2649
2650 var UNSAFE_componentWillUpdateUniqueNames = new Set();
2651
2652 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
2653 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
2654 UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
2655 didWarnAboutUnsafeLifecycles.add(fiber.type);
2656 });
2657 pendingUNSAFE_ComponentWillUpdateWarnings = [];
2658 } // Finally, we flush all the warnings
2659 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
2660
2661
2662 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
2663 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
2664
2665 error('Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '\nPlease update the following components: %s', sortedNames);
2666 }
2667
2668 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
2669 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
2670
2671 error('Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, " + 'refactor your code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n' + '\nPlease update the following components: %s', _sortedNames);
2672 }
2673
2674 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
2675 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
2676
2677 error('Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '\nPlease update the following components: %s', _sortedNames2);
2678 }
2679
2680 if (componentWillMountUniqueNames.size > 0) {
2681 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
2682
2683 warn('componentWillMount has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames3);
2684 }
2685
2686 if (componentWillReceivePropsUniqueNames.size > 0) {
2687 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
2688
2689 warn('componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, refactor your " + 'code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n' + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames4);
2690 }
2691
2692 if (componentWillUpdateUniqueNames.size > 0) {
2693 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
2694
2695 warn('componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames5);
2696 }
2697 };
2698
2699 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
2700
2701 var didWarnAboutLegacyContext = new Set();
2702
2703 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
2704 var strictRoot = findStrictRoot(fiber);
2705
2706 if (strictRoot === null) {
2707 error('Expected to find a StrictMode component in a strict mode tree. ' + 'This error is likely caused by a bug in React. Please file an issue.');
2708
2709 return;
2710 } // Dedup strategy: Warn once per component.
2711
2712
2713 if (didWarnAboutLegacyContext.has(fiber.type)) {
2714 return;
2715 }
2716
2717 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
2718
2719 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
2720 if (warningsForRoot === undefined) {
2721 warningsForRoot = [];
2722 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
2723 }
2724
2725 warningsForRoot.push(fiber);
2726 }
2727 };
2728
2729 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
2730 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
2731 if (fiberArray.length === 0) {
2732 return;
2733 }
2734
2735 var firstFiber = fiberArray[0];
2736 var uniqueNames = new Set();
2737 fiberArray.forEach(function (fiber) {
2738 uniqueNames.add(getComponentName(fiber.type) || 'Component');
2739 didWarnAboutLegacyContext.add(fiber.type);
2740 });
2741 var sortedNames = setToSortedString(uniqueNames);
2742 var firstComponentStack = getStackByFiberInDevAndProd(firstFiber);
2743
2744 error('Legacy context API has been detected within a strict-mode tree.' + '\n\nThe old API will be supported in all 16.x releases, but applications ' + 'using it should migrate to the new version.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here: https://fb.me/react-legacy-context' + '%s', sortedNames, firstComponentStack);
2745 });
2746 };
2747
2748 ReactStrictModeWarnings.discardPendingWarnings = function () {
2749 pendingComponentWillMountWarnings = [];
2750 pendingUNSAFE_ComponentWillMountWarnings = [];
2751 pendingComponentWillReceivePropsWarnings = [];
2752 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2753 pendingComponentWillUpdateWarnings = [];
2754 pendingUNSAFE_ComponentWillUpdateWarnings = [];
2755 pendingLegacyContextWarning = new Map();
2756 };
2757 }
2758
2759 var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
2760
2761 var failedBoundaries = null;
2762 var setRefreshHandler = function (handler) {
2763 {
2764 resolveFamily = handler;
2765 }
2766 };
2767 function resolveFunctionForHotReloading(type) {
2768 {
2769 if (resolveFamily === null) {
2770 // Hot reloading is disabled.
2771 return type;
2772 }
2773
2774 var family = resolveFamily(type);
2775
2776 if (family === undefined) {
2777 return type;
2778 } // Use the latest known implementation.
2779
2780
2781 return family.current;
2782 }
2783 }
2784 function resolveClassForHotReloading(type) {
2785 // No implementation differences.
2786 return resolveFunctionForHotReloading(type);
2787 }
2788 function resolveForwardRefForHotReloading(type) {
2789 {
2790 if (resolveFamily === null) {
2791 // Hot reloading is disabled.
2792 return type;
2793 }
2794
2795 var family = resolveFamily(type);
2796
2797 if (family === undefined) {
2798 // Check if we're dealing with a real forwardRef. Don't want to crash early.
2799 if (type !== null && type !== undefined && typeof type.render === 'function') {
2800 // ForwardRef is special because its resolved .type is an object,
2801 // but it's possible that we only have its inner render function in the map.
2802 // If that inner render function is different, we'll build a new forwardRef type.
2803 var currentRender = resolveFunctionForHotReloading(type.render);
2804
2805 if (type.render !== currentRender) {
2806 var syntheticType = {
2807 $$typeof: REACT_FORWARD_REF_TYPE,
2808 render: currentRender
2809 };
2810
2811 if (type.displayName !== undefined) {
2812 syntheticType.displayName = type.displayName;
2813 }
2814
2815 return syntheticType;
2816 }
2817 }
2818
2819 return type;
2820 } // Use the latest known implementation.
2821
2822
2823 return family.current;
2824 }
2825 }
2826 function isCompatibleFamilyForHotReloading(fiber, element) {
2827 {
2828 if (resolveFamily === null) {
2829 // Hot reloading is disabled.
2830 return false;
2831 }
2832
2833 var prevType = fiber.elementType;
2834 var nextType = element.type; // If we got here, we know types aren't === equal.
2835
2836 var needsCompareFamilies = false;
2837 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
2838
2839 switch (fiber.tag) {
2840 case ClassComponent:
2841 {
2842 if (typeof nextType === 'function') {
2843 needsCompareFamilies = true;
2844 }
2845
2846 break;
2847 }
2848
2849 case FunctionComponent:
2850 {
2851 if (typeof nextType === 'function') {
2852 needsCompareFamilies = true;
2853 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2854 // We don't know the inner type yet.
2855 // We're going to assume that the lazy inner type is stable,
2856 // and so it is sufficient to avoid reconciling it away.
2857 // We're not going to unwrap or actually use the new lazy type.
2858 needsCompareFamilies = true;
2859 }
2860
2861 break;
2862 }
2863
2864 case ForwardRef:
2865 {
2866 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
2867 needsCompareFamilies = true;
2868 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2869 needsCompareFamilies = true;
2870 }
2871
2872 break;
2873 }
2874
2875 case MemoComponent:
2876 case SimpleMemoComponent:
2877 {
2878 if ($$typeofNextType === REACT_MEMO_TYPE) {
2879 // TODO: if it was but can no longer be simple,
2880 // we shouldn't set this.
2881 needsCompareFamilies = true;
2882 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
2883 needsCompareFamilies = true;
2884 }
2885
2886 break;
2887 }
2888
2889 default:
2890 return false;
2891 } // Check if both types have a family and it's the same one.
2892
2893
2894 if (needsCompareFamilies) {
2895 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
2896 // This means both of them need to be registered to preserve state.
2897 // If we unwrapped and compared the inner types for wrappers instead,
2898 // then we would risk falsely saying two separate memo(Foo)
2899 // calls are equivalent because they wrap the same Foo function.
2900 var prevFamily = resolveFamily(prevType);
2901
2902 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
2903 return true;
2904 }
2905 }
2906
2907 return false;
2908 }
2909 }
2910 function markFailedErrorBoundaryForHotReloading(fiber) {
2911 {
2912 if (resolveFamily === null) {
2913 // Hot reloading is disabled.
2914 return;
2915 }
2916
2917 if (typeof WeakSet !== 'function') {
2918 return;
2919 }
2920
2921 if (failedBoundaries === null) {
2922 failedBoundaries = new WeakSet();
2923 }
2924
2925 failedBoundaries.add(fiber);
2926 }
2927 }
2928 var scheduleRefresh = function (root, update) {
2929 {
2930 if (resolveFamily === null) {
2931 // Hot reloading is disabled.
2932 return;
2933 }
2934
2935 var staleFamilies = update.staleFamilies,
2936 updatedFamilies = update.updatedFamilies;
2937 flushPassiveEffects();
2938 flushSync(function () {
2939 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
2940 });
2941 }
2942 };
2943 var scheduleRoot = function (root, element) {
2944 {
2945 if (root.context !== emptyContextObject) {
2946 // Super edge case: root has a legacy _renderSubtree context
2947 // but we don't know the parentComponent so we can't pass it.
2948 // Just ignore. We'll delete this with _renderSubtree code path later.
2949 return;
2950 }
2951
2952 flushPassiveEffects();
2953 syncUpdates(function () {
2954 updateContainer(element, root, null, null);
2955 });
2956 }
2957 };
2958
2959 function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
2960 {
2961 var alternate = fiber.alternate,
2962 child = fiber.child,
2963 sibling = fiber.sibling,
2964 tag = fiber.tag,
2965 type = fiber.type;
2966 var candidateType = null;
2967
2968 switch (tag) {
2969 case FunctionComponent:
2970 case SimpleMemoComponent:
2971 case ClassComponent:
2972 candidateType = type;
2973 break;
2974
2975 case ForwardRef:
2976 candidateType = type.render;
2977 break;
2978 }
2979
2980 if (resolveFamily === null) {
2981 throw new Error('Expected resolveFamily to be set during hot reload.');
2982 }
2983
2984 var needsRender = false;
2985 var needsRemount = false;
2986
2987 if (candidateType !== null) {
2988 var family = resolveFamily(candidateType);
2989
2990 if (family !== undefined) {
2991 if (staleFamilies.has(family)) {
2992 needsRemount = true;
2993 } else if (updatedFamilies.has(family)) {
2994 if (tag === ClassComponent) {
2995 needsRemount = true;
2996 } else {
2997 needsRender = true;
2998 }
2999 }
3000 }
3001 }
3002
3003 if (failedBoundaries !== null) {
3004 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
3005 needsRemount = true;
3006 }
3007 }
3008
3009 if (needsRemount) {
3010 fiber._debugNeedsRemount = true;
3011 }
3012
3013 if (needsRemount || needsRender) {
3014 scheduleWork(fiber, Sync);
3015 }
3016
3017 if (child !== null && !needsRemount) {
3018 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
3019 }
3020
3021 if (sibling !== null) {
3022 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
3023 }
3024 }
3025 }
3026
3027 var findHostInstancesForRefresh = function (root, families) {
3028 {
3029 var hostInstances = new Set();
3030 var types = new Set(families.map(function (family) {
3031 return family.current;
3032 }));
3033 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
3034 return hostInstances;
3035 }
3036 };
3037
3038 function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
3039 {
3040 var child = fiber.child,
3041 sibling = fiber.sibling,
3042 tag = fiber.tag,
3043 type = fiber.type;
3044 var candidateType = null;
3045
3046 switch (tag) {
3047 case FunctionComponent:
3048 case SimpleMemoComponent:
3049 case ClassComponent:
3050 candidateType = type;
3051 break;
3052
3053 case ForwardRef:
3054 candidateType = type.render;
3055 break;
3056 }
3057
3058 var didMatch = false;
3059
3060 if (candidateType !== null) {
3061 if (types.has(candidateType)) {
3062 didMatch = true;
3063 }
3064 }
3065
3066 if (didMatch) {
3067 // We have a match. This only drills down to the closest host components.
3068 // There's no need to search deeper because for the purpose of giving
3069 // visual feedback, "flashing" outermost parent rectangles is sufficient.
3070 findHostInstancesForFiberShallowly(fiber, hostInstances);
3071 } else {
3072 // If there's no match, maybe there will be one further down in the child tree.
3073 if (child !== null) {
3074 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
3075 }
3076 }
3077
3078 if (sibling !== null) {
3079 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
3080 }
3081 }
3082 }
3083
3084 function findHostInstancesForFiberShallowly(fiber, hostInstances) {
3085 {
3086 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
3087
3088 if (foundHostInstances) {
3089 return;
3090 } // If we didn't find any host children, fallback to closest host parent.
3091
3092
3093 var node = fiber;
3094
3095 while (true) {
3096 switch (node.tag) {
3097 case HostComponent:
3098 hostInstances.add(node.stateNode);
3099 return;
3100
3101 case HostPortal:
3102 hostInstances.add(node.stateNode.containerInfo);
3103 return;
3104
3105 case HostRoot:
3106 hostInstances.add(node.stateNode.containerInfo);
3107 return;
3108 }
3109
3110 if (node.return === null) {
3111 throw new Error('Expected to reach root first.');
3112 }
3113
3114 node = node.return;
3115 }
3116 }
3117 }
3118
3119 function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
3120 {
3121 var node = fiber;
3122 var foundHostInstances = false;
3123
3124 while (true) {
3125 if (node.tag === HostComponent) {
3126 // We got a match.
3127 foundHostInstances = true;
3128 hostInstances.add(node.stateNode); // There may still be more, so keep searching.
3129 } else if (node.child !== null) {
3130 node.child.return = node;
3131 node = node.child;
3132 continue;
3133 }
3134
3135 if (node === fiber) {
3136 return foundHostInstances;
3137 }
3138
3139 while (node.sibling === null) {
3140 if (node.return === null || node.return === fiber) {
3141 return foundHostInstances;
3142 }
3143
3144 node = node.return;
3145 }
3146
3147 node.sibling.return = node.return;
3148 node = node.sibling;
3149 }
3150 }
3151
3152 return false;
3153 }
3154
3155 function resolveDefaultProps(Component, baseProps) {
3156 if (Component && Component.defaultProps) {
3157 // Resolve default props. Taken from ReactElement
3158 var props = _assign({}, baseProps);
3159
3160 var defaultProps = Component.defaultProps;
3161
3162 for (var propName in defaultProps) {
3163 if (props[propName] === undefined) {
3164 props[propName] = defaultProps[propName];
3165 }
3166 }
3167
3168 return props;
3169 }
3170
3171 return baseProps;
3172 }
3173 function readLazyComponentType(lazyComponent) {
3174 initializeLazyComponentType(lazyComponent);
3175
3176 if (lazyComponent._status !== Resolved) {
3177 throw lazyComponent._result;
3178 }
3179
3180 return lazyComponent._result;
3181 }
3182
3183 var valueCursor = createCursor(null);
3184 var rendererSigil;
3185
3186 {
3187 // Use this to detect multiple renderers using the same context
3188 rendererSigil = {};
3189 }
3190
3191 var currentlyRenderingFiber = null;
3192 var lastContextDependency = null;
3193 var lastContextWithAllBitsObserved = null;
3194 var isDisallowedContextReadInDEV = false;
3195 function resetContextDependencies() {
3196 // This is called right before React yields execution, to ensure `readContext`
3197 // cannot be called outside the render phase.
3198 currentlyRenderingFiber = null;
3199 lastContextDependency = null;
3200 lastContextWithAllBitsObserved = null;
3201
3202 {
3203 isDisallowedContextReadInDEV = false;
3204 }
3205 }
3206 function enterDisallowedContextReadInDEV() {
3207 {
3208 isDisallowedContextReadInDEV = true;
3209 }
3210 }
3211 function exitDisallowedContextReadInDEV() {
3212 {
3213 isDisallowedContextReadInDEV = false;
3214 }
3215 }
3216 function pushProvider(providerFiber, nextValue) {
3217 var context = providerFiber.type._context;
3218
3219 {
3220 push(valueCursor, context._currentValue2, providerFiber);
3221 context._currentValue2 = nextValue;
3222
3223 {
3224 if (context._currentRenderer2 !== undefined && context._currentRenderer2 !== null && context._currentRenderer2 !== rendererSigil) {
3225 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.');
3226 }
3227
3228 context._currentRenderer2 = rendererSigil;
3229 }
3230 }
3231 }
3232 function popProvider(providerFiber) {
3233 var currentValue = valueCursor.current;
3234 pop(valueCursor, providerFiber);
3235 var context = providerFiber.type._context;
3236
3237 {
3238 context._currentValue2 = currentValue;
3239 }
3240 }
3241 function calculateChangedBits(context, newValue, oldValue) {
3242 if (objectIs(oldValue, newValue)) {
3243 // No change
3244 return 0;
3245 } else {
3246 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
3247
3248 {
3249 if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) {
3250 error('calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits);
3251 }
3252 }
3253
3254 return changedBits | 0;
3255 }
3256 }
3257 function scheduleWorkOnParentPath(parent, renderExpirationTime) {
3258 // Update the child expiration time of all the ancestors, including
3259 // the alternates.
3260 var node = parent;
3261
3262 while (node !== null) {
3263 var alternate = node.alternate;
3264
3265 if (node.childExpirationTime < renderExpirationTime) {
3266 node.childExpirationTime = renderExpirationTime;
3267
3268 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
3269 alternate.childExpirationTime = renderExpirationTime;
3270 }
3271 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
3272 alternate.childExpirationTime = renderExpirationTime;
3273 } else {
3274 // Neither alternate was updated, which means the rest of the
3275 // ancestor path already has sufficient priority.
3276 break;
3277 }
3278
3279 node = node.return;
3280 }
3281 }
3282 function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
3283 var fiber = workInProgress.child;
3284
3285 if (fiber !== null) {
3286 // Set the return pointer of the child to the work-in-progress fiber.
3287 fiber.return = workInProgress;
3288 }
3289
3290 while (fiber !== null) {
3291 var nextFiber = void 0; // Visit this fiber.
3292
3293 var list = fiber.dependencies;
3294
3295 if (list !== null) {
3296 nextFiber = fiber.child;
3297 var dependency = list.firstContext;
3298
3299 while (dependency !== null) {
3300 // Check if the context matches.
3301 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
3302 // Match! Schedule an update on this fiber.
3303 if (fiber.tag === ClassComponent) {
3304 // Schedule a force update on the work-in-progress.
3305 var update = createUpdate(renderExpirationTime, null);
3306 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
3307 // update to the current fiber, too, which means it will persist even if
3308 // this render is thrown away. Since it's a race condition, not sure it's
3309 // worth fixing.
3310
3311 enqueueUpdate(fiber, update);
3312 }
3313
3314 if (fiber.expirationTime < renderExpirationTime) {
3315 fiber.expirationTime = renderExpirationTime;
3316 }
3317
3318 var alternate = fiber.alternate;
3319
3320 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
3321 alternate.expirationTime = renderExpirationTime;
3322 }
3323
3324 scheduleWorkOnParentPath(fiber.return, renderExpirationTime); // Mark the expiration time on the list, too.
3325
3326 if (list.expirationTime < renderExpirationTime) {
3327 list.expirationTime = renderExpirationTime;
3328 } // Since we already found a match, we can stop traversing the
3329 // dependency list.
3330
3331
3332 break;
3333 }
3334
3335 dependency = dependency.next;
3336 }
3337 } else if (fiber.tag === ContextProvider) {
3338 // Don't scan deeper if this is a matching provider
3339 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
3340 } else {
3341 // Traverse down.
3342 nextFiber = fiber.child;
3343 }
3344
3345 if (nextFiber !== null) {
3346 // Set the return pointer of the child to the work-in-progress fiber.
3347 nextFiber.return = fiber;
3348 } else {
3349 // No child. Traverse to next sibling.
3350 nextFiber = fiber;
3351
3352 while (nextFiber !== null) {
3353 if (nextFiber === workInProgress) {
3354 // We're back to the root of this subtree. Exit.
3355 nextFiber = null;
3356 break;
3357 }
3358
3359 var sibling = nextFiber.sibling;
3360
3361 if (sibling !== null) {
3362 // Set the return pointer of the sibling to the work-in-progress fiber.
3363 sibling.return = nextFiber.return;
3364 nextFiber = sibling;
3365 break;
3366 } // No more siblings. Traverse up.
3367
3368
3369 nextFiber = nextFiber.return;
3370 }
3371 }
3372
3373 fiber = nextFiber;
3374 }
3375 }
3376 function prepareToReadContext(workInProgress, renderExpirationTime) {
3377 currentlyRenderingFiber = workInProgress;
3378 lastContextDependency = null;
3379 lastContextWithAllBitsObserved = null;
3380 var dependencies = workInProgress.dependencies;
3381
3382 if (dependencies !== null) {
3383 var firstContext = dependencies.firstContext;
3384
3385 if (firstContext !== null) {
3386 if (dependencies.expirationTime >= renderExpirationTime) {
3387 // Context list has a pending update. Mark that this fiber performed work.
3388 markWorkInProgressReceivedUpdate();
3389 } // Reset the work-in-progress list
3390
3391
3392 dependencies.firstContext = null;
3393 }
3394 }
3395 }
3396 function readContext(context, observedBits) {
3397 {
3398 // This warning would fire if you read context inside a Hook like useMemo.
3399 // Unlike the class check below, it's not enforced in production for perf.
3400 if (isDisallowedContextReadInDEV) {
3401 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().');
3402 }
3403 }
3404
3405 if (lastContextWithAllBitsObserved === context) ; else if (observedBits === false || observedBits === 0) ; else {
3406 var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types.
3407
3408 if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) {
3409 // Observe all updates.
3410 lastContextWithAllBitsObserved = context;
3411 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
3412 } else {
3413 resolvedObservedBits = observedBits;
3414 }
3415
3416 var contextItem = {
3417 context: context,
3418 observedBits: resolvedObservedBits,
3419 next: null
3420 };
3421
3422 if (lastContextDependency === null) {
3423 if (!(currentlyRenderingFiber !== null)) {
3424 {
3425 throw Error( "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." );
3426 }
3427 } // This is the first dependency for this component. Create a new list.
3428
3429
3430 lastContextDependency = contextItem;
3431 currentlyRenderingFiber.dependencies = {
3432 expirationTime: NoWork,
3433 firstContext: contextItem,
3434 responders: null
3435 };
3436 } else {
3437 // Append a new context item.
3438 lastContextDependency = lastContextDependency.next = contextItem;
3439 }
3440 }
3441
3442 return context._currentValue2;
3443 }
3444
3445 var UpdateState = 0;
3446 var ReplaceState = 1;
3447 var ForceUpdate = 2;
3448 var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
3449 // It should only be read right after calling `processUpdateQueue`, via
3450 // `checkHasForceUpdateAfterProcessing`.
3451
3452 var hasForceUpdate = false;
3453 var didWarnUpdateInsideUpdate;
3454 var currentlyProcessingQueue;
3455
3456 {
3457 didWarnUpdateInsideUpdate = false;
3458 currentlyProcessingQueue = null;
3459 }
3460
3461 function initializeUpdateQueue(fiber) {
3462 var queue = {
3463 baseState: fiber.memoizedState,
3464 baseQueue: null,
3465 shared: {
3466 pending: null
3467 },
3468 effects: null
3469 };
3470 fiber.updateQueue = queue;
3471 }
3472 function cloneUpdateQueue(current, workInProgress) {
3473 // Clone the update queue from current. Unless it's already a clone.
3474 var queue = workInProgress.updateQueue;
3475 var currentQueue = current.updateQueue;
3476
3477 if (queue === currentQueue) {
3478 var clone = {
3479 baseState: currentQueue.baseState,
3480 baseQueue: currentQueue.baseQueue,
3481 shared: currentQueue.shared,
3482 effects: currentQueue.effects
3483 };
3484 workInProgress.updateQueue = clone;
3485 }
3486 }
3487 function createUpdate(expirationTime, suspenseConfig) {
3488 var update = {
3489 expirationTime: expirationTime,
3490 suspenseConfig: suspenseConfig,
3491 tag: UpdateState,
3492 payload: null,
3493 callback: null,
3494 next: null
3495 };
3496 update.next = update;
3497
3498 {
3499 update.priority = getCurrentPriorityLevel();
3500 }
3501
3502 return update;
3503 }
3504 function enqueueUpdate(fiber, update) {
3505 var updateQueue = fiber.updateQueue;
3506
3507 if (updateQueue === null) {
3508 // Only occurs if the fiber has been unmounted.
3509 return;
3510 }
3511
3512 var sharedQueue = updateQueue.shared;
3513 var pending = sharedQueue.pending;
3514
3515 if (pending === null) {
3516 // This is the first update. Create a circular list.
3517 update.next = update;
3518 } else {
3519 update.next = pending.next;
3520 pending.next = update;
3521 }
3522
3523 sharedQueue.pending = update;
3524
3525 {
3526 if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) {
3527 error('An update (setState, replaceState, or forceUpdate) was scheduled ' + 'from inside an update function. Update functions should be pure, ' + 'with zero side-effects. Consider using componentDidUpdate or a ' + 'callback.');
3528
3529 didWarnUpdateInsideUpdate = true;
3530 }
3531 }
3532 }
3533 function enqueueCapturedUpdate(workInProgress, update) {
3534 var current = workInProgress.alternate;
3535
3536 if (current !== null) {
3537 // Ensure the work-in-progress queue is a clone
3538 cloneUpdateQueue(current, workInProgress);
3539 } // Captured updates go only on the work-in-progress queue.
3540
3541
3542 var queue = workInProgress.updateQueue; // Append the update to the end of the list.
3543
3544 var last = queue.baseQueue;
3545
3546 if (last === null) {
3547 queue.baseQueue = update.next = update;
3548 update.next = update;
3549 } else {
3550 update.next = last.next;
3551 last.next = update;
3552 }
3553 }
3554
3555 function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
3556 switch (update.tag) {
3557 case ReplaceState:
3558 {
3559 var payload = update.payload;
3560
3561 if (typeof payload === 'function') {
3562 // Updater function
3563 {
3564 enterDisallowedContextReadInDEV();
3565
3566 if ( workInProgress.mode & StrictMode) {
3567 payload.call(instance, prevState, nextProps);
3568 }
3569 }
3570
3571 var nextState = payload.call(instance, prevState, nextProps);
3572
3573 {
3574 exitDisallowedContextReadInDEV();
3575 }
3576
3577 return nextState;
3578 } // State object
3579
3580
3581 return payload;
3582 }
3583
3584 case CaptureUpdate:
3585 {
3586 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
3587 }
3588 // Intentional fallthrough
3589
3590 case UpdateState:
3591 {
3592 var _payload = update.payload;
3593 var partialState;
3594
3595 if (typeof _payload === 'function') {
3596 // Updater function
3597 {
3598 enterDisallowedContextReadInDEV();
3599
3600 if ( workInProgress.mode & StrictMode) {
3601 _payload.call(instance, prevState, nextProps);
3602 }
3603 }
3604
3605 partialState = _payload.call(instance, prevState, nextProps);
3606
3607 {
3608 exitDisallowedContextReadInDEV();
3609 }
3610 } else {
3611 // Partial state object
3612 partialState = _payload;
3613 }
3614
3615 if (partialState === null || partialState === undefined) {
3616 // Null and undefined are treated as no-ops.
3617 return prevState;
3618 } // Merge the partial state and the previous state.
3619
3620
3621 return _assign({}, prevState, partialState);
3622 }
3623
3624 case ForceUpdate:
3625 {
3626 hasForceUpdate = true;
3627 return prevState;
3628 }
3629 }
3630
3631 return prevState;
3632 }
3633
3634 function processUpdateQueue(workInProgress, props, instance, renderExpirationTime) {
3635 // This is always non-null on a ClassComponent or HostRoot
3636 var queue = workInProgress.updateQueue;
3637 hasForceUpdate = false;
3638
3639 {
3640 currentlyProcessingQueue = queue.shared;
3641 } // The last rebase update that is NOT part of the base state.
3642
3643
3644 var baseQueue = queue.baseQueue; // The last pending update that hasn't been processed yet.
3645
3646 var pendingQueue = queue.shared.pending;
3647
3648 if (pendingQueue !== null) {
3649 // We have new updates that haven't been processed yet.
3650 // We'll add them to the base queue.
3651 if (baseQueue !== null) {
3652 // Merge the pending queue and the base queue.
3653 var baseFirst = baseQueue.next;
3654 var pendingFirst = pendingQueue.next;
3655 baseQueue.next = pendingFirst;
3656 pendingQueue.next = baseFirst;
3657 }
3658
3659 baseQueue = pendingQueue;
3660 queue.shared.pending = null; // TODO: Pass `current` as argument
3661
3662 var current = workInProgress.alternate;
3663
3664 if (current !== null) {
3665 var currentQueue = current.updateQueue;
3666
3667 if (currentQueue !== null) {
3668 currentQueue.baseQueue = pendingQueue;
3669 }
3670 }
3671 } // These values may change as we process the queue.
3672
3673
3674 if (baseQueue !== null) {
3675 var first = baseQueue.next; // Iterate through the list of updates to compute the result.
3676
3677 var newState = queue.baseState;
3678 var newExpirationTime = NoWork;
3679 var newBaseState = null;
3680 var newBaseQueueFirst = null;
3681 var newBaseQueueLast = null;
3682
3683 if (first !== null) {
3684 var update = first;
3685
3686 do {
3687 var updateExpirationTime = update.expirationTime;
3688
3689 if (updateExpirationTime < renderExpirationTime) {
3690 // Priority is insufficient. Skip this update. If this is the first
3691 // skipped update, the previous update/state is the new base
3692 // update/state.
3693 var clone = {
3694 expirationTime: update.expirationTime,
3695 suspenseConfig: update.suspenseConfig,
3696 tag: update.tag,
3697 payload: update.payload,
3698 callback: update.callback,
3699 next: null
3700 };
3701
3702 if (newBaseQueueLast === null) {
3703 newBaseQueueFirst = newBaseQueueLast = clone;
3704 newBaseState = newState;
3705 } else {
3706 newBaseQueueLast = newBaseQueueLast.next = clone;
3707 } // Update the remaining priority in the queue.
3708
3709
3710 if (updateExpirationTime > newExpirationTime) {
3711 newExpirationTime = updateExpirationTime;
3712 }
3713 } else {
3714 // This update does have sufficient priority.
3715 if (newBaseQueueLast !== null) {
3716 var _clone = {
3717 expirationTime: Sync,
3718 // This update is going to be committed so we never want uncommit it.
3719 suspenseConfig: update.suspenseConfig,
3720 tag: update.tag,
3721 payload: update.payload,
3722 callback: update.callback,
3723 next: null
3724 };
3725 newBaseQueueLast = newBaseQueueLast.next = _clone;
3726 } // Mark the event time of this update as relevant to this render pass.
3727 // TODO: This should ideally use the true event time of this update rather than
3728 // its priority which is a derived and not reverseable value.
3729 // TODO: We should skip this update if it was already committed but currently
3730 // we have no way of detecting the difference between a committed and suspended
3731 // update here.
3732
3733
3734 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process this update.
3735
3736 newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance);
3737 var callback = update.callback;
3738
3739 if (callback !== null) {
3740 workInProgress.effectTag |= Callback;
3741 var effects = queue.effects;
3742
3743 if (effects === null) {
3744 queue.effects = [update];
3745 } else {
3746 effects.push(update);
3747 }
3748 }
3749 }
3750
3751 update = update.next;
3752
3753 if (update === null || update === first) {
3754 pendingQueue = queue.shared.pending;
3755
3756 if (pendingQueue === null) {
3757 break;
3758 } else {
3759 // An update was scheduled from inside a reducer. Add the new
3760 // pending updates to the end of the list and keep processing.
3761 update = baseQueue.next = pendingQueue.next;
3762 pendingQueue.next = first;
3763 queue.baseQueue = baseQueue = pendingQueue;
3764 queue.shared.pending = null;
3765 }
3766 }
3767 } while (true);
3768 }
3769
3770 if (newBaseQueueLast === null) {
3771 newBaseState = newState;
3772 } else {
3773 newBaseQueueLast.next = newBaseQueueFirst;
3774 }
3775
3776 queue.baseState = newBaseState;
3777 queue.baseQueue = newBaseQueueLast; // Set the remaining expiration time to be whatever is remaining in the queue.
3778 // This should be fine because the only two other things that contribute to
3779 // expiration time are props and context. We're already in the middle of the
3780 // begin phase by the time we start processing the queue, so we've already
3781 // dealt with the props. Context in components that specify
3782 // shouldComponentUpdate is tricky; but we'll have to account for
3783 // that regardless.
3784
3785 markUnprocessedUpdateTime(newExpirationTime);
3786 workInProgress.expirationTime = newExpirationTime;
3787 workInProgress.memoizedState = newState;
3788 }
3789
3790 {
3791 currentlyProcessingQueue = null;
3792 }
3793 }
3794
3795 function callCallback(callback, context) {
3796 if (!(typeof callback === 'function')) {
3797 {
3798 throw Error( "Invalid argument passed as callback. Expected a function. Instead received: " + callback );
3799 }
3800 }
3801
3802 callback.call(context);
3803 }
3804
3805 function resetHasForceUpdateBeforeProcessing() {
3806 hasForceUpdate = false;
3807 }
3808 function checkHasForceUpdateAfterProcessing() {
3809 return hasForceUpdate;
3810 }
3811 function commitUpdateQueue(finishedWork, finishedQueue, instance) {
3812 // Commit the effects
3813 var effects = finishedQueue.effects;
3814 finishedQueue.effects = null;
3815
3816 if (effects !== null) {
3817 for (var i = 0; i < effects.length; i++) {
3818 var effect = effects[i];
3819 var callback = effect.callback;
3820
3821 if (callback !== null) {
3822 effect.callback = null;
3823 callCallback(callback, instance);
3824 }
3825 }
3826 }
3827 }
3828
3829 var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
3830 function requestCurrentSuspenseConfig() {
3831 return ReactCurrentBatchConfig.suspense;
3832 }
3833
3834 var fakeInternalInstance = {};
3835 var isArray = Array.isArray; // React.Component uses a shared frozen object by default.
3836 // We'll use it to determine whether we need to initialize legacy refs.
3837
3838 var emptyRefsObject = new React.Component().refs;
3839 var didWarnAboutStateAssignmentForComponent;
3840 var didWarnAboutUninitializedState;
3841 var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
3842 var didWarnAboutLegacyLifecyclesAndDerivedState;
3843 var didWarnAboutUndefinedDerivedState;
3844 var warnOnUndefinedDerivedState;
3845 var warnOnInvalidCallback;
3846 var didWarnAboutDirectlyAssigningPropsToState;
3847 var didWarnAboutContextTypeAndContextTypes;
3848 var didWarnAboutInvalidateContextType;
3849
3850 {
3851 didWarnAboutStateAssignmentForComponent = new Set();
3852 didWarnAboutUninitializedState = new Set();
3853 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
3854 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
3855 didWarnAboutDirectlyAssigningPropsToState = new Set();
3856 didWarnAboutUndefinedDerivedState = new Set();
3857 didWarnAboutContextTypeAndContextTypes = new Set();
3858 didWarnAboutInvalidateContextType = new Set();
3859 var didWarnOnInvalidCallback = new Set();
3860
3861 warnOnInvalidCallback = function (callback, callerName) {
3862 if (callback === null || typeof callback === 'function') {
3863 return;
3864 }
3865
3866 var key = callerName + "_" + callback;
3867
3868 if (!didWarnOnInvalidCallback.has(key)) {
3869 didWarnOnInvalidCallback.add(key);
3870
3871 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
3872 }
3873 };
3874
3875 warnOnUndefinedDerivedState = function (type, partialState) {
3876 if (partialState === undefined) {
3877 var componentName = getComponentName(type) || 'Component';
3878
3879 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
3880 didWarnAboutUndefinedDerivedState.add(componentName);
3881
3882 error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
3883 }
3884 }
3885 }; // This is so gross but it's at least non-critical and can be removed if
3886 // it causes problems. This is meant to give a nicer error message for
3887 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
3888 // ...)) which otherwise throws a "_processChildContext is not a function"
3889 // exception.
3890
3891
3892 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
3893 enumerable: false,
3894 value: function () {
3895 {
3896 {
3897 throw Error( "_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal)." );
3898 }
3899 }
3900 }
3901 });
3902 Object.freeze(fakeInternalInstance);
3903 }
3904
3905 function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
3906 var prevState = workInProgress.memoizedState;
3907
3908 {
3909 if ( workInProgress.mode & StrictMode) {
3910 // Invoke the function an extra time to help detect side-effects.
3911 getDerivedStateFromProps(nextProps, prevState);
3912 }
3913 }
3914
3915 var partialState = getDerivedStateFromProps(nextProps, prevState);
3916
3917 {
3918 warnOnUndefinedDerivedState(ctor, partialState);
3919 } // Merge the partial state and the previous state.
3920
3921
3922 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
3923 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
3924 // base state.
3925
3926 if (workInProgress.expirationTime === NoWork) {
3927 // Queue is always non-null for classes
3928 var updateQueue = workInProgress.updateQueue;
3929 updateQueue.baseState = memoizedState;
3930 }
3931 }
3932 var classComponentUpdater = {
3933 isMounted: isMounted,
3934 enqueueSetState: function (inst, payload, callback) {
3935 var fiber = get(inst);
3936 var currentTime = requestCurrentTimeForUpdate();
3937 var suspenseConfig = requestCurrentSuspenseConfig();
3938 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3939 var update = createUpdate(expirationTime, suspenseConfig);
3940 update.payload = payload;
3941
3942 if (callback !== undefined && callback !== null) {
3943 {
3944 warnOnInvalidCallback(callback, 'setState');
3945 }
3946
3947 update.callback = callback;
3948 }
3949
3950 enqueueUpdate(fiber, update);
3951 scheduleWork(fiber, expirationTime);
3952 },
3953 enqueueReplaceState: function (inst, payload, callback) {
3954 var fiber = get(inst);
3955 var currentTime = requestCurrentTimeForUpdate();
3956 var suspenseConfig = requestCurrentSuspenseConfig();
3957 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3958 var update = createUpdate(expirationTime, suspenseConfig);
3959 update.tag = ReplaceState;
3960 update.payload = payload;
3961
3962 if (callback !== undefined && callback !== null) {
3963 {
3964 warnOnInvalidCallback(callback, 'replaceState');
3965 }
3966
3967 update.callback = callback;
3968 }
3969
3970 enqueueUpdate(fiber, update);
3971 scheduleWork(fiber, expirationTime);
3972 },
3973 enqueueForceUpdate: function (inst, callback) {
3974 var fiber = get(inst);
3975 var currentTime = requestCurrentTimeForUpdate();
3976 var suspenseConfig = requestCurrentSuspenseConfig();
3977 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
3978 var update = createUpdate(expirationTime, suspenseConfig);
3979 update.tag = ForceUpdate;
3980
3981 if (callback !== undefined && callback !== null) {
3982 {
3983 warnOnInvalidCallback(callback, 'forceUpdate');
3984 }
3985
3986 update.callback = callback;
3987 }
3988
3989 enqueueUpdate(fiber, update);
3990 scheduleWork(fiber, expirationTime);
3991 }
3992 };
3993
3994 function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
3995 var instance = workInProgress.stateNode;
3996
3997 if (typeof instance.shouldComponentUpdate === 'function') {
3998 {
3999 if ( workInProgress.mode & StrictMode) {
4000 // Invoke the function an extra time to help detect side-effects.
4001 instance.shouldComponentUpdate(newProps, newState, nextContext);
4002 }
4003 }
4004
4005 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
4006 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
4007 stopPhaseTimer();
4008
4009 {
4010 if (shouldUpdate === undefined) {
4011 error('%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component');
4012 }
4013 }
4014
4015 return shouldUpdate;
4016 }
4017
4018 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
4019 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
4020 }
4021
4022 return true;
4023 }
4024
4025 function checkClassInstance(workInProgress, ctor, newProps) {
4026 var instance = workInProgress.stateNode;
4027
4028 {
4029 var name = getComponentName(ctor) || 'Component';
4030 var renderPresent = instance.render;
4031
4032 if (!renderPresent) {
4033 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
4034 error('%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
4035 } else {
4036 error('%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
4037 }
4038 }
4039
4040 if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) {
4041 error('getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', name);
4042 }
4043
4044 if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) {
4045 error('getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', name);
4046 }
4047
4048 if (instance.propTypes) {
4049 error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
4050 }
4051
4052 if (instance.contextType) {
4053 error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name);
4054 }
4055
4056 {
4057 if (instance.contextTypes) {
4058 error('contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
4059 }
4060
4061 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
4062 didWarnAboutContextTypeAndContextTypes.add(ctor);
4063
4064 error('%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
4065 }
4066 }
4067
4068 if (typeof instance.componentShouldUpdate === 'function') {
4069 error('%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', name);
4070 }
4071
4072 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
4073 error('%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentName(ctor) || 'A pure component');
4074 }
4075
4076 if (typeof instance.componentDidUnmount === 'function') {
4077 error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
4078 }
4079
4080 if (typeof instance.componentDidReceiveProps === 'function') {
4081 error('%s has a method called ' + 'componentDidReceiveProps(). But there is no such lifecycle method. ' + 'If you meant to update the state in response to changing props, ' + 'use componentWillReceiveProps(). If you meant to fetch data or ' + 'run side-effects or mutations after React has updated the UI, use componentDidUpdate().', name);
4082 }
4083
4084 if (typeof instance.componentWillRecieveProps === 'function') {
4085 error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
4086 }
4087
4088 if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') {
4089 error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);
4090 }
4091
4092 var hasMutatedProps = instance.props !== newProps;
4093
4094 if (instance.props !== undefined && hasMutatedProps) {
4095 error('%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name);
4096 }
4097
4098 if (instance.defaultProps) {
4099 error('Setting defaultProps as an instance property on %s is not supported and will be ignored.' + ' Instead, define defaultProps as a static property on %s.', name, name);
4100 }
4101
4102 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
4103 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
4104
4105 error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
4106 }
4107
4108 if (typeof instance.getDerivedStateFromProps === 'function') {
4109 error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
4110 }
4111
4112 if (typeof instance.getDerivedStateFromError === 'function') {
4113 error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
4114 }
4115
4116 if (typeof ctor.getSnapshotBeforeUpdate === 'function') {
4117 error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name);
4118 }
4119
4120 var _state = instance.state;
4121
4122 if (_state && (typeof _state !== 'object' || isArray(_state))) {
4123 error('%s.state: must be set to an object or null', name);
4124 }
4125
4126 if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') {
4127 error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name);
4128 }
4129 }
4130 }
4131
4132 function adoptClassInstance(workInProgress, instance) {
4133 instance.updater = classComponentUpdater;
4134 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
4135
4136 set(instance, workInProgress);
4137
4138 {
4139 instance._reactInternalInstance = fakeInternalInstance;
4140 }
4141 }
4142
4143 function constructClassInstance(workInProgress, ctor, props) {
4144 var isLegacyContextConsumer = false;
4145 var unmaskedContext = emptyContextObject;
4146 var context = emptyContextObject;
4147 var contextType = ctor.contextType;
4148
4149 {
4150 if ('contextType' in ctor) {
4151 var isValid = // Allow null for conditional declaration
4152 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
4153
4154 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
4155 didWarnAboutInvalidateContextType.add(ctor);
4156 var addendum = '';
4157
4158 if (contextType === undefined) {
4159 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.';
4160 } else if (typeof contextType !== 'object') {
4161 addendum = ' However, it is set to a ' + typeof contextType + '.';
4162 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
4163 addendum = ' Did you accidentally pass the Context.Provider instead?';
4164 } else if (contextType._context !== undefined) {
4165 // <Context.Consumer>
4166 addendum = ' Did you accidentally pass the Context.Consumer instead?';
4167 } else {
4168 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
4169 }
4170
4171 error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
4172 }
4173 }
4174 }
4175
4176 if (typeof contextType === 'object' && contextType !== null) {
4177 context = readContext(contextType);
4178 } else {
4179 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4180 var contextTypes = ctor.contextTypes;
4181 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
4182 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
4183 } // Instantiate twice to help detect side-effects.
4184
4185
4186 {
4187 if ( workInProgress.mode & StrictMode) {
4188 new ctor(props, context); // eslint-disable-line no-new
4189 }
4190 }
4191
4192 var instance = new ctor(props, context);
4193 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
4194 adoptClassInstance(workInProgress, instance);
4195
4196 {
4197 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
4198 var componentName = getComponentName(ctor) || 'Component';
4199
4200 if (!didWarnAboutUninitializedState.has(componentName)) {
4201 didWarnAboutUninitializedState.add(componentName);
4202
4203 error('`%s` uses `getDerivedStateFromProps` but its initial state is ' + '%s. This is not recommended. Instead, define the initial state by ' + 'assigning an object to `this.state` in the constructor of `%s`. ' + 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.', componentName, instance.state === null ? 'null' : 'undefined', componentName);
4204 }
4205 } // If new component APIs are defined, "unsafe" lifecycles won't be called.
4206 // Warn about these lifecycles if they are present.
4207 // Don't warn about react-lifecycles-compat polyfilled methods though.
4208
4209
4210 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
4211 var foundWillMountName = null;
4212 var foundWillReceivePropsName = null;
4213 var foundWillUpdateName = null;
4214
4215 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
4216 foundWillMountName = 'componentWillMount';
4217 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
4218 foundWillMountName = 'UNSAFE_componentWillMount';
4219 }
4220
4221 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
4222 foundWillReceivePropsName = 'componentWillReceiveProps';
4223 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4224 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
4225 }
4226
4227 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
4228 foundWillUpdateName = 'componentWillUpdate';
4229 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4230 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
4231 }
4232
4233 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
4234 var _componentName = getComponentName(ctor) || 'Component';
4235
4236 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
4237
4238 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
4239 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
4240
4241 error('Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' + '%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n' + 'The above lifecycles should be removed. Learn more about this warning here:\n' + 'https://fb.me/react-unsafe-component-lifecycles', _componentName, newApiName, foundWillMountName !== null ? "\n " + foundWillMountName : '', foundWillReceivePropsName !== null ? "\n " + foundWillReceivePropsName : '', foundWillUpdateName !== null ? "\n " + foundWillUpdateName : '');
4242 }
4243 }
4244 }
4245 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
4246 // ReactFiberContext usually updates this cache but can't for newly-created instances.
4247
4248
4249 if (isLegacyContextConsumer) {
4250 cacheContext(workInProgress, unmaskedContext, context);
4251 }
4252
4253 return instance;
4254 }
4255
4256 function callComponentWillMount(workInProgress, instance) {
4257 startPhaseTimer(workInProgress, 'componentWillMount');
4258 var oldState = instance.state;
4259
4260 if (typeof instance.componentWillMount === 'function') {
4261 instance.componentWillMount();
4262 }
4263
4264 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4265 instance.UNSAFE_componentWillMount();
4266 }
4267
4268 stopPhaseTimer();
4269
4270 if (oldState !== instance.state) {
4271 {
4272 error('%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress.type) || 'Component');
4273 }
4274
4275 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4276 }
4277 }
4278
4279 function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
4280 var oldState = instance.state;
4281 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
4282
4283 if (typeof instance.componentWillReceiveProps === 'function') {
4284 instance.componentWillReceiveProps(newProps, nextContext);
4285 }
4286
4287 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4288 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
4289 }
4290
4291 stopPhaseTimer();
4292
4293 if (instance.state !== oldState) {
4294 {
4295 var componentName = getComponentName(workInProgress.type) || 'Component';
4296
4297 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
4298 didWarnAboutStateAssignmentForComponent.add(componentName);
4299
4300 error('%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
4301 }
4302 }
4303
4304 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4305 }
4306 } // Invokes the mount life-cycles on a previously never rendered instance.
4307
4308
4309 function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4310 {
4311 checkClassInstance(workInProgress, ctor, newProps);
4312 }
4313
4314 var instance = workInProgress.stateNode;
4315 instance.props = newProps;
4316 instance.state = workInProgress.memoizedState;
4317 instance.refs = emptyRefsObject;
4318 initializeUpdateQueue(workInProgress);
4319 var contextType = ctor.contextType;
4320
4321 if (typeof contextType === 'object' && contextType !== null) {
4322 instance.context = readContext(contextType);
4323 } else {
4324 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4325 instance.context = getMaskedContext(workInProgress, unmaskedContext);
4326 }
4327
4328 {
4329 if (instance.state === newProps) {
4330 var componentName = getComponentName(ctor) || 'Component';
4331
4332 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
4333 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
4334
4335 error('%s: It is not recommended to assign props directly to state ' + "because updates to props won't be reflected in state. " + 'In most cases, it is better to use props directly.', componentName);
4336 }
4337 }
4338
4339 if (workInProgress.mode & StrictMode) {
4340 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
4341 }
4342
4343 {
4344 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
4345 }
4346 }
4347
4348 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
4349 instance.state = workInProgress.memoizedState;
4350 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4351
4352 if (typeof getDerivedStateFromProps === 'function') {
4353 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4354 instance.state = workInProgress.memoizedState;
4355 } // In order to support react-lifecycles-compat polyfilled components,
4356 // Unsafe lifecycles should not be invoked for components using the new APIs.
4357
4358
4359 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4360 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
4361 // process them now.
4362
4363 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
4364 instance.state = workInProgress.memoizedState;
4365 }
4366
4367 if (typeof instance.componentDidMount === 'function') {
4368 workInProgress.effectTag |= Update;
4369 }
4370 }
4371
4372 function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4373 var instance = workInProgress.stateNode;
4374 var oldProps = workInProgress.memoizedProps;
4375 instance.props = oldProps;
4376 var oldContext = instance.context;
4377 var contextType = ctor.contextType;
4378 var nextContext = emptyContextObject;
4379
4380 if (typeof contextType === 'object' && contextType !== null) {
4381 nextContext = readContext(contextType);
4382 } else {
4383 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4384 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
4385 }
4386
4387 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4388 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
4389 // ever the previously attempted to render - not the "current". However,
4390 // during componentDidUpdate we pass the "current" props.
4391 // In order to support react-lifecycles-compat polyfilled components,
4392 // Unsafe lifecycles should not be invoked for components using the new APIs.
4393
4394 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4395 if (oldProps !== newProps || oldContext !== nextContext) {
4396 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4397 }
4398 }
4399
4400 resetHasForceUpdateBeforeProcessing();
4401 var oldState = workInProgress.memoizedState;
4402 var newState = instance.state = oldState;
4403 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
4404 newState = workInProgress.memoizedState;
4405
4406 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4407 // If an update was already in progress, we should schedule an Update
4408 // effect even though we're bailing out, so that cWU/cDU are called.
4409 if (typeof instance.componentDidMount === 'function') {
4410 workInProgress.effectTag |= Update;
4411 }
4412
4413 return false;
4414 }
4415
4416 if (typeof getDerivedStateFromProps === 'function') {
4417 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4418 newState = workInProgress.memoizedState;
4419 }
4420
4421 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4422
4423 if (shouldUpdate) {
4424 // In order to support react-lifecycles-compat polyfilled components,
4425 // Unsafe lifecycles should not be invoked for components using the new APIs.
4426 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4427 startPhaseTimer(workInProgress, 'componentWillMount');
4428
4429 if (typeof instance.componentWillMount === 'function') {
4430 instance.componentWillMount();
4431 }
4432
4433 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4434 instance.UNSAFE_componentWillMount();
4435 }
4436
4437 stopPhaseTimer();
4438 }
4439
4440 if (typeof instance.componentDidMount === 'function') {
4441 workInProgress.effectTag |= Update;
4442 }
4443 } else {
4444 // If an update was already in progress, we should schedule an Update
4445 // effect even though we're bailing out, so that cWU/cDU are called.
4446 if (typeof instance.componentDidMount === 'function') {
4447 workInProgress.effectTag |= Update;
4448 } // If shouldComponentUpdate returned false, we should still update the
4449 // memoized state to indicate that this work can be reused.
4450
4451
4452 workInProgress.memoizedProps = newProps;
4453 workInProgress.memoizedState = newState;
4454 } // Update the existing instance's state, props, and context pointers even
4455 // if shouldComponentUpdate returns false.
4456
4457
4458 instance.props = newProps;
4459 instance.state = newState;
4460 instance.context = nextContext;
4461 return shouldUpdate;
4462 } // Invokes the update life-cycles and returns false if it shouldn't rerender.
4463
4464
4465 function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
4466 var instance = workInProgress.stateNode;
4467 cloneUpdateQueue(current, workInProgress);
4468 var oldProps = workInProgress.memoizedProps;
4469 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
4470 var oldContext = instance.context;
4471 var contextType = ctor.contextType;
4472 var nextContext = emptyContextObject;
4473
4474 if (typeof contextType === 'object' && contextType !== null) {
4475 nextContext = readContext(contextType);
4476 } else {
4477 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4478 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
4479 }
4480
4481 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4482 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
4483 // ever the previously attempted to render - not the "current". However,
4484 // during componentDidUpdate we pass the "current" props.
4485 // In order to support react-lifecycles-compat polyfilled components,
4486 // Unsafe lifecycles should not be invoked for components using the new APIs.
4487
4488 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4489 if (oldProps !== newProps || oldContext !== nextContext) {
4490 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4491 }
4492 }
4493
4494 resetHasForceUpdateBeforeProcessing();
4495 var oldState = workInProgress.memoizedState;
4496 var newState = instance.state = oldState;
4497 processUpdateQueue(workInProgress, newProps, instance, renderExpirationTime);
4498 newState = workInProgress.memoizedState;
4499
4500 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4501 // If an update was already in progress, we should schedule an Update
4502 // effect even though we're bailing out, so that cWU/cDU are called.
4503 if (typeof instance.componentDidUpdate === 'function') {
4504 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4505 workInProgress.effectTag |= Update;
4506 }
4507 }
4508
4509 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4510 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4511 workInProgress.effectTag |= Snapshot;
4512 }
4513 }
4514
4515 return false;
4516 }
4517
4518 if (typeof getDerivedStateFromProps === 'function') {
4519 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4520 newState = workInProgress.memoizedState;
4521 }
4522
4523 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4524
4525 if (shouldUpdate) {
4526 // In order to support react-lifecycles-compat polyfilled components,
4527 // Unsafe lifecycles should not be invoked for components using the new APIs.
4528 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
4529 startPhaseTimer(workInProgress, 'componentWillUpdate');
4530
4531 if (typeof instance.componentWillUpdate === 'function') {
4532 instance.componentWillUpdate(newProps, newState, nextContext);
4533 }
4534
4535 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4536 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
4537 }
4538
4539 stopPhaseTimer();
4540 }
4541
4542 if (typeof instance.componentDidUpdate === 'function') {
4543 workInProgress.effectTag |= Update;
4544 }
4545
4546 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4547 workInProgress.effectTag |= Snapshot;
4548 }
4549 } else {
4550 // If an update was already in progress, we should schedule an Update
4551 // effect even though we're bailing out, so that cWU/cDU are called.
4552 if (typeof instance.componentDidUpdate === 'function') {
4553 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4554 workInProgress.effectTag |= Update;
4555 }
4556 }
4557
4558 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4559 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4560 workInProgress.effectTag |= Snapshot;
4561 }
4562 } // If shouldComponentUpdate returned false, we should still update the
4563 // memoized props/state to indicate that this work can be reused.
4564
4565
4566 workInProgress.memoizedProps = newProps;
4567 workInProgress.memoizedState = newState;
4568 } // Update the existing instance's state, props, and context pointers even
4569 // if shouldComponentUpdate returns false.
4570
4571
4572 instance.props = newProps;
4573 instance.state = newState;
4574 instance.context = nextContext;
4575 return shouldUpdate;
4576 }
4577
4578 var didWarnAboutMaps;
4579 var didWarnAboutGenerators;
4580 var didWarnAboutStringRefs;
4581 var ownerHasKeyUseWarning;
4582 var ownerHasFunctionTypeWarning;
4583
4584 var warnForMissingKey = function (child) {};
4585
4586 {
4587 didWarnAboutMaps = false;
4588 didWarnAboutGenerators = false;
4589 didWarnAboutStringRefs = {};
4590 /**
4591 * Warn if there's no key explicitly set on dynamic arrays of children or
4592 * object keys are not valid. This allows us to keep track of children between
4593 * updates.
4594 */
4595
4596 ownerHasKeyUseWarning = {};
4597 ownerHasFunctionTypeWarning = {};
4598
4599 warnForMissingKey = function (child) {
4600 if (child === null || typeof child !== 'object') {
4601 return;
4602 }
4603
4604 if (!child._store || child._store.validated || child.key != null) {
4605 return;
4606 }
4607
4608 if (!(typeof child._store === 'object')) {
4609 {
4610 throw Error( "React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue." );
4611 }
4612 }
4613
4614 child._store.validated = true;
4615 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
4616
4617 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
4618 return;
4619 }
4620
4621 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
4622
4623 error('Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
4624 };
4625 }
4626
4627 var isArray$1 = Array.isArray;
4628
4629 function coerceRef(returnFiber, current, element) {
4630 var mixedRef = element.ref;
4631
4632 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
4633 {
4634 // TODO: Clean this up once we turn on the string ref warning for
4635 // everyone, because the strict mode case will no longer be relevant
4636 if ((returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs
4637 // because these cannot be automatically converted to an arrow function
4638 // using a codemod. Therefore, we don't have to warn about string refs again.
4639 !(element._owner && element._self && element._owner.stateNode !== element._self)) {
4640 var componentName = getComponentName(returnFiber.type) || 'Component';
4641
4642 if (!didWarnAboutStringRefs[componentName]) {
4643 {
4644 error('A string ref, "%s", has been found within a strict mode tree. ' + 'String refs are a source of potential bugs and should be avoided. ' + 'We recommend using useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-string-ref%s', mixedRef, getStackByFiberInDevAndProd(returnFiber));
4645 }
4646
4647 didWarnAboutStringRefs[componentName] = true;
4648 }
4649 }
4650 }
4651
4652 if (element._owner) {
4653 var owner = element._owner;
4654 var inst;
4655
4656 if (owner) {
4657 var ownerFiber = owner;
4658
4659 if (!(ownerFiber.tag === ClassComponent)) {
4660 {
4661 throw Error( "Function components cannot have string refs. We recommend using useRef() instead. Learn more about using refs safely here: https://fb.me/react-strict-mode-string-ref" );
4662 }
4663 }
4664
4665 inst = ownerFiber.stateNode;
4666 }
4667
4668 if (!inst) {
4669 {
4670 throw Error( "Missing owner for string ref " + mixedRef + ". This error is likely caused by a bug in React. Please file an issue." );
4671 }
4672 }
4673
4674 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref
4675
4676 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
4677 return current.ref;
4678 }
4679
4680 var ref = function (value) {
4681 var refs = inst.refs;
4682
4683 if (refs === emptyRefsObject) {
4684 // This is a lazy pooled frozen object, so we need to initialize.
4685 refs = inst.refs = {};
4686 }
4687
4688 if (value === null) {
4689 delete refs[stringRef];
4690 } else {
4691 refs[stringRef] = value;
4692 }
4693 };
4694
4695 ref._stringRef = stringRef;
4696 return ref;
4697 } else {
4698 if (!(typeof mixedRef === 'string')) {
4699 {
4700 throw Error( "Expected ref to be a function, a string, an object returned by React.createRef(), or null." );
4701 }
4702 }
4703
4704 if (!element._owner) {
4705 {
4706 throw Error( "Element ref was specified as a string (" + mixedRef + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information." );
4707 }
4708 }
4709 }
4710 }
4711
4712 return mixedRef;
4713 }
4714
4715 function throwOnInvalidObjectType(returnFiber, newChild) {
4716 if (returnFiber.type !== 'textarea') {
4717 var addendum = '';
4718
4719 {
4720 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
4721 }
4722
4723 {
4724 {
4725 throw Error( "Objects are not valid as a React child (found: " + (Object.prototype.toString.call(newChild) === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : newChild) + ")." + addendum );
4726 }
4727 }
4728 }
4729 }
4730
4731 function warnOnFunctionType() {
4732 {
4733 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();
4734
4735 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
4736 return;
4737 }
4738
4739 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
4740
4741 error('Functions are not valid as a React child. This may happen if ' + 'you return a Component instead of <Component /> from render. ' + 'Or maybe you meant to call this function rather than return it.');
4742 }
4743 } // This wrapper function exists because I expect to clone the code in each path
4744 // to be able to optimize each path individually by branching early. This needs
4745 // a compiler or we can do it manually. Helpers that don't need this branching
4746 // live outside of this function.
4747
4748
4749 function ChildReconciler(shouldTrackSideEffects) {
4750 function deleteChild(returnFiber, childToDelete) {
4751 if (!shouldTrackSideEffects) {
4752 // Noop.
4753 return;
4754 } // Deletions are added in reversed order so we add it to the front.
4755 // At this point, the return fiber's effect list is empty except for
4756 // deletions, so we can just append the deletion to the list. The remaining
4757 // effects aren't added until the complete phase. Once we implement
4758 // resuming, this may not be true.
4759
4760
4761 var last = returnFiber.lastEffect;
4762
4763 if (last !== null) {
4764 last.nextEffect = childToDelete;
4765 returnFiber.lastEffect = childToDelete;
4766 } else {
4767 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
4768 }
4769
4770 childToDelete.nextEffect = null;
4771 childToDelete.effectTag = Deletion;
4772 }
4773
4774 function deleteRemainingChildren(returnFiber, currentFirstChild) {
4775 if (!shouldTrackSideEffects) {
4776 // Noop.
4777 return null;
4778 } // TODO: For the shouldClone case, this could be micro-optimized a bit by
4779 // assuming that after the first child we've already added everything.
4780
4781
4782 var childToDelete = currentFirstChild;
4783
4784 while (childToDelete !== null) {
4785 deleteChild(returnFiber, childToDelete);
4786 childToDelete = childToDelete.sibling;
4787 }
4788
4789 return null;
4790 }
4791
4792 function mapRemainingChildren(returnFiber, currentFirstChild) {
4793 // Add the remaining children to a temporary map so that we can find them by
4794 // keys quickly. Implicit (null) keys get added to this set with their index
4795 // instead.
4796 var existingChildren = new Map();
4797 var existingChild = currentFirstChild;
4798
4799 while (existingChild !== null) {
4800 if (existingChild.key !== null) {
4801 existingChildren.set(existingChild.key, existingChild);
4802 } else {
4803 existingChildren.set(existingChild.index, existingChild);
4804 }
4805
4806 existingChild = existingChild.sibling;
4807 }
4808
4809 return existingChildren;
4810 }
4811
4812 function useFiber(fiber, pendingProps) {
4813 // We currently set sibling to null and index to 0 here because it is easy
4814 // to forget to do before returning it. E.g. for the single child case.
4815 var clone = createWorkInProgress(fiber, pendingProps);
4816 clone.index = 0;
4817 clone.sibling = null;
4818 return clone;
4819 }
4820
4821 function placeChild(newFiber, lastPlacedIndex, newIndex) {
4822 newFiber.index = newIndex;
4823
4824 if (!shouldTrackSideEffects) {
4825 // Noop.
4826 return lastPlacedIndex;
4827 }
4828
4829 var current = newFiber.alternate;
4830
4831 if (current !== null) {
4832 var oldIndex = current.index;
4833
4834 if (oldIndex < lastPlacedIndex) {
4835 // This is a move.
4836 newFiber.effectTag = Placement;
4837 return lastPlacedIndex;
4838 } else {
4839 // This item can stay in place.
4840 return oldIndex;
4841 }
4842 } else {
4843 // This is an insertion.
4844 newFiber.effectTag = Placement;
4845 return lastPlacedIndex;
4846 }
4847 }
4848
4849 function placeSingleChild(newFiber) {
4850 // This is simpler for the single child case. We only need to do a
4851 // placement for inserting new children.
4852 if (shouldTrackSideEffects && newFiber.alternate === null) {
4853 newFiber.effectTag = Placement;
4854 }
4855
4856 return newFiber;
4857 }
4858
4859 function updateTextNode(returnFiber, current, textContent, expirationTime) {
4860 if (current === null || current.tag !== HostText) {
4861 // Insert
4862 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
4863 created.return = returnFiber;
4864 return created;
4865 } else {
4866 // Update
4867 var existing = useFiber(current, textContent);
4868 existing.return = returnFiber;
4869 return existing;
4870 }
4871 }
4872
4873 function updateElement(returnFiber, current, element, expirationTime) {
4874 if (current !== null) {
4875 if (current.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
4876 isCompatibleFamilyForHotReloading(current, element) )) {
4877 // Move based on index
4878 var existing = useFiber(current, element.props);
4879 existing.ref = coerceRef(returnFiber, current, element);
4880 existing.return = returnFiber;
4881
4882 {
4883 existing._debugSource = element._source;
4884 existing._debugOwner = element._owner;
4885 }
4886
4887 return existing;
4888 }
4889 } // Insert
4890
4891
4892 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
4893 created.ref = coerceRef(returnFiber, current, element);
4894 created.return = returnFiber;
4895 return created;
4896 }
4897
4898 function updatePortal(returnFiber, current, portal, expirationTime) {
4899 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
4900 // Insert
4901 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
4902 created.return = returnFiber;
4903 return created;
4904 } else {
4905 // Update
4906 var existing = useFiber(current, portal.children || []);
4907 existing.return = returnFiber;
4908 return existing;
4909 }
4910 }
4911
4912 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
4913 if (current === null || current.tag !== Fragment) {
4914 // Insert
4915 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
4916 created.return = returnFiber;
4917 return created;
4918 } else {
4919 // Update
4920 var existing = useFiber(current, fragment);
4921 existing.return = returnFiber;
4922 return existing;
4923 }
4924 }
4925
4926 function createChild(returnFiber, newChild, expirationTime) {
4927 if (typeof newChild === 'string' || typeof newChild === 'number') {
4928 // Text nodes don't have keys. If the previous node is implicitly keyed
4929 // we can continue to replace it without aborting even if it is not a text
4930 // node.
4931 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
4932 created.return = returnFiber;
4933 return created;
4934 }
4935
4936 if (typeof newChild === 'object' && newChild !== null) {
4937 switch (newChild.$$typeof) {
4938 case REACT_ELEMENT_TYPE:
4939 {
4940 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
4941
4942 _created.ref = coerceRef(returnFiber, null, newChild);
4943 _created.return = returnFiber;
4944 return _created;
4945 }
4946
4947 case REACT_PORTAL_TYPE:
4948 {
4949 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
4950
4951 _created2.return = returnFiber;
4952 return _created2;
4953 }
4954 }
4955
4956 if (isArray$1(newChild) || getIteratorFn(newChild)) {
4957 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
4958
4959 _created3.return = returnFiber;
4960 return _created3;
4961 }
4962
4963 throwOnInvalidObjectType(returnFiber, newChild);
4964 }
4965
4966 {
4967 if (typeof newChild === 'function') {
4968 warnOnFunctionType();
4969 }
4970 }
4971
4972 return null;
4973 }
4974
4975 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
4976 // Update the fiber if the keys match, otherwise return null.
4977 var key = oldFiber !== null ? oldFiber.key : null;
4978
4979 if (typeof newChild === 'string' || typeof newChild === 'number') {
4980 // Text nodes don't have keys. If the previous node is implicitly keyed
4981 // we can continue to replace it without aborting even if it is not a text
4982 // node.
4983 if (key !== null) {
4984 return null;
4985 }
4986
4987 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
4988 }
4989
4990 if (typeof newChild === 'object' && newChild !== null) {
4991 switch (newChild.$$typeof) {
4992 case REACT_ELEMENT_TYPE:
4993 {
4994 if (newChild.key === key) {
4995 if (newChild.type === REACT_FRAGMENT_TYPE) {
4996 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
4997 }
4998
4999 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
5000 } else {
5001 return null;
5002 }
5003 }
5004
5005 case REACT_PORTAL_TYPE:
5006 {
5007 if (newChild.key === key) {
5008 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
5009 } else {
5010 return null;
5011 }
5012 }
5013 }
5014
5015 if (isArray$1(newChild) || getIteratorFn(newChild)) {
5016 if (key !== null) {
5017 return null;
5018 }
5019
5020 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
5021 }
5022
5023 throwOnInvalidObjectType(returnFiber, newChild);
5024 }
5025
5026 {
5027 if (typeof newChild === 'function') {
5028 warnOnFunctionType();
5029 }
5030 }
5031
5032 return null;
5033 }
5034
5035 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
5036 if (typeof newChild === 'string' || typeof newChild === 'number') {
5037 // Text nodes don't have keys, so we neither have to check the old nor
5038 // new node for the key. If both are text nodes, they match.
5039 var matchedFiber = existingChildren.get(newIdx) || null;
5040 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
5041 }
5042
5043 if (typeof newChild === 'object' && newChild !== null) {
5044 switch (newChild.$$typeof) {
5045 case REACT_ELEMENT_TYPE:
5046 {
5047 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
5048
5049 if (newChild.type === REACT_FRAGMENT_TYPE) {
5050 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
5051 }
5052
5053 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
5054 }
5055
5056 case REACT_PORTAL_TYPE:
5057 {
5058 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
5059
5060 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
5061 }
5062 }
5063
5064 if (isArray$1(newChild) || getIteratorFn(newChild)) {
5065 var _matchedFiber3 = existingChildren.get(newIdx) || null;
5066
5067 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
5068 }
5069
5070 throwOnInvalidObjectType(returnFiber, newChild);
5071 }
5072
5073 {
5074 if (typeof newChild === 'function') {
5075 warnOnFunctionType();
5076 }
5077 }
5078
5079 return null;
5080 }
5081 /**
5082 * Warns if there is a duplicate or missing key
5083 */
5084
5085
5086 function warnOnInvalidKey(child, knownKeys) {
5087 {
5088 if (typeof child !== 'object' || child === null) {
5089 return knownKeys;
5090 }
5091
5092 switch (child.$$typeof) {
5093 case REACT_ELEMENT_TYPE:
5094 case REACT_PORTAL_TYPE:
5095 warnForMissingKey(child);
5096 var key = child.key;
5097
5098 if (typeof key !== 'string') {
5099 break;
5100 }
5101
5102 if (knownKeys === null) {
5103 knownKeys = new Set();
5104 knownKeys.add(key);
5105 break;
5106 }
5107
5108 if (!knownKeys.has(key)) {
5109 knownKeys.add(key);
5110 break;
5111 }
5112
5113 error('Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key);
5114
5115 break;
5116 }
5117 }
5118
5119 return knownKeys;
5120 }
5121
5122 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
5123 // This algorithm can't optimize by searching from both ends since we
5124 // don't have backpointers on fibers. I'm trying to see how far we can get
5125 // with that model. If it ends up not being worth the tradeoffs, we can
5126 // add it later.
5127 // Even with a two ended optimization, we'd want to optimize for the case
5128 // where there are few changes and brute force the comparison instead of
5129 // going for the Map. It'd like to explore hitting that path first in
5130 // forward-only mode and only go for the Map once we notice that we need
5131 // lots of look ahead. This doesn't handle reversal as well as two ended
5132 // search but that's unusual. Besides, for the two ended optimization to
5133 // work on Iterables, we'd need to copy the whole set.
5134 // In this first iteration, we'll just live with hitting the bad case
5135 // (adding everything to a Map) in for every insert/move.
5136 // If you change this code, also update reconcileChildrenIterator() which
5137 // uses the same algorithm.
5138 {
5139 // First, validate keys.
5140 var knownKeys = null;
5141
5142 for (var i = 0; i < newChildren.length; i++) {
5143 var child = newChildren[i];
5144 knownKeys = warnOnInvalidKey(child, knownKeys);
5145 }
5146 }
5147
5148 var resultingFirstChild = null;
5149 var previousNewFiber = null;
5150 var oldFiber = currentFirstChild;
5151 var lastPlacedIndex = 0;
5152 var newIdx = 0;
5153 var nextOldFiber = null;
5154
5155 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
5156 if (oldFiber.index > newIdx) {
5157 nextOldFiber = oldFiber;
5158 oldFiber = null;
5159 } else {
5160 nextOldFiber = oldFiber.sibling;
5161 }
5162
5163 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
5164
5165 if (newFiber === null) {
5166 // TODO: This breaks on empty slots like null children. That's
5167 // unfortunate because it triggers the slow path all the time. We need
5168 // a better way to communicate whether this was a miss or null,
5169 // boolean, undefined, etc.
5170 if (oldFiber === null) {
5171 oldFiber = nextOldFiber;
5172 }
5173
5174 break;
5175 }
5176
5177 if (shouldTrackSideEffects) {
5178 if (oldFiber && newFiber.alternate === null) {
5179 // We matched the slot, but we didn't reuse the existing fiber, so we
5180 // need to delete the existing child.
5181 deleteChild(returnFiber, oldFiber);
5182 }
5183 }
5184
5185 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
5186
5187 if (previousNewFiber === null) {
5188 // TODO: Move out of the loop. This only happens for the first run.
5189 resultingFirstChild = newFiber;
5190 } else {
5191 // TODO: Defer siblings if we're not at the right index for this slot.
5192 // I.e. if we had null values before, then we want to defer this
5193 // for each null value. However, we also don't want to call updateSlot
5194 // with the previous one.
5195 previousNewFiber.sibling = newFiber;
5196 }
5197
5198 previousNewFiber = newFiber;
5199 oldFiber = nextOldFiber;
5200 }
5201
5202 if (newIdx === newChildren.length) {
5203 // We've reached the end of the new children. We can delete the rest.
5204 deleteRemainingChildren(returnFiber, oldFiber);
5205 return resultingFirstChild;
5206 }
5207
5208 if (oldFiber === null) {
5209 // If we don't have any more existing children we can choose a fast path
5210 // since the rest will all be insertions.
5211 for (; newIdx < newChildren.length; newIdx++) {
5212 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
5213
5214 if (_newFiber === null) {
5215 continue;
5216 }
5217
5218 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
5219
5220 if (previousNewFiber === null) {
5221 // TODO: Move out of the loop. This only happens for the first run.
5222 resultingFirstChild = _newFiber;
5223 } else {
5224 previousNewFiber.sibling = _newFiber;
5225 }
5226
5227 previousNewFiber = _newFiber;
5228 }
5229
5230 return resultingFirstChild;
5231 } // Add all children to a key map for quick lookups.
5232
5233
5234 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
5235
5236 for (; newIdx < newChildren.length; newIdx++) {
5237 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
5238
5239 if (_newFiber2 !== null) {
5240 if (shouldTrackSideEffects) {
5241 if (_newFiber2.alternate !== null) {
5242 // The new fiber is a work in progress, but if there exists a
5243 // current, that means that we reused the fiber. We need to delete
5244 // it from the child list so that we don't add it to the deletion
5245 // list.
5246 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
5247 }
5248 }
5249
5250 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
5251
5252 if (previousNewFiber === null) {
5253 resultingFirstChild = _newFiber2;
5254 } else {
5255 previousNewFiber.sibling = _newFiber2;
5256 }
5257
5258 previousNewFiber = _newFiber2;
5259 }
5260 }
5261
5262 if (shouldTrackSideEffects) {
5263 // Any existing children that weren't consumed above were deleted. We need
5264 // to add them to the deletion list.
5265 existingChildren.forEach(function (child) {
5266 return deleteChild(returnFiber, child);
5267 });
5268 }
5269
5270 return resultingFirstChild;
5271 }
5272
5273 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
5274 // This is the same implementation as reconcileChildrenArray(),
5275 // but using the iterator instead.
5276 var iteratorFn = getIteratorFn(newChildrenIterable);
5277
5278 if (!(typeof iteratorFn === 'function')) {
5279 {
5280 throw Error( "An object is not an iterable. This error is likely caused by a bug in React. Please file an issue." );
5281 }
5282 }
5283
5284 {
5285 // We don't support rendering Generators because it's a mutation.
5286 // See https://github.com/facebook/react/issues/12995
5287 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag
5288 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
5289 if (!didWarnAboutGenerators) {
5290 error('Using Generators as children is unsupported and will likely yield ' + 'unexpected results because enumerating a generator mutates it. ' + 'You may convert it to an array with `Array.from()` or the ' + '`[...spread]` operator before rendering. Keep in mind ' + 'you might need to polyfill these features for older browsers.');
5291 }
5292
5293 didWarnAboutGenerators = true;
5294 } // Warn about using Maps as children
5295
5296
5297 if (newChildrenIterable.entries === iteratorFn) {
5298 if (!didWarnAboutMaps) {
5299 error('Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.');
5300 }
5301
5302 didWarnAboutMaps = true;
5303 } // First, validate keys.
5304 // We'll get a different iterator later for the main pass.
5305
5306
5307 var _newChildren = iteratorFn.call(newChildrenIterable);
5308
5309 if (_newChildren) {
5310 var knownKeys = null;
5311
5312 var _step = _newChildren.next();
5313
5314 for (; !_step.done; _step = _newChildren.next()) {
5315 var child = _step.value;
5316 knownKeys = warnOnInvalidKey(child, knownKeys);
5317 }
5318 }
5319 }
5320
5321 var newChildren = iteratorFn.call(newChildrenIterable);
5322
5323 if (!(newChildren != null)) {
5324 {
5325 throw Error( "An iterable object provided no iterator." );
5326 }
5327 }
5328
5329 var resultingFirstChild = null;
5330 var previousNewFiber = null;
5331 var oldFiber = currentFirstChild;
5332 var lastPlacedIndex = 0;
5333 var newIdx = 0;
5334 var nextOldFiber = null;
5335 var step = newChildren.next();
5336
5337 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
5338 if (oldFiber.index > newIdx) {
5339 nextOldFiber = oldFiber;
5340 oldFiber = null;
5341 } else {
5342 nextOldFiber = oldFiber.sibling;
5343 }
5344
5345 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
5346
5347 if (newFiber === null) {
5348 // TODO: This breaks on empty slots like null children. That's
5349 // unfortunate because it triggers the slow path all the time. We need
5350 // a better way to communicate whether this was a miss or null,
5351 // boolean, undefined, etc.
5352 if (oldFiber === null) {
5353 oldFiber = nextOldFiber;
5354 }
5355
5356 break;
5357 }
5358
5359 if (shouldTrackSideEffects) {
5360 if (oldFiber && newFiber.alternate === null) {
5361 // We matched the slot, but we didn't reuse the existing fiber, so we
5362 // need to delete the existing child.
5363 deleteChild(returnFiber, oldFiber);
5364 }
5365 }
5366
5367 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
5368
5369 if (previousNewFiber === null) {
5370 // TODO: Move out of the loop. This only happens for the first run.
5371 resultingFirstChild = newFiber;
5372 } else {
5373 // TODO: Defer siblings if we're not at the right index for this slot.
5374 // I.e. if we had null values before, then we want to defer this
5375 // for each null value. However, we also don't want to call updateSlot
5376 // with the previous one.
5377 previousNewFiber.sibling = newFiber;
5378 }
5379
5380 previousNewFiber = newFiber;
5381 oldFiber = nextOldFiber;
5382 }
5383
5384 if (step.done) {
5385 // We've reached the end of the new children. We can delete the rest.
5386 deleteRemainingChildren(returnFiber, oldFiber);
5387 return resultingFirstChild;
5388 }
5389
5390 if (oldFiber === null) {
5391 // If we don't have any more existing children we can choose a fast path
5392 // since the rest will all be insertions.
5393 for (; !step.done; newIdx++, step = newChildren.next()) {
5394 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
5395
5396 if (_newFiber3 === null) {
5397 continue;
5398 }
5399
5400 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
5401
5402 if (previousNewFiber === null) {
5403 // TODO: Move out of the loop. This only happens for the first run.
5404 resultingFirstChild = _newFiber3;
5405 } else {
5406 previousNewFiber.sibling = _newFiber3;
5407 }
5408
5409 previousNewFiber = _newFiber3;
5410 }
5411
5412 return resultingFirstChild;
5413 } // Add all children to a key map for quick lookups.
5414
5415
5416 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
5417
5418 for (; !step.done; newIdx++, step = newChildren.next()) {
5419 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
5420
5421 if (_newFiber4 !== null) {
5422 if (shouldTrackSideEffects) {
5423 if (_newFiber4.alternate !== null) {
5424 // The new fiber is a work in progress, but if there exists a
5425 // current, that means that we reused the fiber. We need to delete
5426 // it from the child list so that we don't add it to the deletion
5427 // list.
5428 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
5429 }
5430 }
5431
5432 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
5433
5434 if (previousNewFiber === null) {
5435 resultingFirstChild = _newFiber4;
5436 } else {
5437 previousNewFiber.sibling = _newFiber4;
5438 }
5439
5440 previousNewFiber = _newFiber4;
5441 }
5442 }
5443
5444 if (shouldTrackSideEffects) {
5445 // Any existing children that weren't consumed above were deleted. We need
5446 // to add them to the deletion list.
5447 existingChildren.forEach(function (child) {
5448 return deleteChild(returnFiber, child);
5449 });
5450 }
5451
5452 return resultingFirstChild;
5453 }
5454
5455 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
5456 // There's no need to check for keys on text nodes since we don't have a
5457 // way to define them.
5458 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
5459 // We already have an existing node so let's just update it and delete
5460 // the rest.
5461 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
5462 var existing = useFiber(currentFirstChild, textContent);
5463 existing.return = returnFiber;
5464 return existing;
5465 } // The existing first child is not a text node so we need to create one
5466 // and delete the existing ones.
5467
5468
5469 deleteRemainingChildren(returnFiber, currentFirstChild);
5470 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
5471 created.return = returnFiber;
5472 return created;
5473 }
5474
5475 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
5476 var key = element.key;
5477 var child = currentFirstChild;
5478
5479 while (child !== null) {
5480 // TODO: If key === null and child.key === null, then this only applies to
5481 // the first item in the list.
5482 if (child.key === key) {
5483 switch (child.tag) {
5484 case Fragment:
5485 {
5486 if (element.type === REACT_FRAGMENT_TYPE) {
5487 deleteRemainingChildren(returnFiber, child.sibling);
5488 var existing = useFiber(child, element.props.children);
5489 existing.return = returnFiber;
5490
5491 {
5492 existing._debugSource = element._source;
5493 existing._debugOwner = element._owner;
5494 }
5495
5496 return existing;
5497 }
5498
5499 break;
5500 }
5501
5502 case Block:
5503
5504 // We intentionally fallthrough here if enableBlocksAPI is not on.
5505 // eslint-disable-next-lined no-fallthrough
5506
5507 default:
5508 {
5509 if (child.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
5510 isCompatibleFamilyForHotReloading(child, element) )) {
5511 deleteRemainingChildren(returnFiber, child.sibling);
5512
5513 var _existing3 = useFiber(child, element.props);
5514
5515 _existing3.ref = coerceRef(returnFiber, child, element);
5516 _existing3.return = returnFiber;
5517
5518 {
5519 _existing3._debugSource = element._source;
5520 _existing3._debugOwner = element._owner;
5521 }
5522
5523 return _existing3;
5524 }
5525
5526 break;
5527 }
5528 } // Didn't match.
5529
5530
5531 deleteRemainingChildren(returnFiber, child);
5532 break;
5533 } else {
5534 deleteChild(returnFiber, child);
5535 }
5536
5537 child = child.sibling;
5538 }
5539
5540 if (element.type === REACT_FRAGMENT_TYPE) {
5541 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
5542 created.return = returnFiber;
5543 return created;
5544 } else {
5545 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
5546
5547 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
5548 _created4.return = returnFiber;
5549 return _created4;
5550 }
5551 }
5552
5553 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
5554 var key = portal.key;
5555 var child = currentFirstChild;
5556
5557 while (child !== null) {
5558 // TODO: If key === null and child.key === null, then this only applies to
5559 // the first item in the list.
5560 if (child.key === key) {
5561 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
5562 deleteRemainingChildren(returnFiber, child.sibling);
5563 var existing = useFiber(child, portal.children || []);
5564 existing.return = returnFiber;
5565 return existing;
5566 } else {
5567 deleteRemainingChildren(returnFiber, child);
5568 break;
5569 }
5570 } else {
5571 deleteChild(returnFiber, child);
5572 }
5573
5574 child = child.sibling;
5575 }
5576
5577 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
5578 created.return = returnFiber;
5579 return created;
5580 } // This API will tag the children with the side-effect of the reconciliation
5581 // itself. They will be added to the side-effect list as we pass through the
5582 // children and the parent.
5583
5584
5585 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
5586 // This function is not recursive.
5587 // If the top level item is an array, we treat it as a set of children,
5588 // not as a fragment. Nested arrays on the other hand will be treated as
5589 // fragment nodes. Recursion happens at the normal flow.
5590 // Handle top level unkeyed fragments as if they were arrays.
5591 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
5592 // We treat the ambiguous cases above the same.
5593 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
5594
5595 if (isUnkeyedTopLevelFragment) {
5596 newChild = newChild.props.children;
5597 } // Handle object types
5598
5599
5600 var isObject = typeof newChild === 'object' && newChild !== null;
5601
5602 if (isObject) {
5603 switch (newChild.$$typeof) {
5604 case REACT_ELEMENT_TYPE:
5605 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
5606
5607 case REACT_PORTAL_TYPE:
5608 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
5609 }
5610 }
5611
5612 if (typeof newChild === 'string' || typeof newChild === 'number') {
5613 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
5614 }
5615
5616 if (isArray$1(newChild)) {
5617 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
5618 }
5619
5620 if (getIteratorFn(newChild)) {
5621 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
5622 }
5623
5624 if (isObject) {
5625 throwOnInvalidObjectType(returnFiber, newChild);
5626 }
5627
5628 {
5629 if (typeof newChild === 'function') {
5630 warnOnFunctionType();
5631 }
5632 }
5633
5634 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
5635 // If the new child is undefined, and the return fiber is a composite
5636 // component, throw an error. If Fiber return types are disabled,
5637 // we already threw above.
5638 switch (returnFiber.tag) {
5639 case ClassComponent:
5640 {
5641 {
5642 var instance = returnFiber.stateNode;
5643
5644 if (instance.render._isMockFunction) {
5645 // We allow auto-mocks to proceed as if they're returning null.
5646 break;
5647 }
5648 }
5649 }
5650 // Intentionally fall through to the next case, which handles both
5651 // functions and classes
5652 // eslint-disable-next-lined no-fallthrough
5653
5654 case FunctionComponent:
5655 {
5656 var Component = returnFiber.type;
5657
5658 {
5659 {
5660 throw Error( (Component.displayName || Component.name || 'Component') + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null." );
5661 }
5662 }
5663 }
5664 }
5665 } // Remaining cases are all treated as empty.
5666
5667
5668 return deleteRemainingChildren(returnFiber, currentFirstChild);
5669 }
5670
5671 return reconcileChildFibers;
5672 }
5673
5674 var reconcileChildFibers = ChildReconciler(true);
5675 var mountChildFibers = ChildReconciler(false);
5676 function cloneChildFibers(current, workInProgress) {
5677 if (!(current === null || workInProgress.child === current.child)) {
5678 {
5679 throw Error( "Resuming work not yet implemented." );
5680 }
5681 }
5682
5683 if (workInProgress.child === null) {
5684 return;
5685 }
5686
5687 var currentChild = workInProgress.child;
5688 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps);
5689 workInProgress.child = newChild;
5690 newChild.return = workInProgress;
5691
5692 while (currentChild.sibling !== null) {
5693 currentChild = currentChild.sibling;
5694 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps);
5695 newChild.return = workInProgress;
5696 }
5697
5698 newChild.sibling = null;
5699 } // Reset a workInProgress child set to prepare it for a second pass.
5700
5701 function resetChildFibers(workInProgress, renderExpirationTime) {
5702 var child = workInProgress.child;
5703
5704 while (child !== null) {
5705 resetWorkInProgress(child, renderExpirationTime);
5706 child = child.sibling;
5707 }
5708 }
5709
5710 var NO_CONTEXT$1 = {};
5711 var contextStackCursor$1 = createCursor(NO_CONTEXT$1);
5712 var contextFiberStackCursor = createCursor(NO_CONTEXT$1);
5713 var rootInstanceStackCursor = createCursor(NO_CONTEXT$1);
5714
5715 function requiredContext(c) {
5716 if (!(c !== NO_CONTEXT$1)) {
5717 {
5718 throw Error( "Expected host context to exist. This error is likely caused by a bug in React. Please file an issue." );
5719 }
5720 }
5721
5722 return c;
5723 }
5724
5725 function getRootHostContainer() {
5726 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5727 return rootInstance;
5728 }
5729
5730 function pushHostContainer(fiber, nextRootInstance) {
5731 // Push current root instance onto the stack;
5732 // This allows us to reset root when portals are popped.
5733 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
5734 // This enables us to pop only Fibers that provide unique contexts.
5735
5736 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
5737 // However, we can't just call getRootHostContext() and push it because
5738 // we'd have a different number of entries on the stack depending on
5739 // whether getRootHostContext() throws somewhere in renderer code or not.
5740 // So we push an empty value first. This lets us safely unwind on errors.
5741
5742 push(contextStackCursor$1, NO_CONTEXT$1, fiber);
5743 var nextRootContext = getRootHostContext(); // Now that we know this function doesn't throw, replace it.
5744
5745 pop(contextStackCursor$1, fiber);
5746 push(contextStackCursor$1, nextRootContext, fiber);
5747 }
5748
5749 function popHostContainer(fiber) {
5750 pop(contextStackCursor$1, fiber);
5751 pop(contextFiberStackCursor, fiber);
5752 pop(rootInstanceStackCursor, fiber);
5753 }
5754
5755 function getHostContext() {
5756 var context = requiredContext(contextStackCursor$1.current);
5757 return context;
5758 }
5759
5760 function pushHostContext(fiber) {
5761 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5762 var context = requiredContext(contextStackCursor$1.current);
5763 var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique.
5764
5765 if (context === nextContext) {
5766 return;
5767 } // Track the context and the Fiber that provided it.
5768 // This enables us to pop only Fibers that provide unique contexts.
5769
5770
5771 push(contextFiberStackCursor, fiber, fiber);
5772 push(contextStackCursor$1, nextContext, fiber);
5773 }
5774
5775 function popHostContext(fiber) {
5776 // Do not pop unless this Fiber provided the current context.
5777 // pushHostContext() only pushes Fibers that provide unique contexts.
5778 if (contextFiberStackCursor.current !== fiber) {
5779 return;
5780 }
5781
5782 pop(contextStackCursor$1, fiber);
5783 pop(contextFiberStackCursor, fiber);
5784 }
5785
5786 var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is
5787 // inherited deeply down the subtree. The upper bits only affect
5788 // this immediate suspense boundary and gets reset each new
5789 // boundary or suspense list.
5790
5791 var SubtreeSuspenseContextMask = 1; // Subtree Flags:
5792 // InvisibleParentSuspenseContext indicates that one of our parent Suspense
5793 // boundaries is not currently showing visible main content.
5794 // Either because it is already showing a fallback or is not mounted at all.
5795 // We can use this to determine if it is desirable to trigger a fallback at
5796 // the parent. If not, then we might need to trigger undesirable boundaries
5797 // and/or suspend the commit to avoid hiding the parent content.
5798
5799 var InvisibleParentSuspenseContext = 1; // Shallow Flags:
5800 // ForceSuspenseFallback can be used by SuspenseList to force newly added
5801 // items into their fallback state during one of the render passes.
5802
5803 var ForceSuspenseFallback = 2;
5804 var suspenseStackCursor = createCursor(DefaultSuspenseContext);
5805 function hasSuspenseContext(parentContext, flag) {
5806 return (parentContext & flag) !== 0;
5807 }
5808 function setDefaultShallowSuspenseContext(parentContext) {
5809 return parentContext & SubtreeSuspenseContextMask;
5810 }
5811 function setShallowSuspenseContext(parentContext, shallowContext) {
5812 return parentContext & SubtreeSuspenseContextMask | shallowContext;
5813 }
5814 function addSubtreeSuspenseContext(parentContext, subtreeContext) {
5815 return parentContext | subtreeContext;
5816 }
5817 function pushSuspenseContext(fiber, newContext) {
5818 push(suspenseStackCursor, newContext, fiber);
5819 }
5820 function popSuspenseContext(fiber) {
5821 pop(suspenseStackCursor, fiber);
5822 }
5823
5824 function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
5825 // If it was the primary children that just suspended, capture and render the
5826 // fallback. Otherwise, don't capture and bubble to the next boundary.
5827 var nextState = workInProgress.memoizedState;
5828
5829 if (nextState !== null) {
5830 if (nextState.dehydrated !== null) {
5831 // A dehydrated boundary always captures.
5832 return true;
5833 }
5834
5835 return false;
5836 }
5837
5838 var props = workInProgress.memoizedProps; // In order to capture, the Suspense component must have a fallback prop.
5839
5840 if (props.fallback === undefined) {
5841 return false;
5842 } // Regular boundaries always capture.
5843
5844
5845 if (props.unstable_avoidThisFallback !== true) {
5846 return true;
5847 } // If it's a boundary we should avoid, then we prefer to bubble up to the
5848 // parent boundary if it is currently invisible.
5849
5850
5851 if (hasInvisibleParent) {
5852 return false;
5853 } // If the parent is not able to handle it, we must handle it.
5854
5855
5856 return true;
5857 }
5858 function findFirstSuspended(row) {
5859 var node = row;
5860
5861 while (node !== null) {
5862 if (node.tag === SuspenseComponent) {
5863 var state = node.memoizedState;
5864
5865 if (state !== null) {
5866 var dehydrated = state.dehydrated;
5867
5868 if (dehydrated === null || isSuspenseInstancePending() || isSuspenseInstanceFallback()) {
5869 return node;
5870 }
5871 }
5872 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
5873 // keep track of whether it suspended or not.
5874 node.memoizedProps.revealOrder !== undefined) {
5875 var didSuspend = (node.effectTag & DidCapture) !== NoEffect;
5876
5877 if (didSuspend) {
5878 return node;
5879 }
5880 } else if (node.child !== null) {
5881 node.child.return = node;
5882 node = node.child;
5883 continue;
5884 }
5885
5886 if (node === row) {
5887 return null;
5888 }
5889
5890 while (node.sibling === null) {
5891 if (node.return === null || node.return === row) {
5892 return null;
5893 }
5894
5895 node = node.return;
5896 }
5897
5898 node.sibling.return = node.return;
5899 node = node.sibling;
5900 }
5901
5902 return null;
5903 }
5904
5905 function createDeprecatedResponderListener(responder, props) {
5906 var eventResponderListener = {
5907 responder: responder,
5908 props: props
5909 };
5910
5911 {
5912 Object.freeze(eventResponderListener);
5913 }
5914
5915 return eventResponderListener;
5916 }
5917
5918 var HasEffect =
5919 /* */
5920 1; // Represents the phase in which the effect (not the clean-up) fires.
5921
5922 var Layout =
5923 /* */
5924 2;
5925 var Passive$1 =
5926 /* */
5927 4;
5928
5929 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher,
5930 ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig;
5931 var didWarnAboutMismatchedHooksForComponent;
5932
5933 {
5934 didWarnAboutMismatchedHooksForComponent = new Set();
5935 }
5936
5937 // These are set right before calling the component.
5938 var renderExpirationTime = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from
5939 // the work-in-progress hook.
5940
5941 var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
5942 // current hook list is the list that belongs to the current fiber. The
5943 // work-in-progress hook list is a new list that will be added to the
5944 // work-in-progress fiber.
5945
5946 var currentHook = null;
5947 var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This
5948 // does not get reset if we do another render pass; only when we're completely
5949 // finished evaluating this component. This is an optimization so we know
5950 // whether we need to clear render phase updates after a throw.
5951
5952 var didScheduleRenderPhaseUpdate = false;
5953 var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
5954
5955 var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
5956 // The list stores the order of hooks used during the initial render (mount).
5957 // Subsequent renders (updates) reference this list.
5958
5959 var hookTypesDev = null;
5960 var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
5961 // the dependencies for Hooks that need them (e.g. useEffect or useMemo).
5962 // When true, such Hooks will always be "remounted". Only used during hot reload.
5963
5964 var ignorePreviousDependencies = false;
5965
5966 function mountHookTypesDev() {
5967 {
5968 var hookName = currentHookNameInDev;
5969
5970 if (hookTypesDev === null) {
5971 hookTypesDev = [hookName];
5972 } else {
5973 hookTypesDev.push(hookName);
5974 }
5975 }
5976 }
5977
5978 function updateHookTypesDev() {
5979 {
5980 var hookName = currentHookNameInDev;
5981
5982 if (hookTypesDev !== null) {
5983 hookTypesUpdateIndexDev++;
5984
5985 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
5986 warnOnHookMismatchInDev(hookName);
5987 }
5988 }
5989 }
5990 }
5991
5992 function checkDepsAreArrayDev(deps) {
5993 {
5994 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
5995 // Verify deps, but only on mount to avoid extra checks.
5996 // It's unlikely their type would change as usually you define them inline.
5997 error('%s received a final argument that is not an array (instead, received `%s`). When ' + 'specified, the final argument must be an array.', currentHookNameInDev, typeof deps);
5998 }
5999 }
6000 }
6001
6002 function warnOnHookMismatchInDev(currentHookName) {
6003 {
6004 var componentName = getComponentName(currentlyRenderingFiber$1.type);
6005
6006 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
6007 didWarnAboutMismatchedHooksForComponent.add(componentName);
6008
6009 if (hookTypesDev !== null) {
6010 var table = '';
6011 var secondColumnStart = 30;
6012
6013 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
6014 var oldHookName = hookTypesDev[i];
6015 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
6016 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
6017 // lol @ IE not supporting String#repeat
6018
6019 while (row.length < secondColumnStart) {
6020 row += ' ';
6021 }
6022
6023 row += newHookName + '\n';
6024 table += row;
6025 }
6026
6027 error('React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' ------------------------------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table);
6028 }
6029 }
6030 }
6031 }
6032
6033 function throwInvalidHookError() {
6034 {
6035 {
6036 throw Error( "Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem." );
6037 }
6038 }
6039 }
6040
6041 function areHookInputsEqual(nextDeps, prevDeps) {
6042 {
6043 if (ignorePreviousDependencies) {
6044 // Only true when this component is being hot reloaded.
6045 return false;
6046 }
6047 }
6048
6049 if (prevDeps === null) {
6050 {
6051 error('%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', currentHookNameInDev);
6052 }
6053
6054 return false;
6055 }
6056
6057 {
6058 // Don't bother comparing lengths in prod because these arrays should be
6059 // passed inline.
6060 if (nextDeps.length !== prevDeps.length) {
6061 error('The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + 'Incoming: %s', currentHookNameInDev, "[" + prevDeps.join(', ') + "]", "[" + nextDeps.join(', ') + "]");
6062 }
6063 }
6064
6065 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
6066 if (objectIs(nextDeps[i], prevDeps[i])) {
6067 continue;
6068 }
6069
6070 return false;
6071 }
6072
6073 return true;
6074 }
6075
6076 function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderExpirationTime) {
6077 renderExpirationTime = nextRenderExpirationTime;
6078 currentlyRenderingFiber$1 = workInProgress;
6079
6080 {
6081 hookTypesDev = current !== null ? current._debugHookTypes : null;
6082 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
6083
6084 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
6085 }
6086
6087 workInProgress.memoizedState = null;
6088 workInProgress.updateQueue = null;
6089 workInProgress.expirationTime = NoWork; // The following should have already been reset
6090 // currentHook = null;
6091 // workInProgressHook = null;
6092 // didScheduleRenderPhaseUpdate = false;
6093 // TODO Warn if no hooks are used at all during mount, then some are used during update.
6094 // Currently we will identify the update render as a mount because memoizedState === null.
6095 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
6096 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.
6097 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
6098 // so memoizedState would be null during updates and mounts.
6099
6100 {
6101 if (current !== null && current.memoizedState !== null) {
6102 ReactCurrentDispatcher.current = HooksDispatcherOnUpdateInDEV;
6103 } else if (hookTypesDev !== null) {
6104 // This dispatcher handles an edge case where a component is updating,
6105 // but no stateful hooks have been used.
6106 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
6107 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
6108 // This dispatcher does that.
6109 ReactCurrentDispatcher.current = HooksDispatcherOnMountWithHookTypesInDEV;
6110 } else {
6111 ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV;
6112 }
6113 }
6114
6115 var children = Component(props, secondArg); // Check if there was a render phase update
6116
6117 if (workInProgress.expirationTime === renderExpirationTime) {
6118 // Keep rendering in a loop for as long as render phase updates continue to
6119 // be scheduled. Use a counter to prevent infinite loops.
6120 var numberOfReRenders = 0;
6121
6122 do {
6123 workInProgress.expirationTime = NoWork;
6124
6125 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {
6126 {
6127 throw Error( "Too many re-renders. React limits the number of renders to prevent an infinite loop." );
6128 }
6129 }
6130
6131 numberOfReRenders += 1;
6132
6133 {
6134 // Even when hot reloading, allow dependencies to stabilize
6135 // after first render to prevent infinite render phase updates.
6136 ignorePreviousDependencies = false;
6137 } // Start over from the beginning of the list
6138
6139
6140 currentHook = null;
6141 workInProgressHook = null;
6142 workInProgress.updateQueue = null;
6143
6144 {
6145 // Also validate hook order for cascading updates.
6146 hookTypesUpdateIndexDev = -1;
6147 }
6148
6149 ReactCurrentDispatcher.current = HooksDispatcherOnRerenderInDEV ;
6150 children = Component(props, secondArg);
6151 } while (workInProgress.expirationTime === renderExpirationTime);
6152 } // We can assume the previous dispatcher is always this one, since we set it
6153 // at the beginning of the render phase and there's no re-entrancy.
6154
6155
6156 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
6157
6158 {
6159 workInProgress._debugHookTypes = hookTypesDev;
6160 } // This check uses currentHook so that it works the same in DEV and prod bundles.
6161 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
6162
6163
6164 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
6165 renderExpirationTime = NoWork;
6166 currentlyRenderingFiber$1 = null;
6167 currentHook = null;
6168 workInProgressHook = null;
6169
6170 {
6171 currentHookNameInDev = null;
6172 hookTypesDev = null;
6173 hookTypesUpdateIndexDev = -1;
6174 }
6175
6176 didScheduleRenderPhaseUpdate = false;
6177
6178 if (!!didRenderTooFewHooks) {
6179 {
6180 throw Error( "Rendered fewer hooks than expected. This may be caused by an accidental early return statement." );
6181 }
6182 }
6183
6184 return children;
6185 }
6186 function bailoutHooks(current, workInProgress, expirationTime) {
6187 workInProgress.updateQueue = current.updateQueue;
6188 workInProgress.effectTag &= ~(Passive | Update);
6189
6190 if (current.expirationTime <= expirationTime) {
6191 current.expirationTime = NoWork;
6192 }
6193 }
6194 function resetHooksAfterThrow() {
6195 // We can assume the previous dispatcher is always this one, since we set it
6196 // at the beginning of the render phase and there's no re-entrancy.
6197 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
6198
6199 if (didScheduleRenderPhaseUpdate) {
6200 // There were render phase updates. These are only valid for this render
6201 // phase, which we are now aborting. Remove the updates from the queues so
6202 // they do not persist to the next render. Do not remove updates from hooks
6203 // that weren't processed.
6204 //
6205 // Only reset the updates from the queue if it has a clone. If it does
6206 // not have a clone, that means it wasn't processed, and the updates were
6207 // scheduled before we entered the render phase.
6208 var hook = currentlyRenderingFiber$1.memoizedState;
6209
6210 while (hook !== null) {
6211 var queue = hook.queue;
6212
6213 if (queue !== null) {
6214 queue.pending = null;
6215 }
6216
6217 hook = hook.next;
6218 }
6219 }
6220
6221 renderExpirationTime = NoWork;
6222 currentlyRenderingFiber$1 = null;
6223 currentHook = null;
6224 workInProgressHook = null;
6225
6226 {
6227 hookTypesDev = null;
6228 hookTypesUpdateIndexDev = -1;
6229 currentHookNameInDev = null;
6230 }
6231
6232 didScheduleRenderPhaseUpdate = false;
6233 }
6234
6235 function mountWorkInProgressHook() {
6236 var hook = {
6237 memoizedState: null,
6238 baseState: null,
6239 baseQueue: null,
6240 queue: null,
6241 next: null
6242 };
6243
6244 if (workInProgressHook === null) {
6245 // This is the first hook in the list
6246 currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;
6247 } else {
6248 // Append to the end of the list
6249 workInProgressHook = workInProgressHook.next = hook;
6250 }
6251
6252 return workInProgressHook;
6253 }
6254
6255 function updateWorkInProgressHook() {
6256 // This function is used both for updates and for re-renders triggered by a
6257 // render phase update. It assumes there is either a current hook we can
6258 // clone, or a work-in-progress hook from a previous render pass that we can
6259 // use as a base. When we reach the end of the base list, we must switch to
6260 // the dispatcher used for mounts.
6261 var nextCurrentHook;
6262
6263 if (currentHook === null) {
6264 var current = currentlyRenderingFiber$1.alternate;
6265
6266 if (current !== null) {
6267 nextCurrentHook = current.memoizedState;
6268 } else {
6269 nextCurrentHook = null;
6270 }
6271 } else {
6272 nextCurrentHook = currentHook.next;
6273 }
6274
6275 var nextWorkInProgressHook;
6276
6277 if (workInProgressHook === null) {
6278 nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;
6279 } else {
6280 nextWorkInProgressHook = workInProgressHook.next;
6281 }
6282
6283 if (nextWorkInProgressHook !== null) {
6284 // There's already a work-in-progress. Reuse it.
6285 workInProgressHook = nextWorkInProgressHook;
6286 nextWorkInProgressHook = workInProgressHook.next;
6287 currentHook = nextCurrentHook;
6288 } else {
6289 // Clone from the current hook.
6290 if (!(nextCurrentHook !== null)) {
6291 {
6292 throw Error( "Rendered more hooks than during the previous render." );
6293 }
6294 }
6295
6296 currentHook = nextCurrentHook;
6297 var newHook = {
6298 memoizedState: currentHook.memoizedState,
6299 baseState: currentHook.baseState,
6300 baseQueue: currentHook.baseQueue,
6301 queue: currentHook.queue,
6302 next: null
6303 };
6304
6305 if (workInProgressHook === null) {
6306 // This is the first hook in the list.
6307 currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;
6308 } else {
6309 // Append to the end of the list.
6310 workInProgressHook = workInProgressHook.next = newHook;
6311 }
6312 }
6313
6314 return workInProgressHook;
6315 }
6316
6317 function createFunctionComponentUpdateQueue() {
6318 return {
6319 lastEffect: null
6320 };
6321 }
6322
6323 function basicStateReducer(state, action) {
6324 // $FlowFixMe: Flow doesn't like mixed types
6325 return typeof action === 'function' ? action(state) : action;
6326 }
6327
6328 function mountReducer(reducer, initialArg, init) {
6329 var hook = mountWorkInProgressHook();
6330 var initialState;
6331
6332 if (init !== undefined) {
6333 initialState = init(initialArg);
6334 } else {
6335 initialState = initialArg;
6336 }
6337
6338 hook.memoizedState = hook.baseState = initialState;
6339 var queue = hook.queue = {
6340 pending: null,
6341 dispatch: null,
6342 lastRenderedReducer: reducer,
6343 lastRenderedState: initialState
6344 };
6345 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
6346 return [hook.memoizedState, dispatch];
6347 }
6348
6349 function updateReducer(reducer, initialArg, init) {
6350 var hook = updateWorkInProgressHook();
6351 var queue = hook.queue;
6352
6353 if (!(queue !== null)) {
6354 {
6355 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
6356 }
6357 }
6358
6359 queue.lastRenderedReducer = reducer;
6360 var current = currentHook; // The last rebase update that is NOT part of the base state.
6361
6362 var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet.
6363
6364 var pendingQueue = queue.pending;
6365
6366 if (pendingQueue !== null) {
6367 // We have new updates that haven't been processed yet.
6368 // We'll add them to the base queue.
6369 if (baseQueue !== null) {
6370 // Merge the pending queue and the base queue.
6371 var baseFirst = baseQueue.next;
6372 var pendingFirst = pendingQueue.next;
6373 baseQueue.next = pendingFirst;
6374 pendingQueue.next = baseFirst;
6375 }
6376
6377 current.baseQueue = baseQueue = pendingQueue;
6378 queue.pending = null;
6379 }
6380
6381 if (baseQueue !== null) {
6382 // We have a queue to process.
6383 var first = baseQueue.next;
6384 var newState = current.baseState;
6385 var newBaseState = null;
6386 var newBaseQueueFirst = null;
6387 var newBaseQueueLast = null;
6388 var update = first;
6389
6390 do {
6391 var updateExpirationTime = update.expirationTime;
6392
6393 if (updateExpirationTime < renderExpirationTime) {
6394 // Priority is insufficient. Skip this update. If this is the first
6395 // skipped update, the previous update/state is the new base
6396 // update/state.
6397 var clone = {
6398 expirationTime: update.expirationTime,
6399 suspenseConfig: update.suspenseConfig,
6400 action: update.action,
6401 eagerReducer: update.eagerReducer,
6402 eagerState: update.eagerState,
6403 next: null
6404 };
6405
6406 if (newBaseQueueLast === null) {
6407 newBaseQueueFirst = newBaseQueueLast = clone;
6408 newBaseState = newState;
6409 } else {
6410 newBaseQueueLast = newBaseQueueLast.next = clone;
6411 } // Update the remaining priority in the queue.
6412
6413
6414 if (updateExpirationTime > currentlyRenderingFiber$1.expirationTime) {
6415 currentlyRenderingFiber$1.expirationTime = updateExpirationTime;
6416 markUnprocessedUpdateTime(updateExpirationTime);
6417 }
6418 } else {
6419 // This update does have sufficient priority.
6420 if (newBaseQueueLast !== null) {
6421 var _clone = {
6422 expirationTime: Sync,
6423 // This update is going to be committed so we never want uncommit it.
6424 suspenseConfig: update.suspenseConfig,
6425 action: update.action,
6426 eagerReducer: update.eagerReducer,
6427 eagerState: update.eagerState,
6428 next: null
6429 };
6430 newBaseQueueLast = newBaseQueueLast.next = _clone;
6431 } // Mark the event time of this update as relevant to this render pass.
6432 // TODO: This should ideally use the true event time of this update rather than
6433 // its priority which is a derived and not reverseable value.
6434 // TODO: We should skip this update if it was already committed but currently
6435 // we have no way of detecting the difference between a committed and suspended
6436 // update here.
6437
6438
6439 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process this update.
6440
6441 if (update.eagerReducer === reducer) {
6442 // If this update was processed eagerly, and its reducer matches the
6443 // current reducer, we can use the eagerly computed state.
6444 newState = update.eagerState;
6445 } else {
6446 var action = update.action;
6447 newState = reducer(newState, action);
6448 }
6449 }
6450
6451 update = update.next;
6452 } while (update !== null && update !== first);
6453
6454 if (newBaseQueueLast === null) {
6455 newBaseState = newState;
6456 } else {
6457 newBaseQueueLast.next = newBaseQueueFirst;
6458 } // Mark that the fiber performed work, but only if the new state is
6459 // different from the current state.
6460
6461
6462 if (!objectIs(newState, hook.memoizedState)) {
6463 markWorkInProgressReceivedUpdate();
6464 }
6465
6466 hook.memoizedState = newState;
6467 hook.baseState = newBaseState;
6468 hook.baseQueue = newBaseQueueLast;
6469 queue.lastRenderedState = newState;
6470 }
6471
6472 var dispatch = queue.dispatch;
6473 return [hook.memoizedState, dispatch];
6474 }
6475
6476 function rerenderReducer(reducer, initialArg, init) {
6477 var hook = updateWorkInProgressHook();
6478 var queue = hook.queue;
6479
6480 if (!(queue !== null)) {
6481 {
6482 throw Error( "Should have a queue. This is likely a bug in React. Please file an issue." );
6483 }
6484 }
6485
6486 queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous
6487 // work-in-progress hook.
6488
6489 var dispatch = queue.dispatch;
6490 var lastRenderPhaseUpdate = queue.pending;
6491 var newState = hook.memoizedState;
6492
6493 if (lastRenderPhaseUpdate !== null) {
6494 // The queue doesn't persist past this render pass.
6495 queue.pending = null;
6496 var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;
6497 var update = firstRenderPhaseUpdate;
6498
6499 do {
6500 // Process this render phase update. We don't have to check the
6501 // priority because it will always be the same as the current
6502 // render's.
6503 var action = update.action;
6504 newState = reducer(newState, action);
6505 update = update.next;
6506 } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is
6507 // different from the current state.
6508
6509
6510 if (!objectIs(newState, hook.memoizedState)) {
6511 markWorkInProgressReceivedUpdate();
6512 }
6513
6514 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
6515 // the base state unless the queue is empty.
6516 // TODO: Not sure if this is the desired semantics, but it's what we
6517 // do for gDSFP. I can't remember why.
6518
6519 if (hook.baseQueue === null) {
6520 hook.baseState = newState;
6521 }
6522
6523 queue.lastRenderedState = newState;
6524 }
6525
6526 return [newState, dispatch];
6527 }
6528
6529 function mountState(initialState) {
6530 var hook = mountWorkInProgressHook();
6531
6532 if (typeof initialState === 'function') {
6533 // $FlowFixMe: Flow doesn't like mixed types
6534 initialState = initialState();
6535 }
6536
6537 hook.memoizedState = hook.baseState = initialState;
6538 var queue = hook.queue = {
6539 pending: null,
6540 dispatch: null,
6541 lastRenderedReducer: basicStateReducer,
6542 lastRenderedState: initialState
6543 };
6544 var dispatch = queue.dispatch = dispatchAction.bind(null, currentlyRenderingFiber$1, queue);
6545 return [hook.memoizedState, dispatch];
6546 }
6547
6548 function updateState(initialState) {
6549 return updateReducer(basicStateReducer);
6550 }
6551
6552 function rerenderState(initialState) {
6553 return rerenderReducer(basicStateReducer);
6554 }
6555
6556 function pushEffect(tag, create, destroy, deps) {
6557 var effect = {
6558 tag: tag,
6559 create: create,
6560 destroy: destroy,
6561 deps: deps,
6562 // Circular
6563 next: null
6564 };
6565 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
6566
6567 if (componentUpdateQueue === null) {
6568 componentUpdateQueue = createFunctionComponentUpdateQueue();
6569 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
6570 componentUpdateQueue.lastEffect = effect.next = effect;
6571 } else {
6572 var lastEffect = componentUpdateQueue.lastEffect;
6573
6574 if (lastEffect === null) {
6575 componentUpdateQueue.lastEffect = effect.next = effect;
6576 } else {
6577 var firstEffect = lastEffect.next;
6578 lastEffect.next = effect;
6579 effect.next = firstEffect;
6580 componentUpdateQueue.lastEffect = effect;
6581 }
6582 }
6583
6584 return effect;
6585 }
6586
6587 function mountRef(initialValue) {
6588 var hook = mountWorkInProgressHook();
6589 var ref = {
6590 current: initialValue
6591 };
6592
6593 {
6594 Object.seal(ref);
6595 }
6596
6597 hook.memoizedState = ref;
6598 return ref;
6599 }
6600
6601 function updateRef(initialValue) {
6602 var hook = updateWorkInProgressHook();
6603 return hook.memoizedState;
6604 }
6605
6606 function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
6607 var hook = mountWorkInProgressHook();
6608 var nextDeps = deps === undefined ? null : deps;
6609 currentlyRenderingFiber$1.effectTag |= fiberEffectTag;
6610 hook.memoizedState = pushEffect(HasEffect | hookEffectTag, create, undefined, nextDeps);
6611 }
6612
6613 function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
6614 var hook = updateWorkInProgressHook();
6615 var nextDeps = deps === undefined ? null : deps;
6616 var destroy = undefined;
6617
6618 if (currentHook !== null) {
6619 var prevEffect = currentHook.memoizedState;
6620 destroy = prevEffect.destroy;
6621
6622 if (nextDeps !== null) {
6623 var prevDeps = prevEffect.deps;
6624
6625 if (areHookInputsEqual(nextDeps, prevDeps)) {
6626 pushEffect(hookEffectTag, create, destroy, nextDeps);
6627 return;
6628 }
6629 }
6630 }
6631
6632 currentlyRenderingFiber$1.effectTag |= fiberEffectTag;
6633 hook.memoizedState = pushEffect(HasEffect | hookEffectTag, create, destroy, nextDeps);
6634 }
6635
6636 function mountEffect(create, deps) {
6637
6638 return mountEffectImpl(Update | Passive, Passive$1, create, deps);
6639 }
6640
6641 function updateEffect(create, deps) {
6642
6643 return updateEffectImpl(Update | Passive, Passive$1, create, deps);
6644 }
6645
6646 function mountLayoutEffect(create, deps) {
6647 return mountEffectImpl(Update, Layout, create, deps);
6648 }
6649
6650 function updateLayoutEffect(create, deps) {
6651 return updateEffectImpl(Update, Layout, create, deps);
6652 }
6653
6654 function imperativeHandleEffect(create, ref) {
6655 if (typeof ref === 'function') {
6656 var refCallback = ref;
6657
6658 var _inst = create();
6659
6660 refCallback(_inst);
6661 return function () {
6662 refCallback(null);
6663 };
6664 } else if (ref !== null && ref !== undefined) {
6665 var refObject = ref;
6666
6667 {
6668 if (!refObject.hasOwnProperty('current')) {
6669 error('Expected useImperativeHandle() first argument to either be a ' + 'ref callback or React.createRef() object. Instead received: %s.', 'an object with keys {' + Object.keys(refObject).join(', ') + '}');
6670 }
6671 }
6672
6673 var _inst2 = create();
6674
6675 refObject.current = _inst2;
6676 return function () {
6677 refObject.current = null;
6678 };
6679 }
6680 }
6681
6682 function mountImperativeHandle(ref, create, deps) {
6683 {
6684 if (typeof create !== 'function') {
6685 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
6686 }
6687 } // TODO: If deps are provided, should we skip comparing the ref itself?
6688
6689
6690 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6691 return mountEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6692 }
6693
6694 function updateImperativeHandle(ref, create, deps) {
6695 {
6696 if (typeof create !== 'function') {
6697 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
6698 }
6699 } // TODO: If deps are provided, should we skip comparing the ref itself?
6700
6701
6702 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6703 return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6704 }
6705
6706 function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.
6707 // The react-debug-hooks package injects its own implementation
6708 // so that e.g. DevTools can display custom hook values.
6709 }
6710
6711 var updateDebugValue = mountDebugValue;
6712
6713 function mountCallback(callback, deps) {
6714 var hook = mountWorkInProgressHook();
6715 var nextDeps = deps === undefined ? null : deps;
6716 hook.memoizedState = [callback, nextDeps];
6717 return callback;
6718 }
6719
6720 function updateCallback(callback, deps) {
6721 var hook = updateWorkInProgressHook();
6722 var nextDeps = deps === undefined ? null : deps;
6723 var prevState = hook.memoizedState;
6724
6725 if (prevState !== null) {
6726 if (nextDeps !== null) {
6727 var prevDeps = prevState[1];
6728
6729 if (areHookInputsEqual(nextDeps, prevDeps)) {
6730 return prevState[0];
6731 }
6732 }
6733 }
6734
6735 hook.memoizedState = [callback, nextDeps];
6736 return callback;
6737 }
6738
6739 function mountMemo(nextCreate, deps) {
6740 var hook = mountWorkInProgressHook();
6741 var nextDeps = deps === undefined ? null : deps;
6742 var nextValue = nextCreate();
6743 hook.memoizedState = [nextValue, nextDeps];
6744 return nextValue;
6745 }
6746
6747 function updateMemo(nextCreate, deps) {
6748 var hook = updateWorkInProgressHook();
6749 var nextDeps = deps === undefined ? null : deps;
6750 var prevState = hook.memoizedState;
6751
6752 if (prevState !== null) {
6753 // Assume these are defined. If they're not, areHookInputsEqual will warn.
6754 if (nextDeps !== null) {
6755 var prevDeps = prevState[1];
6756
6757 if (areHookInputsEqual(nextDeps, prevDeps)) {
6758 return prevState[0];
6759 }
6760 }
6761 }
6762
6763 var nextValue = nextCreate();
6764 hook.memoizedState = [nextValue, nextDeps];
6765 return nextValue;
6766 }
6767
6768 function mountDeferredValue(value, config) {
6769 var _mountState = mountState(value),
6770 prevValue = _mountState[0],
6771 setValue = _mountState[1];
6772
6773 mountEffect(function () {
6774 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6775 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6776
6777 try {
6778 setValue(value);
6779 } finally {
6780 ReactCurrentBatchConfig$1.suspense = previousConfig;
6781 }
6782 }, [value, config]);
6783 return prevValue;
6784 }
6785
6786 function updateDeferredValue(value, config) {
6787 var _updateState = updateState(),
6788 prevValue = _updateState[0],
6789 setValue = _updateState[1];
6790
6791 updateEffect(function () {
6792 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6793 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6794
6795 try {
6796 setValue(value);
6797 } finally {
6798 ReactCurrentBatchConfig$1.suspense = previousConfig;
6799 }
6800 }, [value, config]);
6801 return prevValue;
6802 }
6803
6804 function rerenderDeferredValue(value, config) {
6805 var _rerenderState = rerenderState(),
6806 prevValue = _rerenderState[0],
6807 setValue = _rerenderState[1];
6808
6809 updateEffect(function () {
6810 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6811 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6812
6813 try {
6814 setValue(value);
6815 } finally {
6816 ReactCurrentBatchConfig$1.suspense = previousConfig;
6817 }
6818 }, [value, config]);
6819 return prevValue;
6820 }
6821
6822 function startTransition(setPending, config, callback) {
6823 var priorityLevel = getCurrentPriorityLevel();
6824 runWithPriority(priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel, function () {
6825 setPending(true);
6826 });
6827 runWithPriority(priorityLevel > NormalPriority ? NormalPriority : priorityLevel, function () {
6828 var previousConfig = ReactCurrentBatchConfig$1.suspense;
6829 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
6830
6831 try {
6832 setPending(false);
6833 callback();
6834 } finally {
6835 ReactCurrentBatchConfig$1.suspense = previousConfig;
6836 }
6837 });
6838 }
6839
6840 function mountTransition(config) {
6841 var _mountState2 = mountState(false),
6842 isPending = _mountState2[0],
6843 setPending = _mountState2[1];
6844
6845 var start = mountCallback(startTransition.bind(null, setPending, config), [setPending, config]);
6846 return [start, isPending];
6847 }
6848
6849 function updateTransition(config) {
6850 var _updateState2 = updateState(),
6851 isPending = _updateState2[0],
6852 setPending = _updateState2[1];
6853
6854 var start = updateCallback(startTransition.bind(null, setPending, config), [setPending, config]);
6855 return [start, isPending];
6856 }
6857
6858 function rerenderTransition(config) {
6859 var _rerenderState2 = rerenderState(),
6860 isPending = _rerenderState2[0],
6861 setPending = _rerenderState2[1];
6862
6863 var start = updateCallback(startTransition.bind(null, setPending, config), [setPending, config]);
6864 return [start, isPending];
6865 }
6866
6867 function dispatchAction(fiber, queue, action) {
6868 {
6869 if (typeof arguments[3] === 'function') {
6870 error("State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().');
6871 }
6872 }
6873
6874 var currentTime = requestCurrentTimeForUpdate();
6875 var suspenseConfig = requestCurrentSuspenseConfig();
6876 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
6877 var update = {
6878 expirationTime: expirationTime,
6879 suspenseConfig: suspenseConfig,
6880 action: action,
6881 eagerReducer: null,
6882 eagerState: null,
6883 next: null
6884 };
6885
6886 {
6887 update.priority = getCurrentPriorityLevel();
6888 } // Append the update to the end of the list.
6889
6890
6891 var pending = queue.pending;
6892
6893 if (pending === null) {
6894 // This is the first update. Create a circular list.
6895 update.next = update;
6896 } else {
6897 update.next = pending.next;
6898 pending.next = update;
6899 }
6900
6901 queue.pending = update;
6902 var alternate = fiber.alternate;
6903
6904 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
6905 // This is a render phase update. Stash it in a lazily-created map of
6906 // queue -> linked list of updates. After this render pass, we'll restart
6907 // and apply the stashed updates on top of the work-in-progress hook.
6908 didScheduleRenderPhaseUpdate = true;
6909 update.expirationTime = renderExpirationTime;
6910 currentlyRenderingFiber$1.expirationTime = renderExpirationTime;
6911 } else {
6912 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
6913 // The queue is currently empty, which means we can eagerly compute the
6914 // next state before entering the render phase. If the new state is the
6915 // same as the current state, we may be able to bail out entirely.
6916 var lastRenderedReducer = queue.lastRenderedReducer;
6917
6918 if (lastRenderedReducer !== null) {
6919 var prevDispatcher;
6920
6921 {
6922 prevDispatcher = ReactCurrentDispatcher.current;
6923 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6924 }
6925
6926 try {
6927 var currentState = queue.lastRenderedState;
6928 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
6929 // it, on the update object. If the reducer hasn't changed by the
6930 // time we enter the render phase, then the eager state can be used
6931 // without calling the reducer again.
6932
6933 update.eagerReducer = lastRenderedReducer;
6934 update.eagerState = eagerState;
6935
6936 if (objectIs(eagerState, currentState)) {
6937 // Fast path. We can bail out without scheduling React to re-render.
6938 // It's still possible that we'll need to rebase this update later,
6939 // if the component re-renders for a different reason and by that
6940 // time the reducer has changed.
6941 return;
6942 }
6943 } catch (error) {// Suppress the error. It will throw again in the render phase.
6944 } finally {
6945 {
6946 ReactCurrentDispatcher.current = prevDispatcher;
6947 }
6948 }
6949 }
6950 }
6951
6952 scheduleWork(fiber, expirationTime);
6953 }
6954 }
6955
6956 var ContextOnlyDispatcher = {
6957 readContext: readContext,
6958 useCallback: throwInvalidHookError,
6959 useContext: throwInvalidHookError,
6960 useEffect: throwInvalidHookError,
6961 useImperativeHandle: throwInvalidHookError,
6962 useLayoutEffect: throwInvalidHookError,
6963 useMemo: throwInvalidHookError,
6964 useReducer: throwInvalidHookError,
6965 useRef: throwInvalidHookError,
6966 useState: throwInvalidHookError,
6967 useDebugValue: throwInvalidHookError,
6968 useResponder: throwInvalidHookError,
6969 useDeferredValue: throwInvalidHookError,
6970 useTransition: throwInvalidHookError
6971 };
6972 var HooksDispatcherOnMountInDEV = null;
6973 var HooksDispatcherOnMountWithHookTypesInDEV = null;
6974 var HooksDispatcherOnUpdateInDEV = null;
6975 var HooksDispatcherOnRerenderInDEV = null;
6976 var InvalidNestedHooksDispatcherOnMountInDEV = null;
6977 var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
6978 var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
6979
6980 {
6981 var warnInvalidContextAccess = function () {
6982 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().');
6983 };
6984
6985 var warnInvalidHookAccess = function () {
6986 error('Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' + 'You can only call Hooks at the top level of your React function. ' + 'For more information, see ' + 'https://fb.me/rules-of-hooks');
6987 };
6988
6989 HooksDispatcherOnMountInDEV = {
6990 readContext: function (context, observedBits) {
6991 return readContext(context, observedBits);
6992 },
6993 useCallback: function (callback, deps) {
6994 currentHookNameInDev = 'useCallback';
6995 mountHookTypesDev();
6996 checkDepsAreArrayDev(deps);
6997 return mountCallback(callback, deps);
6998 },
6999 useContext: function (context, observedBits) {
7000 currentHookNameInDev = 'useContext';
7001 mountHookTypesDev();
7002 return readContext(context, observedBits);
7003 },
7004 useEffect: function (create, deps) {
7005 currentHookNameInDev = 'useEffect';
7006 mountHookTypesDev();
7007 checkDepsAreArrayDev(deps);
7008 return mountEffect(create, deps);
7009 },
7010 useImperativeHandle: function (ref, create, deps) {
7011 currentHookNameInDev = 'useImperativeHandle';
7012 mountHookTypesDev();
7013 checkDepsAreArrayDev(deps);
7014 return mountImperativeHandle(ref, create, deps);
7015 },
7016 useLayoutEffect: function (create, deps) {
7017 currentHookNameInDev = 'useLayoutEffect';
7018 mountHookTypesDev();
7019 checkDepsAreArrayDev(deps);
7020 return mountLayoutEffect(create, deps);
7021 },
7022 useMemo: function (create, deps) {
7023 currentHookNameInDev = 'useMemo';
7024 mountHookTypesDev();
7025 checkDepsAreArrayDev(deps);
7026 var prevDispatcher = ReactCurrentDispatcher.current;
7027 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7028
7029 try {
7030 return mountMemo(create, deps);
7031 } finally {
7032 ReactCurrentDispatcher.current = prevDispatcher;
7033 }
7034 },
7035 useReducer: function (reducer, initialArg, init) {
7036 currentHookNameInDev = 'useReducer';
7037 mountHookTypesDev();
7038 var prevDispatcher = ReactCurrentDispatcher.current;
7039 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7040
7041 try {
7042 return mountReducer(reducer, initialArg, init);
7043 } finally {
7044 ReactCurrentDispatcher.current = prevDispatcher;
7045 }
7046 },
7047 useRef: function (initialValue) {
7048 currentHookNameInDev = 'useRef';
7049 mountHookTypesDev();
7050 return mountRef(initialValue);
7051 },
7052 useState: function (initialState) {
7053 currentHookNameInDev = 'useState';
7054 mountHookTypesDev();
7055 var prevDispatcher = ReactCurrentDispatcher.current;
7056 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7057
7058 try {
7059 return mountState(initialState);
7060 } finally {
7061 ReactCurrentDispatcher.current = prevDispatcher;
7062 }
7063 },
7064 useDebugValue: function (value, formatterFn) {
7065 currentHookNameInDev = 'useDebugValue';
7066 mountHookTypesDev();
7067 return mountDebugValue();
7068 },
7069 useResponder: function (responder, props) {
7070 currentHookNameInDev = 'useResponder';
7071 mountHookTypesDev();
7072 return createDeprecatedResponderListener(responder, props);
7073 },
7074 useDeferredValue: function (value, config) {
7075 currentHookNameInDev = 'useDeferredValue';
7076 mountHookTypesDev();
7077 return mountDeferredValue(value, config);
7078 },
7079 useTransition: function (config) {
7080 currentHookNameInDev = 'useTransition';
7081 mountHookTypesDev();
7082 return mountTransition(config);
7083 }
7084 };
7085 HooksDispatcherOnMountWithHookTypesInDEV = {
7086 readContext: function (context, observedBits) {
7087 return readContext(context, observedBits);
7088 },
7089 useCallback: function (callback, deps) {
7090 currentHookNameInDev = 'useCallback';
7091 updateHookTypesDev();
7092 return mountCallback(callback, deps);
7093 },
7094 useContext: function (context, observedBits) {
7095 currentHookNameInDev = 'useContext';
7096 updateHookTypesDev();
7097 return readContext(context, observedBits);
7098 },
7099 useEffect: function (create, deps) {
7100 currentHookNameInDev = 'useEffect';
7101 updateHookTypesDev();
7102 return mountEffect(create, deps);
7103 },
7104 useImperativeHandle: function (ref, create, deps) {
7105 currentHookNameInDev = 'useImperativeHandle';
7106 updateHookTypesDev();
7107 return mountImperativeHandle(ref, create, deps);
7108 },
7109 useLayoutEffect: function (create, deps) {
7110 currentHookNameInDev = 'useLayoutEffect';
7111 updateHookTypesDev();
7112 return mountLayoutEffect(create, deps);
7113 },
7114 useMemo: function (create, deps) {
7115 currentHookNameInDev = 'useMemo';
7116 updateHookTypesDev();
7117 var prevDispatcher = ReactCurrentDispatcher.current;
7118 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7119
7120 try {
7121 return mountMemo(create, deps);
7122 } finally {
7123 ReactCurrentDispatcher.current = prevDispatcher;
7124 }
7125 },
7126 useReducer: function (reducer, initialArg, init) {
7127 currentHookNameInDev = 'useReducer';
7128 updateHookTypesDev();
7129 var prevDispatcher = ReactCurrentDispatcher.current;
7130 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7131
7132 try {
7133 return mountReducer(reducer, initialArg, init);
7134 } finally {
7135 ReactCurrentDispatcher.current = prevDispatcher;
7136 }
7137 },
7138 useRef: function (initialValue) {
7139 currentHookNameInDev = 'useRef';
7140 updateHookTypesDev();
7141 return mountRef(initialValue);
7142 },
7143 useState: function (initialState) {
7144 currentHookNameInDev = 'useState';
7145 updateHookTypesDev();
7146 var prevDispatcher = ReactCurrentDispatcher.current;
7147 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7148
7149 try {
7150 return mountState(initialState);
7151 } finally {
7152 ReactCurrentDispatcher.current = prevDispatcher;
7153 }
7154 },
7155 useDebugValue: function (value, formatterFn) {
7156 currentHookNameInDev = 'useDebugValue';
7157 updateHookTypesDev();
7158 return mountDebugValue();
7159 },
7160 useResponder: function (responder, props) {
7161 currentHookNameInDev = 'useResponder';
7162 updateHookTypesDev();
7163 return createDeprecatedResponderListener(responder, props);
7164 },
7165 useDeferredValue: function (value, config) {
7166 currentHookNameInDev = 'useDeferredValue';
7167 updateHookTypesDev();
7168 return mountDeferredValue(value, config);
7169 },
7170 useTransition: function (config) {
7171 currentHookNameInDev = 'useTransition';
7172 updateHookTypesDev();
7173 return mountTransition(config);
7174 }
7175 };
7176 HooksDispatcherOnUpdateInDEV = {
7177 readContext: function (context, observedBits) {
7178 return readContext(context, observedBits);
7179 },
7180 useCallback: function (callback, deps) {
7181 currentHookNameInDev = 'useCallback';
7182 updateHookTypesDev();
7183 return updateCallback(callback, deps);
7184 },
7185 useContext: function (context, observedBits) {
7186 currentHookNameInDev = 'useContext';
7187 updateHookTypesDev();
7188 return readContext(context, observedBits);
7189 },
7190 useEffect: function (create, deps) {
7191 currentHookNameInDev = 'useEffect';
7192 updateHookTypesDev();
7193 return updateEffect(create, deps);
7194 },
7195 useImperativeHandle: function (ref, create, deps) {
7196 currentHookNameInDev = 'useImperativeHandle';
7197 updateHookTypesDev();
7198 return updateImperativeHandle(ref, create, deps);
7199 },
7200 useLayoutEffect: function (create, deps) {
7201 currentHookNameInDev = 'useLayoutEffect';
7202 updateHookTypesDev();
7203 return updateLayoutEffect(create, deps);
7204 },
7205 useMemo: function (create, deps) {
7206 currentHookNameInDev = 'useMemo';
7207 updateHookTypesDev();
7208 var prevDispatcher = ReactCurrentDispatcher.current;
7209 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7210
7211 try {
7212 return updateMemo(create, deps);
7213 } finally {
7214 ReactCurrentDispatcher.current = prevDispatcher;
7215 }
7216 },
7217 useReducer: function (reducer, initialArg, init) {
7218 currentHookNameInDev = 'useReducer';
7219 updateHookTypesDev();
7220 var prevDispatcher = ReactCurrentDispatcher.current;
7221 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7222
7223 try {
7224 return updateReducer(reducer, initialArg, init);
7225 } finally {
7226 ReactCurrentDispatcher.current = prevDispatcher;
7227 }
7228 },
7229 useRef: function (initialValue) {
7230 currentHookNameInDev = 'useRef';
7231 updateHookTypesDev();
7232 return updateRef();
7233 },
7234 useState: function (initialState) {
7235 currentHookNameInDev = 'useState';
7236 updateHookTypesDev();
7237 var prevDispatcher = ReactCurrentDispatcher.current;
7238 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7239
7240 try {
7241 return updateState(initialState);
7242 } finally {
7243 ReactCurrentDispatcher.current = prevDispatcher;
7244 }
7245 },
7246 useDebugValue: function (value, formatterFn) {
7247 currentHookNameInDev = 'useDebugValue';
7248 updateHookTypesDev();
7249 return updateDebugValue();
7250 },
7251 useResponder: function (responder, props) {
7252 currentHookNameInDev = 'useResponder';
7253 updateHookTypesDev();
7254 return createDeprecatedResponderListener(responder, props);
7255 },
7256 useDeferredValue: function (value, config) {
7257 currentHookNameInDev = 'useDeferredValue';
7258 updateHookTypesDev();
7259 return updateDeferredValue(value, config);
7260 },
7261 useTransition: function (config) {
7262 currentHookNameInDev = 'useTransition';
7263 updateHookTypesDev();
7264 return updateTransition(config);
7265 }
7266 };
7267 HooksDispatcherOnRerenderInDEV = {
7268 readContext: function (context, observedBits) {
7269 return readContext(context, observedBits);
7270 },
7271 useCallback: function (callback, deps) {
7272 currentHookNameInDev = 'useCallback';
7273 updateHookTypesDev();
7274 return updateCallback(callback, deps);
7275 },
7276 useContext: function (context, observedBits) {
7277 currentHookNameInDev = 'useContext';
7278 updateHookTypesDev();
7279 return readContext(context, observedBits);
7280 },
7281 useEffect: function (create, deps) {
7282 currentHookNameInDev = 'useEffect';
7283 updateHookTypesDev();
7284 return updateEffect(create, deps);
7285 },
7286 useImperativeHandle: function (ref, create, deps) {
7287 currentHookNameInDev = 'useImperativeHandle';
7288 updateHookTypesDev();
7289 return updateImperativeHandle(ref, create, deps);
7290 },
7291 useLayoutEffect: function (create, deps) {
7292 currentHookNameInDev = 'useLayoutEffect';
7293 updateHookTypesDev();
7294 return updateLayoutEffect(create, deps);
7295 },
7296 useMemo: function (create, deps) {
7297 currentHookNameInDev = 'useMemo';
7298 updateHookTypesDev();
7299 var prevDispatcher = ReactCurrentDispatcher.current;
7300 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
7301
7302 try {
7303 return updateMemo(create, deps);
7304 } finally {
7305 ReactCurrentDispatcher.current = prevDispatcher;
7306 }
7307 },
7308 useReducer: function (reducer, initialArg, init) {
7309 currentHookNameInDev = 'useReducer';
7310 updateHookTypesDev();
7311 var prevDispatcher = ReactCurrentDispatcher.current;
7312 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
7313
7314 try {
7315 return rerenderReducer(reducer, initialArg, init);
7316 } finally {
7317 ReactCurrentDispatcher.current = prevDispatcher;
7318 }
7319 },
7320 useRef: function (initialValue) {
7321 currentHookNameInDev = 'useRef';
7322 updateHookTypesDev();
7323 return updateRef();
7324 },
7325 useState: function (initialState) {
7326 currentHookNameInDev = 'useState';
7327 updateHookTypesDev();
7328 var prevDispatcher = ReactCurrentDispatcher.current;
7329 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
7330
7331 try {
7332 return rerenderState(initialState);
7333 } finally {
7334 ReactCurrentDispatcher.current = prevDispatcher;
7335 }
7336 },
7337 useDebugValue: function (value, formatterFn) {
7338 currentHookNameInDev = 'useDebugValue';
7339 updateHookTypesDev();
7340 return updateDebugValue();
7341 },
7342 useResponder: function (responder, props) {
7343 currentHookNameInDev = 'useResponder';
7344 updateHookTypesDev();
7345 return createDeprecatedResponderListener(responder, props);
7346 },
7347 useDeferredValue: function (value, config) {
7348 currentHookNameInDev = 'useDeferredValue';
7349 updateHookTypesDev();
7350 return rerenderDeferredValue(value, config);
7351 },
7352 useTransition: function (config) {
7353 currentHookNameInDev = 'useTransition';
7354 updateHookTypesDev();
7355 return rerenderTransition(config);
7356 }
7357 };
7358 InvalidNestedHooksDispatcherOnMountInDEV = {
7359 readContext: function (context, observedBits) {
7360 warnInvalidContextAccess();
7361 return readContext(context, observedBits);
7362 },
7363 useCallback: function (callback, deps) {
7364 currentHookNameInDev = 'useCallback';
7365 warnInvalidHookAccess();
7366 mountHookTypesDev();
7367 return mountCallback(callback, deps);
7368 },
7369 useContext: function (context, observedBits) {
7370 currentHookNameInDev = 'useContext';
7371 warnInvalidHookAccess();
7372 mountHookTypesDev();
7373 return readContext(context, observedBits);
7374 },
7375 useEffect: function (create, deps) {
7376 currentHookNameInDev = 'useEffect';
7377 warnInvalidHookAccess();
7378 mountHookTypesDev();
7379 return mountEffect(create, deps);
7380 },
7381 useImperativeHandle: function (ref, create, deps) {
7382 currentHookNameInDev = 'useImperativeHandle';
7383 warnInvalidHookAccess();
7384 mountHookTypesDev();
7385 return mountImperativeHandle(ref, create, deps);
7386 },
7387 useLayoutEffect: function (create, deps) {
7388 currentHookNameInDev = 'useLayoutEffect';
7389 warnInvalidHookAccess();
7390 mountHookTypesDev();
7391 return mountLayoutEffect(create, deps);
7392 },
7393 useMemo: function (create, deps) {
7394 currentHookNameInDev = 'useMemo';
7395 warnInvalidHookAccess();
7396 mountHookTypesDev();
7397 var prevDispatcher = ReactCurrentDispatcher.current;
7398 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7399
7400 try {
7401 return mountMemo(create, deps);
7402 } finally {
7403 ReactCurrentDispatcher.current = prevDispatcher;
7404 }
7405 },
7406 useReducer: function (reducer, initialArg, init) {
7407 currentHookNameInDev = 'useReducer';
7408 warnInvalidHookAccess();
7409 mountHookTypesDev();
7410 var prevDispatcher = ReactCurrentDispatcher.current;
7411 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7412
7413 try {
7414 return mountReducer(reducer, initialArg, init);
7415 } finally {
7416 ReactCurrentDispatcher.current = prevDispatcher;
7417 }
7418 },
7419 useRef: function (initialValue) {
7420 currentHookNameInDev = 'useRef';
7421 warnInvalidHookAccess();
7422 mountHookTypesDev();
7423 return mountRef(initialValue);
7424 },
7425 useState: function (initialState) {
7426 currentHookNameInDev = 'useState';
7427 warnInvalidHookAccess();
7428 mountHookTypesDev();
7429 var prevDispatcher = ReactCurrentDispatcher.current;
7430 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;
7431
7432 try {
7433 return mountState(initialState);
7434 } finally {
7435 ReactCurrentDispatcher.current = prevDispatcher;
7436 }
7437 },
7438 useDebugValue: function (value, formatterFn) {
7439 currentHookNameInDev = 'useDebugValue';
7440 warnInvalidHookAccess();
7441 mountHookTypesDev();
7442 return mountDebugValue();
7443 },
7444 useResponder: function (responder, props) {
7445 currentHookNameInDev = 'useResponder';
7446 warnInvalidHookAccess();
7447 mountHookTypesDev();
7448 return createDeprecatedResponderListener(responder, props);
7449 },
7450 useDeferredValue: function (value, config) {
7451 currentHookNameInDev = 'useDeferredValue';
7452 warnInvalidHookAccess();
7453 mountHookTypesDev();
7454 return mountDeferredValue(value, config);
7455 },
7456 useTransition: function (config) {
7457 currentHookNameInDev = 'useTransition';
7458 warnInvalidHookAccess();
7459 mountHookTypesDev();
7460 return mountTransition(config);
7461 }
7462 };
7463 InvalidNestedHooksDispatcherOnUpdateInDEV = {
7464 readContext: function (context, observedBits) {
7465 warnInvalidContextAccess();
7466 return readContext(context, observedBits);
7467 },
7468 useCallback: function (callback, deps) {
7469 currentHookNameInDev = 'useCallback';
7470 warnInvalidHookAccess();
7471 updateHookTypesDev();
7472 return updateCallback(callback, deps);
7473 },
7474 useContext: function (context, observedBits) {
7475 currentHookNameInDev = 'useContext';
7476 warnInvalidHookAccess();
7477 updateHookTypesDev();
7478 return readContext(context, observedBits);
7479 },
7480 useEffect: function (create, deps) {
7481 currentHookNameInDev = 'useEffect';
7482 warnInvalidHookAccess();
7483 updateHookTypesDev();
7484 return updateEffect(create, deps);
7485 },
7486 useImperativeHandle: function (ref, create, deps) {
7487 currentHookNameInDev = 'useImperativeHandle';
7488 warnInvalidHookAccess();
7489 updateHookTypesDev();
7490 return updateImperativeHandle(ref, create, deps);
7491 },
7492 useLayoutEffect: function (create, deps) {
7493 currentHookNameInDev = 'useLayoutEffect';
7494 warnInvalidHookAccess();
7495 updateHookTypesDev();
7496 return updateLayoutEffect(create, deps);
7497 },
7498 useMemo: function (create, deps) {
7499 currentHookNameInDev = 'useMemo';
7500 warnInvalidHookAccess();
7501 updateHookTypesDev();
7502 var prevDispatcher = ReactCurrentDispatcher.current;
7503 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7504
7505 try {
7506 return updateMemo(create, deps);
7507 } finally {
7508 ReactCurrentDispatcher.current = prevDispatcher;
7509 }
7510 },
7511 useReducer: function (reducer, initialArg, init) {
7512 currentHookNameInDev = 'useReducer';
7513 warnInvalidHookAccess();
7514 updateHookTypesDev();
7515 var prevDispatcher = ReactCurrentDispatcher.current;
7516 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7517
7518 try {
7519 return updateReducer(reducer, initialArg, init);
7520 } finally {
7521 ReactCurrentDispatcher.current = prevDispatcher;
7522 }
7523 },
7524 useRef: function (initialValue) {
7525 currentHookNameInDev = 'useRef';
7526 warnInvalidHookAccess();
7527 updateHookTypesDev();
7528 return updateRef();
7529 },
7530 useState: function (initialState) {
7531 currentHookNameInDev = 'useState';
7532 warnInvalidHookAccess();
7533 updateHookTypesDev();
7534 var prevDispatcher = ReactCurrentDispatcher.current;
7535 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7536
7537 try {
7538 return updateState(initialState);
7539 } finally {
7540 ReactCurrentDispatcher.current = prevDispatcher;
7541 }
7542 },
7543 useDebugValue: function (value, formatterFn) {
7544 currentHookNameInDev = 'useDebugValue';
7545 warnInvalidHookAccess();
7546 updateHookTypesDev();
7547 return updateDebugValue();
7548 },
7549 useResponder: function (responder, props) {
7550 currentHookNameInDev = 'useResponder';
7551 warnInvalidHookAccess();
7552 updateHookTypesDev();
7553 return createDeprecatedResponderListener(responder, props);
7554 },
7555 useDeferredValue: function (value, config) {
7556 currentHookNameInDev = 'useDeferredValue';
7557 warnInvalidHookAccess();
7558 updateHookTypesDev();
7559 return updateDeferredValue(value, config);
7560 },
7561 useTransition: function (config) {
7562 currentHookNameInDev = 'useTransition';
7563 warnInvalidHookAccess();
7564 updateHookTypesDev();
7565 return updateTransition(config);
7566 }
7567 };
7568 InvalidNestedHooksDispatcherOnRerenderInDEV = {
7569 readContext: function (context, observedBits) {
7570 warnInvalidContextAccess();
7571 return readContext(context, observedBits);
7572 },
7573 useCallback: function (callback, deps) {
7574 currentHookNameInDev = 'useCallback';
7575 warnInvalidHookAccess();
7576 updateHookTypesDev();
7577 return updateCallback(callback, deps);
7578 },
7579 useContext: function (context, observedBits) {
7580 currentHookNameInDev = 'useContext';
7581 warnInvalidHookAccess();
7582 updateHookTypesDev();
7583 return readContext(context, observedBits);
7584 },
7585 useEffect: function (create, deps) {
7586 currentHookNameInDev = 'useEffect';
7587 warnInvalidHookAccess();
7588 updateHookTypesDev();
7589 return updateEffect(create, deps);
7590 },
7591 useImperativeHandle: function (ref, create, deps) {
7592 currentHookNameInDev = 'useImperativeHandle';
7593 warnInvalidHookAccess();
7594 updateHookTypesDev();
7595 return updateImperativeHandle(ref, create, deps);
7596 },
7597 useLayoutEffect: function (create, deps) {
7598 currentHookNameInDev = 'useLayoutEffect';
7599 warnInvalidHookAccess();
7600 updateHookTypesDev();
7601 return updateLayoutEffect(create, deps);
7602 },
7603 useMemo: function (create, deps) {
7604 currentHookNameInDev = 'useMemo';
7605 warnInvalidHookAccess();
7606 updateHookTypesDev();
7607 var prevDispatcher = ReactCurrentDispatcher.current;
7608 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7609
7610 try {
7611 return updateMemo(create, deps);
7612 } finally {
7613 ReactCurrentDispatcher.current = prevDispatcher;
7614 }
7615 },
7616 useReducer: function (reducer, initialArg, init) {
7617 currentHookNameInDev = 'useReducer';
7618 warnInvalidHookAccess();
7619 updateHookTypesDev();
7620 var prevDispatcher = ReactCurrentDispatcher.current;
7621 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7622
7623 try {
7624 return rerenderReducer(reducer, initialArg, init);
7625 } finally {
7626 ReactCurrentDispatcher.current = prevDispatcher;
7627 }
7628 },
7629 useRef: function (initialValue) {
7630 currentHookNameInDev = 'useRef';
7631 warnInvalidHookAccess();
7632 updateHookTypesDev();
7633 return updateRef();
7634 },
7635 useState: function (initialState) {
7636 currentHookNameInDev = 'useState';
7637 warnInvalidHookAccess();
7638 updateHookTypesDev();
7639 var prevDispatcher = ReactCurrentDispatcher.current;
7640 ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7641
7642 try {
7643 return rerenderState(initialState);
7644 } finally {
7645 ReactCurrentDispatcher.current = prevDispatcher;
7646 }
7647 },
7648 useDebugValue: function (value, formatterFn) {
7649 currentHookNameInDev = 'useDebugValue';
7650 warnInvalidHookAccess();
7651 updateHookTypesDev();
7652 return updateDebugValue();
7653 },
7654 useResponder: function (responder, props) {
7655 currentHookNameInDev = 'useResponder';
7656 warnInvalidHookAccess();
7657 updateHookTypesDev();
7658 return createDeprecatedResponderListener(responder, props);
7659 },
7660 useDeferredValue: function (value, config) {
7661 currentHookNameInDev = 'useDeferredValue';
7662 warnInvalidHookAccess();
7663 updateHookTypesDev();
7664 return rerenderDeferredValue(value, config);
7665 },
7666 useTransition: function (config) {
7667 currentHookNameInDev = 'useTransition';
7668 warnInvalidHookAccess();
7669 updateHookTypesDev();
7670 return rerenderTransition(config);
7671 }
7672 };
7673 }
7674
7675 var now$1 = unstable_now;
7676 var commitTime = 0;
7677 var profilerStartTime = -1;
7678
7679 function getCommitTime() {
7680 return commitTime;
7681 }
7682
7683 function recordCommitTime() {
7684
7685 commitTime = now$1();
7686 }
7687
7688 function startProfilerTimer(fiber) {
7689
7690 profilerStartTime = now$1();
7691
7692 if (fiber.actualStartTime < 0) {
7693 fiber.actualStartTime = now$1();
7694 }
7695 }
7696
7697 function stopProfilerTimerIfRunning(fiber) {
7698
7699 profilerStartTime = -1;
7700 }
7701
7702 function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
7703
7704 if (profilerStartTime >= 0) {
7705 var elapsedTime = now$1() - profilerStartTime;
7706 fiber.actualDuration += elapsedTime;
7707
7708 if (overrideBaseTime) {
7709 fiber.selfBaseDuration = elapsedTime;
7710 }
7711
7712 profilerStartTime = -1;
7713 }
7714 }
7715
7716 function enterHydrationState(fiber) {
7717 {
7718 return false;
7719 }
7720 }
7721
7722 function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
7723 {
7724 {
7725 {
7726 throw Error( "Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." );
7727 }
7728 }
7729 }
7730 }
7731
7732 function prepareToHydrateHostTextInstance(fiber) {
7733 {
7734 {
7735 {
7736 throw Error( "Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue." );
7737 }
7738 }
7739 }
7740 var shouldUpdate = hydrateTextInstance();
7741 }
7742
7743 function popHydrationState(fiber) {
7744 {
7745 return false;
7746 }
7747 }
7748
7749 var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
7750 var didReceiveUpdate = false;
7751 var didWarnAboutBadClass;
7752 var didWarnAboutModulePatternComponent;
7753 var didWarnAboutContextTypeOnFunctionComponent;
7754 var didWarnAboutGetDerivedStateOnFunctionComponent;
7755 var didWarnAboutFunctionRefs;
7756 var didWarnAboutReassigningProps;
7757 var didWarnAboutRevealOrder;
7758 var didWarnAboutTailOptions;
7759
7760 {
7761 didWarnAboutBadClass = {};
7762 didWarnAboutModulePatternComponent = {};
7763 didWarnAboutContextTypeOnFunctionComponent = {};
7764 didWarnAboutGetDerivedStateOnFunctionComponent = {};
7765 didWarnAboutFunctionRefs = {};
7766 didWarnAboutReassigningProps = false;
7767 didWarnAboutRevealOrder = {};
7768 didWarnAboutTailOptions = {};
7769 }
7770
7771 function reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime) {
7772 if (current === null) {
7773 // If this is a fresh new component that hasn't been rendered yet, we
7774 // won't update its child set by applying minimal side-effects. Instead,
7775 // we will add them all to the child before it gets rendered. That means
7776 // we can optimize this reconciliation pass by not tracking side-effects.
7777 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7778 } else {
7779 // If the current child is the same as the work in progress, it means that
7780 // we haven't yet started any work on these children. Therefore, we use
7781 // the clone algorithm to create a copy of all the current children.
7782 // If we had any progressed work already, that is invalid at this point so
7783 // let's throw it out.
7784 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
7785 }
7786 }
7787
7788 function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime) {
7789 // This function is fork of reconcileChildren. It's used in cases where we
7790 // want to reconcile without matching against the existing set. This has the
7791 // effect of all current children being unmounted; even if the type and key
7792 // are the same, the old child is unmounted and a new child is created.
7793 //
7794 // To do this, we're going to go through the reconcile algorithm twice. In
7795 // the first pass, we schedule a deletion for all the current children by
7796 // passing null.
7797 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderExpirationTime); // In the second pass, we mount the new children. The trick here is that we
7798 // pass null in place of where we usually pass the current child set. This has
7799 // the effect of remounting all children regardless of whether their
7800 // identities match.
7801
7802 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7803 }
7804
7805 function updateForwardRef(current, workInProgress, Component, nextProps, renderExpirationTime) {
7806 // TODO: current can be non-null here even if the component
7807 // hasn't yet mounted. This happens after the first render suspends.
7808 // We'll need to figure out if this is fine or can cause issues.
7809 {
7810 if (workInProgress.type !== workInProgress.elementType) {
7811 // Lazy component props can't be validated in createElement
7812 // because they're only guaranteed to be resolved here.
7813 var innerPropTypes = Component.propTypes;
7814
7815 if (innerPropTypes) {
7816 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
7817 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7818 }
7819 }
7820 }
7821
7822 var render = Component.render;
7823 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent
7824
7825 var nextChildren;
7826 prepareToReadContext(workInProgress, renderExpirationTime);
7827
7828 {
7829 ReactCurrentOwner$1.current = workInProgress;
7830 setIsRendering(true);
7831 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
7832
7833 if ( workInProgress.mode & StrictMode) {
7834 // Only double-render components with Hooks
7835 if (workInProgress.memoizedState !== null) {
7836 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
7837 }
7838 }
7839
7840 setIsRendering(false);
7841 }
7842
7843 if (current !== null && !didReceiveUpdate) {
7844 bailoutHooks(current, workInProgress, renderExpirationTime);
7845 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7846 } // React DevTools reads this flag.
7847
7848
7849 workInProgress.effectTag |= PerformedWork;
7850 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7851 return workInProgress.child;
7852 }
7853
7854 function updateMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
7855 if (current === null) {
7856 var type = Component.type;
7857
7858 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.
7859 Component.defaultProps === undefined) {
7860 var resolvedType = type;
7861
7862 {
7863 resolvedType = resolveFunctionForHotReloading(type);
7864 } // If this is a plain function component without default props,
7865 // and with only the default shallow comparison, we upgrade it
7866 // to a SimpleMemoComponent to allow fast path updates.
7867
7868
7869 workInProgress.tag = SimpleMemoComponent;
7870 workInProgress.type = resolvedType;
7871
7872 {
7873 validateFunctionComponentInDev(workInProgress, type);
7874 }
7875
7876 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, updateExpirationTime, renderExpirationTime);
7877 }
7878
7879 {
7880 var innerPropTypes = type.propTypes;
7881
7882 if (innerPropTypes) {
7883 // Inner memo component props aren't currently validated in createElement.
7884 // We could move it there, but we'd still need this for lazy code path.
7885 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
7886 'prop', getComponentName(type), getCurrentFiberStackInDev);
7887 }
7888 }
7889
7890 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
7891 child.ref = workInProgress.ref;
7892 child.return = workInProgress;
7893 workInProgress.child = child;
7894 return child;
7895 }
7896
7897 {
7898 var _type = Component.type;
7899 var _innerPropTypes = _type.propTypes;
7900
7901 if (_innerPropTypes) {
7902 // Inner memo component props aren't currently validated in createElement.
7903 // We could move it there, but we'd still need this for lazy code path.
7904 checkPropTypes_1(_innerPropTypes, nextProps, // Resolved props
7905 'prop', getComponentName(_type), getCurrentFiberStackInDev);
7906 }
7907 }
7908
7909 var currentChild = current.child; // This is always exactly one child
7910
7911 if (updateExpirationTime < renderExpirationTime) {
7912 // This will be the props with resolved defaultProps,
7913 // unlike current.memoizedProps which will be the unresolved ones.
7914 var prevProps = currentChild.memoizedProps; // Default to shallow comparison
7915
7916 var compare = Component.compare;
7917 compare = compare !== null ? compare : shallowEqual;
7918
7919 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
7920 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7921 }
7922 } // React DevTools reads this flag.
7923
7924
7925 workInProgress.effectTag |= PerformedWork;
7926 var newChild = createWorkInProgress(currentChild, nextProps);
7927 newChild.ref = workInProgress.ref;
7928 newChild.return = workInProgress;
7929 workInProgress.child = newChild;
7930 return newChild;
7931 }
7932
7933 function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
7934 // TODO: current can be non-null here even if the component
7935 // hasn't yet mounted. This happens when the inner render suspends.
7936 // We'll need to figure out if this is fine or can cause issues.
7937 {
7938 if (workInProgress.type !== workInProgress.elementType) {
7939 // Lazy component props can't be validated in createElement
7940 // because they're only guaranteed to be resolved here.
7941 var outerMemoType = workInProgress.elementType;
7942
7943 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
7944 // We warn when you define propTypes on lazy()
7945 // so let's just skip over it to find memo() outer wrapper.
7946 // Inner props for memo are validated later.
7947 outerMemoType = refineResolvedLazyComponent(outerMemoType);
7948 }
7949
7950 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
7951
7952 if (outerPropTypes) {
7953 checkPropTypes_1(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
7954 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
7955 } // Inner propTypes will be validated in the function component path.
7956
7957 }
7958 }
7959
7960 if (current !== null) {
7961 var prevProps = current.memoizedProps;
7962
7963 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload.
7964 workInProgress.type === current.type )) {
7965 didReceiveUpdate = false;
7966
7967 if (updateExpirationTime < renderExpirationTime) {
7968 // The pending update priority was cleared at the beginning of
7969 // beginWork. We're about to bail out, but there might be additional
7970 // updates at a lower priority. Usually, the priority level of the
7971 // remaining updates is accumlated during the evaluation of the
7972 // component (i.e. when processing the update queue). But since since
7973 // we're bailing out early *without* evaluating the component, we need
7974 // to account for it here, too. Reset to the value of the current fiber.
7975 // NOTE: This only applies to SimpleMemoComponent, not MemoComponent,
7976 // because a MemoComponent fiber does not have hooks or an update queue;
7977 // rather, it wraps around an inner component, which may or may not
7978 // contains hooks.
7979 // TODO: Move the reset at in beginWork out of the common path so that
7980 // this is no longer necessary.
7981 workInProgress.expirationTime = current.expirationTime;
7982 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7983 }
7984 }
7985 }
7986
7987 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime);
7988 }
7989
7990 function updateFragment(current, workInProgress, renderExpirationTime) {
7991 var nextChildren = workInProgress.pendingProps;
7992 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7993 return workInProgress.child;
7994 }
7995
7996 function updateMode(current, workInProgress, renderExpirationTime) {
7997 var nextChildren = workInProgress.pendingProps.children;
7998 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7999 return workInProgress.child;
8000 }
8001
8002 function updateProfiler(current, workInProgress, renderExpirationTime) {
8003 {
8004 workInProgress.effectTag |= Update;
8005 }
8006
8007 var nextProps = workInProgress.pendingProps;
8008 var nextChildren = nextProps.children;
8009 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8010 return workInProgress.child;
8011 }
8012
8013 function markRef(current, workInProgress) {
8014 var ref = workInProgress.ref;
8015
8016 if (current === null && ref !== null || current !== null && current.ref !== ref) {
8017 // Schedule a Ref effect
8018 workInProgress.effectTag |= Ref;
8019 }
8020 }
8021
8022 function updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
8023 {
8024 if (workInProgress.type !== workInProgress.elementType) {
8025 // Lazy component props can't be validated in createElement
8026 // because they're only guaranteed to be resolved here.
8027 var innerPropTypes = Component.propTypes;
8028
8029 if (innerPropTypes) {
8030 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
8031 'prop', getComponentName(Component), getCurrentFiberStackInDev);
8032 }
8033 }
8034 }
8035
8036 var context;
8037
8038 {
8039 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
8040 context = getMaskedContext(workInProgress, unmaskedContext);
8041 }
8042
8043 var nextChildren;
8044 prepareToReadContext(workInProgress, renderExpirationTime);
8045
8046 {
8047 ReactCurrentOwner$1.current = workInProgress;
8048 setIsRendering(true);
8049 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
8050
8051 if ( workInProgress.mode & StrictMode) {
8052 // Only double-render components with Hooks
8053 if (workInProgress.memoizedState !== null) {
8054 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
8055 }
8056 }
8057
8058 setIsRendering(false);
8059 }
8060
8061 if (current !== null && !didReceiveUpdate) {
8062 bailoutHooks(current, workInProgress, renderExpirationTime);
8063 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8064 } // React DevTools reads this flag.
8065
8066
8067 workInProgress.effectTag |= PerformedWork;
8068 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8069 return workInProgress.child;
8070 }
8071
8072 function updateClassComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
8073 {
8074 if (workInProgress.type !== workInProgress.elementType) {
8075 // Lazy component props can't be validated in createElement
8076 // because they're only guaranteed to be resolved here.
8077 var innerPropTypes = Component.propTypes;
8078
8079 if (innerPropTypes) {
8080 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
8081 'prop', getComponentName(Component), getCurrentFiberStackInDev);
8082 }
8083 }
8084 } // Push context providers early to prevent context stack mismatches.
8085 // During mounting we don't know the child context yet as the instance doesn't exist.
8086 // We will invalidate the child context in finishClassComponent() right after rendering.
8087
8088
8089 var hasContext;
8090
8091 if (isContextProvider(Component)) {
8092 hasContext = true;
8093 pushContextProvider(workInProgress);
8094 } else {
8095 hasContext = false;
8096 }
8097
8098 prepareToReadContext(workInProgress, renderExpirationTime);
8099 var instance = workInProgress.stateNode;
8100 var shouldUpdate;
8101
8102 if (instance === null) {
8103 if (current !== null) {
8104 // A class component without an instance only mounts if it suspended
8105 // inside a non-concurrent tree, in an inconsistent state. We want to
8106 // treat it like a new mount, even though an empty version of it already
8107 // committed. Disconnect the alternate pointers.
8108 current.alternate = null;
8109 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
8110
8111 workInProgress.effectTag |= Placement;
8112 } // In the initial pass we might need to construct the instance.
8113
8114
8115 constructClassInstance(workInProgress, Component, nextProps);
8116 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8117 shouldUpdate = true;
8118 } else if (current === null) {
8119 // In a resume, we'll already have an instance we can reuse.
8120 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8121 } else {
8122 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderExpirationTime);
8123 }
8124
8125 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
8126
8127 {
8128 var inst = workInProgress.stateNode;
8129
8130 if (inst.props !== nextProps) {
8131 if (!didWarnAboutReassigningProps) {
8132 error('It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentName(workInProgress.type) || 'a component');
8133 }
8134
8135 didWarnAboutReassigningProps = true;
8136 }
8137 }
8138
8139 return nextUnitOfWork;
8140 }
8141
8142 function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
8143 // Refs should update even if shouldComponentUpdate returns false
8144 markRef(current, workInProgress);
8145 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
8146
8147 if (!shouldUpdate && !didCaptureError) {
8148 // Context providers should defer to sCU for rendering
8149 if (hasContext) {
8150 invalidateContextProvider(workInProgress, Component, false);
8151 }
8152
8153 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8154 }
8155
8156 var instance = workInProgress.stateNode; // Rerender
8157
8158 ReactCurrentOwner$1.current = workInProgress;
8159 var nextChildren;
8160
8161 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
8162 // If we captured an error, but getDerivedStateFromError is not defined,
8163 // unmount all the children. componentDidCatch will schedule an update to
8164 // re-render a fallback. This is temporary until we migrate everyone to
8165 // the new API.
8166 // TODO: Warn in a future release.
8167 nextChildren = null;
8168
8169 {
8170 stopProfilerTimerIfRunning();
8171 }
8172 } else {
8173 {
8174 setIsRendering(true);
8175 nextChildren = instance.render();
8176
8177 if ( workInProgress.mode & StrictMode) {
8178 instance.render();
8179 }
8180
8181 setIsRendering(false);
8182 }
8183 } // React DevTools reads this flag.
8184
8185
8186 workInProgress.effectTag |= PerformedWork;
8187
8188 if (current !== null && didCaptureError) {
8189 // If we're recovering from an error, reconcile without reusing any of
8190 // the existing children. Conceptually, the normal children and the children
8191 // that are shown on error are two different sets, so we shouldn't reuse
8192 // normal children even if their identities match.
8193 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime);
8194 } else {
8195 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8196 } // Memoize state using the values we just used to render.
8197 // TODO: Restructure so we never read values from the instance.
8198
8199
8200 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
8201
8202 if (hasContext) {
8203 invalidateContextProvider(workInProgress, Component, true);
8204 }
8205
8206 return workInProgress.child;
8207 }
8208
8209 function pushHostRootContext(workInProgress) {
8210 var root = workInProgress.stateNode;
8211
8212 if (root.pendingContext) {
8213 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
8214 } else if (root.context) {
8215 // Should always be set
8216 pushTopLevelContextObject(workInProgress, root.context, false);
8217 }
8218
8219 pushHostContainer(workInProgress, root.containerInfo);
8220 }
8221
8222 function updateHostRoot(current, workInProgress, renderExpirationTime) {
8223 pushHostRootContext(workInProgress);
8224 var updateQueue = workInProgress.updateQueue;
8225
8226 if (!(current !== null && updateQueue !== null)) {
8227 {
8228 throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." );
8229 }
8230 }
8231
8232 var nextProps = workInProgress.pendingProps;
8233 var prevState = workInProgress.memoizedState;
8234 var prevChildren = prevState !== null ? prevState.element : null;
8235 cloneUpdateQueue(current, workInProgress);
8236 processUpdateQueue(workInProgress, nextProps, null, renderExpirationTime);
8237 var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property
8238 // being called "element".
8239
8240 var nextChildren = nextState.element;
8241
8242 if (nextChildren === prevChildren) {
8243 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8244 }
8245
8246 var root = workInProgress.stateNode;
8247
8248 if (root.hydrate && enterHydrationState()) {
8249 // If we don't have any current children this might be the first pass.
8250 // We always try to hydrate. If this isn't a hydration pass there won't
8251 // be any children to hydrate which is effectively the same thing as
8252 // not hydrating.
8253 var child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8254 workInProgress.child = child;
8255 var node = child;
8256
8257 while (node) {
8258 // Mark each child as hydrating. This is a fast path to know whether this
8259 // tree is part of a hydrating tree. This is used to determine if a child
8260 // node has fully mounted yet, and for scheduling event replaying.
8261 // Conceptually this is similar to Placement in that a new subtree is
8262 // inserted into the React tree here. It just happens to not need DOM
8263 // mutations because it already exists.
8264 node.effectTag = node.effectTag & ~Placement | Hydrating;
8265 node = node.sibling;
8266 }
8267 } else {
8268 // Otherwise reset hydration state in case we aborted and resumed another
8269 // root.
8270 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8271 }
8272
8273 return workInProgress.child;
8274 }
8275
8276 function updateHostComponent(current, workInProgress, renderExpirationTime) {
8277 pushHostContext(workInProgress);
8278
8279 var type = workInProgress.type;
8280 var nextProps = workInProgress.pendingProps;
8281 var prevProps = current !== null ? current.memoizedProps : null;
8282 var nextChildren = nextProps.children;
8283 var isDirectTextChild = shouldSetTextContent(type, nextProps);
8284
8285 if (isDirectTextChild) {
8286 // We special case a direct text child of a host node. This is a common
8287 // case. We won't handle it as a reified child. We will instead handle
8288 // this in the host environment that also has access to this prop. That
8289 // avoids allocating another HostText fiber and traversing it.
8290 nextChildren = null;
8291 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
8292 // If we're switching from a direct text child to a normal child, or to
8293 // empty, we need to schedule the text content to be reset.
8294 workInProgress.effectTag |= ContentReset;
8295 }
8296
8297 markRef(current, workInProgress); // Check the host config to see if the children are offscreen/hidden.
8298
8299 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree()) {
8300 {
8301 markSpawnedWork(Never);
8302 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
8303
8304
8305 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
8306 return null;
8307 }
8308
8309 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8310 return workInProgress.child;
8311 }
8312
8313 function updateHostText(current, workInProgress) {
8314 // immediately after.
8315
8316
8317 return null;
8318 }
8319
8320 function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
8321 if (_current !== null) {
8322 // A lazy component only mounts if it suspended inside a non-
8323 // concurrent tree, in an inconsistent state. We want to treat it like
8324 // a new mount, even though an empty version of it already committed.
8325 // Disconnect the alternate pointers.
8326 _current.alternate = null;
8327 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
8328
8329 workInProgress.effectTag |= Placement;
8330 }
8331
8332 var props = workInProgress.pendingProps; // We can't start a User Timing measurement with correct label yet.
8333 // Cancel and resume right after we know the tag.
8334
8335 cancelWorkTimer(workInProgress);
8336 var Component = readLazyComponentType(elementType); // Store the unwrapped component in the type.
8337
8338 workInProgress.type = Component;
8339 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
8340 startWorkTimer(workInProgress);
8341 var resolvedProps = resolveDefaultProps(Component, props);
8342 var child;
8343
8344 switch (resolvedTag) {
8345 case FunctionComponent:
8346 {
8347 {
8348 validateFunctionComponentInDev(workInProgress, Component);
8349 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
8350 }
8351
8352 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
8353 return child;
8354 }
8355
8356 case ClassComponent:
8357 {
8358 {
8359 workInProgress.type = Component = resolveClassForHotReloading(Component);
8360 }
8361
8362 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
8363 return child;
8364 }
8365
8366 case ForwardRef:
8367 {
8368 {
8369 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
8370 }
8371
8372 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
8373 return child;
8374 }
8375
8376 case MemoComponent:
8377 {
8378 {
8379 if (workInProgress.type !== workInProgress.elementType) {
8380 var outerPropTypes = Component.propTypes;
8381
8382 if (outerPropTypes) {
8383 checkPropTypes_1(outerPropTypes, resolvedProps, // Resolved for outer only
8384 'prop', getComponentName(Component), getCurrentFiberStackInDev);
8385 }
8386 }
8387 }
8388
8389 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
8390 updateExpirationTime, renderExpirationTime);
8391 return child;
8392 }
8393 }
8394
8395 var hint = '';
8396
8397 {
8398 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
8399 hint = ' Did you wrap a component in React.lazy() more than once?';
8400 }
8401 } // This message intentionally doesn't mention ForwardRef or MemoComponent
8402 // because the fact that it's a separate type of work is an
8403 // implementation detail.
8404
8405
8406 {
8407 {
8408 throw Error( "Element type is invalid. Received a promise that resolves to: " + Component + ". Lazy element type must resolve to a class or function." + hint );
8409 }
8410 }
8411 }
8412
8413 function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
8414 if (_current !== null) {
8415 // An incomplete component only mounts if it suspended inside a non-
8416 // concurrent tree, in an inconsistent state. We want to treat it like
8417 // a new mount, even though an empty version of it already committed.
8418 // Disconnect the alternate pointers.
8419 _current.alternate = null;
8420 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
8421
8422 workInProgress.effectTag |= Placement;
8423 } // Promote the fiber to a class and try rendering again.
8424
8425
8426 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`
8427 // Push context providers early to prevent context stack mismatches.
8428 // During mounting we don't know the child context yet as the instance doesn't exist.
8429 // We will invalidate the child context in finishClassComponent() right after rendering.
8430
8431 var hasContext;
8432
8433 if (isContextProvider(Component)) {
8434 hasContext = true;
8435 pushContextProvider(workInProgress);
8436 } else {
8437 hasContext = false;
8438 }
8439
8440 prepareToReadContext(workInProgress, renderExpirationTime);
8441 constructClassInstance(workInProgress, Component, nextProps);
8442 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8443 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
8444 }
8445
8446 function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
8447 if (_current !== null) {
8448 // An indeterminate component only mounts if it suspended inside a non-
8449 // concurrent tree, in an inconsistent state. We want to treat it like
8450 // a new mount, even though an empty version of it already committed.
8451 // Disconnect the alternate pointers.
8452 _current.alternate = null;
8453 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
8454
8455 workInProgress.effectTag |= Placement;
8456 }
8457
8458 var props = workInProgress.pendingProps;
8459 var context;
8460
8461 {
8462 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
8463 context = getMaskedContext(workInProgress, unmaskedContext);
8464 }
8465
8466 prepareToReadContext(workInProgress, renderExpirationTime);
8467 var value;
8468
8469 {
8470 if (Component.prototype && typeof Component.prototype.render === 'function') {
8471 var componentName = getComponentName(Component) || 'Unknown';
8472
8473 if (!didWarnAboutBadClass[componentName]) {
8474 error("The <%s /> component appears to have a render method, but doesn't extend React.Component. " + 'This is likely to cause errors. Change %s to extend React.Component instead.', componentName, componentName);
8475
8476 didWarnAboutBadClass[componentName] = true;
8477 }
8478 }
8479
8480 if (workInProgress.mode & StrictMode) {
8481 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
8482 }
8483
8484 setIsRendering(true);
8485 ReactCurrentOwner$1.current = workInProgress;
8486 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
8487 setIsRendering(false);
8488 } // React DevTools reads this flag.
8489
8490
8491 workInProgress.effectTag |= PerformedWork;
8492
8493 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
8494 {
8495 var _componentName = getComponentName(Component) || 'Unknown';
8496
8497 if (!didWarnAboutModulePatternComponent[_componentName]) {
8498 error('The <%s /> component appears to be a function component that returns a class instance. ' + 'Change %s to a class that extends React.Component instead. ' + "If you can't use a class try assigning the prototype on the function as a workaround. " + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + 'cannot be called with `new` by React.', _componentName, _componentName, _componentName);
8499
8500 didWarnAboutModulePatternComponent[_componentName] = true;
8501 }
8502 } // Proceed under the assumption that this is a class instance
8503
8504
8505 workInProgress.tag = ClassComponent; // Throw out any hooks that were used.
8506
8507 workInProgress.memoizedState = null;
8508 workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches.
8509 // During mounting we don't know the child context yet as the instance doesn't exist.
8510 // We will invalidate the child context in finishClassComponent() right after rendering.
8511
8512 var hasContext = false;
8513
8514 if (isContextProvider(Component)) {
8515 hasContext = true;
8516 pushContextProvider(workInProgress);
8517 } else {
8518 hasContext = false;
8519 }
8520
8521 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
8522 initializeUpdateQueue(workInProgress);
8523 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
8524
8525 if (typeof getDerivedStateFromProps === 'function') {
8526 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
8527 }
8528
8529 adoptClassInstance(workInProgress, value);
8530 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
8531 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
8532 } else {
8533 // Proceed under the assumption that this is a function component
8534 workInProgress.tag = FunctionComponent;
8535
8536 {
8537
8538 if ( workInProgress.mode & StrictMode) {
8539 // Only double-render components with Hooks
8540 if (workInProgress.memoizedState !== null) {
8541 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
8542 }
8543 }
8544 }
8545
8546 reconcileChildren(null, workInProgress, value, renderExpirationTime);
8547
8548 {
8549 validateFunctionComponentInDev(workInProgress, Component);
8550 }
8551
8552 return workInProgress.child;
8553 }
8554 }
8555
8556 function validateFunctionComponentInDev(workInProgress, Component) {
8557 {
8558 if (Component) {
8559 if (Component.childContextTypes) {
8560 error('%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component');
8561 }
8562 }
8563
8564 if (workInProgress.ref !== null) {
8565 var info = '';
8566 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
8567
8568 if (ownerName) {
8569 info += '\n\nCheck the render method of `' + ownerName + '`.';
8570 }
8571
8572 var warningKey = ownerName || workInProgress._debugID || '';
8573 var debugSource = workInProgress._debugSource;
8574
8575 if (debugSource) {
8576 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
8577 }
8578
8579 if (!didWarnAboutFunctionRefs[warningKey]) {
8580 didWarnAboutFunctionRefs[warningKey] = true;
8581
8582 error('Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
8583 }
8584 }
8585
8586 if (typeof Component.getDerivedStateFromProps === 'function') {
8587 var _componentName2 = getComponentName(Component) || 'Unknown';
8588
8589 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) {
8590 error('%s: Function components do not support getDerivedStateFromProps.', _componentName2);
8591
8592 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true;
8593 }
8594 }
8595
8596 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
8597 var _componentName3 = getComponentName(Component) || 'Unknown';
8598
8599 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) {
8600 error('%s: Function components do not support contextType.', _componentName3);
8601
8602 didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true;
8603 }
8604 }
8605 }
8606 }
8607
8608 var SUSPENDED_MARKER = {
8609 dehydrated: null,
8610 retryTime: NoWork
8611 };
8612
8613 function shouldRemainOnFallback(suspenseContext, current, workInProgress) {
8614 // If the context is telling us that we should show a fallback, and we're not
8615 // already showing content, then we should show the fallback instead.
8616 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && (current === null || current.memoizedState !== null);
8617 }
8618
8619 function updateSuspenseComponent(current, workInProgress, renderExpirationTime) {
8620 var mode = workInProgress.mode;
8621 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
8622
8623 {
8624 if (shouldSuspend(workInProgress)) {
8625 workInProgress.effectTag |= DidCapture;
8626 }
8627 }
8628
8629 var suspenseContext = suspenseStackCursor.current;
8630 var nextDidTimeout = false;
8631 var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect;
8632
8633 if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) {
8634 // Something in this boundary's subtree already suspended. Switch to
8635 // rendering the fallback children.
8636 nextDidTimeout = true;
8637 workInProgress.effectTag &= ~DidCapture;
8638 } else {
8639 // Attempting the main content
8640 if (current === null || current.memoizedState !== null) {
8641 // This is a new mount or this boundary is already showing a fallback state.
8642 // Mark this subtree context as having at least one invisible parent that could
8643 // handle the fallback state.
8644 // Boundaries without fallbacks or should be avoided are not considered since
8645 // they cannot handle preferred fallback states.
8646 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {
8647 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
8648 }
8649 }
8650 }
8651
8652 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
8653 pushSuspenseContext(workInProgress, suspenseContext); // This next part is a bit confusing. If the children timeout, we switch to
8654 // showing the fallback children in place of the "primary" children.
8655 // However, we don't want to delete the primary children because then their
8656 // state will be lost (both the React state and the host state, e.g.
8657 // uncontrolled form inputs). Instead we keep them mounted and hide them.
8658 // Both the fallback children AND the primary children are rendered at the
8659 // same time. Once the primary children are un-suspended, we can delete
8660 // the fallback children — don't need to preserve their state.
8661 //
8662 // The two sets of children are siblings in the host environment, but
8663 // semantically, for purposes of reconciliation, they are two separate sets.
8664 // So we store them using two fragment fibers.
8665 //
8666 // However, we want to avoid allocating extra fibers for every placeholder.
8667 // They're only necessary when the children time out, because that's the
8668 // only time when both sets are mounted.
8669 //
8670 // So, the extra fragment fibers are only used if the children time out.
8671 // Otherwise, we render the primary children directly. This requires some
8672 // custom reconciliation logic to preserve the state of the primary
8673 // children. It's essentially a very basic form of re-parenting.
8674
8675 if (current === null) {
8676 // If we're currently hydrating, try to hydrate this boundary.
8677 // But only if this has a fallback.
8678 if (nextProps.fallback !== undefined) ; // This is the initial mount. This branch is pretty simple because there's
8679 // no previous state that needs to be preserved.
8680
8681
8682 if (nextDidTimeout) {
8683 // Mount separate fragments for primary and fallback children.
8684 var nextFallbackChildren = nextProps.fallback;
8685 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
8686 primaryChildFragment.return = workInProgress;
8687
8688 if ((workInProgress.mode & BlockingMode) === NoMode) {
8689 // Outside of blocking mode, we commit the effects from the
8690 // partially completed, timed-out tree, too.
8691 var progressedState = workInProgress.memoizedState;
8692 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
8693 primaryChildFragment.child = progressedPrimaryChild;
8694 var progressedChild = progressedPrimaryChild;
8695
8696 while (progressedChild !== null) {
8697 progressedChild.return = primaryChildFragment;
8698 progressedChild = progressedChild.sibling;
8699 }
8700 }
8701
8702 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
8703 fallbackChildFragment.return = workInProgress;
8704 primaryChildFragment.sibling = fallbackChildFragment; // Skip the primary children, and continue working on the
8705 // fallback children.
8706
8707 workInProgress.memoizedState = SUSPENDED_MARKER;
8708 workInProgress.child = primaryChildFragment;
8709 return fallbackChildFragment;
8710 } else {
8711 // Mount the primary children without an intermediate fragment fiber.
8712 var nextPrimaryChildren = nextProps.children;
8713 workInProgress.memoizedState = null;
8714 return workInProgress.child = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
8715 }
8716 } else {
8717 // This is an update. This branch is more complicated because we need to
8718 // ensure the state of the primary children is preserved.
8719 var prevState = current.memoizedState;
8720
8721 if (prevState !== null) {
8722 // wrapped in a fragment fiber.
8723
8724
8725 var currentPrimaryChildFragment = current.child;
8726 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
8727
8728 if (nextDidTimeout) {
8729 // Still timed out. Reuse the current primary children by cloning
8730 // its fragment. We're going to skip over these entirely.
8731 var _nextFallbackChildren2 = nextProps.fallback;
8732
8733 var _primaryChildFragment2 = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps);
8734
8735 _primaryChildFragment2.return = workInProgress;
8736
8737 if ((workInProgress.mode & BlockingMode) === NoMode) {
8738 // Outside of blocking mode, we commit the effects from the
8739 // partially completed, timed-out tree, too.
8740 var _progressedState = workInProgress.memoizedState;
8741
8742 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
8743
8744 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
8745 _primaryChildFragment2.child = _progressedPrimaryChild;
8746 var _progressedChild2 = _progressedPrimaryChild;
8747
8748 while (_progressedChild2 !== null) {
8749 _progressedChild2.return = _primaryChildFragment2;
8750 _progressedChild2 = _progressedChild2.sibling;
8751 }
8752 }
8753 } // Because primaryChildFragment is a new fiber that we're inserting as the
8754 // parent of a new tree, we need to set its treeBaseDuration.
8755
8756
8757 if ( workInProgress.mode & ProfileMode) {
8758 // treeBaseDuration is the sum of all the child tree base durations.
8759 var _treeBaseDuration = 0;
8760 var _hiddenChild = _primaryChildFragment2.child;
8761
8762 while (_hiddenChild !== null) {
8763 _treeBaseDuration += _hiddenChild.treeBaseDuration;
8764 _hiddenChild = _hiddenChild.sibling;
8765 }
8766
8767 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
8768 } // Clone the fallback child fragment, too. These we'll continue
8769 // working on.
8770
8771
8772 var _fallbackChildFragment2 = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren2);
8773
8774 _fallbackChildFragment2.return = workInProgress;
8775 _primaryChildFragment2.sibling = _fallbackChildFragment2;
8776 _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
8777 // fallback children.
8778
8779 workInProgress.memoizedState = SUSPENDED_MARKER;
8780 workInProgress.child = _primaryChildFragment2;
8781 return _fallbackChildFragment2;
8782 } else {
8783 // No longer suspended. Switch back to showing the primary children,
8784 // and remove the intermediate fragment fiber.
8785 var _nextPrimaryChildren = nextProps.children;
8786 var currentPrimaryChild = currentPrimaryChildFragment.child;
8787 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime); // If this render doesn't suspend, we need to delete the fallback
8788 // children. Wait until the complete phase, after we've confirmed the
8789 // fallback is no longer needed.
8790 // TODO: Would it be better to store the fallback fragment on
8791 // the stateNode?
8792 // Continue rendering the children, like we normally do.
8793
8794 workInProgress.memoizedState = null;
8795 return workInProgress.child = primaryChild;
8796 }
8797 } else {
8798 // The current tree has not already timed out. That means the primary
8799 // children are not wrapped in a fragment fiber.
8800 var _currentPrimaryChild = current.child;
8801
8802 if (nextDidTimeout) {
8803 // Timed out. Wrap the children in a fragment fiber to keep them
8804 // separate from the fallback children.
8805 var _nextFallbackChildren3 = nextProps.fallback;
8806
8807 var _primaryChildFragment3 = createFiberFromFragment( // It shouldn't matter what the pending props are because we aren't
8808 // going to render this fragment.
8809 null, mode, NoWork, null);
8810
8811 _primaryChildFragment3.return = workInProgress;
8812 _primaryChildFragment3.child = _currentPrimaryChild;
8813
8814 if (_currentPrimaryChild !== null) {
8815 _currentPrimaryChild.return = _primaryChildFragment3;
8816 } // Even though we're creating a new fiber, there are no new children,
8817 // because we're reusing an already mounted tree. So we don't need to
8818 // schedule a placement.
8819 // primaryChildFragment.effectTag |= Placement;
8820
8821
8822 if ((workInProgress.mode & BlockingMode) === NoMode) {
8823 // Outside of blocking mode, we commit the effects from the
8824 // partially completed, timed-out tree, too.
8825 var _progressedState2 = workInProgress.memoizedState;
8826
8827 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
8828
8829 _primaryChildFragment3.child = _progressedPrimaryChild2;
8830 var _progressedChild3 = _progressedPrimaryChild2;
8831
8832 while (_progressedChild3 !== null) {
8833 _progressedChild3.return = _primaryChildFragment3;
8834 _progressedChild3 = _progressedChild3.sibling;
8835 }
8836 } // Because primaryChildFragment is a new fiber that we're inserting as the
8837 // parent of a new tree, we need to set its treeBaseDuration.
8838
8839
8840 if ( workInProgress.mode & ProfileMode) {
8841 // treeBaseDuration is the sum of all the child tree base durations.
8842 var _treeBaseDuration2 = 0;
8843 var _hiddenChild2 = _primaryChildFragment3.child;
8844
8845 while (_hiddenChild2 !== null) {
8846 _treeBaseDuration2 += _hiddenChild2.treeBaseDuration;
8847 _hiddenChild2 = _hiddenChild2.sibling;
8848 }
8849
8850 _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2;
8851 } // Create a fragment from the fallback children, too.
8852
8853
8854 var _fallbackChildFragment3 = createFiberFromFragment(_nextFallbackChildren3, mode, renderExpirationTime, null);
8855
8856 _fallbackChildFragment3.return = workInProgress;
8857 _primaryChildFragment3.sibling = _fallbackChildFragment3;
8858 _fallbackChildFragment3.effectTag |= Placement;
8859 _primaryChildFragment3.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
8860 // fallback children.
8861
8862 workInProgress.memoizedState = SUSPENDED_MARKER;
8863 workInProgress.child = _primaryChildFragment3;
8864 return _fallbackChildFragment3;
8865 } else {
8866 // Still haven't timed out. Continue rendering the children, like we
8867 // normally do.
8868 workInProgress.memoizedState = null;
8869 var _nextPrimaryChildren2 = nextProps.children;
8870 return workInProgress.child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
8871 }
8872 }
8873 }
8874 }
8875
8876 function scheduleWorkOnFiber(fiber, renderExpirationTime) {
8877 if (fiber.expirationTime < renderExpirationTime) {
8878 fiber.expirationTime = renderExpirationTime;
8879 }
8880
8881 var alternate = fiber.alternate;
8882
8883 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
8884 alternate.expirationTime = renderExpirationTime;
8885 }
8886
8887 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
8888 }
8889
8890 function propagateSuspenseContextChange(workInProgress, firstChild, renderExpirationTime) {
8891 // Mark any Suspense boundaries with fallbacks as having work to do.
8892 // If they were previously forced into fallbacks, they may now be able
8893 // to unblock.
8894 var node = firstChild;
8895
8896 while (node !== null) {
8897 if (node.tag === SuspenseComponent) {
8898 var state = node.memoizedState;
8899
8900 if (state !== null) {
8901 scheduleWorkOnFiber(node, renderExpirationTime);
8902 }
8903 } else if (node.tag === SuspenseListComponent) {
8904 // If the tail is hidden there might not be an Suspense boundaries
8905 // to schedule work on. In this case we have to schedule it on the
8906 // list itself.
8907 // We don't have to traverse to the children of the list since
8908 // the list will propagate the change when it rerenders.
8909 scheduleWorkOnFiber(node, renderExpirationTime);
8910 } else if (node.child !== null) {
8911 node.child.return = node;
8912 node = node.child;
8913 continue;
8914 }
8915
8916 if (node === workInProgress) {
8917 return;
8918 }
8919
8920 while (node.sibling === null) {
8921 if (node.return === null || node.return === workInProgress) {
8922 return;
8923 }
8924
8925 node = node.return;
8926 }
8927
8928 node.sibling.return = node.return;
8929 node = node.sibling;
8930 }
8931 }
8932
8933 function findLastContentRow(firstChild) {
8934 // This is going to find the last row among these children that is already
8935 // showing content on the screen, as opposed to being in fallback state or
8936 // new. If a row has multiple Suspense boundaries, any of them being in the
8937 // fallback state, counts as the whole row being in a fallback state.
8938 // Note that the "rows" will be workInProgress, but any nested children
8939 // will still be current since we haven't rendered them yet. The mounted
8940 // order may not be the same as the new order. We use the new order.
8941 var row = firstChild;
8942 var lastContentRow = null;
8943
8944 while (row !== null) {
8945 var currentRow = row.alternate; // New rows can't be content rows.
8946
8947 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
8948 lastContentRow = row;
8949 }
8950
8951 row = row.sibling;
8952 }
8953
8954 return lastContentRow;
8955 }
8956
8957 function validateRevealOrder(revealOrder) {
8958 {
8959 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
8960 didWarnAboutRevealOrder[revealOrder] = true;
8961
8962 if (typeof revealOrder === 'string') {
8963 switch (revealOrder.toLowerCase()) {
8964 case 'together':
8965 case 'forwards':
8966 case 'backwards':
8967 {
8968 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
8969
8970 break;
8971 }
8972
8973 case 'forward':
8974 case 'backward':
8975 {
8976 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase());
8977
8978 break;
8979 }
8980
8981 default:
8982 error('"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
8983
8984 break;
8985 }
8986 } else {
8987 error('%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
8988 }
8989 }
8990 }
8991 }
8992
8993 function validateTailOptions(tailMode, revealOrder) {
8994 {
8995 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
8996 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
8997 didWarnAboutTailOptions[tailMode] = true;
8998
8999 error('"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
9000 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
9001 didWarnAboutTailOptions[tailMode] = true;
9002
9003 error('<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
9004 }
9005 }
9006 }
9007 }
9008
9009 function validateSuspenseListNestedChild(childSlot, index) {
9010 {
9011 var isArray = Array.isArray(childSlot);
9012 var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function';
9013
9014 if (isArray || isIterable) {
9015 var type = isArray ? 'array' : 'iterable';
9016
9017 error('A nested %s was passed to row #%s in <SuspenseList />. Wrap it in ' + 'an additional SuspenseList to configure its revealOrder: ' + '<SuspenseList revealOrder=...> ... ' + '<SuspenseList revealOrder=...>{%s}</SuspenseList> ... ' + '</SuspenseList>', type, index, type);
9018
9019 return false;
9020 }
9021 }
9022
9023 return true;
9024 }
9025
9026 function validateSuspenseListChildren(children, revealOrder) {
9027 {
9028 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
9029 if (Array.isArray(children)) {
9030 for (var i = 0; i < children.length; i++) {
9031 if (!validateSuspenseListNestedChild(children[i], i)) {
9032 return;
9033 }
9034 }
9035 } else {
9036 var iteratorFn = getIteratorFn(children);
9037
9038 if (typeof iteratorFn === 'function') {
9039 var childrenIterator = iteratorFn.call(children);
9040
9041 if (childrenIterator) {
9042 var step = childrenIterator.next();
9043 var _i = 0;
9044
9045 for (; !step.done; step = childrenIterator.next()) {
9046 if (!validateSuspenseListNestedChild(step.value, _i)) {
9047 return;
9048 }
9049
9050 _i++;
9051 }
9052 }
9053 } else {
9054 error('A single row was passed to a <SuspenseList revealOrder="%s" />. ' + 'This is not useful since it needs multiple rows. ' + 'Did you mean to pass multiple children or an array?', revealOrder);
9055 }
9056 }
9057 }
9058 }
9059 }
9060
9061 function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode, lastEffectBeforeRendering) {
9062 var renderState = workInProgress.memoizedState;
9063
9064 if (renderState === null) {
9065 workInProgress.memoizedState = {
9066 isBackwards: isBackwards,
9067 rendering: null,
9068 renderingStartTime: 0,
9069 last: lastContentRow,
9070 tail: tail,
9071 tailExpiration: 0,
9072 tailMode: tailMode,
9073 lastEffect: lastEffectBeforeRendering
9074 };
9075 } else {
9076 // We can reuse the existing object from previous renders.
9077 renderState.isBackwards = isBackwards;
9078 renderState.rendering = null;
9079 renderState.renderingStartTime = 0;
9080 renderState.last = lastContentRow;
9081 renderState.tail = tail;
9082 renderState.tailExpiration = 0;
9083 renderState.tailMode = tailMode;
9084 renderState.lastEffect = lastEffectBeforeRendering;
9085 }
9086 } // This can end up rendering this component multiple passes.
9087 // The first pass splits the children fibers into two sets. A head and tail.
9088 // We first render the head. If anything is in fallback state, we do another
9089 // pass through beginWork to rerender all children (including the tail) with
9090 // the force suspend context. If the first render didn't have anything in
9091 // in fallback state. Then we render each row in the tail one-by-one.
9092 // That happens in the completeWork phase without going back to beginWork.
9093
9094
9095 function updateSuspenseListComponent(current, workInProgress, renderExpirationTime) {
9096 var nextProps = workInProgress.pendingProps;
9097 var revealOrder = nextProps.revealOrder;
9098 var tailMode = nextProps.tail;
9099 var newChildren = nextProps.children;
9100 validateRevealOrder(revealOrder);
9101 validateTailOptions(tailMode, revealOrder);
9102 validateSuspenseListChildren(newChildren, revealOrder);
9103 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
9104 var suspenseContext = suspenseStackCursor.current;
9105 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
9106
9107 if (shouldForceFallback) {
9108 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
9109 workInProgress.effectTag |= DidCapture;
9110 } else {
9111 var didSuspendBefore = current !== null && (current.effectTag & DidCapture) !== NoEffect;
9112
9113 if (didSuspendBefore) {
9114 // If we previously forced a fallback, we need to schedule work
9115 // on any nested boundaries to let them know to try to render
9116 // again. This is the same as context updating.
9117 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderExpirationTime);
9118 }
9119
9120 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
9121 }
9122
9123 pushSuspenseContext(workInProgress, suspenseContext);
9124
9125 if ((workInProgress.mode & BlockingMode) === NoMode) {
9126 // Outside of blocking mode, SuspenseList doesn't work so we just
9127 // use make it a noop by treating it as the default revealOrder.
9128 workInProgress.memoizedState = null;
9129 } else {
9130 switch (revealOrder) {
9131 case 'forwards':
9132 {
9133 var lastContentRow = findLastContentRow(workInProgress.child);
9134 var tail;
9135
9136 if (lastContentRow === null) {
9137 // The whole list is part of the tail.
9138 // TODO: We could fast path by just rendering the tail now.
9139 tail = workInProgress.child;
9140 workInProgress.child = null;
9141 } else {
9142 // Disconnect the tail rows after the content row.
9143 // We're going to render them separately later.
9144 tail = lastContentRow.sibling;
9145 lastContentRow.sibling = null;
9146 }
9147
9148 initSuspenseListRenderState(workInProgress, false, // isBackwards
9149 tail, lastContentRow, tailMode, workInProgress.lastEffect);
9150 break;
9151 }
9152
9153 case 'backwards':
9154 {
9155 // We're going to find the first row that has existing content.
9156 // At the same time we're going to reverse the list of everything
9157 // we pass in the meantime. That's going to be our tail in reverse
9158 // order.
9159 var _tail = null;
9160 var row = workInProgress.child;
9161 workInProgress.child = null;
9162
9163 while (row !== null) {
9164 var currentRow = row.alternate; // New rows can't be content rows.
9165
9166 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
9167 // This is the beginning of the main content.
9168 workInProgress.child = row;
9169 break;
9170 }
9171
9172 var nextRow = row.sibling;
9173 row.sibling = _tail;
9174 _tail = row;
9175 row = nextRow;
9176 } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
9177
9178
9179 initSuspenseListRenderState(workInProgress, true, // isBackwards
9180 _tail, null, // last
9181 tailMode, workInProgress.lastEffect);
9182 break;
9183 }
9184
9185 case 'together':
9186 {
9187 initSuspenseListRenderState(workInProgress, false, // isBackwards
9188 null, // tail
9189 null, // last
9190 undefined, workInProgress.lastEffect);
9191 break;
9192 }
9193
9194 default:
9195 {
9196 // The default reveal order is the same as not having
9197 // a boundary.
9198 workInProgress.memoizedState = null;
9199 }
9200 }
9201 }
9202
9203 return workInProgress.child;
9204 }
9205
9206 function updatePortalComponent(current, workInProgress, renderExpirationTime) {
9207 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
9208 var nextChildren = workInProgress.pendingProps;
9209
9210 if (current === null) {
9211 // Portals are special because we don't append the children during mount
9212 // but at commit. Therefore we need to track insertions which the normal
9213 // flow doesn't do during mount. This doesn't happen at the root because
9214 // the root always starts with a "current" with a null child.
9215 // TODO: Consider unifying this with how the root works.
9216 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
9217 } else {
9218 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
9219 }
9220
9221 return workInProgress.child;
9222 }
9223
9224 function updateContextProvider(current, workInProgress, renderExpirationTime) {
9225 var providerType = workInProgress.type;
9226 var context = providerType._context;
9227 var newProps = workInProgress.pendingProps;
9228 var oldProps = workInProgress.memoizedProps;
9229 var newValue = newProps.value;
9230
9231 {
9232 var providerPropTypes = workInProgress.type.propTypes;
9233
9234 if (providerPropTypes) {
9235 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
9236 }
9237 }
9238
9239 pushProvider(workInProgress, newValue);
9240
9241 if (oldProps !== null) {
9242 var oldValue = oldProps.value;
9243 var changedBits = calculateChangedBits(context, newValue, oldValue);
9244
9245 if (changedBits === 0) {
9246 // No change. Bailout early if children are the same.
9247 if (oldProps.children === newProps.children && !hasContextChanged()) {
9248 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
9249 }
9250 } else {
9251 // The context value changed. Search for matching consumers and schedule
9252 // them to update.
9253 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
9254 }
9255 }
9256
9257 var newChildren = newProps.children;
9258 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
9259 return workInProgress.child;
9260 }
9261
9262 var hasWarnedAboutUsingContextAsConsumer = false;
9263
9264 function updateContextConsumer(current, workInProgress, renderExpirationTime) {
9265 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In
9266 // DEV mode, we create a separate object for Context.Consumer that acts
9267 // like a proxy to Context. This proxy object adds unnecessary code in PROD
9268 // so we use the old behaviour (Context.Consumer references Context) to
9269 // reduce size and overhead. The separate object references context via
9270 // a property called "_context", which also gives us the ability to check
9271 // in DEV mode if this property exists or not and warn if it does not.
9272
9273 {
9274 if (context._context === undefined) {
9275 // This may be because it's a Context (rather than a Consumer).
9276 // Or it may be because it's older React where they're the same thing.
9277 // We only want to warn if we're sure it's a new React.
9278 if (context !== context.Consumer) {
9279 if (!hasWarnedAboutUsingContextAsConsumer) {
9280 hasWarnedAboutUsingContextAsConsumer = true;
9281
9282 error('Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
9283 }
9284 }
9285 } else {
9286 context = context._context;
9287 }
9288 }
9289
9290 var newProps = workInProgress.pendingProps;
9291 var render = newProps.children;
9292
9293 {
9294 if (typeof render !== 'function') {
9295 error('A context consumer was rendered with multiple children, or a child ' + "that isn't a function. A context consumer expects a single child " + 'that is a function. If you did pass a function, make sure there ' + 'is no trailing or leading whitespace around it.');
9296 }
9297 }
9298
9299 prepareToReadContext(workInProgress, renderExpirationTime);
9300 var newValue = readContext(context, newProps.unstable_observedBits);
9301 var newChildren;
9302
9303 {
9304 ReactCurrentOwner$1.current = workInProgress;
9305 setIsRendering(true);
9306 newChildren = render(newValue);
9307 setIsRendering(false);
9308 } // React DevTools reads this flag.
9309
9310
9311 workInProgress.effectTag |= PerformedWork;
9312 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
9313 return workInProgress.child;
9314 }
9315
9316 function markWorkInProgressReceivedUpdate() {
9317 didReceiveUpdate = true;
9318 }
9319
9320 function bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime) {
9321 cancelWorkTimer(workInProgress);
9322
9323 if (current !== null) {
9324 // Reuse previous dependencies
9325 workInProgress.dependencies = current.dependencies;
9326 }
9327
9328 {
9329 // Don't update "base" render times for bailouts.
9330 stopProfilerTimerIfRunning();
9331 }
9332
9333 var updateExpirationTime = workInProgress.expirationTime;
9334
9335 if (updateExpirationTime !== NoWork) {
9336 markUnprocessedUpdateTime(updateExpirationTime);
9337 } // Check if the children have any pending work.
9338
9339
9340 var childExpirationTime = workInProgress.childExpirationTime;
9341
9342 if (childExpirationTime < renderExpirationTime) {
9343 // The children don't have any work either. We can skip them.
9344 // TODO: Once we add back resuming, we should check if the children are
9345 // a work-in-progress set. If so, we need to transfer their effects.
9346 return null;
9347 } else {
9348 // This fiber doesn't have work, but its subtree does. Clone the child
9349 // fibers and continue.
9350 cloneChildFibers(current, workInProgress);
9351 return workInProgress.child;
9352 }
9353 }
9354
9355 function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
9356 {
9357 var returnFiber = oldWorkInProgress.return;
9358
9359 if (returnFiber === null) {
9360 throw new Error('Cannot swap the root fiber.');
9361 } // Disconnect from the old current.
9362 // It will get deleted.
9363
9364
9365 current.alternate = null;
9366 oldWorkInProgress.alternate = null; // Connect to the new tree.
9367
9368 newWorkInProgress.index = oldWorkInProgress.index;
9369 newWorkInProgress.sibling = oldWorkInProgress.sibling;
9370 newWorkInProgress.return = oldWorkInProgress.return;
9371 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.
9372
9373 if (oldWorkInProgress === returnFiber.child) {
9374 returnFiber.child = newWorkInProgress;
9375 } else {
9376 var prevSibling = returnFiber.child;
9377
9378 if (prevSibling === null) {
9379 throw new Error('Expected parent to have a child.');
9380 }
9381
9382 while (prevSibling.sibling !== oldWorkInProgress) {
9383 prevSibling = prevSibling.sibling;
9384
9385 if (prevSibling === null) {
9386 throw new Error('Expected to find the previous sibling.');
9387 }
9388 }
9389
9390 prevSibling.sibling = newWorkInProgress;
9391 } // Delete the old fiber and place the new one.
9392 // Since the old fiber is disconnected, we have to schedule it manually.
9393
9394
9395 var last = returnFiber.lastEffect;
9396
9397 if (last !== null) {
9398 last.nextEffect = current;
9399 returnFiber.lastEffect = current;
9400 } else {
9401 returnFiber.firstEffect = returnFiber.lastEffect = current;
9402 }
9403
9404 current.nextEffect = null;
9405 current.effectTag = Deletion;
9406 newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber.
9407
9408 return newWorkInProgress;
9409 }
9410 }
9411
9412 function beginWork(current, workInProgress, renderExpirationTime) {
9413 var updateExpirationTime = workInProgress.expirationTime;
9414
9415 {
9416 if (workInProgress._debugNeedsRemount && current !== null) {
9417 // This will restart the begin phase with a new fiber.
9418 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.expirationTime));
9419 }
9420 }
9421
9422 if (current !== null) {
9423 var oldProps = current.memoizedProps;
9424 var newProps = workInProgress.pendingProps;
9425
9426 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
9427 workInProgress.type !== current.type )) {
9428 // If props or context changed, mark the fiber as having performed work.
9429 // This may be unset if the props are determined to be equal later (memo).
9430 didReceiveUpdate = true;
9431 } else if (updateExpirationTime < renderExpirationTime) {
9432 didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering
9433 // the begin phase. There's still some bookkeeping we that needs to be done
9434 // in this optimized path, mostly pushing stuff onto the stack.
9435
9436 switch (workInProgress.tag) {
9437 case HostRoot:
9438 pushHostRootContext(workInProgress);
9439 break;
9440
9441 case HostComponent:
9442 pushHostContext(workInProgress);
9443
9444 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(workInProgress.type)) {
9445 {
9446 markSpawnedWork(Never);
9447 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
9448
9449
9450 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
9451 return null;
9452 }
9453
9454 break;
9455
9456 case ClassComponent:
9457 {
9458 var Component = workInProgress.type;
9459
9460 if (isContextProvider(Component)) {
9461 pushContextProvider(workInProgress);
9462 }
9463
9464 break;
9465 }
9466
9467 case HostPortal:
9468 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
9469 break;
9470
9471 case ContextProvider:
9472 {
9473 var newValue = workInProgress.memoizedProps.value;
9474 pushProvider(workInProgress, newValue);
9475 break;
9476 }
9477
9478 case Profiler:
9479 {
9480 // Profiler should only call onRender when one of its descendants actually rendered.
9481 var hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
9482
9483 if (hasChildWork) {
9484 workInProgress.effectTag |= Update;
9485 }
9486 }
9487
9488 break;
9489
9490 case SuspenseComponent:
9491 {
9492 var state = workInProgress.memoizedState;
9493
9494 if (state !== null) {
9495 // whether to retry the primary children, or to skip over it and
9496 // go straight to the fallback. Check the priority of the primary
9497 // child fragment.
9498
9499
9500 var primaryChildFragment = workInProgress.child;
9501 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
9502
9503 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
9504 // The primary children have pending work. Use the normal path
9505 // to attempt to render the primary children again.
9506 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
9507 } else {
9508 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient
9509 // priority. Bailout.
9510
9511 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
9512
9513 if (child !== null) {
9514 // The fallback children have pending work. Skip over the
9515 // primary children and work on the fallback.
9516 return child.sibling;
9517 } else {
9518 return null;
9519 }
9520 }
9521 } else {
9522 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
9523 }
9524
9525 break;
9526 }
9527
9528 case SuspenseListComponent:
9529 {
9530 var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect;
9531
9532 var _hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
9533
9534 if (didSuspendBefore) {
9535 if (_hasChildWork) {
9536 // If something was in fallback state last time, and we have all the
9537 // same children then we're still in progressive loading state.
9538 // Something might get unblocked by state updates or retries in the
9539 // tree which will affect the tail. So we need to use the normal
9540 // path to compute the correct tail.
9541 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
9542 } // If none of the children had any work, that means that none of
9543 // them got retried so they'll still be blocked in the same way
9544 // as before. We can fast bail out.
9545
9546
9547 workInProgress.effectTag |= DidCapture;
9548 } // If nothing suspended before and we're rendering the same children,
9549 // then the tail doesn't matter. Anything new that suspends will work
9550 // in the "together" mode, so we can continue from the state we had.
9551
9552
9553 var renderState = workInProgress.memoizedState;
9554
9555 if (renderState !== null) {
9556 // Reset to the "together" mode in case we've started a different
9557 // update in the past but didn't complete it.
9558 renderState.rendering = null;
9559 renderState.tail = null;
9560 }
9561
9562 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
9563
9564 if (_hasChildWork) {
9565 break;
9566 } else {
9567 // If none of the children had any work, that means that none of
9568 // them got retried so they'll still be blocked in the same way
9569 // as before. We can fast bail out.
9570 return null;
9571 }
9572 }
9573 }
9574
9575 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
9576 } else {
9577 // An update was scheduled on this fiber, but there are no new props
9578 // nor legacy context. Set this to false. If an update queue or context
9579 // consumer produces a changed value, it will set this to true. Otherwise,
9580 // the component will assume the children have not changed and bail out.
9581 didReceiveUpdate = false;
9582 }
9583 } else {
9584 didReceiveUpdate = false;
9585 } // Before entering the begin phase, clear pending update priority.
9586 // TODO: This assumes that we're about to evaluate the component and process
9587 // the update queue. However, there's an exception: SimpleMemoComponent
9588 // sometimes bails out later in the begin phase. This indicates that we should
9589 // move this assignment out of the common path and into each branch.
9590
9591
9592 workInProgress.expirationTime = NoWork;
9593
9594 switch (workInProgress.tag) {
9595 case IndeterminateComponent:
9596 {
9597 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderExpirationTime);
9598 }
9599
9600 case LazyComponent:
9601 {
9602 var elementType = workInProgress.elementType;
9603 return mountLazyComponent(current, workInProgress, elementType, updateExpirationTime, renderExpirationTime);
9604 }
9605
9606 case FunctionComponent:
9607 {
9608 var _Component = workInProgress.type;
9609 var unresolvedProps = workInProgress.pendingProps;
9610 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
9611 return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderExpirationTime);
9612 }
9613
9614 case ClassComponent:
9615 {
9616 var _Component2 = workInProgress.type;
9617 var _unresolvedProps = workInProgress.pendingProps;
9618
9619 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
9620
9621 return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
9622 }
9623
9624 case HostRoot:
9625 return updateHostRoot(current, workInProgress, renderExpirationTime);
9626
9627 case HostComponent:
9628 return updateHostComponent(current, workInProgress, renderExpirationTime);
9629
9630 case HostText:
9631 return updateHostText();
9632
9633 case SuspenseComponent:
9634 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
9635
9636 case HostPortal:
9637 return updatePortalComponent(current, workInProgress, renderExpirationTime);
9638
9639 case ForwardRef:
9640 {
9641 var type = workInProgress.type;
9642 var _unresolvedProps2 = workInProgress.pendingProps;
9643
9644 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
9645
9646 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderExpirationTime);
9647 }
9648
9649 case Fragment:
9650 return updateFragment(current, workInProgress, renderExpirationTime);
9651
9652 case Mode:
9653 return updateMode(current, workInProgress, renderExpirationTime);
9654
9655 case Profiler:
9656 return updateProfiler(current, workInProgress, renderExpirationTime);
9657
9658 case ContextProvider:
9659 return updateContextProvider(current, workInProgress, renderExpirationTime);
9660
9661 case ContextConsumer:
9662 return updateContextConsumer(current, workInProgress, renderExpirationTime);
9663
9664 case MemoComponent:
9665 {
9666 var _type2 = workInProgress.type;
9667 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
9668
9669 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
9670
9671 {
9672 if (workInProgress.type !== workInProgress.elementType) {
9673 var outerPropTypes = _type2.propTypes;
9674
9675 if (outerPropTypes) {
9676 checkPropTypes_1(outerPropTypes, _resolvedProps3, // Resolved for outer only
9677 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
9678 }
9679 }
9680 }
9681
9682 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
9683 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
9684 }
9685
9686 case SimpleMemoComponent:
9687 {
9688 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
9689 }
9690
9691 case IncompleteClassComponent:
9692 {
9693 var _Component3 = workInProgress.type;
9694 var _unresolvedProps4 = workInProgress.pendingProps;
9695
9696 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
9697
9698 return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
9699 }
9700
9701 case SuspenseListComponent:
9702 {
9703 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
9704 }
9705 }
9706
9707 {
9708 {
9709 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
9710 }
9711 }
9712 }
9713
9714 function markUpdate(workInProgress) {
9715 // Tag the fiber with an update effect. This turns a Placement into
9716 // a PlacementAndUpdate.
9717 workInProgress.effectTag |= Update;
9718 }
9719
9720 function markRef$1(workInProgress) {
9721 workInProgress.effectTag |= Ref;
9722 }
9723
9724 var appendAllChildren;
9725 var updateHostContainer;
9726 var updateHostComponent$1;
9727 var updateHostText$1;
9728
9729 {
9730 // Mutation mode
9731 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
9732 // We only have the top Fiber that was created but we need recurse down its
9733 // children to find all the terminal nodes.
9734 var node = workInProgress.child;
9735
9736 while (node !== null) {
9737 if (node.tag === HostComponent || node.tag === HostText) {
9738 appendInitialChild(parent, node.stateNode);
9739 } else if (node.tag === HostPortal) ; else if (node.child !== null) {
9740 node.child.return = node;
9741 node = node.child;
9742 continue;
9743 }
9744
9745 if (node === workInProgress) {
9746 return;
9747 }
9748
9749 while (node.sibling === null) {
9750 if (node.return === null || node.return === workInProgress) {
9751 return;
9752 }
9753
9754 node = node.return;
9755 }
9756
9757 node.sibling.return = node.return;
9758 node = node.sibling;
9759 }
9760 };
9761
9762 updateHostContainer = function (workInProgress) {// Noop
9763 };
9764
9765 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9766 // If we have an alternate, that means this is an update and we need to
9767 // schedule a side-effect to do the updates.
9768 var oldProps = current.memoizedProps;
9769
9770 if (oldProps === newProps) {
9771 // In mutation mode, this is sufficient for a bailout because
9772 // we won't touch this node even if children changed.
9773 return;
9774 } // If we get updated because one of our children updated, we don't
9775 // have newProps so we'll have to reuse them.
9776 // TODO: Split the update API as separate for the props vs. children.
9777 // Even better would be if children weren't special cased at all tho.
9778
9779
9780 var instance = workInProgress.stateNode;
9781 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host
9782 // component is hitting the resume path. Figure out why. Possibly
9783 // related to `hidden`.
9784
9785 var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component.
9786
9787 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
9788 // is a new ref we mark this as an update. All the work is done in commitWork.
9789
9790 if (updatePayload) {
9791 markUpdate(workInProgress);
9792 }
9793 };
9794
9795 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9796 // If the text differs, mark it as an update. All the work in done in commitWork.
9797 if (oldText !== newText) {
9798 markUpdate(workInProgress);
9799 }
9800 };
9801 }
9802
9803 function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
9804 switch (renderState.tailMode) {
9805 case 'hidden':
9806 {
9807 // Any insertions at the end of the tail list after this point
9808 // should be invisible. If there are already mounted boundaries
9809 // anything before them are not considered for collapsing.
9810 // Therefore we need to go through the whole tail to find if
9811 // there are any.
9812 var tailNode = renderState.tail;
9813 var lastTailNode = null;
9814
9815 while (tailNode !== null) {
9816 if (tailNode.alternate !== null) {
9817 lastTailNode = tailNode;
9818 }
9819
9820 tailNode = tailNode.sibling;
9821 } // Next we're simply going to delete all insertions after the
9822 // last rendered item.
9823
9824
9825 if (lastTailNode === null) {
9826 // All remaining items in the tail are insertions.
9827 renderState.tail = null;
9828 } else {
9829 // Detach the insertion after the last node that was already
9830 // inserted.
9831 lastTailNode.sibling = null;
9832 }
9833
9834 break;
9835 }
9836
9837 case 'collapsed':
9838 {
9839 // Any insertions at the end of the tail list after this point
9840 // should be invisible. If there are already mounted boundaries
9841 // anything before them are not considered for collapsing.
9842 // Therefore we need to go through the whole tail to find if
9843 // there are any.
9844 var _tailNode = renderState.tail;
9845 var _lastTailNode = null;
9846
9847 while (_tailNode !== null) {
9848 if (_tailNode.alternate !== null) {
9849 _lastTailNode = _tailNode;
9850 }
9851
9852 _tailNode = _tailNode.sibling;
9853 } // Next we're simply going to delete all insertions after the
9854 // last rendered item.
9855
9856
9857 if (_lastTailNode === null) {
9858 // All remaining items in the tail are insertions.
9859 if (!hasRenderedATailFallback && renderState.tail !== null) {
9860 // We suspended during the head. We want to show at least one
9861 // row at the tail. So we'll keep on and cut off the rest.
9862 renderState.tail.sibling = null;
9863 } else {
9864 renderState.tail = null;
9865 }
9866 } else {
9867 // Detach the insertion after the last node that was already
9868 // inserted.
9869 _lastTailNode.sibling = null;
9870 }
9871
9872 break;
9873 }
9874 }
9875 }
9876
9877 function completeWork(current, workInProgress, renderExpirationTime) {
9878 var newProps = workInProgress.pendingProps;
9879
9880 switch (workInProgress.tag) {
9881 case IndeterminateComponent:
9882 case LazyComponent:
9883 case SimpleMemoComponent:
9884 case FunctionComponent:
9885 case ForwardRef:
9886 case Fragment:
9887 case Mode:
9888 case Profiler:
9889 case ContextConsumer:
9890 case MemoComponent:
9891 return null;
9892
9893 case ClassComponent:
9894 {
9895 var Component = workInProgress.type;
9896
9897 if (isContextProvider(Component)) {
9898 popContext(workInProgress);
9899 }
9900
9901 return null;
9902 }
9903
9904 case HostRoot:
9905 {
9906 popHostContainer(workInProgress);
9907 popTopLevelContextObject(workInProgress);
9908 var fiberRoot = workInProgress.stateNode;
9909
9910 if (fiberRoot.pendingContext) {
9911 fiberRoot.context = fiberRoot.pendingContext;
9912 fiberRoot.pendingContext = null;
9913 }
9914
9915 if (current === null || current.child === null) {
9916 // If we hydrated, pop so that we can delete any remaining children
9917 // that weren't hydrated.
9918 var wasHydrated = popHydrationState();
9919
9920 if (wasHydrated) {
9921 // If we hydrated, then we'll need to schedule an update for
9922 // the commit side-effects on the root.
9923 markUpdate(workInProgress);
9924 }
9925 }
9926
9927 updateHostContainer(workInProgress);
9928 return null;
9929 }
9930
9931 case HostComponent:
9932 {
9933 popHostContext(workInProgress);
9934 var rootContainerInstance = getRootHostContainer();
9935 var type = workInProgress.type;
9936
9937 if (current !== null && workInProgress.stateNode != null) {
9938 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
9939
9940 if (current.ref !== workInProgress.ref) {
9941 markRef$1(workInProgress);
9942 }
9943 } else {
9944 if (!newProps) {
9945 if (!(workInProgress.stateNode !== null)) {
9946 {
9947 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
9948 }
9949 } // This can happen when we abort work.
9950
9951
9952 return null;
9953 }
9954
9955 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
9956 // "stack" as the parent. Then append children as we go in beginWork
9957 // or completeWork depending on whether we want to add them top->down or
9958 // bottom->up. Top->down is faster in IE11.
9959
9960 var _wasHydrated = popHydrationState();
9961
9962 if (_wasHydrated) {
9963 // TODO: Move this and createInstance step into the beginPhase
9964 // to consolidate.
9965 if (prepareToHydrateHostInstance()) {
9966 // If changes to the hydrated node need to be applied at the
9967 // commit-phase we mark this as such.
9968 markUpdate(workInProgress);
9969 }
9970 } else {
9971 var instance = createInstance(type, newProps);
9972 appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners
9973
9974 workInProgress.stateNode = instance;
9975 }
9976
9977 if (workInProgress.ref !== null) {
9978 // If there is a ref on a host node we need to schedule a callback
9979 markRef$1(workInProgress);
9980 }
9981 }
9982
9983 return null;
9984 }
9985
9986 case HostText:
9987 {
9988 var newText = newProps;
9989
9990 if (current && workInProgress.stateNode != null) {
9991 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
9992 // to schedule a side-effect to do the updates.
9993
9994 updateHostText$1(current, workInProgress, oldText, newText);
9995 } else {
9996 if (typeof newText !== 'string') {
9997 if (!(workInProgress.stateNode !== null)) {
9998 {
9999 throw Error( "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." );
10000 }
10001 } // This can happen when we abort work.
10002
10003 }
10004
10005 var _rootContainerInstance = getRootHostContainer();
10006
10007 var _currentHostContext = getHostContext();
10008
10009 var _wasHydrated2 = popHydrationState();
10010
10011 if (_wasHydrated2) {
10012 if (prepareToHydrateHostTextInstance()) {
10013 markUpdate(workInProgress);
10014 }
10015 } else {
10016 workInProgress.stateNode = createTextInstance(newText);
10017 }
10018 }
10019
10020 return null;
10021 }
10022
10023 case SuspenseComponent:
10024 {
10025 popSuspenseContext(workInProgress);
10026 var nextState = workInProgress.memoizedState;
10027
10028 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
10029 // Something suspended. Re-render with the fallback children.
10030 workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list.
10031
10032 return workInProgress;
10033 }
10034
10035 var nextDidTimeout = nextState !== null;
10036 var prevDidTimeout = false;
10037
10038 if (current === null) {
10039 if (workInProgress.memoizedProps.fallback !== undefined) ;
10040 } else {
10041 var prevState = current.memoizedState;
10042 prevDidTimeout = prevState !== null;
10043
10044 if (!nextDidTimeout && prevState !== null) {
10045 // We just switched from the fallback to the normal children.
10046 // Delete the fallback.
10047 // TODO: Would it be better to store the fallback fragment on
10048 // the stateNode during the begin phase?
10049 var currentFallbackChild = current.child.sibling;
10050
10051 if (currentFallbackChild !== null) {
10052 // Deletions go at the beginning of the return fiber's effect list
10053 var first = workInProgress.firstEffect;
10054
10055 if (first !== null) {
10056 workInProgress.firstEffect = currentFallbackChild;
10057 currentFallbackChild.nextEffect = first;
10058 } else {
10059 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
10060 currentFallbackChild.nextEffect = null;
10061 }
10062
10063 currentFallbackChild.effectTag = Deletion;
10064 }
10065 }
10066 }
10067
10068 if (nextDidTimeout && !prevDidTimeout) {
10069 // If this subtreee is running in blocking mode we can suspend,
10070 // otherwise we won't suspend.
10071 // TODO: This will still suspend a synchronous tree if anything
10072 // in the concurrent tree already suspended during this render.
10073 // This is a known bug.
10074 if ((workInProgress.mode & BlockingMode) !== NoMode) {
10075 // TODO: Move this back to throwException because this is too late
10076 // if this is a large tree which is common for initial loads. We
10077 // don't know if we should restart a render or not until we get
10078 // this marker, and this is too late.
10079 // If this render already had a ping or lower pri updates,
10080 // and this is the first time we know we're going to suspend we
10081 // should be able to immediately restart from within throwException.
10082 var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true;
10083
10084 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
10085 // If this was in an invisible tree or a new render, then showing
10086 // this boundary is ok.
10087 renderDidSuspend();
10088 } else {
10089 // Otherwise, we're going to have to hide content so we should
10090 // suspend for longer if possible.
10091 renderDidSuspendDelayIfPossible();
10092 }
10093 }
10094 }
10095
10096 {
10097 // TODO: Only schedule updates if these values are non equal, i.e. it changed.
10098 if (nextDidTimeout || prevDidTimeout) {
10099 // If this boundary just timed out, schedule an effect to attach a
10100 // retry listener to the promise. This flag is also used to hide the
10101 // primary children. In mutation mode, we also need the flag to
10102 // *unhide* children that were previously hidden, so check if this
10103 // is currently timed out, too.
10104 workInProgress.effectTag |= Update;
10105 }
10106 }
10107
10108 return null;
10109 }
10110
10111 case HostPortal:
10112 popHostContainer(workInProgress);
10113 updateHostContainer(workInProgress);
10114 return null;
10115
10116 case ContextProvider:
10117 // Pop provider fiber
10118 popProvider(workInProgress);
10119 return null;
10120
10121 case IncompleteClassComponent:
10122 {
10123 // Same as class component case. I put it down here so that the tags are
10124 // sequential to ensure this switch is compiled to a jump table.
10125 var _Component = workInProgress.type;
10126
10127 if (isContextProvider(_Component)) {
10128 popContext(workInProgress);
10129 }
10130
10131 return null;
10132 }
10133
10134 case SuspenseListComponent:
10135 {
10136 popSuspenseContext(workInProgress);
10137 var renderState = workInProgress.memoizedState;
10138
10139 if (renderState === null) {
10140 // We're running in the default, "independent" mode.
10141 // We don't do anything in this mode.
10142 return null;
10143 }
10144
10145 var didSuspendAlready = (workInProgress.effectTag & DidCapture) !== NoEffect;
10146 var renderedTail = renderState.rendering;
10147
10148 if (renderedTail === null) {
10149 // We just rendered the head.
10150 if (!didSuspendAlready) {
10151 // This is the first pass. We need to figure out if anything is still
10152 // suspended in the rendered set.
10153 // If new content unsuspended, but there's still some content that
10154 // didn't. Then we need to do a second pass that forces everything
10155 // to keep showing their fallbacks.
10156 // We might be suspended if something in this render pass suspended, or
10157 // something in the previous committed pass suspended. Otherwise,
10158 // there's no chance so we can skip the expensive call to
10159 // findFirstSuspended.
10160 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.effectTag & DidCapture) === NoEffect);
10161
10162 if (!cannotBeSuspended) {
10163 var row = workInProgress.child;
10164
10165 while (row !== null) {
10166 var suspended = findFirstSuspended(row);
10167
10168 if (suspended !== null) {
10169 didSuspendAlready = true;
10170 workInProgress.effectTag |= DidCapture;
10171 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
10172 // part of the second pass. In that case nothing will subscribe to
10173 // its thennables. Instead, we'll transfer its thennables to the
10174 // SuspenseList so that it can retry if they resolve.
10175 // There might be multiple of these in the list but since we're
10176 // going to wait for all of them anyway, it doesn't really matter
10177 // which ones gets to ping. In theory we could get clever and keep
10178 // track of how many dependencies remain but it gets tricky because
10179 // in the meantime, we can add/remove/change items and dependencies.
10180 // We might bail out of the loop before finding any but that
10181 // doesn't matter since that means that the other boundaries that
10182 // we did find already has their listeners attached.
10183
10184 var newThennables = suspended.updateQueue;
10185
10186 if (newThennables !== null) {
10187 workInProgress.updateQueue = newThennables;
10188 workInProgress.effectTag |= Update;
10189 } // Rerender the whole list, but this time, we'll force fallbacks
10190 // to stay in place.
10191 // Reset the effect list before doing the second pass since that's now invalid.
10192
10193
10194 if (renderState.lastEffect === null) {
10195 workInProgress.firstEffect = null;
10196 }
10197
10198 workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state.
10199
10200 resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately
10201 // rerender the children.
10202
10203 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
10204 return workInProgress.child;
10205 }
10206
10207 row = row.sibling;
10208 }
10209 }
10210 } else {
10211 cutOffTailIfNeeded(renderState, false);
10212 } // Next we're going to render the tail.
10213
10214 } else {
10215 // Append the rendered row to the child list.
10216 if (!didSuspendAlready) {
10217 var _suspended = findFirstSuspended(renderedTail);
10218
10219 if (_suspended !== null) {
10220 workInProgress.effectTag |= DidCapture;
10221 didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't
10222 // get lost if this row ends up dropped during a second pass.
10223
10224 var _newThennables = _suspended.updateQueue;
10225
10226 if (_newThennables !== null) {
10227 workInProgress.updateQueue = _newThennables;
10228 workInProgress.effectTag |= Update;
10229 }
10230
10231 cutOffTailIfNeeded(renderState, true); // This might have been modified.
10232
10233 if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate) {
10234 // We need to delete the row we just rendered.
10235 // Reset the effect list to what it was before we rendered this
10236 // child. The nested children have already appended themselves.
10237 var lastEffect = workInProgress.lastEffect = renderState.lastEffect; // Remove any effects that were appended after this point.
10238
10239 if (lastEffect !== null) {
10240 lastEffect.nextEffect = null;
10241 } // We're done.
10242
10243
10244 return null;
10245 }
10246 } else if ( // The time it took to render last row is greater than time until
10247 // the expiration.
10248 now() * 2 - renderState.renderingStartTime > renderState.tailExpiration && renderExpirationTime > Never) {
10249 // We have now passed our CPU deadline and we'll just give up further
10250 // attempts to render the main content and only render fallbacks.
10251 // The assumption is that this is usually faster.
10252 workInProgress.effectTag |= DidCapture;
10253 didSuspendAlready = true;
10254 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
10255 // to get it started back up to attempt the next item. If we can show
10256 // them, then they really have the same priority as this render.
10257 // So we'll pick it back up the very next render pass once we've had
10258 // an opportunity to yield for paint.
10259
10260 var nextPriority = renderExpirationTime - 1;
10261 workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority;
10262
10263 {
10264 markSpawnedWork(nextPriority);
10265 }
10266 }
10267 }
10268
10269 if (renderState.isBackwards) {
10270 // The effect list of the backwards tail will have been added
10271 // to the end. This breaks the guarantee that life-cycles fire in
10272 // sibling order but that isn't a strong guarantee promised by React.
10273 // Especially since these might also just pop in during future commits.
10274 // Append to the beginning of the list.
10275 renderedTail.sibling = workInProgress.child;
10276 workInProgress.child = renderedTail;
10277 } else {
10278 var previousSibling = renderState.last;
10279
10280 if (previousSibling !== null) {
10281 previousSibling.sibling = renderedTail;
10282 } else {
10283 workInProgress.child = renderedTail;
10284 }
10285
10286 renderState.last = renderedTail;
10287 }
10288 }
10289
10290 if (renderState.tail !== null) {
10291 // We still have tail rows to render.
10292 if (renderState.tailExpiration === 0) {
10293 // Heuristic for how long we're willing to spend rendering rows
10294 // until we just give up and show what we have so far.
10295 var TAIL_EXPIRATION_TIMEOUT_MS = 500;
10296 renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS; // TODO: This is meant to mimic the train model or JND but this
10297 // is a per component value. It should really be since the start
10298 // of the total render or last commit. Consider using something like
10299 // globalMostRecentFallbackTime. That doesn't account for being
10300 // suspended for part of the time or when it's a new render.
10301 // It should probably use a global start time value instead.
10302 } // Pop a row.
10303
10304
10305 var next = renderState.tail;
10306 renderState.rendering = next;
10307 renderState.tail = next.sibling;
10308 renderState.lastEffect = workInProgress.lastEffect;
10309 renderState.renderingStartTime = now();
10310 next.sibling = null; // Restore the context.
10311 // TODO: We can probably just avoid popping it instead and only
10312 // setting it the first time we go from not suspended to suspended.
10313
10314 var suspenseContext = suspenseStackCursor.current;
10315
10316 if (didSuspendAlready) {
10317 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
10318 } else {
10319 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
10320 }
10321
10322 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
10323
10324 return next;
10325 }
10326
10327 return null;
10328 }
10329 }
10330
10331 {
10332 {
10333 throw Error( "Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue." );
10334 }
10335 }
10336 }
10337
10338 function unwindWork(workInProgress, renderExpirationTime) {
10339 switch (workInProgress.tag) {
10340 case ClassComponent:
10341 {
10342 var Component = workInProgress.type;
10343
10344 if (isContextProvider(Component)) {
10345 popContext(workInProgress);
10346 }
10347
10348 var effectTag = workInProgress.effectTag;
10349
10350 if (effectTag & ShouldCapture) {
10351 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
10352 return workInProgress;
10353 }
10354
10355 return null;
10356 }
10357
10358 case HostRoot:
10359 {
10360 popHostContainer(workInProgress);
10361 popTopLevelContextObject(workInProgress);
10362 var _effectTag = workInProgress.effectTag;
10363
10364 if (!((_effectTag & DidCapture) === NoEffect)) {
10365 {
10366 throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." );
10367 }
10368 }
10369
10370 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
10371 return workInProgress;
10372 }
10373
10374 case HostComponent:
10375 {
10376 // TODO: popHydrationState
10377 popHostContext(workInProgress);
10378 return null;
10379 }
10380
10381 case SuspenseComponent:
10382 {
10383 popSuspenseContext(workInProgress);
10384
10385 var _effectTag2 = workInProgress.effectTag;
10386
10387 if (_effectTag2 & ShouldCapture) {
10388 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
10389
10390 return workInProgress;
10391 }
10392
10393 return null;
10394 }
10395
10396 case SuspenseListComponent:
10397 {
10398 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
10399 // caught by a nested boundary. If not, it should bubble through.
10400
10401 return null;
10402 }
10403
10404 case HostPortal:
10405 popHostContainer(workInProgress);
10406 return null;
10407
10408 case ContextProvider:
10409 popProvider(workInProgress);
10410 return null;
10411
10412 default:
10413 return null;
10414 }
10415 }
10416
10417 function unwindInterruptedWork(interruptedWork) {
10418 switch (interruptedWork.tag) {
10419 case ClassComponent:
10420 {
10421 var childContextTypes = interruptedWork.type.childContextTypes;
10422
10423 if (childContextTypes !== null && childContextTypes !== undefined) {
10424 popContext(interruptedWork);
10425 }
10426
10427 break;
10428 }
10429
10430 case HostRoot:
10431 {
10432 popHostContainer(interruptedWork);
10433 popTopLevelContextObject(interruptedWork);
10434 break;
10435 }
10436
10437 case HostComponent:
10438 {
10439 popHostContext(interruptedWork);
10440 break;
10441 }
10442
10443 case HostPortal:
10444 popHostContainer(interruptedWork);
10445 break;
10446
10447 case SuspenseComponent:
10448 popSuspenseContext(interruptedWork);
10449 break;
10450
10451 case SuspenseListComponent:
10452 popSuspenseContext(interruptedWork);
10453 break;
10454
10455 case ContextProvider:
10456 popProvider(interruptedWork);
10457 break;
10458 }
10459 }
10460
10461 function createCapturedValue(value, source) {
10462 // If the value is an error, call this function immediately after it is thrown
10463 // so the stack is accurate.
10464 return {
10465 value: value,
10466 source: source,
10467 stack: getStackByFiberInDevAndProd(source)
10468 };
10469 }
10470
10471 var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
10472 var funcArgs = Array.prototype.slice.call(arguments, 3);
10473
10474 try {
10475 func.apply(context, funcArgs);
10476 } catch (error) {
10477 this.onError(error);
10478 }
10479 };
10480
10481 {
10482 // In DEV mode, we swap out invokeGuardedCallback for a special version
10483 // that plays more nicely with the browser's DevTools. The idea is to preserve
10484 // "Pause on exceptions" behavior. Because React wraps all user-provided
10485 // functions in invokeGuardedCallback, and the production version of
10486 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
10487 // like caught exceptions, and the DevTools won't pause unless the developer
10488 // takes the extra step of enabling pause on caught exceptions. This is
10489 // unintuitive, though, because even though React has caught the error, from
10490 // the developer's perspective, the error is uncaught.
10491 //
10492 // To preserve the expected "Pause on exceptions" behavior, we don't use a
10493 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
10494 // DOM node, and call the user-provided callback from inside an event handler
10495 // for that fake event. If the callback throws, the error is "captured" using
10496 // a global event handler. But because the error happens in a different
10497 // event loop context, it does not interrupt the normal program flow.
10498 // Effectively, this gives us try-catch behavior without actually using
10499 // try-catch. Neat!
10500 // Check that the browser supports the APIs we need to implement our special
10501 // DEV version of invokeGuardedCallback
10502 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
10503 var fakeNode = document.createElement('react');
10504
10505 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
10506 // If document doesn't exist we know for sure we will crash in this method
10507 // when we call document.createEvent(). However this can cause confusing
10508 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
10509 // So we preemptively throw with a better message instead.
10510 if (!(typeof document !== 'undefined')) {
10511 {
10512 throw Error( "The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous." );
10513 }
10514 }
10515
10516 var evt = document.createEvent('Event'); // Keeps track of whether the user-provided callback threw an error. We
10517 // set this to true at the beginning, then set it to false right after
10518 // calling the function. If the function errors, `didError` will never be
10519 // set to false. This strategy works even if the browser is flaky and
10520 // fails to call our global error handler, because it doesn't rely on
10521 // the error event at all.
10522
10523 var didError = true; // Keeps track of the value of window.event so that we can reset it
10524 // during the callback to let user code access window.event in the
10525 // browsers that support it.
10526
10527 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event
10528 // dispatching: https://github.com/facebook/react/issues/13688
10529
10530 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event'); // Create an event handler for our fake event. We will synchronously
10531 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
10532 // call the user-provided callback.
10533
10534 var funcArgs = Array.prototype.slice.call(arguments, 3);
10535
10536 function callCallback() {
10537 // We immediately remove the callback from event listeners so that
10538 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
10539 // nested call would trigger the fake event handlers of any call higher
10540 // in the stack.
10541 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the
10542 // window.event assignment in both IE <= 10 as they throw an error
10543 // "Member not found" in strict mode, and in Firefox which does not
10544 // support window.event.
10545
10546 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
10547 window.event = windowEvent;
10548 }
10549
10550 func.apply(context, funcArgs);
10551 didError = false;
10552 } // Create a global error event handler. We use this to capture the value
10553 // that was thrown. It's possible that this error handler will fire more
10554 // than once; for example, if non-React code also calls `dispatchEvent`
10555 // and a handler for that event throws. We should be resilient to most of
10556 // those cases. Even if our error event handler fires more than once, the
10557 // last error event is always used. If the callback actually does error,
10558 // we know that the last error event is the correct one, because it's not
10559 // possible for anything else to have happened in between our callback
10560 // erroring and the code that follows the `dispatchEvent` call below. If
10561 // the callback doesn't error, but the error event was fired, we know to
10562 // ignore it because `didError` will be false, as described above.
10563
10564
10565 var error; // Use this to track whether the error event is ever called.
10566
10567 var didSetError = false;
10568 var isCrossOriginError = false;
10569
10570 function handleWindowError(event) {
10571 error = event.error;
10572 didSetError = true;
10573
10574 if (error === null && event.colno === 0 && event.lineno === 0) {
10575 isCrossOriginError = true;
10576 }
10577
10578 if (event.defaultPrevented) {
10579 // Some other error handler has prevented default.
10580 // Browsers silence the error report if this happens.
10581 // We'll remember this to later decide whether to log it or not.
10582 if (error != null && typeof error === 'object') {
10583 try {
10584 error._suppressLogging = true;
10585 } catch (inner) {// Ignore.
10586 }
10587 }
10588 }
10589 } // Create a fake event type.
10590
10591
10592 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers
10593
10594 window.addEventListener('error', handleWindowError);
10595 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function
10596 // errors, it will trigger our global error handler.
10597
10598 evt.initEvent(evtType, false, false);
10599 fakeNode.dispatchEvent(evt);
10600
10601 if (windowEventDescriptor) {
10602 Object.defineProperty(window, 'event', windowEventDescriptor);
10603 }
10604
10605 if (didError) {
10606 if (!didSetError) {
10607 // The callback errored, but the error event never fired.
10608 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.');
10609 } else if (isCrossOriginError) {
10610 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.');
10611 }
10612
10613 this.onError(error);
10614 } // Remove our event listeners
10615
10616
10617 window.removeEventListener('error', handleWindowError);
10618 };
10619
10620 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
10621 }
10622 }
10623
10624 var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
10625
10626 var hasError = false;
10627 var caughtError = null; // Used by event system to capture/rethrow the first error.
10628 var reporter = {
10629 onError: function (error) {
10630 hasError = true;
10631 caughtError = error;
10632 }
10633 };
10634 /**
10635 * Call a function while guarding against errors that happens within it.
10636 * Returns an error if it throws, otherwise null.
10637 *
10638 * In production, this is implemented using a try-catch. The reason we don't
10639 * use a try-catch directly is so that we can swap out a different
10640 * implementation in DEV mode.
10641 *
10642 * @param {String} name of the guard to use for logging or debugging
10643 * @param {Function} func The function to invoke
10644 * @param {*} context The context to use when calling the function
10645 * @param {...*} args Arguments for function
10646 */
10647
10648 function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
10649 hasError = false;
10650 caughtError = null;
10651 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
10652 }
10653 function hasCaughtError() {
10654 return hasError;
10655 }
10656 function clearCaughtError() {
10657 if (hasError) {
10658 var error = caughtError;
10659 hasError = false;
10660 caughtError = null;
10661 return error;
10662 } else {
10663 {
10664 {
10665 throw Error( "clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue." );
10666 }
10667 }
10668 }
10669 }
10670
10671 function logCapturedError(capturedError) {
10672
10673 var error = capturedError.error;
10674
10675 {
10676 var componentName = capturedError.componentName,
10677 componentStack = capturedError.componentStack,
10678 errorBoundaryName = capturedError.errorBoundaryName,
10679 errorBoundaryFound = capturedError.errorBoundaryFound,
10680 willRetry = capturedError.willRetry; // Browsers support silencing uncaught errors by calling
10681 // `preventDefault()` in window `error` handler.
10682 // We record this information as an expando on the error.
10683
10684 if (error != null && error._suppressLogging) {
10685 if (errorBoundaryFound && willRetry) {
10686 // The error is recoverable and was silenced.
10687 // Ignore it and don't print the stack addendum.
10688 // This is handy for testing error boundaries without noise.
10689 return;
10690 } // The error is fatal. Since the silencing might have
10691 // been accidental, we'll surface it anyway.
10692 // However, the browser would have silenced the original error
10693 // so we'll print it first, and then print the stack addendum.
10694
10695
10696 console['error'](error); // Don't transform to our wrapper
10697 // For a more detailed description of this block, see:
10698 // https://github.com/facebook/react/pull/13384
10699 }
10700
10701 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:';
10702 var errorBoundaryMessage; // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
10703
10704 if (errorBoundaryFound && errorBoundaryName) {
10705 if (willRetry) {
10706 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
10707 } else {
10708 errorBoundaryMessage = "This error was initially handled by the error boundary " + errorBoundaryName + ".\n" + "Recreating the tree from scratch failed so React will unmount the tree.";
10709 }
10710 } else {
10711 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.';
10712 }
10713
10714 var combinedMessage = "" + componentNameMessage + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.
10715 // We don't include the original error message and JS stack because the browser
10716 // has already printed it. Even if the application swallows the error, it is still
10717 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
10718
10719 console['error'](combinedMessage); // Don't transform to our wrapper
10720 }
10721 }
10722
10723 var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
10724
10725 {
10726 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
10727 }
10728
10729 var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
10730 function logError(boundary, errorInfo) {
10731 var source = errorInfo.source;
10732 var stack = errorInfo.stack;
10733
10734 if (stack === null && source !== null) {
10735 stack = getStackByFiberInDevAndProd(source);
10736 }
10737
10738 var capturedError = {
10739 componentName: source !== null ? getComponentName(source.type) : null,
10740 componentStack: stack !== null ? stack : '',
10741 error: errorInfo.value,
10742 errorBoundary: null,
10743 errorBoundaryName: null,
10744 errorBoundaryFound: false,
10745 willRetry: false
10746 };
10747
10748 if (boundary !== null && boundary.tag === ClassComponent) {
10749 capturedError.errorBoundary = boundary.stateNode;
10750 capturedError.errorBoundaryName = getComponentName(boundary.type);
10751 capturedError.errorBoundaryFound = true;
10752 capturedError.willRetry = true;
10753 }
10754
10755 try {
10756 logCapturedError(capturedError);
10757 } catch (e) {
10758 // This method must not throw, or React internal state will get messed up.
10759 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
10760 // we want to report this error outside of the normal stack as a last resort.
10761 // https://github.com/facebook/react/issues/13188
10762 setTimeout(function () {
10763 throw e;
10764 });
10765 }
10766 }
10767
10768 var callComponentWillUnmountWithTimer = function (current, instance) {
10769 startPhaseTimer(current, 'componentWillUnmount');
10770 instance.props = current.memoizedProps;
10771 instance.state = current.memoizedState;
10772 instance.componentWillUnmount();
10773 stopPhaseTimer();
10774 }; // Capture errors so they don't interrupt unmounting.
10775
10776
10777 function safelyCallComponentWillUnmount(current, instance) {
10778 {
10779 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);
10780
10781 if (hasCaughtError()) {
10782 var unmountError = clearCaughtError();
10783 captureCommitPhaseError(current, unmountError);
10784 }
10785 }
10786 }
10787
10788 function safelyDetachRef(current) {
10789 var ref = current.ref;
10790
10791 if (ref !== null) {
10792 if (typeof ref === 'function') {
10793 {
10794 invokeGuardedCallback(null, ref, null, null);
10795
10796 if (hasCaughtError()) {
10797 var refError = clearCaughtError();
10798 captureCommitPhaseError(current, refError);
10799 }
10800 }
10801 } else {
10802 ref.current = null;
10803 }
10804 }
10805 }
10806
10807 function safelyCallDestroy(current, destroy) {
10808 {
10809 invokeGuardedCallback(null, destroy, null);
10810
10811 if (hasCaughtError()) {
10812 var error = clearCaughtError();
10813 captureCommitPhaseError(current, error);
10814 }
10815 }
10816 }
10817
10818 function commitBeforeMutationLifeCycles(current, finishedWork) {
10819 switch (finishedWork.tag) {
10820 case FunctionComponent:
10821 case ForwardRef:
10822 case SimpleMemoComponent:
10823 case Block:
10824 {
10825 return;
10826 }
10827
10828 case ClassComponent:
10829 {
10830 if (finishedWork.effectTag & Snapshot) {
10831 if (current !== null) {
10832 var prevProps = current.memoizedProps;
10833 var prevState = current.memoizedState;
10834 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
10835 var instance = finishedWork.stateNode; // We could update instance props and state here,
10836 // but instead we rely on them being set during last render.
10837 // TODO: revisit this when we implement resuming.
10838
10839 {
10840 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
10841 if (instance.props !== finishedWork.memoizedProps) {
10842 error('Expected %s props to match memoized props before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
10843 }
10844
10845 if (instance.state !== finishedWork.memoizedState) {
10846 error('Expected %s state to match memoized state before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
10847 }
10848 }
10849 }
10850
10851 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
10852
10853 {
10854 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
10855
10856 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
10857 didWarnSet.add(finishedWork.type);
10858
10859 error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
10860 }
10861 }
10862
10863 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
10864 stopPhaseTimer();
10865 }
10866 }
10867
10868 return;
10869 }
10870
10871 case HostRoot:
10872 case HostComponent:
10873 case HostText:
10874 case HostPortal:
10875 case IncompleteClassComponent:
10876 // Nothing to do for these component types
10877 return;
10878 }
10879
10880 {
10881 {
10882 throw Error( "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." );
10883 }
10884 }
10885 }
10886
10887 function commitHookEffectListUnmount(tag, finishedWork) {
10888 var updateQueue = finishedWork.updateQueue;
10889 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
10890
10891 if (lastEffect !== null) {
10892 var firstEffect = lastEffect.next;
10893 var effect = firstEffect;
10894
10895 do {
10896 if ((effect.tag & tag) === tag) {
10897 // Unmount
10898 var destroy = effect.destroy;
10899 effect.destroy = undefined;
10900
10901 if (destroy !== undefined) {
10902 destroy();
10903 }
10904 }
10905
10906 effect = effect.next;
10907 } while (effect !== firstEffect);
10908 }
10909 }
10910
10911 function commitHookEffectListMount(tag, finishedWork) {
10912 var updateQueue = finishedWork.updateQueue;
10913 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
10914
10915 if (lastEffect !== null) {
10916 var firstEffect = lastEffect.next;
10917 var effect = firstEffect;
10918
10919 do {
10920 if ((effect.tag & tag) === tag) {
10921 // Mount
10922 var create = effect.create;
10923 effect.destroy = create();
10924
10925 {
10926 var destroy = effect.destroy;
10927
10928 if (destroy !== undefined && typeof destroy !== 'function') {
10929 var addendum = void 0;
10930
10931 if (destroy === null) {
10932 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
10933 } else if (typeof destroy.then === 'function') {
10934 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';
10935 } else {
10936 addendum = ' You returned: ' + destroy;
10937 }
10938
10939 error('An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
10940 }
10941 }
10942 }
10943
10944 effect = effect.next;
10945 } while (effect !== firstEffect);
10946 }
10947 }
10948
10949 function commitPassiveHookEffects(finishedWork) {
10950 if ((finishedWork.effectTag & Passive) !== NoEffect) {
10951 switch (finishedWork.tag) {
10952 case FunctionComponent:
10953 case ForwardRef:
10954 case SimpleMemoComponent:
10955 case Block:
10956 {
10957 // TODO (#17945) We should call all passive destroy functions (for all fibers)
10958 // before calling any create functions. The current approach only serializes
10959 // these for a single fiber.
10960 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork);
10961 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
10962 break;
10963 }
10964 }
10965 }
10966 }
10967
10968 function commitLifeCycles(finishedRoot, current, finishedWork, committedExpirationTime) {
10969 switch (finishedWork.tag) {
10970 case FunctionComponent:
10971 case ForwardRef:
10972 case SimpleMemoComponent:
10973 case Block:
10974 {
10975 // At this point layout effects have already been destroyed (during mutation phase).
10976 // This is done to prevent sibling component effects from interfering with each other,
10977 // e.g. a destroy function in one component should never override a ref set
10978 // by a create function in another component during the same commit.
10979 commitHookEffectListMount(Layout | HasEffect, finishedWork);
10980
10981 return;
10982 }
10983
10984 case ClassComponent:
10985 {
10986 var instance = finishedWork.stateNode;
10987
10988 if (finishedWork.effectTag & Update) {
10989 if (current === null) {
10990 startPhaseTimer(finishedWork, 'componentDidMount'); // We could update instance props and state here,
10991 // but instead we rely on them being set during last render.
10992 // TODO: revisit this when we implement resuming.
10993
10994 {
10995 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
10996 if (instance.props !== finishedWork.memoizedProps) {
10997 error('Expected %s props to match memoized props before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
10998 }
10999
11000 if (instance.state !== finishedWork.memoizedState) {
11001 error('Expected %s state to match memoized state before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
11002 }
11003 }
11004 }
11005
11006 instance.componentDidMount();
11007 stopPhaseTimer();
11008 } else {
11009 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
11010 var prevState = current.memoizedState;
11011 startPhaseTimer(finishedWork, 'componentDidUpdate'); // We could update instance props and state here,
11012 // but instead we rely on them being set during last render.
11013 // TODO: revisit this when we implement resuming.
11014
11015 {
11016 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
11017 if (instance.props !== finishedWork.memoizedProps) {
11018 error('Expected %s props to match memoized props before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
11019 }
11020
11021 if (instance.state !== finishedWork.memoizedState) {
11022 error('Expected %s state to match memoized state before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
11023 }
11024 }
11025 }
11026
11027 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
11028 stopPhaseTimer();
11029 }
11030 }
11031
11032 var updateQueue = finishedWork.updateQueue;
11033
11034 if (updateQueue !== null) {
11035 {
11036 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
11037 if (instance.props !== finishedWork.memoizedProps) {
11038 error('Expected %s props to match memoized props before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
11039 }
11040
11041 if (instance.state !== finishedWork.memoizedState) {
11042 error('Expected %s state to match memoized state before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance');
11043 }
11044 }
11045 } // We could update instance props and state here,
11046 // but instead we rely on them being set during last render.
11047 // TODO: revisit this when we implement resuming.
11048
11049
11050 commitUpdateQueue(finishedWork, updateQueue, instance);
11051 }
11052
11053 return;
11054 }
11055
11056 case HostRoot:
11057 {
11058 var _updateQueue = finishedWork.updateQueue;
11059
11060 if (_updateQueue !== null) {
11061 var _instance = null;
11062
11063 if (finishedWork.child !== null) {
11064 switch (finishedWork.child.tag) {
11065 case HostComponent:
11066 _instance = getPublicInstance(finishedWork.child.stateNode);
11067 break;
11068
11069 case ClassComponent:
11070 _instance = finishedWork.child.stateNode;
11071 break;
11072 }
11073 }
11074
11075 commitUpdateQueue(finishedWork, _updateQueue, _instance);
11076 }
11077
11078 return;
11079 }
11080
11081 case HostComponent:
11082 {
11083 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted
11084 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
11085 // These effects should only be committed when components are first mounted,
11086 // aka when there is no current/alternate.
11087
11088 if (current === null && finishedWork.effectTag & Update) {
11089 var type = finishedWork.type;
11090 var props = finishedWork.memoizedProps;
11091 }
11092
11093 return;
11094 }
11095
11096 case HostText:
11097 {
11098 // We have no life-cycles associated with text.
11099 return;
11100 }
11101
11102 case HostPortal:
11103 {
11104 // We have no life-cycles associated with portals.
11105 return;
11106 }
11107
11108 case Profiler:
11109 {
11110 {
11111 var onRender = finishedWork.memoizedProps.onRender;
11112
11113 if (typeof onRender === 'function') {
11114 {
11115 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
11116 }
11117 }
11118 }
11119
11120 return;
11121 }
11122
11123 case SuspenseComponent:
11124 {
11125 return;
11126 }
11127
11128 case SuspenseListComponent:
11129 case IncompleteClassComponent:
11130 case FundamentalComponent:
11131 case ScopeComponent:
11132 return;
11133 }
11134
11135 {
11136 {
11137 throw Error( "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." );
11138 }
11139 }
11140 }
11141
11142 function hideOrUnhideAllChildren(finishedWork, isHidden) {
11143 {
11144 // We only have the top Fiber that was inserted but we need to recurse down its
11145 // children to find all the terminal nodes.
11146 var node = finishedWork;
11147
11148 while (true) {
11149 if (node.tag === HostComponent) {
11150 var instance = node.stateNode;
11151
11152 if (isHidden) {
11153 hideInstance(instance);
11154 } else {
11155 unhideInstance(node.stateNode, node.memoizedProps);
11156 }
11157 } else if (node.tag === HostText) {
11158 var _instance3 = node.stateNode;
11159
11160 if (isHidden) ; else {
11161 unhideTextInstance(_instance3, node.memoizedProps);
11162 }
11163 } else if (node.tag === SuspenseComponent && node.memoizedState !== null && node.memoizedState.dehydrated === null) {
11164 // Found a nested Suspense component that timed out. Skip over the
11165 // primary child fragment, which should remain hidden.
11166 var fallbackChildFragment = node.child.sibling;
11167 fallbackChildFragment.return = node;
11168 node = fallbackChildFragment;
11169 continue;
11170 } else if (node.child !== null) {
11171 node.child.return = node;
11172 node = node.child;
11173 continue;
11174 }
11175
11176 if (node === finishedWork) {
11177 return;
11178 }
11179
11180 while (node.sibling === null) {
11181 if (node.return === null || node.return === finishedWork) {
11182 return;
11183 }
11184
11185 node = node.return;
11186 }
11187
11188 node.sibling.return = node.return;
11189 node = node.sibling;
11190 }
11191 }
11192 }
11193
11194 function commitAttachRef(finishedWork) {
11195 var ref = finishedWork.ref;
11196
11197 if (ref !== null) {
11198 var instance = finishedWork.stateNode;
11199 var instanceToUse;
11200
11201 switch (finishedWork.tag) {
11202 case HostComponent:
11203 instanceToUse = getPublicInstance(instance);
11204 break;
11205
11206 default:
11207 instanceToUse = instance;
11208 } // Moved outside to ensure DCE works with this flag
11209
11210 if (typeof ref === 'function') {
11211 ref(instanceToUse);
11212 } else {
11213 {
11214 if (!ref.hasOwnProperty('current')) {
11215 error('Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
11216 }
11217 }
11218
11219 ref.current = instanceToUse;
11220 }
11221 }
11222 }
11223
11224 function commitDetachRef(current) {
11225 var currentRef = current.ref;
11226
11227 if (currentRef !== null) {
11228 if (typeof currentRef === 'function') {
11229 currentRef(null);
11230 } else {
11231 currentRef.current = null;
11232 }
11233 }
11234 } // User-originating errors (lifecycles and refs) should not interrupt
11235 // deletion, so don't let them throw. Host-originating errors should
11236 // interrupt deletion, so it's okay
11237
11238
11239 function commitUnmount(finishedRoot, current, renderPriorityLevel) {
11240 onCommitUnmount(current);
11241
11242 switch (current.tag) {
11243 case FunctionComponent:
11244 case ForwardRef:
11245 case MemoComponent:
11246 case SimpleMemoComponent:
11247 case Block:
11248 {
11249 var updateQueue = current.updateQueue;
11250
11251 if (updateQueue !== null) {
11252 var lastEffect = updateQueue.lastEffect;
11253
11254 if (lastEffect !== null) {
11255 var firstEffect = lastEffect.next;
11256
11257 {
11258 // When the owner fiber is deleted, the destroy function of a passive
11259 // effect hook is called during the synchronous commit phase. This is
11260 // a concession to implementation complexity. Calling it in the
11261 // passive effect phase (like they usually are, when dependencies
11262 // change during an update) would require either traversing the
11263 // children of the deleted fiber again, or including unmount effects
11264 // as part of the fiber effect list.
11265 //
11266 // Because this is during the sync commit phase, we need to change
11267 // the priority.
11268 //
11269 // TODO: Reconsider this implementation trade off.
11270 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
11271 runWithPriority(priorityLevel, function () {
11272 var effect = firstEffect;
11273
11274 do {
11275 var _destroy = effect.destroy;
11276
11277 if (_destroy !== undefined) {
11278 safelyCallDestroy(current, _destroy);
11279 }
11280
11281 effect = effect.next;
11282 } while (effect !== firstEffect);
11283 });
11284 }
11285 }
11286 }
11287
11288 return;
11289 }
11290
11291 case ClassComponent:
11292 {
11293 safelyDetachRef(current);
11294 var instance = current.stateNode;
11295
11296 if (typeof instance.componentWillUnmount === 'function') {
11297 safelyCallComponentWillUnmount(current, instance);
11298 }
11299
11300 return;
11301 }
11302
11303 case HostComponent:
11304 {
11305
11306 safelyDetachRef(current);
11307 return;
11308 }
11309
11310 case HostPortal:
11311 {
11312 // TODO: this is recursive.
11313 // We are also not using this parent because
11314 // the portal will get pushed immediately.
11315 {
11316 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
11317 }
11318
11319 return;
11320 }
11321
11322 case FundamentalComponent:
11323 {
11324
11325 return;
11326 }
11327
11328 case DehydratedFragment:
11329 {
11330
11331 return;
11332 }
11333
11334 case ScopeComponent:
11335 {
11336
11337 return;
11338 }
11339 }
11340 }
11341
11342 function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) {
11343 // While we're inside a removed host node we don't want to call
11344 // removeChild on the inner nodes because they're removed by the top
11345 // call anyway. We also want to call componentWillUnmount on all
11346 // composites before this host node is removed from the tree. Therefore
11347 // we do an inner loop while we're still inside the host node.
11348 var node = root;
11349
11350 while (true) {
11351 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because they may contain more composite or host nodes.
11352 // Skip portals because commitUnmount() currently visits them recursively.
11353
11354 if (node.child !== null && ( // If we use mutation we drill down into portals using commitUnmount above.
11355 // If we don't use mutation we drill down into portals here instead.
11356 node.tag !== HostPortal)) {
11357 node.child.return = node;
11358 node = node.child;
11359 continue;
11360 }
11361
11362 if (node === root) {
11363 return;
11364 }
11365
11366 while (node.sibling === null) {
11367 if (node.return === null || node.return === root) {
11368 return;
11369 }
11370
11371 node = node.return;
11372 }
11373
11374 node.sibling.return = node.return;
11375 node = node.sibling;
11376 }
11377 }
11378
11379 function detachFiber(current) {
11380 var alternate = current.alternate; // Cut off the return pointers to disconnect it from the tree. Ideally, we
11381 // should clear the child pointer of the parent alternate to let this
11382 // get GC:ed but we don't know which for sure which parent is the current
11383 // one so we'll settle for GC:ing the subtree of this child. This child
11384 // itself will be GC:ed when the parent updates the next time.
11385
11386 current.return = null;
11387 current.child = null;
11388 current.memoizedState = null;
11389 current.updateQueue = null;
11390 current.dependencies = null;
11391 current.alternate = null;
11392 current.firstEffect = null;
11393 current.lastEffect = null;
11394 current.pendingProps = null;
11395 current.memoizedProps = null;
11396 current.stateNode = null;
11397
11398 if (alternate !== null) {
11399 detachFiber(alternate);
11400 }
11401 }
11402
11403 function getHostParentFiber(fiber) {
11404 var parent = fiber.return;
11405
11406 while (parent !== null) {
11407 if (isHostParent(parent)) {
11408 return parent;
11409 }
11410
11411 parent = parent.return;
11412 }
11413
11414 {
11415 {
11416 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
11417 }
11418 }
11419 }
11420
11421 function isHostParent(fiber) {
11422 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
11423 }
11424
11425 function getHostSibling(fiber) {
11426 // We're going to search forward into the tree until we find a sibling host
11427 // node. Unfortunately, if multiple insertions are done in a row we have to
11428 // search past them. This leads to exponential search for the next sibling.
11429 // TODO: Find a more efficient way to do this.
11430 var node = fiber;
11431
11432 siblings: while (true) {
11433 // If we didn't find anything, let's try the next sibling.
11434 while (node.sibling === null) {
11435 if (node.return === null || isHostParent(node.return)) {
11436 // If we pop out of the root or hit the parent the fiber we are the
11437 // last sibling.
11438 return null;
11439 }
11440
11441 node = node.return;
11442 }
11443
11444 node.sibling.return = node.return;
11445 node = node.sibling;
11446
11447 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {
11448 // If it is not host node and, we might have a host node inside it.
11449 // Try to search down until we find one.
11450 if (node.effectTag & Placement) {
11451 // If we don't have a child, try the siblings instead.
11452 continue siblings;
11453 } // If we don't have a child, try the siblings instead.
11454 // We also skip portals because they are not part of this host tree.
11455
11456
11457 if (node.child === null || node.tag === HostPortal) {
11458 continue siblings;
11459 } else {
11460 node.child.return = node;
11461 node = node.child;
11462 }
11463 } // Check if this host node is stable or about to be placed.
11464
11465
11466 if (!(node.effectTag & Placement)) {
11467 // Found it!
11468 return node.stateNode;
11469 }
11470 }
11471 }
11472
11473 function commitPlacement(finishedWork) {
11474
11475
11476 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.
11477
11478 var parent;
11479 var isContainer;
11480 var parentStateNode = parentFiber.stateNode;
11481
11482 switch (parentFiber.tag) {
11483 case HostComponent:
11484 parent = parentStateNode;
11485 isContainer = false;
11486 break;
11487
11488 case HostRoot:
11489 parent = parentStateNode.containerInfo;
11490 isContainer = true;
11491 break;
11492
11493 case HostPortal:
11494 parent = parentStateNode.containerInfo;
11495 isContainer = true;
11496 break;
11497
11498 case FundamentalComponent:
11499
11500 // eslint-disable-next-line-no-fallthrough
11501
11502 default:
11503 {
11504 {
11505 throw Error( "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." );
11506 }
11507 }
11508
11509 }
11510
11511 if (parentFiber.effectTag & ContentReset) {
11512
11513 parentFiber.effectTag &= ~ContentReset;
11514 }
11515
11516 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
11517 // children to find all the terminal nodes.
11518
11519 if (isContainer) {
11520 insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent);
11521 } else {
11522 insertOrAppendPlacementNode(finishedWork, before, parent);
11523 }
11524 }
11525
11526 function insertOrAppendPlacementNodeIntoContainer(node, before, parent) {
11527 var tag = node.tag;
11528 var isHost = tag === HostComponent || tag === HostText;
11529
11530 if (isHost || enableFundamentalAPI ) {
11531 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
11532
11533 if (before) {
11534 insertInContainerBefore(parent, stateNode, before);
11535 } else {
11536 appendChildToContainer(parent, stateNode);
11537 }
11538 } else if (tag === HostPortal) ; else {
11539 var child = node.child;
11540
11541 if (child !== null) {
11542 insertOrAppendPlacementNodeIntoContainer(child, before, parent);
11543 var sibling = child.sibling;
11544
11545 while (sibling !== null) {
11546 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);
11547 sibling = sibling.sibling;
11548 }
11549 }
11550 }
11551 }
11552
11553 function insertOrAppendPlacementNode(node, before, parent) {
11554 var tag = node.tag;
11555 var isHost = tag === HostComponent || tag === HostText;
11556
11557 if (isHost || enableFundamentalAPI ) {
11558 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
11559
11560 if (before) {
11561 insertBefore(parent, stateNode, before);
11562 } else {
11563 appendChild(parent, stateNode);
11564 }
11565 } else if (tag === HostPortal) ; else {
11566 var child = node.child;
11567
11568 if (child !== null) {
11569 insertOrAppendPlacementNode(child, before, parent);
11570 var sibling = child.sibling;
11571
11572 while (sibling !== null) {
11573 insertOrAppendPlacementNode(sibling, before, parent);
11574 sibling = sibling.sibling;
11575 }
11576 }
11577 }
11578 }
11579
11580 function unmountHostComponents(finishedRoot, current, renderPriorityLevel) {
11581 // We only have the top Fiber that was deleted but we need to recurse down its
11582 // children to find all the terminal nodes.
11583 var node = current; // Each iteration, currentParent is populated with node's host parent if not
11584 // currentParentIsValid.
11585
11586 var currentParentIsValid = false; // Note: these two variables *must* always be updated together.
11587
11588 var currentParent;
11589 var currentParentIsContainer;
11590
11591 while (true) {
11592 if (!currentParentIsValid) {
11593 var parent = node.return;
11594
11595 findParent: while (true) {
11596 if (!(parent !== null)) {
11597 {
11598 throw Error( "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." );
11599 }
11600 }
11601
11602 var parentStateNode = parent.stateNode;
11603
11604 switch (parent.tag) {
11605 case HostComponent:
11606 currentParent = parentStateNode;
11607 currentParentIsContainer = false;
11608 break findParent;
11609
11610 case HostRoot:
11611 currentParent = parentStateNode.containerInfo;
11612 currentParentIsContainer = true;
11613 break findParent;
11614
11615 case HostPortal:
11616 currentParent = parentStateNode.containerInfo;
11617 currentParentIsContainer = true;
11618 break findParent;
11619
11620 }
11621
11622 parent = parent.return;
11623 }
11624
11625 currentParentIsValid = true;
11626 }
11627
11628 if (node.tag === HostComponent || node.tag === HostText) {
11629 commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the
11630 // node from the tree.
11631
11632 if (currentParentIsContainer) {
11633 removeChildFromContainer(currentParent, node.stateNode);
11634 } else {
11635 removeChild(currentParent, node.stateNode);
11636 } // Don't visit children because we already visited them.
11637
11638 } else if (node.tag === HostPortal) {
11639 if (node.child !== null) {
11640 // When we go into a portal, it becomes the parent to remove from.
11641 // We will reassign it back when we pop the portal on the way up.
11642 currentParent = node.stateNode.containerInfo;
11643 currentParentIsContainer = true; // Visit children because portals might contain host components.
11644
11645 node.child.return = node;
11646 node = node.child;
11647 continue;
11648 }
11649 } else {
11650 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because we may find more host components below.
11651
11652 if (node.child !== null) {
11653 node.child.return = node;
11654 node = node.child;
11655 continue;
11656 }
11657 }
11658
11659 if (node === current) {
11660 return;
11661 }
11662
11663 while (node.sibling === null) {
11664 if (node.return === null || node.return === current) {
11665 return;
11666 }
11667
11668 node = node.return;
11669
11670 if (node.tag === HostPortal) {
11671 // When we go out of the portal, we need to restore the parent.
11672 // Since we don't keep a stack of them, we will search for it.
11673 currentParentIsValid = false;
11674 }
11675 }
11676
11677 node.sibling.return = node.return;
11678 node = node.sibling;
11679 }
11680 }
11681
11682 function commitDeletion(finishedRoot, current, renderPriorityLevel) {
11683 {
11684 // Recursively delete all host nodes from the parent.
11685 // Detach refs and call componentWillUnmount() on the whole subtree.
11686 unmountHostComponents(finishedRoot, current, renderPriorityLevel);
11687 }
11688
11689 detachFiber(current);
11690 }
11691
11692 function commitWork(current, finishedWork) {
11693
11694 switch (finishedWork.tag) {
11695 case FunctionComponent:
11696 case ForwardRef:
11697 case MemoComponent:
11698 case SimpleMemoComponent:
11699 case Block:
11700 {
11701 // Layout effects are destroyed during the mutation phase so that all
11702 // destroy functions for all fibers are called before any create functions.
11703 // This prevents sibling component effects from interfering with each other,
11704 // e.g. a destroy function in one component should never override a ref set
11705 // by a create function in another component during the same commit.
11706 commitHookEffectListUnmount(Layout | HasEffect, finishedWork);
11707 return;
11708 }
11709
11710 case ClassComponent:
11711 {
11712 return;
11713 }
11714
11715 case HostComponent:
11716 {
11717 var instance = finishedWork.stateNode;
11718
11719 if (instance != null) {
11720 // Commit the work prepared earlier.
11721 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
11722 // as the newProps. The updatePayload will contain the real change in
11723 // this case.
11724
11725 var oldProps = current !== null ? current.memoizedProps : newProps;
11726 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.
11727
11728 var updatePayload = finishedWork.updateQueue;
11729 finishedWork.updateQueue = null;
11730
11731 if (updatePayload !== null) {
11732 commitUpdate(instance, updatePayload, type, oldProps, newProps);
11733 }
11734 }
11735
11736 return;
11737 }
11738
11739 case HostText:
11740 {
11741 if (!(finishedWork.stateNode !== null)) {
11742 {
11743 throw Error( "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." );
11744 }
11745 }
11746
11747 var textInstance = finishedWork.stateNode;
11748 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
11749 // as the newProps. The updatePayload will contain the real change in
11750 // this case.
11751
11752 var oldText = current !== null ? current.memoizedProps : newText;
11753 return;
11754 }
11755
11756 case HostRoot:
11757 {
11758
11759 return;
11760 }
11761
11762 case Profiler:
11763 {
11764 return;
11765 }
11766
11767 case SuspenseComponent:
11768 {
11769 commitSuspenseComponent(finishedWork);
11770 attachSuspenseRetryListeners(finishedWork);
11771 return;
11772 }
11773
11774 case SuspenseListComponent:
11775 {
11776 attachSuspenseRetryListeners(finishedWork);
11777 return;
11778 }
11779
11780 case IncompleteClassComponent:
11781 {
11782 return;
11783 }
11784 }
11785
11786 {
11787 {
11788 throw Error( "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." );
11789 }
11790 }
11791 }
11792
11793 function commitSuspenseComponent(finishedWork) {
11794 var newState = finishedWork.memoizedState;
11795 var newDidTimeout;
11796 var primaryChildParent = finishedWork;
11797
11798 if (newState === null) {
11799 newDidTimeout = false;
11800 } else {
11801 newDidTimeout = true;
11802 primaryChildParent = finishedWork.child;
11803 markCommitTimeOfFallback();
11804 }
11805
11806 if ( primaryChildParent !== null) {
11807 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
11808 }
11809 }
11810
11811 function attachSuspenseRetryListeners(finishedWork) {
11812 // If this boundary just timed out, then it will have a set of thenables.
11813 // For each thenable, attach a listener so that when it resolves, React
11814 // attempts to re-render the boundary in the primary (pre-timeout) state.
11815 var thenables = finishedWork.updateQueue;
11816
11817 if (thenables !== null) {
11818 finishedWork.updateQueue = null;
11819 var retryCache = finishedWork.stateNode;
11820
11821 if (retryCache === null) {
11822 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
11823 }
11824
11825 thenables.forEach(function (thenable) {
11826 // Memoize using the boundary fiber to prevent redundant listeners.
11827 var retry = resolveRetryThenable.bind(null, finishedWork, thenable);
11828
11829 if (!retryCache.has(thenable)) {
11830 {
11831 if (thenable.__reactDoNotTraceInteractions !== true) {
11832 retry = unstable_wrap(retry);
11833 }
11834 }
11835
11836 retryCache.add(thenable);
11837 thenable.then(retry, retry);
11838 }
11839 });
11840 }
11841 }
11842
11843 function commitResetTextContent(current) {
11844
11845 resetTextContent(current.stateNode);
11846 }
11847
11848 var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
11849
11850 function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
11851 var update = createUpdate(expirationTime, null); // Unmount the root by rendering null.
11852
11853 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
11854 // being called "element".
11855
11856 update.payload = {
11857 element: null
11858 };
11859 var error = errorInfo.value;
11860
11861 update.callback = function () {
11862 onUncaughtError(error);
11863 logError(fiber, errorInfo);
11864 };
11865
11866 return update;
11867 }
11868
11869 function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
11870 var update = createUpdate(expirationTime, null);
11871 update.tag = CaptureUpdate;
11872 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
11873
11874 if (typeof getDerivedStateFromError === 'function') {
11875 var error$1 = errorInfo.value;
11876
11877 update.payload = function () {
11878 logError(fiber, errorInfo);
11879 return getDerivedStateFromError(error$1);
11880 };
11881 }
11882
11883 var inst = fiber.stateNode;
11884
11885 if (inst !== null && typeof inst.componentDidCatch === 'function') {
11886 update.callback = function callback() {
11887 {
11888 markFailedErrorBoundaryForHotReloading(fiber);
11889 }
11890
11891 if (typeof getDerivedStateFromError !== 'function') {
11892 // To preserve the preexisting retry behavior of error boundaries,
11893 // we keep track of which ones already failed during this batch.
11894 // This gets reset before we yield back to the browser.
11895 // TODO: Warn in strict mode if getDerivedStateFromError is
11896 // not defined.
11897 markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined
11898
11899 logError(fiber, errorInfo);
11900 }
11901
11902 var error$1 = errorInfo.value;
11903 var stack = errorInfo.stack;
11904 this.componentDidCatch(error$1, {
11905 componentStack: stack !== null ? stack : ''
11906 });
11907
11908 {
11909 if (typeof getDerivedStateFromError !== 'function') {
11910 // If componentDidCatch is the only error boundary method defined,
11911 // then it needs to call setState to recover from errors.
11912 // If no state update is scheduled then the boundary will swallow the error.
11913 if (fiber.expirationTime !== Sync) {
11914 error('%s: Error boundaries should implement getDerivedStateFromError(). ' + 'In that method, return a state update to display an error message or fallback UI.', getComponentName(fiber.type) || 'Unknown');
11915 }
11916 }
11917 }
11918 };
11919 } else {
11920 update.callback = function () {
11921 markFailedErrorBoundaryForHotReloading(fiber);
11922 };
11923 }
11924
11925 return update;
11926 }
11927
11928 function attachPingListener(root, renderExpirationTime, thenable) {
11929 // Attach a listener to the promise to "ping" the root and retry. But
11930 // only if one does not already exist for the current render expiration
11931 // time (which acts like a "thread ID" here).
11932 var pingCache = root.pingCache;
11933 var threadIDs;
11934
11935 if (pingCache === null) {
11936 pingCache = root.pingCache = new PossiblyWeakMap();
11937 threadIDs = new Set();
11938 pingCache.set(thenable, threadIDs);
11939 } else {
11940 threadIDs = pingCache.get(thenable);
11941
11942 if (threadIDs === undefined) {
11943 threadIDs = new Set();
11944 pingCache.set(thenable, threadIDs);
11945 }
11946 }
11947
11948 if (!threadIDs.has(renderExpirationTime)) {
11949 // Memoize using the thread ID to prevent redundant listeners.
11950 threadIDs.add(renderExpirationTime);
11951 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
11952 thenable.then(ping, ping);
11953 }
11954 }
11955
11956 function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
11957 // The source fiber did not complete.
11958 sourceFiber.effectTag |= Incomplete; // Its effect list is no longer valid.
11959
11960 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
11961
11962 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
11963 // This is a thenable.
11964 var thenable = value;
11965
11966 if ((sourceFiber.mode & BlockingMode) === NoMode) {
11967 // Reset the memoizedState to what it was before we attempted
11968 // to render it.
11969 var currentSource = sourceFiber.alternate;
11970
11971 if (currentSource) {
11972 sourceFiber.updateQueue = currentSource.updateQueue;
11973 sourceFiber.memoizedState = currentSource.memoizedState;
11974 sourceFiber.expirationTime = currentSource.expirationTime;
11975 } else {
11976 sourceFiber.updateQueue = null;
11977 sourceFiber.memoizedState = null;
11978 }
11979 }
11980
11981 var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext); // Schedule the nearest Suspense to re-render the timed out view.
11982
11983 var _workInProgress = returnFiber;
11984
11985 do {
11986 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) {
11987 // Found the nearest boundary.
11988 // Stash the promise on the boundary fiber. If the boundary times out, we'll
11989 // attach another listener to flip the boundary back to its normal state.
11990 var thenables = _workInProgress.updateQueue;
11991
11992 if (thenables === null) {
11993 var updateQueue = new Set();
11994 updateQueue.add(thenable);
11995 _workInProgress.updateQueue = updateQueue;
11996 } else {
11997 thenables.add(thenable);
11998 } // If the boundary is outside of blocking mode, we should *not*
11999 // suspend the commit. Pretend as if the suspended component rendered
12000 // null and keep rendering. In the commit phase, we'll schedule a
12001 // subsequent synchronous update to re-render the Suspense.
12002 //
12003 // Note: It doesn't matter whether the component that suspended was
12004 // inside a blocking mode tree. If the Suspense is outside of it, we
12005 // should *not* suspend the commit.
12006
12007
12008 if ((_workInProgress.mode & BlockingMode) === NoMode) {
12009 _workInProgress.effectTag |= DidCapture; // We're going to commit this fiber even though it didn't complete.
12010 // But we shouldn't call any lifecycle methods or callbacks. Remove
12011 // all lifecycle effect tags.
12012
12013 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
12014
12015 if (sourceFiber.tag === ClassComponent) {
12016 var currentSourceFiber = sourceFiber.alternate;
12017
12018 if (currentSourceFiber === null) {
12019 // This is a new mount. Change the tag so it's not mistaken for a
12020 // completed class component. For example, we should not call
12021 // componentWillUnmount if it is deleted.
12022 sourceFiber.tag = IncompleteClassComponent;
12023 } else {
12024 // When we try rendering again, we should not reuse the current fiber,
12025 // since it's known to be in an inconsistent state. Use a force update to
12026 // prevent a bail out.
12027 var update = createUpdate(Sync, null);
12028 update.tag = ForceUpdate;
12029 enqueueUpdate(sourceFiber, update);
12030 }
12031 } // The source fiber did not complete. Mark it with Sync priority to
12032 // indicate that it still has pending work.
12033
12034
12035 sourceFiber.expirationTime = Sync; // Exit without suspending.
12036
12037 return;
12038 } // Confirmed that the boundary is in a concurrent mode tree. Continue
12039 // with the normal suspend path.
12040 //
12041 // After this we'll use a set of heuristics to determine whether this
12042 // render pass will run to completion or restart or "suspend" the commit.
12043 // The actual logic for this is spread out in different places.
12044 //
12045 // This first principle is that if we're going to suspend when we complete
12046 // a root, then we should also restart if we get an update or ping that
12047 // might unsuspend it, and vice versa. The only reason to suspend is
12048 // because you think you might want to restart before committing. However,
12049 // it doesn't make sense to restart only while in the period we're suspended.
12050 //
12051 // Restarting too aggressively is also not good because it starves out any
12052 // intermediate loading state. So we use heuristics to determine when.
12053 // Suspense Heuristics
12054 //
12055 // If nothing threw a Promise or all the same fallbacks are already showing,
12056 // then don't suspend/restart.
12057 //
12058 // If this is an initial render of a new tree of Suspense boundaries and
12059 // those trigger a fallback, then don't suspend/restart. We want to ensure
12060 // that we can show the initial loading state as quickly as possible.
12061 //
12062 // If we hit a "Delayed" case, such as when we'd switch from content back into
12063 // a fallback, then we should always suspend/restart. SuspenseConfig applies to
12064 // this case. If none is defined, JND is used instead.
12065 //
12066 // If we're already showing a fallback and it gets "retried", allowing us to show
12067 // another level, but there's still an inner boundary that would show a fallback,
12068 // then we suspend/restart for 500ms since the last time we showed a fallback
12069 // anywhere in the tree. This effectively throttles progressive loading into a
12070 // consistent train of commits. This also gives us an opportunity to restart to
12071 // get to the completed state slightly earlier.
12072 //
12073 // If there's ambiguity due to batching it's resolved in preference of:
12074 // 1) "delayed", 2) "initial render", 3) "retry".
12075 //
12076 // We want to ensure that a "busy" state doesn't get force committed. We want to
12077 // ensure that new initial loading states can commit as soon as possible.
12078
12079
12080 attachPingListener(root, renderExpirationTime, thenable);
12081 _workInProgress.effectTag |= ShouldCapture;
12082 _workInProgress.expirationTime = renderExpirationTime;
12083 return;
12084 } // This boundary already captured during this render. Continue to the next
12085 // boundary.
12086
12087
12088 _workInProgress = _workInProgress.return;
12089 } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode.
12090 // TODO: Use invariant so the message is stripped in prod?
12091
12092
12093 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));
12094 } // We didn't find a boundary that could handle this type of exception. Start
12095 // over and traverse parent path again, this time treating the exception
12096 // as an error.
12097
12098
12099 renderDidError();
12100 value = createCapturedValue(value, sourceFiber);
12101 var workInProgress = returnFiber;
12102
12103 do {
12104 switch (workInProgress.tag) {
12105 case HostRoot:
12106 {
12107 var _errorInfo = value;
12108 workInProgress.effectTag |= ShouldCapture;
12109 workInProgress.expirationTime = renderExpirationTime;
12110
12111 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
12112
12113 enqueueCapturedUpdate(workInProgress, _update);
12114 return;
12115 }
12116
12117 case ClassComponent:
12118 // Capture and retry
12119 var errorInfo = value;
12120 var ctor = workInProgress.type;
12121 var instance = workInProgress.stateNode;
12122
12123 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
12124 workInProgress.effectTag |= ShouldCapture;
12125 workInProgress.expirationTime = renderExpirationTime; // Schedule the error boundary to re-render using updated state
12126
12127 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
12128
12129 enqueueCapturedUpdate(workInProgress, _update2);
12130 return;
12131 }
12132
12133 break;
12134 }
12135
12136 workInProgress = workInProgress.return;
12137 } while (workInProgress !== null);
12138 }
12139
12140 var ceil = Math.ceil;
12141 var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher,
12142 ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner,
12143 IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;
12144 var NoContext =
12145 /* */
12146 0;
12147 var BatchedContext =
12148 /* */
12149 1;
12150 var DiscreteEventContext =
12151 /* */
12152 4;
12153 var LegacyUnbatchedContext =
12154 /* */
12155 8;
12156 var RenderContext =
12157 /* */
12158 16;
12159 var CommitContext =
12160 /* */
12161 32;
12162 var RootIncomplete = 0;
12163 var RootFatalErrored = 1;
12164 var RootErrored = 2;
12165 var RootSuspended = 3;
12166 var RootSuspendedWithDelay = 4;
12167 var RootCompleted = 5;
12168 // Describes where we are in the React execution stack
12169 var executionContext = NoContext; // The root we're working on
12170
12171 var workInProgressRoot = null; // The fiber we're working on
12172
12173 var workInProgress = null; // The expiration time we're rendering
12174
12175 var renderExpirationTime$1 = NoWork; // Whether to root completed, errored, suspended, etc.
12176
12177 var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown
12178
12179 var workInProgressRootFatalError = null; // Most recent event time among processed updates during this render.
12180 // This is conceptually a time stamp but expressed in terms of an ExpirationTime
12181 // because we deal mostly with expiration times in the hot path, so this avoids
12182 // the conversion happening in the hot path.
12183
12184 var workInProgressRootLatestProcessedExpirationTime = Sync;
12185 var workInProgressRootLatestSuspenseTimeout = Sync;
12186 var workInProgressRootCanSuspendUsingConfig = null; // The work left over by components that were visited during this render. Only
12187 // includes unprocessed updates, not work in bailed out children.
12188
12189 var workInProgressRootNextUnprocessedUpdateTime = NoWork; // If we're pinged while rendering we don't always restart immediately.
12190 // This flag determines if it might be worthwhile to restart if an opportunity
12191 // happens latere.
12192
12193 var workInProgressRootHasPendingPing = false; // The most recent time we committed a fallback. This lets us ensure a train
12194 // model where we don't commit new loading states in too quick succession.
12195
12196 var globalMostRecentFallbackTime = 0;
12197 var FALLBACK_THROTTLE_MS = 500;
12198 var nextEffect = null;
12199 var hasUncaughtError = false;
12200 var firstUncaughtError = null;
12201 var legacyErrorBoundariesThatAlreadyFailed = null;
12202 var rootDoesHavePassiveEffects = false;
12203 var rootWithPendingPassiveEffects = null;
12204 var pendingPassiveEffectsRenderPriority = NoPriority;
12205 var pendingPassiveEffectsExpirationTime = NoWork;
12206 var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates
12207
12208 var NESTED_UPDATE_LIMIT = 50;
12209 var nestedUpdateCount = 0;
12210 var rootWithNestedUpdates = null;
12211 var NESTED_PASSIVE_UPDATE_LIMIT = 50;
12212 var nestedPassiveUpdateCount = 0;
12213 var interruptedBy = null; // Marks the need to reschedule pending interactions at these expiration times
12214 // during the commit phase. This enables them to be traced across components
12215 // that spawn new work during render. E.g. hidden boundaries, suspended SSR
12216 // hydration or SuspenseList.
12217
12218 var spawnedWorkDuringRender = null; // Expiration times are computed by adding to the current time (the start
12219 // time). However, if two updates are scheduled within the same event, we
12220 // should treat their start times as simultaneous, even if the actual clock
12221 // time has advanced between the first and second call.
12222 // In other words, because expiration times determine how updates are batched,
12223 // we want all updates of like priority that occur within the same event to
12224 // receive the same expiration time. Otherwise we get tearing.
12225
12226 var currentEventTime = NoWork;
12227 function requestCurrentTimeForUpdate() {
12228 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
12229 // We're inside React, so it's fine to read the actual time.
12230 return msToExpirationTime(now());
12231 } // We're not inside React, so we may be in the middle of a browser event.
12232
12233
12234 if (currentEventTime !== NoWork) {
12235 // Use the same start time for all updates until we enter React again.
12236 return currentEventTime;
12237 } // This is the first update since React yielded. Compute a new start time.
12238
12239
12240 currentEventTime = msToExpirationTime(now());
12241 return currentEventTime;
12242 }
12243 function getCurrentTime() {
12244 return msToExpirationTime(now());
12245 }
12246 function computeExpirationForFiber(currentTime, fiber, suspenseConfig) {
12247 var mode = fiber.mode;
12248
12249 if ((mode & BlockingMode) === NoMode) {
12250 return Sync;
12251 }
12252
12253 var priorityLevel = getCurrentPriorityLevel();
12254
12255 if ((mode & ConcurrentMode) === NoMode) {
12256 return priorityLevel === ImmediatePriority ? Sync : Batched;
12257 }
12258
12259 if ((executionContext & RenderContext) !== NoContext) {
12260 // Use whatever time we're already rendering
12261 // TODO: Should there be a way to opt out, like with `runWithPriority`?
12262 return renderExpirationTime$1;
12263 }
12264
12265 var expirationTime;
12266
12267 if (suspenseConfig !== null) {
12268 // Compute an expiration time based on the Suspense timeout.
12269 expirationTime = computeSuspenseExpiration(currentTime, suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
12270 } else {
12271 // Compute an expiration time based on the Scheduler priority.
12272 switch (priorityLevel) {
12273 case ImmediatePriority:
12274 expirationTime = Sync;
12275 break;
12276
12277 case UserBlockingPriority:
12278 // TODO: Rename this to computeUserBlockingExpiration
12279 expirationTime = computeInteractiveExpiration(currentTime);
12280 break;
12281
12282 case NormalPriority:
12283 case LowPriority:
12284 // TODO: Handle LowPriority
12285 // TODO: Rename this to... something better.
12286 expirationTime = computeAsyncExpiration(currentTime);
12287 break;
12288
12289 case IdlePriority:
12290 expirationTime = Idle;
12291 break;
12292
12293 default:
12294 {
12295 {
12296 throw Error( "Expected a valid priority level" );
12297 }
12298 }
12299
12300 }
12301 } // If we're in the middle of rendering a tree, do not update at the same
12302 // expiration time that is already rendering.
12303 // TODO: We shouldn't have to do this if the update is on a different root.
12304 // Refactor computeExpirationForFiber + scheduleUpdate so we have access to
12305 // the root when we check for this condition.
12306
12307
12308 if (workInProgressRoot !== null && expirationTime === renderExpirationTime$1) {
12309 // This is a trick to move this update into a separate batch
12310 expirationTime -= 1;
12311 }
12312
12313 return expirationTime;
12314 }
12315 function scheduleUpdateOnFiber(fiber, expirationTime) {
12316 checkForNestedUpdates();
12317 warnAboutRenderPhaseUpdatesInDEV(fiber);
12318 var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);
12319
12320 if (root === null) {
12321 warnAboutUpdateOnUnmountedFiberInDEV(fiber);
12322 return;
12323 }
12324
12325 checkForInterruption(fiber, expirationTime);
12326 recordScheduleUpdate(); // TODO: computeExpirationForFiber also reads the priority. Pass the
12327 // priority as an argument to that function and this one.
12328
12329 var priorityLevel = getCurrentPriorityLevel();
12330
12331 if (expirationTime === Sync) {
12332 if ( // Check if we're inside unbatchedUpdates
12333 (executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering
12334 (executionContext & (RenderContext | CommitContext)) === NoContext) {
12335 // Register pending interactions on the root to avoid losing traced interaction data.
12336 schedulePendingInteractions(root, expirationTime); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed
12337 // root inside of batchedUpdates should be synchronous, but layout updates
12338 // should be deferred until the end of the batch.
12339
12340 performSyncWorkOnRoot(root);
12341 } else {
12342 ensureRootIsScheduled(root);
12343 schedulePendingInteractions(root, expirationTime);
12344
12345 if (executionContext === NoContext) {
12346 // Flush the synchronous work now, unless we're already working or inside
12347 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
12348 // scheduleCallbackForFiber to preserve the ability to schedule a callback
12349 // without immediately flushing it. We only do this for user-initiated
12350 // updates, to preserve historical behavior of legacy mode.
12351 flushSyncCallbackQueue();
12352 }
12353 }
12354 } else {
12355 ensureRootIsScheduled(root);
12356 schedulePendingInteractions(root, expirationTime);
12357 }
12358
12359 if ((executionContext & DiscreteEventContext) !== NoContext && ( // Only updates at user-blocking priority or greater are considered
12360 // discrete, even inside a discrete event.
12361 priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority)) {
12362 // This is the result of a discrete event. Track the lowest priority
12363 // discrete update per root so we can flush them early, if needed.
12364 if (rootsWithPendingDiscreteUpdates === null) {
12365 rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);
12366 } else {
12367 var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);
12368
12369 if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {
12370 rootsWithPendingDiscreteUpdates.set(root, expirationTime);
12371 }
12372 }
12373 }
12374 }
12375 var scheduleWork = scheduleUpdateOnFiber; // This is split into a separate function so we can mark a fiber with pending
12376 // work without treating it as a typical update that originates from an event;
12377 // e.g. retrying a Suspense boundary isn't an update, but it does schedule work
12378 // on a fiber.
12379
12380 function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
12381 // Update the source fiber's expiration time
12382 if (fiber.expirationTime < expirationTime) {
12383 fiber.expirationTime = expirationTime;
12384 }
12385
12386 var alternate = fiber.alternate;
12387
12388 if (alternate !== null && alternate.expirationTime < expirationTime) {
12389 alternate.expirationTime = expirationTime;
12390 } // Walk the parent path to the root and update the child expiration time.
12391
12392
12393 var node = fiber.return;
12394 var root = null;
12395
12396 if (node === null && fiber.tag === HostRoot) {
12397 root = fiber.stateNode;
12398 } else {
12399 while (node !== null) {
12400 alternate = node.alternate;
12401
12402 if (node.childExpirationTime < expirationTime) {
12403 node.childExpirationTime = expirationTime;
12404
12405 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
12406 alternate.childExpirationTime = expirationTime;
12407 }
12408 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
12409 alternate.childExpirationTime = expirationTime;
12410 }
12411
12412 if (node.return === null && node.tag === HostRoot) {
12413 root = node.stateNode;
12414 break;
12415 }
12416
12417 node = node.return;
12418 }
12419 }
12420
12421 if (root !== null) {
12422 if (workInProgressRoot === root) {
12423 // Received an update to a tree that's in the middle of rendering. Mark
12424 // that's unprocessed work on this root.
12425 markUnprocessedUpdateTime(expirationTime);
12426
12427 if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
12428 // The root already suspended with a delay, which means this render
12429 // definitely won't finish. Since we have a new update, let's mark it as
12430 // suspended now, right before marking the incoming update. This has the
12431 // effect of interrupting the current render and switching to the update.
12432 // TODO: This happens to work when receiving an update during the render
12433 // phase, because of the trick inside computeExpirationForFiber to
12434 // subtract 1 from `renderExpirationTime` to move it into a
12435 // separate bucket. But we should probably model it with an exception,
12436 // using the same mechanism we use to force hydration of a subtree.
12437 // TODO: This does not account for low pri updates that were already
12438 // scheduled before the root started rendering. Need to track the next
12439 // pending expiration time (perhaps by backtracking the return path) and
12440 // then trigger a restart in the `renderDidSuspendDelayIfPossible` path.
12441 markRootSuspendedAtTime(root, renderExpirationTime$1);
12442 }
12443 } // Mark that the root has a pending update.
12444
12445
12446 markRootUpdatedAtTime(root, expirationTime);
12447 }
12448
12449 return root;
12450 }
12451
12452 function getNextRootExpirationTimeToWorkOn(root) {
12453 // Determines the next expiration time that the root should render, taking
12454 // into account levels that may be suspended, or levels that may have
12455 // received a ping.
12456 var lastExpiredTime = root.lastExpiredTime;
12457
12458 if (lastExpiredTime !== NoWork) {
12459 return lastExpiredTime;
12460 } // "Pending" refers to any update that hasn't committed yet, including if it
12461 // suspended. The "suspended" range is therefore a subset.
12462
12463
12464 var firstPendingTime = root.firstPendingTime;
12465
12466 if (!isRootSuspendedAtTime(root, firstPendingTime)) {
12467 // The highest priority pending time is not suspended. Let's work on that.
12468 return firstPendingTime;
12469 } // If the first pending time is suspended, check if there's a lower priority
12470 // pending level that we know about. Or check if we received a ping. Work
12471 // on whichever is higher priority.
12472
12473
12474 var lastPingedTime = root.lastPingedTime;
12475 var nextKnownPendingLevel = root.nextKnownPendingLevel;
12476 var nextLevel = lastPingedTime > nextKnownPendingLevel ? lastPingedTime : nextKnownPendingLevel;
12477
12478 if ( nextLevel <= Idle && firstPendingTime !== nextLevel) {
12479 // Don't work on Idle/Never priority unless everything else is committed.
12480 return NoWork;
12481 }
12482
12483 return nextLevel;
12484 } // Use this function to schedule a task for a root. There's only one task per
12485 // root; if a task was already scheduled, we'll check to make sure the
12486 // expiration time of the existing task is the same as the expiration time of
12487 // the next level that the root has work on. This function is called on every
12488 // update, and right before exiting a task.
12489
12490
12491 function ensureRootIsScheduled(root) {
12492 var lastExpiredTime = root.lastExpiredTime;
12493
12494 if (lastExpiredTime !== NoWork) {
12495 // Special case: Expired work should flush synchronously.
12496 root.callbackExpirationTime = Sync;
12497 root.callbackPriority = ImmediatePriority;
12498 root.callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
12499 return;
12500 }
12501
12502 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
12503 var existingCallbackNode = root.callbackNode;
12504
12505 if (expirationTime === NoWork) {
12506 // There's nothing to work on.
12507 if (existingCallbackNode !== null) {
12508 root.callbackNode = null;
12509 root.callbackExpirationTime = NoWork;
12510 root.callbackPriority = NoPriority;
12511 }
12512
12513 return;
12514 } // TODO: If this is an update, we already read the current time. Pass the
12515 // time as an argument.
12516
12517
12518 var currentTime = requestCurrentTimeForUpdate();
12519 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime); // If there's an existing render task, confirm it has the correct priority and
12520 // expiration time. Otherwise, we'll cancel it and schedule a new one.
12521
12522 if (existingCallbackNode !== null) {
12523 var existingCallbackPriority = root.callbackPriority;
12524 var existingCallbackExpirationTime = root.callbackExpirationTime;
12525
12526 if ( // Callback must have the exact same expiration time.
12527 existingCallbackExpirationTime === expirationTime && // Callback must have greater or equal priority.
12528 existingCallbackPriority >= priorityLevel) {
12529 // Existing callback is sufficient.
12530 return;
12531 } // Need to schedule a new task.
12532 // TODO: Instead of scheduling a new task, we should be able to change the
12533 // priority of the existing one.
12534
12535
12536 cancelCallback(existingCallbackNode);
12537 }
12538
12539 root.callbackExpirationTime = expirationTime;
12540 root.callbackPriority = priorityLevel;
12541 var callbackNode;
12542
12543 if (expirationTime === Sync) {
12544 // Sync React callbacks are scheduled on a special internal queue
12545 callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
12546 } else {
12547 callbackNode = scheduleCallback(priorityLevel, performConcurrentWorkOnRoot.bind(null, root), // Compute a task timeout based on the expiration time. This also affects
12548 // ordering because tasks are processed in timeout order.
12549 {
12550 timeout: expirationTimeToMs(expirationTime) - now()
12551 });
12552 }
12553
12554 root.callbackNode = callbackNode;
12555 } // This is the entry point for every concurrent task, i.e. anything that
12556 // goes through Scheduler.
12557
12558
12559 function performConcurrentWorkOnRoot(root, didTimeout) {
12560 // Since we know we're in a React event, we can clear the current
12561 // event time. The next update will compute a new event time.
12562 currentEventTime = NoWork;
12563
12564 if (didTimeout) {
12565 // The render task took too long to complete. Mark the current time as
12566 // expired to synchronously render all expired work in a single batch.
12567 var currentTime = requestCurrentTimeForUpdate();
12568 markRootExpiredAtTime(root, currentTime); // This will schedule a synchronous callback.
12569
12570 ensureRootIsScheduled(root);
12571 return null;
12572 } // Determine the next expiration time to work on, using the fields stored
12573 // on the root.
12574
12575
12576 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
12577
12578 if (expirationTime !== NoWork) {
12579 var originalCallbackNode = root.callbackNode;
12580
12581 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
12582 {
12583 throw Error( "Should not already be working." );
12584 }
12585 }
12586
12587 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
12588 // and prepare a fresh one. Otherwise we'll continue where we left off.
12589
12590 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) {
12591 prepareFreshStack(root, expirationTime);
12592 startWorkOnPendingInteractions(root, expirationTime);
12593 } // If we have a work-in-progress fiber, it means there's still work to do
12594 // in this root.
12595
12596
12597 if (workInProgress !== null) {
12598 var prevExecutionContext = executionContext;
12599 executionContext |= RenderContext;
12600 var prevDispatcher = pushDispatcher();
12601 var prevInteractions = pushInteractions(root);
12602 startWorkLoopTimer(workInProgress);
12603
12604 do {
12605 try {
12606 workLoopConcurrent();
12607 break;
12608 } catch (thrownValue) {
12609 handleError(root, thrownValue);
12610 }
12611 } while (true);
12612
12613 resetContextDependencies();
12614 executionContext = prevExecutionContext;
12615 popDispatcher(prevDispatcher);
12616
12617 {
12618 popInteractions(prevInteractions);
12619 }
12620
12621 if (workInProgressRootExitStatus === RootFatalErrored) {
12622 var fatalError = workInProgressRootFatalError;
12623 stopInterruptedWorkLoopTimer();
12624 prepareFreshStack(root, expirationTime);
12625 markRootSuspendedAtTime(root, expirationTime);
12626 ensureRootIsScheduled(root);
12627 throw fatalError;
12628 }
12629
12630 if (workInProgress !== null) {
12631 // There's still work left over. Exit without committing.
12632 stopInterruptedWorkLoopTimer();
12633 } else {
12634 // We now have a consistent tree. The next step is either to commit it,
12635 // or, if something suspended, wait to commit it after a timeout.
12636 stopFinishedWorkLoopTimer();
12637 var finishedWork = root.finishedWork = root.current.alternate;
12638 root.finishedExpirationTime = expirationTime;
12639 finishConcurrentRender(root, finishedWork, workInProgressRootExitStatus, expirationTime);
12640 }
12641
12642 ensureRootIsScheduled(root);
12643
12644 if (root.callbackNode === originalCallbackNode) {
12645 // The task node scheduled for this root is the same one that's
12646 // currently executed. Need to return a continuation.
12647 return performConcurrentWorkOnRoot.bind(null, root);
12648 }
12649 }
12650 }
12651
12652 return null;
12653 }
12654
12655 function finishConcurrentRender(root, finishedWork, exitStatus, expirationTime) {
12656 // Set this to null to indicate there's no in-progress render.
12657 workInProgressRoot = null;
12658
12659 switch (exitStatus) {
12660 case RootIncomplete:
12661 case RootFatalErrored:
12662 {
12663 {
12664 {
12665 throw Error( "Root did not complete. This is a bug in React." );
12666 }
12667 }
12668 }
12669 // Flow knows about invariant, so it complains if I add a break
12670 // statement, but eslint doesn't know about invariant, so it complains
12671 // if I do. eslint-disable-next-line no-fallthrough
12672
12673 case RootErrored:
12674 {
12675 // If this was an async render, the error may have happened due to
12676 // a mutation in a concurrent event. Try rendering one more time,
12677 // synchronously, to see if the error goes away. If there are
12678 // lower priority updates, let's include those, too, in case they
12679 // fix the inconsistency. Render at Idle to include all updates.
12680 // If it was Idle or Never or some not-yet-invented time, render
12681 // at that time.
12682 markRootExpiredAtTime(root, expirationTime > Idle ? Idle : expirationTime); // We assume that this second render pass will be synchronous
12683 // and therefore not hit this path again.
12684
12685 break;
12686 }
12687
12688 case RootSuspended:
12689 {
12690 markRootSuspendedAtTime(root, expirationTime);
12691 var lastSuspendedTime = root.lastSuspendedTime;
12692
12693 if (expirationTime === lastSuspendedTime) {
12694 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
12695 } // We have an acceptable loading state. We need to figure out if we
12696 // should immediately commit it or wait a bit.
12697 // If we have processed new updates during this render, we may now
12698 // have a new loading state ready. We want to ensure that we commit
12699 // that as soon as possible.
12700
12701
12702 var hasNotProcessedNewUpdates = workInProgressRootLatestProcessedExpirationTime === Sync;
12703
12704 if (hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope
12705 !( IsThisRendererActing.current)) {
12706 // If we have not processed any new updates during this pass, then
12707 // this is either a retry of an existing fallback state or a
12708 // hidden tree. Hidden trees shouldn't be batched with other work
12709 // and after that's fixed it can only be a retry. We're going to
12710 // throttle committing retries so that we don't show too many
12711 // loading states too quickly.
12712 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.
12713
12714 if (msUntilTimeout > 10) {
12715 if (workInProgressRootHasPendingPing) {
12716 var lastPingedTime = root.lastPingedTime;
12717
12718 if (lastPingedTime === NoWork || lastPingedTime >= expirationTime) {
12719 // This render was pinged but we didn't get to restart
12720 // earlier so try restarting now instead.
12721 root.lastPingedTime = expirationTime;
12722 prepareFreshStack(root, expirationTime);
12723 break;
12724 }
12725 }
12726
12727 var nextTime = getNextRootExpirationTimeToWorkOn(root);
12728
12729 if (nextTime !== NoWork && nextTime !== expirationTime) {
12730 // There's additional work on this root.
12731 break;
12732 }
12733
12734 if (lastSuspendedTime !== NoWork && lastSuspendedTime !== expirationTime) {
12735 // We should prefer to render the fallback of at the last
12736 // suspended level. Ping the last suspended level to try
12737 // rendering it again.
12738 root.lastPingedTime = lastSuspendedTime;
12739 break;
12740 } // The render is suspended, it hasn't timed out, and there's no
12741 // lower priority work to do. Instead of committing the fallback
12742 // immediately, wait for more data to arrive.
12743
12744
12745 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);
12746 break;
12747 }
12748 } // The work expired. Commit immediately.
12749
12750
12751 commitRoot(root);
12752 break;
12753 }
12754
12755 case RootSuspendedWithDelay:
12756 {
12757 markRootSuspendedAtTime(root, expirationTime);
12758 var _lastSuspendedTime = root.lastSuspendedTime;
12759
12760 if (expirationTime === _lastSuspendedTime) {
12761 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
12762 }
12763
12764 {
12765 // We're suspended in a state that should be avoided. We'll try to
12766 // avoid committing it for as long as the timeouts let us.
12767 if (workInProgressRootHasPendingPing) {
12768 var _lastPingedTime = root.lastPingedTime;
12769
12770 if (_lastPingedTime === NoWork || _lastPingedTime >= expirationTime) {
12771 // This render was pinged but we didn't get to restart earlier
12772 // so try restarting now instead.
12773 root.lastPingedTime = expirationTime;
12774 prepareFreshStack(root, expirationTime);
12775 break;
12776 }
12777 }
12778
12779 var _nextTime = getNextRootExpirationTimeToWorkOn(root);
12780
12781 if (_nextTime !== NoWork && _nextTime !== expirationTime) {
12782 // There's additional work on this root.
12783 break;
12784 }
12785
12786 if (_lastSuspendedTime !== NoWork && _lastSuspendedTime !== expirationTime) {
12787 // We should prefer to render the fallback of at the last
12788 // suspended level. Ping the last suspended level to try
12789 // rendering it again.
12790 root.lastPingedTime = _lastSuspendedTime;
12791 break;
12792 }
12793
12794 var _msUntilTimeout;
12795
12796 if (workInProgressRootLatestSuspenseTimeout !== Sync) {
12797 // We have processed a suspense config whose expiration time we
12798 // can use as the timeout.
12799 _msUntilTimeout = expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now();
12800 } else if (workInProgressRootLatestProcessedExpirationTime === Sync) {
12801 // This should never normally happen because only new updates
12802 // cause delayed states, so we should have processed something.
12803 // However, this could also happen in an offscreen tree.
12804 _msUntilTimeout = 0;
12805 } else {
12806 // If we don't have a suspense config, we're going to use a
12807 // heuristic to determine how long we can suspend.
12808 var eventTimeMs = inferTimeFromExpirationTime(workInProgressRootLatestProcessedExpirationTime);
12809 var currentTimeMs = now();
12810 var timeUntilExpirationMs = expirationTimeToMs(expirationTime) - currentTimeMs;
12811 var timeElapsed = currentTimeMs - eventTimeMs;
12812
12813 if (timeElapsed < 0) {
12814 // We get this wrong some time since we estimate the time.
12815 timeElapsed = 0;
12816 }
12817
12818 _msUntilTimeout = jnd(timeElapsed) - timeElapsed; // Clamp the timeout to the expiration time. TODO: Once the
12819 // event time is exact instead of inferred from expiration time
12820 // we don't need this.
12821
12822 if (timeUntilExpirationMs < _msUntilTimeout) {
12823 _msUntilTimeout = timeUntilExpirationMs;
12824 }
12825 } // Don't bother with a very short suspense time.
12826
12827
12828 if (_msUntilTimeout > 10) {
12829 // The render is suspended, it hasn't timed out, and there's no
12830 // lower priority work to do. Instead of committing the fallback
12831 // immediately, wait for more data to arrive.
12832 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);
12833 break;
12834 }
12835 } // The work expired. Commit immediately.
12836
12837
12838 commitRoot(root);
12839 break;
12840 }
12841
12842 case RootCompleted:
12843 {
12844 // The work completed. Ready to commit.
12845 if ( // do not delay if we're inside an act() scope
12846 workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null) {
12847 // If we have exceeded the minimum loading delay, which probably
12848 // means we have shown a spinner already, we might have to suspend
12849 // a bit longer to ensure that the spinner is shown for
12850 // enough time.
12851 var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay(workInProgressRootLatestProcessedExpirationTime, expirationTime, workInProgressRootCanSuspendUsingConfig);
12852
12853 if (_msUntilTimeout2 > 10) {
12854 markRootSuspendedAtTime(root, expirationTime);
12855 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout2);
12856 break;
12857 }
12858 }
12859
12860 commitRoot(root);
12861 break;
12862 }
12863
12864 default:
12865 {
12866 {
12867 {
12868 throw Error( "Unknown root exit status." );
12869 }
12870 }
12871 }
12872 }
12873 } // This is the entry point for synchronous tasks that don't go
12874 // through Scheduler
12875
12876
12877 function performSyncWorkOnRoot(root) {
12878 // Check if there's expired work on this root. Otherwise, render at Sync.
12879 var lastExpiredTime = root.lastExpiredTime;
12880 var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync;
12881
12882 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
12883 {
12884 throw Error( "Should not already be working." );
12885 }
12886 }
12887
12888 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
12889 // and prepare a fresh one. Otherwise we'll continue where we left off.
12890
12891 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime$1) {
12892 prepareFreshStack(root, expirationTime);
12893 startWorkOnPendingInteractions(root, expirationTime);
12894 } // If we have a work-in-progress fiber, it means there's still work to do
12895 // in this root.
12896
12897
12898 if (workInProgress !== null) {
12899 var prevExecutionContext = executionContext;
12900 executionContext |= RenderContext;
12901 var prevDispatcher = pushDispatcher();
12902 var prevInteractions = pushInteractions(root);
12903 startWorkLoopTimer(workInProgress);
12904
12905 do {
12906 try {
12907 workLoopSync();
12908 break;
12909 } catch (thrownValue) {
12910 handleError(root, thrownValue);
12911 }
12912 } while (true);
12913
12914 resetContextDependencies();
12915 executionContext = prevExecutionContext;
12916 popDispatcher(prevDispatcher);
12917
12918 {
12919 popInteractions(prevInteractions);
12920 }
12921
12922 if (workInProgressRootExitStatus === RootFatalErrored) {
12923 var fatalError = workInProgressRootFatalError;
12924 stopInterruptedWorkLoopTimer();
12925 prepareFreshStack(root, expirationTime);
12926 markRootSuspendedAtTime(root, expirationTime);
12927 ensureRootIsScheduled(root);
12928 throw fatalError;
12929 }
12930
12931 if (workInProgress !== null) {
12932 // This is a sync render, so we should have finished the whole tree.
12933 {
12934 {
12935 throw Error( "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." );
12936 }
12937 }
12938 } else {
12939 // We now have a consistent tree. Because this is a sync render, we
12940 // will commit it even if something suspended.
12941 stopFinishedWorkLoopTimer();
12942 root.finishedWork = root.current.alternate;
12943 root.finishedExpirationTime = expirationTime;
12944 finishSyncRender(root);
12945 } // Before exiting, make sure there's a callback scheduled for the next
12946 // pending level.
12947
12948
12949 ensureRootIsScheduled(root);
12950 }
12951
12952 return null;
12953 }
12954
12955 function finishSyncRender(root) {
12956 // Set this to null to indicate there's no in-progress render.
12957 workInProgressRoot = null;
12958 commitRoot(root);
12959 }
12960 function syncUpdates(fn, a, b, c) {
12961 return runWithPriority(ImmediatePriority, fn.bind(null, a, b, c));
12962 }
12963 function flushSync(fn, a) {
12964 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
12965 {
12966 {
12967 throw Error( "flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering." );
12968 }
12969 }
12970 }
12971
12972 var prevExecutionContext = executionContext;
12973 executionContext |= BatchedContext;
12974
12975 try {
12976 return runWithPriority(ImmediatePriority, fn.bind(null, a));
12977 } finally {
12978 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
12979 // Note that this will happen even if batchedUpdates is higher up
12980 // the stack.
12981
12982 flushSyncCallbackQueue();
12983 }
12984 }
12985
12986 function prepareFreshStack(root, expirationTime) {
12987 root.finishedWork = null;
12988 root.finishedExpirationTime = NoWork;
12989 var timeoutHandle = root.timeoutHandle;
12990
12991 if (timeoutHandle !== noTimeout) {
12992 // The root previous suspended and scheduled a timeout to commit a fallback
12993 // state. Now that we have additional work, cancel the timeout.
12994 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
12995
12996 cancelTimeout(timeoutHandle);
12997 }
12998
12999 if (workInProgress !== null) {
13000 var interruptedWork = workInProgress.return;
13001
13002 while (interruptedWork !== null) {
13003 unwindInterruptedWork(interruptedWork);
13004 interruptedWork = interruptedWork.return;
13005 }
13006 }
13007
13008 workInProgressRoot = root;
13009 workInProgress = createWorkInProgress(root.current, null);
13010 renderExpirationTime$1 = expirationTime;
13011 workInProgressRootExitStatus = RootIncomplete;
13012 workInProgressRootFatalError = null;
13013 workInProgressRootLatestProcessedExpirationTime = Sync;
13014 workInProgressRootLatestSuspenseTimeout = Sync;
13015 workInProgressRootCanSuspendUsingConfig = null;
13016 workInProgressRootNextUnprocessedUpdateTime = NoWork;
13017 workInProgressRootHasPendingPing = false;
13018
13019 {
13020 spawnedWorkDuringRender = null;
13021 }
13022
13023 {
13024 ReactStrictModeWarnings.discardPendingWarnings();
13025 }
13026 }
13027
13028 function handleError(root, thrownValue) {
13029 do {
13030 try {
13031 // Reset module-level state that was set during the render phase.
13032 resetContextDependencies();
13033 resetHooksAfterThrow();
13034 resetCurrentFiber();
13035
13036 if (workInProgress === null || workInProgress.return === null) {
13037 // Expected to be working on a non-root fiber. This is a fatal error
13038 // because there's no ancestor that can handle it; the root is
13039 // supposed to capture all errors that weren't caught by an error
13040 // boundary.
13041 workInProgressRootExitStatus = RootFatalErrored;
13042 workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next
13043 // sibling, or the parent if there are no siblings. But since the root
13044 // has no siblings nor a parent, we set it to null. Usually this is
13045 // handled by `completeUnitOfWork` or `unwindWork`, but since we're
13046 // interntionally not calling those, we need set it here.
13047 // TODO: Consider calling `unwindWork` to pop the contexts.
13048
13049 workInProgress = null;
13050 return null;
13051 }
13052
13053 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
13054 // Record the time spent rendering before an error was thrown. This
13055 // avoids inaccurate Profiler durations in the case of a
13056 // suspended render.
13057 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
13058 }
13059
13060 throwException(root, workInProgress.return, workInProgress, thrownValue, renderExpirationTime$1);
13061 workInProgress = completeUnitOfWork(workInProgress);
13062 } catch (yetAnotherThrownValue) {
13063 // Something in the return path also threw.
13064 thrownValue = yetAnotherThrownValue;
13065 continue;
13066 } // Return to the normal work loop.
13067
13068
13069 return;
13070 } while (true);
13071 }
13072
13073 function pushDispatcher(root) {
13074 var prevDispatcher = ReactCurrentDispatcher$1.current;
13075 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
13076
13077 if (prevDispatcher === null) {
13078 // The React isomorphic package does not include a default dispatcher.
13079 // Instead the first renderer will lazily attach one, in order to give
13080 // nicer error messages.
13081 return ContextOnlyDispatcher;
13082 } else {
13083 return prevDispatcher;
13084 }
13085 }
13086
13087 function popDispatcher(prevDispatcher) {
13088 ReactCurrentDispatcher$1.current = prevDispatcher;
13089 }
13090
13091 function pushInteractions(root) {
13092 {
13093 var prevInteractions = __interactionsRef.current;
13094 __interactionsRef.current = root.memoizedInteractions;
13095 return prevInteractions;
13096 }
13097 }
13098
13099 function popInteractions(prevInteractions) {
13100 {
13101 __interactionsRef.current = prevInteractions;
13102 }
13103 }
13104
13105 function markCommitTimeOfFallback() {
13106 globalMostRecentFallbackTime = now();
13107 }
13108 function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) {
13109 if (expirationTime < workInProgressRootLatestProcessedExpirationTime && expirationTime > Idle) {
13110 workInProgressRootLatestProcessedExpirationTime = expirationTime;
13111 }
13112
13113 if (suspenseConfig !== null) {
13114 if (expirationTime < workInProgressRootLatestSuspenseTimeout && expirationTime > Idle) {
13115 workInProgressRootLatestSuspenseTimeout = expirationTime; // Most of the time we only have one config and getting wrong is not bad.
13116
13117 workInProgressRootCanSuspendUsingConfig = suspenseConfig;
13118 }
13119 }
13120 }
13121 function markUnprocessedUpdateTime(expirationTime) {
13122 if (expirationTime > workInProgressRootNextUnprocessedUpdateTime) {
13123 workInProgressRootNextUnprocessedUpdateTime = expirationTime;
13124 }
13125 }
13126 function renderDidSuspend() {
13127 if (workInProgressRootExitStatus === RootIncomplete) {
13128 workInProgressRootExitStatus = RootSuspended;
13129 }
13130 }
13131 function renderDidSuspendDelayIfPossible() {
13132 if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {
13133 workInProgressRootExitStatus = RootSuspendedWithDelay;
13134 } // Check if there's a lower priority update somewhere else in the tree.
13135
13136
13137 if (workInProgressRootNextUnprocessedUpdateTime !== NoWork && workInProgressRoot !== null) {
13138 // Mark the current render as suspended, and then mark that there's a
13139 // pending update.
13140 // TODO: This should immediately interrupt the current render, instead
13141 // of waiting until the next time we yield.
13142 markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime$1);
13143 markRootUpdatedAtTime(workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime);
13144 }
13145 }
13146 function renderDidError() {
13147 if (workInProgressRootExitStatus !== RootCompleted) {
13148 workInProgressRootExitStatus = RootErrored;
13149 }
13150 } // Called during render to determine if anything has suspended.
13151 // Returns false if we're not sure.
13152
13153 function renderHasNotSuspendedYet() {
13154 // If something errored or completed, we can't really be sure,
13155 // so those are false.
13156 return workInProgressRootExitStatus === RootIncomplete;
13157 }
13158
13159 function inferTimeFromExpirationTime(expirationTime) {
13160 // We don't know exactly when the update was scheduled, but we can infer an
13161 // approximate start time from the expiration time.
13162 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
13163 return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
13164 }
13165
13166 function inferTimeFromExpirationTimeWithSuspenseConfig(expirationTime, suspenseConfig) {
13167 // We don't know exactly when the update was scheduled, but we can infer an
13168 // approximate start time from the expiration time by subtracting the timeout
13169 // that was added to the event time.
13170 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
13171 return earliestExpirationTimeMs - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
13172 } // The work loop is an extremely hot path. Tell Closure not to inline it.
13173
13174 /** @noinline */
13175
13176
13177 function workLoopSync() {
13178 // Already timed out, so perform work without checking if we need to yield.
13179 while (workInProgress !== null) {
13180 workInProgress = performUnitOfWork(workInProgress);
13181 }
13182 }
13183 /** @noinline */
13184
13185
13186 function workLoopConcurrent() {
13187 // Perform work until Scheduler asks us to yield
13188 while (workInProgress !== null && !shouldYield()) {
13189 workInProgress = performUnitOfWork(workInProgress);
13190 }
13191 }
13192
13193 function performUnitOfWork(unitOfWork) {
13194 // The current, flushed, state of this fiber is the alternate. Ideally
13195 // nothing should rely on this, but relying on it here means that we don't
13196 // need an additional field on the work in progress.
13197 var current = unitOfWork.alternate;
13198 startWorkTimer(unitOfWork);
13199 setCurrentFiber(unitOfWork);
13200 var next;
13201
13202 if ( (unitOfWork.mode & ProfileMode) !== NoMode) {
13203 startProfilerTimer(unitOfWork);
13204 next = beginWork$1(current, unitOfWork, renderExpirationTime$1);
13205 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
13206 } else {
13207 next = beginWork$1(current, unitOfWork, renderExpirationTime$1);
13208 }
13209
13210 resetCurrentFiber();
13211 unitOfWork.memoizedProps = unitOfWork.pendingProps;
13212
13213 if (next === null) {
13214 // If this doesn't spawn new work, complete the current work.
13215 next = completeUnitOfWork(unitOfWork);
13216 }
13217
13218 ReactCurrentOwner$2.current = null;
13219 return next;
13220 }
13221
13222 function completeUnitOfWork(unitOfWork) {
13223 // Attempt to complete the current unit of work, then move to the next
13224 // sibling. If there are no more siblings, return to the parent fiber.
13225 workInProgress = unitOfWork;
13226
13227 do {
13228 // The current, flushed, state of this fiber is the alternate. Ideally
13229 // nothing should rely on this, but relying on it here means that we don't
13230 // need an additional field on the work in progress.
13231 var current = workInProgress.alternate;
13232 var returnFiber = workInProgress.return; // Check if the work completed or if something threw.
13233
13234 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
13235 setCurrentFiber(workInProgress);
13236 var next = void 0;
13237
13238 if ( (workInProgress.mode & ProfileMode) === NoMode) {
13239 next = completeWork(current, workInProgress, renderExpirationTime$1);
13240 } else {
13241 startProfilerTimer(workInProgress);
13242 next = completeWork(current, workInProgress, renderExpirationTime$1); // Update render duration assuming we didn't error.
13243
13244 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
13245 }
13246
13247 stopWorkTimer(workInProgress);
13248 resetCurrentFiber();
13249 resetChildExpirationTime(workInProgress);
13250
13251 if (next !== null) {
13252 // Completing this fiber spawned new work. Work on that next.
13253 return next;
13254 }
13255
13256 if (returnFiber !== null && // Do not append effects to parents if a sibling failed to complete
13257 (returnFiber.effectTag & Incomplete) === NoEffect) {
13258 // Append all the effects of the subtree and this fiber onto the effect
13259 // list of the parent. The completion order of the children affects the
13260 // side-effect order.
13261 if (returnFiber.firstEffect === null) {
13262 returnFiber.firstEffect = workInProgress.firstEffect;
13263 }
13264
13265 if (workInProgress.lastEffect !== null) {
13266 if (returnFiber.lastEffect !== null) {
13267 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
13268 }
13269
13270 returnFiber.lastEffect = workInProgress.lastEffect;
13271 } // If this fiber had side-effects, we append it AFTER the children's
13272 // side-effects. We can perform certain side-effects earlier if needed,
13273 // by doing multiple passes over the effect list. We don't want to
13274 // schedule our own side-effect on our own list because if end up
13275 // reusing children we'll schedule this effect onto itself since we're
13276 // at the end.
13277
13278
13279 var effectTag = workInProgress.effectTag; // Skip both NoWork and PerformedWork tags when creating the effect
13280 // list. PerformedWork effect is read by React DevTools but shouldn't be
13281 // committed.
13282
13283 if (effectTag > PerformedWork) {
13284 if (returnFiber.lastEffect !== null) {
13285 returnFiber.lastEffect.nextEffect = workInProgress;
13286 } else {
13287 returnFiber.firstEffect = workInProgress;
13288 }
13289
13290 returnFiber.lastEffect = workInProgress;
13291 }
13292 }
13293 } else {
13294 // This fiber did not complete because something threw. Pop values off
13295 // the stack without entering the complete phase. If this is a boundary,
13296 // capture values if possible.
13297 var _next = unwindWork(workInProgress); // Because this fiber did not complete, don't reset its expiration time.
13298
13299
13300 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
13301 // Record the render duration for the fiber that errored.
13302 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); // Include the time spent working on failed children before continuing.
13303
13304 var actualDuration = workInProgress.actualDuration;
13305 var child = workInProgress.child;
13306
13307 while (child !== null) {
13308 actualDuration += child.actualDuration;
13309 child = child.sibling;
13310 }
13311
13312 workInProgress.actualDuration = actualDuration;
13313 }
13314
13315 if (_next !== null) {
13316 // If completing this work spawned new work, do that next. We'll come
13317 // back here again.
13318 // Since we're restarting, remove anything that is not a host effect
13319 // from the effect tag.
13320 // TODO: The name stopFailedWorkTimer is misleading because Suspense
13321 // also captures and restarts.
13322 stopFailedWorkTimer(workInProgress);
13323 _next.effectTag &= HostEffectMask;
13324 return _next;
13325 }
13326
13327 stopWorkTimer(workInProgress);
13328
13329 if (returnFiber !== null) {
13330 // Mark the parent fiber as incomplete and clear its effect list.
13331 returnFiber.firstEffect = returnFiber.lastEffect = null;
13332 returnFiber.effectTag |= Incomplete;
13333 }
13334 }
13335
13336 var siblingFiber = workInProgress.sibling;
13337
13338 if (siblingFiber !== null) {
13339 // If there is more work to do in this returnFiber, do that next.
13340 return siblingFiber;
13341 } // Otherwise, return to the parent
13342
13343
13344 workInProgress = returnFiber;
13345 } while (workInProgress !== null); // We've reached the root.
13346
13347
13348 if (workInProgressRootExitStatus === RootIncomplete) {
13349 workInProgressRootExitStatus = RootCompleted;
13350 }
13351
13352 return null;
13353 }
13354
13355 function getRemainingExpirationTime(fiber) {
13356 var updateExpirationTime = fiber.expirationTime;
13357 var childExpirationTime = fiber.childExpirationTime;
13358 return updateExpirationTime > childExpirationTime ? updateExpirationTime : childExpirationTime;
13359 }
13360
13361 function resetChildExpirationTime(completedWork) {
13362 if (renderExpirationTime$1 !== Never && completedWork.childExpirationTime === Never) {
13363 // The children of this component are hidden. Don't bubble their
13364 // expiration times.
13365 return;
13366 }
13367
13368 var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time.
13369
13370 if ( (completedWork.mode & ProfileMode) !== NoMode) {
13371 // In profiling mode, resetChildExpirationTime is also used to reset
13372 // profiler durations.
13373 var actualDuration = completedWork.actualDuration;
13374 var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will
13375 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
13376 // When work is done, it should bubble to the parent's actualDuration. If
13377 // the fiber has not been cloned though, (meaning no work was done), then
13378 // this value will reflect the amount of time spent working on a previous
13379 // render. In that case it should not bubble. We determine whether it was
13380 // cloned by comparing the child pointer.
13381
13382 var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;
13383 var child = completedWork.child;
13384
13385 while (child !== null) {
13386 var childUpdateExpirationTime = child.expirationTime;
13387 var childChildExpirationTime = child.childExpirationTime;
13388
13389 if (childUpdateExpirationTime > newChildExpirationTime) {
13390 newChildExpirationTime = childUpdateExpirationTime;
13391 }
13392
13393 if (childChildExpirationTime > newChildExpirationTime) {
13394 newChildExpirationTime = childChildExpirationTime;
13395 }
13396
13397 if (shouldBubbleActualDurations) {
13398 actualDuration += child.actualDuration;
13399 }
13400
13401 treeBaseDuration += child.treeBaseDuration;
13402 child = child.sibling;
13403 }
13404
13405 completedWork.actualDuration = actualDuration;
13406 completedWork.treeBaseDuration = treeBaseDuration;
13407 } else {
13408 var _child = completedWork.child;
13409
13410 while (_child !== null) {
13411 var _childUpdateExpirationTime = _child.expirationTime;
13412 var _childChildExpirationTime = _child.childExpirationTime;
13413
13414 if (_childUpdateExpirationTime > newChildExpirationTime) {
13415 newChildExpirationTime = _childUpdateExpirationTime;
13416 }
13417
13418 if (_childChildExpirationTime > newChildExpirationTime) {
13419 newChildExpirationTime = _childChildExpirationTime;
13420 }
13421
13422 _child = _child.sibling;
13423 }
13424 }
13425
13426 completedWork.childExpirationTime = newChildExpirationTime;
13427 }
13428
13429 function commitRoot(root) {
13430 var renderPriorityLevel = getCurrentPriorityLevel();
13431 runWithPriority(ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel));
13432 return null;
13433 }
13434
13435 function commitRootImpl(root, renderPriorityLevel) {
13436 do {
13437 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which
13438 // means `flushPassiveEffects` will sometimes result in additional
13439 // passive effects. So we need to keep flushing in a loop until there are
13440 // no more pending effects.
13441 // TODO: Might be better if `flushPassiveEffects` did not automatically
13442 // flush synchronous work at the end, to avoid factoring hazards like this.
13443 flushPassiveEffects();
13444 } while (rootWithPendingPassiveEffects !== null);
13445
13446 flushRenderPhaseStrictModeWarningsInDEV();
13447
13448 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
13449 {
13450 throw Error( "Should not already be working." );
13451 }
13452 }
13453
13454 var finishedWork = root.finishedWork;
13455 var expirationTime = root.finishedExpirationTime;
13456
13457 if (finishedWork === null) {
13458 return null;
13459 }
13460
13461 root.finishedWork = null;
13462 root.finishedExpirationTime = NoWork;
13463
13464 if (!(finishedWork !== root.current)) {
13465 {
13466 throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." );
13467 }
13468 } // commitRoot never returns a continuation; it always finishes synchronously.
13469 // So we can clear these now to allow a new callback to be scheduled.
13470
13471
13472 root.callbackNode = null;
13473 root.callbackExpirationTime = NoWork;
13474 root.callbackPriority = NoPriority;
13475 root.nextKnownPendingLevel = NoWork;
13476 startCommitTimer(); // Update the first and last pending times on this root. The new first
13477 // pending time is whatever is left on the root fiber.
13478
13479 var remainingExpirationTimeBeforeCommit = getRemainingExpirationTime(finishedWork);
13480 markRootFinishedAtTime(root, expirationTime, remainingExpirationTimeBeforeCommit);
13481
13482 if (root === workInProgressRoot) {
13483 // We can reset these now that they are finished.
13484 workInProgressRoot = null;
13485 workInProgress = null;
13486 renderExpirationTime$1 = NoWork;
13487 } // This indicates that the last root we worked on is not the same one that
13488 // we're committing now. This most commonly happens when a suspended root
13489 // times out.
13490 // Get the list of effects.
13491
13492
13493 var firstEffect;
13494
13495 if (finishedWork.effectTag > PerformedWork) {
13496 // A fiber's effect list consists only of its children, not itself. So if
13497 // the root has an effect, we need to add it to the end of the list. The
13498 // resulting list is the set that would belong to the root's parent, if it
13499 // had one; that is, all the effects in the tree including the root.
13500 if (finishedWork.lastEffect !== null) {
13501 finishedWork.lastEffect.nextEffect = finishedWork;
13502 firstEffect = finishedWork.firstEffect;
13503 } else {
13504 firstEffect = finishedWork;
13505 }
13506 } else {
13507 // There is no effect on the root.
13508 firstEffect = finishedWork.firstEffect;
13509 }
13510
13511 if (firstEffect !== null) {
13512 var prevExecutionContext = executionContext;
13513 executionContext |= CommitContext;
13514 var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles
13515
13516 ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass
13517 // of the effect list for each phase: all mutation effects come before all
13518 // layout effects, and so on.
13519 // The first phase a "before mutation" phase. We use this phase to read the
13520 // state of the host tree right before we mutate it. This is where
13521 // getSnapshotBeforeUpdate is called.
13522
13523 startCommitSnapshotEffectsTimer();
13524 prepareForCommit(root.containerInfo);
13525 nextEffect = firstEffect;
13526
13527 do {
13528 {
13529 invokeGuardedCallback(null, commitBeforeMutationEffects, null);
13530
13531 if (hasCaughtError()) {
13532 if (!(nextEffect !== null)) {
13533 {
13534 throw Error( "Should be working on an effect." );
13535 }
13536 }
13537
13538 var error = clearCaughtError();
13539 captureCommitPhaseError(nextEffect, error);
13540 nextEffect = nextEffect.nextEffect;
13541 }
13542 }
13543 } while (nextEffect !== null);
13544
13545 stopCommitSnapshotEffectsTimer();
13546
13547 {
13548 // Mark the current commit time to be shared by all Profilers in this
13549 // batch. This enables them to be grouped later.
13550 recordCommitTime();
13551 } // The next phase is the mutation phase, where we mutate the host tree.
13552
13553
13554 startCommitHostEffectsTimer();
13555 nextEffect = firstEffect;
13556
13557 do {
13558 {
13559 invokeGuardedCallback(null, commitMutationEffects, null, root, renderPriorityLevel);
13560
13561 if (hasCaughtError()) {
13562 if (!(nextEffect !== null)) {
13563 {
13564 throw Error( "Should be working on an effect." );
13565 }
13566 }
13567
13568 var _error = clearCaughtError();
13569
13570 captureCommitPhaseError(nextEffect, _error);
13571 nextEffect = nextEffect.nextEffect;
13572 }
13573 }
13574 } while (nextEffect !== null);
13575
13576 stopCommitHostEffectsTimer();
13577 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
13578 // the mutation phase, so that the previous tree is still current during
13579 // componentWillUnmount, but before the layout phase, so that the finished
13580 // work is current during componentDidMount/Update.
13581
13582 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
13583 // the host tree after it's been mutated. The idiomatic use case for this is
13584 // layout, but class component lifecycles also fire here for legacy reasons.
13585
13586 startCommitLifeCyclesTimer();
13587 nextEffect = firstEffect;
13588
13589 do {
13590 {
13591 invokeGuardedCallback(null, commitLayoutEffects, null, root, expirationTime);
13592
13593 if (hasCaughtError()) {
13594 if (!(nextEffect !== null)) {
13595 {
13596 throw Error( "Should be working on an effect." );
13597 }
13598 }
13599
13600 var _error2 = clearCaughtError();
13601
13602 captureCommitPhaseError(nextEffect, _error2);
13603 nextEffect = nextEffect.nextEffect;
13604 }
13605 }
13606 } while (nextEffect !== null);
13607
13608 stopCommitLifeCyclesTimer();
13609 nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an
13610 // opportunity to paint.
13611
13612 requestPaint();
13613
13614 {
13615 popInteractions(prevInteractions);
13616 }
13617
13618 executionContext = prevExecutionContext;
13619 } else {
13620 // No effects.
13621 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
13622 // no effects.
13623 // TODO: Maybe there's a better way to report this.
13624
13625 startCommitSnapshotEffectsTimer();
13626 stopCommitSnapshotEffectsTimer();
13627
13628 {
13629 recordCommitTime();
13630 }
13631
13632 startCommitHostEffectsTimer();
13633 stopCommitHostEffectsTimer();
13634 startCommitLifeCyclesTimer();
13635 stopCommitLifeCyclesTimer();
13636 }
13637
13638 stopCommitTimer();
13639 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
13640
13641 if (rootDoesHavePassiveEffects) {
13642 // This commit has passive effects. Stash a reference to them. But don't
13643 // schedule a callback until after flushing layout work.
13644 rootDoesHavePassiveEffects = false;
13645 rootWithPendingPassiveEffects = root;
13646 pendingPassiveEffectsExpirationTime = expirationTime;
13647 pendingPassiveEffectsRenderPriority = renderPriorityLevel;
13648 } else {
13649 // We are done with the effect chain at this point so let's clear the
13650 // nextEffect pointers to assist with GC. If we have passive effects, we'll
13651 // clear this in flushPassiveEffects.
13652 nextEffect = firstEffect;
13653
13654 while (nextEffect !== null) {
13655 var nextNextEffect = nextEffect.nextEffect;
13656 nextEffect.nextEffect = null;
13657 nextEffect = nextNextEffect;
13658 }
13659 } // Check if there's remaining work on this root
13660
13661
13662 var remainingExpirationTime = root.firstPendingTime;
13663
13664 if (remainingExpirationTime !== NoWork) {
13665 {
13666 if (spawnedWorkDuringRender !== null) {
13667 var expirationTimes = spawnedWorkDuringRender;
13668 spawnedWorkDuringRender = null;
13669
13670 for (var i = 0; i < expirationTimes.length; i++) {
13671 scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);
13672 }
13673 }
13674
13675 schedulePendingInteractions(root, remainingExpirationTime);
13676 }
13677 } else {
13678 // If there's no remaining work, we can clear the set of already failed
13679 // error boundaries.
13680 legacyErrorBoundariesThatAlreadyFailed = null;
13681 }
13682
13683 {
13684 if (!rootDidHavePassiveEffects) {
13685 // If there are no passive effects, then we can complete the pending interactions.
13686 // Otherwise, we'll wait until after the passive effects are flushed.
13687 // Wait to do this until after remaining work has been scheduled,
13688 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.
13689 finishPendingInteractions(root, expirationTime);
13690 }
13691 }
13692
13693 if (remainingExpirationTime === Sync) {
13694 // Count the number of times the root synchronously re-renders without
13695 // finishing. If there are too many, it indicates an infinite update loop.
13696 if (root === rootWithNestedUpdates) {
13697 nestedUpdateCount++;
13698 } else {
13699 nestedUpdateCount = 0;
13700 rootWithNestedUpdates = root;
13701 }
13702 } else {
13703 nestedUpdateCount = 0;
13704 }
13705
13706 onCommitRoot(finishedWork.stateNode, expirationTime); // Always call this before exiting `commitRoot`, to ensure that any
13707 // additional work on this root is scheduled.
13708
13709 ensureRootIsScheduled(root);
13710
13711 if (hasUncaughtError) {
13712 hasUncaughtError = false;
13713 var _error3 = firstUncaughtError;
13714 firstUncaughtError = null;
13715 throw _error3;
13716 }
13717
13718 if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
13719 // This is a legacy edge case. We just committed the initial mount of
13720 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
13721 // synchronously, but layout updates should be deferred until the end
13722 // of the batch.
13723 return null;
13724 } // If layout work was scheduled, flush it now.
13725
13726
13727 flushSyncCallbackQueue();
13728 return null;
13729 }
13730
13731 function commitBeforeMutationEffects() {
13732 while (nextEffect !== null) {
13733 var effectTag = nextEffect.effectTag;
13734
13735 if ((effectTag & Snapshot) !== NoEffect) {
13736 setCurrentFiber(nextEffect);
13737 recordEffect();
13738 var current = nextEffect.alternate;
13739 commitBeforeMutationLifeCycles(current, nextEffect);
13740 resetCurrentFiber();
13741 }
13742
13743 if ((effectTag & Passive) !== NoEffect) {
13744 // If there are passive effects, schedule a callback to flush at
13745 // the earliest opportunity.
13746 if (!rootDoesHavePassiveEffects) {
13747 rootDoesHavePassiveEffects = true;
13748 scheduleCallback(NormalPriority, function () {
13749 flushPassiveEffects();
13750 return null;
13751 });
13752 }
13753 }
13754
13755 nextEffect = nextEffect.nextEffect;
13756 }
13757 }
13758
13759 function commitMutationEffects(root, renderPriorityLevel) {
13760 // TODO: Should probably move the bulk of this function to commitWork.
13761 while (nextEffect !== null) {
13762 setCurrentFiber(nextEffect);
13763 var effectTag = nextEffect.effectTag;
13764
13765 if (effectTag & ContentReset) {
13766 commitResetTextContent(nextEffect);
13767 }
13768
13769 if (effectTag & Ref) {
13770 var current = nextEffect.alternate;
13771
13772 if (current !== null) {
13773 commitDetachRef(current);
13774 }
13775 } // The following switch statement is only concerned about placement,
13776 // updates, and deletions. To avoid needing to add a case for every possible
13777 // bitmap value, we remove the secondary effects from the effect tag and
13778 // switch on that value.
13779
13780
13781 var primaryEffectTag = effectTag & (Placement | Update | Deletion | Hydrating);
13782
13783 switch (primaryEffectTag) {
13784 case Placement:
13785 {
13786 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
13787 // inserted, before any life-cycles like componentDidMount gets called.
13788 // TODO: findDOMNode doesn't rely on this any more but isMounted does
13789 // and isMounted is deprecated anyway so we should be able to kill this.
13790
13791 nextEffect.effectTag &= ~Placement;
13792 break;
13793 }
13794
13795 case PlacementAndUpdate:
13796 {
13797 // Placement
13798 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
13799 // inserted, before any life-cycles like componentDidMount gets called.
13800
13801 nextEffect.effectTag &= ~Placement; // Update
13802
13803 var _current = nextEffect.alternate;
13804 commitWork(_current, nextEffect);
13805 break;
13806 }
13807
13808 case Hydrating:
13809 {
13810 nextEffect.effectTag &= ~Hydrating;
13811 break;
13812 }
13813
13814 case HydratingAndUpdate:
13815 {
13816 nextEffect.effectTag &= ~Hydrating; // Update
13817
13818 var _current2 = nextEffect.alternate;
13819 commitWork(_current2, nextEffect);
13820 break;
13821 }
13822
13823 case Update:
13824 {
13825 var _current3 = nextEffect.alternate;
13826 commitWork(_current3, nextEffect);
13827 break;
13828 }
13829
13830 case Deletion:
13831 {
13832 commitDeletion(root, nextEffect, renderPriorityLevel);
13833 break;
13834 }
13835 } // TODO: Only record a mutation effect if primaryEffectTag is non-zero.
13836
13837
13838 recordEffect();
13839 resetCurrentFiber();
13840 nextEffect = nextEffect.nextEffect;
13841 }
13842 }
13843
13844 function commitLayoutEffects(root, committedExpirationTime) {
13845 // TODO: Should probably move the bulk of this function to commitWork.
13846 while (nextEffect !== null) {
13847 setCurrentFiber(nextEffect);
13848 var effectTag = nextEffect.effectTag;
13849
13850 if (effectTag & (Update | Callback)) {
13851 recordEffect();
13852 var current = nextEffect.alternate;
13853 commitLifeCycles(root, current, nextEffect);
13854 }
13855
13856 if (effectTag & Ref) {
13857 recordEffect();
13858 commitAttachRef(nextEffect);
13859 }
13860
13861 resetCurrentFiber();
13862 nextEffect = nextEffect.nextEffect;
13863 }
13864 }
13865
13866 function flushPassiveEffects() {
13867 if (pendingPassiveEffectsRenderPriority !== NoPriority) {
13868 var priorityLevel = pendingPassiveEffectsRenderPriority > NormalPriority ? NormalPriority : pendingPassiveEffectsRenderPriority;
13869 pendingPassiveEffectsRenderPriority = NoPriority;
13870 return runWithPriority(priorityLevel, flushPassiveEffectsImpl);
13871 }
13872 }
13873
13874 function flushPassiveEffectsImpl() {
13875 if (rootWithPendingPassiveEffects === null) {
13876 return false;
13877 }
13878
13879 var root = rootWithPendingPassiveEffects;
13880 var expirationTime = pendingPassiveEffectsExpirationTime;
13881 rootWithPendingPassiveEffects = null;
13882 pendingPassiveEffectsExpirationTime = NoWork;
13883
13884 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
13885 {
13886 throw Error( "Cannot flush passive effects while already rendering." );
13887 }
13888 }
13889
13890 var prevExecutionContext = executionContext;
13891 executionContext |= CommitContext;
13892 var prevInteractions = pushInteractions(root);
13893
13894 {
13895 // Note: This currently assumes there are no passive effects on the root fiber
13896 // because the root is not part of its own effect list.
13897 // This could change in the future.
13898 var _effect2 = root.current.firstEffect;
13899
13900 while (_effect2 !== null) {
13901 {
13902 setCurrentFiber(_effect2);
13903 invokeGuardedCallback(null, commitPassiveHookEffects, null, _effect2);
13904
13905 if (hasCaughtError()) {
13906 if (!(_effect2 !== null)) {
13907 {
13908 throw Error( "Should be working on an effect." );
13909 }
13910 }
13911
13912 var _error5 = clearCaughtError();
13913
13914 captureCommitPhaseError(_effect2, _error5);
13915 }
13916
13917 resetCurrentFiber();
13918 }
13919
13920 var nextNextEffect = _effect2.nextEffect; // Remove nextEffect pointer to assist GC
13921
13922 _effect2.nextEffect = null;
13923 _effect2 = nextNextEffect;
13924 }
13925 }
13926
13927 {
13928 popInteractions(prevInteractions);
13929 finishPendingInteractions(root, expirationTime);
13930 }
13931
13932 executionContext = prevExecutionContext;
13933 flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this
13934 // exceeds the limit, we'll fire a warning.
13935
13936 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
13937 return true;
13938 }
13939
13940 function isAlreadyFailedLegacyErrorBoundary(instance) {
13941 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
13942 }
13943 function markLegacyErrorBoundaryAsFailed(instance) {
13944 if (legacyErrorBoundariesThatAlreadyFailed === null) {
13945 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
13946 } else {
13947 legacyErrorBoundariesThatAlreadyFailed.add(instance);
13948 }
13949 }
13950
13951 function prepareToThrowUncaughtError(error) {
13952 if (!hasUncaughtError) {
13953 hasUncaughtError = true;
13954 firstUncaughtError = error;
13955 }
13956 }
13957
13958 var onUncaughtError = prepareToThrowUncaughtError;
13959
13960 function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
13961 var errorInfo = createCapturedValue(error, sourceFiber);
13962 var update = createRootErrorUpdate(rootFiber, errorInfo, Sync);
13963 enqueueUpdate(rootFiber, update);
13964 var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);
13965
13966 if (root !== null) {
13967 ensureRootIsScheduled(root);
13968 schedulePendingInteractions(root, Sync);
13969 }
13970 }
13971
13972 function captureCommitPhaseError(sourceFiber, error) {
13973 if (sourceFiber.tag === HostRoot) {
13974 // Error was thrown at the root. There is no parent, so the root
13975 // itself should capture it.
13976 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);
13977 return;
13978 }
13979
13980 var fiber = sourceFiber.return;
13981
13982 while (fiber !== null) {
13983 if (fiber.tag === HostRoot) {
13984 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);
13985 return;
13986 } else if (fiber.tag === ClassComponent) {
13987 var ctor = fiber.type;
13988 var instance = fiber.stateNode;
13989
13990 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
13991 var errorInfo = createCapturedValue(error, sourceFiber);
13992 var update = createClassErrorUpdate(fiber, errorInfo, // TODO: This is always sync
13993 Sync);
13994 enqueueUpdate(fiber, update);
13995 var root = markUpdateTimeFromFiberToRoot(fiber, Sync);
13996
13997 if (root !== null) {
13998 ensureRootIsScheduled(root);
13999 schedulePendingInteractions(root, Sync);
14000 }
14001
14002 return;
14003 }
14004 }
14005
14006 fiber = fiber.return;
14007 }
14008 }
14009 function pingSuspendedRoot(root, thenable, suspendedTime) {
14010 var pingCache = root.pingCache;
14011
14012 if (pingCache !== null) {
14013 // The thenable resolved, so we no longer need to memoize, because it will
14014 // never be thrown again.
14015 pingCache.delete(thenable);
14016 }
14017
14018 if (workInProgressRoot === root && renderExpirationTime$1 === suspendedTime) {
14019 // Received a ping at the same priority level at which we're currently
14020 // rendering. We might want to restart this render. This should mirror
14021 // the logic of whether or not a root suspends once it completes.
14022 // TODO: If we're rendering sync either due to Sync, Batched or expired,
14023 // we should probably never restart.
14024 // If we're suspended with delay, we'll always suspend so we can always
14025 // restart. If we're suspended without any updates, it might be a retry.
14026 // If it's early in the retry we can restart. We can't know for sure
14027 // whether we'll eventually process an update during this render pass,
14028 // but it's somewhat unlikely that we get to a ping before that, since
14029 // getting to the root most update is usually very fast.
14030 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && workInProgressRootLatestProcessedExpirationTime === Sync && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
14031 // Restart from the root. Don't need to schedule a ping because
14032 // we're already working on this tree.
14033 prepareFreshStack(root, renderExpirationTime$1);
14034 } else {
14035 // Even though we can't restart right now, we might get an
14036 // opportunity later. So we mark this render as having a ping.
14037 workInProgressRootHasPendingPing = true;
14038 }
14039
14040 return;
14041 }
14042
14043 if (!isRootSuspendedAtTime(root, suspendedTime)) {
14044 // The root is no longer suspended at this time.
14045 return;
14046 }
14047
14048 var lastPingedTime = root.lastPingedTime;
14049
14050 if (lastPingedTime !== NoWork && lastPingedTime < suspendedTime) {
14051 // There's already a lower priority ping scheduled.
14052 return;
14053 } // Mark the time at which this ping was scheduled.
14054
14055
14056 root.lastPingedTime = suspendedTime;
14057
14058 ensureRootIsScheduled(root);
14059 schedulePendingInteractions(root, suspendedTime);
14060 }
14061
14062 function retryTimedOutBoundary(boundaryFiber, retryTime) {
14063 // The boundary fiber (a Suspense component or SuspenseList component)
14064 // previously was rendered in its fallback state. One of the promises that
14065 // suspended it has resolved, which means at least part of the tree was
14066 // likely unblocked. Try rendering again, at a new expiration time.
14067 if (retryTime === NoWork) {
14068 var suspenseConfig = null; // Retries don't carry over the already committed update.
14069
14070 var currentTime = requestCurrentTimeForUpdate();
14071 retryTime = computeExpirationForFiber(currentTime, boundaryFiber, suspenseConfig);
14072 } // TODO: Special case idle priority?
14073
14074
14075 var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);
14076
14077 if (root !== null) {
14078 ensureRootIsScheduled(root);
14079 schedulePendingInteractions(root, retryTime);
14080 }
14081 }
14082 function resolveRetryThenable(boundaryFiber, thenable) {
14083 var retryTime = NoWork; // Default
14084
14085 var retryCache;
14086
14087 {
14088 retryCache = boundaryFiber.stateNode;
14089 }
14090
14091 if (retryCache !== null) {
14092 // The thenable resolved, so we no longer need to memoize, because it will
14093 // never be thrown again.
14094 retryCache.delete(thenable);
14095 }
14096
14097 retryTimedOutBoundary(boundaryFiber, retryTime);
14098 } // Computes the next Just Noticeable Difference (JND) boundary.
14099 // The theory is that a person can't tell the difference between small differences in time.
14100 // Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
14101 // difference in the experience. However, waiting for longer might mean that we can avoid
14102 // showing an intermediate loading state. The longer we have already waited, the harder it
14103 // is to tell small differences in time. Therefore, the longer we've already waited,
14104 // the longer we can wait additionally. At some point we have to give up though.
14105 // We pick a train model where the next boundary commits at a consistent schedule.
14106 // These particular numbers are vague estimates. We expect to adjust them based on research.
14107
14108 function jnd(timeElapsed) {
14109 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
14110 }
14111
14112 function computeMsUntilSuspenseLoadingDelay(mostRecentEventTime, committedExpirationTime, suspenseConfig) {
14113 var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0;
14114
14115 if (busyMinDurationMs <= 0) {
14116 return 0;
14117 }
14118
14119 var busyDelayMs = suspenseConfig.busyDelayMs | 0; // Compute the time until this render pass would expire.
14120
14121 var currentTimeMs = now();
14122 var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig(mostRecentEventTime, suspenseConfig);
14123 var timeElapsed = currentTimeMs - eventTimeMs;
14124
14125 if (timeElapsed <= busyDelayMs) {
14126 // If we haven't yet waited longer than the initial delay, we don't
14127 // have to wait any additional time.
14128 return 0;
14129 }
14130
14131 var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed; // This is the value that is passed to `setTimeout`.
14132
14133 return msUntilTimeout;
14134 }
14135
14136 function checkForNestedUpdates() {
14137 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
14138 nestedUpdateCount = 0;
14139 rootWithNestedUpdates = null;
14140
14141 {
14142 {
14143 throw Error( "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." );
14144 }
14145 }
14146 }
14147
14148 {
14149 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
14150 nestedPassiveUpdateCount = 0;
14151
14152 error('Maximum update depth exceeded. This can happen when a component ' + "calls setState inside useEffect, but useEffect either doesn't " + 'have a dependency array, or one of the dependencies changes on ' + 'every render.');
14153 }
14154 }
14155 }
14156
14157 function flushRenderPhaseStrictModeWarningsInDEV() {
14158 {
14159 ReactStrictModeWarnings.flushLegacyContextWarning();
14160
14161 {
14162 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
14163 }
14164 }
14165 }
14166
14167 function stopFinishedWorkLoopTimer() {
14168 var didCompleteRoot = true;
14169 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
14170 interruptedBy = null;
14171 }
14172
14173 function stopInterruptedWorkLoopTimer() {
14174 // TODO: Track which fiber caused the interruption.
14175 var didCompleteRoot = false;
14176 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
14177 interruptedBy = null;
14178 }
14179
14180 function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) {
14181 if ( workInProgressRoot !== null && updateExpirationTime > renderExpirationTime$1) {
14182 interruptedBy = fiberThatReceivedUpdate;
14183 }
14184 }
14185
14186 var didWarnStateUpdateForUnmountedComponent = null;
14187
14188 function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
14189 {
14190 var tag = fiber.tag;
14191
14192 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent && tag !== Block) {
14193 // Only warn for user-defined components, not internal ones like Suspense.
14194 return;
14195 }
14196 // the problematic code almost always lies inside that component.
14197
14198
14199 var componentName = getComponentName(fiber.type) || 'ReactComponent';
14200
14201 if (didWarnStateUpdateForUnmountedComponent !== null) {
14202 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {
14203 return;
14204 }
14205
14206 didWarnStateUpdateForUnmountedComponent.add(componentName);
14207 } else {
14208 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);
14209 }
14210
14211 error("Can't perform a React state update on an unmounted component. This " + 'is a no-op, but it indicates a memory leak in your application. To ' + 'fix, cancel all subscriptions and asynchronous tasks in %s.%s', tag === ClassComponent ? 'the componentWillUnmount method' : 'a useEffect cleanup function', getStackByFiberInDevAndProd(fiber));
14212 }
14213 }
14214
14215 var beginWork$1;
14216
14217 {
14218 var dummyFiber = null;
14219
14220 beginWork$1 = function (current, unitOfWork, expirationTime) {
14221 // If a component throws an error, we replay it again in a synchronously
14222 // dispatched event, so that the debugger will treat it as an uncaught
14223 // error See ReactErrorUtils for more information.
14224 // Before entering the begin phase, copy the work-in-progress onto a dummy
14225 // fiber. If beginWork throws, we'll use this to reset the state.
14226 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
14227
14228 try {
14229 return beginWork(current, unitOfWork, expirationTime);
14230 } catch (originalError) {
14231 if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {
14232 // Don't replay promises. Treat everything else like an error.
14233 throw originalError;
14234 } // Keep this code in sync with handleError; any changes here must have
14235 // corresponding changes there.
14236
14237
14238 resetContextDependencies();
14239 resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the
14240 // same fiber again.
14241 // Unwind the failed stack frame
14242
14243 unwindInterruptedWork(unitOfWork); // Restore the original properties of the fiber.
14244
14245 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
14246
14247 if ( unitOfWork.mode & ProfileMode) {
14248 // Reset the profiler timer.
14249 startProfilerTimer(unitOfWork);
14250 } // Run beginWork again.
14251
14252
14253 invokeGuardedCallback(null, beginWork, null, current, unitOfWork, expirationTime);
14254
14255 if (hasCaughtError()) {
14256 var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`.
14257 // Rethrow this error instead of the original one.
14258
14259 throw replayError;
14260 } else {
14261 // This branch is reachable if the render phase is impure.
14262 throw originalError;
14263 }
14264 }
14265 };
14266 }
14267
14268 var didWarnAboutUpdateInRender = false;
14269 var didWarnAboutUpdateInRenderForAnotherComponent;
14270
14271 {
14272 didWarnAboutUpdateInRenderForAnotherComponent = new Set();
14273 }
14274
14275 function warnAboutRenderPhaseUpdatesInDEV(fiber) {
14276 {
14277 if (isRendering && (executionContext & RenderContext) !== NoContext) {
14278 switch (fiber.tag) {
14279 case FunctionComponent:
14280 case ForwardRef:
14281 case SimpleMemoComponent:
14282 {
14283 var renderingComponentName = workInProgress && getComponentName(workInProgress.type) || 'Unknown'; // Dedupe by the rendering component because it's the one that needs to be fixed.
14284
14285 var dedupeKey = renderingComponentName;
14286
14287 if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) {
14288 didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey);
14289 var setStateComponentName = getComponentName(fiber.type) || 'Unknown';
14290
14291 error('Cannot update a component (`%s`) while rendering a ' + 'different component (`%s`). To locate the bad setState() call inside `%s`, ' + 'follow the stack trace as described in https://fb.me/setstate-in-render', setStateComponentName, renderingComponentName, renderingComponentName);
14292 }
14293
14294 break;
14295 }
14296
14297 case ClassComponent:
14298 {
14299 if (!didWarnAboutUpdateInRender) {
14300 error('Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure ' + 'function of props and state.');
14301
14302 didWarnAboutUpdateInRender = true;
14303 }
14304
14305 break;
14306 }
14307 }
14308 }
14309 }
14310 } // a 'shared' variable that changes when act() opens/closes in tests.
14311
14312
14313 var IsThisRendererActing = {
14314 current: false
14315 };
14316
14317 var didWarnAboutUnmockedScheduler = false; // TODO Before we release concurrent mode, revisit this and decide whether a mocked
14318 // scheduler is the actual recommendation. The alternative could be a testing build,
14319 // a new lib, or whatever; we dunno just yet. This message is for early adopters
14320 // to get their tests right.
14321
14322 function warnIfUnmockedScheduler(fiber) {
14323 {
14324 if (didWarnAboutUnmockedScheduler === false && unstable_flushAllWithoutAsserting === undefined) {
14325 if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) {
14326 didWarnAboutUnmockedScheduler = true;
14327
14328 error('In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \n' + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + 'For more info, visit https://fb.me/react-mock-scheduler');
14329 }
14330 }
14331 }
14332 }
14333
14334 function computeThreadID(root, expirationTime) {
14335 // Interaction threads are unique per root and expiration time.
14336 return expirationTime * 1000 + root.interactionThreadID;
14337 }
14338
14339 function markSpawnedWork(expirationTime) {
14340
14341 if (spawnedWorkDuringRender === null) {
14342 spawnedWorkDuringRender = [expirationTime];
14343 } else {
14344 spawnedWorkDuringRender.push(expirationTime);
14345 }
14346 }
14347
14348 function scheduleInteractions(root, expirationTime, interactions) {
14349
14350 if (interactions.size > 0) {
14351 var pendingInteractionMap = root.pendingInteractionMap;
14352 var pendingInteractions = pendingInteractionMap.get(expirationTime);
14353
14354 if (pendingInteractions != null) {
14355 interactions.forEach(function (interaction) {
14356 if (!pendingInteractions.has(interaction)) {
14357 // Update the pending async work count for previously unscheduled interaction.
14358 interaction.__count++;
14359 }
14360
14361 pendingInteractions.add(interaction);
14362 });
14363 } else {
14364 pendingInteractionMap.set(expirationTime, new Set(interactions)); // Update the pending async work count for the current interactions.
14365
14366 interactions.forEach(function (interaction) {
14367 interaction.__count++;
14368 });
14369 }
14370
14371 var subscriber = __subscriberRef.current;
14372
14373 if (subscriber !== null) {
14374 var threadID = computeThreadID(root, expirationTime);
14375 subscriber.onWorkScheduled(interactions, threadID);
14376 }
14377 }
14378 }
14379
14380 function schedulePendingInteractions(root, expirationTime) {
14381
14382 scheduleInteractions(root, expirationTime, __interactionsRef.current);
14383 }
14384
14385 function startWorkOnPendingInteractions(root, expirationTime) {
14386 // we can accurately attribute time spent working on it, And so that cascading
14387 // work triggered during the render phase will be associated with it.
14388
14389
14390 var interactions = new Set();
14391 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
14392 if (scheduledExpirationTime >= expirationTime) {
14393 scheduledInteractions.forEach(function (interaction) {
14394 return interactions.add(interaction);
14395 });
14396 }
14397 }); // Store the current set of interactions on the FiberRoot for a few reasons:
14398 // We can re-use it in hot functions like performConcurrentWorkOnRoot()
14399 // without having to recalculate it. We will also use it in commitWork() to
14400 // pass to any Profiler onRender() hooks. This also provides DevTools with a
14401 // way to access it when the onCommitRoot() hook is called.
14402
14403 root.memoizedInteractions = interactions;
14404
14405 if (interactions.size > 0) {
14406 var subscriber = __subscriberRef.current;
14407
14408 if (subscriber !== null) {
14409 var threadID = computeThreadID(root, expirationTime);
14410
14411 try {
14412 subscriber.onWorkStarted(interactions, threadID);
14413 } catch (error) {
14414 // If the subscriber throws, rethrow it in a separate task
14415 scheduleCallback(ImmediatePriority, function () {
14416 throw error;
14417 });
14418 }
14419 }
14420 }
14421 }
14422
14423 function finishPendingInteractions(root, committedExpirationTime) {
14424
14425 var earliestRemainingTimeAfterCommit = root.firstPendingTime;
14426 var subscriber;
14427
14428 try {
14429 subscriber = __subscriberRef.current;
14430
14431 if (subscriber !== null && root.memoizedInteractions.size > 0) {
14432 var threadID = computeThreadID(root, committedExpirationTime);
14433 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
14434 }
14435 } catch (error) {
14436 // If the subscriber throws, rethrow it in a separate task
14437 scheduleCallback(ImmediatePriority, function () {
14438 throw error;
14439 });
14440 } finally {
14441 // Clear completed interactions from the pending Map.
14442 // Unless the render was suspended or cascading work was scheduled,
14443 // In which case– leave pending interactions until the subsequent render.
14444 var pendingInteractionMap = root.pendingInteractionMap;
14445 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
14446 // Only decrement the pending interaction count if we're done.
14447 // If there's still work at the current priority,
14448 // That indicates that we are waiting for suspense data.
14449 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
14450 pendingInteractionMap.delete(scheduledExpirationTime);
14451 scheduledInteractions.forEach(function (interaction) {
14452 interaction.__count--;
14453
14454 if (subscriber !== null && interaction.__count === 0) {
14455 try {
14456 subscriber.onInteractionScheduledWorkCompleted(interaction);
14457 } catch (error) {
14458 // If the subscriber throws, rethrow it in a separate task
14459 scheduleCallback(ImmediatePriority, function () {
14460 throw error;
14461 });
14462 }
14463 }
14464 });
14465 }
14466 });
14467 }
14468 }
14469
14470 var onScheduleFiberRoot = null;
14471 var onCommitFiberRoot = null;
14472 var onCommitFiberUnmount = null;
14473 var hasLoggedError = false;
14474 var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
14475 function injectInternals(internals) {
14476 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
14477 // No DevTools
14478 return false;
14479 }
14480
14481 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
14482
14483 if (hook.isDisabled) {
14484 // This isn't a real property on the hook, but it can be set to opt out
14485 // of DevTools integration and associated warnings and logs.
14486 // https://github.com/facebook/react/issues/3877
14487 return true;
14488 }
14489
14490 if (!hook.supportsFiber) {
14491 {
14492 error('The installed version of React DevTools is too old and will not work ' + 'with the current version of React. Please update React DevTools. ' + 'https://fb.me/react-devtools');
14493 } // DevTools exists, even though it doesn't support Fiber.
14494
14495
14496 return true;
14497 }
14498
14499 try {
14500 var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
14501
14502 if (true) {
14503 // Only used by Fast Refresh
14504 if (typeof hook.onScheduleFiberRoot === 'function') {
14505 onScheduleFiberRoot = function (root, children) {
14506 try {
14507 hook.onScheduleFiberRoot(rendererID, root, children);
14508 } catch (err) {
14509 if (true && !hasLoggedError) {
14510 hasLoggedError = true;
14511
14512 error('React instrumentation encountered an error: %s', err);
14513 }
14514 }
14515 };
14516 }
14517 }
14518
14519 onCommitFiberRoot = function (root, expirationTime) {
14520 try {
14521 var didError = (root.current.effectTag & DidCapture) === DidCapture;
14522
14523 if (enableProfilerTimer) {
14524 var currentTime = getCurrentTime();
14525 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime);
14526 hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
14527 } else {
14528 hook.onCommitFiberRoot(rendererID, root, undefined, didError);
14529 }
14530 } catch (err) {
14531 if (true) {
14532 if (!hasLoggedError) {
14533 hasLoggedError = true;
14534
14535 error('React instrumentation encountered an error: %s', err);
14536 }
14537 }
14538 }
14539 };
14540
14541 onCommitFiberUnmount = function (fiber) {
14542 try {
14543 hook.onCommitFiberUnmount(rendererID, fiber);
14544 } catch (err) {
14545 if (true) {
14546 if (!hasLoggedError) {
14547 hasLoggedError = true;
14548
14549 error('React instrumentation encountered an error: %s', err);
14550 }
14551 }
14552 }
14553 };
14554 } catch (err) {
14555 // Catch all errors because it is unsafe to throw during initialization.
14556 {
14557 error('React instrumentation encountered an error: %s.', err);
14558 }
14559 } // DevTools exists
14560
14561
14562 return true;
14563 }
14564 function onScheduleRoot(root, children) {
14565 if (typeof onScheduleFiberRoot === 'function') {
14566 onScheduleFiberRoot(root, children);
14567 }
14568 }
14569 function onCommitRoot(root, expirationTime) {
14570 if (typeof onCommitFiberRoot === 'function') {
14571 onCommitFiberRoot(root, expirationTime);
14572 }
14573 }
14574 function onCommitUnmount(fiber) {
14575 if (typeof onCommitFiberUnmount === 'function') {
14576 onCommitFiberUnmount(fiber);
14577 }
14578 }
14579
14580 var hasBadMapPolyfill;
14581
14582 {
14583 hasBadMapPolyfill = false;
14584
14585 try {
14586 var nonExtensibleObject = Object.preventExtensions({});
14587 var testMap = new Map([[nonExtensibleObject, null]]);
14588 var testSet = new Set([nonExtensibleObject]); // This is necessary for Rollup to not consider these unused.
14589 // https://github.com/rollup/rollup/issues/1771
14590 // TODO: we can remove these if Rollup fixes the bug.
14591
14592 testMap.set(0, 0);
14593 testSet.add(0);
14594 } catch (e) {
14595 // TODO: Consider warning about bad polyfills
14596 hasBadMapPolyfill = true;
14597 }
14598 }
14599
14600 var debugCounter = 1;
14601
14602 function FiberNode(tag, pendingProps, key, mode) {
14603 // Instance
14604 this.tag = tag;
14605 this.key = key;
14606 this.elementType = null;
14607 this.type = null;
14608 this.stateNode = null; // Fiber
14609
14610 this.return = null;
14611 this.child = null;
14612 this.sibling = null;
14613 this.index = 0;
14614 this.ref = null;
14615 this.pendingProps = pendingProps;
14616 this.memoizedProps = null;
14617 this.updateQueue = null;
14618 this.memoizedState = null;
14619 this.dependencies = null;
14620 this.mode = mode; // Effects
14621
14622 this.effectTag = NoEffect;
14623 this.nextEffect = null;
14624 this.firstEffect = null;
14625 this.lastEffect = null;
14626 this.expirationTime = NoWork;
14627 this.childExpirationTime = NoWork;
14628 this.alternate = null;
14629
14630 {
14631 // Note: The following is done to avoid a v8 performance cliff.
14632 //
14633 // Initializing the fields below to smis and later updating them with
14634 // double values will cause Fibers to end up having separate shapes.
14635 // This behavior/bug has something to do with Object.preventExtension().
14636 // Fortunately this only impacts DEV builds.
14637 // Unfortunately it makes React unusably slow for some applications.
14638 // To work around this, initialize the fields below with doubles.
14639 //
14640 // Learn more about this here:
14641 // https://github.com/facebook/react/issues/14365
14642 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
14643 this.actualDuration = Number.NaN;
14644 this.actualStartTime = Number.NaN;
14645 this.selfBaseDuration = Number.NaN;
14646 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
14647 // This won't trigger the performance cliff mentioned above,
14648 // and it simplifies other profiler code (including DevTools).
14649
14650 this.actualDuration = 0;
14651 this.actualStartTime = -1;
14652 this.selfBaseDuration = 0;
14653 this.treeBaseDuration = 0;
14654 } // This is normally DEV-only except www when it adds listeners.
14655 // TODO: remove the User Timing integration in favor of Root Events.
14656
14657
14658 {
14659 this._debugID = debugCounter++;
14660 this._debugIsCurrentlyTiming = false;
14661 }
14662
14663 {
14664 this._debugSource = null;
14665 this._debugOwner = null;
14666 this._debugNeedsRemount = false;
14667 this._debugHookTypes = null;
14668
14669 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
14670 Object.preventExtensions(this);
14671 }
14672 }
14673 } // This is a constructor function, rather than a POJO constructor, still
14674 // please ensure we do the following:
14675 // 1) Nobody should add any instance methods on this. Instance methods can be
14676 // more difficult to predict when they get optimized and they are almost
14677 // never inlined properly in static compilers.
14678 // 2) Nobody should rely on `instanceof Fiber` for type testing. We should
14679 // always know when it is a fiber.
14680 // 3) We might want to experiment with using numeric keys since they are easier
14681 // to optimize in a non-JIT environment.
14682 // 4) We can easily go from a constructor to a createFiber object literal if that
14683 // is faster.
14684 // 5) It should be easy to port this to a C struct and keep a C implementation
14685 // compatible.
14686
14687
14688 var createFiber = function (tag, pendingProps, key, mode) {
14689 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
14690 return new FiberNode(tag, pendingProps, key, mode);
14691 };
14692
14693 function shouldConstruct(Component) {
14694 var prototype = Component.prototype;
14695 return !!(prototype && prototype.isReactComponent);
14696 }
14697
14698 function isSimpleFunctionComponent(type) {
14699 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
14700 }
14701 function resolveLazyComponentTag(Component) {
14702 if (typeof Component === 'function') {
14703 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
14704 } else if (Component !== undefined && Component !== null) {
14705 var $$typeof = Component.$$typeof;
14706
14707 if ($$typeof === REACT_FORWARD_REF_TYPE) {
14708 return ForwardRef;
14709 }
14710
14711 if ($$typeof === REACT_MEMO_TYPE) {
14712 return MemoComponent;
14713 }
14714 }
14715
14716 return IndeterminateComponent;
14717 } // This is used to create an alternate fiber to do work on.
14718
14719 function createWorkInProgress(current, pendingProps) {
14720 var workInProgress = current.alternate;
14721
14722 if (workInProgress === null) {
14723 // We use a double buffering pooling technique because we know that we'll
14724 // only ever need at most two versions of a tree. We pool the "other" unused
14725 // node that we're free to reuse. This is lazily created to avoid allocating
14726 // extra objects for things that are never updated. It also allow us to
14727 // reclaim the extra memory if needed.
14728 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
14729 workInProgress.elementType = current.elementType;
14730 workInProgress.type = current.type;
14731 workInProgress.stateNode = current.stateNode;
14732
14733 {
14734 // DEV-only fields
14735 {
14736 workInProgress._debugID = current._debugID;
14737 }
14738
14739 workInProgress._debugSource = current._debugSource;
14740 workInProgress._debugOwner = current._debugOwner;
14741 workInProgress._debugHookTypes = current._debugHookTypes;
14742 }
14743
14744 workInProgress.alternate = current;
14745 current.alternate = workInProgress;
14746 } else {
14747 workInProgress.pendingProps = pendingProps; // We already have an alternate.
14748 // Reset the effect tag.
14749
14750 workInProgress.effectTag = NoEffect; // The effect list is no longer valid.
14751
14752 workInProgress.nextEffect = null;
14753 workInProgress.firstEffect = null;
14754 workInProgress.lastEffect = null;
14755
14756 {
14757 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
14758 // This prevents time from endlessly accumulating in new commits.
14759 // This has the downside of resetting values for different priority renders,
14760 // But works for yielding (the common case) and should support resuming.
14761 workInProgress.actualDuration = 0;
14762 workInProgress.actualStartTime = -1;
14763 }
14764 }
14765
14766 workInProgress.childExpirationTime = current.childExpirationTime;
14767 workInProgress.expirationTime = current.expirationTime;
14768 workInProgress.child = current.child;
14769 workInProgress.memoizedProps = current.memoizedProps;
14770 workInProgress.memoizedState = current.memoizedState;
14771 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
14772 // it cannot be shared with the current fiber.
14773
14774 var currentDependencies = current.dependencies;
14775 workInProgress.dependencies = currentDependencies === null ? null : {
14776 expirationTime: currentDependencies.expirationTime,
14777 firstContext: currentDependencies.firstContext,
14778 responders: currentDependencies.responders
14779 }; // These will be overridden during the parent's reconciliation
14780
14781 workInProgress.sibling = current.sibling;
14782 workInProgress.index = current.index;
14783 workInProgress.ref = current.ref;
14784
14785 {
14786 workInProgress.selfBaseDuration = current.selfBaseDuration;
14787 workInProgress.treeBaseDuration = current.treeBaseDuration;
14788 }
14789
14790 {
14791 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
14792
14793 switch (workInProgress.tag) {
14794 case IndeterminateComponent:
14795 case FunctionComponent:
14796 case SimpleMemoComponent:
14797 workInProgress.type = resolveFunctionForHotReloading(current.type);
14798 break;
14799
14800 case ClassComponent:
14801 workInProgress.type = resolveClassForHotReloading(current.type);
14802 break;
14803
14804 case ForwardRef:
14805 workInProgress.type = resolveForwardRefForHotReloading(current.type);
14806 break;
14807 }
14808 }
14809
14810 return workInProgress;
14811 } // Used to reuse a Fiber for a second pass.
14812
14813 function resetWorkInProgress(workInProgress, renderExpirationTime) {
14814 // This resets the Fiber to what createFiber or createWorkInProgress would
14815 // have set the values to before during the first pass. Ideally this wouldn't
14816 // be necessary but unfortunately many code paths reads from the workInProgress
14817 // when they should be reading from current and writing to workInProgress.
14818 // We assume pendingProps, index, key, ref, return are still untouched to
14819 // avoid doing another reconciliation.
14820 // Reset the effect tag but keep any Placement tags, since that's something
14821 // that child fiber is setting, not the reconciliation.
14822 workInProgress.effectTag &= Placement; // The effect list is no longer valid.
14823
14824 workInProgress.nextEffect = null;
14825 workInProgress.firstEffect = null;
14826 workInProgress.lastEffect = null;
14827 var current = workInProgress.alternate;
14828
14829 if (current === null) {
14830 // Reset to createFiber's initial values.
14831 workInProgress.childExpirationTime = NoWork;
14832 workInProgress.expirationTime = renderExpirationTime;
14833 workInProgress.child = null;
14834 workInProgress.memoizedProps = null;
14835 workInProgress.memoizedState = null;
14836 workInProgress.updateQueue = null;
14837 workInProgress.dependencies = null;
14838
14839 {
14840 // Note: We don't reset the actualTime counts. It's useful to accumulate
14841 // actual time across multiple render passes.
14842 workInProgress.selfBaseDuration = 0;
14843 workInProgress.treeBaseDuration = 0;
14844 }
14845 } else {
14846 // Reset to the cloned values that createWorkInProgress would've.
14847 workInProgress.childExpirationTime = current.childExpirationTime;
14848 workInProgress.expirationTime = current.expirationTime;
14849 workInProgress.child = current.child;
14850 workInProgress.memoizedProps = current.memoizedProps;
14851 workInProgress.memoizedState = current.memoizedState;
14852 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
14853 // it cannot be shared with the current fiber.
14854
14855 var currentDependencies = current.dependencies;
14856 workInProgress.dependencies = currentDependencies === null ? null : {
14857 expirationTime: currentDependencies.expirationTime,
14858 firstContext: currentDependencies.firstContext,
14859 responders: currentDependencies.responders
14860 };
14861
14862 {
14863 // Note: We don't reset the actualTime counts. It's useful to accumulate
14864 // actual time across multiple render passes.
14865 workInProgress.selfBaseDuration = current.selfBaseDuration;
14866 workInProgress.treeBaseDuration = current.treeBaseDuration;
14867 }
14868 }
14869
14870 return workInProgress;
14871 }
14872 function createHostRootFiber(tag) {
14873 var mode;
14874
14875 if (tag === ConcurrentRoot) {
14876 mode = ConcurrentMode | BlockingMode | StrictMode;
14877 } else if (tag === BlockingRoot) {
14878 mode = BlockingMode | StrictMode;
14879 } else {
14880 mode = NoMode;
14881 }
14882
14883 if ( isDevToolsPresent) {
14884 // Always collect profile timings when DevTools are present.
14885 // This enables DevTools to start capturing timing at any point–
14886 // Without some nodes in the tree having empty base times.
14887 mode |= ProfileMode;
14888 }
14889
14890 return createFiber(HostRoot, null, null, mode);
14891 }
14892 function createFiberFromTypeAndProps(type, // React$ElementType
14893 key, pendingProps, owner, mode, expirationTime) {
14894 var fiber;
14895 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
14896
14897 var resolvedType = type;
14898
14899 if (typeof type === 'function') {
14900 if (shouldConstruct(type)) {
14901 fiberTag = ClassComponent;
14902
14903 {
14904 resolvedType = resolveClassForHotReloading(resolvedType);
14905 }
14906 } else {
14907 {
14908 resolvedType = resolveFunctionForHotReloading(resolvedType);
14909 }
14910 }
14911 } else if (typeof type === 'string') {
14912 fiberTag = HostComponent;
14913 } else {
14914 getTag: switch (type) {
14915 case REACT_FRAGMENT_TYPE:
14916 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
14917
14918 case REACT_CONCURRENT_MODE_TYPE:
14919 fiberTag = Mode;
14920 mode |= ConcurrentMode | BlockingMode | StrictMode;
14921 break;
14922
14923 case REACT_STRICT_MODE_TYPE:
14924 fiberTag = Mode;
14925 mode |= StrictMode;
14926 break;
14927
14928 case REACT_PROFILER_TYPE:
14929 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
14930
14931 case REACT_SUSPENSE_TYPE:
14932 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
14933
14934 case REACT_SUSPENSE_LIST_TYPE:
14935 return createFiberFromSuspenseList(pendingProps, mode, expirationTime, key);
14936
14937 default:
14938 {
14939 if (typeof type === 'object' && type !== null) {
14940 switch (type.$$typeof) {
14941 case REACT_PROVIDER_TYPE:
14942 fiberTag = ContextProvider;
14943 break getTag;
14944
14945 case REACT_CONTEXT_TYPE:
14946 // This is a consumer
14947 fiberTag = ContextConsumer;
14948 break getTag;
14949
14950 case REACT_FORWARD_REF_TYPE:
14951 fiberTag = ForwardRef;
14952
14953 {
14954 resolvedType = resolveForwardRefForHotReloading(resolvedType);
14955 }
14956
14957 break getTag;
14958
14959 case REACT_MEMO_TYPE:
14960 fiberTag = MemoComponent;
14961 break getTag;
14962
14963 case REACT_LAZY_TYPE:
14964 fiberTag = LazyComponent;
14965 resolvedType = null;
14966 break getTag;
14967
14968 case REACT_BLOCK_TYPE:
14969 fiberTag = Block;
14970 break getTag;
14971
14972 }
14973 }
14974
14975 var info = '';
14976
14977 {
14978 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
14979 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.';
14980 }
14981
14982 var ownerName = owner ? getComponentName(owner.type) : null;
14983
14984 if (ownerName) {
14985 info += '\n\nCheck the render method of `' + ownerName + '`.';
14986 }
14987 }
14988
14989 {
14990 {
14991 throw Error( "Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + (type == null ? type : typeof type) + "." + info );
14992 }
14993 }
14994 }
14995 }
14996 }
14997
14998 fiber = createFiber(fiberTag, pendingProps, key, mode);
14999 fiber.elementType = type;
15000 fiber.type = resolvedType;
15001 fiber.expirationTime = expirationTime;
15002 return fiber;
15003 }
15004 function createFiberFromElement(element, mode, expirationTime) {
15005 var owner = null;
15006
15007 {
15008 owner = element._owner;
15009 }
15010
15011 var type = element.type;
15012 var key = element.key;
15013 var pendingProps = element.props;
15014 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
15015
15016 {
15017 fiber._debugSource = element._source;
15018 fiber._debugOwner = element._owner;
15019 }
15020
15021 return fiber;
15022 }
15023 function createFiberFromFragment(elements, mode, expirationTime, key) {
15024 var fiber = createFiber(Fragment, elements, key, mode);
15025 fiber.expirationTime = expirationTime;
15026 return fiber;
15027 }
15028
15029 function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
15030 {
15031 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
15032 error('Profiler must specify an "id" string and "onRender" function as props');
15033 }
15034 }
15035
15036 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); // TODO: The Profiler fiber shouldn't have a type. It has a tag.
15037
15038 fiber.elementType = REACT_PROFILER_TYPE;
15039 fiber.type = REACT_PROFILER_TYPE;
15040 fiber.expirationTime = expirationTime;
15041 return fiber;
15042 }
15043
15044 function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
15045 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
15046 // This needs to be fixed in getComponentName so that it relies on the tag
15047 // instead.
15048
15049 fiber.type = REACT_SUSPENSE_TYPE;
15050 fiber.elementType = REACT_SUSPENSE_TYPE;
15051 fiber.expirationTime = expirationTime;
15052 return fiber;
15053 }
15054 function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) {
15055 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
15056
15057 {
15058 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.
15059 // This needs to be fixed in getComponentName so that it relies on the tag
15060 // instead.
15061 fiber.type = REACT_SUSPENSE_LIST_TYPE;
15062 }
15063
15064 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
15065 fiber.expirationTime = expirationTime;
15066 return fiber;
15067 }
15068 function createFiberFromText(content, mode, expirationTime) {
15069 var fiber = createFiber(HostText, content, null, mode);
15070 fiber.expirationTime = expirationTime;
15071 return fiber;
15072 }
15073 function createFiberFromPortal(portal, mode, expirationTime) {
15074 var pendingProps = portal.children !== null ? portal.children : [];
15075 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
15076 fiber.expirationTime = expirationTime;
15077 fiber.stateNode = {
15078 containerInfo: portal.containerInfo,
15079 pendingChildren: null,
15080 // Used by persistent updates
15081 implementation: portal.implementation
15082 };
15083 return fiber;
15084 } // Used for stashing WIP properties to replay failed work in DEV.
15085
15086 function assignFiberPropertiesInDEV(target, source) {
15087 if (target === null) {
15088 // This Fiber's initial properties will always be overwritten.
15089 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
15090 target = createFiber(IndeterminateComponent, null, null, NoMode);
15091 } // This is intentionally written as a list of all properties.
15092 // We tried to use Object.assign() instead but this is called in
15093 // the hottest path, and Object.assign() was too slow:
15094 // https://github.com/facebook/react/issues/12502
15095 // This code is DEV-only so size is not a concern.
15096
15097
15098 target.tag = source.tag;
15099 target.key = source.key;
15100 target.elementType = source.elementType;
15101 target.type = source.type;
15102 target.stateNode = source.stateNode;
15103 target.return = source.return;
15104 target.child = source.child;
15105 target.sibling = source.sibling;
15106 target.index = source.index;
15107 target.ref = source.ref;
15108 target.pendingProps = source.pendingProps;
15109 target.memoizedProps = source.memoizedProps;
15110 target.updateQueue = source.updateQueue;
15111 target.memoizedState = source.memoizedState;
15112 target.dependencies = source.dependencies;
15113 target.mode = source.mode;
15114 target.effectTag = source.effectTag;
15115 target.nextEffect = source.nextEffect;
15116 target.firstEffect = source.firstEffect;
15117 target.lastEffect = source.lastEffect;
15118 target.expirationTime = source.expirationTime;
15119 target.childExpirationTime = source.childExpirationTime;
15120 target.alternate = source.alternate;
15121
15122 {
15123 target.actualDuration = source.actualDuration;
15124 target.actualStartTime = source.actualStartTime;
15125 target.selfBaseDuration = source.selfBaseDuration;
15126 target.treeBaseDuration = source.treeBaseDuration;
15127 }
15128
15129 {
15130 target._debugID = source._debugID;
15131 }
15132
15133 target._debugSource = source._debugSource;
15134 target._debugOwner = source._debugOwner;
15135 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
15136 target._debugNeedsRemount = source._debugNeedsRemount;
15137 target._debugHookTypes = source._debugHookTypes;
15138 return target;
15139 }
15140
15141 function FiberRootNode(containerInfo, tag, hydrate) {
15142 this.tag = tag;
15143 this.current = null;
15144 this.containerInfo = containerInfo;
15145 this.pendingChildren = null;
15146 this.pingCache = null;
15147 this.finishedExpirationTime = NoWork;
15148 this.finishedWork = null;
15149 this.timeoutHandle = noTimeout;
15150 this.context = null;
15151 this.pendingContext = null;
15152 this.hydrate = hydrate;
15153 this.callbackNode = null;
15154 this.callbackPriority = NoPriority;
15155 this.firstPendingTime = NoWork;
15156 this.firstSuspendedTime = NoWork;
15157 this.lastSuspendedTime = NoWork;
15158 this.nextKnownPendingLevel = NoWork;
15159 this.lastPingedTime = NoWork;
15160 this.lastExpiredTime = NoWork;
15161
15162 {
15163 this.interactionThreadID = unstable_getThreadID();
15164 this.memoizedInteractions = new Set();
15165 this.pendingInteractionMap = new Map();
15166 }
15167 }
15168
15169 function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) {
15170 var root = new FiberRootNode(containerInfo, tag, hydrate);
15171 // stateNode is any.
15172
15173
15174 var uninitializedFiber = createHostRootFiber(tag);
15175 root.current = uninitializedFiber;
15176 uninitializedFiber.stateNode = root;
15177 initializeUpdateQueue(uninitializedFiber);
15178 return root;
15179 }
15180 function isRootSuspendedAtTime(root, expirationTime) {
15181 var firstSuspendedTime = root.firstSuspendedTime;
15182 var lastSuspendedTime = root.lastSuspendedTime;
15183 return firstSuspendedTime !== NoWork && firstSuspendedTime >= expirationTime && lastSuspendedTime <= expirationTime;
15184 }
15185 function markRootSuspendedAtTime(root, expirationTime) {
15186 var firstSuspendedTime = root.firstSuspendedTime;
15187 var lastSuspendedTime = root.lastSuspendedTime;
15188
15189 if (firstSuspendedTime < expirationTime) {
15190 root.firstSuspendedTime = expirationTime;
15191 }
15192
15193 if (lastSuspendedTime > expirationTime || firstSuspendedTime === NoWork) {
15194 root.lastSuspendedTime = expirationTime;
15195 }
15196
15197 if (expirationTime <= root.lastPingedTime) {
15198 root.lastPingedTime = NoWork;
15199 }
15200
15201 if (expirationTime <= root.lastExpiredTime) {
15202 root.lastExpiredTime = NoWork;
15203 }
15204 }
15205 function markRootUpdatedAtTime(root, expirationTime) {
15206 // Update the range of pending times
15207 var firstPendingTime = root.firstPendingTime;
15208
15209 if (expirationTime > firstPendingTime) {
15210 root.firstPendingTime = expirationTime;
15211 } // Update the range of suspended times. Treat everything lower priority or
15212 // equal to this update as unsuspended.
15213
15214
15215 var firstSuspendedTime = root.firstSuspendedTime;
15216
15217 if (firstSuspendedTime !== NoWork) {
15218 if (expirationTime >= firstSuspendedTime) {
15219 // The entire suspended range is now unsuspended.
15220 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
15221 } else if (expirationTime >= root.lastSuspendedTime) {
15222 root.lastSuspendedTime = expirationTime + 1;
15223 } // This is a pending level. Check if it's higher priority than the next
15224 // known pending level.
15225
15226
15227 if (expirationTime > root.nextKnownPendingLevel) {
15228 root.nextKnownPendingLevel = expirationTime;
15229 }
15230 }
15231 }
15232 function markRootFinishedAtTime(root, finishedExpirationTime, remainingExpirationTime) {
15233 // Update the range of pending times
15234 root.firstPendingTime = remainingExpirationTime; // Update the range of suspended times. Treat everything higher priority or
15235 // equal to this update as unsuspended.
15236
15237 if (finishedExpirationTime <= root.lastSuspendedTime) {
15238 // The entire suspended range is now unsuspended.
15239 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
15240 } else if (finishedExpirationTime <= root.firstSuspendedTime) {
15241 // Part of the suspended range is now unsuspended. Narrow the range to
15242 // include everything between the unsuspended time (non-inclusive) and the
15243 // last suspended time.
15244 root.firstSuspendedTime = finishedExpirationTime - 1;
15245 }
15246
15247 if (finishedExpirationTime <= root.lastPingedTime) {
15248 // Clear the pinged time
15249 root.lastPingedTime = NoWork;
15250 }
15251
15252 if (finishedExpirationTime <= root.lastExpiredTime) {
15253 // Clear the expired time
15254 root.lastExpiredTime = NoWork;
15255 }
15256 }
15257 function markRootExpiredAtTime(root, expirationTime) {
15258 var lastExpiredTime = root.lastExpiredTime;
15259
15260 if (lastExpiredTime === NoWork || lastExpiredTime > expirationTime) {
15261 root.lastExpiredTime = expirationTime;
15262 }
15263 }
15264
15265 var didWarnAboutNestedUpdates;
15266
15267 {
15268 didWarnAboutNestedUpdates = false;
15269 }
15270
15271 function getContextForSubtree(parentComponent) {
15272 if (!parentComponent) {
15273 return emptyContextObject;
15274 }
15275
15276 var fiber = get(parentComponent);
15277 var parentContext = findCurrentUnmaskedContext(fiber);
15278
15279 if (fiber.tag === ClassComponent) {
15280 var Component = fiber.type;
15281
15282 if (isContextProvider(Component)) {
15283 return processChildContext(fiber, Component, parentContext);
15284 }
15285 }
15286
15287 return parentContext;
15288 }
15289
15290 function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) {
15291 return createFiberRoot(containerInfo, tag, hydrate);
15292 }
15293 function updateContainer(element, container, parentComponent, callback) {
15294 {
15295 onScheduleRoot(container, element);
15296 }
15297
15298 var current = container.current;
15299 var currentTime = requestCurrentTimeForUpdate();
15300
15301 {
15302 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15303 if ('undefined' !== typeof jest) {
15304 warnIfUnmockedScheduler(current);
15305 }
15306 }
15307
15308 var suspenseConfig = requestCurrentSuspenseConfig();
15309 var expirationTime = computeExpirationForFiber(currentTime, current, suspenseConfig);
15310 var context = getContextForSubtree(parentComponent);
15311
15312 if (container.context === null) {
15313 container.context = context;
15314 } else {
15315 container.pendingContext = context;
15316 }
15317
15318 {
15319 if (isRendering && current$1 !== null && !didWarnAboutNestedUpdates) {
15320 didWarnAboutNestedUpdates = true;
15321
15322 error('Render methods should be a pure function of props and state; ' + 'triggering nested component updates from render is not allowed. ' + 'If necessary, trigger nested updates in componentDidUpdate.\n\n' + 'Check the render method of %s.', getComponentName(current$1.type) || 'Unknown');
15323 }
15324 }
15325
15326 var update = createUpdate(expirationTime, suspenseConfig); // Caution: React DevTools currently depends on this property
15327 // being called "element".
15328
15329 update.payload = {
15330 element: element
15331 };
15332 callback = callback === undefined ? null : callback;
15333
15334 if (callback !== null) {
15335 {
15336 if (typeof callback !== 'function') {
15337 error('render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
15338 }
15339 }
15340
15341 update.callback = callback;
15342 }
15343
15344 enqueueUpdate(current, update);
15345 scheduleWork(current, expirationTime);
15346 return expirationTime;
15347 }
15348
15349 var shouldSuspendImpl = function (fiber) {
15350 return false;
15351 };
15352
15353 function shouldSuspend(fiber) {
15354 return shouldSuspendImpl(fiber);
15355 }
15356 var overrideHookState = null;
15357 var overrideProps = null;
15358 var scheduleUpdate = null;
15359 var setSuspenseHandler = null;
15360
15361 {
15362 var copyWithSetImpl = function (obj, path, idx, value) {
15363 if (idx >= path.length) {
15364 return value;
15365 }
15366
15367 var key = path[idx];
15368 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj); // $FlowFixMe number or string is fine here
15369
15370 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
15371 return updated;
15372 };
15373
15374 var copyWithSet = function (obj, path, value) {
15375 return copyWithSetImpl(obj, path, 0, value);
15376 }; // Support DevTools editable values for useState and useReducer.
15377
15378
15379 overrideHookState = function (fiber, id, path, value) {
15380 // For now, the "id" of stateful hooks is just the stateful hook index.
15381 // This may change in the future with e.g. nested hooks.
15382 var currentHook = fiber.memoizedState;
15383
15384 while (currentHook !== null && id > 0) {
15385 currentHook = currentHook.next;
15386 id--;
15387 }
15388
15389 if (currentHook !== null) {
15390 var newState = copyWithSet(currentHook.memoizedState, path, value);
15391 currentHook.memoizedState = newState;
15392 currentHook.baseState = newState; // We aren't actually adding an update to the queue,
15393 // because there is no update we can add for useReducer hooks that won't trigger an error.
15394 // (There's no appropriate action type for DevTools overrides.)
15395 // As a result though, React will see the scheduled update as a noop and bailout.
15396 // Shallow cloning props works as a workaround for now to bypass the bailout check.
15397
15398 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
15399 scheduleWork(fiber, Sync);
15400 }
15401 }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
15402
15403
15404 overrideProps = function (fiber, path, value) {
15405 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
15406
15407 if (fiber.alternate) {
15408 fiber.alternate.pendingProps = fiber.pendingProps;
15409 }
15410
15411 scheduleWork(fiber, Sync);
15412 };
15413
15414 scheduleUpdate = function (fiber) {
15415 scheduleWork(fiber, Sync);
15416 };
15417
15418 setSuspenseHandler = function (newShouldSuspendImpl) {
15419 shouldSuspendImpl = newShouldSuspendImpl;
15420 };
15421 }
15422
15423 function injectIntoDevTools(devToolsConfig) {
15424 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
15425 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
15426 return injectInternals(_assign({}, devToolsConfig, {
15427 overrideHookState: overrideHookState,
15428 overrideProps: overrideProps,
15429 setSuspenseHandler: setSuspenseHandler,
15430 scheduleUpdate: scheduleUpdate,
15431 currentDispatcherRef: ReactCurrentDispatcher,
15432 findHostInstanceByFiber: function (fiber) {
15433 var hostFiber = findCurrentHostFiber(fiber);
15434
15435 if (hostFiber === null) {
15436 return null;
15437 }
15438
15439 return hostFiber.stateNode;
15440 },
15441 findFiberByHostInstance: function (instance) {
15442 if (!findFiberByHostInstance) {
15443 // Might not be implemented by the renderer.
15444 return null;
15445 }
15446
15447 return findFiberByHostInstance(instance);
15448 },
15449 // React Refresh
15450 findHostInstancesForRefresh: findHostInstancesForRefresh ,
15451 scheduleRefresh: scheduleRefresh ,
15452 scheduleRoot: scheduleRoot ,
15453 setRefreshHandler: setRefreshHandler ,
15454 // Enables DevTools to append owner stacks to error messages in DEV mode.
15455 getCurrentFiber: function () {
15456 return current$1;
15457 }
15458 }));
15459 }
15460 var IsSomeRendererActing$1 = ReactSharedInternals.IsSomeRendererActing;
15461
15462 var container = _class({
15463
15464 grab: function(){
15465 for (var i = 0; i < arguments.length; i++) arguments[i].inject(this);
15466 return this;
15467 },
15468
15469 empty: function(){
15470 var node;
15471 while (node = this.firstChild) node.eject();
15472 return this;
15473 }
15474
15475 });
15476
15477 function elementFrom(node){
15478 if (node.toElement) return node.toElement();
15479 if (node.getDOMNode) return node.getDOMNode();
15480 if (node.getNode) return node.getNode();
15481 return node;
15482 }
15483
15484 var native_1 = _class({
15485
15486 // conventions
15487
15488 toElement: function(){
15489 return this.element;
15490 },
15491
15492 getDOMNode: function(){
15493 return this.toElement();
15494 },
15495
15496 getNode: function(){
15497 return this.toElement();
15498 },
15499
15500 // placement
15501
15502 inject: function(container){
15503 (container.containerElement || elementFrom(container))
15504 .appendChild(this.element);
15505 return this;
15506 },
15507
15508 injectBefore: function(sibling){
15509 var element = elementFrom(sibling);
15510 element.parentNode.insertBefore(this.element, element);
15511 return this;
15512 },
15513
15514 eject: function(){
15515 var element = this.element, parent = element.parentNode;
15516 if (parent) parent.removeChild(element); // TODO: VML Nodes are dead after being ejected
15517 return this;
15518 },
15519
15520 // events
15521
15522 subscribe: function(type, fn, bind){
15523 if (typeof type != 'string'){ // listen type / fn with object
15524 var subscriptions = [];
15525 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
15526 return function(){ // unsubscribe
15527 for (var i = 0, l = subscriptions.length; i < l; i++)
15528 subscriptions[i]();
15529 return this;
15530 };
15531 } else { // listen to one
15532 if (!bind) bind = this;
15533 var bound;
15534 if (typeof fn === 'function'){
15535 bound = fn.bind ? fn.bind(bind)
15536 : function(){ return fn.apply(bind, arguments); };
15537 } else {
15538 bound = fn;
15539 }
15540 var element = this.element;
15541 if (element.addEventListener){
15542 element.addEventListener(type, bound, false);
15543 return function(){ // unsubscribe
15544 element.removeEventListener(type, bound, false);
15545 return this;
15546 };
15547 } else {
15548 element.attachEvent('on' + type, bound);
15549 return function(){ // unsubscribe
15550 element.detachEvent('on' + type, bound);
15551 return this;
15552 };
15553 }
15554 }
15555 }
15556
15557 });
15558
15559 var fps = 1000 / 60, invalids = [], renderTimer, renderInvalids = function(){
15560 clearTimeout(renderTimer);
15561 renderTimer = null;
15562 var canvases = invalids;
15563 invalids = [];
15564 for (var i = 0, l = canvases.length; i < l; i++){
15565 var c = canvases[i];
15566 c._valid = true;
15567 c.render();
15568 }
15569 };
15570
15571 var resolution = typeof window !== 'undefined' && window.devicePixelRatio || 1;
15572
15573 var previousHit = null, previousHitSurface = null;
15574
15575 var CanvasSurface = _class(native_1, container, {
15576
15577 initialize: function(width, height, existingElement){
15578 var element = this.element = existingElement || document.createElement('canvas');
15579 var context = this.context = element.getContext('2d');
15580 this._valid = true;
15581 if (width != null && height != null) this.resize(width, height);
15582
15583 element.addEventListener('mousemove', this, false);
15584 element.addEventListener('mouseout', this, false);
15585 element.addEventListener('mouseover', this, false);
15586 element.addEventListener('mouseup', this, false);
15587 element.addEventListener('mousedown', this, false);
15588 element.addEventListener('click', this, false);
15589 },
15590
15591 handleEvent: function(event){
15592 if (event.clientX == null) return;
15593 var element = this.element,
15594 rect = element.getBoundingClientRect(),
15595 x = event.clientX - rect.left - element.clientLeft,
15596 y = event.clientY - rect.top - element.clientTop,
15597 hit = this.hitTest(x, y);
15598
15599 if (hit !== previousHit){
15600 if (previousHit){
15601 previousHit.dispatch({
15602 type: 'mouseout',
15603 target: previousHit,
15604 relatedTarget: hit,
15605 sourceEvent: event
15606 });
15607 }
15608 if (hit){
15609 hit.dispatch({
15610 type: 'mouseover',
15611 target: hit,
15612 relatedTarget: previousHit,
15613 sourceEvent: event
15614 });
15615 }
15616 previousHit = hit;
15617 previousHitSurface = this;
15618 this.refreshCursor();
15619 }
15620
15621 if (hit) hit.dispatch(event);
15622 },
15623
15624 refreshCursor: function(){
15625 if (previousHitSurface !== this) return;
15626 var hit = previousHit, hitCursor = '', hitTooltip = '';
15627 while (hit){
15628 if (!hitCursor && hit._cursor){
15629 hitCursor = hit._cursor;
15630 if (hitTooltip) break;
15631 }
15632 if (!hitTooltip && hit._tooltip){
15633 hitTooltip = hit._tooltip;
15634 if (hitCursor) break;
15635 }
15636 hit = hit.parentNode;
15637 }
15638 // TODO: No way to set cursor/title on the surface
15639 this.element.style.cursor = hitCursor;
15640 this.element.title = hitTooltip;
15641 },
15642
15643 resize: function(width, height){
15644 var element = this.element;
15645 element.setAttribute('width', width * resolution);
15646 element.setAttribute('height', height * resolution);
15647 element.style.width = width + 'px';
15648 element.style.height = height + 'px';
15649 this.width = width;
15650 this.height = height;
15651 return this;
15652 },
15653
15654 invalidate: function(left, top, width, height){
15655 if (this._valid){
15656 this._valid = false;
15657 invalids.push(this);
15658 if (!renderTimer){
15659 if (window.mozRequestAnimationFrame){
15660 renderTimer = true;
15661 window.mozRequestAnimationFrame(renderInvalids);
15662 } else {
15663 renderTimer = setTimeout(renderInvalids, fps);
15664 }
15665 }
15666 }
15667 return this;
15668 },
15669
15670 hitTest: function(x, y){
15671 if (x < 0 || y < 0 || x > this.width || y > this.height) return null;
15672 var node = this.lastChild;
15673 while (node){
15674 var hit = node.hitTest(x, y);
15675 if (hit) return hit;
15676 node = node.previousSibling;
15677 }
15678 return null;
15679 },
15680
15681 render: function(){
15682 var node = this.firstChild, context = this.context;
15683 context.setTransform(resolution, 0, 0, resolution, 0, 0);
15684 context.clearRect(0, 0, this.width, this.height);
15685 while (node){
15686 node.renderTo(context, resolution, 0, 0, resolution, 0, 0);
15687 node = node.nextSibling;
15688 }
15689 this.refreshCursor();
15690 }
15691
15692 });
15693
15694 CanvasSurface.tagName = 'canvas';
15695
15696 var surface = CanvasSurface;
15697
15698 var path = _class({
15699
15700 initialize: function(path){
15701 this.reset().push(path);
15702 },
15703
15704 /* parser */
15705
15706 push: function(){
15707 var p = Array.prototype.join.call(arguments, ' ')
15708 .match(/[a-df-z]|[\-+]?(?:[\d\.]e[\-+]?|[^\s\-+,a-z])+/ig);
15709 if (!p) return this;
15710
15711 var last, cmd = p[0], i = 1;
15712 while (cmd){
15713 switch (cmd){
15714 case 'm': this.move(p[i++], p[i++]); break;
15715 case 'l': this.line(p[i++], p[i++]); break;
15716 case 'c': this.curve(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
15717 case 's': this.curve(p[i++], p[i++], null, null, p[i++], p[i++]); break;
15718 case 'q': this.curve(p[i++], p[i++], p[i++], p[i++]); break;
15719 case 't': this.curve(p[i++], p[i++]); break;
15720 case 'a': this.arc(p[i+5], p[i+6], p[i], p[i+1], p[i+3], !+p[i+4], p[i+2]); i += 7; break;
15721 case 'h': this.line(p[i++], 0); break;
15722 case 'v': this.line(0, p[i++]); break;
15723
15724 case 'M': this.moveTo(p[i++], p[i++]); break;
15725 case 'L': this.lineTo(p[i++], p[i++]); break;
15726 case 'C': this.curveTo(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
15727 case 'S': this.curveTo(p[i++], p[i++], null, null, p[i++], p[i++]); break;
15728 case 'Q': this.curveTo(p[i++], p[i++], p[i++], p[i++]); break;
15729 case 'T': this.curveTo(p[i++], p[i++]); break;
15730 case 'A': this.arcTo(p[i+5], p[i+6], p[i], p[i+1], p[i+3], !+p[i+4], p[i+2]); i += 7; break;
15731 case 'H': this.lineTo(p[i++], this.penY); break;
15732 case 'V': this.lineTo(this.penX, p[i++]); break;
15733
15734 case 'Z': case 'z': this.close(); break;
15735 default: cmd = last; i--; continue;
15736 }
15737
15738 last = cmd;
15739 if (last == 'm') last = 'l';
15740 else if (last == 'M') last = 'L';
15741 cmd = p[i++];
15742 }
15743 return this;
15744 },
15745
15746 /* utility methods */
15747
15748 reset: function(){
15749 this.penX = this.penY = 0;
15750 this.penDownX = this.penDownY = null;
15751 this._pivotX = this._pivotY = 0;
15752 this.onReset();
15753 return this;
15754 },
15755
15756 move: function(x,y){
15757 this.onMove(this.penX, this.penY, this._pivotX = this.penX += (+x), this._pivotY = this.penY += (+y));
15758 return this;
15759 },
15760 moveTo: function(x,y){
15761 this.onMove(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
15762 return this;
15763 },
15764
15765 line: function(x,y){
15766 return this.lineTo(this.penX + (+x), this.penY + (+y));
15767 },
15768 lineTo: function(x,y){
15769 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
15770 this.onLine(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
15771 return this;
15772 },
15773
15774 curve: function(c1x, c1y, c2x, c2y, ex, ey){
15775 var x = this.penX, y = this.penY;
15776 return this.curveTo(
15777 x + (+c1x), y + (+c1y),
15778 c2x == null ? null : x + (+c2x),
15779 c2y == null ? null : y + (+c2y),
15780 ex == null ? null : x + (+ex),
15781 ey == null ? null : y + (+ey)
15782 );
15783 },
15784 curveTo: function(c1x, c1y, c2x, c2y, ex, ey){
15785 var x = this.penX, y = this.penY;
15786 if (c2x == null){
15787 c2x = +c1x; c2y = +c1y;
15788 c1x = (x * 2) - (this._pivotX || 0); c1y = (y * 2) - (this._pivotY || 0);
15789 }
15790 if (ex == null){
15791 this._pivotX = +c1x; this._pivotY = +c1y;
15792 ex = +c2x; ey = +c2y;
15793 c2x = (ex + (+c1x) * 2) / 3; c2y = (ey + (+c1y) * 2) / 3;
15794 c1x = (x + (+c1x) * 2) / 3; c1y = (y + (+c1y) * 2) / 3;
15795 } else {
15796 this._pivotX = +c2x; this._pivotY = +c2y;
15797 }
15798 if (this.penDownX == null){ this.penDownX = x; this.penDownY = y; }
15799 this.onBezierCurve(x, y, +c1x, +c1y, +c2x, +c2y, this.penX = +ex, this.penY = +ey);
15800 return this;
15801 },
15802
15803 arc: function(x, y, rx, ry, outer, counterClockwise, rotation){
15804 return this.arcTo(this.penX + (+x), this.penY + (+y), rx, ry, outer, counterClockwise, rotation);
15805 },
15806 arcTo: function(x, y, rx, ry, outer, counterClockwise, rotation){
15807 ry = Math.abs(+ry || +rx || (+y - this.penY));
15808 rx = Math.abs(+rx || (+x - this.penX));
15809
15810 if (!rx || !ry || (x == this.penX && y == this.penY)) return this.lineTo(x, y);
15811
15812 var tX = this.penX, tY = this.penY, clockwise = !+counterClockwise, large = !!+outer;
15813
15814 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad);
15815 x -= tX; y -= tY;
15816
15817 // Ellipse Center
15818 var cx = cos * x / 2 + sin * y / 2,
15819 cy = -sin * x / 2 + cos * y / 2,
15820 rxry = rx * rx * ry * ry,
15821 rycx = ry * ry * cx * cx,
15822 rxcy = rx * rx * cy * cy,
15823 a = rxry - rxcy - rycx;
15824
15825 if (a < 0){
15826 a = Math.sqrt(1 - a / rxry);
15827 rx *= a; ry *= a;
15828 cx = x / 2; cy = y / 2;
15829 } else {
15830 a = Math.sqrt(a / (rxcy + rycx));
15831 if (large == clockwise) a = -a;
15832 var cxd = -a * cy * rx / ry,
15833 cyd = a * cx * ry / rx;
15834 cx = cos * cxd - sin * cyd + x / 2;
15835 cy = sin * cxd + cos * cyd + y / 2;
15836 }
15837
15838 // Rotation + Scale Transform
15839 var xx = cos / rx, yx = sin / rx,
15840 xy = -sin / ry, yy = cos / ry;
15841
15842 // Start and End Angle
15843 var sa = Math.atan2(xy * -cx + yy * -cy, xx * -cx + yx * -cy),
15844 ea = Math.atan2(xy * (x - cx) + yy * (y - cy), xx * (x - cx) + yx * (y - cy));
15845
15846 cx += tX; cy += tY;
15847 x += tX; y += tY;
15848
15849 // Circular Arc
15850 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
15851 this.onArc(
15852 tX, tY, this._pivotX = this.penX = x, this._pivotY = this.penY = y,
15853 cx, cy, rx, ry, sa, ea, !clockwise, rotation
15854 );
15855 return this;
15856 },
15857
15858 counterArc: function(x, y, rx, ry, outer){
15859 return this.arc(x, y, rx, ry, outer, true);
15860 },
15861 counterArcTo: function(x, y, rx, ry, outer){
15862 return this.arcTo(x, y, rx, ry, outer, true);
15863 },
15864
15865 close: function(){
15866 if (this.penDownX != null){
15867 this.onClose(this.penX, this.penY, this.penX = this.penDownX, this.penY = this.penDownY);
15868 this.penDownX = null;
15869 }
15870 return this;
15871 },
15872
15873 /* overridable handlers */
15874
15875 onReset: function(){
15876 },
15877
15878 onMove: function(sx, sy, ex, ey){
15879 },
15880
15881 onLine: function(sx, sy, ex, ey){
15882 this.onBezierCurve(sx, sy, sx, sy, ex, ey, ex, ey);
15883 },
15884
15885 onBezierCurve: function(sx, sy, c1x, c1y, c2x, c2y, ex, ey){
15886 var gx = ex - sx, gy = ey - sy,
15887 g = gx * gx + gy * gy,
15888 v1, v2, cx, cy, u;
15889
15890 cx = c1x - sx; cy = c1y - sy;
15891 u = cx * gx + cy * gy;
15892
15893 if (u > g){
15894 cx -= gx;
15895 cy -= gy;
15896 } else if (u > 0 && g != 0){
15897 cx -= u/g * gx;
15898 cy -= u/g * gy;
15899 }
15900
15901 v1 = cx * cx + cy * cy;
15902
15903 cx = c2x - sx; cy = c2y - sy;
15904 u = cx * gx + cy * gy;
15905
15906 if (u > g){
15907 cx -= gx;
15908 cy -= gy;
15909 } else if (u > 0 && g != 0){
15910 cx -= u/g * gx;
15911 cy -= u/g * gy;
15912 }
15913
15914 v2 = cx * cx + cy * cy;
15915
15916 if (v1 < 0.01 && v2 < 0.01){
15917 this.onLine(sx, sy, ex, ey);
15918 return;
15919 }
15920
15921 // Avoid infinite recursion
15922 if (isNaN(v1) || isNaN(v2)){
15923 throw new Error('Bad input');
15924 }
15925
15926 // Split curve
15927 var s1x = (c1x + c2x) * 0.5, s1y = (c1y + c2y) * 0.5,
15928 l1x = (c1x + sx) * 0.5, l1y = (c1y + sy) * 0.5,
15929 l2x = (l1x + s1x) * 0.5, l2y = (l1y + s1y) * 0.5,
15930 r2x = (ex + c2x) * 0.5, r2y = (ey + c2y) * 0.5,
15931 r1x = (r2x + s1x) * 0.5, r1y = (r2y + s1y) * 0.5,
15932 l2r1x = (l2x + r1x) * 0.5, l2r1y = (l2y + r1y) * 0.5;
15933
15934 // TODO: Manual stack if necessary. Currently recursive without tail optimization.
15935 this.onBezierCurve(sx, sy, l1x, l1y, l2x, l2y, l2r1x, l2r1y);
15936 this.onBezierCurve(l2r1x, l2r1y, r1x, r1y, r2x, r2y, ex, ey);
15937 },
15938
15939 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
15940 // Inverse Rotation + Scale Transform
15941 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad),
15942 xx = cos * rx, yx = -sin * ry,
15943 xy = sin * rx, yy = cos * ry;
15944
15945 // Bezier Curve Approximation
15946 var arc = ea - sa;
15947 if (arc < 0 && !ccw) arc += Math.PI * 2;
15948 else if (arc > 0 && ccw) arc -= Math.PI * 2;
15949
15950 var n = Math.ceil(Math.abs(arc / (Math.PI / 2))),
15951 step = arc / n,
15952 k = (4 / 3) * Math.tan(step / 4);
15953
15954 var x = Math.cos(sa), y = Math.sin(sa);
15955
15956 for (var i = 0; i < n; i++){
15957 var cp1x = x - k * y, cp1y = y + k * x;
15958
15959 sa += step;
15960 x = Math.cos(sa); y = Math.sin(sa);
15961
15962 var cp2x = x + k * y, cp2y = y - k * x;
15963
15964 this.onBezierCurve(
15965 sx, sy,
15966 cx + xx * cp1x + yx * cp1y, cy + xy * cp1x + yy * cp1y,
15967 cx + xx * cp2x + yx * cp2y, cy + xy * cp2x + yy * cp2y,
15968 (sx = (cx + xx * x + yx * y)), (sy = (cy + xy * x + yy * y))
15969 );
15970 }
15971 },
15972
15973 onClose: function(sx, sy, ex, ey){
15974 this.onLine(sx, sy, ex, ey);
15975 }
15976
15977 });
15978
15979 var CanvasPath = _class(path, {
15980
15981 initialize: function(path){
15982 this.reset();
15983 if (path instanceof CanvasPath){
15984 this.path = path.path.slice(0);
15985 } else if (path){
15986 if (path.applyToPath)
15987 path.applyToPath(this);
15988 else
15989 this.push(path);
15990 }
15991 },
15992
15993 onReset: function(){
15994 this.path = [];
15995 },
15996
15997 onMove: function(sx, sy, x, y){
15998 this.path.push(function(context){
15999 context.moveTo(x, y);
16000 });
16001 },
16002
16003 onLine: function(sx, sy, x, y){
16004 this.path.push(function(context){
16005 context.lineTo(x, y);
16006 });
16007 },
16008
16009 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
16010 this.path.push(function(context){
16011 context.bezierCurveTo(p1x, p1y, p2x, p2y, x, y);
16012 });
16013 },
16014
16015 _arcToBezier: path.prototype.onArc,
16016
16017 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
16018 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
16019 this.path.push(function(context){
16020 context.arc(cx, cy, rx, sa, ea, ccw);
16021 });
16022 },
16023
16024 onClose: function(){
16025 this.path.push(function(context){
16026 context.closePath();
16027 });
16028 },
16029
16030 toCommands: function(){
16031 return this.path.slice(0);
16032 }
16033
16034 });
16035
16036 var path$1 = CanvasPath;
16037
16038 var colors = {
16039 maroon: '#800000', red: '#ff0000', orange: '#ffA500', yellow: '#ffff00', olive: '#808000',
16040 purple: '#800080', fuchsia: "#ff00ff", white: '#ffffff', lime: '#00ff00', green: '#008000',
16041 navy: '#000080', blue: '#0000ff', aqua: '#00ffff', teal: '#008080',
16042 black: '#000000', silver: '#c0c0c0', gray: '#808080'
16043 };
16044
16045 var map = function(array, fn){
16046 var results = [];
16047 for (var i = 0, l = array.length; i < l; i++)
16048 results[i] = fn(array[i], i);
16049 return results;
16050 };
16051
16052 var Color = function(color, type){
16053
16054 if (color.isColor){
16055
16056 this.red = color.red;
16057 this.green = color.green;
16058 this.blue = color.blue;
16059 this.alpha = color.alpha;
16060
16061 } else {
16062
16063 var namedColor = colors[color];
16064 if (namedColor){
16065 color = namedColor;
16066 type = 'hex';
16067 }
16068
16069 switch (typeof color){
16070 case 'string': if (!type) type = (type = color.match(/^rgb|^hsb|^hsl/)) ? type[0] : 'hex'; break;
16071 case 'object': type = type || 'rgb'; color = color.toString(); break;
16072 case 'number': type = 'hex'; color = color.toString(16); break;
16073 }
16074
16075 color = Color['parse' + type.toUpperCase()](color);
16076 this.red = color[0];
16077 this.green = color[1];
16078 this.blue = color[2];
16079 this.alpha = color[3];
16080 }
16081
16082 this.isColor = true;
16083
16084 };
16085
16086 var limit = function(number, min, max){
16087 return Math.min(max, Math.max(min, number));
16088 };
16089
16090 var listMatch = /([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,?\s*([-.\d]*\%?)/;
16091 var hexMatch = /^#?([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{0,2})$/i;
16092
16093 Color.parseRGB = function(color){
16094 return map(color.match(listMatch).slice(1), function(bit, i){
16095 if (bit) bit = parseFloat(bit) * (bit[bit.length - 1] == '%' ? 2.55 : 1);
16096 return (i < 3) ? Math.round(((bit %= 256) < 0) ? bit + 256 : bit) : limit(((bit === '') ? 1 : Number(bit)), 0, 1);
16097 });
16098 };
16099
16100 Color.parseHEX = function(color){
16101 if (color.length == 1) color = color + color + color;
16102 return map(color.match(hexMatch).slice(1), function(bit, i){
16103 if (i == 3) return (bit) ? parseInt(bit, 16) / 255 : 1;
16104 return parseInt((bit.length == 1) ? bit + bit : bit, 16);
16105 });
16106 };
16107
16108 Color.parseHSB = function(color){
16109 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
16110 if (bit) bit = parseFloat(bit);
16111 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
16112 else if (i < 3) return limit(Math.round(bit), 0, 100);
16113 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
16114 });
16115
16116 var a = hsb[3];
16117 var br = Math.round(hsb[2] / 100 * 255);
16118 if (hsb[1] == 0) return [br, br, br, a];
16119
16120 var hue = hsb[0];
16121 var f = hue % 60;
16122 var p = Math.round((hsb[2] * (100 - hsb[1])) / 10000 * 255);
16123 var q = Math.round((hsb[2] * (6000 - hsb[1] * f)) / 600000 * 255);
16124 var t = Math.round((hsb[2] * (6000 - hsb[1] * (60 - f))) / 600000 * 255);
16125
16126 switch (Math.floor(hue / 60)){
16127 case 0: return [br, t, p, a];
16128 case 1: return [q, br, p, a];
16129 case 2: return [p, br, t, a];
16130 case 3: return [p, q, br, a];
16131 case 4: return [t, p, br, a];
16132 default: return [br, p, q, a];
16133 }
16134 };
16135
16136 Color.parseHSL = function(color){
16137 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
16138 if (bit) bit = parseFloat(bit);
16139 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
16140 else if (i < 3) return limit(Math.round(bit), 0, 100);
16141 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
16142 });
16143
16144 var h = hsb[0] / 60;
16145 var s = hsb[1] / 100;
16146 var l = hsb[2] / 100;
16147 var a = hsb[3];
16148
16149 var c = (1 - Math.abs(2 * l - 1)) * s;
16150 var x = c * (1 - Math.abs(h % 2 - 1));
16151 var m = l - c / 2;
16152
16153 var p = Math.round((c + m) * 255);
16154 var q = Math.round((x + m) * 255);
16155 var t = Math.round((m) * 255);
16156
16157 switch (Math.floor(h)){
16158 case 0: return [p, q, t, a];
16159 case 1: return [q, p, t, a];
16160 case 2: return [t, p, q, a];
16161 case 3: return [t, q, p, a];
16162 case 4: return [q, t, p, a];
16163 default: return [p, t, q, a];
16164 }
16165 };
16166
16167 var toString = function(type, array){
16168 if (array[3] != 1) type += 'a';
16169 else array.pop();
16170 return type + '(' + array.join(', ') + ')';
16171 };
16172
16173 Color.prototype = {
16174
16175 toHSB: function(array){
16176 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
16177
16178 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
16179 var hue = 0, saturation = (delta != 0) ? delta / max : 0, brightness = max / 255;
16180 if (saturation){
16181 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
16182 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
16183 if ((hue /= 6) < 0) hue++;
16184 }
16185
16186 var hsb = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100), alpha];
16187
16188 return (array) ? hsb : toString('hsb', hsb);
16189 },
16190
16191 toHSL: function(array){
16192 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
16193
16194 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
16195 var hue = 0, saturation = (delta != 0) ? delta / (255 - Math.abs((max + min) - 255)) : 0, lightness = (max + min) / 512;
16196 if (saturation){
16197 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
16198 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
16199 if ((hue /= 6) < 0) hue++;
16200 }
16201
16202 var hsl = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(lightness * 100), alpha];
16203
16204 return (array) ? hsl : toString('hsl', hsl);
16205 },
16206
16207 toHEX: function(array){
16208
16209 var a = this.alpha;
16210 var alpha = ((a = Math.round((a * 255)).toString(16)).length == 1) ? a + a : a;
16211
16212 var hex = map([this.red, this.green, this.blue], function(bit){
16213 bit = bit.toString(16);
16214 return (bit.length == 1) ? '0' + bit : bit;
16215 });
16216
16217 return (array) ? hex.concat(alpha) : '#' + hex.join('') + ((alpha == 'ff') ? '' : alpha);
16218 },
16219
16220 toRGB: function(array){
16221 var rgb = [this.red, this.green, this.blue, this.alpha];
16222 return (array) ? rgb : toString('rgb', rgb);
16223 }
16224
16225 };
16226
16227 Color.prototype.toString = Color.prototype.toRGB;
16228
16229 Color.hex = function(hex){
16230 return new Color(hex, 'hex');
16231 };
16232
16233 if (commonjsGlobal.hex == null) commonjsGlobal.hex = Color.hex;
16234
16235 Color.hsb = function(h, s, b, a){
16236 return new Color([h || 0, s || 0, b || 0, (a == null) ? 1 : a], 'hsb');
16237 };
16238
16239 if (commonjsGlobal.hsb == null) commonjsGlobal.hsb = Color.hsb;
16240
16241 Color.hsl = function(h, s, l, a){
16242 return new Color([h || 0, s || 0, l || 0, (a == null) ? 1 : a], 'hsl');
16243 };
16244
16245 if (commonjsGlobal.hsl == null) commonjsGlobal.hsl = Color.hsl;
16246
16247 Color.rgb = function(r, g, b, a){
16248 return new Color([r || 0, g || 0, b || 0, (a == null) ? 1 : a], 'rgb');
16249 };
16250
16251 if (commonjsGlobal.rgb == null) commonjsGlobal.rgb = Color.rgb;
16252
16253 Color.detach = function(color){
16254 color = new Color(color);
16255 return [Color.rgb(color.red, color.green, color.blue).toString(), color.alpha];
16256 };
16257
16258 var color = Color;
16259
16260 var dummy = _class({
16261
16262 // placement
16263
16264 _resetPlacement: function(){
16265 var container = this.parentNode;
16266 if (container){
16267 var previous = this.previousSibling, next = this.nextSibling;
16268 if (previous){
16269 previous.nextSibling = next;
16270 } else {
16271 container.firstChild = next;
16272 }
16273 if (next){
16274 next.previousSibling = previous;
16275 } else {
16276 container.lastChild = this.previousSibling;
16277 }
16278 }
16279 this.previousSibling = null;
16280 this.nextSibling = null;
16281 this.parentNode = null;
16282 return this;
16283 },
16284
16285 inject: function(container){
16286 this._resetPlacement();
16287 var last = container.lastChild;
16288 if (last){
16289 last.nextSibling = this;
16290 this.previousSibling = last;
16291 } else {
16292 container.firstChild = this;
16293 }
16294 container.lastChild = this;
16295 this.parentNode = container;
16296 this._place();
16297 return this;
16298 },
16299
16300 injectBefore: function(sibling){
16301 this._resetPlacement();
16302 var container = sibling.parentNode;
16303 if (!container) return this;
16304 var previous = sibling.previousSibling;
16305 if (previous){
16306 previous.nextSibling = this;
16307 this.previousSibling = previous;
16308 } else {
16309 container.firstChild = this;
16310 }
16311 sibling.previousSibling = this;
16312 this.nextSibling = sibling;
16313 this.parentNode = container;
16314 this._place();
16315 return this;
16316 },
16317
16318 eject: function(){
16319 this._resetPlacement();
16320 this._place();
16321 return this;
16322 },
16323
16324 _place: function(){},
16325
16326 // events
16327
16328 dispatch: function(event){
16329 var events = this._events,
16330 listeners = events && events[event.type];
16331 if (listeners){
16332 listeners = listeners.slice(0);
16333 for (var i = 0, l = listeners.length; i < l; i++){
16334 var fn = listeners[i], result;
16335 if (typeof fn == 'function')
16336 result = fn.call(this, event);
16337 else
16338 result = fn.handleEvent(event);
16339 if (result === false) event.preventDefault();
16340 }
16341 }
16342 if (this.parentNode && this.parentNode.dispatch){
16343 this.parentNode.dispatch(event);
16344 }
16345 },
16346
16347 subscribe: function(type, fn, bind){
16348 if (typeof type != 'string'){ // listen type / fn with object
16349 var subscriptions = [];
16350 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
16351 return function(){ // unsubscribe
16352 for (var i = 0, l = subscriptions.length; i < l; i++)
16353 subscriptions[i]();
16354 return this;
16355 };
16356 } else { // listen to one
16357 var bound = typeof fn === 'function' ? fn.bind(bind || this) : fn,
16358 events = this._events || (this._events = {}),
16359 listeners = events[type] || (events[type] = []);
16360 listeners.push(bound);
16361 return function(){
16362 // unsubscribe
16363 for (var i = 0, l = listeners.length; i < l; i++){
16364 if (listeners[i] === bound){
16365 listeners.splice(i, 1);
16366 break;
16367 }
16368 }
16369 }
16370 }
16371 }
16372
16373 });
16374
16375 var CanvasNode = _class(transform, dummy, {
16376
16377 invalidate: function(){
16378 if (this.parentNode) this.parentNode.invalidate();
16379 if (this._layer) this._layerCache = null;
16380 return this;
16381 },
16382
16383 _place: function(){
16384 this.invalidate();
16385 },
16386
16387 _transform: function(){
16388 this.invalidate();
16389 },
16390
16391 blend: function(opacity){
16392 if (opacity >= 1 && this._layer) this._layer = null;
16393 this._opacity = opacity;
16394 if (this.parentNode) this.parentNode.invalidate();
16395 return this;
16396 },
16397
16398 // visibility
16399
16400 hide: function(){
16401 this._invisible = true;
16402 if (this.parentNode) this.parentNode.invalidate();
16403 return this;
16404 },
16405
16406 show: function(){
16407 this._invisible = false;
16408 if (this.parentNode) this.parentNode.invalidate();
16409 return this;
16410 },
16411
16412 // interaction
16413
16414 indicate: function(cursor, tooltip){
16415 this._cursor = cursor;
16416 this._tooltip = tooltip;
16417 return this.invalidate();
16418 },
16419
16420 hitTest: function(x, y){
16421 if (this._invisible) return null;
16422 var point = this.inversePoint(x, y);
16423 if (!point) return null;
16424 return this.localHitTest(point.x, point.y);
16425 },
16426
16427 // rendering
16428
16429 renderTo: function(context, xx, yx, xy, yy, x, y){
16430 var opacity = this._opacity;
16431 if (opacity == null || opacity >= 1){
16432 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
16433 }
16434
16435 // Render to a compositing layer and cache it
16436
16437 var layer = this._layer, canvas, isDirty = true,
16438 w = context.canvas.width, h = context.canvas.height;
16439 if (layer){
16440 layer.setTransform(1, 0, 0, 1, 0, 0);
16441 canvas = layer.canvas;
16442 if (canvas.width < w || canvas.height < h){
16443 canvas.width = w;
16444 canvas.height = h;
16445 } else {
16446 var c = this._layerCache;
16447 if (c && c.xx === xx && c.yx === yx && c.xy === xy
16448 && c.yy === yy && c.x === x && c.y === y){
16449 isDirty = false;
16450 } else {
16451 layer.clearRect(0, 0, w, h);
16452 }
16453 }
16454 } else {
16455 canvas = document.createElement('canvas');
16456 canvas.width = w;
16457 canvas.height = h;
16458 this._layer = layer = canvas.getContext('2d');
16459 }
16460
16461 if (isDirty){
16462 this.renderLayerTo(layer, xx, yx, xy, yy, x, y);
16463 this._layerCache = {
16464 xx: xx,
16465 yx: yx,
16466 xy: xy,
16467 yy: yy,
16468 x: x,
16469 y: y
16470 };
16471 }
16472
16473 context.globalAlpha = opacity;
16474 context.setTransform(1, 0, 0, 1, 0, 0);
16475 context.drawImage(
16476 canvas,
16477 0, 0, w, h,
16478 0, 0, w, h
16479 );
16480 context.globalAlpha = 1;
16481 }
16482
16483 });
16484
16485 var node = CanvasNode;
16486
16487 var genericCanvas = typeof document !== 'undefined' && document.createElement('canvas'),
16488 genericContext = genericCanvas && genericCanvas.getContext && genericCanvas.getContext('2d');
16489
16490 function recolorImage(img, color1, color2){
16491 // TODO: Fix this experimental implementation
16492 color1 = color.detach(color1);
16493 color2 = color.detach(color2);
16494 var canvas = document.createElement('canvas'),
16495 context = canvas.getContext('2d');
16496 canvas.width = img.width;
16497 canvas.height = img.height;
16498 context.fillStyle = color2[0];
16499 context.fillRect(0, 0, img.width, img.height);
16500 context.globalCompositeOperation = 'lighter';
16501 context.drawImage(img, 0, 0);
16502 return canvas;
16503 }
16504
16505 var Base = _class(node, {
16506
16507 initialize: function(){
16508 this._fill = null;
16509 this._pendingFill = null;
16510 this._fillTransform = null;
16511 this._stroke = null;
16512 this._strokeCap = null;
16513 this._strokeDash = null;
16514 this._strokeJoin = null;
16515 this._strokeWidth = null;
16516 },
16517
16518 /* styles */
16519
16520 _addColors: function(gradient, stops){
16521 // Enumerate stops, assumes offsets are enumerated in order
16522 // TODO: Sort. Chrome doesn't always enumerate in expected order but requires stops to be specified in order.
16523 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++)
16524 gradient.addColorStop(i / l, new color(stops[i]).toString());
16525 else for (var offset in stops)
16526 gradient.addColorStop(offset, new color(stops[offset]).toString());
16527 return gradient;
16528 },
16529
16530
16531 fill: function(color$1){
16532 if (arguments.length > 1) return this.fillLinear(arguments);
16533 if (this._pendingFill) this._pendingFill();
16534 this._fill = color$1 ? new color(color$1).toString() : null;
16535 return this.invalidate();
16536 },
16537
16538 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
16539 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
16540 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
16541 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
16542 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
16543 if (centerX == null) centerX = focusX;
16544 if (centerY == null) centerY = focusY;
16545
16546 centerX += centerX - focusX;
16547 centerY += centerY - focusY;
16548
16549 if (radiusX === 0 || radiusX === '0') return this.fillLinear(stops);
16550 var ys = radiusY / radiusX;
16551
16552 if (this._pendingFill) this._pendingFill();
16553
16554 var gradient = genericContext.createRadialGradient(focusX, focusY / ys, 0, centerX, centerY / ys, radiusX * 2);
16555
16556 // Double fill radius to simulate repeating gradient
16557 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++){
16558 gradient.addColorStop(i / l / 2, new color(stops[i]).toString());
16559 gradient.addColorStop(1 - i / l / 2, new color(stops[i]).toString());
16560 } else for (var offset in stops){
16561 gradient.addColorStop(offset / 2, new color(stops[offset]).toString());
16562 gradient.addColorStop(1- offset / 2, new color(stops[offset]).toString());
16563 }
16564
16565 this._fill = gradient;
16566 this._fillTransform = new transform(1, 0, 0, ys);
16567 return this.invalidate();
16568 },
16569
16570 fillLinear: function(stops, x1, y1, x2, y2){
16571 if (arguments.length < 5){
16572 var angle = ((x1 == null) ? 270 : x1) * Math.PI / 180;
16573
16574 var x = Math.cos(angle), y = -Math.sin(angle),
16575 l = (Math.abs(x) + Math.abs(y)) / 2,
16576 w = this.width || 1, h = this.height || 1;
16577
16578 x *= l; y *= l;
16579
16580 x1 = 0.5 - x;
16581 x2 = 0.5 + x;
16582 y1 = 0.5 - y;
16583 y2 = 0.5 + y;
16584 this._fillTransform = new transform(w, 0, 0, h);
16585 } else {
16586 this._fillTransform = null;
16587 }
16588 if (this._pendingFill) this._pendingFill();
16589 var gradient = genericContext.createLinearGradient(x1, y1, x2, y2);
16590 this._addColors(gradient, stops);
16591 this._fill = gradient;
16592 return this.invalidate();
16593 },
16594
16595 fillImage: function(url, width, height, left, top, color1, color2){
16596 if (this._pendingFill) this._pendingFill();
16597 var img = url;
16598 if (!(img instanceof Image)){
16599 img = new Image();
16600 img.src = url;
16601 }
16602 if (img.width && img.height){
16603 return this._fillImage(img, width, height, left || 0, top || 0, color1, color2);
16604 }
16605
16606 // Not yet loaded
16607 this._fill = null;
16608 var self = this,
16609 callback = function(){
16610 cancel();
16611 self._fillImage(img, width, height, left || 0, top || 0, color1, color2);
16612 },
16613 cancel = function(){
16614 img.removeEventListener('load', callback, false);
16615 self._pendingFill = null;
16616 };
16617 this._pendingFill = cancel;
16618 img.addEventListener('load', callback, false);
16619 return this;
16620 },
16621
16622 _fillImage: function(img, width, height, left, top, color1, color2){
16623 var w = width ? width / img.width : 1,
16624 h = height ? height / img.height : 1;
16625 if (color1 != null) img = recolorImage(img, color1, color2);
16626 this._fill = genericContext.createPattern(img, 'repeat');
16627 this._fillTransform = new transform(w, 0, 0, h, left || 0, top || 0);
16628 return this.invalidate();
16629 },
16630
16631 stroke: function(color$1, width, cap, join, dash){
16632 this._stroke = color$1 ? new color(color$1).toString() : null;
16633 this._strokeWidth = (width != null) ? width : 1;
16634 this._strokeCap = (cap != null) ? cap : 'round';
16635 this._strokeJoin = (join != null) ? join : 'round';
16636 this._strokeDash = dash;
16637 return this.invalidate();
16638 },
16639
16640 // Rendering
16641
16642 element_renderTo: node.prototype.renderTo,
16643
16644 renderTo: function(context, xx, yx, xy, yy, x, y){
16645 var opacity = this._opacity;
16646 if (opacity == null || opacity >= 1){
16647 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
16648 }
16649 if (this._fill && this._stroke){
16650 return this.element_renderTo(context, xx, yx, xy, yy, x, y);
16651 }
16652 context.globalAlpha = opacity;
16653 var r = this.renderLayerTo(context, xx, yx, xy, yy, x, y);
16654 context.globalAlpha = 1;
16655 return r;
16656 },
16657
16658 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
16659 context.setTransform(xx, yx, xy, yy, x, y);
16660 this.renderShapeTo(context);
16661 }
16662
16663 });
16664
16665 Base._genericContext = genericContext;
16666
16667 var base = Base;
16668
16669 var shape = _class(base, {
16670
16671 base_initialize: base.prototype.initialize,
16672
16673 initialize: function(path, width, height){
16674 this.base_initialize();
16675 this.width = width;
16676 this.height = height;
16677 if (path != null) this.draw(path);
16678 },
16679
16680 draw: function(path, width, height){
16681 if (!(path instanceof path$1)) path = new path$1(path);
16682 this.path = path;
16683 this._commands = path.toCommands();
16684 if (width != null) this.width = width;
16685 if (height != null) this.height = height;
16686 return this.invalidate();
16687 },
16688
16689 localHitTest: function(x, y){
16690 if (!this._fill) return null;
16691 if (this.width == null || this.height == null){
16692 var context = base._genericContext, commands = this._commands;
16693 if (!commands) return null;
16694 context.beginPath();
16695 for (var i = 0, l = commands.length; i < l; i++)
16696 commands[i](context);
16697 return context.isPointInPath(x, y) ? this : null;
16698 }
16699 if (x > 0 && y > 0 && x < this.width && y < this.height){
16700 return this;
16701 }
16702 return null;
16703 },
16704
16705 renderShapeTo: function(context){
16706 if (this._invisible || !this._commands || (!this._fill && !this._stroke)) {
16707 return null;
16708 }
16709 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
16710 var commands = this._commands,
16711 fill = this._fill,
16712 stroke = this._stroke,
16713 dash = this._strokeDash;
16714
16715 context.beginPath();
16716
16717 if (dash) {
16718 if (context.setLineDash) {
16719 context.setLineDash(dash);
16720 } else {
16721 // TODO: Remove when FF supports setLineDash.
16722 context.mozDash = dash;
16723 }
16724 // TODO: Create fallback to other browsers.
16725 } else {
16726 if (context.setLineDash) {
16727 context.setLineDash([]);
16728 } else {
16729 context.mozDash = null;
16730 }
16731 }
16732
16733 for (var i = 0, l = commands.length; i < l; i++)
16734 commands[i](context);
16735
16736 if (fill){
16737 var m = this._fillTransform;
16738 if (m){
16739 context.save(); // TODO: Optimize away this by restoring the transform before stroking
16740 context.transform(m.xx, m.yx, m.xy, m.yy, m.x, m.y);
16741 context.fillStyle = fill;
16742 context.fill();
16743 context.restore();
16744 } else {
16745 context.fillStyle = fill;
16746 context.fill();
16747 }
16748 }
16749 if (stroke){
16750 context.strokeStyle = stroke;
16751 context.lineWidth = this._strokeWidth;
16752 context.lineCap = this._strokeCap;
16753 context.lineJoin = this._strokeJoin;
16754 context.stroke();
16755 }
16756 }
16757
16758 });
16759
16760 var group = _class(node, container, {
16761
16762 initialize: function(width, height){
16763 this.width = width;
16764 this.height = height;
16765 },
16766
16767 localHitTest: function(x, y){
16768 var node = this.lastChild;
16769 while (node){
16770 var hit = node.hitTest(x, y);
16771 if (hit) return hit;
16772 node = node.previousSibling;
16773 }
16774 return null;
16775 },
16776
16777 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
16778 if (this._invisible) return;
16779
16780 x = xx * this.x + xy * this.y + x;
16781 y = yx * this.x + yy * this.y + y;
16782
16783 var t = xx;
16784 xx = t * this.xx + xy * this.yx;
16785 xy = t * this.xy + xy * this.yy;
16786 t = yx;
16787 yx = t * this.xx + yy * this.yx;
16788 yy = t * this.xy + yy * this.yy;
16789
16790 var node = this.firstChild;
16791 while (node){
16792 node.renderTo(context, xx, yx, xy, yy, x, y);
16793 node = node.nextSibling;
16794 }
16795 }
16796
16797 });
16798
16799 var clippingrectangle = _class(node, container, {
16800
16801 initialize: function(width, height){
16802 this.width = width;
16803 this.height = height;
16804 },
16805
16806 localHitTest: function(x, y) {
16807 var node = this.lastChild;
16808 while (node){
16809 var hit = node.hitTest(x, y);
16810 if (hit) return hit;
16811 node = node.previousSibling;
16812 }
16813 return null;
16814 },
16815
16816 renderLayerTo: function(context, xx, yx, xy, yy, x, y) {
16817 context.setTransform(xx, yx, xy, yy, x, y);
16818 context.save();
16819 // Need beginPath to fix Firefox bug. See 3354054.
16820 context.beginPath();
16821 context.rect(this.x, this.y, this.width, this.height);
16822 context.clip();
16823
16824 var node = this.firstChild;
16825 while(node) {
16826 node.renderTo(context, xx, yx, xy, yy, x, y);
16827 node = node.nextSibling;
16828 }
16829 context.restore();
16830 }
16831 });
16832
16833 var fontAnchors = { middle: 'center' };
16834
16835 var text = _class(base, {
16836
16837 base_initialize: base.prototype.initialize,
16838
16839 initialize: function(text, font, alignment, path){
16840 this.base_initialize();
16841 this.draw.apply(this, arguments);
16842 },
16843
16844 draw: function(text, font, alignment, path){
16845 var em;
16846 if (typeof font == 'string'){
16847 em = Number(/(\d+)/.exec(font)[0]);
16848 } else if (font){
16849 em = parseFloat(font.fontSize || font['font-size'] || '12');
16850 font = (font.fontStyle || font['font-style'] || '') + ' ' +
16851 (font.fontVariant || font['font-variant'] || '') + ' ' +
16852 (font.fontWeight || font['font-weight'] || '') + ' ' +
16853 em + 'px ' +
16854 (font.fontFamily || font['font-family'] || 'Arial');
16855 } else {
16856 font = this._font;
16857 }
16858
16859 var lines = text && text.split(/\r?\n/);
16860 this._font = font;
16861 this._fontSize = em;
16862 this._text = lines;
16863 this._alignment = fontAnchors[alignment] || alignment || 'left';
16864
16865 var context = base._genericContext;
16866
16867 context.font = this._font;
16868 context.textAlign = this._alignment;
16869 context.textBaseline = 'middle';
16870
16871 lines = this._text;
16872 var l = lines.length, width = 0;
16873 for (var i = 0; i < l; i++){
16874 var w = context.measureText(lines[i]).width;
16875 if (w > width) width = w;
16876 }
16877 this.width = width;
16878 this.height = l ? l * 1.1 * em : 0;
16879 return this.invalidate();
16880 },
16881
16882 // Interaction
16883
16884 localHitTest: function(x, y){
16885 if (!this._fill) return null;
16886 if (x > 0 && y > 0 && x < this.width && y < this.height){
16887 return this;
16888 }
16889 return null;
16890 },
16891
16892 // Rendering
16893
16894 renderShapeTo: function(context){
16895 if (this._invisible || !this._text || (!this._fill && !this._stroke)) {
16896 return null;
16897 }
16898 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
16899 var fill = this._fill,
16900 stroke = this._stroke,
16901 text = this._text,
16902 dash = this._strokeDash;
16903
16904 context.font = this._font;
16905 context.textAlign = this._alignment;
16906 context.textBaseline = 'middle';
16907
16908 var em = this._fontSize,
16909 y = em / 2,
16910 lineHeight = 1.1 * em,
16911 lines = text,
16912 l = lines.length;
16913
16914 if (fill){
16915 context.fillStyle = fill;
16916 for (var i = 0; i < l; i++)
16917 context.fillText(lines[i], 0, y + i * lineHeight);
16918 }
16919 if (stroke){
16920 if (dash) {
16921 if (context.setLineDash) {
16922 context.setLineDash(dash);
16923 } else {
16924 // TODO: Remove when FF supports setLineDash.
16925 context.mozDash = dash;
16926 }
16927 // TODO: Create fallback to other browsers.
16928 } else {
16929 if (context.setLineDash) {
16930 context.setLineDash([]);
16931 } else {
16932 context.mozDash = null;
16933 }
16934 }
16935
16936 context.strokeStyle = stroke;
16937 context.lineWidth = this._strokeWidth;
16938 context.lineCap = this._strokeCap;
16939 context.lineJoin = this._strokeJoin;
16940 for (i = 0; i < l; i++)
16941 context.strokeText(lines[i], 0, y + i * lineHeight);
16942 }
16943 }
16944
16945 });
16946
16947 var VMLCSS = 'behavior:url(#default#VML);display:inline-block;position:absolute;left:0px;top:0px;';
16948
16949 var styleSheet, styledTags = {}, styleTag = function(tag){
16950 if (styleSheet) styledTags[tag] = styleSheet.addRule('av\\:' + tag, VMLCSS);
16951 };
16952
16953 var init = function(document){
16954
16955 var namespaces;
16956 try { // IE9 workaround: sometimes it throws here
16957 namespaces = document.namespaces;
16958 } catch (e) {
16959 }
16960 if (!namespaces) return false;
16961
16962 namespaces.add('av', 'urn:schemas-microsoft-com:vml');
16963 namespaces.add('ao', 'urn:schemas-microsoft-com:office:office');
16964
16965 styleSheet = document.createStyleSheet();
16966 styleSheet.addRule('vml', 'display:inline-block;position:relative;overflow:hidden;');
16967 /* styleTag('skew');
16968 styleTag('fill');
16969 styleTag('stroke');
16970 styleTag('path');
16971 styleTag('textpath');
16972 styleTag('group');*/
16973
16974 styleTag('vml');
16975
16976 return true;
16977
16978 };
16979
16980 var createElement = function(tag){
16981 if (!(tag in styledTags)) styleTag(tag);
16982 return document.createElement('av:' + tag);
16983 };
16984
16985 var dom = {
16986 init: init,
16987 createElement: createElement
16988 };
16989
16990 var precision = 100;
16991
16992 var VMLSurface = _class(native_1, container, {
16993
16994 initialize: function VMLSurface(width, height, existingElement){
16995 this.element = existingElement || document.createElement('vml');
16996 this.containerElement = dom.createElement('group');
16997 this.element.appendChild(this.containerElement);
16998 if (width != null && height != null) this.resize(width, height);
16999 },
17000
17001 resize: function(width, height){
17002 this.width = width;
17003 this.height = height;
17004
17005 var style = this.element.style;
17006 style.pixelWidth = width;
17007 style.pixelHeight = height;
17008
17009 style = this.containerElement.style;
17010 style.width = width;
17011 style.height = height;
17012
17013 var halfPixel = (0.5 * precision);
17014
17015 this.containerElement.coordorigin = halfPixel + ',' + halfPixel;
17016 this.containerElement.coordsize = (width * precision) + ',' + (height * precision);
17017
17018 return this;
17019 }
17020
17021 });
17022
17023 VMLSurface.tagName = 'av:vml';
17024
17025 var surface$1 = VMLSurface;
17026
17027 var precision$1 = 100;
17028
17029 var round = Math.round;
17030
17031 var VMLPath = _class(path, {
17032
17033 initialize: function(path){
17034 this.reset();
17035 if (path instanceof VMLPath){
17036 this.path = [Array.prototype.join.call(path.path, ' ')];
17037 } else if (path){
17038 if (path.applyToPath)
17039 path.applyToPath(this);
17040 else
17041 this.push(path);
17042 }
17043 },
17044
17045 onReset: function(){
17046 this.path = [];
17047 },
17048
17049 onMove: function(sx, sy, x, y){
17050 this.path.push('m', round(x * precision$1), round(y * precision$1));
17051 },
17052
17053 onLine: function(sx, sy, x, y){
17054 this.path.push('l', round(x * precision$1), round(y * precision$1));
17055 },
17056
17057 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
17058 this.path.push('c',
17059 round(p1x * precision$1), round(p1y * precision$1),
17060 round(p2x * precision$1), round(p2y * precision$1),
17061 round(x * precision$1), round(y * precision$1)
17062 );
17063 },
17064
17065 _arcToBezier: path.prototype.onArc,
17066
17067 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
17068 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
17069 cx *= precision$1;
17070 cy *= precision$1;
17071 rx *= precision$1;
17072 this.path.push(ccw ? 'at' : 'wa',
17073 round(cx - rx), round(cy - rx),
17074 round(cx + rx), round(cy + rx),
17075 round(sx * precision$1), round(sy * precision$1),
17076 round(ex * precision$1), round(ey * precision$1)
17077 );
17078 },
17079
17080 onClose: function(){
17081 this.path.push('x');
17082 },
17083
17084 toVML: function(){
17085 return this.path.join(' ');
17086 }
17087
17088 });
17089
17090 VMLPath.prototype.toString = VMLPath.prototype.toVML;
17091
17092 var path$2 = VMLPath;
17093
17094 var shadow = _class(dummy, native_1, {
17095
17096 dummy_inject: dummy.prototype.inject,
17097 dummy_injectBefore: dummy.prototype.injectBefore,
17098 dummy_eject: dummy.prototype.eject,
17099 native_inject: native_1.prototype.inject,
17100 native_injectBefore: native_1.prototype.injectBefore,
17101 native_eject: native_1.prototype.eject,
17102
17103 inject: function(container){
17104 this.dummy_inject(container);
17105 this.native_inject(container);
17106 return this;
17107 },
17108
17109 injectBefore: function(sibling){
17110 this.dummy_injectBefore(sibling);
17111 this.native_injectBefore(sibling);
17112 return this;
17113 },
17114
17115 eject: function(){
17116 this.dummy_eject();
17117 this.native_eject();
17118 return this;
17119 }
17120
17121 });
17122
17123 var node$1 = _class(shadow, transform, {
17124
17125 initialize: function(tag){
17126 //this.uid = uniqueID();
17127 var element = this.element = dom.createElement(tag);
17128 //element.setAttribute('id', 'e' + this.uid);
17129 },
17130
17131 _place: function(){
17132 if (this.parentNode){
17133 this._transform();
17134 }
17135 },
17136
17137 // visibility
17138
17139 hide: function(){
17140 this.element.style.display = 'none';
17141 return this;
17142 },
17143
17144 show: function(){
17145 this.element.style.display = '';
17146 return this;
17147 },
17148
17149 // interaction
17150
17151 indicate: function(cursor, tooltip){
17152 if (cursor) this.element.style.cursor = cursor;
17153 if (tooltip) this.element.title = tooltip;
17154 return this;
17155 }
17156
17157 });
17158
17159 var precision$2 = 100;
17160
17161 var defaultBox = { left: 0, top: 0, width: 500, height: 500 };
17162
17163 var base$1 = _class(node$1, {
17164
17165 element_initialize: node$1.prototype.initialize,
17166
17167 initialize: function(tag){
17168 this.element_initialize(tag);
17169 var element = this.element;
17170
17171 var skew = this.skewElement = dom.createElement('skew');
17172 skew.on = true;
17173 element.appendChild(skew);
17174
17175 var fill = this.fillElement = dom.createElement('fill');
17176 fill.on = false;
17177 element.appendChild(fill);
17178
17179 var stroke = this.strokeElement = dom.createElement('stroke');
17180 stroke.on = false;
17181 element.appendChild(stroke);
17182 },
17183
17184 /* transform */
17185
17186 _transform: function(){
17187 var container = this.parentNode;
17188
17189 // Active Transformation Matrix
17190 var m = container ? new transform(container._activeTransform).transform(this) : this;
17191
17192 // Box in shape user space
17193
17194 var box = this._boxCoords || this._size || defaultBox;
17195
17196 var originX = box.left || 0,
17197 originY = box.top || 0,
17198 width = box.width || 1,
17199 height = box.height || 1;
17200
17201 // Flipped
17202 var flip = m.yx / m.xx > m.yy / m.xy;
17203 if (m.xx < 0 ? m.xy >= 0 : m.xy < 0) flip = !flip;
17204 flip = flip ? -1 : 1;
17205
17206 m = new transform().scale(flip, 1).transform(m);
17207
17208 // Rotation is approximated based on the transform
17209 var rotation = Math.atan2(-m.xy, m.yy) * 180 / Math.PI;
17210
17211 // Reverse the rotation, leaving the final transform in box space
17212 var rad = rotation * Math.PI / 180, sin = Math.sin(rad), cos = Math.cos(rad);
17213
17214 var transform$1 = new transform(
17215 (m.xx * cos - m.xy * sin),
17216 (m.yx * cos - m.yy * sin) * flip,
17217 (m.xy * cos + m.xx * sin) * flip,
17218 (m.yy * cos + m.yx * sin)
17219 );
17220
17221 var rotationTransform = new transform().rotate(rotation, 0, 0);
17222
17223 var shapeToBox = new transform().rotate(-rotation, 0, 0).transform(m).moveTo(0,0);
17224
17225 // Scale box after reversing rotation
17226 width *= Math.abs(shapeToBox.xx);
17227 height *= Math.abs(shapeToBox.yy);
17228
17229 // Place box
17230 var left = m.x, top = m.y;
17231
17232 // Compensate for offset by center origin rotation
17233 var vx = -width / 2, vy = -height / 2;
17234 var point = rotationTransform.point(vx, vy);
17235 left -= point.x - vx;
17236 top -= point.y - vy;
17237
17238 // Adjust box position based on offset
17239 var rsm = new transform(m).moveTo(0,0);
17240 point = rsm.point(originX, originY);
17241 left += point.x;
17242 top += point.y;
17243
17244 if (flip < 0) left = -left - width;
17245
17246 // Place transformation origin
17247 var point0 = rsm.point(-originX, -originY);
17248 var point1 = rotationTransform.point(width, height);
17249 var point2 = rotationTransform.point(width, 0);
17250 var point3 = rotationTransform.point(0, height);
17251
17252 var minX = Math.min(0, point1.x, point2.x, point3.x),
17253 maxX = Math.max(0, point1.x, point2.x, point3.x),
17254 minY = Math.min(0, point1.y, point2.y, point3.y),
17255 maxY = Math.max(0, point1.y, point2.y, point3.y);
17256
17257 var transformOriginX = (point0.x - point1.x / 2) / (maxX - minX) * flip,
17258 transformOriginY = (point0.y - point1.y / 2) / (maxY - minY);
17259
17260 // Adjust the origin
17261 point = shapeToBox.point(originX, originY);
17262 originX = point.x;
17263 originY = point.y;
17264
17265 // Scale stroke
17266 var strokeWidth = this._strokeWidth;
17267 if (strokeWidth){
17268 // Scale is the hypothenus between the two vectors
17269 // TODO: Use area calculation instead
17270 var vx = m.xx + m.xy, vy = m.yy + m.yx;
17271 strokeWidth *= Math.sqrt(vx * vx + vy * vy) / Math.sqrt(2);
17272 }
17273
17274 // convert to multiplied precision space
17275 originX *= precision$2;
17276 originY *= precision$2;
17277 left *= precision$2;
17278 top *= precision$2;
17279 width *= precision$2;
17280 height *= precision$2;
17281
17282 // Set box
17283 var element = this.element;
17284 element.coordorigin = originX + ',' + originY;
17285 element.coordsize = width + ',' + height;
17286 element.style.left = left + 'px';
17287 element.style.top = top + 'px';
17288 element.style.width = width;
17289 element.style.height = height;
17290 element.style.rotation = rotation.toFixed(8);
17291 element.style.flip = flip < 0 ? 'x' : '';
17292
17293 // Set transform
17294 var skew = this.skewElement;
17295 skew.matrix = [transform$1.xx.toFixed(4), transform$1.xy.toFixed(4), transform$1.yx.toFixed(4), transform$1.yy.toFixed(4), 0, 0];
17296 skew.origin = transformOriginX + ',' + transformOriginY;
17297
17298 // Set stroke
17299 this.strokeElement.weight = strokeWidth + 'px';
17300 },
17301
17302 /* styles */
17303
17304 _createGradient: function(style, stops){
17305 var fill = this.fillElement;
17306
17307 // Temporarily eject the fill from the DOM
17308 this.element.removeChild(fill);
17309
17310 fill.type = style;
17311 fill.method = 'none';
17312 fill.rotate = true;
17313
17314 var colors = [], color1, color2;
17315
17316 var addColor = function(offset, color$1){
17317 color$1 = color.detach(color$1);
17318 if (color1 == null) color1 = color2 = color$1;
17319 else color2 = color$1;
17320 colors.push(offset + ' ' + color$1[0]);
17321 };
17322
17323 // Enumerate stops, assumes offsets are enumerated in order
17324 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++) addColor(i / l, stops[i]);
17325 else for (var offset in stops) addColor(offset, stops[offset]);
17326
17327 fill.color = color1[0];
17328 fill.color2 = color2[0];
17329
17330 //if (fill.colors) fill.colors.value = colors; else
17331 fill.colors = colors;
17332
17333 // Opacity order gets flipped when color stops are specified
17334 fill.opacity = color2[1];
17335 fill['ao:opacity2'] = color1[1];
17336
17337 fill.on = true;
17338 this.element.appendChild(fill);
17339 return fill;
17340 },
17341
17342 _setColor: function(type, color$1){
17343 var element = type == 'fill' ? this.fillElement : this.strokeElement;
17344 if (color$1 == null){
17345 element.on = false;
17346 } else {
17347 color$1 = color.detach(color$1);
17348 element.color = color$1[0];
17349 element.opacity = color$1[1];
17350 element.on = true;
17351 }
17352 },
17353
17354 fill: function(color){
17355 if (arguments.length > 1){
17356 this.fillLinear(arguments);
17357 } else {
17358 this._boxCoords = defaultBox;
17359 var fill = this.fillElement;
17360 fill.type = 'solid';
17361 fill.color2 = '';
17362 fill['ao:opacity2'] = '';
17363 if (fill.colors) fill.colors.value = '';
17364 this._setColor('fill', color);
17365 }
17366 return this;
17367 },
17368
17369 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
17370 var fill = this._createGradient('gradientradial', stops);
17371 if (focusX == null) focusX = this.left + this.width * 0.5;
17372 if (focusY == null) focusY = this.top + this.height * 0.5;
17373 if (radiusY == null) radiusY = radiusX || (this.height * 0.5);
17374 if (radiusX == null) radiusX = this.width * 0.5;
17375 if (centerX == null) centerX = focusX;
17376 if (centerY == null) centerY = focusY;
17377
17378 centerX += centerX - focusX;
17379 centerY += centerY - focusY;
17380
17381 var box = this._boxCoords = {
17382 left: centerX - radiusX * 2,
17383 top: centerY - radiusY * 2,
17384 width: radiusX * 4,
17385 height: radiusY * 4
17386 };
17387 focusX -= box.left;
17388 focusY -= box.top;
17389 focusX /= box.width;
17390 focusY /= box.height;
17391
17392 fill.focussize = '0 0';
17393 fill.focusposition = focusX + ',' + focusY;
17394 fill.focus = '50%';
17395
17396 this._transform();
17397
17398 return this;
17399 },
17400
17401 fillLinear: function(stops, x1, y1, x2, y2){
17402 var fill = this._createGradient('gradient', stops);
17403 fill.focus = '100%';
17404 if (arguments.length == 5){
17405 var w = Math.abs(x2 - x1), h = Math.abs(y2 - y1);
17406 this._boxCoords = {
17407 left: Math.min(x1, x2),
17408 top: Math.min(y1, y2),
17409 width: w < 1 ? h : w,
17410 height: h < 1 ? w : h
17411 };
17412 fill.angle = (360 + Math.atan2((x2 - x1) / h, (y2 - y1) / w) * 180 / Math.PI) % 360;
17413 } else {
17414 this._boxCoords = null;
17415 fill.angle = (x1 == null) ? 0 : (90 + x1) % 360;
17416 }
17417 this._transform();
17418 return this;
17419 },
17420
17421 fillImage: function(url, width, height, left, top, color1, color2){
17422 var fill = this.fillElement;
17423 if (color1 != null){
17424 color1 = color.detach(color1);
17425 if (color2 != null) color2 = color.detach(color2);
17426 fill.type = 'pattern';
17427 fill.color = color1[0];
17428 fill.color2 = color2 == null ? color1[0] : color2[0];
17429 fill.opacity = color2 == null ? 0 : color2[1];
17430 fill['ao:opacity2'] = color1[1];
17431 } else {
17432 fill.type = 'tile';
17433 fill.color = '';
17434 fill.color2 = '';
17435 fill.opacity = 1;
17436 fill['ao:opacity2'] = 1;
17437 }
17438 if (fill.colors) fill.colors.value = '';
17439 fill.rotate = true;
17440 fill.src = url;
17441
17442 fill.size = '1,1';
17443 fill.position = '0,0';
17444 fill.origin = '0,0';
17445 fill.aspect = 'ignore'; // ignore, atleast, atmost
17446 fill.on = true;
17447
17448 if (!left) left = 0;
17449 if (!top) top = 0;
17450 this._boxCoords = width ? { left: left + 0.5, top: top + 0.5, width: width, height: height } : null;
17451 this._transform();
17452 return this;
17453 },
17454
17455 /* stroke */
17456
17457 stroke: function(color, width, cap, join){
17458 var stroke = this.strokeElement;
17459 this._strokeWidth = (width != null) ? width : 1;
17460 stroke.weight = (width != null) ? width + 'px' : 1;
17461 stroke.endcap = (cap != null) ? ((cap == 'butt') ? 'flat' : cap) : 'round';
17462 stroke.joinstyle = (join != null) ? join : 'round';
17463
17464 this._setColor('stroke', color);
17465 return this;
17466 }
17467
17468 });
17469
17470 var precision$3 = 100;
17471
17472 var shape$1 = _class(base$1, {
17473
17474 base_initialize: base$1.prototype.initialize,
17475
17476 initialize: function(path, width, height){
17477 this.base_initialize('shape');
17478
17479 var p = this.pathElement = dom.createElement('path');
17480 p.gradientshapeok = true;
17481 this.element.appendChild(p);
17482
17483 this.width = width;
17484 this.height = height;
17485
17486 if (path != null) this.draw(path);
17487 },
17488
17489 // SVG to VML
17490
17491 draw: function(path, width, height){
17492
17493 if (!(path instanceof path$2)) path = new path$2(path);
17494 this._vml = path.toVML();
17495 //this._size = path.measure();
17496
17497 if (width != null) this.width = width;
17498 if (height != null) this.height = height;
17499
17500 if (!this._boxCoords) this._transform();
17501 this._redraw(this._prefix, this._suffix);
17502
17503 return this;
17504 },
17505
17506 // radial gradient workaround
17507
17508 _redraw: function(prefix, suffix){
17509 var vml = this._vml || '';
17510
17511 this._prefix = prefix;
17512 this._suffix = suffix;
17513 if (prefix){
17514 vml = [
17515 prefix, vml, suffix,
17516 // Don't stroke the path with the extra ellipse, redraw the stroked path separately
17517 'ns e', vml, 'nf'
17518 ].join(' ');
17519 }
17520
17521 this.element.path = vml + 'e';
17522 },
17523
17524 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
17525 var fill = this._createGradient('gradientradial', stops);
17526 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
17527 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
17528 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
17529 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
17530 if (centerX == null) centerX = focusX;
17531 if (centerY == null) centerY = focusY;
17532
17533 centerX += centerX - focusX;
17534 centerY += centerY - focusY;
17535
17536 var cx = Math.round(centerX * precision$3),
17537 cy = Math.round(centerY * precision$3),
17538
17539 rx = Math.round(radiusX * 2 * precision$3),
17540 ry = Math.round(radiusY * 2 * precision$3),
17541
17542 arc = ['wa', cx - rx, cy - ry, cx + rx, cy + ry].join(' ');
17543
17544 this._redraw(
17545 // Resolve rendering bug
17546 ['m', cx, cy - ry, 'l', cx, cy - ry].join(' '),
17547 // Draw an ellipse around the path to force an elliptical gradient on any shape
17548 [
17549 'm', cx, cy - ry,
17550 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry,
17551 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry
17552 ].join(' ')
17553 );
17554
17555 this._boxCoords = { left: focusX - 2, top: focusY - 2, width: 4, height: 4 };
17556
17557 fill.focusposition = '0.5,0.5';
17558 fill.focussize = '0 0';
17559 fill.focus = '50%';
17560
17561 this._transform();
17562
17563 return this;
17564 }
17565
17566 });
17567
17568 var group$1 = _class(node$1, container, {
17569
17570 element_initialize: node$1.prototype.initialize,
17571
17572 initialize: function(width, height){
17573 this.element_initialize('group');
17574 this.width = width;
17575 this.height = height;
17576 },
17577
17578 _transform: function(){
17579 var element = this.element;
17580 element.coordorigin = '0,0';
17581 element.coordsize = '1000,1000';
17582 element.style.left = 0;
17583 element.style.top = 0;
17584 element.style.width = 1000;
17585 element.style.height = 1000;
17586 element.style.rotation = 0;
17587
17588 var container = this.parentNode;
17589 this._activeTransform = container ? new transform(container._activeTransform).transform(this) : this;
17590 var node = this.firstChild;
17591 while (node){
17592 node._transform();
17593 node = node.nextSibling;
17594 }
17595 }
17596
17597 });
17598
17599 var clippingrectangle$1 = _class(node$1, container, {
17600
17601 element_initialize: node$1.prototype.initialize,
17602
17603 initialize: function(width, height){
17604 this.element_initialize('clippingrectangle');
17605 this.width = width;
17606 this.height = height;
17607 },
17608
17609 _transform: function(){
17610 var element = this.element;
17611 element.clip = true;
17612 element.coordorigin = -this.x + ',' + (-1 * this.y);
17613 element.coordsize = this.width + ',' + this.height;
17614 // IE8 doesn't like clipBottom. Don't ask me why.
17615 // element.style.clipBottom = this.height + this.y;
17616 element.style.clipLeft = this.x;
17617 element.style.clipRight = this.width + this.x;
17618 element.style.clipTop = this.y;
17619 element.style.left = -this.x;
17620 element.style.top = -this.y;
17621 element.style.width = this.width + this.x;
17622 element.style.height = this.height + this.y;
17623 element.style.rotation = 0;
17624
17625 var container = this.parentNode;
17626 this._activeTransform = container ? new transform(container._activeTransform).transform(this) : this;
17627 var node = this.firstChild;
17628 while (node){
17629 node._transform();
17630 node = node.nextSibling;
17631 }
17632 }
17633
17634 });
17635
17636 var fontAnchors$1 = { start: 'left', middle: 'center', end: 'right' };
17637
17638 var text$1 = _class(base$1, {
17639
17640 base_initialize: base$1.prototype.initialize,
17641
17642 initialize: function(text, font, alignment, path){
17643 this.base_initialize('shape');
17644
17645 var p = this.pathElement = dom.createElement('path');
17646 p.textpathok = true;
17647 this.element.appendChild(p);
17648
17649 p = this.textPathElement = dom.createElement("textpath");
17650 p.on = true;
17651 p.style['v-text-align'] = 'left';
17652 this.element.appendChild(p);
17653
17654 this.draw.apply(this, arguments);
17655 },
17656
17657 draw: function(text, font, alignment, path){
17658 var element = this.element,
17659 textPath = this.textPathElement,
17660 style = textPath.style;
17661
17662 textPath.string = text;
17663
17664 if (font){
17665 if (typeof font == 'string'){
17666 style.font = font;
17667 } else {
17668 for (var key in font){
17669 var ckey = key.camelCase ? key.camelCase() : key;
17670 if (ckey == 'fontFamily') style[ckey] = "'" + font[key] + "'";
17671 // NOT UNIVERSALLY SUPPORTED OPTIONS
17672 // else if (ckey == 'kerning') style['v-text-kern'] = !!font[key];
17673 // else if (ckey == 'rotateGlyphs') style['v-rotate-letters'] = !!font[key];
17674 // else if (ckey == 'letterSpacing') style['v-text-spacing'] = Number(font[key]) + '';
17675 else style[ckey] = font[key];
17676 }
17677 }
17678 }
17679
17680 if (alignment) style['v-text-align'] = fontAnchors$1[alignment] || alignment;
17681
17682 if (path){
17683 this.currentPath = path = new path$2(path);
17684 this.element.path = path.toVML();
17685 } else if (!this.currentPath){
17686 var i = -1, offsetRows = '\n';
17687 while ((i = text.indexOf('\n', i + 1)) > -1) offsetRows += '\n';
17688 textPath.string = offsetRows + textPath.string;
17689 this.element.path = 'm0,0l1,0';
17690 }
17691
17692 // Measuring the bounding box is currently necessary for gradients etc.
17693
17694 // Clone element because the element is dead once it has been in the DOM
17695 element = element.cloneNode(true);
17696 style = element.style;
17697
17698 // Reset coordinates while measuring
17699 element.coordorigin = '0,0';
17700 element.coordsize = '10000,10000';
17701 style.left = '0px';
17702 style.top = '0px';
17703 style.width = '10000px';
17704 style.height = '10000px';
17705 style.rotation = 0;
17706 element.removeChild(element.firstChild); // Remove skew
17707
17708 // Inject the clone into the document
17709
17710 var canvas = new surface$1(1, 1),
17711 group = new group$1(), // Wrapping it in a group seems to alleviate some client rect weirdness
17712 body = element.ownerDocument.body;
17713
17714 canvas.inject(body);
17715 group.element.appendChild(element);
17716 group.inject(canvas);
17717
17718 var ebb = element.getBoundingClientRect(),
17719 cbb = canvas.toElement().getBoundingClientRect();
17720
17721 canvas.eject();
17722
17723 this.left = ebb.left - cbb.left;
17724 this.top = ebb.top - cbb.top;
17725 this.width = ebb.right - ebb.left;
17726 this.height = ebb.bottom - ebb.top;
17727 this.right = ebb.right - cbb.left;
17728 this.bottom = ebb.bottom - cbb.top;
17729
17730 this._transform();
17731
17732 //this._size = { left: this.left, top: this.top, width: this.width, height: this.height};
17733 return this;
17734 }
17735
17736 });
17737
17738 var fastNoSideEffects = createCommonjsModule(function (module, exports) {
17739 var hasCanvas = function(){
17740
17741 var canvas = document.createElement('canvas');
17742 return canvas && !!canvas.getContext;
17743
17744 };
17745
17746 if (hasCanvas()) {
17747 exports.Surface = surface;
17748 exports.Path = path$1;
17749 exports.Shape = shape;
17750 exports.Group = group;
17751 exports.ClippingRectangle = clippingrectangle;
17752 exports.Text = text;
17753 } else {
17754 exports.Surface = surface$1;
17755 exports.Path = path$2;
17756 exports.Shape = shape$1;
17757 exports.Group = group$1;
17758 exports.ClippingRectangle = clippingrectangle$1;
17759 exports.Text = text$1;
17760
17761 var DOM = dom;
17762 if (typeof document !== 'undefined') DOM.init(document);
17763 }
17764 });
17765 var fastNoSideEffects_1 = fastNoSideEffects.Surface;
17766 var fastNoSideEffects_2 = fastNoSideEffects.Path;
17767 var fastNoSideEffects_3 = fastNoSideEffects.Shape;
17768 var fastNoSideEffects_4 = fastNoSideEffects.Group;
17769 var fastNoSideEffects_5 = fastNoSideEffects.ClippingRectangle;
17770 var fastNoSideEffects_6 = fastNoSideEffects.Text;
17771
17772 current.setCurrent( // Change to 'art/modes/dom' for easier debugging via SVG
17773 fastNoSideEffects);
17774 /** Declarative fill-type objects; API design not finalized */
17775
17776 var slice = Array.prototype.slice;
17777
17778 var LinearGradient =
17779 /*#__PURE__*/
17780 function () {
17781 function LinearGradient(stops, x1, y1, x2, y2) {
17782 this._args = slice.call(arguments);
17783 }
17784
17785 var _proto = LinearGradient.prototype;
17786
17787 _proto.applyFill = function applyFill(node) {
17788 node.fillLinear.apply(node, this._args);
17789 };
17790
17791 return LinearGradient;
17792 }();
17793
17794 var RadialGradient =
17795 /*#__PURE__*/
17796 function () {
17797 function RadialGradient(stops, fx, fy, rx, ry, cx, cy) {
17798 this._args = slice.call(arguments);
17799 }
17800
17801 var _proto2 = RadialGradient.prototype;
17802
17803 _proto2.applyFill = function applyFill(node) {
17804 node.fillRadial.apply(node, this._args);
17805 };
17806
17807 return RadialGradient;
17808 }();
17809
17810 var Pattern =
17811 /*#__PURE__*/
17812 function () {
17813 function Pattern(url, width, height, left, top) {
17814 this._args = slice.call(arguments);
17815 }
17816
17817 var _proto3 = Pattern.prototype;
17818
17819 _proto3.applyFill = function applyFill(node) {
17820 node.fillImage.apply(node, this._args);
17821 };
17822
17823 return Pattern;
17824 }();
17825 /** React Components */
17826
17827
17828 var Surface =
17829 /*#__PURE__*/
17830 function (_React$Component) {
17831 _inheritsLoose(Surface, _React$Component);
17832
17833 function Surface() {
17834 return _React$Component.apply(this, arguments) || this;
17835 }
17836
17837 var _proto4 = Surface.prototype;
17838
17839 _proto4.componentDidMount = function componentDidMount() {
17840 var _this$props = this.props,
17841 height = _this$props.height,
17842 width = _this$props.width;
17843 this._surface = current.Surface(+width, +height, this._tagRef);
17844 this._mountNode = createContainer(this._surface, LegacyRoot, false);
17845 updateContainer(this.props.children, this._mountNode, this);
17846 };
17847
17848 _proto4.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
17849 var props = this.props;
17850
17851 if (props.height !== prevProps.height || props.width !== prevProps.width) {
17852 this._surface.resize(+props.width, +props.height);
17853 }
17854
17855 updateContainer(this.props.children, this._mountNode, this);
17856
17857 if (this._surface.render) {
17858 this._surface.render();
17859 }
17860 };
17861
17862 _proto4.componentWillUnmount = function componentWillUnmount() {
17863 updateContainer(null, this._mountNode, this);
17864 };
17865
17866 _proto4.render = function render() {
17867 var _this = this;
17868
17869 // This is going to be a placeholder because we don't know what it will
17870 // actually resolve to because ART may render canvas, vml or svg tags here.
17871 // We only allow a subset of properties since others might conflict with
17872 // ART's properties.
17873 var props = this.props; // TODO: ART's Canvas Mode overrides surface title and cursor
17874
17875 var Tag = current.Surface.tagName;
17876 return React.createElement(Tag, {
17877 ref: function (ref) {
17878 return _this._tagRef = ref;
17879 },
17880 accessKey: props.accessKey,
17881 className: props.className,
17882 draggable: props.draggable,
17883 role: props.role,
17884 style: props.style,
17885 tabIndex: props.tabIndex,
17886 title: props.title
17887 });
17888 };
17889
17890 return Surface;
17891 }(React.Component);
17892
17893 var Text =
17894 /*#__PURE__*/
17895 function (_React$Component2) {
17896 _inheritsLoose(Text, _React$Component2);
17897
17898 function Text(props) {
17899 var _this2;
17900
17901 _this2 = _React$Component2.call(this, props) || this; // We allow reading these props. Ideally we could expose the Text node as
17902 // ref directly.
17903
17904 ['height', 'width', 'x', 'y'].forEach(function (key) {
17905 Object.defineProperty(_assertThisInitialized(_this2), key, {
17906 get: function () {
17907 return this._text ? this._text[key] : undefined;
17908 }
17909 });
17910 });
17911 return _this2;
17912 }
17913
17914 var _proto5 = Text.prototype;
17915
17916 _proto5.render = function render() {
17917 var _this3 = this;
17918
17919 // This means you can't have children that render into strings...
17920 var T = TYPES.TEXT;
17921 return React.createElement(T, _extends({}, this.props, {
17922 ref: function (t) {
17923 return _this3._text = t;
17924 }
17925 }), childrenAsString(this.props.children));
17926 };
17927
17928 return Text;
17929 }(React.Component);
17930
17931 injectIntoDevTools({
17932 findFiberByHostInstance: function () {
17933 return null;
17934 },
17935 bundleType: 1 ,
17936 version: ReactVersion,
17937 rendererPackageName: 'react-art'
17938 });
17939 /** API */
17940
17941 var ClippingRectangle = TYPES.CLIPPING_RECTANGLE;
17942 var Group = TYPES.GROUP;
17943 var Shape = TYPES.SHAPE;
17944 var Path = current.Path;
17945
17946 var ReactART = /*#__PURE__*/Object.freeze({
17947 __proto__: null,
17948 ClippingRectangle: ClippingRectangle,
17949 Group: Group,
17950 Shape: Shape,
17951 Path: Path,
17952 LinearGradient: LinearGradient,
17953 Pattern: Pattern,
17954 RadialGradient: RadialGradient,
17955 Surface: Surface,
17956 Text: Text,
17957 Transform: transform
17958 });
17959
17960 var reactArt = ReactART;
17961
17962 return reactArt;
17963
17964})));