UNPKG

662 kBJavaScriptView Raw
1/** @license React v16.9.0-rc.0
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.ReactART = factory(global.React));
16}(this, (function (React) { 'use strict';
17
18var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
19
20var _assign = ReactInternals.assign;
21
22// TODO: this is special because it gets imported during build.
23
24var ReactVersion = '16.9.0-rc.0';
25
26var LegacyRoot = 0;
27var BatchedRoot = 1;
28var ConcurrentRoot = 2;
29
30// Do not require this module directly! Use normal `invariant` calls with
31// template literal strings. The messages will be converted to ReactError during
32// build, and in production they will be minified.
33
34// Do not require this module directly! Use normal `invariant` calls with
35// template literal strings. The messages will be converted to ReactError during
36// build, and in production they will be minified.
37
38function ReactError(error) {
39 error.name = 'Invariant Violation';
40 return error;
41}
42
43var FunctionComponent = 0;
44var ClassComponent = 1;
45var IndeterminateComponent = 2; // Before we know whether it is function or class
46var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
47var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
48var HostComponent = 5;
49var HostText = 6;
50var Fragment = 7;
51var Mode = 8;
52var ContextConsumer = 9;
53var ContextProvider = 10;
54var ForwardRef = 11;
55var Profiler = 12;
56var SuspenseComponent = 13;
57var MemoComponent = 14;
58var SimpleMemoComponent = 15;
59var LazyComponent = 16;
60var IncompleteClassComponent = 17;
61var DehydratedSuspenseComponent = 18;
62var SuspenseListComponent = 19;
63var FundamentalComponent = 20;
64
65/**
66 * Use invariant() to assert state which your program assumes to be true.
67 *
68 * Provide sprintf-style format (only %s is supported) and arguments
69 * to provide information about what broke and what you were
70 * expecting.
71 *
72 * The invariant message will be stripped in production, but the invariant
73 * will remain to ensure logic does not differ in production.
74 */
75
76/**
77 * Similar to invariant but only logs a warning if the condition is not met.
78 * This can be used to log issues in development environments in critical
79 * paths. Removing the logging code for production environments will keep the
80 * same logic and follow the same code paths.
81 */
82
83var warningWithoutStack = function () {};
84
85{
86 warningWithoutStack = function (condition, format) {
87 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
88 args[_key - 2] = arguments[_key];
89 }
90
91 if (format === undefined) {
92 throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
93 }
94 if (args.length > 8) {
95 // Check before the condition to catch violations early.
96 throw new Error('warningWithoutStack() currently supports at most 8 arguments.');
97 }
98 if (condition) {
99 return;
100 }
101 if (typeof console !== 'undefined') {
102 var argsWithFormat = args.map(function (item) {
103 return '' + item;
104 });
105 argsWithFormat.unshift('Warning: ' + format);
106
107 // We intentionally don't use spread (or .apply) directly because it
108 // breaks IE9: https://github.com/facebook/react/issues/13610
109 Function.prototype.apply.call(console.error, console, argsWithFormat);
110 }
111 try {
112 // --- Welcome to debugging React ---
113 // This error was thrown as a convenience so that you can use this stack
114 // to find the callsite that caused this warning to fire.
115 var argIndex = 0;
116 var message = 'Warning: ' + format.replace(/%s/g, function () {
117 return args[argIndex++];
118 });
119 throw new Error(message);
120 } catch (x) {}
121 };
122}
123
124var warningWithoutStack$1 = warningWithoutStack;
125
126/**
127 * `ReactInstanceMap` maintains a mapping from a public facing stateful
128 * instance (key) and the internal representation (value). This allows public
129 * methods to accept the user facing instance as an argument and map them back
130 * to internal methods.
131 *
132 * Note that this module is currently shared and assumed to be stateless.
133 * If this becomes an actual Map, that will break.
134 */
135
136/**
137 * This API should be called `delete` but we'd have to make sure to always
138 * transform these to strings for IE support. When this transform is fully
139 * supported we can rename it.
140 */
141
142
143function get(key) {
144 return key._reactInternalFiber;
145}
146
147
148
149function set(key, value) {
150 key._reactInternalFiber = value;
151}
152
153var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
154
155// Prevent newer renderers from RTE when used with older react package versions.
156// Current owner and dispatcher used to share the same ref,
157// but PR #14548 split them out to better support the react-debug-tools package.
158if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
159 ReactSharedInternals.ReactCurrentDispatcher = {
160 current: null
161 };
162}
163if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {
164 ReactSharedInternals.ReactCurrentBatchConfig = {
165 suspense: null
166 };
167}
168
169// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
170// nor polyfill, then a plain number is used for performance.
171var hasSymbol = typeof Symbol === 'function' && Symbol.for;
172
173var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
174var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
175var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
176var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
177var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
178var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
179var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace;
180// TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
181// (unstable) APIs that have been removed. Can we remove the symbols?
182
183var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
184var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
185var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
186var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
187var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
188var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
189var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for('react.fundamental') : 0xead5;
190var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for('react.responder') : 0xead6;
191
192var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
193var FAUX_ITERATOR_SYMBOL = '@@iterator';
194
195function getIteratorFn(maybeIterable) {
196 if (maybeIterable === null || typeof maybeIterable !== 'object') {
197 return null;
198 }
199 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
200 if (typeof maybeIterator === 'function') {
201 return maybeIterator;
202 }
203 return null;
204}
205
206var Pending = 0;
207var Resolved = 1;
208var Rejected = 2;
209
210function refineResolvedLazyComponent(lazyComponent) {
211 return lazyComponent._status === Resolved ? lazyComponent._result : null;
212}
213
214function getWrappedName(outerType, innerType, wrapperName) {
215 var functionName = innerType.displayName || innerType.name || '';
216 return outerType.displayName || (functionName !== '' ? wrapperName + '(' + functionName + ')' : wrapperName);
217}
218
219function getComponentName(type) {
220 if (type == null) {
221 // Host root, text node or just invalid type.
222 return null;
223 }
224 {
225 if (typeof type.tag === 'number') {
226 warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
227 }
228 }
229 if (typeof type === 'function') {
230 return type.displayName || type.name || null;
231 }
232 if (typeof type === 'string') {
233 return type;
234 }
235 switch (type) {
236 case REACT_FRAGMENT_TYPE:
237 return 'Fragment';
238 case REACT_PORTAL_TYPE:
239 return 'Portal';
240 case REACT_PROFILER_TYPE:
241 return 'Profiler';
242 case REACT_STRICT_MODE_TYPE:
243 return 'StrictMode';
244 case REACT_SUSPENSE_TYPE:
245 return 'Suspense';
246 case REACT_SUSPENSE_LIST_TYPE:
247 return 'SuspenseList';
248 }
249 if (typeof type === 'object') {
250 switch (type.$$typeof) {
251 case REACT_CONTEXT_TYPE:
252 return 'Context.Consumer';
253 case REACT_PROVIDER_TYPE:
254 return 'Context.Provider';
255 case REACT_FORWARD_REF_TYPE:
256 return getWrappedName(type, type.render, 'ForwardRef');
257 case REACT_MEMO_TYPE:
258 return getComponentName(type.type);
259 case REACT_LAZY_TYPE:
260 {
261 var thenable = type;
262 var resolvedThenable = refineResolvedLazyComponent(thenable);
263 if (resolvedThenable) {
264 return getComponentName(resolvedThenable);
265 }
266 break;
267 }
268 }
269 }
270 return null;
271}
272
273// Don't change these two values. They're used by React Dev Tools.
274var NoEffect = /* */0;
275var PerformedWork = /* */1;
276
277// You can change the rest (and add more).
278var Placement = /* */2;
279var Update = /* */4;
280var PlacementAndUpdate = /* */6;
281var Deletion = /* */8;
282var ContentReset = /* */16;
283var Callback = /* */32;
284var DidCapture = /* */64;
285var Ref = /* */128;
286var Snapshot = /* */256;
287var Passive = /* */512;
288
289// Passive & Update & Callback & Ref & Snapshot
290var LifecycleEffectMask = /* */932;
291
292// Union of all host effects
293var HostEffectMask = /* */1023;
294
295var Incomplete = /* */1024;
296var ShouldCapture = /* */2048;
297
298var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
299
300var MOUNTING = 1;
301var MOUNTED = 2;
302var UNMOUNTED = 3;
303
304function isFiberMountedImpl(fiber) {
305 var node = fiber;
306 if (!fiber.alternate) {
307 // If there is no alternate, this might be a new tree that isn't inserted
308 // yet. If it is, then it will have a pending insertion effect on it.
309 if ((node.effectTag & Placement) !== NoEffect) {
310 return MOUNTING;
311 }
312 while (node.return) {
313 node = node.return;
314 if ((node.effectTag & Placement) !== NoEffect) {
315 return MOUNTING;
316 }
317 }
318 } else {
319 while (node.return) {
320 node = node.return;
321 }
322 }
323 if (node.tag === HostRoot) {
324 // TODO: Check if this was a nested HostRoot when used with
325 // renderContainerIntoSubtree.
326 return MOUNTED;
327 }
328 // If we didn't hit the root, that means that we're in an disconnected tree
329 // that has been unmounted.
330 return UNMOUNTED;
331}
332
333function isFiberMounted(fiber) {
334 return isFiberMountedImpl(fiber) === MOUNTED;
335}
336
337function isMounted(component) {
338 {
339 var owner = ReactCurrentOwner.current;
340 if (owner !== null && owner.tag === ClassComponent) {
341 var ownerFiber = owner;
342 var instance = ownerFiber.stateNode;
343 !instance._warnedAboutRefsInRender ? warningWithoutStack$1(false, '%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentName(ownerFiber.type) || 'A component') : void 0;
344 instance._warnedAboutRefsInRender = true;
345 }
346 }
347
348 var fiber = get(component);
349 if (!fiber) {
350 return false;
351 }
352 return isFiberMountedImpl(fiber) === MOUNTED;
353}
354
355function assertIsMounted(fiber) {
356 (function () {
357 if (!(isFiberMountedImpl(fiber) === MOUNTED)) {
358 {
359 throw ReactError(Error('Unable to find node on an unmounted component.'));
360 }
361 }
362 })();
363}
364
365function findCurrentFiberUsingSlowPath(fiber) {
366 var alternate = fiber.alternate;
367 if (!alternate) {
368 // If there is no alternate, then we only need to check if it is mounted.
369 var state = isFiberMountedImpl(fiber);
370 (function () {
371 if (!(state !== UNMOUNTED)) {
372 {
373 throw ReactError(Error('Unable to find node on an unmounted component.'));
374 }
375 }
376 })();
377 if (state === MOUNTING) {
378 return null;
379 }
380 return fiber;
381 }
382 // If we have two possible branches, we'll walk backwards up to the root
383 // to see what path the root points to. On the way we may hit one of the
384 // special cases and we'll deal with them.
385 var a = fiber;
386 var b = alternate;
387 while (true) {
388 var parentA = a.return;
389 if (parentA === null) {
390 // We're at the root.
391 break;
392 }
393 var parentB = parentA.alternate;
394 if (parentB === null) {
395 // There is no alternate. This is an unusual case. Currently, it only
396 // happens when a Suspense component is hidden. An extra fragment fiber
397 // is inserted in between the Suspense fiber and its children. Skip
398 // over this extra fragment fiber and proceed to the next parent.
399 var nextParent = parentA.return;
400 if (nextParent !== null) {
401 a = b = nextParent;
402 continue;
403 }
404 // If there's no parent, we're at the root.
405 break;
406 }
407
408 // If both copies of the parent fiber point to the same child, we can
409 // assume that the child is current. This happens when we bailout on low
410 // priority: the bailed out fiber's child reuses the current child.
411 if (parentA.child === parentB.child) {
412 var child = parentA.child;
413 while (child) {
414 if (child === a) {
415 // We've determined that A is the current branch.
416 assertIsMounted(parentA);
417 return fiber;
418 }
419 if (child === b) {
420 // We've determined that B is the current branch.
421 assertIsMounted(parentA);
422 return alternate;
423 }
424 child = child.sibling;
425 }
426 // We should never have an alternate for any mounting node. So the only
427 // way this could possibly happen is if this was unmounted, if at all.
428 (function () {
429 {
430 {
431 throw ReactError(Error('Unable to find node on an unmounted component.'));
432 }
433 }
434 })();
435 }
436
437 if (a.return !== b.return) {
438 // The return pointer of A and the return pointer of B point to different
439 // fibers. We assume that return pointers never criss-cross, so A must
440 // belong to the child set of A.return, and B must belong to the child
441 // set of B.return.
442 a = parentA;
443 b = parentB;
444 } else {
445 // The return pointers point to the same fiber. We'll have to use the
446 // default, slow path: scan the child sets of each parent alternate to see
447 // which child belongs to which set.
448 //
449 // Search parent A's child set
450 var didFindChild = false;
451 var _child = parentA.child;
452 while (_child) {
453 if (_child === a) {
454 didFindChild = true;
455 a = parentA;
456 b = parentB;
457 break;
458 }
459 if (_child === b) {
460 didFindChild = true;
461 b = parentA;
462 a = parentB;
463 break;
464 }
465 _child = _child.sibling;
466 }
467 if (!didFindChild) {
468 // Search parent B's child set
469 _child = parentB.child;
470 while (_child) {
471 if (_child === a) {
472 didFindChild = true;
473 a = parentB;
474 b = parentA;
475 break;
476 }
477 if (_child === b) {
478 didFindChild = true;
479 b = parentB;
480 a = parentA;
481 break;
482 }
483 _child = _child.sibling;
484 }
485 (function () {
486 if (!didFindChild) {
487 {
488 throw ReactError(Error('Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.'));
489 }
490 }
491 })();
492 }
493 }
494
495 (function () {
496 if (!(a.alternate === b)) {
497 {
498 throw ReactError(Error('Return fibers should always be each others\' alternates. This error is likely caused by a bug in React. Please file an issue.'));
499 }
500 }
501 })();
502 }
503 // If the root is not a host container, we're in a disconnected tree. I.e.
504 // unmounted.
505 (function () {
506 if (!(a.tag === HostRoot)) {
507 {
508 throw ReactError(Error('Unable to find node on an unmounted component.'));
509 }
510 }
511 })();
512 if (a.stateNode.current === a) {
513 // We've determined that A is the current branch.
514 return fiber;
515 }
516 // Otherwise B has to be current branch.
517 return alternate;
518}
519
520function findCurrentHostFiber(parent) {
521 var currentParent = findCurrentFiberUsingSlowPath(parent);
522 if (!currentParent) {
523 return null;
524 }
525
526 // Next we'll drill down this component to find the first HostComponent/Text.
527 var node = currentParent;
528 while (true) {
529 if (node.tag === HostComponent || node.tag === HostText) {
530 return node;
531 } else if (node.child) {
532 node.child.return = node;
533 node = node.child;
534 continue;
535 }
536 if (node === currentParent) {
537 return null;
538 }
539 while (!node.sibling) {
540 if (!node.return || node.return === currentParent) {
541 return null;
542 }
543 node = node.return;
544 }
545 node.sibling.return = node.return;
546 node = node.sibling;
547 }
548 // Flow needs the return null here, but ESLint complains about it.
549 // eslint-disable-next-line no-unreachable
550 return null;
551}
552
553var _class = function(mixins){
554 var proto = {};
555 for (var i = 0, l = arguments.length; i < l; i++){
556 var mixin = arguments[i];
557 if (typeof mixin == 'function') mixin = mixin.prototype;
558 for (var key in mixin) proto[key] = mixin[key];
559 }
560 if (!proto.initialize) proto.initialize = function(){};
561 proto.constructor = function(a,b,c,d,e,f,g,h){
562 return new proto.initialize(a,b,c,d,e,f,g,h);
563 };
564 proto.constructor.prototype = proto.initialize.prototype = proto;
565 return proto.constructor;
566};
567
568function Transform(xx, yx, xy, yy, x, y){
569 if (xx && typeof xx == 'object'){
570 yx = xx.yx; yy = xx.yy; y = xx.y;
571 xy = xx.xy; x = xx.x; xx = xx.xx;
572 }
573 this.xx = xx == null ? 1 : xx;
574 this.yx = yx || 0;
575 this.xy = xy || 0;
576 this.yy = yy == null ? 1 : yy;
577 this.x = (x == null ? this.x : x) || 0;
578 this.y = (y == null ? this.y : y) || 0;
579 this._transform();
580 return this;
581}
582
583var transform = _class({
584
585 initialize: Transform,
586
587 _transform: function(){},
588
589 xx: 1, yx: 0, x: 0,
590 xy: 0, yy: 1, y: 0,
591
592 transform: function(xx, yx, xy, yy, x, y){
593 var m = this;
594 if (xx && typeof xx == 'object'){
595 yx = xx.yx; yy = xx.yy; y = xx.y;
596 xy = xx.xy; x = xx.x; xx = xx.xx;
597 }
598 if (!x) x = 0;
599 if (!y) y = 0;
600 return this.transformTo(
601 m.xx * xx + m.xy * yx,
602 m.yx * xx + m.yy * yx,
603 m.xx * xy + m.xy * yy,
604 m.yx * xy + m.yy * yy,
605 m.xx * x + m.xy * y + m.x,
606 m.yx * x + m.yy * y + m.y
607 );
608 },
609
610 transformTo: Transform,
611
612 translate: function(x, y){
613 return this.transform(1, 0, 0, 1, x, y);
614 },
615
616 move: function(x, y){
617 this.x += x || 0;
618 this.y += y || 0;
619 this._transform();
620 return this;
621 },
622
623 scale: function(x, y){
624 if (y == null) y = x;
625 return this.transform(x, 0, 0, y, 0, 0);
626 },
627
628 rotate: function(deg, x, y){
629 if (x == null || y == null){
630 x = (this.left || 0) + (this.width || 0) / 2;
631 y = (this.top || 0) + (this.height || 0) / 2;
632 }
633
634 var rad = deg * Math.PI / 180, sin = Math.sin(rad), cos = Math.cos(rad);
635
636 this.transform(1, 0, 0, 1, x, y);
637 var m = this;
638
639 return this.transformTo(
640 cos * m.xx - sin * m.yx,
641 sin * m.xx + cos * m.yx,
642 cos * m.xy - sin * m.yy,
643 sin * m.xy + cos * m.yy,
644 m.x,
645 m.y
646 ).transform(1, 0, 0, 1, -x, -y);
647 },
648
649 moveTo: function(x, y){
650 var m = this;
651 return this.transformTo(m.xx, m.yx, m.xy, m.yy, x, y);
652 },
653
654 rotateTo: function(deg, x, y){
655 var m = this;
656 var flip = m.yx / m.xx > m.yy / m.xy ? -1 : 1;
657 if (m.xx < 0 ? m.xy >= 0 : m.xy < 0) flip = -flip;
658 return this.rotate(deg - Math.atan2(flip * m.yx, flip * m.xx) * 180 / Math.PI, x, y);
659 },
660
661 scaleTo: function(x, y){
662 // Normalize
663 var m = this;
664
665 var h = Math.sqrt(m.xx * m.xx + m.yx * m.yx);
666 m.xx /= h; m.yx /= h;
667
668 h = Math.sqrt(m.yy * m.yy + m.xy * m.xy);
669 m.yy /= h; m.xy /= h;
670
671 return this.scale(x, y);
672 },
673
674 resizeTo: function(width, height){
675 var w = this.width, h = this.height;
676 if (!w || !h) return this;
677 return this.scaleTo(width / w, height / h);
678 },
679
680 /*
681 inverse: function(){
682 var a = this.xx, b = this.yx,
683 c = this.xy, d = this.yy,
684 e = this.x, f = this.y;
685 if (a * d - b * c == 0) return null;
686 return new Transform(
687 d/(a * d-b * c), b/(b * c-a * d),
688 c/(b * c-a * d), a/(a * d-b * c),
689 (d * e-c * f)/(b * c-a * d), (b * e-a * f)/(a * d-b * c)
690 );
691 },
692 */
693
694 inversePoint: function(x, y){
695 var a = this.xx, b = this.yx,
696 c = this.xy, d = this.yy,
697 e = this.x, f = this.y;
698 var det = b * c - a * d;
699 if (det == 0) return null;
700 return {
701 x: (d * (e - x) + c * (y - f)) / det,
702 y: (a * (f - y) + b * (x - e)) / det
703 };
704 },
705
706 point: function(x, y){
707 var m = this;
708 return {
709 x: m.xx * x + m.xy * y + m.x,
710 y: m.yx * x + m.yy * y + m.y
711 };
712 }
713
714});
715
716var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
717
718
719
720
721
722function createCommonjsModule(fn, module) {
723 return module = { exports: {} }, fn(module, module.exports), module.exports;
724}
725
726var current = createCommonjsModule(function (module, exports) {
727function warning(){
728 throw new Error('You must require a mode before requiring anything else.');
729}
730
731exports.Surface = warning;
732exports.Path = warning;
733exports.Shape = warning;
734exports.Group = warning;
735exports.ClippingRectangle = warning;
736exports.Text = warning;
737
738exports.setCurrent = function(mode){
739 for (var key in mode){
740 exports[key] = mode[key];
741 }
742};
743});
744
745var current_1 = current.Surface;
746var current_2 = current.Path;
747var current_3 = current.Shape;
748var current_4 = current.Group;
749var current_5 = current.ClippingRectangle;
750var current_6 = current.Text;
751var current_7 = current.setCurrent;
752
753var TYPES = {
754 CLIPPING_RECTANGLE: 'ClippingRectangle',
755 GROUP: 'Group',
756 SHAPE: 'Shape',
757 TEXT: 'Text'
758};
759
760var EVENT_TYPES = {
761 onClick: 'click',
762 onMouseMove: 'mousemove',
763 onMouseOver: 'mouseover',
764 onMouseOut: 'mouseout',
765 onMouseUp: 'mouseup',
766 onMouseDown: 'mousedown'
767};
768
769function childrenAsString(children) {
770 if (!children) {
771 return '';
772 } else if (typeof children === 'string') {
773 return children;
774 } else if (children.length) {
775 return children.join('');
776 } else {
777 return '';
778 }
779}
780
781// Renderers that don't support persistence
782// can re-export everything from this module.
783
784function shim() {
785 (function () {
786 {
787 {
788 throw ReactError(Error('The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue.'));
789 }
790 }
791 })();
792}
793
794// Persistence (when unsupported)
795var supportsPersistence = false;
796var cloneInstance = shim;
797var cloneFundamentalInstance = shim;
798var createContainerChildSet = shim;
799var appendChildToContainerChildSet = shim;
800var finalizeContainerChildren = shim;
801var replaceContainerChildren = shim;
802var cloneHiddenInstance = shim;
803var cloneHiddenTextInstance = shim;
804
805// Renderers that don't support hydration
806// can re-export everything from this module.
807
808function shim$1() {
809 (function () {
810 {
811 {
812 throw ReactError(Error('The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue.'));
813 }
814 }
815 })();
816}
817
818// Hydration (when unsupported)
819
820var supportsHydration = false;
821var canHydrateInstance = shim$1;
822var canHydrateTextInstance = shim$1;
823var canHydrateSuspenseInstance = shim$1;
824var isSuspenseInstancePending = shim$1;
825var isSuspenseInstanceFallback = shim$1;
826var registerSuspenseInstanceRetry = shim$1;
827var getNextHydratableSibling = shim$1;
828var getFirstHydratableChild = shim$1;
829var hydrateInstance = shim$1;
830var hydrateTextInstance = shim$1;
831var getNextHydratableInstanceAfterSuspenseInstance = shim$1;
832var clearSuspenseBoundary = shim$1;
833var clearSuspenseBoundaryFromContainer = shim$1;
834var didNotMatchHydratedContainerTextInstance = shim$1;
835var didNotMatchHydratedTextInstance = shim$1;
836var didNotHydrateContainerInstance = shim$1;
837var didNotHydrateInstance = shim$1;
838var didNotFindHydratableContainerInstance = shim$1;
839var didNotFindHydratableContainerTextInstance = shim$1;
840var didNotFindHydratableContainerSuspenseInstance = shim$1;
841var didNotFindHydratableInstance = shim$1;
842var didNotFindHydratableTextInstance = shim$1;
843var didNotFindHydratableSuspenseInstance = shim$1;
844
845var pooledTransform = new transform();
846
847var NO_CONTEXT = {};
848var UPDATE_SIGNAL = {};
849{
850 Object.freeze(NO_CONTEXT);
851 Object.freeze(UPDATE_SIGNAL);
852}
853
854/** Helper Methods */
855
856function addEventListeners(instance, type, listener) {
857 // We need to explicitly unregister before unmount.
858 // For this reason we need to track subscriptions.
859 if (!instance._listeners) {
860 instance._listeners = {};
861 instance._subscriptions = {};
862 }
863
864 instance._listeners[type] = listener;
865
866 if (listener) {
867 if (!instance._subscriptions[type]) {
868 instance._subscriptions[type] = instance.subscribe(type, createEventHandler(instance), instance);
869 }
870 } else {
871 if (instance._subscriptions[type]) {
872 instance._subscriptions[type]();
873 delete instance._subscriptions[type];
874 }
875 }
876}
877
878function createEventHandler(instance) {
879 return function handleEvent(event) {
880 var listener = instance._listeners[event.type];
881
882 if (!listener) {
883 // Noop
884 } else if (typeof listener === 'function') {
885 listener.call(instance, event);
886 } else if (listener.handleEvent) {
887 listener.handleEvent(event);
888 }
889 };
890}
891
892function destroyEventListeners(instance) {
893 if (instance._subscriptions) {
894 for (var type in instance._subscriptions) {
895 instance._subscriptions[type]();
896 }
897 }
898
899 instance._subscriptions = null;
900 instance._listeners = null;
901}
902
903function getScaleX(props) {
904 if (props.scaleX != null) {
905 return props.scaleX;
906 } else if (props.scale != null) {
907 return props.scale;
908 } else {
909 return 1;
910 }
911}
912
913function getScaleY(props) {
914 if (props.scaleY != null) {
915 return props.scaleY;
916 } else if (props.scale != null) {
917 return props.scale;
918 } else {
919 return 1;
920 }
921}
922
923function isSameFont(oldFont, newFont) {
924 if (oldFont === newFont) {
925 return true;
926 } else if (typeof newFont === 'string' || typeof oldFont === 'string') {
927 return false;
928 } else {
929 return newFont.fontSize === oldFont.fontSize && newFont.fontStyle === oldFont.fontStyle && newFont.fontVariant === oldFont.fontVariant && newFont.fontWeight === oldFont.fontWeight && newFont.fontFamily === oldFont.fontFamily;
930 }
931}
932
933/** Render Methods */
934
935function applyClippingRectangleProps(instance, props) {
936 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
937
938 applyNodeProps(instance, props, prevProps);
939
940 instance.width = props.width;
941 instance.height = props.height;
942}
943
944function applyGroupProps(instance, props) {
945 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
946
947 applyNodeProps(instance, props, prevProps);
948
949 instance.width = props.width;
950 instance.height = props.height;
951}
952
953function applyNodeProps(instance, props) {
954 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
955
956 var scaleX = getScaleX(props);
957 var scaleY = getScaleY(props);
958
959 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);
960
961 if (props.transform != null) {
962 pooledTransform.transform(props.transform);
963 }
964
965 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) {
966 instance.transformTo(pooledTransform);
967 }
968
969 if (props.cursor !== prevProps.cursor || props.title !== prevProps.title) {
970 instance.indicate(props.cursor, props.title);
971 }
972
973 if (instance.blend && props.opacity !== prevProps.opacity) {
974 instance.blend(props.opacity == null ? 1 : props.opacity);
975 }
976
977 if (props.visible !== prevProps.visible) {
978 if (props.visible == null || props.visible) {
979 instance.show();
980 } else {
981 instance.hide();
982 }
983 }
984
985 for (var type in EVENT_TYPES) {
986 addEventListeners(instance, EVENT_TYPES[type], props[type]);
987 }
988}
989
990function applyRenderableNodeProps(instance, props) {
991 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
992
993 applyNodeProps(instance, props, prevProps);
994
995 if (prevProps.fill !== props.fill) {
996 if (props.fill && props.fill.applyFill) {
997 props.fill.applyFill(instance);
998 } else {
999 instance.fill(props.fill);
1000 }
1001 }
1002 if (prevProps.stroke !== props.stroke || prevProps.strokeWidth !== props.strokeWidth || prevProps.strokeCap !== props.strokeCap || prevProps.strokeJoin !== props.strokeJoin ||
1003 // TODO: Consider deep check of stokeDash; may benefit VML in IE.
1004 prevProps.strokeDash !== props.strokeDash) {
1005 instance.stroke(props.stroke, props.strokeWidth, props.strokeCap, props.strokeJoin, props.strokeDash);
1006 }
1007}
1008
1009function applyShapeProps(instance, props) {
1010 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1011
1012 applyRenderableNodeProps(instance, props, prevProps);
1013
1014 var path = props.d || childrenAsString(props.children);
1015
1016 var prevDelta = instance._prevDelta;
1017 var prevPath = instance._prevPath;
1018
1019 if (path !== prevPath || path.delta !== prevDelta || prevProps.height !== props.height || prevProps.width !== props.width) {
1020 instance.draw(path, props.width, props.height);
1021
1022 instance._prevDelta = path.delta;
1023 instance._prevPath = path;
1024 }
1025}
1026
1027function applyTextProps(instance, props) {
1028 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1029
1030 applyRenderableNodeProps(instance, props, prevProps);
1031
1032 var string = props.children;
1033
1034 if (instance._currentString !== string || !isSameFont(props.font, prevProps.font) || props.alignment !== prevProps.alignment || props.path !== prevProps.path) {
1035 instance.draw(string, props.font, props.alignment, props.path);
1036
1037 instance._currentString = string;
1038 }
1039}
1040
1041function appendInitialChild(parentInstance, child) {
1042 if (typeof child === 'string') {
1043 // Noop for string children of Text (eg <Text>{'foo'}{'bar'}</Text>)
1044 (function () {
1045 {
1046 {
1047 throw ReactError(Error('Text children should already be flattened.'));
1048 }
1049 }
1050 })();
1051 return;
1052 }
1053
1054 child.inject(parentInstance);
1055}
1056
1057function createInstance(type, props, internalInstanceHandle) {
1058 var instance = void 0;
1059
1060 switch (type) {
1061 case TYPES.CLIPPING_RECTANGLE:
1062 instance = current.ClippingRectangle();
1063 instance._applyProps = applyClippingRectangleProps;
1064 break;
1065 case TYPES.GROUP:
1066 instance = current.Group();
1067 instance._applyProps = applyGroupProps;
1068 break;
1069 case TYPES.SHAPE:
1070 instance = current.Shape();
1071 instance._applyProps = applyShapeProps;
1072 break;
1073 case TYPES.TEXT:
1074 instance = current.Text(props.children, props.font, props.alignment, props.path);
1075 instance._applyProps = applyTextProps;
1076 break;
1077 }
1078
1079 (function () {
1080 if (!instance) {
1081 {
1082 throw ReactError(Error('ReactART does not support the type "' + type + '"'));
1083 }
1084 }
1085 })();
1086
1087 instance._applyProps(instance, props);
1088
1089 return instance;
1090}
1091
1092function createTextInstance(text, rootContainerInstance, internalInstanceHandle) {
1093 return text;
1094}
1095
1096function finalizeInitialChildren(domElement, type, props) {
1097 return false;
1098}
1099
1100function getPublicInstance(instance) {
1101 return instance;
1102}
1103
1104function prepareForCommit() {
1105 // Noop
1106}
1107
1108function prepareUpdate(domElement, type, oldProps, newProps) {
1109 return UPDATE_SIGNAL;
1110}
1111
1112function resetAfterCommit() {
1113 // Noop
1114}
1115
1116function resetTextContent(domElement) {
1117 // Noop
1118}
1119
1120function shouldDeprioritizeSubtree(type, props) {
1121 return false;
1122}
1123
1124function getRootHostContext() {
1125 return NO_CONTEXT;
1126}
1127
1128function getChildHostContext() {
1129 return NO_CONTEXT;
1130}
1131
1132var scheduleTimeout = setTimeout;
1133var cancelTimeout = clearTimeout;
1134var noTimeout = -1;
1135
1136function shouldSetTextContent(type, props) {
1137 return typeof props.children === 'string' || typeof props.children === 'number';
1138}
1139
1140// The ART renderer is secondary to the React DOM renderer.
1141var isPrimaryRenderer = false;
1142
1143// The ART renderer shouldn't trigger missing act() warnings
1144var warnsIfNotActing = false;
1145
1146var supportsMutation = true;
1147
1148function appendChild(parentInstance, child) {
1149 if (child.parentNode === parentInstance) {
1150 child.eject();
1151 }
1152 child.inject(parentInstance);
1153}
1154
1155function appendChildToContainer(parentInstance, child) {
1156 if (child.parentNode === parentInstance) {
1157 child.eject();
1158 }
1159 child.inject(parentInstance);
1160}
1161
1162function insertBefore(parentInstance, child, beforeChild) {
1163 (function () {
1164 if (!(child !== beforeChild)) {
1165 {
1166 throw ReactError(Error('ReactART: Can not insert node before itself'));
1167 }
1168 }
1169 })();
1170 child.injectBefore(beforeChild);
1171}
1172
1173function insertInContainerBefore(parentInstance, child, beforeChild) {
1174 (function () {
1175 if (!(child !== beforeChild)) {
1176 {
1177 throw ReactError(Error('ReactART: Can not insert node before itself'));
1178 }
1179 }
1180 })();
1181 child.injectBefore(beforeChild);
1182}
1183
1184function removeChild(parentInstance, child) {
1185 destroyEventListeners(child);
1186 child.eject();
1187}
1188
1189function removeChildFromContainer(parentInstance, child) {
1190 destroyEventListeners(child);
1191 child.eject();
1192}
1193
1194
1195
1196
1197
1198function commitUpdate(instance, updatePayload, type, oldProps, newProps) {
1199 instance._applyProps(instance, newProps, oldProps);
1200}
1201
1202function hideInstance(instance) {
1203 instance.hide();
1204}
1205
1206
1207
1208function unhideInstance(instance, props) {
1209 if (props.visible == null || props.visible) {
1210 instance.show();
1211 }
1212}
1213
1214function unhideTextInstance(textInstance, text) {
1215 // Noop
1216}
1217
1218function mountResponderInstance(responder, responderInstance, props, state, instance, rootContainerInstance) {
1219 throw new Error('Not yet implemented.');
1220}
1221
1222function unmountResponderInstance(responderInstance) {
1223 throw new Error('Not yet implemented.');
1224}
1225
1226function getFundamentalComponentInstance(fundamentalInstance) {
1227 throw new Error('Not yet implemented.');
1228}
1229
1230function mountFundamentalComponent(fundamentalInstance) {
1231 throw new Error('Not yet implemented.');
1232}
1233
1234function shouldUpdateFundamentalComponent(fundamentalInstance) {
1235 throw new Error('Not yet implemented.');
1236}
1237
1238function updateFundamentalComponent(fundamentalInstance) {
1239 throw new Error('Not yet implemented.');
1240}
1241
1242function unmountFundamentalComponent(fundamentalInstance) {
1243 throw new Error('Not yet implemented.');
1244}
1245
1246var enableUserTimingAPI = true;
1247
1248// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
1249var debugRenderPhaseSideEffects = false;
1250
1251// In some cases, StrictMode should also double-render lifecycles.
1252// This can be confusing for tests though,
1253// And it can be bad for performance in production.
1254// This feature flag can be used to control the behavior:
1255var debugRenderPhaseSideEffectsForStrictMode = true;
1256
1257// To preserve the "Pause on caught exceptions" behavior of the debugger, we
1258// replay the begin phase of a failed component inside invokeGuardedCallback.
1259var replayFailedUnitOfWorkWithInvokeGuardedCallback = true;
1260
1261// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
1262var warnAboutDeprecatedLifecycles = true;
1263
1264// Gather advanced timing metrics for Profiler subtrees.
1265var enableProfilerTimer = true;
1266
1267// Trace which interactions trigger each commit.
1268var enableSchedulerTracing = true;
1269
1270// Only used in www builds.
1271var enableSuspenseServerRenderer = false; // TODO: true? Here it might just be false.
1272
1273// Only used in www builds.
1274
1275
1276// Only used in www builds.
1277
1278
1279// Disable javascript: URL strings in href for XSS protection.
1280
1281
1282// React Fire: prevent the value and checked attributes from syncing
1283// with their related DOM properties
1284
1285
1286// These APIs will no longer be "unstable" in the upcoming 16.7 release,
1287// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
1288
1289
1290
1291
1292// See https://github.com/react-native-community/discussions-and-proposals/issues/72 for more information
1293// This is a flag so we can fix warnings in RN core before turning it on
1294
1295
1296// Experimental React Flare event system and event components support.
1297var enableFlareAPI = false;
1298
1299// Experimental Host Component support.
1300var enableFundamentalAPI = false;
1301
1302// New API for JSX transforms to target - https://github.com/reactjs/rfcs/pull/107
1303
1304
1305// We will enforce mocking scheduler with scheduler/unstable_mock at some point. (v17?)
1306// Till then, we warn about the missing mock, but still fallback to a sync mode compatible version
1307var warnAboutUnmockedScheduler = false;
1308// Temporary flag to revert the fix in #15650
1309var revertPassiveEffectsChange = false;
1310
1311// For tests, we flush suspense fallbacks in an act scope;
1312// *except* in some of our own tests, where we test incremental loading states.
1313var flushSuspenseFallbacksInTests = true;
1314
1315// Changes priority of some events like mousemove to user-blocking priority,
1316// but without making them discrete. The flag exists in case it causes
1317// starvation problems.
1318
1319
1320// Add a callback property to suspense to notify which promises are currently
1321// in the update queue. This allows reporting and tracing of what is causing
1322// the user to see a loading state.
1323var enableSuspenseCallback = false;
1324
1325// Part of the simplification of React.createElement so we can eventually move
1326// from React.createElement to React.jsx
1327// https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md
1328var warnAboutDefaultPropsOnFunctionComponents = false;
1329
1330var disableLegacyContext = false;
1331
1332var disableSchedulerTimeoutBasedOnReactExpirationTime = false;
1333
1334/**
1335 * Copyright (c) 2013-present, Facebook, Inc.
1336 *
1337 * This source code is licensed under the MIT license found in the
1338 * LICENSE file in the root directory of this source tree.
1339 */
1340
1341
1342
1343var ReactPropTypesSecret$1 = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
1344
1345var ReactPropTypesSecret_1 = ReactPropTypesSecret$1;
1346
1347/**
1348 * Copyright (c) 2013-present, Facebook, Inc.
1349 *
1350 * This source code is licensed under the MIT license found in the
1351 * LICENSE file in the root directory of this source tree.
1352 */
1353
1354
1355
1356var printWarning = function() {};
1357
1358{
1359 var ReactPropTypesSecret = ReactPropTypesSecret_1;
1360 var loggedTypeFailures = {};
1361
1362 printWarning = function(text) {
1363 var message = 'Warning: ' + text;
1364 if (typeof console !== 'undefined') {
1365 console.error(message);
1366 }
1367 try {
1368 // --- Welcome to debugging React ---
1369 // This error was thrown as a convenience so that you can use this stack
1370 // to find the callsite that caused this warning to fire.
1371 throw new Error(message);
1372 } catch (x) {}
1373 };
1374}
1375
1376/**
1377 * Assert that the values match with the type specs.
1378 * Error messages are memorized and will only be shown once.
1379 *
1380 * @param {object} typeSpecs Map of name to a ReactPropType
1381 * @param {object} values Runtime values that need to be type-checked
1382 * @param {string} location e.g. "prop", "context", "child context"
1383 * @param {string} componentName Name of the component for error messages.
1384 * @param {?Function} getStack Returns the component stack.
1385 * @private
1386 */
1387function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
1388 {
1389 for (var typeSpecName in typeSpecs) {
1390 if (typeSpecs.hasOwnProperty(typeSpecName)) {
1391 var error;
1392 // Prop type validation may throw. In case they do, we don't want to
1393 // fail the render phase where it didn't fail before. So we log it.
1394 // After these have been cleaned up, we'll let them throw.
1395 try {
1396 // This is intentionally an invariant that gets caught. It's the same
1397 // behavior as without this statement except with a better message.
1398 if (typeof typeSpecs[typeSpecName] !== 'function') {
1399 var err = Error(
1400 (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +
1401 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'
1402 );
1403 err.name = 'Invariant Violation';
1404 throw err;
1405 }
1406 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
1407 } catch (ex) {
1408 error = ex;
1409 }
1410 if (error && !(error instanceof Error)) {
1411 printWarning(
1412 (componentName || 'React class') + ': type specification of ' +
1413 location + ' `' + typeSpecName + '` is invalid; the type checker ' +
1414 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +
1415 'You may have forgotten to pass an argument to the type checker ' +
1416 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
1417 'shape all require an argument).'
1418 );
1419
1420 }
1421 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
1422 // Only monitor this failure once because there tends to be a lot of the
1423 // same error.
1424 loggedTypeFailures[error.message] = true;
1425
1426 var stack = getStack ? getStack() : '';
1427
1428 printWarning(
1429 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')
1430 );
1431 }
1432 }
1433 }
1434 }
1435}
1436
1437var checkPropTypes_1 = checkPropTypes;
1438
1439var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
1440
1441var describeComponentFrame = function (name, source, ownerName) {
1442 var sourceInfo = '';
1443 if (source) {
1444 var path = source.fileName;
1445 var fileName = path.replace(BEFORE_SLASH_RE, '');
1446 {
1447 // In DEV, include code for a common special case:
1448 // prefer "folder/index.js" instead of just "index.js".
1449 if (/^index\./.test(fileName)) {
1450 var match = path.match(BEFORE_SLASH_RE);
1451 if (match) {
1452 var pathBeforeSlash = match[1];
1453 if (pathBeforeSlash) {
1454 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
1455 fileName = folderName + '/' + fileName;
1456 }
1457 }
1458 }
1459 }
1460 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
1461 } else if (ownerName) {
1462 sourceInfo = ' (created by ' + ownerName + ')';
1463 }
1464 return '\n in ' + (name || 'Unknown') + sourceInfo;
1465};
1466
1467var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1468
1469function describeFiber(fiber) {
1470 switch (fiber.tag) {
1471 case HostRoot:
1472 case HostPortal:
1473 case HostText:
1474 case Fragment:
1475 case ContextProvider:
1476 case ContextConsumer:
1477 return '';
1478 default:
1479 var owner = fiber._debugOwner;
1480 var source = fiber._debugSource;
1481 var name = getComponentName(fiber.type);
1482 var ownerName = null;
1483 if (owner) {
1484 ownerName = getComponentName(owner.type);
1485 }
1486 return describeComponentFrame(name, source, ownerName);
1487 }
1488}
1489
1490function getStackByFiberInDevAndProd(workInProgress) {
1491 var info = '';
1492 var node = workInProgress;
1493 do {
1494 info += describeFiber(node);
1495 node = node.return;
1496 } while (node);
1497 return info;
1498}
1499
1500var current$1 = null;
1501var phase = null;
1502
1503function getCurrentFiberOwnerNameInDevOrNull() {
1504 {
1505 if (current$1 === null) {
1506 return null;
1507 }
1508 var owner = current$1._debugOwner;
1509 if (owner !== null && typeof owner !== 'undefined') {
1510 return getComponentName(owner.type);
1511 }
1512 }
1513 return null;
1514}
1515
1516function getCurrentFiberStackInDev() {
1517 {
1518 if (current$1 === null) {
1519 return '';
1520 }
1521 // Safe because if current fiber exists, we are reconciling,
1522 // and it is guaranteed to be the work-in-progress version.
1523 return getStackByFiberInDevAndProd(current$1);
1524 }
1525 return '';
1526}
1527
1528function resetCurrentFiber() {
1529 {
1530 ReactDebugCurrentFrame.getCurrentStack = null;
1531 current$1 = null;
1532 phase = null;
1533 }
1534}
1535
1536function setCurrentFiber(fiber) {
1537 {
1538 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
1539 current$1 = fiber;
1540 phase = null;
1541 }
1542}
1543
1544function setCurrentPhase(lifeCyclePhase) {
1545 {
1546 phase = lifeCyclePhase;
1547 }
1548}
1549
1550// Prefix measurements so that it's possible to filter them.
1551// Longer prefixes are hard to read in DevTools.
1552var reactEmoji = '\u269B';
1553var warningEmoji = '\u26D4';
1554var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
1555
1556// Keep track of current fiber so that we know the path to unwind on pause.
1557// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
1558var currentFiber = null;
1559// If we're in the middle of user code, which fiber and method is it?
1560// Reusing `currentFiber` would be confusing for this because user code fiber
1561// can change during commit phase too, but we don't need to unwind it (since
1562// lifecycles in the commit phase don't resemble a tree).
1563var currentPhase = null;
1564var currentPhaseFiber = null;
1565// Did lifecycle hook schedule an update? This is often a performance problem,
1566// so we will keep track of it, and include it in the report.
1567// Track commits caused by cascading updates.
1568var isCommitting = false;
1569var hasScheduledUpdateInCurrentCommit = false;
1570var hasScheduledUpdateInCurrentPhase = false;
1571var commitCountInCurrentWorkLoop = 0;
1572var effectCountInCurrentCommit = 0;
1573var isWaitingForCallback = false;
1574// During commits, we only show a measurement once per method name
1575// to avoid stretch the commit phase with measurement overhead.
1576var labelsInCurrentCommit = new Set();
1577
1578var formatMarkName = function (markName) {
1579 return reactEmoji + ' ' + markName;
1580};
1581
1582var formatLabel = function (label, warning) {
1583 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
1584 var suffix = warning ? ' Warning: ' + warning : '';
1585 return '' + prefix + label + suffix;
1586};
1587
1588var beginMark = function (markName) {
1589 performance.mark(formatMarkName(markName));
1590};
1591
1592var clearMark = function (markName) {
1593 performance.clearMarks(formatMarkName(markName));
1594};
1595
1596var endMark = function (label, markName, warning) {
1597 var formattedMarkName = formatMarkName(markName);
1598 var formattedLabel = formatLabel(label, warning);
1599 try {
1600 performance.measure(formattedLabel, formattedMarkName);
1601 } catch (err) {}
1602 // If previous mark was missing for some reason, this will throw.
1603 // This could only happen if React crashed in an unexpected place earlier.
1604 // Don't pile on with more errors.
1605
1606 // Clear marks immediately to avoid growing buffer.
1607 performance.clearMarks(formattedMarkName);
1608 performance.clearMeasures(formattedLabel);
1609};
1610
1611var getFiberMarkName = function (label, debugID) {
1612 return label + ' (#' + debugID + ')';
1613};
1614
1615var getFiberLabel = function (componentName, isMounted, phase) {
1616 if (phase === null) {
1617 // These are composite component total time measurements.
1618 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
1619 } else {
1620 // Composite component methods.
1621 return componentName + '.' + phase;
1622 }
1623};
1624
1625var beginFiberMark = function (fiber, phase) {
1626 var componentName = getComponentName(fiber.type) || 'Unknown';
1627 var debugID = fiber._debugID;
1628 var isMounted = fiber.alternate !== null;
1629 var label = getFiberLabel(componentName, isMounted, phase);
1630
1631 if (isCommitting && labelsInCurrentCommit.has(label)) {
1632 // During the commit phase, we don't show duplicate labels because
1633 // there is a fixed overhead for every measurement, and we don't
1634 // want to stretch the commit phase beyond necessary.
1635 return false;
1636 }
1637 labelsInCurrentCommit.add(label);
1638
1639 var markName = getFiberMarkName(label, debugID);
1640 beginMark(markName);
1641 return true;
1642};
1643
1644var clearFiberMark = function (fiber, phase) {
1645 var componentName = getComponentName(fiber.type) || 'Unknown';
1646 var debugID = fiber._debugID;
1647 var isMounted = fiber.alternate !== null;
1648 var label = getFiberLabel(componentName, isMounted, phase);
1649 var markName = getFiberMarkName(label, debugID);
1650 clearMark(markName);
1651};
1652
1653var endFiberMark = function (fiber, phase, warning) {
1654 var componentName = getComponentName(fiber.type) || 'Unknown';
1655 var debugID = fiber._debugID;
1656 var isMounted = fiber.alternate !== null;
1657 var label = getFiberLabel(componentName, isMounted, phase);
1658 var markName = getFiberMarkName(label, debugID);
1659 endMark(label, markName, warning);
1660};
1661
1662var shouldIgnoreFiber = function (fiber) {
1663 // Host components should be skipped in the timeline.
1664 // We could check typeof fiber.type, but does this work with RN?
1665 switch (fiber.tag) {
1666 case HostRoot:
1667 case HostComponent:
1668 case HostText:
1669 case HostPortal:
1670 case Fragment:
1671 case ContextProvider:
1672 case ContextConsumer:
1673 case Mode:
1674 return true;
1675 default:
1676 return false;
1677 }
1678};
1679
1680var clearPendingPhaseMeasurement = function () {
1681 if (currentPhase !== null && currentPhaseFiber !== null) {
1682 clearFiberMark(currentPhaseFiber, currentPhase);
1683 }
1684 currentPhaseFiber = null;
1685 currentPhase = null;
1686 hasScheduledUpdateInCurrentPhase = false;
1687};
1688
1689var pauseTimers = function () {
1690 // Stops all currently active measurements so that they can be resumed
1691 // if we continue in a later deferred loop from the same unit of work.
1692 var fiber = currentFiber;
1693 while (fiber) {
1694 if (fiber._debugIsCurrentlyTiming) {
1695 endFiberMark(fiber, null, null);
1696 }
1697 fiber = fiber.return;
1698 }
1699};
1700
1701var resumeTimersRecursively = function (fiber) {
1702 if (fiber.return !== null) {
1703 resumeTimersRecursively(fiber.return);
1704 }
1705 if (fiber._debugIsCurrentlyTiming) {
1706 beginFiberMark(fiber, null);
1707 }
1708};
1709
1710var resumeTimers = function () {
1711 // Resumes all measurements that were active during the last deferred loop.
1712 if (currentFiber !== null) {
1713 resumeTimersRecursively(currentFiber);
1714 }
1715};
1716
1717function recordEffect() {
1718 if (enableUserTimingAPI) {
1719 effectCountInCurrentCommit++;
1720 }
1721}
1722
1723function recordScheduleUpdate() {
1724 if (enableUserTimingAPI) {
1725 if (isCommitting) {
1726 hasScheduledUpdateInCurrentCommit = true;
1727 }
1728 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
1729 hasScheduledUpdateInCurrentPhase = true;
1730 }
1731 }
1732}
1733
1734function startRequestCallbackTimer() {
1735 if (enableUserTimingAPI) {
1736 if (supportsUserTiming && !isWaitingForCallback) {
1737 isWaitingForCallback = true;
1738 beginMark('(Waiting for async callback...)');
1739 }
1740 }
1741}
1742
1743function stopRequestCallbackTimer(didExpire) {
1744 if (enableUserTimingAPI) {
1745 if (supportsUserTiming) {
1746 isWaitingForCallback = false;
1747 var warning = didExpire ? 'Update expired; will flush synchronously' : null;
1748 endMark('(Waiting for async callback...)', '(Waiting for async callback...)', warning);
1749 }
1750 }
1751}
1752
1753function startWorkTimer(fiber) {
1754 if (enableUserTimingAPI) {
1755 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1756 return;
1757 }
1758 // If we pause, this is the fiber to unwind from.
1759 currentFiber = fiber;
1760 if (!beginFiberMark(fiber, null)) {
1761 return;
1762 }
1763 fiber._debugIsCurrentlyTiming = true;
1764 }
1765}
1766
1767function cancelWorkTimer(fiber) {
1768 if (enableUserTimingAPI) {
1769 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1770 return;
1771 }
1772 // Remember we shouldn't complete measurement for this fiber.
1773 // Otherwise flamechart will be deep even for small updates.
1774 fiber._debugIsCurrentlyTiming = false;
1775 clearFiberMark(fiber, null);
1776 }
1777}
1778
1779function stopWorkTimer(fiber) {
1780 if (enableUserTimingAPI) {
1781 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1782 return;
1783 }
1784 // If we pause, its parent is the fiber to unwind from.
1785 currentFiber = fiber.return;
1786 if (!fiber._debugIsCurrentlyTiming) {
1787 return;
1788 }
1789 fiber._debugIsCurrentlyTiming = false;
1790 endFiberMark(fiber, null, null);
1791 }
1792}
1793
1794function stopFailedWorkTimer(fiber) {
1795 if (enableUserTimingAPI) {
1796 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1797 return;
1798 }
1799 // If we pause, its parent is the fiber to unwind from.
1800 currentFiber = fiber.return;
1801 if (!fiber._debugIsCurrentlyTiming) {
1802 return;
1803 }
1804 fiber._debugIsCurrentlyTiming = false;
1805 var warning = fiber.tag === SuspenseComponent || fiber.tag === DehydratedSuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
1806 endFiberMark(fiber, null, warning);
1807 }
1808}
1809
1810function startPhaseTimer(fiber, phase) {
1811 if (enableUserTimingAPI) {
1812 if (!supportsUserTiming) {
1813 return;
1814 }
1815 clearPendingPhaseMeasurement();
1816 if (!beginFiberMark(fiber, phase)) {
1817 return;
1818 }
1819 currentPhaseFiber = fiber;
1820 currentPhase = phase;
1821 }
1822}
1823
1824function stopPhaseTimer() {
1825 if (enableUserTimingAPI) {
1826 if (!supportsUserTiming) {
1827 return;
1828 }
1829 if (currentPhase !== null && currentPhaseFiber !== null) {
1830 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
1831 endFiberMark(currentPhaseFiber, currentPhase, warning);
1832 }
1833 currentPhase = null;
1834 currentPhaseFiber = null;
1835 }
1836}
1837
1838function startWorkLoopTimer(nextUnitOfWork) {
1839 if (enableUserTimingAPI) {
1840 currentFiber = nextUnitOfWork;
1841 if (!supportsUserTiming) {
1842 return;
1843 }
1844 commitCountInCurrentWorkLoop = 0;
1845 // This is top level call.
1846 // Any other measurements are performed within.
1847 beginMark('(React Tree Reconciliation)');
1848 // Resume any measurements that were in progress during the last loop.
1849 resumeTimers();
1850 }
1851}
1852
1853function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
1854 if (enableUserTimingAPI) {
1855 if (!supportsUserTiming) {
1856 return;
1857 }
1858 var warning = null;
1859 if (interruptedBy !== null) {
1860 if (interruptedBy.tag === HostRoot) {
1861 warning = 'A top-level update interrupted the previous render';
1862 } else {
1863 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
1864 warning = 'An update to ' + componentName + ' interrupted the previous render';
1865 }
1866 } else if (commitCountInCurrentWorkLoop > 1) {
1867 warning = 'There were cascading updates';
1868 }
1869 commitCountInCurrentWorkLoop = 0;
1870 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)';
1871 // Pause any measurements until the next loop.
1872 pauseTimers();
1873 endMark(label, '(React Tree Reconciliation)', warning);
1874 }
1875}
1876
1877function startCommitTimer() {
1878 if (enableUserTimingAPI) {
1879 if (!supportsUserTiming) {
1880 return;
1881 }
1882 isCommitting = true;
1883 hasScheduledUpdateInCurrentCommit = false;
1884 labelsInCurrentCommit.clear();
1885 beginMark('(Committing Changes)');
1886 }
1887}
1888
1889function stopCommitTimer() {
1890 if (enableUserTimingAPI) {
1891 if (!supportsUserTiming) {
1892 return;
1893 }
1894
1895 var warning = null;
1896 if (hasScheduledUpdateInCurrentCommit) {
1897 warning = 'Lifecycle hook scheduled a cascading update';
1898 } else if (commitCountInCurrentWorkLoop > 0) {
1899 warning = 'Caused by a cascading update in earlier commit';
1900 }
1901 hasScheduledUpdateInCurrentCommit = false;
1902 commitCountInCurrentWorkLoop++;
1903 isCommitting = false;
1904 labelsInCurrentCommit.clear();
1905
1906 endMark('(Committing Changes)', '(Committing Changes)', warning);
1907 }
1908}
1909
1910function startCommitSnapshotEffectsTimer() {
1911 if (enableUserTimingAPI) {
1912 if (!supportsUserTiming) {
1913 return;
1914 }
1915 effectCountInCurrentCommit = 0;
1916 beginMark('(Committing Snapshot Effects)');
1917 }
1918}
1919
1920function stopCommitSnapshotEffectsTimer() {
1921 if (enableUserTimingAPI) {
1922 if (!supportsUserTiming) {
1923 return;
1924 }
1925 var count = effectCountInCurrentCommit;
1926 effectCountInCurrentCommit = 0;
1927 endMark('(Committing Snapshot Effects: ' + count + ' Total)', '(Committing Snapshot Effects)', null);
1928 }
1929}
1930
1931function startCommitHostEffectsTimer() {
1932 if (enableUserTimingAPI) {
1933 if (!supportsUserTiming) {
1934 return;
1935 }
1936 effectCountInCurrentCommit = 0;
1937 beginMark('(Committing Host Effects)');
1938 }
1939}
1940
1941function stopCommitHostEffectsTimer() {
1942 if (enableUserTimingAPI) {
1943 if (!supportsUserTiming) {
1944 return;
1945 }
1946 var count = effectCountInCurrentCommit;
1947 effectCountInCurrentCommit = 0;
1948 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
1949 }
1950}
1951
1952function startCommitLifeCyclesTimer() {
1953 if (enableUserTimingAPI) {
1954 if (!supportsUserTiming) {
1955 return;
1956 }
1957 effectCountInCurrentCommit = 0;
1958 beginMark('(Calling Lifecycle Methods)');
1959 }
1960}
1961
1962function stopCommitLifeCyclesTimer() {
1963 if (enableUserTimingAPI) {
1964 if (!supportsUserTiming) {
1965 return;
1966 }
1967 var count = effectCountInCurrentCommit;
1968 effectCountInCurrentCommit = 0;
1969 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
1970 }
1971}
1972
1973var valueStack = [];
1974
1975var fiberStack = void 0;
1976
1977{
1978 fiberStack = [];
1979}
1980
1981var index = -1;
1982
1983function createCursor(defaultValue) {
1984 return {
1985 current: defaultValue
1986 };
1987}
1988
1989function pop(cursor, fiber) {
1990 if (index < 0) {
1991 {
1992 warningWithoutStack$1(false, 'Unexpected pop.');
1993 }
1994 return;
1995 }
1996
1997 {
1998 if (fiber !== fiberStack[index]) {
1999 warningWithoutStack$1(false, 'Unexpected Fiber popped.');
2000 }
2001 }
2002
2003 cursor.current = valueStack[index];
2004
2005 valueStack[index] = null;
2006
2007 {
2008 fiberStack[index] = null;
2009 }
2010
2011 index--;
2012}
2013
2014function push(cursor, value, fiber) {
2015 index++;
2016
2017 valueStack[index] = cursor.current;
2018
2019 {
2020 fiberStack[index] = fiber;
2021 }
2022
2023 cursor.current = value;
2024}
2025
2026var warnedAboutMissingGetChildContext = void 0;
2027
2028{
2029 warnedAboutMissingGetChildContext = {};
2030}
2031
2032var emptyContextObject = {};
2033{
2034 Object.freeze(emptyContextObject);
2035}
2036
2037// A cursor to the current merged context object on the stack.
2038var contextStackCursor = createCursor(emptyContextObject);
2039// A cursor to a boolean indicating whether the context has changed.
2040var didPerformWorkStackCursor = createCursor(false);
2041// Keep track of the previous context object that was on the stack.
2042// We use this to get access to the parent context after we have already
2043// pushed the next context provider, and now need to merge their contexts.
2044var previousContext = emptyContextObject;
2045
2046function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
2047 if (disableLegacyContext) {
2048 return emptyContextObject;
2049 } else {
2050 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
2051 // If the fiber is a context provider itself, when we read its context
2052 // we may have already pushed its own child context on the stack. A context
2053 // provider should not "see" its own child context. Therefore we read the
2054 // previous (parent) context instead for a context provider.
2055 return previousContext;
2056 }
2057 return contextStackCursor.current;
2058 }
2059}
2060
2061function cacheContext(workInProgress, unmaskedContext, maskedContext) {
2062 if (disableLegacyContext) {
2063 return;
2064 } else {
2065 var instance = workInProgress.stateNode;
2066 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
2067 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
2068 }
2069}
2070
2071function getMaskedContext(workInProgress, unmaskedContext) {
2072 if (disableLegacyContext) {
2073 return emptyContextObject;
2074 } else {
2075 var type = workInProgress.type;
2076 var contextTypes = type.contextTypes;
2077 if (!contextTypes) {
2078 return emptyContextObject;
2079 }
2080
2081 // Avoid recreating masked context unless unmasked context has changed.
2082 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
2083 // This may trigger infinite loops if componentWillReceiveProps calls setState.
2084 var instance = workInProgress.stateNode;
2085 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
2086 return instance.__reactInternalMemoizedMaskedChildContext;
2087 }
2088
2089 var context = {};
2090 for (var key in contextTypes) {
2091 context[key] = unmaskedContext[key];
2092 }
2093
2094 {
2095 var name = getComponentName(type) || 'Unknown';
2096 checkPropTypes_1(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
2097 }
2098
2099 // Cache unmasked context so we can avoid recreating masked context unless necessary.
2100 // Context is created before the class component is instantiated so check for instance.
2101 if (instance) {
2102 cacheContext(workInProgress, unmaskedContext, context);
2103 }
2104
2105 return context;
2106 }
2107}
2108
2109function hasContextChanged() {
2110 if (disableLegacyContext) {
2111 return false;
2112 } else {
2113 return didPerformWorkStackCursor.current;
2114 }
2115}
2116
2117function isContextProvider(type) {
2118 if (disableLegacyContext) {
2119 return false;
2120 } else {
2121 var childContextTypes = type.childContextTypes;
2122 return childContextTypes !== null && childContextTypes !== undefined;
2123 }
2124}
2125
2126function popContext(fiber) {
2127 if (disableLegacyContext) {
2128 return;
2129 } else {
2130 pop(didPerformWorkStackCursor, fiber);
2131 pop(contextStackCursor, fiber);
2132 }
2133}
2134
2135function popTopLevelContextObject(fiber) {
2136 if (disableLegacyContext) {
2137 return;
2138 } else {
2139 pop(didPerformWorkStackCursor, fiber);
2140 pop(contextStackCursor, fiber);
2141 }
2142}
2143
2144function pushTopLevelContextObject(fiber, context, didChange) {
2145 if (disableLegacyContext) {
2146 return;
2147 } else {
2148 (function () {
2149 if (!(contextStackCursor.current === emptyContextObject)) {
2150 {
2151 throw ReactError(Error('Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue.'));
2152 }
2153 }
2154 })();
2155
2156 push(contextStackCursor, context, fiber);
2157 push(didPerformWorkStackCursor, didChange, fiber);
2158 }
2159}
2160
2161function processChildContext(fiber, type, parentContext) {
2162 if (disableLegacyContext) {
2163 return parentContext;
2164 } else {
2165 var instance = fiber.stateNode;
2166 var childContextTypes = type.childContextTypes;
2167
2168 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
2169 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
2170 if (typeof instance.getChildContext !== 'function') {
2171 {
2172 var componentName = getComponentName(type) || 'Unknown';
2173
2174 if (!warnedAboutMissingGetChildContext[componentName]) {
2175 warnedAboutMissingGetChildContext[componentName] = true;
2176 warningWithoutStack$1(false, '%s.childContextTypes is specified but there is no getChildContext() method ' + 'on the instance. You can either define getChildContext() on %s or remove ' + 'childContextTypes from it.', componentName, componentName);
2177 }
2178 }
2179 return parentContext;
2180 }
2181
2182 var childContext = void 0;
2183 {
2184 setCurrentPhase('getChildContext');
2185 }
2186 startPhaseTimer(fiber, 'getChildContext');
2187 childContext = instance.getChildContext();
2188 stopPhaseTimer();
2189 {
2190 setCurrentPhase(null);
2191 }
2192 for (var contextKey in childContext) {
2193 (function () {
2194 if (!(contextKey in childContextTypes)) {
2195 {
2196 throw ReactError(Error((getComponentName(type) || 'Unknown') + '.getChildContext(): key "' + contextKey + '" is not defined in childContextTypes.'));
2197 }
2198 }
2199 })();
2200 }
2201 {
2202 var name = getComponentName(type) || 'Unknown';
2203 checkPropTypes_1(childContextTypes, childContext, 'child context', name,
2204 // In practice, there is one case in which we won't get a stack. It's when
2205 // somebody calls unstable_renderSubtreeIntoContainer() and we process
2206 // context from the parent component instance. The stack will be missing
2207 // because it's outside of the reconciliation, and so the pointer has not
2208 // been set. This is rare and doesn't matter. We'll also remove that API.
2209 getCurrentFiberStackInDev);
2210 }
2211
2212 return _assign({}, parentContext, childContext);
2213 }
2214}
2215
2216function pushContextProvider(workInProgress) {
2217 if (disableLegacyContext) {
2218 return false;
2219 } else {
2220 var instance = workInProgress.stateNode;
2221 // We push the context as early as possible to ensure stack integrity.
2222 // If the instance does not exist yet, we will push null at first,
2223 // and replace it on the stack later when invalidating the context.
2224 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject;
2225
2226 // Remember the parent context so we can merge with it later.
2227 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
2228 previousContext = contextStackCursor.current;
2229 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
2230 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
2231
2232 return true;
2233 }
2234}
2235
2236function invalidateContextProvider(workInProgress, type, didChange) {
2237 if (disableLegacyContext) {
2238 return;
2239 } else {
2240 var instance = workInProgress.stateNode;
2241 (function () {
2242 if (!instance) {
2243 {
2244 throw ReactError(Error('Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue.'));
2245 }
2246 }
2247 })();
2248
2249 if (didChange) {
2250 // Merge parent and own context.
2251 // Skip this if we're not updating due to sCU.
2252 // This avoids unnecessarily recomputing memoized values.
2253 var mergedContext = processChildContext(workInProgress, type, previousContext);
2254 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
2255
2256 // Replace the old (or empty) context with the new one.
2257 // It is important to unwind the context in the reverse order.
2258 pop(didPerformWorkStackCursor, workInProgress);
2259 pop(contextStackCursor, workInProgress);
2260 // Now push the new context and mark that it has changed.
2261 push(contextStackCursor, mergedContext, workInProgress);
2262 push(didPerformWorkStackCursor, didChange, workInProgress);
2263 } else {
2264 pop(didPerformWorkStackCursor, workInProgress);
2265 push(didPerformWorkStackCursor, didChange, workInProgress);
2266 }
2267 }
2268}
2269
2270function findCurrentUnmaskedContext(fiber) {
2271 if (disableLegacyContext) {
2272 return emptyContextObject;
2273 } else {
2274 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
2275 // makes sense elsewhere
2276 (function () {
2277 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {
2278 {
2279 throw ReactError(Error('Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue.'));
2280 }
2281 }
2282 })();
2283
2284 var node = fiber;
2285 do {
2286 switch (node.tag) {
2287 case HostRoot:
2288 return node.stateNode.context;
2289 case ClassComponent:
2290 {
2291 var Component = node.type;
2292 if (isContextProvider(Component)) {
2293 return node.stateNode.__reactInternalMemoizedMergedChildContext;
2294 }
2295 break;
2296 }
2297 }
2298 node = node.return;
2299 } while (node !== null);
2300 (function () {
2301 {
2302 {
2303 throw ReactError(Error('Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.'));
2304 }
2305 }
2306 })();
2307 }
2308}
2309
2310/**
2311 * Similar to invariant but only logs a warning if the condition is not met.
2312 * This can be used to log issues in development environments in critical
2313 * paths. Removing the logging code for production environments will keep the
2314 * same logic and follow the same code paths.
2315 */
2316
2317var warning = warningWithoutStack$1;
2318
2319{
2320 warning = function (condition, format) {
2321 if (condition) {
2322 return;
2323 }
2324 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
2325 var stack = ReactDebugCurrentFrame.getStackAddendum();
2326 // eslint-disable-next-line react-internal/warning-and-invariant-args
2327
2328 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
2329 args[_key - 2] = arguments[_key];
2330 }
2331
2332 warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack]));
2333 };
2334}
2335
2336var warning$1 = warning;
2337
2338var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2339
2340var _ReactInternals$Sched = ReactInternals$1.Scheduler;
2341var unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback;
2342var unstable_now = _ReactInternals$Sched.unstable_now;
2343var unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback;
2344var unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield;
2345var unstable_requestPaint = _ReactInternals$Sched.unstable_requestPaint;
2346var unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode;
2347var unstable_runWithPriority = _ReactInternals$Sched.unstable_runWithPriority;
2348var unstable_next = _ReactInternals$Sched.unstable_next;
2349var unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution;
2350var unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution;
2351var unstable_getCurrentPriorityLevel = _ReactInternals$Sched.unstable_getCurrentPriorityLevel;
2352var unstable_ImmediatePriority = _ReactInternals$Sched.unstable_ImmediatePriority;
2353var unstable_UserBlockingPriority = _ReactInternals$Sched.unstable_UserBlockingPriority;
2354var unstable_NormalPriority = _ReactInternals$Sched.unstable_NormalPriority;
2355var unstable_LowPriority = _ReactInternals$Sched.unstable_LowPriority;
2356var unstable_IdlePriority = _ReactInternals$Sched.unstable_IdlePriority;
2357var unstable_forceFrameRate = _ReactInternals$Sched.unstable_forceFrameRate;
2358var unstable_flushAllWithoutAsserting = _ReactInternals$Sched.unstable_flushAllWithoutAsserting;
2359
2360var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2361
2362var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing;
2363var __interactionsRef = _ReactInternals$Sched$1.__interactionsRef;
2364var __subscriberRef = _ReactInternals$Sched$1.__subscriberRef;
2365var unstable_clear = _ReactInternals$Sched$1.unstable_clear;
2366var unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent;
2367var unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID;
2368var unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe;
2369var unstable_trace = _ReactInternals$Sched$1.unstable_trace;
2370var unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe;
2371var unstable_wrap = _ReactInternals$Sched$1.unstable_wrap;
2372
2373// Intentionally not named imports because Rollup would use dynamic dispatch for
2374// CommonJS interop named imports.
2375var Scheduler_runWithPriority = unstable_runWithPriority;
2376var Scheduler_scheduleCallback = unstable_scheduleCallback;
2377var Scheduler_cancelCallback = unstable_cancelCallback;
2378var Scheduler_shouldYield = unstable_shouldYield;
2379var Scheduler_requestPaint = unstable_requestPaint;
2380var Scheduler_now = unstable_now;
2381var Scheduler_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel;
2382var Scheduler_ImmediatePriority = unstable_ImmediatePriority;
2383var Scheduler_UserBlockingPriority = unstable_UserBlockingPriority;
2384var Scheduler_NormalPriority = unstable_NormalPriority;
2385var Scheduler_LowPriority = unstable_LowPriority;
2386var Scheduler_IdlePriority = unstable_IdlePriority;
2387
2388
2389if (enableSchedulerTracing) {
2390 // Provide explicit error message when production+profiling bundle of e.g.
2391 // react-dom is used with production (non-profiling) bundle of
2392 // scheduler/tracing
2393 (function () {
2394 if (!(__interactionsRef != null && __interactionsRef.current != null)) {
2395 {
2396 throw ReactError(Error('It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at http://fb.me/react-profiling'));
2397 }
2398 }
2399 })();
2400}
2401
2402var fakeCallbackNode = {};
2403
2404// Except for NoPriority, these correspond to Scheduler priorities. We use
2405// ascending numbers so we can compare them like numbers. They start at 90 to
2406// avoid clashing with Scheduler's priorities.
2407var ImmediatePriority = 99;
2408var UserBlockingPriority = 98;
2409var NormalPriority = 97;
2410var LowPriority = 96;
2411var IdlePriority = 95;
2412// NoPriority is the absence of priority. Also React-only.
2413var NoPriority = 90;
2414
2415var shouldYield = Scheduler_shouldYield;
2416var requestPaint =
2417// Fall back gracefully if we're running an older version of Scheduler.
2418Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {};
2419
2420var syncQueue = null;
2421var immediateQueueCallbackNode = null;
2422var isFlushingSyncQueue = false;
2423var initialTimeMs = Scheduler_now();
2424
2425// If the initial timestamp is reasonably small, use Scheduler's `now` directly.
2426// This will be the case for modern browsers that support `performance.now`. In
2427// older browsers, Scheduler falls back to `Date.now`, which returns a Unix
2428// timestamp. In that case, subtract the module initialization time to simulate
2429// the behavior of performance.now and keep our times small enough to fit
2430// within 32 bits.
2431// TODO: Consider lifting this into Scheduler.
2432var now = initialTimeMs < 10000 ? Scheduler_now : function () {
2433 return Scheduler_now() - initialTimeMs;
2434};
2435
2436function getCurrentPriorityLevel() {
2437 switch (Scheduler_getCurrentPriorityLevel()) {
2438 case Scheduler_ImmediatePriority:
2439 return ImmediatePriority;
2440 case Scheduler_UserBlockingPriority:
2441 return UserBlockingPriority;
2442 case Scheduler_NormalPriority:
2443 return NormalPriority;
2444 case Scheduler_LowPriority:
2445 return LowPriority;
2446 case Scheduler_IdlePriority:
2447 return IdlePriority;
2448 default:
2449 (function () {
2450 {
2451 {
2452 throw ReactError(Error('Unknown priority level.'));
2453 }
2454 }
2455 })();
2456 }
2457}
2458
2459function reactPriorityToSchedulerPriority(reactPriorityLevel) {
2460 switch (reactPriorityLevel) {
2461 case ImmediatePriority:
2462 return Scheduler_ImmediatePriority;
2463 case UserBlockingPriority:
2464 return Scheduler_UserBlockingPriority;
2465 case NormalPriority:
2466 return Scheduler_NormalPriority;
2467 case LowPriority:
2468 return Scheduler_LowPriority;
2469 case IdlePriority:
2470 return Scheduler_IdlePriority;
2471 default:
2472 (function () {
2473 {
2474 {
2475 throw ReactError(Error('Unknown priority level.'));
2476 }
2477 }
2478 })();
2479 }
2480}
2481
2482function runWithPriority(reactPriorityLevel, fn) {
2483 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
2484 return Scheduler_runWithPriority(priorityLevel, fn);
2485}
2486
2487function scheduleCallback(reactPriorityLevel, callback, options) {
2488 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
2489 return Scheduler_scheduleCallback(priorityLevel, callback, options);
2490}
2491
2492function scheduleSyncCallback(callback) {
2493 // Push this callback into an internal queue. We'll flush these either in
2494 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
2495 if (syncQueue === null) {
2496 syncQueue = [callback];
2497 // Flush the queue in the next tick, at the earliest.
2498 immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl);
2499 } else {
2500 // Push onto existing queue. Don't need to schedule a callback because
2501 // we already scheduled one when we created the queue.
2502 syncQueue.push(callback);
2503 }
2504 return fakeCallbackNode;
2505}
2506
2507function cancelCallback(callbackNode) {
2508 if (callbackNode !== fakeCallbackNode) {
2509 Scheduler_cancelCallback(callbackNode);
2510 }
2511}
2512
2513function flushSyncCallbackQueue() {
2514 if (immediateQueueCallbackNode !== null) {
2515 Scheduler_cancelCallback(immediateQueueCallbackNode);
2516 }
2517 flushSyncCallbackQueueImpl();
2518}
2519
2520function flushSyncCallbackQueueImpl() {
2521 if (!isFlushingSyncQueue && syncQueue !== null) {
2522 // Prevent re-entrancy.
2523 isFlushingSyncQueue = true;
2524 var i = 0;
2525 try {
2526 var _isSync = true;
2527 var queue = syncQueue;
2528 runWithPriority(ImmediatePriority, function () {
2529 for (; i < queue.length; i++) {
2530 var callback = queue[i];
2531 do {
2532 callback = callback(_isSync);
2533 } while (callback !== null);
2534 }
2535 });
2536 syncQueue = null;
2537 } catch (error) {
2538 // If something throws, leave the remaining callbacks on the queue.
2539 if (syncQueue !== null) {
2540 syncQueue = syncQueue.slice(i + 1);
2541 }
2542 // Resume flushing in the next tick
2543 Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue);
2544 throw error;
2545 } finally {
2546 isFlushingSyncQueue = false;
2547 }
2548 }
2549}
2550
2551var NoMode = 0;
2552var StrictMode = 1;
2553// TODO: Remove BatchedMode and ConcurrentMode by reading from the root
2554// tag instead
2555var BatchedMode = 2;
2556var ConcurrentMode = 4;
2557var ProfileMode = 8;
2558
2559// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
2560// Math.pow(2, 30) - 1
2561// 0b111111111111111111111111111111
2562var MAX_SIGNED_31_BIT_INT = 1073741823;
2563
2564var NoWork = 0;
2565var Never = 1;
2566var Sync = MAX_SIGNED_31_BIT_INT;
2567var Batched = Sync - 1;
2568
2569var UNIT_SIZE = 10;
2570var MAGIC_NUMBER_OFFSET = Batched - 1;
2571
2572// 1 unit of expiration time represents 10ms.
2573function msToExpirationTime(ms) {
2574 // Always add an offset so that we don't clash with the magic number for NoWork.
2575 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
2576}
2577
2578function expirationTimeToMs(expirationTime) {
2579 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
2580}
2581
2582function ceiling(num, precision) {
2583 return ((num / precision | 0) + 1) * precision;
2584}
2585
2586function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
2587 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
2588}
2589
2590// TODO: This corresponds to Scheduler's NormalPriority, not LowPriority. Update
2591// the names to reflect.
2592var LOW_PRIORITY_EXPIRATION = 5000;
2593var LOW_PRIORITY_BATCH_SIZE = 250;
2594
2595function computeAsyncExpiration(currentTime) {
2596 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
2597}
2598
2599function computeSuspenseExpiration(currentTime, timeoutMs) {
2600 // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time?
2601 return computeExpirationBucket(currentTime, timeoutMs, LOW_PRIORITY_BATCH_SIZE);
2602}
2603
2604// We intentionally set a higher expiration time for interactive updates in
2605// dev than in production.
2606//
2607// If the main thread is being blocked so long that you hit the expiration,
2608// it's a problem that could be solved with better scheduling.
2609//
2610// People will be more likely to notice this and fix it with the long
2611// expiration time in development.
2612//
2613// In production we opt for better UX at the risk of masking scheduling
2614// problems, by expiring fast.
2615var HIGH_PRIORITY_EXPIRATION = 500;
2616var HIGH_PRIORITY_BATCH_SIZE = 100;
2617
2618function computeInteractiveExpiration(currentTime) {
2619 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
2620}
2621
2622function inferPriorityFromExpirationTime(currentTime, expirationTime) {
2623 if (expirationTime === Sync) {
2624 return ImmediatePriority;
2625 }
2626 if (expirationTime === Never) {
2627 return IdlePriority;
2628 }
2629 var msUntil = expirationTimeToMs(expirationTime) - expirationTimeToMs(currentTime);
2630 if (msUntil <= 0) {
2631 return ImmediatePriority;
2632 }
2633 if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) {
2634 return UserBlockingPriority;
2635 }
2636 if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) {
2637 return NormalPriority;
2638 }
2639
2640 // TODO: Handle LowPriority
2641
2642 // Assume anything lower has idle priority
2643 return IdlePriority;
2644}
2645
2646/**
2647 * inlined Object.is polyfill to avoid requiring consumers ship their own
2648 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
2649 */
2650function is(x, y) {
2651 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
2652 ;
2653}
2654
2655var hasOwnProperty = Object.prototype.hasOwnProperty;
2656
2657/**
2658 * Performs equality by iterating through keys on an object and returning false
2659 * when any key has values which are not strictly equal between the arguments.
2660 * Returns true when the values of all keys are strictly equal.
2661 */
2662function shallowEqual(objA, objB) {
2663 if (is(objA, objB)) {
2664 return true;
2665 }
2666
2667 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
2668 return false;
2669 }
2670
2671 var keysA = Object.keys(objA);
2672 var keysB = Object.keys(objB);
2673
2674 if (keysA.length !== keysB.length) {
2675 return false;
2676 }
2677
2678 // Test for A's keys different from B.
2679 for (var i = 0; i < keysA.length; i++) {
2680 if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
2681 return false;
2682 }
2683 }
2684
2685 return true;
2686}
2687
2688/**
2689 * Forked from fbjs/warning:
2690 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
2691 *
2692 * Only change is we use console.warn instead of console.error,
2693 * and do nothing when 'console' is not supported.
2694 * This really simplifies the code.
2695 * ---
2696 * Similar to invariant but only logs a warning if the condition is not met.
2697 * This can be used to log issues in development environments in critical
2698 * paths. Removing the logging code for production environments will keep the
2699 * same logic and follow the same code paths.
2700 */
2701
2702var lowPriorityWarning = function () {};
2703
2704{
2705 var printWarning$1 = function (format) {
2706 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
2707 args[_key - 1] = arguments[_key];
2708 }
2709
2710 var argIndex = 0;
2711 var message = 'Warning: ' + format.replace(/%s/g, function () {
2712 return args[argIndex++];
2713 });
2714 if (typeof console !== 'undefined') {
2715 console.warn(message);
2716 }
2717 try {
2718 // --- Welcome to debugging React ---
2719 // This error was thrown as a convenience so that you can use this stack
2720 // to find the callsite that caused this warning to fire.
2721 throw new Error(message);
2722 } catch (x) {}
2723 };
2724
2725 lowPriorityWarning = function (condition, format) {
2726 if (format === undefined) {
2727 throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument');
2728 }
2729 if (!condition) {
2730 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
2731 args[_key2 - 2] = arguments[_key2];
2732 }
2733
2734 printWarning$1.apply(undefined, [format].concat(args));
2735 }
2736 };
2737}
2738
2739var lowPriorityWarning$1 = lowPriorityWarning;
2740
2741var ReactStrictModeWarnings = {
2742 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
2743 flushPendingUnsafeLifecycleWarnings: function () {},
2744 recordLegacyContextWarning: function (fiber, instance) {},
2745 flushLegacyContextWarning: function () {},
2746 discardPendingWarnings: function () {}
2747};
2748
2749{
2750 var findStrictRoot = function (fiber) {
2751 var maybeStrictRoot = null;
2752
2753 var node = fiber;
2754 while (node !== null) {
2755 if (node.mode & StrictMode) {
2756 maybeStrictRoot = node;
2757 }
2758 node = node.return;
2759 }
2760
2761 return maybeStrictRoot;
2762 };
2763
2764 var setToSortedString = function (set) {
2765 var array = [];
2766 set.forEach(function (value) {
2767 array.push(value);
2768 });
2769 return array.sort().join(', ');
2770 };
2771
2772 var pendingComponentWillMountWarnings = [];
2773 var pendingUNSAFE_ComponentWillMountWarnings = [];
2774 var pendingComponentWillReceivePropsWarnings = [];
2775 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2776 var pendingComponentWillUpdateWarnings = [];
2777 var pendingUNSAFE_ComponentWillUpdateWarnings = [];
2778
2779 // Tracks components we have already warned about.
2780 var didWarnAboutUnsafeLifecycles = new Set();
2781
2782 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
2783 // Dedup strategy: Warn once per component.
2784 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
2785 return;
2786 }
2787
2788 if (typeof instance.componentWillMount === 'function' &&
2789 // Don't warn about react-lifecycles-compat polyfilled components.
2790 instance.componentWillMount.__suppressDeprecationWarning !== true) {
2791 pendingComponentWillMountWarnings.push(fiber);
2792 }
2793
2794 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') {
2795 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
2796 }
2797
2798 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
2799 pendingComponentWillReceivePropsWarnings.push(fiber);
2800 }
2801
2802 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
2803 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
2804 }
2805
2806 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
2807 pendingComponentWillUpdateWarnings.push(fiber);
2808 }
2809
2810 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
2811 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
2812 }
2813 };
2814
2815 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
2816 // We do an initial pass to gather component names
2817 var componentWillMountUniqueNames = new Set();
2818 if (pendingComponentWillMountWarnings.length > 0) {
2819 pendingComponentWillMountWarnings.forEach(function (fiber) {
2820 componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2821 didWarnAboutUnsafeLifecycles.add(fiber.type);
2822 });
2823 pendingComponentWillMountWarnings = [];
2824 }
2825
2826 var UNSAFE_componentWillMountUniqueNames = new Set();
2827 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
2828 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
2829 UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
2830 didWarnAboutUnsafeLifecycles.add(fiber.type);
2831 });
2832 pendingUNSAFE_ComponentWillMountWarnings = [];
2833 }
2834
2835 var componentWillReceivePropsUniqueNames = new Set();
2836 if (pendingComponentWillReceivePropsWarnings.length > 0) {
2837 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
2838 componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2839 didWarnAboutUnsafeLifecycles.add(fiber.type);
2840 });
2841
2842 pendingComponentWillReceivePropsWarnings = [];
2843 }
2844
2845 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
2846 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
2847 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
2848 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
2849 didWarnAboutUnsafeLifecycles.add(fiber.type);
2850 });
2851
2852 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2853 }
2854
2855 var componentWillUpdateUniqueNames = new Set();
2856 if (pendingComponentWillUpdateWarnings.length > 0) {
2857 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
2858 componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
2859 didWarnAboutUnsafeLifecycles.add(fiber.type);
2860 });
2861
2862 pendingComponentWillUpdateWarnings = [];
2863 }
2864
2865 var UNSAFE_componentWillUpdateUniqueNames = new Set();
2866 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
2867 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
2868 UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
2869 didWarnAboutUnsafeLifecycles.add(fiber.type);
2870 });
2871
2872 pendingUNSAFE_ComponentWillUpdateWarnings = [];
2873 }
2874
2875 // Finally, we flush all the warnings
2876 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
2877 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
2878 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
2879 warningWithoutStack$1(false, 'Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '\nPlease update the following components: %s', sortedNames);
2880 }
2881
2882 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
2883 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
2884 warningWithoutStack$1(false, 'Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, " + 'refactor your code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n' + '\nPlease update the following components: %s', _sortedNames);
2885 }
2886
2887 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
2888 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
2889 warningWithoutStack$1(false, 'Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '\nPlease update the following components: %s', _sortedNames2);
2890 }
2891
2892 if (componentWillMountUniqueNames.size > 0) {
2893 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
2894
2895 lowPriorityWarning$1(false, 'componentWillMount has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames3);
2896 }
2897
2898 if (componentWillReceivePropsUniqueNames.size > 0) {
2899 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
2900
2901 lowPriorityWarning$1(false, 'componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, refactor your " + 'code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n' + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames4);
2902 }
2903
2904 if (componentWillUpdateUniqueNames.size > 0) {
2905 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
2906
2907 lowPriorityWarning$1(false, 'componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-async-component-lifecycle-hooks for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames5);
2908 }
2909 };
2910
2911 var pendingLegacyContextWarning = new Map();
2912
2913 // Tracks components we have already warned about.
2914 var didWarnAboutLegacyContext = new Set();
2915
2916 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
2917 var strictRoot = findStrictRoot(fiber);
2918 if (strictRoot === null) {
2919 warningWithoutStack$1(false, 'Expected to find a StrictMode component in a strict mode tree. ' + 'This error is likely caused by a bug in React. Please file an issue.');
2920 return;
2921 }
2922
2923 // Dedup strategy: Warn once per component.
2924 if (didWarnAboutLegacyContext.has(fiber.type)) {
2925 return;
2926 }
2927
2928 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
2929
2930 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
2931 if (warningsForRoot === undefined) {
2932 warningsForRoot = [];
2933 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
2934 }
2935 warningsForRoot.push(fiber);
2936 }
2937 };
2938
2939 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
2940 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
2941 var uniqueNames = new Set();
2942 fiberArray.forEach(function (fiber) {
2943 uniqueNames.add(getComponentName(fiber.type) || 'Component');
2944 didWarnAboutLegacyContext.add(fiber.type);
2945 });
2946
2947 var sortedNames = setToSortedString(uniqueNames);
2948 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
2949
2950 warningWithoutStack$1(false, 'Legacy context API has been detected within a strict-mode tree: %s' + '\n\nThe old API will be supported in all 16.x releases, but applications ' + 'using it should migrate to the new version.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here:' + '\nhttps://fb.me/react-legacy-context', strictRootComponentStack, sortedNames);
2951 });
2952 };
2953
2954 ReactStrictModeWarnings.discardPendingWarnings = function () {
2955 pendingComponentWillMountWarnings = [];
2956 pendingUNSAFE_ComponentWillMountWarnings = [];
2957 pendingComponentWillReceivePropsWarnings = [];
2958 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
2959 pendingComponentWillUpdateWarnings = [];
2960 pendingUNSAFE_ComponentWillUpdateWarnings = [];
2961 pendingLegacyContextWarning = new Map();
2962 };
2963}
2964
2965// Resolves type to a family.
2966
2967
2968// Used by React Refresh runtime through DevTools Global Hook.
2969
2970
2971var resolveFamily = null;
2972// $FlowFixMe Flow gets confused by a WeakSet feature check below.
2973var failedBoundaries = null;
2974
2975var setRefreshHandler = function (handler) {
2976 {
2977 resolveFamily = handler;
2978 }
2979};
2980
2981function resolveFunctionForHotReloading(type) {
2982 {
2983 if (resolveFamily === null) {
2984 // Hot reloading is disabled.
2985 return type;
2986 }
2987 var family = resolveFamily(type);
2988 if (family === undefined) {
2989 return type;
2990 }
2991 // Use the latest known implementation.
2992 return family.current;
2993 }
2994}
2995
2996function resolveClassForHotReloading(type) {
2997 // No implementation differences.
2998 return resolveFunctionForHotReloading(type);
2999}
3000
3001function resolveForwardRefForHotReloading(type) {
3002 {
3003 if (resolveFamily === null) {
3004 // Hot reloading is disabled.
3005 return type;
3006 }
3007 var family = resolveFamily(type);
3008 if (family === undefined) {
3009 // Check if we're dealing with a real forwardRef. Don't want to crash early.
3010 if (type !== null && type !== undefined && typeof type.render === 'function') {
3011 // ForwardRef is special because its resolved .type is an object,
3012 // but it's possible that we only have its inner render function in the map.
3013 // If that inner render function is different, we'll build a new forwardRef type.
3014 var currentRender = resolveFunctionForHotReloading(type.render);
3015 if (type.render !== currentRender) {
3016 var syntheticType = {
3017 $$typeof: REACT_FORWARD_REF_TYPE,
3018 render: currentRender
3019 };
3020 if (type.displayName !== undefined) {
3021 syntheticType.displayName = type.displayName;
3022 }
3023 return syntheticType;
3024 }
3025 }
3026 return type;
3027 }
3028 // Use the latest known implementation.
3029 return family.current;
3030 }
3031}
3032
3033function isCompatibleFamilyForHotReloading(fiber, element) {
3034 {
3035 if (resolveFamily === null) {
3036 // Hot reloading is disabled.
3037 return false;
3038 }
3039
3040 var prevType = fiber.elementType;
3041 var nextType = element.type;
3042
3043 // If we got here, we know types aren't === equal.
3044 var needsCompareFamilies = false;
3045
3046 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
3047
3048 switch (fiber.tag) {
3049 case ClassComponent:
3050 {
3051 if (typeof nextType === 'function') {
3052 needsCompareFamilies = true;
3053 }
3054 break;
3055 }
3056 case FunctionComponent:
3057 {
3058 if (typeof nextType === 'function') {
3059 needsCompareFamilies = true;
3060 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
3061 // We don't know the inner type yet.
3062 // We're going to assume that the lazy inner type is stable,
3063 // and so it is sufficient to avoid reconciling it away.
3064 // We're not going to unwrap or actually use the new lazy type.
3065 needsCompareFamilies = true;
3066 }
3067 break;
3068 }
3069 case ForwardRef:
3070 {
3071 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
3072 needsCompareFamilies = true;
3073 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
3074 needsCompareFamilies = true;
3075 }
3076 break;
3077 }
3078 case MemoComponent:
3079 case SimpleMemoComponent:
3080 {
3081 if ($$typeofNextType === REACT_MEMO_TYPE) {
3082 // TODO: if it was but can no longer be simple,
3083 // we shouldn't set this.
3084 needsCompareFamilies = true;
3085 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
3086 needsCompareFamilies = true;
3087 }
3088 break;
3089 }
3090 default:
3091 return false;
3092 }
3093
3094 // Check if both types have a family and it's the same one.
3095 if (needsCompareFamilies) {
3096 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
3097 // This means both of them need to be registered to preserve state.
3098 // If we unwrapped and compared the inner types for wrappers instead,
3099 // then we would risk falsely saying two separate memo(Foo)
3100 // calls are equivalent because they wrap the same Foo function.
3101 var prevFamily = resolveFamily(prevType);
3102 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
3103 return true;
3104 }
3105 }
3106 return false;
3107 }
3108}
3109
3110function markFailedErrorBoundaryForHotReloading(fiber) {
3111 {
3112 if (resolveFamily === null) {
3113 // Hot reloading is disabled.
3114 return;
3115 }
3116 if (typeof WeakSet !== 'function') {
3117 return;
3118 }
3119 if (failedBoundaries === null) {
3120 failedBoundaries = new WeakSet();
3121 }
3122 failedBoundaries.add(fiber);
3123 }
3124}
3125
3126var scheduleRefresh = function (root, update) {
3127 {
3128 if (resolveFamily === null) {
3129 // Hot reloading is disabled.
3130 return;
3131 }
3132 var _staleFamilies = update.staleFamilies,
3133 _updatedFamilies = update.updatedFamilies;
3134
3135 flushPassiveEffects();
3136 flushSync(function () {
3137 scheduleFibersWithFamiliesRecursively(root.current, _updatedFamilies, _staleFamilies);
3138 });
3139 }
3140};
3141
3142var scheduleRoot = function (root, element) {
3143 {
3144 if (root.context !== emptyContextObject) {
3145 // Super edge case: root has a legacy _renderSubtree context
3146 // but we don't know the parentComponent so we can't pass it.
3147 // Just ignore. We'll delete this with _renderSubtree code path later.
3148 return;
3149 }
3150 flushPassiveEffects();
3151 updateContainerAtExpirationTime(element, root, null, Sync, null);
3152 }
3153};
3154
3155function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
3156 {
3157 var alternate = fiber.alternate,
3158 child = fiber.child,
3159 sibling = fiber.sibling,
3160 tag = fiber.tag,
3161 type = fiber.type;
3162
3163
3164 var candidateType = null;
3165 switch (tag) {
3166 case FunctionComponent:
3167 case SimpleMemoComponent:
3168 case ClassComponent:
3169 candidateType = type;
3170 break;
3171 case ForwardRef:
3172 candidateType = type.render;
3173 break;
3174 default:
3175 break;
3176 }
3177
3178 if (resolveFamily === null) {
3179 throw new Error('Expected resolveFamily to be set during hot reload.');
3180 }
3181
3182 var needsRender = false;
3183 var needsRemount = false;
3184 if (candidateType !== null) {
3185 var family = resolveFamily(candidateType);
3186 if (family !== undefined) {
3187 if (staleFamilies.has(family)) {
3188 needsRemount = true;
3189 } else if (updatedFamilies.has(family)) {
3190 needsRender = true;
3191 }
3192 }
3193 }
3194 if (failedBoundaries !== null) {
3195 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
3196 needsRemount = true;
3197 }
3198 }
3199
3200 if (needsRemount) {
3201 fiber._debugNeedsRemount = true;
3202 }
3203 if (needsRemount || needsRender) {
3204 scheduleWork(fiber, Sync);
3205 }
3206 if (child !== null && !needsRemount) {
3207 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
3208 }
3209 if (sibling !== null) {
3210 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
3211 }
3212 }
3213}
3214
3215var findHostInstancesForRefresh = function (root, families) {
3216 {
3217 var hostInstances = new Set();
3218 var types = new Set(families.map(function (family) {
3219 return family.current;
3220 }));
3221 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
3222 return hostInstances;
3223 }
3224};
3225
3226function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
3227 {
3228 var child = fiber.child,
3229 sibling = fiber.sibling,
3230 tag = fiber.tag,
3231 type = fiber.type;
3232
3233
3234 var candidateType = null;
3235 switch (tag) {
3236 case FunctionComponent:
3237 case SimpleMemoComponent:
3238 case ClassComponent:
3239 candidateType = type;
3240 break;
3241 case ForwardRef:
3242 candidateType = type.render;
3243 break;
3244 default:
3245 break;
3246 }
3247
3248 var didMatch = false;
3249 if (candidateType !== null) {
3250 if (types.has(candidateType)) {
3251 didMatch = true;
3252 }
3253 }
3254
3255 if (didMatch) {
3256 // We have a match. This only drills down to the closest host components.
3257 // There's no need to search deeper because for the purpose of giving
3258 // visual feedback, "flashing" outermost parent rectangles is sufficient.
3259 findHostInstancesForFiberShallowly(fiber, hostInstances);
3260 } else {
3261 // If there's no match, maybe there will be one further down in the child tree.
3262 if (child !== null) {
3263 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
3264 }
3265 }
3266
3267 if (sibling !== null) {
3268 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
3269 }
3270 }
3271}
3272
3273function findHostInstancesForFiberShallowly(fiber, hostInstances) {
3274 {
3275 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
3276 if (foundHostInstances) {
3277 return;
3278 }
3279 // If we didn't find any host children, fallback to closest host parent.
3280 var node = fiber;
3281 while (true) {
3282 switch (node.tag) {
3283 case HostComponent:
3284 hostInstances.add(node.stateNode);
3285 return;
3286 case HostPortal:
3287 hostInstances.add(node.stateNode.containerInfo);
3288 return;
3289 case HostRoot:
3290 hostInstances.add(node.stateNode.containerInfo);
3291 return;
3292 }
3293 if (node.return === null) {
3294 throw new Error('Expected to reach root first.');
3295 }
3296 node = node.return;
3297 }
3298 }
3299}
3300
3301function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
3302 {
3303 var node = fiber;
3304 var foundHostInstances = false;
3305 while (true) {
3306 if (node.tag === HostComponent) {
3307 // We got a match.
3308 foundHostInstances = true;
3309 hostInstances.add(node.stateNode);
3310 // There may still be more, so keep searching.
3311 } else if (node.child !== null) {
3312 node.child.return = node;
3313 node = node.child;
3314 continue;
3315 }
3316 if (node === fiber) {
3317 return foundHostInstances;
3318 }
3319 while (node.sibling === null) {
3320 if (node.return === null || node.return === fiber) {
3321 return foundHostInstances;
3322 }
3323 node = node.return;
3324 }
3325 node.sibling.return = node.return;
3326 node = node.sibling;
3327 }
3328 }
3329 return false;
3330}
3331
3332function resolveDefaultProps(Component, baseProps) {
3333 if (Component && Component.defaultProps) {
3334 // Resolve default props. Taken from ReactElement
3335 var props = _assign({}, baseProps);
3336 var defaultProps = Component.defaultProps;
3337 for (var propName in defaultProps) {
3338 if (props[propName] === undefined) {
3339 props[propName] = defaultProps[propName];
3340 }
3341 }
3342 return props;
3343 }
3344 return baseProps;
3345}
3346
3347function readLazyComponentType(lazyComponent) {
3348 var status = lazyComponent._status;
3349 var result = lazyComponent._result;
3350 switch (status) {
3351 case Resolved:
3352 {
3353 var Component = result;
3354 return Component;
3355 }
3356 case Rejected:
3357 {
3358 var error = result;
3359 throw error;
3360 }
3361 case Pending:
3362 {
3363 var thenable = result;
3364 throw thenable;
3365 }
3366 default:
3367 {
3368 lazyComponent._status = Pending;
3369 var ctor = lazyComponent._ctor;
3370 var _thenable = ctor();
3371 _thenable.then(function (moduleObject) {
3372 if (lazyComponent._status === Pending) {
3373 var defaultExport = moduleObject.default;
3374 {
3375 if (defaultExport === undefined) {
3376 warning$1(false, 'lazy: Expected the result of a dynamic import() call. ' + 'Instead received: %s\n\nYour code should look like: \n ' + "const MyComponent = lazy(() => import('./MyComponent'))", moduleObject);
3377 }
3378 }
3379 lazyComponent._status = Resolved;
3380 lazyComponent._result = defaultExport;
3381 }
3382 }, function (error) {
3383 if (lazyComponent._status === Pending) {
3384 lazyComponent._status = Rejected;
3385 lazyComponent._result = error;
3386 }
3387 });
3388 // Handle synchronous thenables.
3389 switch (lazyComponent._status) {
3390 case Resolved:
3391 return lazyComponent._result;
3392 case Rejected:
3393 throw lazyComponent._result;
3394 }
3395 lazyComponent._result = _thenable;
3396 throw _thenable;
3397 }
3398 }
3399}
3400
3401var valueCursor = createCursor(null);
3402
3403var rendererSigil = void 0;
3404{
3405 // Use this to detect multiple renderers using the same context
3406 rendererSigil = {};
3407}
3408
3409var currentlyRenderingFiber = null;
3410var lastContextDependency = null;
3411var lastContextWithAllBitsObserved = null;
3412
3413var isDisallowedContextReadInDEV = false;
3414
3415function resetContextDependencies() {
3416 // This is called right before React yields execution, to ensure `readContext`
3417 // cannot be called outside the render phase.
3418 currentlyRenderingFiber = null;
3419 lastContextDependency = null;
3420 lastContextWithAllBitsObserved = null;
3421 {
3422 isDisallowedContextReadInDEV = false;
3423 }
3424}
3425
3426function enterDisallowedContextReadInDEV() {
3427 {
3428 isDisallowedContextReadInDEV = true;
3429 }
3430}
3431
3432function exitDisallowedContextReadInDEV() {
3433 {
3434 isDisallowedContextReadInDEV = false;
3435 }
3436}
3437
3438function pushProvider(providerFiber, nextValue) {
3439 var context = providerFiber.type._context;
3440
3441 if (isPrimaryRenderer) {
3442 push(valueCursor, context._currentValue, providerFiber);
3443
3444 context._currentValue = nextValue;
3445 {
3446 !(context._currentRenderer === undefined || context._currentRenderer === null || context._currentRenderer === rendererSigil) ? warningWithoutStack$1(false, 'Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.') : void 0;
3447 context._currentRenderer = rendererSigil;
3448 }
3449 } else {
3450 push(valueCursor, context._currentValue2, providerFiber);
3451
3452 context._currentValue2 = nextValue;
3453 {
3454 !(context._currentRenderer2 === undefined || context._currentRenderer2 === null || context._currentRenderer2 === rendererSigil) ? warningWithoutStack$1(false, 'Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.') : void 0;
3455 context._currentRenderer2 = rendererSigil;
3456 }
3457 }
3458}
3459
3460function popProvider(providerFiber) {
3461 var currentValue = valueCursor.current;
3462
3463 pop(valueCursor, providerFiber);
3464
3465 var context = providerFiber.type._context;
3466 if (isPrimaryRenderer) {
3467 context._currentValue = currentValue;
3468 } else {
3469 context._currentValue2 = currentValue;
3470 }
3471}
3472
3473function calculateChangedBits(context, newValue, oldValue) {
3474 if (is(oldValue, newValue)) {
3475 // No change
3476 return 0;
3477 } else {
3478 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
3479
3480 {
3481 !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0;
3482 }
3483 return changedBits | 0;
3484 }
3485}
3486
3487function scheduleWorkOnParentPath(parent, renderExpirationTime) {
3488 // Update the child expiration time of all the ancestors, including
3489 // the alternates.
3490 var node = parent;
3491 while (node !== null) {
3492 var alternate = node.alternate;
3493 if (node.childExpirationTime < renderExpirationTime) {
3494 node.childExpirationTime = renderExpirationTime;
3495 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
3496 alternate.childExpirationTime = renderExpirationTime;
3497 }
3498 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
3499 alternate.childExpirationTime = renderExpirationTime;
3500 } else {
3501 // Neither alternate was updated, which means the rest of the
3502 // ancestor path already has sufficient priority.
3503 break;
3504 }
3505 node = node.return;
3506 }
3507}
3508
3509function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
3510 var fiber = workInProgress.child;
3511 if (fiber !== null) {
3512 // Set the return pointer of the child to the work-in-progress fiber.
3513 fiber.return = workInProgress;
3514 }
3515 while (fiber !== null) {
3516 var nextFiber = void 0;
3517
3518 // Visit this fiber.
3519 var list = fiber.dependencies;
3520 if (list !== null) {
3521 nextFiber = fiber.child;
3522
3523 var dependency = list.firstContext;
3524 while (dependency !== null) {
3525 // Check if the context matches.
3526 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
3527 // Match! Schedule an update on this fiber.
3528
3529 if (fiber.tag === ClassComponent) {
3530 // Schedule a force update on the work-in-progress.
3531 var update = createUpdate(renderExpirationTime, null);
3532 update.tag = ForceUpdate;
3533 // TODO: Because we don't have a work-in-progress, this will add the
3534 // update to the current fiber, too, which means it will persist even if
3535 // this render is thrown away. Since it's a race condition, not sure it's
3536 // worth fixing.
3537 enqueueUpdate(fiber, update);
3538 }
3539
3540 if (fiber.expirationTime < renderExpirationTime) {
3541 fiber.expirationTime = renderExpirationTime;
3542 }
3543 var alternate = fiber.alternate;
3544 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
3545 alternate.expirationTime = renderExpirationTime;
3546 }
3547
3548 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
3549
3550 // Mark the expiration time on the list, too.
3551 if (list.expirationTime < renderExpirationTime) {
3552 list.expirationTime = renderExpirationTime;
3553 }
3554
3555 // Since we already found a match, we can stop traversing the
3556 // dependency list.
3557 break;
3558 }
3559 dependency = dependency.next;
3560 }
3561 } else if (fiber.tag === ContextProvider) {
3562 // Don't scan deeper if this is a matching provider
3563 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
3564 } else if (enableSuspenseServerRenderer && fiber.tag === DehydratedSuspenseComponent) {
3565 // If a dehydrated suspense component is in this subtree, we don't know
3566 // if it will have any context consumers in it. The best we can do is
3567 // mark it as having updates on its children.
3568 if (fiber.expirationTime < renderExpirationTime) {
3569 fiber.expirationTime = renderExpirationTime;
3570 }
3571 var _alternate = fiber.alternate;
3572 if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) {
3573 _alternate.expirationTime = renderExpirationTime;
3574 }
3575 // This is intentionally passing this fiber as the parent
3576 // because we want to schedule this fiber as having work
3577 // on its children. We'll use the childExpirationTime on
3578 // this fiber to indicate that a context has changed.
3579 scheduleWorkOnParentPath(fiber, renderExpirationTime);
3580 nextFiber = fiber.sibling;
3581 } else {
3582 // Traverse down.
3583 nextFiber = fiber.child;
3584 }
3585
3586 if (nextFiber !== null) {
3587 // Set the return pointer of the child to the work-in-progress fiber.
3588 nextFiber.return = fiber;
3589 } else {
3590 // No child. Traverse to next sibling.
3591 nextFiber = fiber;
3592 while (nextFiber !== null) {
3593 if (nextFiber === workInProgress) {
3594 // We're back to the root of this subtree. Exit.
3595 nextFiber = null;
3596 break;
3597 }
3598 var sibling = nextFiber.sibling;
3599 if (sibling !== null) {
3600 // Set the return pointer of the sibling to the work-in-progress fiber.
3601 sibling.return = nextFiber.return;
3602 nextFiber = sibling;
3603 break;
3604 }
3605 // No more siblings. Traverse up.
3606 nextFiber = nextFiber.return;
3607 }
3608 }
3609 fiber = nextFiber;
3610 }
3611}
3612
3613function prepareToReadContext(workInProgress, renderExpirationTime) {
3614 currentlyRenderingFiber = workInProgress;
3615 lastContextDependency = null;
3616 lastContextWithAllBitsObserved = null;
3617
3618 var dependencies = workInProgress.dependencies;
3619 if (dependencies !== null) {
3620 var firstContext = dependencies.firstContext;
3621 if (firstContext !== null) {
3622 if (dependencies.expirationTime >= renderExpirationTime) {
3623 // Context list has a pending update. Mark that this fiber performed work.
3624 markWorkInProgressReceivedUpdate();
3625 }
3626 // Reset the work-in-progress list
3627 dependencies.firstContext = null;
3628 }
3629 }
3630}
3631
3632function readContext(context, observedBits) {
3633 {
3634 // This warning would fire if you read context inside a Hook like useMemo.
3635 // Unlike the class check below, it's not enforced in production for perf.
3636 !!isDisallowedContextReadInDEV ? warning$1(false, 'Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().') : void 0;
3637 }
3638
3639 if (lastContextWithAllBitsObserved === context) {
3640 // Nothing to do. We already observe everything in this context.
3641 } else if (observedBits === false || observedBits === 0) {
3642 // Do not observe any updates.
3643 } else {
3644 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types.
3645 if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) {
3646 // Observe all updates.
3647 lastContextWithAllBitsObserved = context;
3648 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
3649 } else {
3650 resolvedObservedBits = observedBits;
3651 }
3652
3653 var contextItem = {
3654 context: context,
3655 observedBits: resolvedObservedBits,
3656 next: null
3657 };
3658
3659 if (lastContextDependency === null) {
3660 (function () {
3661 if (!(currentlyRenderingFiber !== null)) {
3662 {
3663 throw ReactError(Error('Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo().'));
3664 }
3665 }
3666 })();
3667
3668 // This is the first dependency for this component. Create a new list.
3669 lastContextDependency = contextItem;
3670 currentlyRenderingFiber.dependencies = {
3671 expirationTime: NoWork,
3672 firstContext: contextItem,
3673 responders: null
3674 };
3675 } else {
3676 // Append a new context item.
3677 lastContextDependency = lastContextDependency.next = contextItem;
3678 }
3679 }
3680 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
3681}
3682
3683// UpdateQueue is a linked list of prioritized updates.
3684//
3685// Like fibers, update queues come in pairs: a current queue, which represents
3686// the visible state of the screen, and a work-in-progress queue, which can be
3687// mutated and processed asynchronously before it is committed — a form of
3688// double buffering. If a work-in-progress render is discarded before finishing,
3689// we create a new work-in-progress by cloning the current queue.
3690//
3691// Both queues share a persistent, singly-linked list structure. To schedule an
3692// update, we append it to the end of both queues. Each queue maintains a
3693// pointer to first update in the persistent list that hasn't been processed.
3694// The work-in-progress pointer always has a position equal to or greater than
3695// the current queue, since we always work on that one. The current queue's
3696// pointer is only updated during the commit phase, when we swap in the
3697// work-in-progress.
3698//
3699// For example:
3700//
3701// Current pointer: A - B - C - D - E - F
3702// Work-in-progress pointer: D - E - F
3703// ^
3704// The work-in-progress queue has
3705// processed more updates than current.
3706//
3707// The reason we append to both queues is because otherwise we might drop
3708// updates without ever processing them. For example, if we only add updates to
3709// the work-in-progress queue, some updates could be lost whenever a work-in
3710// -progress render restarts by cloning from current. Similarly, if we only add
3711// updates to the current queue, the updates will be lost whenever an already
3712// in-progress queue commits and swaps with the current queue. However, by
3713// adding to both queues, we guarantee that the update will be part of the next
3714// work-in-progress. (And because the work-in-progress queue becomes the
3715// current queue once it commits, there's no danger of applying the same
3716// update twice.)
3717//
3718// Prioritization
3719// --------------
3720//
3721// Updates are not sorted by priority, but by insertion; new updates are always
3722// appended to the end of the list.
3723//
3724// The priority is still important, though. When processing the update queue
3725// during the render phase, only the updates with sufficient priority are
3726// included in the result. If we skip an update because it has insufficient
3727// priority, it remains in the queue to be processed later, during a lower
3728// priority render. Crucially, all updates subsequent to a skipped update also
3729// remain in the queue *regardless of their priority*. That means high priority
3730// updates are sometimes processed twice, at two separate priorities. We also
3731// keep track of a base state, that represents the state before the first
3732// update in the queue is applied.
3733//
3734// For example:
3735//
3736// Given a base state of '', and the following queue of updates
3737//
3738// A1 - B2 - C1 - D2
3739//
3740// where the number indicates the priority, and the update is applied to the
3741// previous state by appending a letter, React will process these updates as
3742// two separate renders, one per distinct priority level:
3743//
3744// First render, at priority 1:
3745// Base state: ''
3746// Updates: [A1, C1]
3747// Result state: 'AC'
3748//
3749// Second render, at priority 2:
3750// Base state: 'A' <- The base state does not include C1,
3751// because B2 was skipped.
3752// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
3753// Result state: 'ABCD'
3754//
3755// Because we process updates in insertion order, and rebase high priority
3756// updates when preceding updates are skipped, the final result is deterministic
3757// regardless of priority. Intermediate state may vary according to system
3758// resources, but the final state is always the same.
3759
3760var UpdateState = 0;
3761var ReplaceState = 1;
3762var ForceUpdate = 2;
3763var CaptureUpdate = 3;
3764
3765// Global state that is reset at the beginning of calling `processUpdateQueue`.
3766// It should only be read right after calling `processUpdateQueue`, via
3767// `checkHasForceUpdateAfterProcessing`.
3768var hasForceUpdate = false;
3769
3770var didWarnUpdateInsideUpdate = void 0;
3771var currentlyProcessingQueue = void 0;
3772
3773{
3774 didWarnUpdateInsideUpdate = false;
3775 currentlyProcessingQueue = null;
3776
3777}
3778
3779function createUpdateQueue(baseState) {
3780 var queue = {
3781 baseState: baseState,
3782 firstUpdate: null,
3783 lastUpdate: null,
3784 firstCapturedUpdate: null,
3785 lastCapturedUpdate: null,
3786 firstEffect: null,
3787 lastEffect: null,
3788 firstCapturedEffect: null,
3789 lastCapturedEffect: null
3790 };
3791 return queue;
3792}
3793
3794function cloneUpdateQueue(currentQueue) {
3795 var queue = {
3796 baseState: currentQueue.baseState,
3797 firstUpdate: currentQueue.firstUpdate,
3798 lastUpdate: currentQueue.lastUpdate,
3799
3800 // TODO: With resuming, if we bail out and resuse the child tree, we should
3801 // keep these effects.
3802 firstCapturedUpdate: null,
3803 lastCapturedUpdate: null,
3804
3805 firstEffect: null,
3806 lastEffect: null,
3807
3808 firstCapturedEffect: null,
3809 lastCapturedEffect: null
3810 };
3811 return queue;
3812}
3813
3814function createUpdate(expirationTime, suspenseConfig) {
3815 var update = {
3816 expirationTime: expirationTime,
3817 suspenseConfig: suspenseConfig,
3818
3819 tag: UpdateState,
3820 payload: null,
3821 callback: null,
3822
3823 next: null,
3824 nextEffect: null
3825 };
3826 {
3827 update.priority = getCurrentPriorityLevel();
3828 }
3829 return update;
3830}
3831
3832function appendUpdateToQueue(queue, update) {
3833 // Append the update to the end of the list.
3834 if (queue.lastUpdate === null) {
3835 // Queue is empty
3836 queue.firstUpdate = queue.lastUpdate = update;
3837 } else {
3838 queue.lastUpdate.next = update;
3839 queue.lastUpdate = update;
3840 }
3841}
3842
3843function enqueueUpdate(fiber, update) {
3844 // Update queues are created lazily.
3845 var alternate = fiber.alternate;
3846 var queue1 = void 0;
3847 var queue2 = void 0;
3848 if (alternate === null) {
3849 // There's only one fiber.
3850 queue1 = fiber.updateQueue;
3851 queue2 = null;
3852 if (queue1 === null) {
3853 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
3854 }
3855 } else {
3856 // There are two owners.
3857 queue1 = fiber.updateQueue;
3858 queue2 = alternate.updateQueue;
3859 if (queue1 === null) {
3860 if (queue2 === null) {
3861 // Neither fiber has an update queue. Create new ones.
3862 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
3863 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
3864 } else {
3865 // Only one fiber has an update queue. Clone to create a new one.
3866 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
3867 }
3868 } else {
3869 if (queue2 === null) {
3870 // Only one fiber has an update queue. Clone to create a new one.
3871 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
3872 } else {
3873 // Both owners have an update queue.
3874 }
3875 }
3876 }
3877 if (queue2 === null || queue1 === queue2) {
3878 // There's only a single queue.
3879 appendUpdateToQueue(queue1, update);
3880 } else {
3881 // There are two queues. We need to append the update to both queues,
3882 // while accounting for the persistent structure of the list — we don't
3883 // want the same update to be added multiple times.
3884 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
3885 // One of the queues is not empty. We must add the update to both queues.
3886 appendUpdateToQueue(queue1, update);
3887 appendUpdateToQueue(queue2, update);
3888 } else {
3889 // Both queues are non-empty. The last update is the same in both lists,
3890 // because of structural sharing. So, only append to one of the lists.
3891 appendUpdateToQueue(queue1, update);
3892 // But we still need to update the `lastUpdate` pointer of queue2.
3893 queue2.lastUpdate = update;
3894 }
3895 }
3896
3897 {
3898 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
3899 warningWithoutStack$1(false, 'An update (setState, replaceState, or forceUpdate) was scheduled ' + 'from inside an update function. Update functions should be pure, ' + 'with zero side-effects. Consider using componentDidUpdate or a ' + 'callback.');
3900 didWarnUpdateInsideUpdate = true;
3901 }
3902 }
3903}
3904
3905function enqueueCapturedUpdate(workInProgress, update) {
3906 // Captured updates go into a separate list, and only on the work-in-
3907 // progress queue.
3908 var workInProgressQueue = workInProgress.updateQueue;
3909 if (workInProgressQueue === null) {
3910 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
3911 } else {
3912 // TODO: I put this here rather than createWorkInProgress so that we don't
3913 // clone the queue unnecessarily. There's probably a better way to
3914 // structure this.
3915 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
3916 }
3917
3918 // Append the update to the end of the list.
3919 if (workInProgressQueue.lastCapturedUpdate === null) {
3920 // This is the first render phase update
3921 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
3922 } else {
3923 workInProgressQueue.lastCapturedUpdate.next = update;
3924 workInProgressQueue.lastCapturedUpdate = update;
3925 }
3926}
3927
3928function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
3929 var current = workInProgress.alternate;
3930 if (current !== null) {
3931 // If the work-in-progress queue is equal to the current queue,
3932 // we need to clone it first.
3933 if (queue === current.updateQueue) {
3934 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
3935 }
3936 }
3937 return queue;
3938}
3939
3940function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
3941 switch (update.tag) {
3942 case ReplaceState:
3943 {
3944 var _payload = update.payload;
3945 if (typeof _payload === 'function') {
3946 // Updater function
3947 {
3948 enterDisallowedContextReadInDEV();
3949 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
3950 _payload.call(instance, prevState, nextProps);
3951 }
3952 }
3953 var nextState = _payload.call(instance, prevState, nextProps);
3954 {
3955 exitDisallowedContextReadInDEV();
3956 }
3957 return nextState;
3958 }
3959 // State object
3960 return _payload;
3961 }
3962 case CaptureUpdate:
3963 {
3964 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
3965 }
3966 // Intentional fallthrough
3967 case UpdateState:
3968 {
3969 var _payload2 = update.payload;
3970 var partialState = void 0;
3971 if (typeof _payload2 === 'function') {
3972 // Updater function
3973 {
3974 enterDisallowedContextReadInDEV();
3975 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
3976 _payload2.call(instance, prevState, nextProps);
3977 }
3978 }
3979 partialState = _payload2.call(instance, prevState, nextProps);
3980 {
3981 exitDisallowedContextReadInDEV();
3982 }
3983 } else {
3984 // Partial state object
3985 partialState = _payload2;
3986 }
3987 if (partialState === null || partialState === undefined) {
3988 // Null and undefined are treated as no-ops.
3989 return prevState;
3990 }
3991 // Merge the partial state and the previous state.
3992 return _assign({}, prevState, partialState);
3993 }
3994 case ForceUpdate:
3995 {
3996 hasForceUpdate = true;
3997 return prevState;
3998 }
3999 }
4000 return prevState;
4001}
4002
4003function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
4004 hasForceUpdate = false;
4005
4006 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
4007
4008 {
4009 currentlyProcessingQueue = queue;
4010 }
4011
4012 // These values may change as we process the queue.
4013 var newBaseState = queue.baseState;
4014 var newFirstUpdate = null;
4015 var newExpirationTime = NoWork;
4016
4017 // Iterate through the list of updates to compute the result.
4018 var update = queue.firstUpdate;
4019 var resultState = newBaseState;
4020 while (update !== null) {
4021 var updateExpirationTime = update.expirationTime;
4022 if (updateExpirationTime < renderExpirationTime) {
4023 // This update does not have sufficient priority. Skip it.
4024 if (newFirstUpdate === null) {
4025 // This is the first skipped update. It will be the first update in
4026 // the new list.
4027 newFirstUpdate = update;
4028 // Since this is the first update that was skipped, the current result
4029 // is the new base state.
4030 newBaseState = resultState;
4031 }
4032 // Since this update will remain in the list, update the remaining
4033 // expiration time.
4034 if (newExpirationTime < updateExpirationTime) {
4035 newExpirationTime = updateExpirationTime;
4036 }
4037 } else {
4038 // This update does have sufficient priority.
4039
4040 // Mark the event time of this update as relevant to this render pass.
4041 // TODO: This should ideally use the true event time of this update rather than
4042 // its priority which is a derived and not reverseable value.
4043 // TODO: We should skip this update if it was already committed but currently
4044 // we have no way of detecting the difference between a committed and suspended
4045 // update here.
4046 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig);
4047
4048 // Process it and compute a new result.
4049 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
4050 var _callback = update.callback;
4051 if (_callback !== null) {
4052 workInProgress.effectTag |= Callback;
4053 // Set this to null, in case it was mutated during an aborted render.
4054 update.nextEffect = null;
4055 if (queue.lastEffect === null) {
4056 queue.firstEffect = queue.lastEffect = update;
4057 } else {
4058 queue.lastEffect.nextEffect = update;
4059 queue.lastEffect = update;
4060 }
4061 }
4062 }
4063 // Continue to the next update.
4064 update = update.next;
4065 }
4066
4067 // Separately, iterate though the list of captured updates.
4068 var newFirstCapturedUpdate = null;
4069 update = queue.firstCapturedUpdate;
4070 while (update !== null) {
4071 var _updateExpirationTime = update.expirationTime;
4072 if (_updateExpirationTime < renderExpirationTime) {
4073 // This update does not have sufficient priority. Skip it.
4074 if (newFirstCapturedUpdate === null) {
4075 // This is the first skipped captured update. It will be the first
4076 // update in the new list.
4077 newFirstCapturedUpdate = update;
4078 // If this is the first update that was skipped, the current result is
4079 // the new base state.
4080 if (newFirstUpdate === null) {
4081 newBaseState = resultState;
4082 }
4083 }
4084 // Since this update will remain in the list, update the remaining
4085 // expiration time.
4086 if (newExpirationTime < _updateExpirationTime) {
4087 newExpirationTime = _updateExpirationTime;
4088 }
4089 } else {
4090 // This update does have sufficient priority. Process it and compute
4091 // a new result.
4092 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
4093 var _callback2 = update.callback;
4094 if (_callback2 !== null) {
4095 workInProgress.effectTag |= Callback;
4096 // Set this to null, in case it was mutated during an aborted render.
4097 update.nextEffect = null;
4098 if (queue.lastCapturedEffect === null) {
4099 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
4100 } else {
4101 queue.lastCapturedEffect.nextEffect = update;
4102 queue.lastCapturedEffect = update;
4103 }
4104 }
4105 }
4106 update = update.next;
4107 }
4108
4109 if (newFirstUpdate === null) {
4110 queue.lastUpdate = null;
4111 }
4112 if (newFirstCapturedUpdate === null) {
4113 queue.lastCapturedUpdate = null;
4114 } else {
4115 workInProgress.effectTag |= Callback;
4116 }
4117 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
4118 // We processed every update, without skipping. That means the new base
4119 // state is the same as the result state.
4120 newBaseState = resultState;
4121 }
4122
4123 queue.baseState = newBaseState;
4124 queue.firstUpdate = newFirstUpdate;
4125 queue.firstCapturedUpdate = newFirstCapturedUpdate;
4126
4127 // Set the remaining expiration time to be whatever is remaining in the queue.
4128 // This should be fine because the only two other things that contribute to
4129 // expiration time are props and context. We're already in the middle of the
4130 // begin phase by the time we start processing the queue, so we've already
4131 // dealt with the props. Context in components that specify
4132 // shouldComponentUpdate is tricky; but we'll have to account for
4133 // that regardless.
4134 workInProgress.expirationTime = newExpirationTime;
4135 workInProgress.memoizedState = resultState;
4136
4137 {
4138 currentlyProcessingQueue = null;
4139 }
4140}
4141
4142function callCallback(callback, context) {
4143 (function () {
4144 if (!(typeof callback === 'function')) {
4145 {
4146 throw ReactError(Error('Invalid argument passed as callback. Expected a function. Instead received: ' + callback));
4147 }
4148 }
4149 })();
4150 callback.call(context);
4151}
4152
4153function resetHasForceUpdateBeforeProcessing() {
4154 hasForceUpdate = false;
4155}
4156
4157function checkHasForceUpdateAfterProcessing() {
4158 return hasForceUpdate;
4159}
4160
4161function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
4162 // If the finished render included captured updates, and there are still
4163 // lower priority updates left over, we need to keep the captured updates
4164 // in the queue so that they are rebased and not dropped once we process the
4165 // queue again at the lower priority.
4166 if (finishedQueue.firstCapturedUpdate !== null) {
4167 // Join the captured update list to the end of the normal list.
4168 if (finishedQueue.lastUpdate !== null) {
4169 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
4170 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
4171 }
4172 // Clear the list of captured updates.
4173 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
4174 }
4175
4176 // Commit the effects
4177 commitUpdateEffects(finishedQueue.firstEffect, instance);
4178 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
4179
4180 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
4181 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
4182}
4183
4184function commitUpdateEffects(effect, instance) {
4185 while (effect !== null) {
4186 var _callback3 = effect.callback;
4187 if (_callback3 !== null) {
4188 effect.callback = null;
4189 callCallback(_callback3, instance);
4190 }
4191 effect = effect.nextEffect;
4192 }
4193}
4194
4195var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
4196
4197
4198function requestCurrentSuspenseConfig() {
4199 return ReactCurrentBatchConfig.suspense;
4200}
4201
4202var fakeInternalInstance = {};
4203var isArray$1 = Array.isArray;
4204
4205// React.Component uses a shared frozen object by default.
4206// We'll use it to determine whether we need to initialize legacy refs.
4207var emptyRefsObject = new React.Component().refs;
4208
4209var didWarnAboutStateAssignmentForComponent = void 0;
4210var didWarnAboutUninitializedState = void 0;
4211var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0;
4212var didWarnAboutLegacyLifecyclesAndDerivedState = void 0;
4213var didWarnAboutUndefinedDerivedState = void 0;
4214var warnOnUndefinedDerivedState = void 0;
4215var warnOnInvalidCallback = void 0;
4216var didWarnAboutDirectlyAssigningPropsToState = void 0;
4217var didWarnAboutContextTypeAndContextTypes = void 0;
4218var didWarnAboutInvalidateContextType = void 0;
4219
4220{
4221 didWarnAboutStateAssignmentForComponent = new Set();
4222 didWarnAboutUninitializedState = new Set();
4223 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
4224 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
4225 didWarnAboutDirectlyAssigningPropsToState = new Set();
4226 didWarnAboutUndefinedDerivedState = new Set();
4227 didWarnAboutContextTypeAndContextTypes = new Set();
4228 didWarnAboutInvalidateContextType = new Set();
4229
4230 var didWarnOnInvalidCallback = new Set();
4231
4232 warnOnInvalidCallback = function (callback, callerName) {
4233 if (callback === null || typeof callback === 'function') {
4234 return;
4235 }
4236 var key = callerName + '_' + callback;
4237 if (!didWarnOnInvalidCallback.has(key)) {
4238 didWarnOnInvalidCallback.add(key);
4239 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
4240 }
4241 };
4242
4243 warnOnUndefinedDerivedState = function (type, partialState) {
4244 if (partialState === undefined) {
4245 var componentName = getComponentName(type) || 'Component';
4246 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
4247 didWarnAboutUndefinedDerivedState.add(componentName);
4248 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
4249 }
4250 }
4251 };
4252
4253 // This is so gross but it's at least non-critical and can be removed if
4254 // it causes problems. This is meant to give a nicer error message for
4255 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
4256 // ...)) which otherwise throws a "_processChildContext is not a function"
4257 // exception.
4258 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
4259 enumerable: false,
4260 value: function () {
4261 (function () {
4262 {
4263 {
4264 throw ReactError(Error('_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn\'t supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal).'));
4265 }
4266 }
4267 })();
4268 }
4269 });
4270 Object.freeze(fakeInternalInstance);
4271}
4272
4273function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
4274 var prevState = workInProgress.memoizedState;
4275
4276 {
4277 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
4278 // Invoke the function an extra time to help detect side-effects.
4279 getDerivedStateFromProps(nextProps, prevState);
4280 }
4281 }
4282
4283 var partialState = getDerivedStateFromProps(nextProps, prevState);
4284
4285 {
4286 warnOnUndefinedDerivedState(ctor, partialState);
4287 }
4288 // Merge the partial state and the previous state.
4289 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
4290 workInProgress.memoizedState = memoizedState;
4291
4292 // Once the update queue is empty, persist the derived state onto the
4293 // base state.
4294 var updateQueue = workInProgress.updateQueue;
4295 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
4296 updateQueue.baseState = memoizedState;
4297 }
4298}
4299
4300var classComponentUpdater = {
4301 isMounted: isMounted,
4302 enqueueSetState: function (inst, payload, callback) {
4303 var fiber = get(inst);
4304 var currentTime = requestCurrentTime();
4305 var suspenseConfig = requestCurrentSuspenseConfig();
4306 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
4307
4308 var update = createUpdate(expirationTime, suspenseConfig);
4309 update.payload = payload;
4310 if (callback !== undefined && callback !== null) {
4311 {
4312 warnOnInvalidCallback(callback, 'setState');
4313 }
4314 update.callback = callback;
4315 }
4316
4317 if (revertPassiveEffectsChange) {
4318 flushPassiveEffects();
4319 }
4320 enqueueUpdate(fiber, update);
4321 scheduleWork(fiber, expirationTime);
4322 },
4323 enqueueReplaceState: function (inst, payload, callback) {
4324 var fiber = get(inst);
4325 var currentTime = requestCurrentTime();
4326 var suspenseConfig = requestCurrentSuspenseConfig();
4327 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
4328
4329 var update = createUpdate(expirationTime, suspenseConfig);
4330 update.tag = ReplaceState;
4331 update.payload = payload;
4332
4333 if (callback !== undefined && callback !== null) {
4334 {
4335 warnOnInvalidCallback(callback, 'replaceState');
4336 }
4337 update.callback = callback;
4338 }
4339
4340 if (revertPassiveEffectsChange) {
4341 flushPassiveEffects();
4342 }
4343 enqueueUpdate(fiber, update);
4344 scheduleWork(fiber, expirationTime);
4345 },
4346 enqueueForceUpdate: function (inst, callback) {
4347 var fiber = get(inst);
4348 var currentTime = requestCurrentTime();
4349 var suspenseConfig = requestCurrentSuspenseConfig();
4350 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
4351
4352 var update = createUpdate(expirationTime, suspenseConfig);
4353 update.tag = ForceUpdate;
4354
4355 if (callback !== undefined && callback !== null) {
4356 {
4357 warnOnInvalidCallback(callback, 'forceUpdate');
4358 }
4359 update.callback = callback;
4360 }
4361
4362 if (revertPassiveEffectsChange) {
4363 flushPassiveEffects();
4364 }
4365 enqueueUpdate(fiber, update);
4366 scheduleWork(fiber, expirationTime);
4367 }
4368};
4369
4370function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
4371 var instance = workInProgress.stateNode;
4372 if (typeof instance.shouldComponentUpdate === 'function') {
4373 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
4374 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
4375 stopPhaseTimer();
4376
4377 {
4378 !(shouldUpdate !== undefined) ? warningWithoutStack$1(false, '%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentName(ctor) || 'Component') : void 0;
4379 }
4380
4381 return shouldUpdate;
4382 }
4383
4384 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
4385 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
4386 }
4387
4388 return true;
4389}
4390
4391function checkClassInstance(workInProgress, ctor, newProps) {
4392 var instance = workInProgress.stateNode;
4393 {
4394 var name = getComponentName(ctor) || 'Component';
4395 var renderPresent = instance.render;
4396
4397 if (!renderPresent) {
4398 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
4399 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
4400 } else {
4401 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
4402 }
4403 }
4404
4405 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
4406 !noGetInitialStateOnES6 ? warningWithoutStack$1(false, 'getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', name) : void 0;
4407 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
4408 !noGetDefaultPropsOnES6 ? warningWithoutStack$1(false, 'getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', name) : void 0;
4409 var noInstancePropTypes = !instance.propTypes;
4410 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
4411 var noInstanceContextType = !instance.contextType;
4412 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
4413
4414 if (disableLegacyContext) {
4415 if (ctor.childContextTypes) {
4416 warningWithoutStack$1(false, '%s uses the legacy childContextTypes API which is no longer supported. ' + 'Use React.createContext() instead.', name);
4417 }
4418 if (ctor.contextTypes) {
4419 warningWithoutStack$1(false, '%s uses the legacy contextTypes API which is no longer supported. ' + 'Use React.createContext() with static contextType instead.', name);
4420 }
4421 } else {
4422 var noInstanceContextTypes = !instance.contextTypes;
4423 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
4424
4425 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
4426 didWarnAboutContextTypeAndContextTypes.add(ctor);
4427 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
4428 }
4429 }
4430
4431 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
4432 !noComponentShouldUpdate ? warningWithoutStack$1(false, '%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', name) : void 0;
4433 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
4434 warningWithoutStack$1(false, '%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentName(ctor) || 'A pure component');
4435 }
4436 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
4437 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
4438 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
4439 !noComponentDidReceiveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidReceiveProps(). But there is no such lifecycle method. ' + 'If you meant to update the state in response to changing props, ' + 'use componentWillReceiveProps(). If you meant to fetch data or ' + 'run side-effects or mutations after React has updated the UI, use componentDidUpdate().', name) : void 0;
4440 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
4441 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
4442 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
4443 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
4444 var hasMutatedProps = instance.props !== newProps;
4445 !(instance.props === undefined || !hasMutatedProps) ? warningWithoutStack$1(false, '%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name) : void 0;
4446 var noInstanceDefaultProps = !instance.defaultProps;
4447 !noInstanceDefaultProps ? warningWithoutStack$1(false, 'Setting defaultProps as an instance property on %s is not supported and will be ignored.' + ' Instead, define defaultProps as a static property on %s.', name, name) : void 0;
4448
4449 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
4450 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
4451 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
4452 }
4453
4454 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
4455 !noInstanceGetDerivedStateFromProps ? warningWithoutStack$1(false, '%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name) : void 0;
4456 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
4457 !noInstanceGetDerivedStateFromCatch ? warningWithoutStack$1(false, '%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name) : void 0;
4458 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
4459 !noStaticGetSnapshotBeforeUpdate ? warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name) : void 0;
4460 var _state = instance.state;
4461 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
4462 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
4463 }
4464 if (typeof instance.getChildContext === 'function') {
4465 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
4466 }
4467 }
4468}
4469
4470function adoptClassInstance(workInProgress, instance) {
4471 instance.updater = classComponentUpdater;
4472 workInProgress.stateNode = instance;
4473 // The instance needs access to the fiber so that it can schedule updates
4474 set(instance, workInProgress);
4475 {
4476 instance._reactInternalInstance = fakeInternalInstance;
4477 }
4478}
4479
4480function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
4481 var isLegacyContextConsumer = false;
4482 var unmaskedContext = emptyContextObject;
4483 var context = emptyContextObject;
4484 var contextType = ctor.contextType;
4485
4486 {
4487 if ('contextType' in ctor) {
4488 var isValid =
4489 // Allow null for conditional declaration
4490 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
4491
4492 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
4493 didWarnAboutInvalidateContextType.add(ctor);
4494
4495 var addendum = '';
4496 if (contextType === undefined) {
4497 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.';
4498 } else if (typeof contextType !== 'object') {
4499 addendum = ' However, it is set to a ' + typeof contextType + '.';
4500 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
4501 addendum = ' Did you accidentally pass the Context.Provider instead?';
4502 } else if (contextType._context !== undefined) {
4503 // <Context.Consumer>
4504 addendum = ' Did you accidentally pass the Context.Consumer instead?';
4505 } else {
4506 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
4507 }
4508 warningWithoutStack$1(false, '%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
4509 }
4510 }
4511 }
4512
4513 if (typeof contextType === 'object' && contextType !== null) {
4514 context = readContext(contextType);
4515 } else if (!disableLegacyContext) {
4516 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4517 var contextTypes = ctor.contextTypes;
4518 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
4519 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
4520 }
4521
4522 // Instantiate twice to help detect side-effects.
4523 {
4524 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
4525 new ctor(props, context); // eslint-disable-line no-new
4526 }
4527 }
4528
4529 var instance = new ctor(props, context);
4530 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
4531 adoptClassInstance(workInProgress, instance);
4532
4533 {
4534 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
4535 var componentName = getComponentName(ctor) || 'Component';
4536 if (!didWarnAboutUninitializedState.has(componentName)) {
4537 didWarnAboutUninitializedState.add(componentName);
4538 warningWithoutStack$1(false, '`%s` uses `getDerivedStateFromProps` but its initial state is ' + '%s. This is not recommended. Instead, define the initial state by ' + 'assigning an object to `this.state` in the constructor of `%s`. ' + 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.', componentName, instance.state === null ? 'null' : 'undefined', componentName);
4539 }
4540 }
4541
4542 // If new component APIs are defined, "unsafe" lifecycles won't be called.
4543 // Warn about these lifecycles if they are present.
4544 // Don't warn about react-lifecycles-compat polyfilled methods though.
4545 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
4546 var foundWillMountName = null;
4547 var foundWillReceivePropsName = null;
4548 var foundWillUpdateName = null;
4549 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
4550 foundWillMountName = 'componentWillMount';
4551 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
4552 foundWillMountName = 'UNSAFE_componentWillMount';
4553 }
4554 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
4555 foundWillReceivePropsName = 'componentWillReceiveProps';
4556 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4557 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
4558 }
4559 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
4560 foundWillUpdateName = 'componentWillUpdate';
4561 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4562 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
4563 }
4564 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
4565 var _componentName = getComponentName(ctor) || 'Component';
4566 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
4567 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
4568 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
4569 warningWithoutStack$1(false, 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' + '%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n' + 'The above lifecycles should be removed. Learn more about this warning here:\n' + 'https://fb.me/react-async-component-lifecycle-hooks', _componentName, newApiName, foundWillMountName !== null ? '\n ' + foundWillMountName : '', foundWillReceivePropsName !== null ? '\n ' + foundWillReceivePropsName : '', foundWillUpdateName !== null ? '\n ' + foundWillUpdateName : '');
4570 }
4571 }
4572 }
4573 }
4574
4575 // Cache unmasked context so we can avoid recreating masked context unless necessary.
4576 // ReactFiberContext usually updates this cache but can't for newly-created instances.
4577 if (isLegacyContextConsumer) {
4578 cacheContext(workInProgress, unmaskedContext, context);
4579 }
4580
4581 return instance;
4582}
4583
4584function callComponentWillMount(workInProgress, instance) {
4585 startPhaseTimer(workInProgress, 'componentWillMount');
4586 var oldState = instance.state;
4587
4588 if (typeof instance.componentWillMount === 'function') {
4589 instance.componentWillMount();
4590 }
4591 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4592 instance.UNSAFE_componentWillMount();
4593 }
4594
4595 stopPhaseTimer();
4596
4597 if (oldState !== instance.state) {
4598 {
4599 warningWithoutStack$1(false, '%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentName(workInProgress.type) || 'Component');
4600 }
4601 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4602 }
4603}
4604
4605function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
4606 var oldState = instance.state;
4607 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
4608 if (typeof instance.componentWillReceiveProps === 'function') {
4609 instance.componentWillReceiveProps(newProps, nextContext);
4610 }
4611 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
4612 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
4613 }
4614 stopPhaseTimer();
4615
4616 if (instance.state !== oldState) {
4617 {
4618 var componentName = getComponentName(workInProgress.type) || 'Component';
4619 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
4620 didWarnAboutStateAssignmentForComponent.add(componentName);
4621 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
4622 }
4623 }
4624 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4625 }
4626}
4627
4628// Invokes the mount life-cycles on a previously never rendered instance.
4629function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4630 {
4631 checkClassInstance(workInProgress, ctor, newProps);
4632 }
4633
4634 var instance = workInProgress.stateNode;
4635 instance.props = newProps;
4636 instance.state = workInProgress.memoizedState;
4637 instance.refs = emptyRefsObject;
4638
4639 var contextType = ctor.contextType;
4640 if (typeof contextType === 'object' && contextType !== null) {
4641 instance.context = readContext(contextType);
4642 } else if (disableLegacyContext) {
4643 instance.context = emptyContextObject;
4644 } else {
4645 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4646 instance.context = getMaskedContext(workInProgress, unmaskedContext);
4647 }
4648
4649 {
4650 if (instance.state === newProps) {
4651 var componentName = getComponentName(ctor) || 'Component';
4652 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
4653 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
4654 warningWithoutStack$1(false, '%s: It is not recommended to assign props directly to state ' + "because updates to props won't be reflected in state. " + 'In most cases, it is better to use props directly.', componentName);
4655 }
4656 }
4657
4658 if (workInProgress.mode & StrictMode) {
4659 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
4660 }
4661
4662 if (warnAboutDeprecatedLifecycles) {
4663 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
4664 }
4665 }
4666
4667 var updateQueue = workInProgress.updateQueue;
4668 if (updateQueue !== null) {
4669 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4670 instance.state = workInProgress.memoizedState;
4671 }
4672
4673 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4674 if (typeof getDerivedStateFromProps === 'function') {
4675 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4676 instance.state = workInProgress.memoizedState;
4677 }
4678
4679 // In order to support react-lifecycles-compat polyfilled components,
4680 // Unsafe lifecycles should not be invoked for components using the new APIs.
4681 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4682 callComponentWillMount(workInProgress, instance);
4683 // If we had additional state updates during this life-cycle, let's
4684 // process them now.
4685 updateQueue = workInProgress.updateQueue;
4686 if (updateQueue !== null) {
4687 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4688 instance.state = workInProgress.memoizedState;
4689 }
4690 }
4691
4692 if (typeof instance.componentDidMount === 'function') {
4693 workInProgress.effectTag |= Update;
4694 }
4695}
4696
4697function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4698 var instance = workInProgress.stateNode;
4699
4700 var oldProps = workInProgress.memoizedProps;
4701 instance.props = oldProps;
4702
4703 var oldContext = instance.context;
4704 var contextType = ctor.contextType;
4705 var nextContext = emptyContextObject;
4706 if (typeof contextType === 'object' && contextType !== null) {
4707 nextContext = readContext(contextType);
4708 } else if (!disableLegacyContext) {
4709 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4710 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
4711 }
4712
4713 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4714 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
4715
4716 // Note: During these life-cycles, instance.props/instance.state are what
4717 // ever the previously attempted to render - not the "current". However,
4718 // during componentDidUpdate we pass the "current" props.
4719
4720 // In order to support react-lifecycles-compat polyfilled components,
4721 // Unsafe lifecycles should not be invoked for components using the new APIs.
4722 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4723 if (oldProps !== newProps || oldContext !== nextContext) {
4724 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4725 }
4726 }
4727
4728 resetHasForceUpdateBeforeProcessing();
4729
4730 var oldState = workInProgress.memoizedState;
4731 var newState = instance.state = oldState;
4732 var updateQueue = workInProgress.updateQueue;
4733 if (updateQueue !== null) {
4734 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4735 newState = workInProgress.memoizedState;
4736 }
4737 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4738 // If an update was already in progress, we should schedule an Update
4739 // effect even though we're bailing out, so that cWU/cDU are called.
4740 if (typeof instance.componentDidMount === 'function') {
4741 workInProgress.effectTag |= Update;
4742 }
4743 return false;
4744 }
4745
4746 if (typeof getDerivedStateFromProps === 'function') {
4747 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4748 newState = workInProgress.memoizedState;
4749 }
4750
4751 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4752
4753 if (shouldUpdate) {
4754 // In order to support react-lifecycles-compat polyfilled components,
4755 // Unsafe lifecycles should not be invoked for components using the new APIs.
4756 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4757 startPhaseTimer(workInProgress, 'componentWillMount');
4758 if (typeof instance.componentWillMount === 'function') {
4759 instance.componentWillMount();
4760 }
4761 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4762 instance.UNSAFE_componentWillMount();
4763 }
4764 stopPhaseTimer();
4765 }
4766 if (typeof instance.componentDidMount === 'function') {
4767 workInProgress.effectTag |= Update;
4768 }
4769 } else {
4770 // If an update was already in progress, we should schedule an Update
4771 // effect even though we're bailing out, so that cWU/cDU are called.
4772 if (typeof instance.componentDidMount === 'function') {
4773 workInProgress.effectTag |= Update;
4774 }
4775
4776 // If shouldComponentUpdate returned false, we should still update the
4777 // memoized state to indicate that this work can be reused.
4778 workInProgress.memoizedProps = newProps;
4779 workInProgress.memoizedState = newState;
4780 }
4781
4782 // Update the existing instance's state, props, and context pointers even
4783 // if shouldComponentUpdate returns false.
4784 instance.props = newProps;
4785 instance.state = newState;
4786 instance.context = nextContext;
4787
4788 return shouldUpdate;
4789}
4790
4791// Invokes the update life-cycles and returns false if it shouldn't rerender.
4792function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
4793 var instance = workInProgress.stateNode;
4794
4795 var oldProps = workInProgress.memoizedProps;
4796 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
4797
4798 var oldContext = instance.context;
4799 var contextType = ctor.contextType;
4800 var nextContext = emptyContextObject;
4801 if (typeof contextType === 'object' && contextType !== null) {
4802 nextContext = readContext(contextType);
4803 } else if (!disableLegacyContext) {
4804 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4805 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
4806 }
4807
4808 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4809 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
4810
4811 // Note: During these life-cycles, instance.props/instance.state are what
4812 // ever the previously attempted to render - not the "current". However,
4813 // during componentDidUpdate we pass the "current" props.
4814
4815 // In order to support react-lifecycles-compat polyfilled components,
4816 // Unsafe lifecycles should not be invoked for components using the new APIs.
4817 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4818 if (oldProps !== newProps || oldContext !== nextContext) {
4819 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4820 }
4821 }
4822
4823 resetHasForceUpdateBeforeProcessing();
4824
4825 var oldState = workInProgress.memoizedState;
4826 var newState = instance.state = oldState;
4827 var updateQueue = workInProgress.updateQueue;
4828 if (updateQueue !== null) {
4829 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4830 newState = workInProgress.memoizedState;
4831 }
4832
4833 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4834 // If an update was already in progress, we should schedule an Update
4835 // effect even though we're bailing out, so that cWU/cDU are called.
4836 if (typeof instance.componentDidUpdate === 'function') {
4837 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4838 workInProgress.effectTag |= Update;
4839 }
4840 }
4841 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4842 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4843 workInProgress.effectTag |= Snapshot;
4844 }
4845 }
4846 return false;
4847 }
4848
4849 if (typeof getDerivedStateFromProps === 'function') {
4850 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4851 newState = workInProgress.memoizedState;
4852 }
4853
4854 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4855
4856 if (shouldUpdate) {
4857 // In order to support react-lifecycles-compat polyfilled components,
4858 // Unsafe lifecycles should not be invoked for components using the new APIs.
4859 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
4860 startPhaseTimer(workInProgress, 'componentWillUpdate');
4861 if (typeof instance.componentWillUpdate === 'function') {
4862 instance.componentWillUpdate(newProps, newState, nextContext);
4863 }
4864 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4865 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
4866 }
4867 stopPhaseTimer();
4868 }
4869 if (typeof instance.componentDidUpdate === 'function') {
4870 workInProgress.effectTag |= Update;
4871 }
4872 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4873 workInProgress.effectTag |= Snapshot;
4874 }
4875 } else {
4876 // If an update was already in progress, we should schedule an Update
4877 // effect even though we're bailing out, so that cWU/cDU are called.
4878 if (typeof instance.componentDidUpdate === 'function') {
4879 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4880 workInProgress.effectTag |= Update;
4881 }
4882 }
4883 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4884 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4885 workInProgress.effectTag |= Snapshot;
4886 }
4887 }
4888
4889 // If shouldComponentUpdate returned false, we should still update the
4890 // memoized props/state to indicate that this work can be reused.
4891 workInProgress.memoizedProps = newProps;
4892 workInProgress.memoizedState = newState;
4893 }
4894
4895 // Update the existing instance's state, props, and context pointers even
4896 // if shouldComponentUpdate returns false.
4897 instance.props = newProps;
4898 instance.state = newState;
4899 instance.context = nextContext;
4900
4901 return shouldUpdate;
4902}
4903
4904var didWarnAboutMaps = void 0;
4905var didWarnAboutGenerators = void 0;
4906var didWarnAboutStringRefInStrictMode = void 0;
4907var ownerHasKeyUseWarning = void 0;
4908var ownerHasFunctionTypeWarning = void 0;
4909var warnForMissingKey = function (child) {};
4910
4911{
4912 didWarnAboutMaps = false;
4913 didWarnAboutGenerators = false;
4914 didWarnAboutStringRefInStrictMode = {};
4915
4916 /**
4917 * Warn if there's no key explicitly set on dynamic arrays of children or
4918 * object keys are not valid. This allows us to keep track of children between
4919 * updates.
4920 */
4921 ownerHasKeyUseWarning = {};
4922 ownerHasFunctionTypeWarning = {};
4923
4924 warnForMissingKey = function (child) {
4925 if (child === null || typeof child !== 'object') {
4926 return;
4927 }
4928 if (!child._store || child._store.validated || child.key != null) {
4929 return;
4930 }
4931 (function () {
4932 if (!(typeof child._store === 'object')) {
4933 {
4934 throw ReactError(Error('React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue.'));
4935 }
4936 }
4937 })();
4938 child._store.validated = true;
4939
4940 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
4941 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
4942 return;
4943 }
4944 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
4945
4946 warning$1(false, 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
4947 };
4948}
4949
4950var isArray = Array.isArray;
4951
4952function coerceRef(returnFiber, current, element) {
4953 var mixedRef = element.ref;
4954 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
4955 {
4956 if (returnFiber.mode & StrictMode) {
4957 var componentName = getComponentName(returnFiber.type) || 'Component';
4958 if (!didWarnAboutStringRefInStrictMode[componentName]) {
4959 warningWithoutStack$1(false, 'A string ref, "%s", has been found within a strict mode tree. ' + 'String refs are a source of potential bugs and should be avoided. ' + 'We recommend using createRef() instead.' + '\n%s' + '\n\nLearn more about using refs safely here:' + '\nhttps://fb.me/react-strict-mode-string-ref', mixedRef, getStackByFiberInDevAndProd(returnFiber));
4960 didWarnAboutStringRefInStrictMode[componentName] = true;
4961 }
4962 }
4963 }
4964
4965 if (element._owner) {
4966 var owner = element._owner;
4967 var inst = void 0;
4968 if (owner) {
4969 var ownerFiber = owner;
4970 (function () {
4971 if (!(ownerFiber.tag === ClassComponent)) {
4972 {
4973 throw ReactError(Error('Function components cannot have refs. Did you mean to use React.forwardRef()?'));
4974 }
4975 }
4976 })();
4977 inst = ownerFiber.stateNode;
4978 }
4979 (function () {
4980 if (!inst) {
4981 {
4982 throw ReactError(Error('Missing owner for string ref ' + mixedRef + '. This error is likely caused by a bug in React. Please file an issue.'));
4983 }
4984 }
4985 })();
4986 var stringRef = '' + mixedRef;
4987 // Check if previous string ref matches new string ref
4988 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
4989 return current.ref;
4990 }
4991 var ref = function (value) {
4992 var refs = inst.refs;
4993 if (refs === emptyRefsObject) {
4994 // This is a lazy pooled frozen object, so we need to initialize.
4995 refs = inst.refs = {};
4996 }
4997 if (value === null) {
4998 delete refs[stringRef];
4999 } else {
5000 refs[stringRef] = value;
5001 }
5002 };
5003 ref._stringRef = stringRef;
5004 return ref;
5005 } else {
5006 (function () {
5007 if (!(typeof mixedRef === 'string')) {
5008 {
5009 throw ReactError(Error('Expected ref to be a function, a string, an object returned by React.createRef(), or null.'));
5010 }
5011 }
5012 })();
5013 (function () {
5014 if (!element._owner) {
5015 {
5016 throw ReactError(Error('Element ref was specified as a string (' + mixedRef + ') but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component\'s render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information.'));
5017 }
5018 }
5019 })();
5020 }
5021 }
5022 return mixedRef;
5023}
5024
5025function throwOnInvalidObjectType(returnFiber, newChild) {
5026 if (returnFiber.type !== 'textarea') {
5027 var addendum = '';
5028 {
5029 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
5030 }
5031 (function () {
5032 {
5033 {
5034 throw ReactError(Error('Objects are not valid as a React child (found: ' + (Object.prototype.toString.call(newChild) === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : newChild) + ').' + addendum));
5035 }
5036 }
5037 })();
5038 }
5039}
5040
5041function warnOnFunctionType() {
5042 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();
5043
5044 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
5045 return;
5046 }
5047 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
5048
5049 warning$1(false, 'Functions are not valid as a React child. This may happen if ' + 'you return a Component instead of <Component /> from render. ' + 'Or maybe you meant to call this function rather than return it.');
5050}
5051
5052// This wrapper function exists because I expect to clone the code in each path
5053// to be able to optimize each path individually by branching early. This needs
5054// a compiler or we can do it manually. Helpers that don't need this branching
5055// live outside of this function.
5056function ChildReconciler(shouldTrackSideEffects) {
5057 function deleteChild(returnFiber, childToDelete) {
5058 if (!shouldTrackSideEffects) {
5059 // Noop.
5060 return;
5061 }
5062 // Deletions are added in reversed order so we add it to the front.
5063 // At this point, the return fiber's effect list is empty except for
5064 // deletions, so we can just append the deletion to the list. The remaining
5065 // effects aren't added until the complete phase. Once we implement
5066 // resuming, this may not be true.
5067 var last = returnFiber.lastEffect;
5068 if (last !== null) {
5069 last.nextEffect = childToDelete;
5070 returnFiber.lastEffect = childToDelete;
5071 } else {
5072 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
5073 }
5074 childToDelete.nextEffect = null;
5075 childToDelete.effectTag = Deletion;
5076 }
5077
5078 function deleteRemainingChildren(returnFiber, currentFirstChild) {
5079 if (!shouldTrackSideEffects) {
5080 // Noop.
5081 return null;
5082 }
5083
5084 // TODO: For the shouldClone case, this could be micro-optimized a bit by
5085 // assuming that after the first child we've already added everything.
5086 var childToDelete = currentFirstChild;
5087 while (childToDelete !== null) {
5088 deleteChild(returnFiber, childToDelete);
5089 childToDelete = childToDelete.sibling;
5090 }
5091 return null;
5092 }
5093
5094 function mapRemainingChildren(returnFiber, currentFirstChild) {
5095 // Add the remaining children to a temporary map so that we can find them by
5096 // keys quickly. Implicit (null) keys get added to this set with their index
5097 var existingChildren = new Map();
5098
5099 var existingChild = currentFirstChild;
5100 while (existingChild !== null) {
5101 if (existingChild.key !== null) {
5102 existingChildren.set(existingChild.key, existingChild);
5103 } else {
5104 existingChildren.set(existingChild.index, existingChild);
5105 }
5106 existingChild = existingChild.sibling;
5107 }
5108 return existingChildren;
5109 }
5110
5111 function useFiber(fiber, pendingProps, expirationTime) {
5112 // We currently set sibling to null and index to 0 here because it is easy
5113 // to forget to do before returning it. E.g. for the single child case.
5114 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
5115 clone.index = 0;
5116 clone.sibling = null;
5117 return clone;
5118 }
5119
5120 function placeChild(newFiber, lastPlacedIndex, newIndex) {
5121 newFiber.index = newIndex;
5122 if (!shouldTrackSideEffects) {
5123 // Noop.
5124 return lastPlacedIndex;
5125 }
5126 var current = newFiber.alternate;
5127 if (current !== null) {
5128 var oldIndex = current.index;
5129 if (oldIndex < lastPlacedIndex) {
5130 // This is a move.
5131 newFiber.effectTag = Placement;
5132 return lastPlacedIndex;
5133 } else {
5134 // This item can stay in place.
5135 return oldIndex;
5136 }
5137 } else {
5138 // This is an insertion.
5139 newFiber.effectTag = Placement;
5140 return lastPlacedIndex;
5141 }
5142 }
5143
5144 function placeSingleChild(newFiber) {
5145 // This is simpler for the single child case. We only need to do a
5146 // placement for inserting new children.
5147 if (shouldTrackSideEffects && newFiber.alternate === null) {
5148 newFiber.effectTag = Placement;
5149 }
5150 return newFiber;
5151 }
5152
5153 function updateTextNode(returnFiber, current, textContent, expirationTime) {
5154 if (current === null || current.tag !== HostText) {
5155 // Insert
5156 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
5157 created.return = returnFiber;
5158 return created;
5159 } else {
5160 // Update
5161 var existing = useFiber(current, textContent, expirationTime);
5162 existing.return = returnFiber;
5163 return existing;
5164 }
5165 }
5166
5167 function updateElement(returnFiber, current, element, expirationTime) {
5168 if (current !== null && (current.elementType === element.type || (
5169 // Keep this check inline so it only runs on the false path:
5170 isCompatibleFamilyForHotReloading(current, element)))) {
5171 // Move based on index
5172 var existing = useFiber(current, element.props, expirationTime);
5173 existing.ref = coerceRef(returnFiber, current, element);
5174 existing.return = returnFiber;
5175 {
5176 existing._debugSource = element._source;
5177 existing._debugOwner = element._owner;
5178 }
5179 return existing;
5180 } else {
5181 // Insert
5182 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
5183 created.ref = coerceRef(returnFiber, current, element);
5184 created.return = returnFiber;
5185 return created;
5186 }
5187 }
5188
5189 function updatePortal(returnFiber, current, portal, expirationTime) {
5190 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
5191 // Insert
5192 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
5193 created.return = returnFiber;
5194 return created;
5195 } else {
5196 // Update
5197 var existing = useFiber(current, portal.children || [], expirationTime);
5198 existing.return = returnFiber;
5199 return existing;
5200 }
5201 }
5202
5203 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
5204 if (current === null || current.tag !== Fragment) {
5205 // Insert
5206 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
5207 created.return = returnFiber;
5208 return created;
5209 } else {
5210 // Update
5211 var existing = useFiber(current, fragment, expirationTime);
5212 existing.return = returnFiber;
5213 return existing;
5214 }
5215 }
5216
5217 function createChild(returnFiber, newChild, expirationTime) {
5218 if (typeof newChild === 'string' || typeof newChild === 'number') {
5219 // Text nodes don't have keys. If the previous node is implicitly keyed
5220 // we can continue to replace it without aborting even if it is not a text
5221 // node.
5222 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
5223 created.return = returnFiber;
5224 return created;
5225 }
5226
5227 if (typeof newChild === 'object' && newChild !== null) {
5228 switch (newChild.$$typeof) {
5229 case REACT_ELEMENT_TYPE:
5230 {
5231 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
5232 _created.ref = coerceRef(returnFiber, null, newChild);
5233 _created.return = returnFiber;
5234 return _created;
5235 }
5236 case REACT_PORTAL_TYPE:
5237 {
5238 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
5239 _created2.return = returnFiber;
5240 return _created2;
5241 }
5242 }
5243
5244 if (isArray(newChild) || getIteratorFn(newChild)) {
5245 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
5246 _created3.return = returnFiber;
5247 return _created3;
5248 }
5249
5250 throwOnInvalidObjectType(returnFiber, newChild);
5251 }
5252
5253 {
5254 if (typeof newChild === 'function') {
5255 warnOnFunctionType();
5256 }
5257 }
5258
5259 return null;
5260 }
5261
5262 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
5263 // Update the fiber if the keys match, otherwise return null.
5264
5265 var key = oldFiber !== null ? oldFiber.key : null;
5266
5267 if (typeof newChild === 'string' || typeof newChild === 'number') {
5268 // Text nodes don't have keys. If the previous node is implicitly keyed
5269 // we can continue to replace it without aborting even if it is not a text
5270 // node.
5271 if (key !== null) {
5272 return null;
5273 }
5274 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
5275 }
5276
5277 if (typeof newChild === 'object' && newChild !== null) {
5278 switch (newChild.$$typeof) {
5279 case REACT_ELEMENT_TYPE:
5280 {
5281 if (newChild.key === key) {
5282 if (newChild.type === REACT_FRAGMENT_TYPE) {
5283 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
5284 }
5285 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
5286 } else {
5287 return null;
5288 }
5289 }
5290 case REACT_PORTAL_TYPE:
5291 {
5292 if (newChild.key === key) {
5293 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
5294 } else {
5295 return null;
5296 }
5297 }
5298 }
5299
5300 if (isArray(newChild) || getIteratorFn(newChild)) {
5301 if (key !== null) {
5302 return null;
5303 }
5304
5305 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
5306 }
5307
5308 throwOnInvalidObjectType(returnFiber, newChild);
5309 }
5310
5311 {
5312 if (typeof newChild === 'function') {
5313 warnOnFunctionType();
5314 }
5315 }
5316
5317 return null;
5318 }
5319
5320 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
5321 if (typeof newChild === 'string' || typeof newChild === 'number') {
5322 // Text nodes don't have keys, so we neither have to check the old nor
5323 // new node for the key. If both are text nodes, they match.
5324 var matchedFiber = existingChildren.get(newIdx) || null;
5325 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
5326 }
5327
5328 if (typeof newChild === 'object' && newChild !== null) {
5329 switch (newChild.$$typeof) {
5330 case REACT_ELEMENT_TYPE:
5331 {
5332 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
5333 if (newChild.type === REACT_FRAGMENT_TYPE) {
5334 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
5335 }
5336 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
5337 }
5338 case REACT_PORTAL_TYPE:
5339 {
5340 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
5341 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
5342 }
5343 }
5344
5345 if (isArray(newChild) || getIteratorFn(newChild)) {
5346 var _matchedFiber3 = existingChildren.get(newIdx) || null;
5347 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
5348 }
5349
5350 throwOnInvalidObjectType(returnFiber, newChild);
5351 }
5352
5353 {
5354 if (typeof newChild === 'function') {
5355 warnOnFunctionType();
5356 }
5357 }
5358
5359 return null;
5360 }
5361
5362 /**
5363 * Warns if there is a duplicate or missing key
5364 */
5365 function warnOnInvalidKey(child, knownKeys) {
5366 {
5367 if (typeof child !== 'object' || child === null) {
5368 return knownKeys;
5369 }
5370 switch (child.$$typeof) {
5371 case REACT_ELEMENT_TYPE:
5372 case REACT_PORTAL_TYPE:
5373 warnForMissingKey(child);
5374 var key = child.key;
5375 if (typeof key !== 'string') {
5376 break;
5377 }
5378 if (knownKeys === null) {
5379 knownKeys = new Set();
5380 knownKeys.add(key);
5381 break;
5382 }
5383 if (!knownKeys.has(key)) {
5384 knownKeys.add(key);
5385 break;
5386 }
5387 warning$1(false, 'Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key);
5388 break;
5389 default:
5390 break;
5391 }
5392 }
5393 return knownKeys;
5394 }
5395
5396 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
5397 // This algorithm can't optimize by searching from both ends since we
5398 // don't have backpointers on fibers. I'm trying to see how far we can get
5399 // with that model. If it ends up not being worth the tradeoffs, we can
5400 // add it later.
5401
5402 // Even with a two ended optimization, we'd want to optimize for the case
5403 // where there are few changes and brute force the comparison instead of
5404 // going for the Map. It'd like to explore hitting that path first in
5405 // forward-only mode and only go for the Map once we notice that we need
5406 // lots of look ahead. This doesn't handle reversal as well as two ended
5407 // search but that's unusual. Besides, for the two ended optimization to
5408 // work on Iterables, we'd need to copy the whole set.
5409
5410 // In this first iteration, we'll just live with hitting the bad case
5411 // (adding everything to a Map) in for every insert/move.
5412
5413 // If you change this code, also update reconcileChildrenIterator() which
5414 // uses the same algorithm.
5415
5416 {
5417 // First, validate keys.
5418 var knownKeys = null;
5419 for (var i = 0; i < newChildren.length; i++) {
5420 var child = newChildren[i];
5421 knownKeys = warnOnInvalidKey(child, knownKeys);
5422 }
5423 }
5424
5425 var resultingFirstChild = null;
5426 var previousNewFiber = null;
5427
5428 var oldFiber = currentFirstChild;
5429 var lastPlacedIndex = 0;
5430 var newIdx = 0;
5431 var nextOldFiber = null;
5432 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
5433 if (oldFiber.index > newIdx) {
5434 nextOldFiber = oldFiber;
5435 oldFiber = null;
5436 } else {
5437 nextOldFiber = oldFiber.sibling;
5438 }
5439 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
5440 if (newFiber === null) {
5441 // TODO: This breaks on empty slots like null children. That's
5442 // unfortunate because it triggers the slow path all the time. We need
5443 // a better way to communicate whether this was a miss or null,
5444 // boolean, undefined, etc.
5445 if (oldFiber === null) {
5446 oldFiber = nextOldFiber;
5447 }
5448 break;
5449 }
5450 if (shouldTrackSideEffects) {
5451 if (oldFiber && newFiber.alternate === null) {
5452 // We matched the slot, but we didn't reuse the existing fiber, so we
5453 // need to delete the existing child.
5454 deleteChild(returnFiber, oldFiber);
5455 }
5456 }
5457 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
5458 if (previousNewFiber === null) {
5459 // TODO: Move out of the loop. This only happens for the first run.
5460 resultingFirstChild = newFiber;
5461 } else {
5462 // TODO: Defer siblings if we're not at the right index for this slot.
5463 // I.e. if we had null values before, then we want to defer this
5464 // for each null value. However, we also don't want to call updateSlot
5465 // with the previous one.
5466 previousNewFiber.sibling = newFiber;
5467 }
5468 previousNewFiber = newFiber;
5469 oldFiber = nextOldFiber;
5470 }
5471
5472 if (newIdx === newChildren.length) {
5473 // We've reached the end of the new children. We can delete the rest.
5474 deleteRemainingChildren(returnFiber, oldFiber);
5475 return resultingFirstChild;
5476 }
5477
5478 if (oldFiber === null) {
5479 // If we don't have any more existing children we can choose a fast path
5480 // since the rest will all be insertions.
5481 for (; newIdx < newChildren.length; newIdx++) {
5482 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
5483 if (_newFiber === null) {
5484 continue;
5485 }
5486 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
5487 if (previousNewFiber === null) {
5488 // TODO: Move out of the loop. This only happens for the first run.
5489 resultingFirstChild = _newFiber;
5490 } else {
5491 previousNewFiber.sibling = _newFiber;
5492 }
5493 previousNewFiber = _newFiber;
5494 }
5495 return resultingFirstChild;
5496 }
5497
5498 // Add all children to a key map for quick lookups.
5499 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
5500
5501 // Keep scanning and use the map to restore deleted items as moves.
5502 for (; newIdx < newChildren.length; newIdx++) {
5503 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
5504 if (_newFiber2 !== null) {
5505 if (shouldTrackSideEffects) {
5506 if (_newFiber2.alternate !== null) {
5507 // The new fiber is a work in progress, but if there exists a
5508 // current, that means that we reused the fiber. We need to delete
5509 // it from the child list so that we don't add it to the deletion
5510 // list.
5511 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
5512 }
5513 }
5514 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
5515 if (previousNewFiber === null) {
5516 resultingFirstChild = _newFiber2;
5517 } else {
5518 previousNewFiber.sibling = _newFiber2;
5519 }
5520 previousNewFiber = _newFiber2;
5521 }
5522 }
5523
5524 if (shouldTrackSideEffects) {
5525 // Any existing children that weren't consumed above were deleted. We need
5526 // to add them to the deletion list.
5527 existingChildren.forEach(function (child) {
5528 return deleteChild(returnFiber, child);
5529 });
5530 }
5531
5532 return resultingFirstChild;
5533 }
5534
5535 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
5536 // This is the same implementation as reconcileChildrenArray(),
5537 // but using the iterator instead.
5538
5539 var iteratorFn = getIteratorFn(newChildrenIterable);
5540 (function () {
5541 if (!(typeof iteratorFn === 'function')) {
5542 {
5543 throw ReactError(Error('An object is not an iterable. This error is likely caused by a bug in React. Please file an issue.'));
5544 }
5545 }
5546 })();
5547
5548 {
5549 // We don't support rendering Generators because it's a mutation.
5550 // See https://github.com/facebook/react/issues/12995
5551 if (typeof Symbol === 'function' &&
5552 // $FlowFixMe Flow doesn't know about toStringTag
5553 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
5554 !didWarnAboutGenerators ? warning$1(false, 'Using Generators as children is unsupported and will likely yield ' + 'unexpected results because enumerating a generator mutates it. ' + 'You may convert it to an array with `Array.from()` or the ' + '`[...spread]` operator before rendering. Keep in mind ' + 'you might need to polyfill these features for older browsers.') : void 0;
5555 didWarnAboutGenerators = true;
5556 }
5557
5558 // Warn about using Maps as children
5559 if (newChildrenIterable.entries === iteratorFn) {
5560 !didWarnAboutMaps ? warning$1(false, 'Using Maps as children is unsupported and will likely yield ' + 'unexpected results. Convert it to a sequence/iterable of keyed ' + 'ReactElements instead.') : void 0;
5561 didWarnAboutMaps = true;
5562 }
5563
5564 // First, validate keys.
5565 // We'll get a different iterator later for the main pass.
5566 var _newChildren = iteratorFn.call(newChildrenIterable);
5567 if (_newChildren) {
5568 var knownKeys = null;
5569 var _step = _newChildren.next();
5570 for (; !_step.done; _step = _newChildren.next()) {
5571 var child = _step.value;
5572 knownKeys = warnOnInvalidKey(child, knownKeys);
5573 }
5574 }
5575 }
5576
5577 var newChildren = iteratorFn.call(newChildrenIterable);
5578 (function () {
5579 if (!(newChildren != null)) {
5580 {
5581 throw ReactError(Error('An iterable object provided no iterator.'));
5582 }
5583 }
5584 })();
5585
5586 var resultingFirstChild = null;
5587 var previousNewFiber = null;
5588
5589 var oldFiber = currentFirstChild;
5590 var lastPlacedIndex = 0;
5591 var newIdx = 0;
5592 var nextOldFiber = null;
5593
5594 var step = newChildren.next();
5595 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
5596 if (oldFiber.index > newIdx) {
5597 nextOldFiber = oldFiber;
5598 oldFiber = null;
5599 } else {
5600 nextOldFiber = oldFiber.sibling;
5601 }
5602 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
5603 if (newFiber === null) {
5604 // TODO: This breaks on empty slots like null children. That's
5605 // unfortunate because it triggers the slow path all the time. We need
5606 // a better way to communicate whether this was a miss or null,
5607 // boolean, undefined, etc.
5608 if (oldFiber === null) {
5609 oldFiber = nextOldFiber;
5610 }
5611 break;
5612 }
5613 if (shouldTrackSideEffects) {
5614 if (oldFiber && newFiber.alternate === null) {
5615 // We matched the slot, but we didn't reuse the existing fiber, so we
5616 // need to delete the existing child.
5617 deleteChild(returnFiber, oldFiber);
5618 }
5619 }
5620 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
5621 if (previousNewFiber === null) {
5622 // TODO: Move out of the loop. This only happens for the first run.
5623 resultingFirstChild = newFiber;
5624 } else {
5625 // TODO: Defer siblings if we're not at the right index for this slot.
5626 // I.e. if we had null values before, then we want to defer this
5627 // for each null value. However, we also don't want to call updateSlot
5628 // with the previous one.
5629 previousNewFiber.sibling = newFiber;
5630 }
5631 previousNewFiber = newFiber;
5632 oldFiber = nextOldFiber;
5633 }
5634
5635 if (step.done) {
5636 // We've reached the end of the new children. We can delete the rest.
5637 deleteRemainingChildren(returnFiber, oldFiber);
5638 return resultingFirstChild;
5639 }
5640
5641 if (oldFiber === null) {
5642 // If we don't have any more existing children we can choose a fast path
5643 // since the rest will all be insertions.
5644 for (; !step.done; newIdx++, step = newChildren.next()) {
5645 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
5646 if (_newFiber3 === null) {
5647 continue;
5648 }
5649 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
5650 if (previousNewFiber === null) {
5651 // TODO: Move out of the loop. This only happens for the first run.
5652 resultingFirstChild = _newFiber3;
5653 } else {
5654 previousNewFiber.sibling = _newFiber3;
5655 }
5656 previousNewFiber = _newFiber3;
5657 }
5658 return resultingFirstChild;
5659 }
5660
5661 // Add all children to a key map for quick lookups.
5662 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
5663
5664 // Keep scanning and use the map to restore deleted items as moves.
5665 for (; !step.done; newIdx++, step = newChildren.next()) {
5666 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
5667 if (_newFiber4 !== null) {
5668 if (shouldTrackSideEffects) {
5669 if (_newFiber4.alternate !== null) {
5670 // The new fiber is a work in progress, but if there exists a
5671 // current, that means that we reused the fiber. We need to delete
5672 // it from the child list so that we don't add it to the deletion
5673 // list.
5674 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
5675 }
5676 }
5677 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
5678 if (previousNewFiber === null) {
5679 resultingFirstChild = _newFiber4;
5680 } else {
5681 previousNewFiber.sibling = _newFiber4;
5682 }
5683 previousNewFiber = _newFiber4;
5684 }
5685 }
5686
5687 if (shouldTrackSideEffects) {
5688 // Any existing children that weren't consumed above were deleted. We need
5689 // to add them to the deletion list.
5690 existingChildren.forEach(function (child) {
5691 return deleteChild(returnFiber, child);
5692 });
5693 }
5694
5695 return resultingFirstChild;
5696 }
5697
5698 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
5699 // There's no need to check for keys on text nodes since we don't have a
5700 // way to define them.
5701 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
5702 // We already have an existing node so let's just update it and delete
5703 // the rest.
5704 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
5705 var existing = useFiber(currentFirstChild, textContent, expirationTime);
5706 existing.return = returnFiber;
5707 return existing;
5708 }
5709 // The existing first child is not a text node so we need to create one
5710 // and delete the existing ones.
5711 deleteRemainingChildren(returnFiber, currentFirstChild);
5712 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
5713 created.return = returnFiber;
5714 return created;
5715 }
5716
5717 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
5718 var key = element.key;
5719 var child = currentFirstChild;
5720 while (child !== null) {
5721 // TODO: If key === null and child.key === null, then this only applies to
5722 // the first item in the list.
5723 if (child.key === key) {
5724 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type || (
5725 // Keep this check inline so it only runs on the false path:
5726 isCompatibleFamilyForHotReloading(child, element))) {
5727 deleteRemainingChildren(returnFiber, child.sibling);
5728 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
5729 existing.ref = coerceRef(returnFiber, child, element);
5730 existing.return = returnFiber;
5731 {
5732 existing._debugSource = element._source;
5733 existing._debugOwner = element._owner;
5734 }
5735 return existing;
5736 } else {
5737 deleteRemainingChildren(returnFiber, child);
5738 break;
5739 }
5740 } else {
5741 deleteChild(returnFiber, child);
5742 }
5743 child = child.sibling;
5744 }
5745
5746 if (element.type === REACT_FRAGMENT_TYPE) {
5747 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
5748 created.return = returnFiber;
5749 return created;
5750 } else {
5751 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
5752 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
5753 _created4.return = returnFiber;
5754 return _created4;
5755 }
5756 }
5757
5758 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
5759 var key = portal.key;
5760 var child = currentFirstChild;
5761 while (child !== null) {
5762 // TODO: If key === null and child.key === null, then this only applies to
5763 // the first item in the list.
5764 if (child.key === key) {
5765 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
5766 deleteRemainingChildren(returnFiber, child.sibling);
5767 var existing = useFiber(child, portal.children || [], expirationTime);
5768 existing.return = returnFiber;
5769 return existing;
5770 } else {
5771 deleteRemainingChildren(returnFiber, child);
5772 break;
5773 }
5774 } else {
5775 deleteChild(returnFiber, child);
5776 }
5777 child = child.sibling;
5778 }
5779
5780 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
5781 created.return = returnFiber;
5782 return created;
5783 }
5784
5785 // This API will tag the children with the side-effect of the reconciliation
5786 // itself. They will be added to the side-effect list as we pass through the
5787 // children and the parent.
5788 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
5789 // This function is not recursive.
5790 // If the top level item is an array, we treat it as a set of children,
5791 // not as a fragment. Nested arrays on the other hand will be treated as
5792 // fragment nodes. Recursion happens at the normal flow.
5793
5794 // Handle top level unkeyed fragments as if they were arrays.
5795 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
5796 // We treat the ambiguous cases above the same.
5797 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
5798 if (isUnkeyedTopLevelFragment) {
5799 newChild = newChild.props.children;
5800 }
5801
5802 // Handle object types
5803 var isObject = typeof newChild === 'object' && newChild !== null;
5804
5805 if (isObject) {
5806 switch (newChild.$$typeof) {
5807 case REACT_ELEMENT_TYPE:
5808 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
5809 case REACT_PORTAL_TYPE:
5810 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
5811 }
5812 }
5813
5814 if (typeof newChild === 'string' || typeof newChild === 'number') {
5815 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
5816 }
5817
5818 if (isArray(newChild)) {
5819 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
5820 }
5821
5822 if (getIteratorFn(newChild)) {
5823 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
5824 }
5825
5826 if (isObject) {
5827 throwOnInvalidObjectType(returnFiber, newChild);
5828 }
5829
5830 {
5831 if (typeof newChild === 'function') {
5832 warnOnFunctionType();
5833 }
5834 }
5835 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
5836 // If the new child is undefined, and the return fiber is a composite
5837 // component, throw an error. If Fiber return types are disabled,
5838 // we already threw above.
5839 switch (returnFiber.tag) {
5840 case ClassComponent:
5841 {
5842 {
5843 var instance = returnFiber.stateNode;
5844 if (instance.render._isMockFunction) {
5845 // We allow auto-mocks to proceed as if they're returning null.
5846 break;
5847 }
5848 }
5849 }
5850 // Intentionally fall through to the next case, which handles both
5851 // functions and classes
5852 // eslint-disable-next-lined no-fallthrough
5853 case FunctionComponent:
5854 {
5855 var Component = returnFiber.type;
5856 (function () {
5857 {
5858 {
5859 throw ReactError(Error((Component.displayName || Component.name || 'Component') + '(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.'));
5860 }
5861 }
5862 })();
5863 }
5864 }
5865 }
5866
5867 // Remaining cases are all treated as empty.
5868 return deleteRemainingChildren(returnFiber, currentFirstChild);
5869 }
5870
5871 return reconcileChildFibers;
5872}
5873
5874var reconcileChildFibers = ChildReconciler(true);
5875var mountChildFibers = ChildReconciler(false);
5876
5877function cloneChildFibers(current, workInProgress) {
5878 (function () {
5879 if (!(current === null || workInProgress.child === current.child)) {
5880 {
5881 throw ReactError(Error('Resuming work not yet implemented.'));
5882 }
5883 }
5884 })();
5885
5886 if (workInProgress.child === null) {
5887 return;
5888 }
5889
5890 var currentChild = workInProgress.child;
5891 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
5892 workInProgress.child = newChild;
5893
5894 newChild.return = workInProgress;
5895 while (currentChild.sibling !== null) {
5896 currentChild = currentChild.sibling;
5897 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
5898 newChild.return = workInProgress;
5899 }
5900 newChild.sibling = null;
5901}
5902
5903// Reset a workInProgress child set to prepare it for a second pass.
5904function resetChildFibers(workInProgress, renderExpirationTime) {
5905 var child = workInProgress.child;
5906 while (child !== null) {
5907 resetWorkInProgress(child, renderExpirationTime);
5908 child = child.sibling;
5909 }
5910}
5911
5912var NO_CONTEXT$1 = {};
5913
5914var contextStackCursor$1 = createCursor(NO_CONTEXT$1);
5915var contextFiberStackCursor = createCursor(NO_CONTEXT$1);
5916var rootInstanceStackCursor = createCursor(NO_CONTEXT$1);
5917
5918function requiredContext(c) {
5919 (function () {
5920 if (!(c !== NO_CONTEXT$1)) {
5921 {
5922 throw ReactError(Error('Expected host context to exist. This error is likely caused by a bug in React. Please file an issue.'));
5923 }
5924 }
5925 })();
5926 return c;
5927}
5928
5929function getRootHostContainer() {
5930 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5931 return rootInstance;
5932}
5933
5934function pushHostContainer(fiber, nextRootInstance) {
5935 // Push current root instance onto the stack;
5936 // This allows us to reset root when portals are popped.
5937 push(rootInstanceStackCursor, nextRootInstance, fiber);
5938 // Track the context and the Fiber that provided it.
5939 // This enables us to pop only Fibers that provide unique contexts.
5940 push(contextFiberStackCursor, fiber, fiber);
5941
5942 // Finally, we need to push the host context to the stack.
5943 // However, we can't just call getRootHostContext() and push it because
5944 // we'd have a different number of entries on the stack depending on
5945 // whether getRootHostContext() throws somewhere in renderer code or not.
5946 // So we push an empty value first. This lets us safely unwind on errors.
5947 push(contextStackCursor$1, NO_CONTEXT$1, fiber);
5948 var nextRootContext = getRootHostContext(nextRootInstance);
5949 // Now that we know this function doesn't throw, replace it.
5950 pop(contextStackCursor$1, fiber);
5951 push(contextStackCursor$1, nextRootContext, fiber);
5952}
5953
5954function popHostContainer(fiber) {
5955 pop(contextStackCursor$1, fiber);
5956 pop(contextFiberStackCursor, fiber);
5957 pop(rootInstanceStackCursor, fiber);
5958}
5959
5960function getHostContext() {
5961 var context = requiredContext(contextStackCursor$1.current);
5962 return context;
5963}
5964
5965function pushHostContext(fiber) {
5966 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5967 var context = requiredContext(contextStackCursor$1.current);
5968 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
5969
5970 // Don't push this Fiber's context unless it's unique.
5971 if (context === nextContext) {
5972 return;
5973 }
5974
5975 // Track the context and the Fiber that provided it.
5976 // This enables us to pop only Fibers that provide unique contexts.
5977 push(contextFiberStackCursor, fiber, fiber);
5978 push(contextStackCursor$1, nextContext, fiber);
5979}
5980
5981function popHostContext(fiber) {
5982 // Do not pop unless this Fiber provided the current context.
5983 // pushHostContext() only pushes Fibers that provide unique contexts.
5984 if (contextFiberStackCursor.current !== fiber) {
5985 return;
5986 }
5987
5988 pop(contextStackCursor$1, fiber);
5989 pop(contextFiberStackCursor, fiber);
5990}
5991
5992var DefaultSuspenseContext = 0;
5993
5994// The Suspense Context is split into two parts. The lower bits is
5995// inherited deeply down the subtree. The upper bits only affect
5996// this immediate suspense boundary and gets reset each new
5997// boundary or suspense list.
5998var SubtreeSuspenseContextMask = 1;
5999
6000// Subtree Flags:
6001
6002// InvisibleParentSuspenseContext indicates that one of our parent Suspense
6003// boundaries is not currently showing visible main content.
6004// Either because it is already showing a fallback or is not mounted at all.
6005// We can use this to determine if it is desirable to trigger a fallback at
6006// the parent. If not, then we might need to trigger undesirable boundaries
6007// and/or suspend the commit to avoid hiding the parent content.
6008var InvisibleParentSuspenseContext = 1;
6009
6010// Shallow Flags:
6011
6012// ForceSuspenseFallback can be used by SuspenseList to force newly added
6013// items into their fallback state during one of the render passes.
6014var ForceSuspenseFallback = 2;
6015
6016var suspenseStackCursor = createCursor(DefaultSuspenseContext);
6017
6018function hasSuspenseContext(parentContext, flag) {
6019 return (parentContext & flag) !== 0;
6020}
6021
6022function setDefaultShallowSuspenseContext(parentContext) {
6023 return parentContext & SubtreeSuspenseContextMask;
6024}
6025
6026function setShallowSuspenseContext(parentContext, shallowContext) {
6027 return parentContext & SubtreeSuspenseContextMask | shallowContext;
6028}
6029
6030function addSubtreeSuspenseContext(parentContext, subtreeContext) {
6031 return parentContext | subtreeContext;
6032}
6033
6034function pushSuspenseContext(fiber, newContext) {
6035 push(suspenseStackCursor, newContext, fiber);
6036}
6037
6038function popSuspenseContext(fiber) {
6039 pop(suspenseStackCursor, fiber);
6040}
6041
6042// TODO: This is now an empty object. Should we switch this to a boolean?
6043// Alternatively we can make this use an effect tag similar to SuspenseList.
6044
6045
6046function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
6047 // If it was the primary children that just suspended, capture and render the
6048 var nextState = workInProgress.memoizedState;
6049 if (nextState !== null) {
6050 return false;
6051 }
6052 var props = workInProgress.memoizedProps;
6053 // In order to capture, the Suspense component must have a fallback prop.
6054 if (props.fallback === undefined) {
6055 return false;
6056 }
6057 // Regular boundaries always capture.
6058 if (props.unstable_avoidThisFallback !== true) {
6059 return true;
6060 }
6061 // If it's a boundary we should avoid, then we prefer to bubble up to the
6062 // parent boundary if it is currently invisible.
6063 if (hasInvisibleParent) {
6064 return false;
6065 }
6066 // If the parent is not able to handle it, we must handle it.
6067 return true;
6068}
6069
6070function findFirstSuspended(row) {
6071 var node = row;
6072 while (node !== null) {
6073 if (node.tag === SuspenseComponent) {
6074 var state = node.memoizedState;
6075 if (state !== null) {
6076 return node;
6077 }
6078 } else if (node.tag === SuspenseListComponent &&
6079 // revealOrder undefined can't be trusted because it don't
6080 // keep track of whether it suspended or not.
6081 node.memoizedProps.revealOrder !== undefined) {
6082 var didSuspend = (node.effectTag & DidCapture) !== NoEffect;
6083 if (didSuspend) {
6084 return node;
6085 }
6086 } else if (node.child !== null) {
6087 node.child.return = node;
6088 node = node.child;
6089 continue;
6090 }
6091 if (node === row) {
6092 return null;
6093 }
6094 while (node.sibling === null) {
6095 if (node.return === null || node.return === row) {
6096 return null;
6097 }
6098 node = node.return;
6099 }
6100 node.sibling.return = node.return;
6101 node = node.sibling;
6102 }
6103 return null;
6104}
6105
6106function createResponderListener(responder, props) {
6107 var eventResponderListener = {
6108 responder: responder,
6109 props: props
6110 };
6111 {
6112 Object.freeze(eventResponderListener);
6113 }
6114 return eventResponderListener;
6115}
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125function createResponderInstance(responder, responderProps, responderState, target, fiber) {
6126 return {
6127 fiber: fiber,
6128 props: responderProps,
6129 responder: responder,
6130 rootEventTypes: null,
6131 state: responderState,
6132 target: target
6133 };
6134}
6135
6136var NoEffect$1 = /* */0;
6137var UnmountSnapshot = /* */2;
6138var UnmountMutation = /* */4;
6139var MountMutation = /* */8;
6140var UnmountLayout = /* */16;
6141var MountLayout = /* */32;
6142var MountPassive = /* */64;
6143var UnmountPassive = /* */128;
6144
6145var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
6146
6147
6148var didWarnAboutMismatchedHooksForComponent = void 0;
6149{
6150 didWarnAboutMismatchedHooksForComponent = new Set();
6151}
6152
6153// These are set right before calling the component.
6154var renderExpirationTime$1 = NoWork;
6155// The work-in-progress fiber. I've named it differently to distinguish it from
6156// the work-in-progress hook.
6157var currentlyRenderingFiber$1 = null;
6158
6159// Hooks are stored as a linked list on the fiber's memoizedState field. The
6160// current hook list is the list that belongs to the current fiber. The
6161// work-in-progress hook list is a new list that will be added to the
6162// work-in-progress fiber.
6163var currentHook = null;
6164var nextCurrentHook = null;
6165var firstWorkInProgressHook = null;
6166var workInProgressHook = null;
6167var nextWorkInProgressHook = null;
6168
6169var remainingExpirationTime = NoWork;
6170var componentUpdateQueue = null;
6171var sideEffectTag = 0;
6172
6173// Updates scheduled during render will trigger an immediate re-render at the
6174// end of the current pass. We can't store these updates on the normal queue,
6175// because if the work is aborted, they should be discarded. Because this is
6176// a relatively rare case, we also don't want to add an additional field to
6177// either the hook or queue object types. So we store them in a lazily create
6178// map of queue -> render-phase updates, which are discarded once the component
6179// completes without re-rendering.
6180
6181// Whether an update was scheduled during the currently executing render pass.
6182var didScheduleRenderPhaseUpdate = false;
6183// Lazily created map of render-phase updates
6184var renderPhaseUpdates = null;
6185// Counter to prevent infinite loops.
6186var numberOfReRenders = 0;
6187var RE_RENDER_LIMIT = 25;
6188
6189// In DEV, this is the name of the currently executing primitive hook
6190var currentHookNameInDev = null;
6191
6192// In DEV, this list ensures that hooks are called in the same order between renders.
6193// The list stores the order of hooks used during the initial render (mount).
6194// Subsequent renders (updates) reference this list.
6195var hookTypesDev = null;
6196var hookTypesUpdateIndexDev = -1;
6197
6198// In DEV, this tracks whether currently rendering component needs to ignore
6199// the dependencies for Hooks that need them (e.g. useEffect or useMemo).
6200// When true, such Hooks will always be "remounted". Only used during hot reload.
6201var ignorePreviousDependencies = false;
6202
6203function mountHookTypesDev() {
6204 {
6205 var hookName = currentHookNameInDev;
6206
6207 if (hookTypesDev === null) {
6208 hookTypesDev = [hookName];
6209 } else {
6210 hookTypesDev.push(hookName);
6211 }
6212 }
6213}
6214
6215function updateHookTypesDev() {
6216 {
6217 var hookName = currentHookNameInDev;
6218
6219 if (hookTypesDev !== null) {
6220 hookTypesUpdateIndexDev++;
6221 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
6222 warnOnHookMismatchInDev(hookName);
6223 }
6224 }
6225 }
6226}
6227
6228function checkDepsAreArrayDev(deps) {
6229 {
6230 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
6231 // Verify deps, but only on mount to avoid extra checks.
6232 // It's unlikely their type would change as usually you define them inline.
6233 warning$1(false, '%s received a final argument that is not an array (instead, received `%s`). When ' + 'specified, the final argument must be an array.', currentHookNameInDev, typeof deps);
6234 }
6235 }
6236}
6237
6238function warnOnHookMismatchInDev(currentHookName) {
6239 {
6240 var componentName = getComponentName(currentlyRenderingFiber$1.type);
6241 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
6242 didWarnAboutMismatchedHooksForComponent.add(componentName);
6243
6244 if (hookTypesDev !== null) {
6245 var table = '';
6246
6247 var secondColumnStart = 30;
6248
6249 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
6250 var oldHookName = hookTypesDev[i];
6251 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
6252
6253 var row = i + 1 + '. ' + oldHookName;
6254
6255 // Extra space so second column lines up
6256 // lol @ IE not supporting String#repeat
6257 while (row.length < secondColumnStart) {
6258 row += ' ';
6259 }
6260
6261 row += newHookName + '\n';
6262
6263 table += row;
6264 }
6265
6266 warning$1(false, 'React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://fb.me/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' ------------------------------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table);
6267 }
6268 }
6269 }
6270}
6271
6272function throwInvalidHookError() {
6273 (function () {
6274 {
6275 {
6276 throw ReactError(Error('Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.'));
6277 }
6278 }
6279 })();
6280}
6281
6282function areHookInputsEqual(nextDeps, prevDeps) {
6283 {
6284 if (ignorePreviousDependencies) {
6285 // Only true when this component is being hot reloaded.
6286 return false;
6287 }
6288 }
6289
6290 if (prevDeps === null) {
6291 {
6292 warning$1(false, '%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', currentHookNameInDev);
6293 }
6294 return false;
6295 }
6296
6297 {
6298 // Don't bother comparing lengths in prod because these arrays should be
6299 // passed inline.
6300 if (nextDeps.length !== prevDeps.length) {
6301 warning$1(false, 'The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + 'Incoming: %s', currentHookNameInDev, '[' + prevDeps.join(', ') + ']', '[' + nextDeps.join(', ') + ']');
6302 }
6303 }
6304 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
6305 if (is(nextDeps[i], prevDeps[i])) {
6306 continue;
6307 }
6308 return false;
6309 }
6310 return true;
6311}
6312
6313function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
6314 renderExpirationTime$1 = nextRenderExpirationTime;
6315 currentlyRenderingFiber$1 = workInProgress;
6316 nextCurrentHook = current !== null ? current.memoizedState : null;
6317
6318 {
6319 hookTypesDev = current !== null ? current._debugHookTypes : null;
6320 hookTypesUpdateIndexDev = -1;
6321 // Used for hot reloading:
6322 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
6323 }
6324
6325 // The following should have already been reset
6326 // currentHook = null;
6327 // workInProgressHook = null;
6328
6329 // remainingExpirationTime = NoWork;
6330 // componentUpdateQueue = null;
6331
6332 // didScheduleRenderPhaseUpdate = false;
6333 // renderPhaseUpdates = null;
6334 // numberOfReRenders = 0;
6335 // sideEffectTag = 0;
6336
6337 // TODO Warn if no hooks are used at all during mount, then some are used during update.
6338 // Currently we will identify the update render as a mount because nextCurrentHook === null.
6339 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
6340
6341 // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used.
6342 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
6343 // so nextCurrentHook would be null during updates and mounts.
6344 {
6345 if (nextCurrentHook !== null) {
6346 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
6347 } else if (hookTypesDev !== null) {
6348 // This dispatcher handles an edge case where a component is updating,
6349 // but no stateful hooks have been used.
6350 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
6351 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
6352 // This dispatcher does that.
6353 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
6354 } else {
6355 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
6356 }
6357 }
6358
6359 var children = Component(props, refOrContext);
6360
6361 if (didScheduleRenderPhaseUpdate) {
6362 do {
6363 didScheduleRenderPhaseUpdate = false;
6364 numberOfReRenders += 1;
6365
6366 // Start over from the beginning of the list
6367 nextCurrentHook = current !== null ? current.memoizedState : null;
6368 nextWorkInProgressHook = firstWorkInProgressHook;
6369
6370 currentHook = null;
6371 workInProgressHook = null;
6372 componentUpdateQueue = null;
6373
6374 {
6375 // Also validate hook order for cascading updates.
6376 hookTypesUpdateIndexDev = -1;
6377 }
6378
6379 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
6380
6381 children = Component(props, refOrContext);
6382 } while (didScheduleRenderPhaseUpdate);
6383
6384 renderPhaseUpdates = null;
6385 numberOfReRenders = 0;
6386 }
6387
6388 // We can assume the previous dispatcher is always this one, since we set it
6389 // at the beginning of the render phase and there's no re-entrancy.
6390 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
6391
6392 var renderedWork = currentlyRenderingFiber$1;
6393
6394 renderedWork.memoizedState = firstWorkInProgressHook;
6395 renderedWork.expirationTime = remainingExpirationTime;
6396 renderedWork.updateQueue = componentUpdateQueue;
6397 renderedWork.effectTag |= sideEffectTag;
6398
6399 {
6400 renderedWork._debugHookTypes = hookTypesDev;
6401 }
6402
6403 // This check uses currentHook so that it works the same in DEV and prod bundles.
6404 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
6405 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
6406
6407 renderExpirationTime$1 = NoWork;
6408 currentlyRenderingFiber$1 = null;
6409
6410 currentHook = null;
6411 nextCurrentHook = null;
6412 firstWorkInProgressHook = null;
6413 workInProgressHook = null;
6414 nextWorkInProgressHook = null;
6415
6416 {
6417 currentHookNameInDev = null;
6418 hookTypesDev = null;
6419 hookTypesUpdateIndexDev = -1;
6420 }
6421
6422 remainingExpirationTime = NoWork;
6423 componentUpdateQueue = null;
6424 sideEffectTag = 0;
6425
6426 // These were reset above
6427 // didScheduleRenderPhaseUpdate = false;
6428 // renderPhaseUpdates = null;
6429 // numberOfReRenders = 0;
6430
6431 (function () {
6432 if (!!didRenderTooFewHooks) {
6433 {
6434 throw ReactError(Error('Rendered fewer hooks than expected. This may be caused by an accidental early return statement.'));
6435 }
6436 }
6437 })();
6438
6439 return children;
6440}
6441
6442function bailoutHooks(current, workInProgress, expirationTime) {
6443 workInProgress.updateQueue = current.updateQueue;
6444 workInProgress.effectTag &= ~(Passive | Update);
6445 if (current.expirationTime <= expirationTime) {
6446 current.expirationTime = NoWork;
6447 }
6448}
6449
6450function resetHooks() {
6451 // We can assume the previous dispatcher is always this one, since we set it
6452 // at the beginning of the render phase and there's no re-entrancy.
6453 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
6454
6455 // This is used to reset the state of this module when a component throws.
6456 // It's also called inside mountIndeterminateComponent if we determine the
6457 // component is a module-style component.
6458 renderExpirationTime$1 = NoWork;
6459 currentlyRenderingFiber$1 = null;
6460
6461 currentHook = null;
6462 nextCurrentHook = null;
6463 firstWorkInProgressHook = null;
6464 workInProgressHook = null;
6465 nextWorkInProgressHook = null;
6466
6467 {
6468 hookTypesDev = null;
6469 hookTypesUpdateIndexDev = -1;
6470
6471 currentHookNameInDev = null;
6472 }
6473
6474 remainingExpirationTime = NoWork;
6475 componentUpdateQueue = null;
6476 sideEffectTag = 0;
6477
6478 didScheduleRenderPhaseUpdate = false;
6479 renderPhaseUpdates = null;
6480 numberOfReRenders = 0;
6481}
6482
6483function mountWorkInProgressHook() {
6484 var hook = {
6485 memoizedState: null,
6486
6487 baseState: null,
6488 queue: null,
6489 baseUpdate: null,
6490
6491 next: null
6492 };
6493
6494 if (workInProgressHook === null) {
6495 // This is the first hook in the list
6496 firstWorkInProgressHook = workInProgressHook = hook;
6497 } else {
6498 // Append to the end of the list
6499 workInProgressHook = workInProgressHook.next = hook;
6500 }
6501 return workInProgressHook;
6502}
6503
6504function updateWorkInProgressHook() {
6505 // This function is used both for updates and for re-renders triggered by a
6506 // render phase update. It assumes there is either a current hook we can
6507 // clone, or a work-in-progress hook from a previous render pass that we can
6508 // use as a base. When we reach the end of the base list, we must switch to
6509 // the dispatcher used for mounts.
6510 if (nextWorkInProgressHook !== null) {
6511 // There's already a work-in-progress. Reuse it.
6512 workInProgressHook = nextWorkInProgressHook;
6513 nextWorkInProgressHook = workInProgressHook.next;
6514
6515 currentHook = nextCurrentHook;
6516 nextCurrentHook = currentHook !== null ? currentHook.next : null;
6517 } else {
6518 // Clone from the current hook.
6519 (function () {
6520 if (!(nextCurrentHook !== null)) {
6521 {
6522 throw ReactError(Error('Rendered more hooks than during the previous render.'));
6523 }
6524 }
6525 })();
6526 currentHook = nextCurrentHook;
6527
6528 var newHook = {
6529 memoizedState: currentHook.memoizedState,
6530
6531 baseState: currentHook.baseState,
6532 queue: currentHook.queue,
6533 baseUpdate: currentHook.baseUpdate,
6534
6535 next: null
6536 };
6537
6538 if (workInProgressHook === null) {
6539 // This is the first hook in the list.
6540 workInProgressHook = firstWorkInProgressHook = newHook;
6541 } else {
6542 // Append to the end of the list.
6543 workInProgressHook = workInProgressHook.next = newHook;
6544 }
6545 nextCurrentHook = currentHook.next;
6546 }
6547 return workInProgressHook;
6548}
6549
6550function createFunctionComponentUpdateQueue() {
6551 return {
6552 lastEffect: null
6553 };
6554}
6555
6556function basicStateReducer(state, action) {
6557 return typeof action === 'function' ? action(state) : action;
6558}
6559
6560function mountReducer(reducer, initialArg, init) {
6561 var hook = mountWorkInProgressHook();
6562 var initialState = void 0;
6563 if (init !== undefined) {
6564 initialState = init(initialArg);
6565 } else {
6566 initialState = initialArg;
6567 }
6568 hook.memoizedState = hook.baseState = initialState;
6569 var queue = hook.queue = {
6570 last: null,
6571 dispatch: null,
6572 lastRenderedReducer: reducer,
6573 lastRenderedState: initialState
6574 };
6575 var dispatch = queue.dispatch = dispatchAction.bind(null,
6576 // Flow doesn't know this is non-null, but we do.
6577 currentlyRenderingFiber$1, queue);
6578 return [hook.memoizedState, dispatch];
6579}
6580
6581function updateReducer(reducer, initialArg, init) {
6582 var hook = updateWorkInProgressHook();
6583 var queue = hook.queue;
6584 (function () {
6585 if (!(queue !== null)) {
6586 {
6587 throw ReactError(Error('Should have a queue. This is likely a bug in React. Please file an issue.'));
6588 }
6589 }
6590 })();
6591
6592 queue.lastRenderedReducer = reducer;
6593
6594 if (numberOfReRenders > 0) {
6595 // This is a re-render. Apply the new render phase updates to the previous
6596 var _dispatch = queue.dispatch;
6597 if (renderPhaseUpdates !== null) {
6598 // Render phase updates are stored in a map of queue -> linked list
6599 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
6600 if (firstRenderPhaseUpdate !== undefined) {
6601 renderPhaseUpdates.delete(queue);
6602 var newState = hook.memoizedState;
6603 var update = firstRenderPhaseUpdate;
6604 do {
6605 // Process this render phase update. We don't have to check the
6606 // priority because it will always be the same as the current
6607 // render's.
6608 var _action = update.action;
6609 newState = reducer(newState, _action);
6610 update = update.next;
6611 } while (update !== null);
6612
6613 // Mark that the fiber performed work, but only if the new state is
6614 // different from the current state.
6615 if (!is(newState, hook.memoizedState)) {
6616 markWorkInProgressReceivedUpdate();
6617 }
6618
6619 hook.memoizedState = newState;
6620 // Don't persist the state accumulated from the render phase updates to
6621 // the base state unless the queue is empty.
6622 // TODO: Not sure if this is the desired semantics, but it's what we
6623 // do for gDSFP. I can't remember why.
6624 if (hook.baseUpdate === queue.last) {
6625 hook.baseState = newState;
6626 }
6627
6628 queue.lastRenderedState = newState;
6629
6630 return [newState, _dispatch];
6631 }
6632 }
6633 return [hook.memoizedState, _dispatch];
6634 }
6635
6636 // The last update in the entire queue
6637 var last = queue.last;
6638 // The last update that is part of the base state.
6639 var baseUpdate = hook.baseUpdate;
6640 var baseState = hook.baseState;
6641
6642 // Find the first unprocessed update.
6643 var first = void 0;
6644 if (baseUpdate !== null) {
6645 if (last !== null) {
6646 // For the first update, the queue is a circular linked list where
6647 // `queue.last.next = queue.first`. Once the first update commits, and
6648 // the `baseUpdate` is no longer empty, we can unravel the list.
6649 last.next = null;
6650 }
6651 first = baseUpdate.next;
6652 } else {
6653 first = last !== null ? last.next : null;
6654 }
6655 if (first !== null) {
6656 var _newState = baseState;
6657 var newBaseState = null;
6658 var newBaseUpdate = null;
6659 var prevUpdate = baseUpdate;
6660 var _update = first;
6661 var didSkip = false;
6662 do {
6663 var updateExpirationTime = _update.expirationTime;
6664 if (updateExpirationTime < renderExpirationTime$1) {
6665 // Priority is insufficient. Skip this update. If this is the first
6666 // skipped update, the previous update/state is the new base
6667 // update/state.
6668 if (!didSkip) {
6669 didSkip = true;
6670 newBaseUpdate = prevUpdate;
6671 newBaseState = _newState;
6672 }
6673 // Update the remaining priority in the queue.
6674 if (updateExpirationTime > remainingExpirationTime) {
6675 remainingExpirationTime = updateExpirationTime;
6676 }
6677 } else {
6678 // This update does have sufficient priority.
6679
6680 // Mark the event time of this update as relevant to this render pass.
6681 // TODO: This should ideally use the true event time of this update rather than
6682 // its priority which is a derived and not reverseable value.
6683 // TODO: We should skip this update if it was already committed but currently
6684 // we have no way of detecting the difference between a committed and suspended
6685 // update here.
6686 markRenderEventTimeAndConfig(updateExpirationTime, _update.suspenseConfig);
6687
6688 // Process this update.
6689 if (_update.eagerReducer === reducer) {
6690 // If this update was processed eagerly, and its reducer matches the
6691 // current reducer, we can use the eagerly computed state.
6692 _newState = _update.eagerState;
6693 } else {
6694 var _action2 = _update.action;
6695 _newState = reducer(_newState, _action2);
6696 }
6697 }
6698 prevUpdate = _update;
6699 _update = _update.next;
6700 } while (_update !== null && _update !== first);
6701
6702 if (!didSkip) {
6703 newBaseUpdate = prevUpdate;
6704 newBaseState = _newState;
6705 }
6706
6707 // Mark that the fiber performed work, but only if the new state is
6708 // different from the current state.
6709 if (!is(_newState, hook.memoizedState)) {
6710 markWorkInProgressReceivedUpdate();
6711 }
6712
6713 hook.memoizedState = _newState;
6714 hook.baseUpdate = newBaseUpdate;
6715 hook.baseState = newBaseState;
6716
6717 queue.lastRenderedState = _newState;
6718 }
6719
6720 var dispatch = queue.dispatch;
6721 return [hook.memoizedState, dispatch];
6722}
6723
6724function mountState(initialState) {
6725 var hook = mountWorkInProgressHook();
6726 if (typeof initialState === 'function') {
6727 initialState = initialState();
6728 }
6729 hook.memoizedState = hook.baseState = initialState;
6730 var queue = hook.queue = {
6731 last: null,
6732 dispatch: null,
6733 lastRenderedReducer: basicStateReducer,
6734 lastRenderedState: initialState
6735 };
6736 var dispatch = queue.dispatch = dispatchAction.bind(null,
6737 // Flow doesn't know this is non-null, but we do.
6738 currentlyRenderingFiber$1, queue);
6739 return [hook.memoizedState, dispatch];
6740}
6741
6742function updateState(initialState) {
6743 return updateReducer(basicStateReducer, initialState);
6744}
6745
6746function pushEffect(tag, create, destroy, deps) {
6747 var effect = {
6748 tag: tag,
6749 create: create,
6750 destroy: destroy,
6751 deps: deps,
6752 // Circular
6753 next: null
6754 };
6755 if (componentUpdateQueue === null) {
6756 componentUpdateQueue = createFunctionComponentUpdateQueue();
6757 componentUpdateQueue.lastEffect = effect.next = effect;
6758 } else {
6759 var _lastEffect = componentUpdateQueue.lastEffect;
6760 if (_lastEffect === null) {
6761 componentUpdateQueue.lastEffect = effect.next = effect;
6762 } else {
6763 var firstEffect = _lastEffect.next;
6764 _lastEffect.next = effect;
6765 effect.next = firstEffect;
6766 componentUpdateQueue.lastEffect = effect;
6767 }
6768 }
6769 return effect;
6770}
6771
6772function mountRef(initialValue) {
6773 var hook = mountWorkInProgressHook();
6774 var ref = { current: initialValue };
6775 {
6776 Object.seal(ref);
6777 }
6778 hook.memoizedState = ref;
6779 return ref;
6780}
6781
6782function updateRef(initialValue) {
6783 var hook = updateWorkInProgressHook();
6784 return hook.memoizedState;
6785}
6786
6787function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
6788 var hook = mountWorkInProgressHook();
6789 var nextDeps = deps === undefined ? null : deps;
6790 sideEffectTag |= fiberEffectTag;
6791 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);
6792}
6793
6794function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
6795 var hook = updateWorkInProgressHook();
6796 var nextDeps = deps === undefined ? null : deps;
6797 var destroy = undefined;
6798
6799 if (currentHook !== null) {
6800 var prevEffect = currentHook.memoizedState;
6801 destroy = prevEffect.destroy;
6802 if (nextDeps !== null) {
6803 var prevDeps = prevEffect.deps;
6804 if (areHookInputsEqual(nextDeps, prevDeps)) {
6805 pushEffect(NoEffect$1, create, destroy, nextDeps);
6806 return;
6807 }
6808 }
6809 }
6810
6811 sideEffectTag |= fiberEffectTag;
6812 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);
6813}
6814
6815function mountEffect(create, deps) {
6816 {
6817 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
6818 if ('undefined' !== typeof jest) {
6819 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
6820 }
6821 }
6822 return mountEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
6823}
6824
6825function updateEffect(create, deps) {
6826 {
6827 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
6828 if ('undefined' !== typeof jest) {
6829 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
6830 }
6831 }
6832 return updateEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
6833}
6834
6835function mountLayoutEffect(create, deps) {
6836 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
6837}
6838
6839function updateLayoutEffect(create, deps) {
6840 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
6841}
6842
6843function imperativeHandleEffect(create, ref) {
6844 if (typeof ref === 'function') {
6845 var refCallback = ref;
6846 var _inst = create();
6847 refCallback(_inst);
6848 return function () {
6849 refCallback(null);
6850 };
6851 } else if (ref !== null && ref !== undefined) {
6852 var refObject = ref;
6853 {
6854 !refObject.hasOwnProperty('current') ? warning$1(false, 'Expected useImperativeHandle() first argument to either be a ' + 'ref callback or React.createRef() object. Instead received: %s.', 'an object with keys {' + Object.keys(refObject).join(', ') + '}') : void 0;
6855 }
6856 var _inst2 = create();
6857 refObject.current = _inst2;
6858 return function () {
6859 refObject.current = null;
6860 };
6861 }
6862}
6863
6864function mountImperativeHandle(ref, create, deps) {
6865 {
6866 !(typeof create === 'function') ? warning$1(false, 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null') : void 0;
6867 }
6868
6869 // TODO: If deps are provided, should we skip comparing the ref itself?
6870 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6871
6872 return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6873}
6874
6875function updateImperativeHandle(ref, create, deps) {
6876 {
6877 !(typeof create === 'function') ? warning$1(false, 'Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null') : void 0;
6878 }
6879
6880 // TODO: If deps are provided, should we skip comparing the ref itself?
6881 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
6882
6883 return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
6884}
6885
6886function mountDebugValue(value, formatterFn) {
6887 // This hook is normally a no-op.
6888 // The react-debug-hooks package injects its own implementation
6889 // so that e.g. DevTools can display custom hook values.
6890}
6891
6892var updateDebugValue = mountDebugValue;
6893
6894function mountCallback(callback, deps) {
6895 var hook = mountWorkInProgressHook();
6896 var nextDeps = deps === undefined ? null : deps;
6897 hook.memoizedState = [callback, nextDeps];
6898 return callback;
6899}
6900
6901function updateCallback(callback, deps) {
6902 var hook = updateWorkInProgressHook();
6903 var nextDeps = deps === undefined ? null : deps;
6904 var prevState = hook.memoizedState;
6905 if (prevState !== null) {
6906 if (nextDeps !== null) {
6907 var prevDeps = prevState[1];
6908 if (areHookInputsEqual(nextDeps, prevDeps)) {
6909 return prevState[0];
6910 }
6911 }
6912 }
6913 hook.memoizedState = [callback, nextDeps];
6914 return callback;
6915}
6916
6917function mountMemo(nextCreate, deps) {
6918 var hook = mountWorkInProgressHook();
6919 var nextDeps = deps === undefined ? null : deps;
6920 var nextValue = nextCreate();
6921 hook.memoizedState = [nextValue, nextDeps];
6922 return nextValue;
6923}
6924
6925function updateMemo(nextCreate, deps) {
6926 var hook = updateWorkInProgressHook();
6927 var nextDeps = deps === undefined ? null : deps;
6928 var prevState = hook.memoizedState;
6929 if (prevState !== null) {
6930 // Assume these are defined. If they're not, areHookInputsEqual will warn.
6931 if (nextDeps !== null) {
6932 var prevDeps = prevState[1];
6933 if (areHookInputsEqual(nextDeps, prevDeps)) {
6934 return prevState[0];
6935 }
6936 }
6937 }
6938 var nextValue = nextCreate();
6939 hook.memoizedState = [nextValue, nextDeps];
6940 return nextValue;
6941}
6942
6943function dispatchAction(fiber, queue, action) {
6944 (function () {
6945 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {
6946 {
6947 throw ReactError(Error('Too many re-renders. React limits the number of renders to prevent an infinite loop.'));
6948 }
6949 }
6950 })();
6951
6952 {
6953 !(arguments.length <= 3) ? warning$1(false, "State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().') : void 0;
6954 }
6955
6956 var alternate = fiber.alternate;
6957 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
6958 // This is a render phase update. Stash it in a lazily-created map of
6959 // queue -> linked list of updates. After this render pass, we'll restart
6960 // and apply the stashed updates on top of the work-in-progress hook.
6961 didScheduleRenderPhaseUpdate = true;
6962 var update = {
6963 expirationTime: renderExpirationTime$1,
6964 suspenseConfig: null,
6965 action: action,
6966 eagerReducer: null,
6967 eagerState: null,
6968 next: null
6969 };
6970 {
6971 update.priority = getCurrentPriorityLevel();
6972 }
6973 if (renderPhaseUpdates === null) {
6974 renderPhaseUpdates = new Map();
6975 }
6976 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
6977 if (firstRenderPhaseUpdate === undefined) {
6978 renderPhaseUpdates.set(queue, update);
6979 } else {
6980 // Append the update to the end of the list.
6981 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
6982 while (lastRenderPhaseUpdate.next !== null) {
6983 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
6984 }
6985 lastRenderPhaseUpdate.next = update;
6986 }
6987 } else {
6988 if (revertPassiveEffectsChange) {
6989 flushPassiveEffects();
6990 }
6991
6992 var currentTime = requestCurrentTime();
6993 var _suspenseConfig = requestCurrentSuspenseConfig();
6994 var _expirationTime = computeExpirationForFiber(currentTime, fiber, _suspenseConfig);
6995
6996 var _update2 = {
6997 expirationTime: _expirationTime,
6998 suspenseConfig: _suspenseConfig,
6999 action: action,
7000 eagerReducer: null,
7001 eagerState: null,
7002 next: null
7003 };
7004
7005 {
7006 _update2.priority = getCurrentPriorityLevel();
7007 }
7008
7009 // Append the update to the end of the list.
7010 var _last = queue.last;
7011 if (_last === null) {
7012 // This is the first update. Create a circular list.
7013 _update2.next = _update2;
7014 } else {
7015 var first = _last.next;
7016 if (first !== null) {
7017 // Still circular.
7018 _update2.next = first;
7019 }
7020 _last.next = _update2;
7021 }
7022 queue.last = _update2;
7023
7024 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
7025 // The queue is currently empty, which means we can eagerly compute the
7026 // next state before entering the render phase. If the new state is the
7027 // same as the current state, we may be able to bail out entirely.
7028 var _lastRenderedReducer = queue.lastRenderedReducer;
7029 if (_lastRenderedReducer !== null) {
7030 var prevDispatcher = void 0;
7031 {
7032 prevDispatcher = ReactCurrentDispatcher$1.current;
7033 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7034 }
7035 try {
7036 var currentState = queue.lastRenderedState;
7037 var _eagerState = _lastRenderedReducer(currentState, action);
7038 // Stash the eagerly computed state, and the reducer used to compute
7039 // it, on the update object. If the reducer hasn't changed by the
7040 // time we enter the render phase, then the eager state can be used
7041 // without calling the reducer again.
7042 _update2.eagerReducer = _lastRenderedReducer;
7043 _update2.eagerState = _eagerState;
7044 if (is(_eagerState, currentState)) {
7045 // Fast path. We can bail out without scheduling React to re-render.
7046 // It's still possible that we'll need to rebase this update later,
7047 // if the component re-renders for a different reason and by that
7048 // time the reducer has changed.
7049 return;
7050 }
7051 } catch (error) {
7052 // Suppress the error. It will throw again in the render phase.
7053 } finally {
7054 {
7055 ReactCurrentDispatcher$1.current = prevDispatcher;
7056 }
7057 }
7058 }
7059 }
7060 {
7061 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
7062 if ('undefined' !== typeof jest) {
7063 warnIfNotScopedWithMatchingAct(fiber);
7064 warnIfNotCurrentlyActingUpdatesInDev(fiber);
7065 }
7066 }
7067 scheduleWork(fiber, _expirationTime);
7068 }
7069}
7070
7071var ContextOnlyDispatcher = {
7072 readContext: readContext,
7073
7074 useCallback: throwInvalidHookError,
7075 useContext: throwInvalidHookError,
7076 useEffect: throwInvalidHookError,
7077 useImperativeHandle: throwInvalidHookError,
7078 useLayoutEffect: throwInvalidHookError,
7079 useMemo: throwInvalidHookError,
7080 useReducer: throwInvalidHookError,
7081 useRef: throwInvalidHookError,
7082 useState: throwInvalidHookError,
7083 useDebugValue: throwInvalidHookError,
7084 useResponder: throwInvalidHookError
7085};
7086
7087var HooksDispatcherOnMountInDEV = null;
7088var HooksDispatcherOnMountWithHookTypesInDEV = null;
7089var HooksDispatcherOnUpdateInDEV = null;
7090var InvalidNestedHooksDispatcherOnMountInDEV = null;
7091var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
7092
7093{
7094 var warnInvalidContextAccess = function () {
7095 warning$1(false, 'Context can only be read while React is rendering. ' + 'In classes, you can read it in the render method or getDerivedStateFromProps. ' + 'In function components, you can read it directly in the function body, but not ' + 'inside Hooks like useReducer() or useMemo().');
7096 };
7097
7098 var warnInvalidHookAccess = function () {
7099 warning$1(false, 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' + 'You can only call Hooks at the top level of your React function. ' + 'For more information, see ' + 'https://fb.me/rules-of-hooks');
7100 };
7101
7102 HooksDispatcherOnMountInDEV = {
7103 readContext: function (context, observedBits) {
7104 return readContext(context, observedBits);
7105 },
7106 useCallback: function (callback, deps) {
7107 currentHookNameInDev = 'useCallback';
7108 mountHookTypesDev();
7109 checkDepsAreArrayDev(deps);
7110 return mountCallback(callback, deps);
7111 },
7112 useContext: function (context, observedBits) {
7113 currentHookNameInDev = 'useContext';
7114 mountHookTypesDev();
7115 return readContext(context, observedBits);
7116 },
7117 useEffect: function (create, deps) {
7118 currentHookNameInDev = 'useEffect';
7119 mountHookTypesDev();
7120 checkDepsAreArrayDev(deps);
7121 return mountEffect(create, deps);
7122 },
7123 useImperativeHandle: function (ref, create, deps) {
7124 currentHookNameInDev = 'useImperativeHandle';
7125 mountHookTypesDev();
7126 checkDepsAreArrayDev(deps);
7127 return mountImperativeHandle(ref, create, deps);
7128 },
7129 useLayoutEffect: function (create, deps) {
7130 currentHookNameInDev = 'useLayoutEffect';
7131 mountHookTypesDev();
7132 checkDepsAreArrayDev(deps);
7133 return mountLayoutEffect(create, deps);
7134 },
7135 useMemo: function (create, deps) {
7136 currentHookNameInDev = 'useMemo';
7137 mountHookTypesDev();
7138 checkDepsAreArrayDev(deps);
7139 var prevDispatcher = ReactCurrentDispatcher$1.current;
7140 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7141 try {
7142 return mountMemo(create, deps);
7143 } finally {
7144 ReactCurrentDispatcher$1.current = prevDispatcher;
7145 }
7146 },
7147 useReducer: function (reducer, initialArg, init) {
7148 currentHookNameInDev = 'useReducer';
7149 mountHookTypesDev();
7150 var prevDispatcher = ReactCurrentDispatcher$1.current;
7151 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7152 try {
7153 return mountReducer(reducer, initialArg, init);
7154 } finally {
7155 ReactCurrentDispatcher$1.current = prevDispatcher;
7156 }
7157 },
7158 useRef: function (initialValue) {
7159 currentHookNameInDev = 'useRef';
7160 mountHookTypesDev();
7161 return mountRef(initialValue);
7162 },
7163 useState: function (initialState) {
7164 currentHookNameInDev = 'useState';
7165 mountHookTypesDev();
7166 var prevDispatcher = ReactCurrentDispatcher$1.current;
7167 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7168 try {
7169 return mountState(initialState);
7170 } finally {
7171 ReactCurrentDispatcher$1.current = prevDispatcher;
7172 }
7173 },
7174 useDebugValue: function (value, formatterFn) {
7175 currentHookNameInDev = 'useDebugValue';
7176 mountHookTypesDev();
7177 return mountDebugValue(value, formatterFn);
7178 },
7179 useResponder: function (responder, props) {
7180 currentHookNameInDev = 'useResponder';
7181 mountHookTypesDev();
7182 return createResponderListener(responder, props);
7183 }
7184 };
7185
7186 HooksDispatcherOnMountWithHookTypesInDEV = {
7187 readContext: function (context, observedBits) {
7188 return readContext(context, observedBits);
7189 },
7190 useCallback: function (callback, deps) {
7191 currentHookNameInDev = 'useCallback';
7192 updateHookTypesDev();
7193 return mountCallback(callback, deps);
7194 },
7195 useContext: function (context, observedBits) {
7196 currentHookNameInDev = 'useContext';
7197 updateHookTypesDev();
7198 return readContext(context, observedBits);
7199 },
7200 useEffect: function (create, deps) {
7201 currentHookNameInDev = 'useEffect';
7202 updateHookTypesDev();
7203 return mountEffect(create, deps);
7204 },
7205 useImperativeHandle: function (ref, create, deps) {
7206 currentHookNameInDev = 'useImperativeHandle';
7207 updateHookTypesDev();
7208 return mountImperativeHandle(ref, create, deps);
7209 },
7210 useLayoutEffect: function (create, deps) {
7211 currentHookNameInDev = 'useLayoutEffect';
7212 updateHookTypesDev();
7213 return mountLayoutEffect(create, deps);
7214 },
7215 useMemo: function (create, deps) {
7216 currentHookNameInDev = 'useMemo';
7217 updateHookTypesDev();
7218 var prevDispatcher = ReactCurrentDispatcher$1.current;
7219 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7220 try {
7221 return mountMemo(create, deps);
7222 } finally {
7223 ReactCurrentDispatcher$1.current = prevDispatcher;
7224 }
7225 },
7226 useReducer: function (reducer, initialArg, init) {
7227 currentHookNameInDev = 'useReducer';
7228 updateHookTypesDev();
7229 var prevDispatcher = ReactCurrentDispatcher$1.current;
7230 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7231 try {
7232 return mountReducer(reducer, initialArg, init);
7233 } finally {
7234 ReactCurrentDispatcher$1.current = prevDispatcher;
7235 }
7236 },
7237 useRef: function (initialValue) {
7238 currentHookNameInDev = 'useRef';
7239 updateHookTypesDev();
7240 return mountRef(initialValue);
7241 },
7242 useState: function (initialState) {
7243 currentHookNameInDev = 'useState';
7244 updateHookTypesDev();
7245 var prevDispatcher = ReactCurrentDispatcher$1.current;
7246 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7247 try {
7248 return mountState(initialState);
7249 } finally {
7250 ReactCurrentDispatcher$1.current = prevDispatcher;
7251 }
7252 },
7253 useDebugValue: function (value, formatterFn) {
7254 currentHookNameInDev = 'useDebugValue';
7255 updateHookTypesDev();
7256 return mountDebugValue(value, formatterFn);
7257 },
7258 useResponder: function (responder, props) {
7259 currentHookNameInDev = 'useResponder';
7260 updateHookTypesDev();
7261 return createResponderListener(responder, props);
7262 }
7263 };
7264
7265 HooksDispatcherOnUpdateInDEV = {
7266 readContext: function (context, observedBits) {
7267 return readContext(context, observedBits);
7268 },
7269 useCallback: function (callback, deps) {
7270 currentHookNameInDev = 'useCallback';
7271 updateHookTypesDev();
7272 return updateCallback(callback, deps);
7273 },
7274 useContext: function (context, observedBits) {
7275 currentHookNameInDev = 'useContext';
7276 updateHookTypesDev();
7277 return readContext(context, observedBits);
7278 },
7279 useEffect: function (create, deps) {
7280 currentHookNameInDev = 'useEffect';
7281 updateHookTypesDev();
7282 return updateEffect(create, deps);
7283 },
7284 useImperativeHandle: function (ref, create, deps) {
7285 currentHookNameInDev = 'useImperativeHandle';
7286 updateHookTypesDev();
7287 return updateImperativeHandle(ref, create, deps);
7288 },
7289 useLayoutEffect: function (create, deps) {
7290 currentHookNameInDev = 'useLayoutEffect';
7291 updateHookTypesDev();
7292 return updateLayoutEffect(create, deps);
7293 },
7294 useMemo: function (create, deps) {
7295 currentHookNameInDev = 'useMemo';
7296 updateHookTypesDev();
7297 var prevDispatcher = ReactCurrentDispatcher$1.current;
7298 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7299 try {
7300 return updateMemo(create, deps);
7301 } finally {
7302 ReactCurrentDispatcher$1.current = prevDispatcher;
7303 }
7304 },
7305 useReducer: function (reducer, initialArg, init) {
7306 currentHookNameInDev = 'useReducer';
7307 updateHookTypesDev();
7308 var prevDispatcher = ReactCurrentDispatcher$1.current;
7309 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7310 try {
7311 return updateReducer(reducer, initialArg, init);
7312 } finally {
7313 ReactCurrentDispatcher$1.current = prevDispatcher;
7314 }
7315 },
7316 useRef: function (initialValue) {
7317 currentHookNameInDev = 'useRef';
7318 updateHookTypesDev();
7319 return updateRef(initialValue);
7320 },
7321 useState: function (initialState) {
7322 currentHookNameInDev = 'useState';
7323 updateHookTypesDev();
7324 var prevDispatcher = ReactCurrentDispatcher$1.current;
7325 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7326 try {
7327 return updateState(initialState);
7328 } finally {
7329 ReactCurrentDispatcher$1.current = prevDispatcher;
7330 }
7331 },
7332 useDebugValue: function (value, formatterFn) {
7333 currentHookNameInDev = 'useDebugValue';
7334 updateHookTypesDev();
7335 return updateDebugValue(value, formatterFn);
7336 },
7337 useResponder: function (responder, props) {
7338 currentHookNameInDev = 'useResponder';
7339 updateHookTypesDev();
7340 return createResponderListener(responder, props);
7341 }
7342 };
7343
7344 InvalidNestedHooksDispatcherOnMountInDEV = {
7345 readContext: function (context, observedBits) {
7346 warnInvalidContextAccess();
7347 return readContext(context, observedBits);
7348 },
7349 useCallback: function (callback, deps) {
7350 currentHookNameInDev = 'useCallback';
7351 warnInvalidHookAccess();
7352 mountHookTypesDev();
7353 return mountCallback(callback, deps);
7354 },
7355 useContext: function (context, observedBits) {
7356 currentHookNameInDev = 'useContext';
7357 warnInvalidHookAccess();
7358 mountHookTypesDev();
7359 return readContext(context, observedBits);
7360 },
7361 useEffect: function (create, deps) {
7362 currentHookNameInDev = 'useEffect';
7363 warnInvalidHookAccess();
7364 mountHookTypesDev();
7365 return mountEffect(create, deps);
7366 },
7367 useImperativeHandle: function (ref, create, deps) {
7368 currentHookNameInDev = 'useImperativeHandle';
7369 warnInvalidHookAccess();
7370 mountHookTypesDev();
7371 return mountImperativeHandle(ref, create, deps);
7372 },
7373 useLayoutEffect: function (create, deps) {
7374 currentHookNameInDev = 'useLayoutEffect';
7375 warnInvalidHookAccess();
7376 mountHookTypesDev();
7377 return mountLayoutEffect(create, deps);
7378 },
7379 useMemo: function (create, deps) {
7380 currentHookNameInDev = 'useMemo';
7381 warnInvalidHookAccess();
7382 mountHookTypesDev();
7383 var prevDispatcher = ReactCurrentDispatcher$1.current;
7384 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7385 try {
7386 return mountMemo(create, deps);
7387 } finally {
7388 ReactCurrentDispatcher$1.current = prevDispatcher;
7389 }
7390 },
7391 useReducer: function (reducer, initialArg, init) {
7392 currentHookNameInDev = 'useReducer';
7393 warnInvalidHookAccess();
7394 mountHookTypesDev();
7395 var prevDispatcher = ReactCurrentDispatcher$1.current;
7396 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7397 try {
7398 return mountReducer(reducer, initialArg, init);
7399 } finally {
7400 ReactCurrentDispatcher$1.current = prevDispatcher;
7401 }
7402 },
7403 useRef: function (initialValue) {
7404 currentHookNameInDev = 'useRef';
7405 warnInvalidHookAccess();
7406 mountHookTypesDev();
7407 return mountRef(initialValue);
7408 },
7409 useState: function (initialState) {
7410 currentHookNameInDev = 'useState';
7411 warnInvalidHookAccess();
7412 mountHookTypesDev();
7413 var prevDispatcher = ReactCurrentDispatcher$1.current;
7414 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
7415 try {
7416 return mountState(initialState);
7417 } finally {
7418 ReactCurrentDispatcher$1.current = prevDispatcher;
7419 }
7420 },
7421 useDebugValue: function (value, formatterFn) {
7422 currentHookNameInDev = 'useDebugValue';
7423 warnInvalidHookAccess();
7424 mountHookTypesDev();
7425 return mountDebugValue(value, formatterFn);
7426 },
7427 useResponder: function (responder, props) {
7428 currentHookNameInDev = 'useResponder';
7429 warnInvalidHookAccess();
7430 mountHookTypesDev();
7431 return createResponderListener(responder, props);
7432 }
7433 };
7434
7435 InvalidNestedHooksDispatcherOnUpdateInDEV = {
7436 readContext: function (context, observedBits) {
7437 warnInvalidContextAccess();
7438 return readContext(context, observedBits);
7439 },
7440 useCallback: function (callback, deps) {
7441 currentHookNameInDev = 'useCallback';
7442 warnInvalidHookAccess();
7443 updateHookTypesDev();
7444 return updateCallback(callback, deps);
7445 },
7446 useContext: function (context, observedBits) {
7447 currentHookNameInDev = 'useContext';
7448 warnInvalidHookAccess();
7449 updateHookTypesDev();
7450 return readContext(context, observedBits);
7451 },
7452 useEffect: function (create, deps) {
7453 currentHookNameInDev = 'useEffect';
7454 warnInvalidHookAccess();
7455 updateHookTypesDev();
7456 return updateEffect(create, deps);
7457 },
7458 useImperativeHandle: function (ref, create, deps) {
7459 currentHookNameInDev = 'useImperativeHandle';
7460 warnInvalidHookAccess();
7461 updateHookTypesDev();
7462 return updateImperativeHandle(ref, create, deps);
7463 },
7464 useLayoutEffect: function (create, deps) {
7465 currentHookNameInDev = 'useLayoutEffect';
7466 warnInvalidHookAccess();
7467 updateHookTypesDev();
7468 return updateLayoutEffect(create, deps);
7469 },
7470 useMemo: function (create, deps) {
7471 currentHookNameInDev = 'useMemo';
7472 warnInvalidHookAccess();
7473 updateHookTypesDev();
7474 var prevDispatcher = ReactCurrentDispatcher$1.current;
7475 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7476 try {
7477 return updateMemo(create, deps);
7478 } finally {
7479 ReactCurrentDispatcher$1.current = prevDispatcher;
7480 }
7481 },
7482 useReducer: function (reducer, initialArg, init) {
7483 currentHookNameInDev = 'useReducer';
7484 warnInvalidHookAccess();
7485 updateHookTypesDev();
7486 var prevDispatcher = ReactCurrentDispatcher$1.current;
7487 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7488 try {
7489 return updateReducer(reducer, initialArg, init);
7490 } finally {
7491 ReactCurrentDispatcher$1.current = prevDispatcher;
7492 }
7493 },
7494 useRef: function (initialValue) {
7495 currentHookNameInDev = 'useRef';
7496 warnInvalidHookAccess();
7497 updateHookTypesDev();
7498 return updateRef(initialValue);
7499 },
7500 useState: function (initialState) {
7501 currentHookNameInDev = 'useState';
7502 warnInvalidHookAccess();
7503 updateHookTypesDev();
7504 var prevDispatcher = ReactCurrentDispatcher$1.current;
7505 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
7506 try {
7507 return updateState(initialState);
7508 } finally {
7509 ReactCurrentDispatcher$1.current = prevDispatcher;
7510 }
7511 },
7512 useDebugValue: function (value, formatterFn) {
7513 currentHookNameInDev = 'useDebugValue';
7514 warnInvalidHookAccess();
7515 updateHookTypesDev();
7516 return updateDebugValue(value, formatterFn);
7517 },
7518 useResponder: function (responder, props) {
7519 currentHookNameInDev = 'useResponder';
7520 warnInvalidHookAccess();
7521 updateHookTypesDev();
7522 return createResponderListener(responder, props);
7523 }
7524 };
7525}
7526
7527// Intentionally not named imports because Rollup would use dynamic dispatch for
7528// CommonJS interop named imports.
7529var now$1 = unstable_now;
7530
7531
7532var commitTime = 0;
7533var profilerStartTime = -1;
7534
7535function getCommitTime() {
7536 return commitTime;
7537}
7538
7539function recordCommitTime() {
7540 if (!enableProfilerTimer) {
7541 return;
7542 }
7543 commitTime = now$1();
7544}
7545
7546function startProfilerTimer(fiber) {
7547 if (!enableProfilerTimer) {
7548 return;
7549 }
7550
7551 profilerStartTime = now$1();
7552
7553 if (fiber.actualStartTime < 0) {
7554 fiber.actualStartTime = now$1();
7555 }
7556}
7557
7558function stopProfilerTimerIfRunning(fiber) {
7559 if (!enableProfilerTimer) {
7560 return;
7561 }
7562 profilerStartTime = -1;
7563}
7564
7565function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
7566 if (!enableProfilerTimer) {
7567 return;
7568 }
7569
7570 if (profilerStartTime >= 0) {
7571 var elapsedTime = now$1() - profilerStartTime;
7572 fiber.actualDuration += elapsedTime;
7573 if (overrideBaseTime) {
7574 fiber.selfBaseDuration = elapsedTime;
7575 }
7576 profilerStartTime = -1;
7577 }
7578}
7579
7580// The deepest Fiber on the stack involved in a hydration context.
7581// This may have been an insertion or a hydration.
7582var hydrationParentFiber = null;
7583var nextHydratableInstance = null;
7584var isHydrating = false;
7585
7586function enterHydrationState(fiber) {
7587 if (!supportsHydration) {
7588 return false;
7589 }
7590
7591 var parentInstance = fiber.stateNode.containerInfo;
7592 nextHydratableInstance = getFirstHydratableChild(parentInstance);
7593 hydrationParentFiber = fiber;
7594 isHydrating = true;
7595 return true;
7596}
7597
7598function reenterHydrationStateFromDehydratedSuspenseInstance(fiber) {
7599 if (!supportsHydration) {
7600 return false;
7601 }
7602
7603 var suspenseInstance = fiber.stateNode;
7604 nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
7605 popToNextHostParent(fiber);
7606 isHydrating = true;
7607 return true;
7608}
7609
7610function deleteHydratableInstance(returnFiber, instance) {
7611 {
7612 switch (returnFiber.tag) {
7613 case HostRoot:
7614 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
7615 break;
7616 case HostComponent:
7617 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
7618 break;
7619 }
7620 }
7621
7622 var childToDelete = createFiberFromHostInstanceForDeletion();
7623 childToDelete.stateNode = instance;
7624 childToDelete.return = returnFiber;
7625 childToDelete.effectTag = Deletion;
7626
7627 // This might seem like it belongs on progressedFirstDeletion. However,
7628 // these children are not part of the reconciliation list of children.
7629 // Even if we abort and rereconcile the children, that will try to hydrate
7630 // again and the nodes are still in the host tree so these will be
7631 // recreated.
7632 if (returnFiber.lastEffect !== null) {
7633 returnFiber.lastEffect.nextEffect = childToDelete;
7634 returnFiber.lastEffect = childToDelete;
7635 } else {
7636 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
7637 }
7638}
7639
7640function insertNonHydratedInstance(returnFiber, fiber) {
7641 fiber.effectTag |= Placement;
7642 {
7643 switch (returnFiber.tag) {
7644 case HostRoot:
7645 {
7646 var parentContainer = returnFiber.stateNode.containerInfo;
7647 switch (fiber.tag) {
7648 case HostComponent:
7649 var type = fiber.type;
7650 var props = fiber.pendingProps;
7651 didNotFindHydratableContainerInstance(parentContainer, type, props);
7652 break;
7653 case HostText:
7654 var text = fiber.pendingProps;
7655 didNotFindHydratableContainerTextInstance(parentContainer, text);
7656 break;
7657 case SuspenseComponent:
7658 didNotFindHydratableContainerSuspenseInstance(parentContainer);
7659 break;
7660 }
7661 break;
7662 }
7663 case HostComponent:
7664 {
7665 var parentType = returnFiber.type;
7666 var parentProps = returnFiber.memoizedProps;
7667 var parentInstance = returnFiber.stateNode;
7668 switch (fiber.tag) {
7669 case HostComponent:
7670 var _type = fiber.type;
7671 var _props = fiber.pendingProps;
7672 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
7673 break;
7674 case HostText:
7675 var _text = fiber.pendingProps;
7676 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
7677 break;
7678 case SuspenseComponent:
7679 didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance);
7680 break;
7681 }
7682 break;
7683 }
7684 default:
7685 return;
7686 }
7687 }
7688}
7689
7690function tryHydrate(fiber, nextInstance) {
7691 switch (fiber.tag) {
7692 case HostComponent:
7693 {
7694 var type = fiber.type;
7695 var props = fiber.pendingProps;
7696 var instance = canHydrateInstance(nextInstance, type, props);
7697 if (instance !== null) {
7698 fiber.stateNode = instance;
7699 return true;
7700 }
7701 return false;
7702 }
7703 case HostText:
7704 {
7705 var text = fiber.pendingProps;
7706 var textInstance = canHydrateTextInstance(nextInstance, text);
7707 if (textInstance !== null) {
7708 fiber.stateNode = textInstance;
7709 return true;
7710 }
7711 return false;
7712 }
7713 case SuspenseComponent:
7714 {
7715 if (enableSuspenseServerRenderer) {
7716 var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
7717 if (suspenseInstance !== null) {
7718 // Downgrade the tag to a dehydrated component until we've hydrated it.
7719 fiber.tag = DehydratedSuspenseComponent;
7720 fiber.stateNode = suspenseInstance;
7721 return true;
7722 }
7723 }
7724 return false;
7725 }
7726 default:
7727 return false;
7728 }
7729}
7730
7731function tryToClaimNextHydratableInstance(fiber) {
7732 if (!isHydrating) {
7733 return;
7734 }
7735 var nextInstance = nextHydratableInstance;
7736 if (!nextInstance) {
7737 // Nothing to hydrate. Make it an insertion.
7738 insertNonHydratedInstance(hydrationParentFiber, fiber);
7739 isHydrating = false;
7740 hydrationParentFiber = fiber;
7741 return;
7742 }
7743 var firstAttemptedInstance = nextInstance;
7744 if (!tryHydrate(fiber, nextInstance)) {
7745 // If we can't hydrate this instance let's try the next one.
7746 // We use this as a heuristic. It's based on intuition and not data so it
7747 // might be flawed or unnecessary.
7748 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
7749 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
7750 // Nothing to hydrate. Make it an insertion.
7751 insertNonHydratedInstance(hydrationParentFiber, fiber);
7752 isHydrating = false;
7753 hydrationParentFiber = fiber;
7754 return;
7755 }
7756 // We matched the next one, we'll now assume that the first one was
7757 // superfluous and we'll delete it. Since we can't eagerly delete it
7758 // we'll have to schedule a deletion. To do that, this node needs a dummy
7759 // fiber associated with it.
7760 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
7761 }
7762 hydrationParentFiber = fiber;
7763 nextHydratableInstance = getFirstHydratableChild(nextInstance);
7764}
7765
7766function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
7767 if (!supportsHydration) {
7768 (function () {
7769 {
7770 {
7771 throw ReactError(Error('Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'));
7772 }
7773 }
7774 })();
7775 }
7776
7777 var instance = fiber.stateNode;
7778 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
7779 // TODO: Type this specific to this type of component.
7780 fiber.updateQueue = updatePayload;
7781 // If the update payload indicates that there is a change or if there
7782 // is a new ref we mark this as an update.
7783 if (updatePayload !== null) {
7784 return true;
7785 }
7786 return false;
7787}
7788
7789function prepareToHydrateHostTextInstance(fiber) {
7790 if (!supportsHydration) {
7791 (function () {
7792 {
7793 {
7794 throw ReactError(Error('Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'));
7795 }
7796 }
7797 })();
7798 }
7799
7800 var textInstance = fiber.stateNode;
7801 var textContent = fiber.memoizedProps;
7802 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
7803 {
7804 if (shouldUpdate) {
7805 // We assume that prepareToHydrateHostTextInstance is called in a context where the
7806 // hydration parent is the parent host component of this host text.
7807 var returnFiber = hydrationParentFiber;
7808 if (returnFiber !== null) {
7809 switch (returnFiber.tag) {
7810 case HostRoot:
7811 {
7812 var parentContainer = returnFiber.stateNode.containerInfo;
7813 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
7814 break;
7815 }
7816 case HostComponent:
7817 {
7818 var parentType = returnFiber.type;
7819 var parentProps = returnFiber.memoizedProps;
7820 var parentInstance = returnFiber.stateNode;
7821 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
7822 break;
7823 }
7824 }
7825 }
7826 }
7827 }
7828 return shouldUpdate;
7829}
7830
7831function skipPastDehydratedSuspenseInstance(fiber) {
7832 if (!supportsHydration) {
7833 (function () {
7834 {
7835 {
7836 throw ReactError(Error('Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.'));
7837 }
7838 }
7839 })();
7840 }
7841 var suspenseInstance = fiber.stateNode;
7842 (function () {
7843 if (!suspenseInstance) {
7844 {
7845 throw ReactError(Error('Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.'));
7846 }
7847 }
7848 })();
7849 nextHydratableInstance = getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
7850}
7851
7852function popToNextHostParent(fiber) {
7853 var parent = fiber.return;
7854 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== DehydratedSuspenseComponent) {
7855 parent = parent.return;
7856 }
7857 hydrationParentFiber = parent;
7858}
7859
7860function popHydrationState(fiber) {
7861 if (!supportsHydration) {
7862 return false;
7863 }
7864 if (fiber !== hydrationParentFiber) {
7865 // We're deeper than the current hydration context, inside an inserted
7866 // tree.
7867 return false;
7868 }
7869 if (!isHydrating) {
7870 // If we're not currently hydrating but we're in a hydration context, then
7871 // we were an insertion and now need to pop up reenter hydration of our
7872 // siblings.
7873 popToNextHostParent(fiber);
7874 isHydrating = true;
7875 return false;
7876 }
7877
7878 var type = fiber.type;
7879
7880 // If we have any remaining hydratable nodes, we need to delete them now.
7881 // We only do this deeper than head and body since they tend to have random
7882 // other nodes in them. We also ignore components with pure text content in
7883 // side of them.
7884 // TODO: Better heuristic.
7885 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
7886 var nextInstance = nextHydratableInstance;
7887 while (nextInstance) {
7888 deleteHydratableInstance(fiber, nextInstance);
7889 nextInstance = getNextHydratableSibling(nextInstance);
7890 }
7891 }
7892
7893 popToNextHostParent(fiber);
7894 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
7895 return true;
7896}
7897
7898function resetHydrationState() {
7899 if (!supportsHydration) {
7900 return;
7901 }
7902
7903 hydrationParentFiber = null;
7904 nextHydratableInstance = null;
7905 isHydrating = false;
7906}
7907
7908var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
7909
7910var didReceiveUpdate = false;
7911
7912var didWarnAboutBadClass = void 0;
7913var didWarnAboutModulePatternComponent = void 0;
7914var didWarnAboutContextTypeOnFunctionComponent = void 0;
7915var didWarnAboutGetDerivedStateOnFunctionComponent = void 0;
7916var didWarnAboutFunctionRefs = void 0;
7917var didWarnAboutReassigningProps = void 0;
7918var didWarnAboutMaxDuration = void 0;
7919var didWarnAboutRevealOrder = void 0;
7920var didWarnAboutTailOptions = void 0;
7921var didWarnAboutDefaultPropsOnFunctionComponent = void 0;
7922
7923{
7924 didWarnAboutBadClass = {};
7925 didWarnAboutModulePatternComponent = {};
7926 didWarnAboutContextTypeOnFunctionComponent = {};
7927 didWarnAboutGetDerivedStateOnFunctionComponent = {};
7928 didWarnAboutFunctionRefs = {};
7929 didWarnAboutReassigningProps = false;
7930 didWarnAboutMaxDuration = false;
7931 didWarnAboutRevealOrder = {};
7932 didWarnAboutTailOptions = {};
7933 didWarnAboutDefaultPropsOnFunctionComponent = {};
7934}
7935
7936function reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime) {
7937 if (current === null) {
7938 // If this is a fresh new component that hasn't been rendered yet, we
7939 // won't update its child set by applying minimal side-effects. Instead,
7940 // we will add them all to the child before it gets rendered. That means
7941 // we can optimize this reconciliation pass by not tracking side-effects.
7942 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7943 } else {
7944 // If the current child is the same as the work in progress, it means that
7945 // we haven't yet started any work on these children. Therefore, we use
7946 // the clone algorithm to create a copy of all the current children.
7947
7948 // If we had any progressed work already, that is invalid at this point so
7949 // let's throw it out.
7950 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
7951 }
7952}
7953
7954function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime) {
7955 // This function is fork of reconcileChildren. It's used in cases where we
7956 // want to reconcile without matching against the existing set. This has the
7957 // effect of all current children being unmounted; even if the type and key
7958 // are the same, the old child is unmounted and a new child is created.
7959 //
7960 // To do this, we're going to go through the reconcile algorithm twice. In
7961 // the first pass, we schedule a deletion for all the current children by
7962 // passing null.
7963 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderExpirationTime);
7964 // In the second pass, we mount the new children. The trick here is that we
7965 // pass null in place of where we usually pass the current child set. This has
7966 // the effect of remounting all children regardless of whether their their
7967 // identity matches.
7968 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7969}
7970
7971function updateForwardRef(current, workInProgress, Component, nextProps, renderExpirationTime) {
7972 // TODO: current can be non-null here even if the component
7973 // hasn't yet mounted. This happens after the first render suspends.
7974 // We'll need to figure out if this is fine or can cause issues.
7975
7976 {
7977 if (workInProgress.type !== workInProgress.elementType) {
7978 // Lazy component props can't be validated in createElement
7979 // because they're only guaranteed to be resolved here.
7980 var innerPropTypes = Component.propTypes;
7981 if (innerPropTypes) {
7982 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
7983 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7984 }
7985 }
7986 }
7987
7988 var render = Component.render;
7989 var ref = workInProgress.ref;
7990
7991 // The rest is a fork of updateFunctionComponent
7992 var nextChildren = void 0;
7993 prepareToReadContext(workInProgress, renderExpirationTime);
7994 {
7995 ReactCurrentOwner$2.current = workInProgress;
7996 setCurrentPhase('render');
7997 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
7998 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7999 // Only double-render components with Hooks
8000 if (workInProgress.memoizedState !== null) {
8001 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
8002 }
8003 }
8004 setCurrentPhase(null);
8005 }
8006
8007 if (current !== null && !didReceiveUpdate) {
8008 bailoutHooks(current, workInProgress, renderExpirationTime);
8009 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8010 }
8011
8012 // React DevTools reads this flag.
8013 workInProgress.effectTag |= PerformedWork;
8014 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8015 return workInProgress.child;
8016}
8017
8018function updateMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
8019 if (current === null) {
8020 var type = Component.type;
8021 if (isSimpleFunctionComponent(type) && Component.compare === null &&
8022 // SimpleMemoComponent codepath doesn't resolve outer props either.
8023 Component.defaultProps === undefined) {
8024 var resolvedType = type;
8025 {
8026 resolvedType = resolveFunctionForHotReloading(type);
8027 }
8028 // If this is a plain function component without default props,
8029 // and with only the default shallow comparison, we upgrade it
8030 // to a SimpleMemoComponent to allow fast path updates.
8031 workInProgress.tag = SimpleMemoComponent;
8032 workInProgress.type = resolvedType;
8033 {
8034 validateFunctionComponentInDev(workInProgress, type);
8035 }
8036 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, updateExpirationTime, renderExpirationTime);
8037 }
8038 {
8039 var innerPropTypes = type.propTypes;
8040 if (innerPropTypes) {
8041 // Inner memo component props aren't currently validated in createElement.
8042 // We could move it there, but we'd still need this for lazy code path.
8043 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
8044 'prop', getComponentName(type), getCurrentFiberStackInDev);
8045 }
8046 }
8047 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
8048 child.ref = workInProgress.ref;
8049 child.return = workInProgress;
8050 workInProgress.child = child;
8051 return child;
8052 }
8053 {
8054 var _type = Component.type;
8055 var _innerPropTypes = _type.propTypes;
8056 if (_innerPropTypes) {
8057 // Inner memo component props aren't currently validated in createElement.
8058 // We could move it there, but we'd still need this for lazy code path.
8059 checkPropTypes_1(_innerPropTypes, nextProps, // Resolved props
8060 'prop', getComponentName(_type), getCurrentFiberStackInDev);
8061 }
8062 }
8063 var currentChild = current.child; // This is always exactly one child
8064 if (updateExpirationTime < renderExpirationTime) {
8065 // This will be the props with resolved defaultProps,
8066 // unlike current.memoizedProps which will be the unresolved ones.
8067 var prevProps = currentChild.memoizedProps;
8068 // Default to shallow comparison
8069 var compare = Component.compare;
8070 compare = compare !== null ? compare : shallowEqual;
8071 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
8072 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8073 }
8074 }
8075 // React DevTools reads this flag.
8076 workInProgress.effectTag |= PerformedWork;
8077 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
8078 newChild.ref = workInProgress.ref;
8079 newChild.return = workInProgress;
8080 workInProgress.child = newChild;
8081 return newChild;
8082}
8083
8084function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
8085 // TODO: current can be non-null here even if the component
8086 // hasn't yet mounted. This happens when the inner render suspends.
8087 // We'll need to figure out if this is fine or can cause issues.
8088
8089 {
8090 if (workInProgress.type !== workInProgress.elementType) {
8091 // Lazy component props can't be validated in createElement
8092 // because they're only guaranteed to be resolved here.
8093 var outerMemoType = workInProgress.elementType;
8094 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
8095 // We warn when you define propTypes on lazy()
8096 // so let's just skip over it to find memo() outer wrapper.
8097 // Inner props for memo are validated later.
8098 outerMemoType = refineResolvedLazyComponent(outerMemoType);
8099 }
8100 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
8101 if (outerPropTypes) {
8102 checkPropTypes_1(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
8103 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
8104 }
8105 // Inner propTypes will be validated in the function component path.
8106 }
8107 }
8108 if (current !== null) {
8109 var prevProps = current.memoizedProps;
8110 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && (
8111 // Prevent bailout if the implementation changed due to hot reload:
8112 workInProgress.type === current.type)) {
8113 didReceiveUpdate = false;
8114 if (updateExpirationTime < renderExpirationTime) {
8115 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8116 }
8117 }
8118 }
8119 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime);
8120}
8121
8122function updateFragment(current, workInProgress, renderExpirationTime) {
8123 var nextChildren = workInProgress.pendingProps;
8124 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8125 return workInProgress.child;
8126}
8127
8128function updateMode(current, workInProgress, renderExpirationTime) {
8129 var nextChildren = workInProgress.pendingProps.children;
8130 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8131 return workInProgress.child;
8132}
8133
8134function updateProfiler(current, workInProgress, renderExpirationTime) {
8135 if (enableProfilerTimer) {
8136 workInProgress.effectTag |= Update;
8137 }
8138 var nextProps = workInProgress.pendingProps;
8139 var nextChildren = nextProps.children;
8140 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8141 return workInProgress.child;
8142}
8143
8144function markRef(current, workInProgress) {
8145 var ref = workInProgress.ref;
8146 if (current === null && ref !== null || current !== null && current.ref !== ref) {
8147 // Schedule a Ref effect
8148 workInProgress.effectTag |= Ref;
8149 }
8150}
8151
8152function updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
8153 {
8154 if (workInProgress.type !== workInProgress.elementType) {
8155 // Lazy component props can't be validated in createElement
8156 // because they're only guaranteed to be resolved here.
8157 var innerPropTypes = Component.propTypes;
8158 if (innerPropTypes) {
8159 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
8160 'prop', getComponentName(Component), getCurrentFiberStackInDev);
8161 }
8162 }
8163 }
8164
8165 var context = void 0;
8166 if (!disableLegacyContext) {
8167 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
8168 context = getMaskedContext(workInProgress, unmaskedContext);
8169 }
8170
8171 var nextChildren = void 0;
8172 prepareToReadContext(workInProgress, renderExpirationTime);
8173 {
8174 ReactCurrentOwner$2.current = workInProgress;
8175 setCurrentPhase('render');
8176 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
8177 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8178 // Only double-render components with Hooks
8179 if (workInProgress.memoizedState !== null) {
8180 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
8181 }
8182 }
8183 setCurrentPhase(null);
8184 }
8185
8186 if (current !== null && !didReceiveUpdate) {
8187 bailoutHooks(current, workInProgress, renderExpirationTime);
8188 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8189 }
8190
8191 // React DevTools reads this flag.
8192 workInProgress.effectTag |= PerformedWork;
8193 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8194 return workInProgress.child;
8195}
8196
8197function updateClassComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
8198 {
8199 if (workInProgress.type !== workInProgress.elementType) {
8200 // Lazy component props can't be validated in createElement
8201 // because they're only guaranteed to be resolved here.
8202 var innerPropTypes = Component.propTypes;
8203 if (innerPropTypes) {
8204 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
8205 'prop', getComponentName(Component), getCurrentFiberStackInDev);
8206 }
8207 }
8208 }
8209
8210 // Push context providers early to prevent context stack mismatches.
8211 // During mounting we don't know the child context yet as the instance doesn't exist.
8212 // We will invalidate the child context in finishClassComponent() right after rendering.
8213 var hasContext = void 0;
8214 if (isContextProvider(Component)) {
8215 hasContext = true;
8216 pushContextProvider(workInProgress);
8217 } else {
8218 hasContext = false;
8219 }
8220 prepareToReadContext(workInProgress, renderExpirationTime);
8221
8222 var instance = workInProgress.stateNode;
8223 var shouldUpdate = void 0;
8224 if (instance === null) {
8225 if (current !== null) {
8226 // An class component without an instance only mounts if it suspended
8227 // inside a non- concurrent tree, in an inconsistent state. We want to
8228 // tree it like a new mount, even though an empty version of it already
8229 // committed. Disconnect the alternate pointers.
8230 current.alternate = null;
8231 workInProgress.alternate = null;
8232 // Since this is conceptually a new fiber, schedule a Placement effect
8233 workInProgress.effectTag |= Placement;
8234 }
8235 // In the initial pass we might need to construct the instance.
8236 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8237 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8238 shouldUpdate = true;
8239 } else if (current === null) {
8240 // In a resume, we'll already have an instance we can reuse.
8241 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8242 } else {
8243 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderExpirationTime);
8244 }
8245 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
8246 {
8247 var inst = workInProgress.stateNode;
8248 if (inst.props !== nextProps) {
8249 !didWarnAboutReassigningProps ? warning$1(false, 'It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentName(workInProgress.type) || 'a component') : void 0;
8250 didWarnAboutReassigningProps = true;
8251 }
8252 }
8253 return nextUnitOfWork;
8254}
8255
8256function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
8257 // Refs should update even if shouldComponentUpdate returns false
8258 markRef(current, workInProgress);
8259
8260 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
8261
8262 if (!shouldUpdate && !didCaptureError) {
8263 // Context providers should defer to sCU for rendering
8264 if (hasContext) {
8265 invalidateContextProvider(workInProgress, Component, false);
8266 }
8267
8268 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8269 }
8270
8271 var instance = workInProgress.stateNode;
8272
8273 // Rerender
8274 ReactCurrentOwner$2.current = workInProgress;
8275 var nextChildren = void 0;
8276 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
8277 // If we captured an error, but getDerivedStateFrom catch is not defined,
8278 // unmount all the children. componentDidCatch will schedule an update to
8279 // re-render a fallback. This is temporary until we migrate everyone to
8280 // the new API.
8281 // TODO: Warn in a future release.
8282 nextChildren = null;
8283
8284 if (enableProfilerTimer) {
8285 stopProfilerTimerIfRunning(workInProgress);
8286 }
8287 } else {
8288 {
8289 setCurrentPhase('render');
8290 nextChildren = instance.render();
8291 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8292 instance.render();
8293 }
8294 setCurrentPhase(null);
8295 }
8296 }
8297
8298 // React DevTools reads this flag.
8299 workInProgress.effectTag |= PerformedWork;
8300 if (current !== null && didCaptureError) {
8301 // If we're recovering from an error, reconcile without reusing any of
8302 // the existing children. Conceptually, the normal children and the children
8303 // that are shown on error are two different sets, so we shouldn't reuse
8304 // normal children even if their identities match.
8305 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime);
8306 } else {
8307 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8308 }
8309
8310 // Memoize state using the values we just used to render.
8311 // TODO: Restructure so we never read values from the instance.
8312 workInProgress.memoizedState = instance.state;
8313
8314 // The context might have changed so we need to recalculate it.
8315 if (hasContext) {
8316 invalidateContextProvider(workInProgress, Component, true);
8317 }
8318
8319 return workInProgress.child;
8320}
8321
8322function pushHostRootContext(workInProgress) {
8323 var root = workInProgress.stateNode;
8324 if (root.pendingContext) {
8325 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
8326 } else if (root.context) {
8327 // Should always be set
8328 pushTopLevelContextObject(workInProgress, root.context, false);
8329 }
8330 pushHostContainer(workInProgress, root.containerInfo);
8331}
8332
8333function updateHostRoot(current, workInProgress, renderExpirationTime) {
8334 pushHostRootContext(workInProgress);
8335 var updateQueue = workInProgress.updateQueue;
8336 (function () {
8337 if (!(updateQueue !== null)) {
8338 {
8339 throw ReactError(Error('If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue.'));
8340 }
8341 }
8342 })();
8343 var nextProps = workInProgress.pendingProps;
8344 var prevState = workInProgress.memoizedState;
8345 var prevChildren = prevState !== null ? prevState.element : null;
8346 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
8347 var nextState = workInProgress.memoizedState;
8348 // Caution: React DevTools currently depends on this property
8349 // being called "element".
8350 var nextChildren = nextState.element;
8351 if (nextChildren === prevChildren) {
8352 // If the state is the same as before, that's a bailout because we had
8353 // no work that expires at this time.
8354 resetHydrationState();
8355 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
8356 }
8357 var root = workInProgress.stateNode;
8358 if ((current === null || current.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
8359 // If we don't have any current children this might be the first pass.
8360 // We always try to hydrate. If this isn't a hydration pass there won't
8361 // be any children to hydrate which is effectively the same thing as
8362 // not hydrating.
8363
8364 // This is a bit of a hack. We track the host root as a placement to
8365 // know that we're currently in a mounting state. That way isMounted
8366 // works as expected. We must reset this before committing.
8367 // TODO: Delete this when we delete isMounted and findDOMNode.
8368 workInProgress.effectTag |= Placement;
8369
8370 // Ensure that children mount into this root without tracking
8371 // side-effects. This ensures that we don't store Placement effects on
8372 // nodes that will be hydrated.
8373 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
8374 } else {
8375 // Otherwise reset hydration state in case we aborted and resumed another
8376 // root.
8377 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8378 resetHydrationState();
8379 }
8380 return workInProgress.child;
8381}
8382
8383function updateHostComponent(current, workInProgress, renderExpirationTime) {
8384 pushHostContext(workInProgress);
8385
8386 if (current === null) {
8387 tryToClaimNextHydratableInstance(workInProgress);
8388 }
8389
8390 var type = workInProgress.type;
8391 var nextProps = workInProgress.pendingProps;
8392 var prevProps = current !== null ? current.memoizedProps : null;
8393
8394 var nextChildren = nextProps.children;
8395 var isDirectTextChild = shouldSetTextContent(type, nextProps);
8396
8397 if (isDirectTextChild) {
8398 // We special case a direct text child of a host node. This is a common
8399 // case. We won't handle it as a reified child. We will instead handle
8400 // this in the host environment that also have access to this prop. That
8401 // avoids allocating another HostText fiber and traversing it.
8402 nextChildren = null;
8403 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
8404 // If we're switching from a direct text child to a normal child, or to
8405 // empty, we need to schedule the text content to be reset.
8406 workInProgress.effectTag |= ContentReset;
8407 }
8408
8409 markRef(current, workInProgress);
8410
8411 // Check the host config to see if the children are offscreen/hidden.
8412 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(type, nextProps)) {
8413 if (enableSchedulerTracing) {
8414 markSpawnedWork(Never);
8415 }
8416 // Schedule this fiber to re-render at offscreen priority. Then bailout.
8417 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
8418 return null;
8419 }
8420
8421 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
8422 return workInProgress.child;
8423}
8424
8425function updateHostText(current, workInProgress) {
8426 if (current === null) {
8427 tryToClaimNextHydratableInstance(workInProgress);
8428 }
8429 // Nothing to do here. This is terminal. We'll do the completion step
8430 // immediately after.
8431 return null;
8432}
8433
8434function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
8435 if (_current !== null) {
8436 // An lazy component only mounts if it suspended inside a non-
8437 // concurrent tree, in an inconsistent state. We want to treat it like
8438 // a new mount, even though an empty version of it already committed.
8439 // Disconnect the alternate pointers.
8440 _current.alternate = null;
8441 workInProgress.alternate = null;
8442 // Since this is conceptually a new fiber, schedule a Placement effect
8443 workInProgress.effectTag |= Placement;
8444 }
8445
8446 var props = workInProgress.pendingProps;
8447 // We can't start a User Timing measurement with correct label yet.
8448 // Cancel and resume right after we know the tag.
8449 cancelWorkTimer(workInProgress);
8450 var Component = readLazyComponentType(elementType);
8451 // Store the unwrapped component in the type.
8452 workInProgress.type = Component;
8453 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
8454 startWorkTimer(workInProgress);
8455 var resolvedProps = resolveDefaultProps(Component, props);
8456 var child = void 0;
8457 switch (resolvedTag) {
8458 case FunctionComponent:
8459 {
8460 {
8461 validateFunctionComponentInDev(workInProgress, Component);
8462 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
8463 }
8464 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
8465 break;
8466 }
8467 case ClassComponent:
8468 {
8469 {
8470 workInProgress.type = Component = resolveClassForHotReloading(Component);
8471 }
8472 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
8473 break;
8474 }
8475 case ForwardRef:
8476 {
8477 {
8478 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
8479 }
8480 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
8481 break;
8482 }
8483 case MemoComponent:
8484 {
8485 {
8486 if (workInProgress.type !== workInProgress.elementType) {
8487 var outerPropTypes = Component.propTypes;
8488 if (outerPropTypes) {
8489 checkPropTypes_1(outerPropTypes, resolvedProps, // Resolved for outer only
8490 'prop', getComponentName(Component), getCurrentFiberStackInDev);
8491 }
8492 }
8493 }
8494 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
8495 updateExpirationTime, renderExpirationTime);
8496 break;
8497 }
8498 default:
8499 {
8500 var hint = '';
8501 {
8502 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
8503 hint = ' Did you wrap a component in React.lazy() more than once?';
8504 }
8505 }
8506 // This message intentionally doesn't mention ForwardRef or MemoComponent
8507 // because the fact that it's a separate type of work is an
8508 // implementation detail.
8509 (function () {
8510 {
8511 {
8512 throw ReactError(Error('Element type is invalid. Received a promise that resolves to: ' + Component + '. Lazy element type must resolve to a class or function.' + hint));
8513 }
8514 }
8515 })();
8516 }
8517 }
8518 return child;
8519}
8520
8521function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
8522 if (_current !== null) {
8523 // An incomplete component only mounts if it suspended inside a non-
8524 // concurrent tree, in an inconsistent state. We want to treat it like
8525 // a new mount, even though an empty version of it already committed.
8526 // Disconnect the alternate pointers.
8527 _current.alternate = null;
8528 workInProgress.alternate = null;
8529 // Since this is conceptually a new fiber, schedule a Placement effect
8530 workInProgress.effectTag |= Placement;
8531 }
8532
8533 // Promote the fiber to a class and try rendering again.
8534 workInProgress.tag = ClassComponent;
8535
8536 // The rest of this function is a fork of `updateClassComponent`
8537
8538 // Push context providers early to prevent context stack mismatches.
8539 // During mounting we don't know the child context yet as the instance doesn't exist.
8540 // We will invalidate the child context in finishClassComponent() right after rendering.
8541 var hasContext = void 0;
8542 if (isContextProvider(Component)) {
8543 hasContext = true;
8544 pushContextProvider(workInProgress);
8545 } else {
8546 hasContext = false;
8547 }
8548 prepareToReadContext(workInProgress, renderExpirationTime);
8549
8550 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8551 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
8552
8553 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
8554}
8555
8556function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
8557 if (_current !== null) {
8558 // An indeterminate component only mounts if it suspended inside a non-
8559 // concurrent tree, in an inconsistent state. We want to treat it like
8560 // a new mount, even though an empty version of it already committed.
8561 // Disconnect the alternate pointers.
8562 _current.alternate = null;
8563 workInProgress.alternate = null;
8564 // Since this is conceptually a new fiber, schedule a Placement effect
8565 workInProgress.effectTag |= Placement;
8566 }
8567
8568 var props = workInProgress.pendingProps;
8569 var context = void 0;
8570 if (!disableLegacyContext) {
8571 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
8572 context = getMaskedContext(workInProgress, unmaskedContext);
8573 }
8574
8575 prepareToReadContext(workInProgress, renderExpirationTime);
8576 var value = void 0;
8577
8578 {
8579 if (Component.prototype && typeof Component.prototype.render === 'function') {
8580 var componentName = getComponentName(Component) || 'Unknown';
8581
8582 if (!didWarnAboutBadClass[componentName]) {
8583 warningWithoutStack$1(false, "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + 'This is likely to cause errors. Change %s to extend React.Component instead.', componentName, componentName);
8584 didWarnAboutBadClass[componentName] = true;
8585 }
8586 }
8587
8588 if (workInProgress.mode & StrictMode) {
8589 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
8590 }
8591
8592 ReactCurrentOwner$2.current = workInProgress;
8593 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
8594 }
8595 // React DevTools reads this flag.
8596 workInProgress.effectTag |= PerformedWork;
8597
8598 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
8599 {
8600 var _componentName = getComponentName(Component) || 'Unknown';
8601 if (!didWarnAboutModulePatternComponent[_componentName]) {
8602 warningWithoutStack$1(false, 'The <%s /> component appears to be a function component that returns a class instance. ' + 'Change %s to a class that extends React.Component instead. ' + "If you can't use a class try assigning the prototype on the function as a workaround. " + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + 'cannot be called with `new` by React.', _componentName, _componentName, _componentName);
8603 didWarnAboutModulePatternComponent[_componentName] = true;
8604 }
8605 }
8606
8607 // Proceed under the assumption that this is a class instance
8608 workInProgress.tag = ClassComponent;
8609
8610 // Throw out any hooks that were used.
8611 resetHooks();
8612
8613 // Push context providers early to prevent context stack mismatches.
8614 // During mounting we don't know the child context yet as the instance doesn't exist.
8615 // We will invalidate the child context in finishClassComponent() right after rendering.
8616 var hasContext = false;
8617 if (isContextProvider(Component)) {
8618 hasContext = true;
8619 pushContextProvider(workInProgress);
8620 } else {
8621 hasContext = false;
8622 }
8623
8624 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
8625
8626 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
8627 if (typeof getDerivedStateFromProps === 'function') {
8628 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
8629 }
8630
8631 adoptClassInstance(workInProgress, value);
8632 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
8633 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
8634 } else {
8635 // Proceed under the assumption that this is a function component
8636 workInProgress.tag = FunctionComponent;
8637 {
8638 if (disableLegacyContext && Component.contextTypes) {
8639 warningWithoutStack$1(false, '%s uses the legacy contextTypes API which is no longer supported. ' + 'Use React.createContext() with React.useContext() instead.', getComponentName(Component) || 'Unknown');
8640 }
8641
8642 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8643 // Only double-render components with Hooks
8644 if (workInProgress.memoizedState !== null) {
8645 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
8646 }
8647 }
8648 }
8649 reconcileChildren(null, workInProgress, value, renderExpirationTime);
8650 {
8651 validateFunctionComponentInDev(workInProgress, Component);
8652 }
8653 return workInProgress.child;
8654 }
8655}
8656
8657function validateFunctionComponentInDev(workInProgress, Component) {
8658 if (Component) {
8659 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
8660 }
8661 if (workInProgress.ref !== null) {
8662 var info = '';
8663 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
8664 if (ownerName) {
8665 info += '\n\nCheck the render method of `' + ownerName + '`.';
8666 }
8667
8668 var warningKey = ownerName || workInProgress._debugID || '';
8669 var debugSource = workInProgress._debugSource;
8670 if (debugSource) {
8671 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
8672 }
8673 if (!didWarnAboutFunctionRefs[warningKey]) {
8674 didWarnAboutFunctionRefs[warningKey] = true;
8675 warning$1(false, 'Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
8676 }
8677 }
8678
8679 if (warnAboutDefaultPropsOnFunctionComponents && Component.defaultProps !== undefined) {
8680 var componentName = getComponentName(Component) || 'Unknown';
8681
8682 if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) {
8683 warningWithoutStack$1(false, '%s: Support for defaultProps will be removed from function components ' + 'in a future major release. Use JavaScript default parameters instead.', componentName);
8684 didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true;
8685 }
8686 }
8687
8688 if (typeof Component.getDerivedStateFromProps === 'function') {
8689 var _componentName2 = getComponentName(Component) || 'Unknown';
8690
8691 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) {
8692 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', _componentName2);
8693 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true;
8694 }
8695 }
8696
8697 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
8698 var _componentName3 = getComponentName(Component) || 'Unknown';
8699
8700 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) {
8701 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName3);
8702 didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true;
8703 }
8704 }
8705}
8706
8707// TODO: This is now an empty object. Should we just make it a boolean?
8708var SUSPENDED_MARKER = {};
8709
8710function shouldRemainOnFallback(suspenseContext, current, workInProgress) {
8711 // If the context is telling us that we should show a fallback, and we're not
8712 // already showing content, then we should show the fallback instead.
8713 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && (current === null || current.memoizedState !== null);
8714}
8715
8716function updateSuspenseComponent(current, workInProgress, renderExpirationTime) {
8717 var mode = workInProgress.mode;
8718 var nextProps = workInProgress.pendingProps;
8719
8720 // This is used by DevTools to force a boundary to suspend.
8721 {
8722 if (shouldSuspend(workInProgress)) {
8723 workInProgress.effectTag |= DidCapture;
8724 }
8725 }
8726
8727 var suspenseContext = suspenseStackCursor.current;
8728
8729 var nextState = null;
8730 var nextDidTimeout = false;
8731
8732 if ((workInProgress.effectTag & DidCapture) !== NoEffect || shouldRemainOnFallback(suspenseContext, current, workInProgress)) {
8733 // Something in this boundary's subtree already suspended. Switch to
8734 // rendering the fallback children.
8735 nextState = SUSPENDED_MARKER;
8736 nextDidTimeout = true;
8737 workInProgress.effectTag &= ~DidCapture;
8738 } else {
8739 // Attempting the main content
8740 if (current === null || current.memoizedState !== null) {
8741 // This is a new mount or this boundary is already showing a fallback state.
8742 // Mark this subtree context as having at least one invisible parent that could
8743 // handle the fallback state.
8744 // Boundaries without fallbacks or should be avoided are not considered since
8745 // they cannot handle preferred fallback states.
8746 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {
8747 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
8748 }
8749 }
8750 }
8751
8752 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
8753
8754 pushSuspenseContext(workInProgress, suspenseContext);
8755
8756 {
8757 if ('maxDuration' in nextProps) {
8758 if (!didWarnAboutMaxDuration) {
8759 didWarnAboutMaxDuration = true;
8760 warning$1(false, 'maxDuration has been removed from React. ' + 'Remove the maxDuration prop.');
8761 }
8762 }
8763 }
8764
8765 // This next part is a bit confusing. If the children timeout, we switch to
8766 // showing the fallback children in place of the "primary" children.
8767 // However, we don't want to delete the primary children because then their
8768 // state will be lost (both the React state and the host state, e.g.
8769 // uncontrolled form inputs). Instead we keep them mounted and hide them.
8770 // Both the fallback children AND the primary children are rendered at the
8771 // same time. Once the primary children are un-suspended, we can delete
8772 // the fallback children — don't need to preserve their state.
8773 //
8774 // The two sets of children are siblings in the host environment, but
8775 // semantically, for purposes of reconciliation, they are two separate sets.
8776 // So we store them using two fragment fibers.
8777 //
8778 // However, we want to avoid allocating extra fibers for every placeholder.
8779 // They're only necessary when the children time out, because that's the
8780 // only time when both sets are mounted.
8781 //
8782 // So, the extra fragment fibers are only used if the children time out.
8783 // Otherwise, we render the primary children directly. This requires some
8784 // custom reconciliation logic to preserve the state of the primary
8785 // children. It's essentially a very basic form of re-parenting.
8786
8787 // `child` points to the child fiber. In the normal case, this is the first
8788 // fiber of the primary children set. In the timed-out case, it's a
8789 // a fragment fiber containing the primary children.
8790 var child = void 0;
8791 // `next` points to the next fiber React should render. In the normal case,
8792 // it's the same as `child`: the first fiber of the primary children set.
8793 // In the timed-out case, it's a fragment fiber containing the *fallback*
8794 // children -- we skip over the primary children entirely.
8795 var next = void 0;
8796 if (current === null) {
8797 if (enableSuspenseServerRenderer) {
8798 // If we're currently hydrating, try to hydrate this boundary.
8799 // But only if this has a fallback.
8800 if (nextProps.fallback !== undefined) {
8801 tryToClaimNextHydratableInstance(workInProgress);
8802 // This could've changed the tag if this was a dehydrated suspense component.
8803 if (workInProgress.tag === DehydratedSuspenseComponent) {
8804 popSuspenseContext(workInProgress);
8805 return updateDehydratedSuspenseComponent(null, workInProgress, renderExpirationTime);
8806 }
8807 }
8808 }
8809
8810 // This is the initial mount. This branch is pretty simple because there's
8811 // no previous state that needs to be preserved.
8812 if (nextDidTimeout) {
8813 // Mount separate fragments for primary and fallback children.
8814 var nextFallbackChildren = nextProps.fallback;
8815 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
8816 primaryChildFragment.return = workInProgress;
8817
8818 if ((workInProgress.mode & BatchedMode) === NoMode) {
8819 // Outside of batched mode, we commit the effects from the
8820 var progressedState = workInProgress.memoizedState;
8821 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
8822 primaryChildFragment.child = progressedPrimaryChild;
8823 var progressedChild = progressedPrimaryChild;
8824 while (progressedChild !== null) {
8825 progressedChild.return = primaryChildFragment;
8826 progressedChild = progressedChild.sibling;
8827 }
8828 }
8829
8830 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
8831 fallbackChildFragment.return = workInProgress;
8832 primaryChildFragment.sibling = fallbackChildFragment;
8833 child = primaryChildFragment;
8834 // Skip the primary children, and continue working on the
8835 // fallback children.
8836 next = fallbackChildFragment;
8837 } else {
8838 // Mount the primary children without an intermediate fragment fiber.
8839 var nextPrimaryChildren = nextProps.children;
8840 child = next = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
8841 }
8842 } else {
8843 // This is an update. This branch is more complicated because we need to
8844 // ensure the state of the primary children is preserved.
8845 var prevState = current.memoizedState;
8846 var prevDidTimeout = prevState !== null;
8847 if (prevDidTimeout) {
8848 // The current tree already timed out. That means each child set is
8849 var currentPrimaryChildFragment = current.child;
8850 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
8851 if (nextDidTimeout) {
8852 // Still timed out. Reuse the current primary children by cloning
8853 // its fragment. We're going to skip over these entirely.
8854 var _nextFallbackChildren = nextProps.fallback;
8855 var _primaryChildFragment = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
8856 _primaryChildFragment.return = workInProgress;
8857
8858 if ((workInProgress.mode & BatchedMode) === NoMode) {
8859 // Outside of batched mode, we commit the effects from the
8860 var _progressedState = workInProgress.memoizedState;
8861 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
8862 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
8863 _primaryChildFragment.child = _progressedPrimaryChild;
8864 var _progressedChild = _progressedPrimaryChild;
8865 while (_progressedChild !== null) {
8866 _progressedChild.return = _primaryChildFragment;
8867 _progressedChild = _progressedChild.sibling;
8868 }
8869 }
8870 }
8871
8872 // Because primaryChildFragment is a new fiber that we're inserting as the
8873 // parent of a new tree, we need to set its treeBaseDuration.
8874 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
8875 // treeBaseDuration is the sum of all the child tree base durations.
8876 var treeBaseDuration = 0;
8877 var hiddenChild = _primaryChildFragment.child;
8878 while (hiddenChild !== null) {
8879 treeBaseDuration += hiddenChild.treeBaseDuration;
8880 hiddenChild = hiddenChild.sibling;
8881 }
8882 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
8883 }
8884
8885 // Clone the fallback child fragment, too. These we'll continue
8886 // working on.
8887 var _fallbackChildFragment = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime);
8888 _fallbackChildFragment.return = workInProgress;
8889 _primaryChildFragment.sibling = _fallbackChildFragment;
8890 child = _primaryChildFragment;
8891 _primaryChildFragment.childExpirationTime = NoWork;
8892 // Skip the primary children, and continue working on the
8893 // fallback children.
8894 next = _fallbackChildFragment;
8895 } else {
8896 // No longer suspended. Switch back to showing the primary children,
8897 // and remove the intermediate fragment fiber.
8898 var _nextPrimaryChildren = nextProps.children;
8899 var currentPrimaryChild = currentPrimaryChildFragment.child;
8900 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime);
8901
8902 // If this render doesn't suspend, we need to delete the fallback
8903 // children. Wait until the complete phase, after we've confirmed the
8904 // fallback is no longer needed.
8905 // TODO: Would it be better to store the fallback fragment on
8906 // the stateNode?
8907
8908 // Continue rendering the children, like we normally do.
8909 child = next = primaryChild;
8910 }
8911 } else {
8912 // The current tree has not already timed out. That means the primary
8913 // children are not wrapped in a fragment fiber.
8914 var _currentPrimaryChild = current.child;
8915 if (nextDidTimeout) {
8916 // Timed out. Wrap the children in a fragment fiber to keep them
8917 // separate from the fallback children.
8918 var _nextFallbackChildren2 = nextProps.fallback;
8919 var _primaryChildFragment2 = createFiberFromFragment(
8920 // It shouldn't matter what the pending props are because we aren't
8921 // going to render this fragment.
8922 null, mode, NoWork, null);
8923 _primaryChildFragment2.return = workInProgress;
8924 _primaryChildFragment2.child = _currentPrimaryChild;
8925 if (_currentPrimaryChild !== null) {
8926 _currentPrimaryChild.return = _primaryChildFragment2;
8927 }
8928
8929 // Even though we're creating a new fiber, there are no new children,
8930 // because we're reusing an already mounted tree. So we don't need to
8931 // schedule a placement.
8932 // primaryChildFragment.effectTag |= Placement;
8933
8934 if ((workInProgress.mode & BatchedMode) === NoMode) {
8935 // Outside of batched mode, we commit the effects from the
8936 var _progressedState2 = workInProgress.memoizedState;
8937 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
8938 _primaryChildFragment2.child = _progressedPrimaryChild2;
8939 var _progressedChild2 = _progressedPrimaryChild2;
8940 while (_progressedChild2 !== null) {
8941 _progressedChild2.return = _primaryChildFragment2;
8942 _progressedChild2 = _progressedChild2.sibling;
8943 }
8944 }
8945
8946 // Because primaryChildFragment is a new fiber that we're inserting as the
8947 // parent of a new tree, we need to set its treeBaseDuration.
8948 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
8949 // treeBaseDuration is the sum of all the child tree base durations.
8950 var _treeBaseDuration = 0;
8951 var _hiddenChild = _primaryChildFragment2.child;
8952 while (_hiddenChild !== null) {
8953 _treeBaseDuration += _hiddenChild.treeBaseDuration;
8954 _hiddenChild = _hiddenChild.sibling;
8955 }
8956 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
8957 }
8958
8959 // Create a fragment from the fallback children, too.
8960 var _fallbackChildFragment2 = createFiberFromFragment(_nextFallbackChildren2, mode, renderExpirationTime, null);
8961 _fallbackChildFragment2.return = workInProgress;
8962 _primaryChildFragment2.sibling = _fallbackChildFragment2;
8963 _fallbackChildFragment2.effectTag |= Placement;
8964 child = _primaryChildFragment2;
8965 _primaryChildFragment2.childExpirationTime = NoWork;
8966 // Skip the primary children, and continue working on the
8967 // fallback children.
8968 next = _fallbackChildFragment2;
8969 } else {
8970 // Still haven't timed out. Continue rendering the children, like we
8971 // normally do.
8972 var _nextPrimaryChildren2 = nextProps.children;
8973 next = child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
8974 }
8975 }
8976 workInProgress.stateNode = current.stateNode;
8977 }
8978
8979 workInProgress.memoizedState = nextState;
8980 workInProgress.child = child;
8981 return next;
8982}
8983
8984function retrySuspenseComponentWithoutHydrating(current, workInProgress, renderExpirationTime) {
8985 // Detach from the current dehydrated boundary.
8986 current.alternate = null;
8987 workInProgress.alternate = null;
8988
8989 // Insert a deletion in the effect list.
8990 var returnFiber = workInProgress.return;
8991 (function () {
8992 if (!(returnFiber !== null)) {
8993 {
8994 throw ReactError(Error('Suspense boundaries are never on the root. This is probably a bug in React.'));
8995 }
8996 }
8997 })();
8998 var last = returnFiber.lastEffect;
8999 if (last !== null) {
9000 last.nextEffect = current;
9001 returnFiber.lastEffect = current;
9002 } else {
9003 returnFiber.firstEffect = returnFiber.lastEffect = current;
9004 }
9005 current.nextEffect = null;
9006 current.effectTag = Deletion;
9007
9008 popSuspenseContext(workInProgress);
9009
9010 // Upgrade this work in progress to a real Suspense component.
9011 workInProgress.tag = SuspenseComponent;
9012 workInProgress.stateNode = null;
9013 workInProgress.memoizedState = null;
9014 // This is now an insertion.
9015 workInProgress.effectTag |= Placement;
9016 // Retry as a real Suspense component.
9017 return updateSuspenseComponent(null, workInProgress, renderExpirationTime);
9018}
9019
9020function updateDehydratedSuspenseComponent(current, workInProgress, renderExpirationTime) {
9021 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
9022 var suspenseInstance = workInProgress.stateNode;
9023 if (current === null) {
9024 // During the first pass, we'll bail out and not drill into the children.
9025 // Instead, we'll leave the content in place and try to hydrate it later.
9026 if (isSuspenseInstanceFallback(suspenseInstance)) {
9027 // This is a client-only boundary. Since we won't get any content from the server
9028 // for this, we need to schedule that at a higher priority based on when it would
9029 // have timed out. In theory we could render it in this pass but it would have the
9030 // wrong priority associated with it and will prevent hydration of parent path.
9031 // Instead, we'll leave work left on it to render it in a separate commit.
9032
9033 // TODO This time should be the time at which the server rendered response that is
9034 // a parent to this boundary was displayed. However, since we currently don't have
9035 // a protocol to transfer that time, we'll just estimate it by using the current
9036 // time. This will mean that Suspense timeouts are slightly shifted to later than
9037 // they should be.
9038 var serverDisplayTime = requestCurrentTime();
9039 // Schedule a normal pri update to render this content.
9040 workInProgress.expirationTime = computeAsyncExpiration(serverDisplayTime);
9041 } else {
9042 // We'll continue hydrating the rest at offscreen priority since we'll already
9043 // be showing the right content coming from the server, it is no rush.
9044 workInProgress.expirationTime = Never;
9045 }
9046 return null;
9047 }
9048 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
9049 // Something suspended. Leave the existing children in place.
9050 // TODO: In non-concurrent mode, should we commit the nodes we have hydrated so far?
9051 workInProgress.child = null;
9052 return null;
9053 }
9054 if (isSuspenseInstanceFallback(suspenseInstance)) {
9055 // This boundary is in a permanent fallback state. In this case, we'll never
9056 // get an update and we'll never be able to hydrate the final content. Let's just try the
9057 // client side render instead.
9058 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderExpirationTime);
9059 }
9060 // We use childExpirationTime to indicate that a child might depend on context, so if
9061 // any context has changed, we need to treat is as if the input might have changed.
9062 var hasContextChanged$$1 = current.childExpirationTime >= renderExpirationTime;
9063 if (didReceiveUpdate || hasContextChanged$$1) {
9064 // This boundary has changed since the first render. This means that we are now unable to
9065 // hydrate it. We might still be able to hydrate it using an earlier expiration time but
9066 // during this render we can't. Instead, we're going to delete the whole subtree and
9067 // instead inject a new real Suspense boundary to take its place, which may render content
9068 // or fallback. The real Suspense boundary will suspend for a while so we have some time
9069 // to ensure it can produce real content, but all state and pending events will be lost.
9070 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderExpirationTime);
9071 } else if (isSuspenseInstancePending(suspenseInstance)) {
9072 // This component is still pending more data from the server, so we can't hydrate its
9073 // content. We treat it as if this component suspended itself. It might seem as if
9074 // we could just try to render it client-side instead. However, this will perform a
9075 // lot of unnecessary work and is unlikely to complete since it often will suspend
9076 // on missing data anyway. Additionally, the server might be able to render more
9077 // than we can on the client yet. In that case we'd end up with more fallback states
9078 // on the client than if we just leave it alone. If the server times out or errors
9079 // these should update this boundary to the permanent Fallback state instead.
9080 // Mark it as having captured (i.e. suspended).
9081 workInProgress.effectTag |= DidCapture;
9082 // Leave the children in place. I.e. empty.
9083 workInProgress.child = null;
9084 // Register a callback to retry this boundary once the server has sent the result.
9085 registerSuspenseInstanceRetry(suspenseInstance, retryTimedOutBoundary.bind(null, current));
9086 return null;
9087 } else {
9088 // This is the first attempt.
9089 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress);
9090 var nextProps = workInProgress.pendingProps;
9091 var nextChildren = nextProps.children;
9092 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
9093 return workInProgress.child;
9094 }
9095}
9096
9097function propagateSuspenseContextChange(workInProgress, firstChild, renderExpirationTime) {
9098 // Mark any Suspense boundaries with fallbacks as having work to do.
9099 // If they were previously forced into fallbacks, they may now be able
9100 // to unblock.
9101 var node = firstChild;
9102 while (node !== null) {
9103 if (node.tag === SuspenseComponent) {
9104 var state = node.memoizedState;
9105 if (state !== null) {
9106 if (node.expirationTime < renderExpirationTime) {
9107 node.expirationTime = renderExpirationTime;
9108 }
9109 var alternate = node.alternate;
9110 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
9111 alternate.expirationTime = renderExpirationTime;
9112 }
9113 scheduleWorkOnParentPath(node.return, renderExpirationTime);
9114 }
9115 } else if (node.child !== null) {
9116 node.child.return = node;
9117 node = node.child;
9118 continue;
9119 }
9120 if (node === workInProgress) {
9121 return;
9122 }
9123 while (node.sibling === null) {
9124 if (node.return === null || node.return === workInProgress) {
9125 return;
9126 }
9127 node = node.return;
9128 }
9129 node.sibling.return = node.return;
9130 node = node.sibling;
9131 }
9132}
9133
9134function findLastContentRow(firstChild) {
9135 // This is going to find the last row among these children that is already
9136 // showing content on the screen, as opposed to being in fallback state or
9137 // new. If a row has multiple Suspense boundaries, any of them being in the
9138 // fallback state, counts as the whole row being in a fallback state.
9139 // Note that the "rows" will be workInProgress, but any nested children
9140 // will still be current since we haven't rendered them yet. The mounted
9141 // order may not be the same as the new order. We use the new order.
9142 var row = firstChild;
9143 var lastContentRow = null;
9144 while (row !== null) {
9145 var currentRow = row.alternate;
9146 // New rows can't be content rows.
9147 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
9148 lastContentRow = row;
9149 }
9150 row = row.sibling;
9151 }
9152 return lastContentRow;
9153}
9154
9155function validateRevealOrder(revealOrder) {
9156 {
9157 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
9158 didWarnAboutRevealOrder[revealOrder] = true;
9159 if (typeof revealOrder === 'string') {
9160 switch (revealOrder.toLowerCase()) {
9161 case 'together':
9162 case 'forwards':
9163 case 'backwards':
9164 {
9165 warning$1(false, '"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
9166 break;
9167 }
9168 case 'forward':
9169 case 'backward':
9170 {
9171 warning$1(false, '"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase());
9172 break;
9173 }
9174 default:
9175 warning$1(false, '"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
9176 break;
9177 }
9178 } else {
9179 warning$1(false, '%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
9180 }
9181 }
9182 }
9183}
9184
9185function validateTailOptions(tailMode, revealOrder) {
9186 {
9187 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
9188 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
9189 didWarnAboutTailOptions[tailMode] = true;
9190 warning$1(false, '"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
9191 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
9192 didWarnAboutTailOptions[tailMode] = true;
9193 warning$1(false, '<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
9194 }
9195 }
9196 }
9197}
9198
9199function validateSuspenseListNestedChild(childSlot, index) {
9200 {
9201 var isArray = Array.isArray(childSlot);
9202 var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function';
9203 if (isArray || isIterable) {
9204 var type = isArray ? 'array' : 'iterable';
9205 warning$1(false, 'A nested %s was passed to row #%s in <SuspenseList />. Wrap it in ' + 'an additional SuspenseList to configure its revealOrder: ' + '<SuspenseList revealOrder=...> ... ' + '<SuspenseList revealOrder=...>{%s}</SuspenseList> ... ' + '</SuspenseList>', type, index, type);
9206 return false;
9207 }
9208 }
9209 return true;
9210}
9211
9212function validateSuspenseListChildren(children, revealOrder) {
9213 {
9214 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
9215 if (Array.isArray(children)) {
9216 for (var i = 0; i < children.length; i++) {
9217 if (!validateSuspenseListNestedChild(children[i], i)) {
9218 return;
9219 }
9220 }
9221 } else {
9222 var iteratorFn = getIteratorFn(children);
9223 if (typeof iteratorFn === 'function') {
9224 var childrenIterator = iteratorFn.call(children);
9225 if (childrenIterator) {
9226 var step = childrenIterator.next();
9227 var _i = 0;
9228 for (; !step.done; step = childrenIterator.next()) {
9229 if (!validateSuspenseListNestedChild(step.value, _i)) {
9230 return;
9231 }
9232 _i++;
9233 }
9234 }
9235 } else {
9236 warning$1(false, 'A single row was passed to a <SuspenseList revealOrder="%s" />. ' + 'This is not useful since it needs multiple rows. ' + 'Did you mean to pass multiple children or an array?', revealOrder);
9237 }
9238 }
9239 }
9240 }
9241}
9242
9243function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode) {
9244 var renderState = workInProgress.memoizedState;
9245 if (renderState === null) {
9246 workInProgress.memoizedState = {
9247 isBackwards: isBackwards,
9248 rendering: null,
9249 last: lastContentRow,
9250 tail: tail,
9251 tailExpiration: 0,
9252 tailMode: tailMode
9253 };
9254 } else {
9255 // We can reuse the existing object from previous renders.
9256 renderState.isBackwards = isBackwards;
9257 renderState.rendering = null;
9258 renderState.last = lastContentRow;
9259 renderState.tail = tail;
9260 renderState.tailExpiration = 0;
9261 renderState.tailMode = tailMode;
9262 }
9263}
9264
9265// This can end up rendering this component multiple passes.
9266// The first pass splits the children fibers into two sets. A head and tail.
9267// We first render the head. If anything is in fallback state, we do another
9268// pass through beginWork to rerender all children (including the tail) with
9269// the force suspend context. If the first render didn't have anything in
9270// in fallback state. Then we render each row in the tail one-by-one.
9271// That happens in the completeWork phase without going back to beginWork.
9272function updateSuspenseListComponent(current, workInProgress, renderExpirationTime) {
9273 var nextProps = workInProgress.pendingProps;
9274 var revealOrder = nextProps.revealOrder;
9275 var tailMode = nextProps.tail;
9276 var newChildren = nextProps.children;
9277
9278 validateRevealOrder(revealOrder);
9279 validateTailOptions(tailMode, revealOrder);
9280 validateSuspenseListChildren(newChildren, revealOrder);
9281
9282 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
9283
9284 var suspenseContext = suspenseStackCursor.current;
9285
9286 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
9287 if (shouldForceFallback) {
9288 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
9289 workInProgress.effectTag |= DidCapture;
9290 } else {
9291 var didSuspendBefore = current !== null && (current.effectTag & DidCapture) !== NoEffect;
9292 if (didSuspendBefore) {
9293 // If we previously forced a fallback, we need to schedule work
9294 // on any nested boundaries to let them know to try to render
9295 // again. This is the same as context updating.
9296 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderExpirationTime);
9297 }
9298 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
9299 }
9300 pushSuspenseContext(workInProgress, suspenseContext);
9301
9302 if ((workInProgress.mode & BatchedMode) === NoMode) {
9303 // Outside of batched mode, SuspenseList doesn't work so we just
9304 // use make it a noop by treating it as the default revealOrder.
9305 workInProgress.memoizedState = null;
9306 } else {
9307 switch (revealOrder) {
9308 case 'forwards':
9309 {
9310 var lastContentRow = findLastContentRow(workInProgress.child);
9311 var tail = void 0;
9312 if (lastContentRow === null) {
9313 // The whole list is part of the tail.
9314 // TODO: We could fast path by just rendering the tail now.
9315 tail = workInProgress.child;
9316 workInProgress.child = null;
9317 } else {
9318 // Disconnect the tail rows after the content row.
9319 // We're going to render them separately later.
9320 tail = lastContentRow.sibling;
9321 lastContentRow.sibling = null;
9322 }
9323 initSuspenseListRenderState(workInProgress, false, // isBackwards
9324 tail, lastContentRow, tailMode);
9325 break;
9326 }
9327 case 'backwards':
9328 {
9329 // We're going to find the first row that has existing content.
9330 // At the same time we're going to reverse the list of everything
9331 // we pass in the meantime. That's going to be our tail in reverse
9332 // order.
9333 var _tail = null;
9334 var row = workInProgress.child;
9335 workInProgress.child = null;
9336 while (row !== null) {
9337 var currentRow = row.alternate;
9338 // New rows can't be content rows.
9339 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
9340 // This is the beginning of the main content.
9341 workInProgress.child = row;
9342 break;
9343 }
9344 var nextRow = row.sibling;
9345 row.sibling = _tail;
9346 _tail = row;
9347 row = nextRow;
9348 }
9349 // TODO: If workInProgress.child is null, we can continue on the tail immediately.
9350 initSuspenseListRenderState(workInProgress, true, // isBackwards
9351 _tail, null, // last
9352 tailMode);
9353 break;
9354 }
9355 case 'together':
9356 {
9357 initSuspenseListRenderState(workInProgress, false, // isBackwards
9358 null, // tail
9359 null, // last
9360 undefined);
9361 break;
9362 }
9363 default:
9364 {
9365 // The default reveal order is the same as not having
9366 // a boundary.
9367 workInProgress.memoizedState = null;
9368 }
9369 }
9370 }
9371 return workInProgress.child;
9372}
9373
9374function updatePortalComponent(current, workInProgress, renderExpirationTime) {
9375 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
9376 var nextChildren = workInProgress.pendingProps;
9377 if (current === null) {
9378 // Portals are special because we don't append the children during mount
9379 // but at commit. Therefore we need to track insertions which the normal
9380 // flow doesn't do during mount. This doesn't happen at the root because
9381 // the root always starts with a "current" with a null child.
9382 // TODO: Consider unifying this with how the root works.
9383 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
9384 } else {
9385 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
9386 }
9387 return workInProgress.child;
9388}
9389
9390function updateContextProvider(current, workInProgress, renderExpirationTime) {
9391 var providerType = workInProgress.type;
9392 var context = providerType._context;
9393
9394 var newProps = workInProgress.pendingProps;
9395 var oldProps = workInProgress.memoizedProps;
9396
9397 var newValue = newProps.value;
9398
9399 {
9400 var providerPropTypes = workInProgress.type.propTypes;
9401
9402 if (providerPropTypes) {
9403 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
9404 }
9405 }
9406
9407 pushProvider(workInProgress, newValue);
9408
9409 if (oldProps !== null) {
9410 var oldValue = oldProps.value;
9411 var changedBits = calculateChangedBits(context, newValue, oldValue);
9412 if (changedBits === 0) {
9413 // No change. Bailout early if children are the same.
9414 if (oldProps.children === newProps.children && !hasContextChanged()) {
9415 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
9416 }
9417 } else {
9418 // The context value changed. Search for matching consumers and schedule
9419 // them to update.
9420 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
9421 }
9422 }
9423
9424 var newChildren = newProps.children;
9425 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
9426 return workInProgress.child;
9427}
9428
9429var hasWarnedAboutUsingContextAsConsumer = false;
9430
9431function updateContextConsumer(current, workInProgress, renderExpirationTime) {
9432 var context = workInProgress.type;
9433 // The logic below for Context differs depending on PROD or DEV mode. In
9434 // DEV mode, we create a separate object for Context.Consumer that acts
9435 // like a proxy to Context. This proxy object adds unnecessary code in PROD
9436 // so we use the old behaviour (Context.Consumer references Context) to
9437 // reduce size and overhead. The separate object references context via
9438 // a property called "_context", which also gives us the ability to check
9439 // in DEV mode if this property exists or not and warn if it does not.
9440 {
9441 if (context._context === undefined) {
9442 // This may be because it's a Context (rather than a Consumer).
9443 // Or it may be because it's older React where they're the same thing.
9444 // We only want to warn if we're sure it's a new React.
9445 if (context !== context.Consumer) {
9446 if (!hasWarnedAboutUsingContextAsConsumer) {
9447 hasWarnedAboutUsingContextAsConsumer = true;
9448 warning$1(false, 'Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
9449 }
9450 }
9451 } else {
9452 context = context._context;
9453 }
9454 }
9455 var newProps = workInProgress.pendingProps;
9456 var render = newProps.children;
9457
9458 {
9459 !(typeof render === 'function') ? warningWithoutStack$1(false, 'A context consumer was rendered with multiple children, or a child ' + "that isn't a function. A context consumer expects a single child " + 'that is a function. If you did pass a function, make sure there ' + 'is no trailing or leading whitespace around it.') : void 0;
9460 }
9461
9462 prepareToReadContext(workInProgress, renderExpirationTime);
9463 var newValue = readContext(context, newProps.unstable_observedBits);
9464 var newChildren = void 0;
9465 {
9466 ReactCurrentOwner$2.current = workInProgress;
9467 setCurrentPhase('render');
9468 newChildren = render(newValue);
9469 setCurrentPhase(null);
9470 }
9471
9472 // React DevTools reads this flag.
9473 workInProgress.effectTag |= PerformedWork;
9474 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
9475 return workInProgress.child;
9476}
9477
9478function updateFundamentalComponent$1(current, workInProgress, renderExpirationTime) {
9479 var fundamentalImpl = workInProgress.type.impl;
9480 if (fundamentalImpl.reconcileChildren === false) {
9481 return null;
9482 }
9483 var nextProps = workInProgress.pendingProps;
9484 var nextChildren = nextProps.children;
9485
9486 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
9487 return workInProgress.child;
9488}
9489
9490function markWorkInProgressReceivedUpdate() {
9491 didReceiveUpdate = true;
9492}
9493
9494function bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime) {
9495 cancelWorkTimer(workInProgress);
9496
9497 if (current !== null) {
9498 // Reuse previous dependencies
9499 workInProgress.dependencies = current.dependencies;
9500 }
9501
9502 if (enableProfilerTimer) {
9503 // Don't update "base" render times for bailouts.
9504 stopProfilerTimerIfRunning(workInProgress);
9505 }
9506
9507 // Check if the children have any pending work.
9508 var childExpirationTime = workInProgress.childExpirationTime;
9509 if (childExpirationTime < renderExpirationTime) {
9510 // The children don't have any work either. We can skip them.
9511 // TODO: Once we add back resuming, we should check if the children are
9512 // a work-in-progress set. If so, we need to transfer their effects.
9513 return null;
9514 } else {
9515 // This fiber doesn't have work, but its subtree does. Clone the child
9516 // fibers and continue.
9517 cloneChildFibers(current, workInProgress);
9518 return workInProgress.child;
9519 }
9520}
9521
9522function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
9523 {
9524 var returnFiber = oldWorkInProgress.return;
9525 if (returnFiber === null) {
9526 throw new Error('Cannot swap the root fiber.');
9527 }
9528
9529 // Disconnect from the old current.
9530 // It will get deleted.
9531 current.alternate = null;
9532 oldWorkInProgress.alternate = null;
9533
9534 // Connect to the new tree.
9535 newWorkInProgress.index = oldWorkInProgress.index;
9536 newWorkInProgress.sibling = oldWorkInProgress.sibling;
9537 newWorkInProgress.return = oldWorkInProgress.return;
9538 newWorkInProgress.ref = oldWorkInProgress.ref;
9539
9540 // Replace the child/sibling pointers above it.
9541 if (oldWorkInProgress === returnFiber.child) {
9542 returnFiber.child = newWorkInProgress;
9543 } else {
9544 var prevSibling = returnFiber.child;
9545 if (prevSibling === null) {
9546 throw new Error('Expected parent to have a child.');
9547 }
9548 while (prevSibling.sibling !== oldWorkInProgress) {
9549 prevSibling = prevSibling.sibling;
9550 if (prevSibling === null) {
9551 throw new Error('Expected to find the previous sibling.');
9552 }
9553 }
9554 prevSibling.sibling = newWorkInProgress;
9555 }
9556
9557 // Delete the old fiber and place the new one.
9558 // Since the old fiber is disconnected, we have to schedule it manually.
9559 var last = returnFiber.lastEffect;
9560 if (last !== null) {
9561 last.nextEffect = current;
9562 returnFiber.lastEffect = current;
9563 } else {
9564 returnFiber.firstEffect = returnFiber.lastEffect = current;
9565 }
9566 current.nextEffect = null;
9567 current.effectTag = Deletion;
9568
9569 newWorkInProgress.effectTag |= Placement;
9570
9571 // Restart work from the new fiber.
9572 return newWorkInProgress;
9573 }
9574}
9575
9576function beginWork$1(current, workInProgress, renderExpirationTime) {
9577 var updateExpirationTime = workInProgress.expirationTime;
9578
9579 {
9580 if (workInProgress._debugNeedsRemount && current !== null) {
9581 // This will restart the begin phase with a new fiber.
9582 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.expirationTime));
9583 }
9584 }
9585
9586 if (current !== null) {
9587 var oldProps = current.memoizedProps;
9588 var newProps = workInProgress.pendingProps;
9589
9590 if (oldProps !== newProps || hasContextChanged() || (
9591 // Force a re-render if the implementation changed due to hot reload:
9592 workInProgress.type !== current.type)) {
9593 // If props or context changed, mark the fiber as having performed work.
9594 // This may be unset if the props are determined to be equal later (memo).
9595 didReceiveUpdate = true;
9596 } else if (updateExpirationTime < renderExpirationTime) {
9597 didReceiveUpdate = false;
9598 // This fiber does not have any pending work. Bailout without entering
9599 // the begin phase. There's still some bookkeeping we that needs to be done
9600 // in this optimized path, mostly pushing stuff onto the stack.
9601 switch (workInProgress.tag) {
9602 case HostRoot:
9603 pushHostRootContext(workInProgress);
9604 resetHydrationState();
9605 break;
9606 case HostComponent:
9607 pushHostContext(workInProgress);
9608 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(workInProgress.type, newProps)) {
9609 if (enableSchedulerTracing) {
9610 markSpawnedWork(Never);
9611 }
9612 // Schedule this fiber to re-render at offscreen priority. Then bailout.
9613 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
9614 return null;
9615 }
9616 break;
9617 case ClassComponent:
9618 {
9619 var Component = workInProgress.type;
9620 if (isContextProvider(Component)) {
9621 pushContextProvider(workInProgress);
9622 }
9623 break;
9624 }
9625 case HostPortal:
9626 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
9627 break;
9628 case ContextProvider:
9629 {
9630 var newValue = workInProgress.memoizedProps.value;
9631 pushProvider(workInProgress, newValue);
9632 break;
9633 }
9634 case Profiler:
9635 if (enableProfilerTimer) {
9636 workInProgress.effectTag |= Update;
9637 }
9638 break;
9639 case SuspenseComponent:
9640 {
9641 var state = workInProgress.memoizedState;
9642 var didTimeout = state !== null;
9643 if (didTimeout) {
9644 // If this boundary is currently timed out, we need to decide
9645 // whether to retry the primary children, or to skip over it and
9646 // go straight to the fallback. Check the priority of the primary
9647 var primaryChildFragment = workInProgress.child;
9648 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
9649 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
9650 // The primary children have pending work. Use the normal path
9651 // to attempt to render the primary children again.
9652 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
9653 } else {
9654 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
9655 // The primary children do not have pending work with sufficient
9656 // priority. Bailout.
9657 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
9658 if (child !== null) {
9659 // The fallback children have pending work. Skip over the
9660 // primary children and work on the fallback.
9661 return child.sibling;
9662 } else {
9663 return null;
9664 }
9665 }
9666 } else {
9667 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
9668 }
9669 break;
9670 }
9671 case DehydratedSuspenseComponent:
9672 {
9673 if (enableSuspenseServerRenderer) {
9674 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
9675 // We know that this component will suspend again because if it has
9676 // been unsuspended it has committed as a regular Suspense component.
9677 // If it needs to be retried, it should have work scheduled on it.
9678 workInProgress.effectTag |= DidCapture;
9679 }
9680 break;
9681 }
9682 case SuspenseListComponent:
9683 {
9684 var didSuspendBefore = (current.effectTag & DidCapture) !== NoEffect;
9685
9686 var hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
9687
9688 if (didSuspendBefore) {
9689 if (hasChildWork) {
9690 // If something was in fallback state last time, and we have all the
9691 // same children then we're still in progressive loading state.
9692 // Something might get unblocked by state updates or retries in the
9693 // tree which will affect the tail. So we need to use the normal
9694 // path to compute the correct tail.
9695 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
9696 }
9697 // If none of the children had any work, that means that none of
9698 // them got retried so they'll still be blocked in the same way
9699 // as before. We can fast bail out.
9700 workInProgress.effectTag |= DidCapture;
9701 }
9702
9703 // If nothing suspended before and we're rendering the same children,
9704 // then the tail doesn't matter. Anything new that suspends will work
9705 // in the "together" mode, so we can continue from the state we had.
9706 var renderState = workInProgress.memoizedState;
9707 if (renderState !== null) {
9708 // Reset to the "together" mode in case we've started a different
9709 // update in the past but didn't complete it.
9710 renderState.rendering = null;
9711 renderState.tail = null;
9712 }
9713 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
9714
9715 if (hasChildWork) {
9716 break;
9717 } else {
9718 // If none of the children had any work, that means that none of
9719 // them got retried so they'll still be blocked in the same way
9720 // as before. We can fast bail out.
9721 return null;
9722 }
9723 }
9724 }
9725 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
9726 }
9727 } else {
9728 didReceiveUpdate = false;
9729 }
9730
9731 // Before entering the begin phase, clear the expiration time.
9732 workInProgress.expirationTime = NoWork;
9733
9734 switch (workInProgress.tag) {
9735 case IndeterminateComponent:
9736 {
9737 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderExpirationTime);
9738 }
9739 case LazyComponent:
9740 {
9741 var elementType = workInProgress.elementType;
9742 return mountLazyComponent(current, workInProgress, elementType, updateExpirationTime, renderExpirationTime);
9743 }
9744 case FunctionComponent:
9745 {
9746 var _Component = workInProgress.type;
9747 var unresolvedProps = workInProgress.pendingProps;
9748 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
9749 return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderExpirationTime);
9750 }
9751 case ClassComponent:
9752 {
9753 var _Component2 = workInProgress.type;
9754 var _unresolvedProps = workInProgress.pendingProps;
9755 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
9756 return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
9757 }
9758 case HostRoot:
9759 return updateHostRoot(current, workInProgress, renderExpirationTime);
9760 case HostComponent:
9761 return updateHostComponent(current, workInProgress, renderExpirationTime);
9762 case HostText:
9763 return updateHostText(current, workInProgress);
9764 case SuspenseComponent:
9765 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
9766 case HostPortal:
9767 return updatePortalComponent(current, workInProgress, renderExpirationTime);
9768 case ForwardRef:
9769 {
9770 var type = workInProgress.type;
9771 var _unresolvedProps2 = workInProgress.pendingProps;
9772 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
9773 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderExpirationTime);
9774 }
9775 case Fragment:
9776 return updateFragment(current, workInProgress, renderExpirationTime);
9777 case Mode:
9778 return updateMode(current, workInProgress, renderExpirationTime);
9779 case Profiler:
9780 return updateProfiler(current, workInProgress, renderExpirationTime);
9781 case ContextProvider:
9782 return updateContextProvider(current, workInProgress, renderExpirationTime);
9783 case ContextConsumer:
9784 return updateContextConsumer(current, workInProgress, renderExpirationTime);
9785 case MemoComponent:
9786 {
9787 var _type2 = workInProgress.type;
9788 var _unresolvedProps3 = workInProgress.pendingProps;
9789 // Resolve outer props first, then resolve inner props.
9790 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
9791 {
9792 if (workInProgress.type !== workInProgress.elementType) {
9793 var outerPropTypes = _type2.propTypes;
9794 if (outerPropTypes) {
9795 checkPropTypes_1(outerPropTypes, _resolvedProps3, // Resolved for outer only
9796 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
9797 }
9798 }
9799 }
9800 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
9801 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
9802 }
9803 case SimpleMemoComponent:
9804 {
9805 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
9806 }
9807 case IncompleteClassComponent:
9808 {
9809 var _Component3 = workInProgress.type;
9810 var _unresolvedProps4 = workInProgress.pendingProps;
9811 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
9812 return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
9813 }
9814 case DehydratedSuspenseComponent:
9815 {
9816 if (enableSuspenseServerRenderer) {
9817 return updateDehydratedSuspenseComponent(current, workInProgress, renderExpirationTime);
9818 }
9819 break;
9820 }
9821 case SuspenseListComponent:
9822 {
9823 return updateSuspenseListComponent(current, workInProgress, renderExpirationTime);
9824 }
9825 case FundamentalComponent:
9826 {
9827 if (enableFundamentalAPI) {
9828 return updateFundamentalComponent$1(current, workInProgress, renderExpirationTime);
9829 }
9830 break;
9831 }
9832 }
9833 (function () {
9834 {
9835 {
9836 throw ReactError(Error('Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.'));
9837 }
9838 }
9839 })();
9840}
9841
9842function createFundamentalStateInstance(currentFiber, props, impl, state) {
9843 return {
9844 currentFiber: currentFiber,
9845 impl: impl,
9846 instance: null,
9847 prevProps: null,
9848 props: props,
9849 state: state
9850 };
9851}
9852
9853var emptyObject = {};
9854var isArray$2 = Array.isArray;
9855
9856function markUpdate(workInProgress) {
9857 // Tag the fiber with an update effect. This turns a Placement into
9858 // a PlacementAndUpdate.
9859 workInProgress.effectTag |= Update;
9860}
9861
9862function markRef$1(workInProgress) {
9863 workInProgress.effectTag |= Ref;
9864}
9865
9866var appendAllChildren = void 0;
9867var updateHostContainer = void 0;
9868var updateHostComponent$1 = void 0;
9869var updateHostText$1 = void 0;
9870if (supportsMutation) {
9871 // Mutation mode
9872
9873 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
9874 // We only have the top Fiber that was created but we need recurse down its
9875 // children to find all the terminal nodes.
9876 var node = workInProgress.child;
9877 while (node !== null) {
9878 if (node.tag === HostComponent || node.tag === HostText) {
9879 appendInitialChild(parent, node.stateNode);
9880 } else if (node.tag === FundamentalComponent) {
9881 appendInitialChild(parent, node.stateNode.instance);
9882 } else if (node.tag === HostPortal) {
9883 // If we have a portal child, then we don't want to traverse
9884 // down its children. Instead, we'll get insertions from each child in
9885 // the portal directly.
9886 } else if (node.child !== null) {
9887 node.child.return = node;
9888 node = node.child;
9889 continue;
9890 }
9891 if (node === workInProgress) {
9892 return;
9893 }
9894 while (node.sibling === null) {
9895 if (node.return === null || node.return === workInProgress) {
9896 return;
9897 }
9898 node = node.return;
9899 }
9900 node.sibling.return = node.return;
9901 node = node.sibling;
9902 }
9903 };
9904
9905 updateHostContainer = function (workInProgress) {
9906 // Noop
9907 };
9908 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9909 // If we have an alternate, that means this is an update and we need to
9910 // schedule a side-effect to do the updates.
9911 var oldProps = current.memoizedProps;
9912 if (oldProps === newProps) {
9913 // In mutation mode, this is sufficient for a bailout because
9914 // we won't touch this node even if children changed.
9915 return;
9916 }
9917
9918 // If we get updated because one of our children updated, we don't
9919 // have newProps so we'll have to reuse them.
9920 // TODO: Split the update API as separate for the props vs. children.
9921 // Even better would be if children weren't special cased at all tho.
9922 var instance = workInProgress.stateNode;
9923 var currentHostContext = getHostContext();
9924 // TODO: Experiencing an error where oldProps is null. Suggests a host
9925 // component is hitting the resume path. Figure out why. Possibly
9926 // related to `hidden`.
9927 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9928 // TODO: Type this specific to this type of component.
9929 workInProgress.updateQueue = updatePayload;
9930 // If the update payload indicates that there is a change or if there
9931 // is a new ref we mark this as an update. All the work is done in commitWork.
9932 if (updatePayload) {
9933 markUpdate(workInProgress);
9934 }
9935 };
9936 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9937 // If the text differs, mark it as an update. All the work in done in commitWork.
9938 if (oldText !== newText) {
9939 markUpdate(workInProgress);
9940 }
9941 };
9942} else if (supportsPersistence) {
9943 // Persistent host tree mode
9944
9945 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
9946 // We only have the top Fiber that was created but we need recurse down its
9947 // children to find all the terminal nodes.
9948 var node = workInProgress.child;
9949 while (node !== null) {
9950 // eslint-disable-next-line no-labels
9951 branches: if (node.tag === HostComponent) {
9952 var instance = node.stateNode;
9953 if (needsVisibilityToggle && isHidden) {
9954 // This child is inside a timed out tree. Hide it.
9955 var props = node.memoizedProps;
9956 var type = node.type;
9957 instance = cloneHiddenInstance(instance, type, props, node);
9958 }
9959 appendInitialChild(parent, instance);
9960 } else if (node.tag === HostText) {
9961 var _instance = node.stateNode;
9962 if (needsVisibilityToggle && isHidden) {
9963 // This child is inside a timed out tree. Hide it.
9964 var text = node.memoizedProps;
9965 _instance = cloneHiddenTextInstance(_instance, text, node);
9966 }
9967 appendInitialChild(parent, _instance);
9968 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
9969 var _instance2 = node.stateNode.instance;
9970 if (needsVisibilityToggle && isHidden) {
9971 // This child is inside a timed out tree. Hide it.
9972 var _props = node.memoizedProps;
9973 var _type = node.type;
9974 _instance2 = cloneHiddenInstance(_instance2, _type, _props, node);
9975 }
9976 appendInitialChild(parent, _instance2);
9977 } else if (node.tag === HostPortal) {
9978 // If we have a portal child, then we don't want to traverse
9979 // down its children. Instead, we'll get insertions from each child in
9980 // the portal directly.
9981 } else if (node.tag === SuspenseComponent) {
9982 if ((node.effectTag & Update) !== NoEffect) {
9983 // Need to toggle the visibility of the primary children.
9984 var newIsHidden = node.memoizedState !== null;
9985 if (newIsHidden) {
9986 var primaryChildParent = node.child;
9987 if (primaryChildParent !== null) {
9988 if (primaryChildParent.child !== null) {
9989 primaryChildParent.child.return = primaryChildParent;
9990 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
9991 }
9992 var fallbackChildParent = primaryChildParent.sibling;
9993 if (fallbackChildParent !== null) {
9994 fallbackChildParent.return = node;
9995 node = fallbackChildParent;
9996 continue;
9997 }
9998 }
9999 }
10000 }
10001 if (node.child !== null) {
10002 // Continue traversing like normal
10003 node.child.return = node;
10004 node = node.child;
10005 continue;
10006 }
10007 } else if (node.child !== null) {
10008 node.child.return = node;
10009 node = node.child;
10010 continue;
10011 }
10012 // $FlowFixMe This is correct but Flow is confused by the labeled break.
10013 node = node;
10014 if (node === workInProgress) {
10015 return;
10016 }
10017 while (node.sibling === null) {
10018 if (node.return === null || node.return === workInProgress) {
10019 return;
10020 }
10021 node = node.return;
10022 }
10023 node.sibling.return = node.return;
10024 node = node.sibling;
10025 }
10026 };
10027
10028 // An unfortunate fork of appendAllChildren because we have two different parent types.
10029 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
10030 // We only have the top Fiber that was created but we need recurse down its
10031 // children to find all the terminal nodes.
10032 var node = workInProgress.child;
10033 while (node !== null) {
10034 // eslint-disable-next-line no-labels
10035 branches: if (node.tag === HostComponent) {
10036 var instance = node.stateNode;
10037 if (needsVisibilityToggle && isHidden) {
10038 // This child is inside a timed out tree. Hide it.
10039 var props = node.memoizedProps;
10040 var type = node.type;
10041 instance = cloneHiddenInstance(instance, type, props, node);
10042 }
10043 appendChildToContainerChildSet(containerChildSet, instance);
10044 } else if (node.tag === HostText) {
10045 var _instance3 = node.stateNode;
10046 if (needsVisibilityToggle && isHidden) {
10047 // This child is inside a timed out tree. Hide it.
10048 var text = node.memoizedProps;
10049 _instance3 = cloneHiddenTextInstance(_instance3, text, node);
10050 }
10051 appendChildToContainerChildSet(containerChildSet, _instance3);
10052 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
10053 var _instance4 = node.stateNode.instance;
10054 if (needsVisibilityToggle && isHidden) {
10055 // This child is inside a timed out tree. Hide it.
10056 var _props2 = node.memoizedProps;
10057 var _type2 = node.type;
10058 _instance4 = cloneHiddenInstance(_instance4, _type2, _props2, node);
10059 }
10060 appendChildToContainerChildSet(containerChildSet, _instance4);
10061 } else if (node.tag === HostPortal) {
10062 // If we have a portal child, then we don't want to traverse
10063 // down its children. Instead, we'll get insertions from each child in
10064 // the portal directly.
10065 } else if (node.tag === SuspenseComponent) {
10066 if ((node.effectTag & Update) !== NoEffect) {
10067 // Need to toggle the visibility of the primary children.
10068 var newIsHidden = node.memoizedState !== null;
10069 if (newIsHidden) {
10070 var primaryChildParent = node.child;
10071 if (primaryChildParent !== null) {
10072 if (primaryChildParent.child !== null) {
10073 primaryChildParent.child.return = primaryChildParent;
10074 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
10075 }
10076 var fallbackChildParent = primaryChildParent.sibling;
10077 if (fallbackChildParent !== null) {
10078 fallbackChildParent.return = node;
10079 node = fallbackChildParent;
10080 continue;
10081 }
10082 }
10083 }
10084 }
10085 if (node.child !== null) {
10086 // Continue traversing like normal
10087 node.child.return = node;
10088 node = node.child;
10089 continue;
10090 }
10091 } else if (node.child !== null) {
10092 node.child.return = node;
10093 node = node.child;
10094 continue;
10095 }
10096 // $FlowFixMe This is correct but Flow is confused by the labeled break.
10097 node = node;
10098 if (node === workInProgress) {
10099 return;
10100 }
10101 while (node.sibling === null) {
10102 if (node.return === null || node.return === workInProgress) {
10103 return;
10104 }
10105 node = node.return;
10106 }
10107 node.sibling.return = node.return;
10108 node = node.sibling;
10109 }
10110 };
10111 updateHostContainer = function (workInProgress) {
10112 var portalOrRoot = workInProgress.stateNode;
10113 var childrenUnchanged = workInProgress.firstEffect === null;
10114 if (childrenUnchanged) {
10115 // No changes, just reuse the existing instance.
10116 } else {
10117 var container = portalOrRoot.containerInfo;
10118 var newChildSet = createContainerChildSet(container);
10119 // If children might have changed, we have to add them all to the set.
10120 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
10121 portalOrRoot.pendingChildren = newChildSet;
10122 // Schedule an update on the container to swap out the container.
10123 markUpdate(workInProgress);
10124 finalizeContainerChildren(container, newChildSet);
10125 }
10126 };
10127 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
10128 var currentInstance = current.stateNode;
10129 var oldProps = current.memoizedProps;
10130 // If there are no effects associated with this node, then none of our children had any updates.
10131 // This guarantees that we can reuse all of them.
10132 var childrenUnchanged = workInProgress.firstEffect === null;
10133 if (childrenUnchanged && oldProps === newProps) {
10134 // No changes, just reuse the existing instance.
10135 // Note that this might release a previous clone.
10136 workInProgress.stateNode = currentInstance;
10137 return;
10138 }
10139 var recyclableInstance = workInProgress.stateNode;
10140 var currentHostContext = getHostContext();
10141 var updatePayload = null;
10142 if (oldProps !== newProps) {
10143 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
10144 }
10145 if (childrenUnchanged && updatePayload === null) {
10146 // No changes, just reuse the existing instance.
10147 // Note that this might release a previous clone.
10148 workInProgress.stateNode = currentInstance;
10149 return;
10150 }
10151 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
10152 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
10153 markUpdate(workInProgress);
10154 }
10155 workInProgress.stateNode = newInstance;
10156 if (childrenUnchanged) {
10157 // If there are no other effects in this tree, we need to flag this node as having one.
10158 // Even though we're not going to use it for anything.
10159 // Otherwise parents won't know that there are new children to propagate upwards.
10160 markUpdate(workInProgress);
10161 } else {
10162 // If children might have changed, we have to add them all to the set.
10163 appendAllChildren(newInstance, workInProgress, false, false);
10164 }
10165 };
10166 updateHostText$1 = function (current, workInProgress, oldText, newText) {
10167 if (oldText !== newText) {
10168 // If the text content differs, we'll create a new text instance for it.
10169 var rootContainerInstance = getRootHostContainer();
10170 var currentHostContext = getHostContext();
10171 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
10172 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
10173 // This lets the parents know that at least one of their children has changed.
10174 markUpdate(workInProgress);
10175 }
10176 };
10177} else {
10178 // No host operations
10179 updateHostContainer = function (workInProgress) {
10180 // Noop
10181 };
10182 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
10183 // Noop
10184 };
10185 updateHostText$1 = function (current, workInProgress, oldText, newText) {
10186 // Noop
10187 };
10188}
10189
10190function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
10191 switch (renderState.tailMode) {
10192 case 'hidden':
10193 {
10194 // Any insertions at the end of the tail list after this point
10195 // should be invisible. If there are already mounted boundaries
10196 // anything before them are not considered for collapsing.
10197 // Therefore we need to go through the whole tail to find if
10198 // there are any.
10199 var tailNode = renderState.tail;
10200 var lastTailNode = null;
10201 while (tailNode !== null) {
10202 if (tailNode.alternate !== null) {
10203 lastTailNode = tailNode;
10204 }
10205 tailNode = tailNode.sibling;
10206 }
10207 // Next we're simply going to delete all insertions after the
10208 // last rendered item.
10209 if (lastTailNode === null) {
10210 // All remaining items in the tail are insertions.
10211 renderState.tail = null;
10212 } else {
10213 // Detach the insertion after the last node that was already
10214 // inserted.
10215 lastTailNode.sibling = null;
10216 }
10217 break;
10218 }
10219 case 'collapsed':
10220 {
10221 // Any insertions at the end of the tail list after this point
10222 // should be invisible. If there are already mounted boundaries
10223 // anything before them are not considered for collapsing.
10224 // Therefore we need to go through the whole tail to find if
10225 // there are any.
10226 var _tailNode = renderState.tail;
10227 var _lastTailNode = null;
10228 while (_tailNode !== null) {
10229 if (_tailNode.alternate !== null) {
10230 _lastTailNode = _tailNode;
10231 }
10232 _tailNode = _tailNode.sibling;
10233 }
10234 // Next we're simply going to delete all insertions after the
10235 // last rendered item.
10236 if (_lastTailNode === null) {
10237 // All remaining items in the tail are insertions.
10238 if (!hasRenderedATailFallback && renderState.tail !== null) {
10239 // We suspended during the head. We want to show at least one
10240 // row at the tail. So we'll keep on and cut off the rest.
10241 renderState.tail.sibling = null;
10242 } else {
10243 renderState.tail = null;
10244 }
10245 } else {
10246 // Detach the insertion after the last node that was already
10247 // inserted.
10248 _lastTailNode.sibling = null;
10249 }
10250 break;
10251 }
10252 }
10253}
10254
10255function completeWork(current, workInProgress, renderExpirationTime) {
10256 var newProps = workInProgress.pendingProps;
10257
10258 switch (workInProgress.tag) {
10259 case IndeterminateComponent:
10260 break;
10261 case LazyComponent:
10262 break;
10263 case SimpleMemoComponent:
10264 case FunctionComponent:
10265 break;
10266 case ClassComponent:
10267 {
10268 var Component = workInProgress.type;
10269 if (isContextProvider(Component)) {
10270 popContext(workInProgress);
10271 }
10272 break;
10273 }
10274 case HostRoot:
10275 {
10276 popHostContainer(workInProgress);
10277 popTopLevelContextObject(workInProgress);
10278 var fiberRoot = workInProgress.stateNode;
10279 if (fiberRoot.pendingContext) {
10280 fiberRoot.context = fiberRoot.pendingContext;
10281 fiberRoot.pendingContext = null;
10282 }
10283 if (current === null || current.child === null) {
10284 // If we hydrated, pop so that we can delete any remaining children
10285 // that weren't hydrated.
10286 popHydrationState(workInProgress);
10287 // This resets the hacky state to fix isMounted before committing.
10288 // TODO: Delete this when we delete isMounted and findDOMNode.
10289 workInProgress.effectTag &= ~Placement;
10290 }
10291 updateHostContainer(workInProgress);
10292 break;
10293 }
10294 case HostComponent:
10295 {
10296 popHostContext(workInProgress);
10297 var rootContainerInstance = getRootHostContainer();
10298 var type = workInProgress.type;
10299 if (current !== null && workInProgress.stateNode != null) {
10300 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
10301
10302 if (enableFlareAPI) {
10303 var prevListeners = current.memoizedProps.listeners;
10304 var nextListeners = newProps.listeners;
10305 var instance = workInProgress.stateNode;
10306 if (prevListeners !== nextListeners) {
10307 updateEventListeners(nextListeners, instance, rootContainerInstance, workInProgress);
10308 }
10309 }
10310
10311 if (current.ref !== workInProgress.ref) {
10312 markRef$1(workInProgress);
10313 }
10314 } else {
10315 if (!newProps) {
10316 (function () {
10317 if (!(workInProgress.stateNode !== null)) {
10318 {
10319 throw ReactError(Error('We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.'));
10320 }
10321 }
10322 })();
10323 // This can happen when we abort work.
10324 break;
10325 }
10326
10327 var currentHostContext = getHostContext();
10328 // TODO: Move createInstance to beginWork and keep it on a context
10329 // "stack" as the parent. Then append children as we go in beginWork
10330 // or completeWork depending on we want to add then top->down or
10331 // bottom->up. Top->down is faster in IE11.
10332 var wasHydrated = popHydrationState(workInProgress);
10333 if (wasHydrated) {
10334 // TODO: Move this and createInstance step into the beginPhase
10335 // to consolidate.
10336 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
10337 // If changes to the hydrated node needs to be applied at the
10338 // commit-phase we mark this as such.
10339 markUpdate(workInProgress);
10340 }
10341 } else {
10342 var _instance5 = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
10343
10344 appendAllChildren(_instance5, workInProgress, false, false);
10345
10346 if (enableFlareAPI) {
10347 var listeners = newProps.listeners;
10348 if (listeners != null) {
10349 updateEventListeners(listeners, _instance5, rootContainerInstance, workInProgress);
10350 }
10351 }
10352
10353 // Certain renderers require commit-time effects for initial mount.
10354 // (eg DOM renderer supports auto-focus for certain elements).
10355 // Make sure such renderers get scheduled for later work.
10356 if (finalizeInitialChildren(_instance5, type, newProps, rootContainerInstance, currentHostContext)) {
10357 markUpdate(workInProgress);
10358 }
10359 workInProgress.stateNode = _instance5;
10360 }
10361
10362 if (workInProgress.ref !== null) {
10363 // If there is a ref on a host node we need to schedule a callback
10364 markRef$1(workInProgress);
10365 }
10366 }
10367 break;
10368 }
10369 case HostText:
10370 {
10371 var newText = newProps;
10372 if (current && workInProgress.stateNode != null) {
10373 var oldText = current.memoizedProps;
10374 // If we have an alternate, that means this is an update and we need
10375 // to schedule a side-effect to do the updates.
10376 updateHostText$1(current, workInProgress, oldText, newText);
10377 } else {
10378 if (typeof newText !== 'string') {
10379 (function () {
10380 if (!(workInProgress.stateNode !== null)) {
10381 {
10382 throw ReactError(Error('We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.'));
10383 }
10384 }
10385 })();
10386 // This can happen when we abort work.
10387 }
10388 var _rootContainerInstance = getRootHostContainer();
10389 var _currentHostContext = getHostContext();
10390 var _wasHydrated = popHydrationState(workInProgress);
10391 if (_wasHydrated) {
10392 if (prepareToHydrateHostTextInstance(workInProgress)) {
10393 markUpdate(workInProgress);
10394 }
10395 } else {
10396 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
10397 }
10398 }
10399 break;
10400 }
10401 case ForwardRef:
10402 break;
10403 case SuspenseComponent:
10404 {
10405 popSuspenseContext(workInProgress);
10406 var nextState = workInProgress.memoizedState;
10407 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
10408 // Something suspended. Re-render with the fallback children.
10409 workInProgress.expirationTime = renderExpirationTime;
10410 // Do not reset the effect list.
10411 return workInProgress;
10412 }
10413
10414 var nextDidTimeout = nextState !== null;
10415 var prevDidTimeout = false;
10416 if (current === null) {
10417 // In cases where we didn't find a suitable hydration boundary we never
10418 // downgraded this to a DehydratedSuspenseComponent, but we still need to
10419 // pop the hydration state since we might be inside the insertion tree.
10420 popHydrationState(workInProgress);
10421 } else {
10422 var prevState = current.memoizedState;
10423 prevDidTimeout = prevState !== null;
10424 if (!nextDidTimeout && prevState !== null) {
10425 // We just switched from the fallback to the normal children.
10426 // Delete the fallback.
10427 // TODO: Would it be better to store the fallback fragment on
10428 var currentFallbackChild = current.child.sibling;
10429 if (currentFallbackChild !== null) {
10430 // Deletions go at the beginning of the return fiber's effect list
10431 var first = workInProgress.firstEffect;
10432 if (first !== null) {
10433 workInProgress.firstEffect = currentFallbackChild;
10434 currentFallbackChild.nextEffect = first;
10435 } else {
10436 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
10437 currentFallbackChild.nextEffect = null;
10438 }
10439 currentFallbackChild.effectTag = Deletion;
10440 }
10441 }
10442 }
10443
10444 if (nextDidTimeout && !prevDidTimeout) {
10445 // If this subtreee is running in batched mode we can suspend,
10446 // otherwise we won't suspend.
10447 // TODO: This will still suspend a synchronous tree if anything
10448 // in the concurrent tree already suspended during this render.
10449 // This is a known bug.
10450 if ((workInProgress.mode & BatchedMode) !== NoMode) {
10451 // TODO: Move this back to throwException because this is too late
10452 // if this is a large tree which is common for initial loads. We
10453 // don't know if we should restart a render or not until we get
10454 // this marker, and this is too late.
10455 // If this render already had a ping or lower pri updates,
10456 // and this is the first time we know we're going to suspend we
10457 // should be able to immediately restart from within throwException.
10458 var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true;
10459 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
10460 // If this was in an invisible tree or a new render, then showing
10461 // this boundary is ok.
10462 renderDidSuspend();
10463 } else {
10464 // Otherwise, we're going to have to hide content so we should
10465 // suspend for longer if possible.
10466 renderDidSuspendDelayIfPossible();
10467 }
10468 }
10469 }
10470
10471 if (supportsPersistence) {
10472 // TODO: Only schedule updates if not prevDidTimeout.
10473 if (nextDidTimeout) {
10474 // If this boundary just timed out, schedule an effect to attach a
10475 // retry listener to the proimse. This flag is also used to hide the
10476 // primary children.
10477 workInProgress.effectTag |= Update;
10478 }
10479 }
10480 if (supportsMutation) {
10481 // TODO: Only schedule updates if these values are non equal, i.e. it changed.
10482 if (nextDidTimeout || prevDidTimeout) {
10483 // If this boundary just timed out, schedule an effect to attach a
10484 // retry listener to the proimse. This flag is also used to hide the
10485 // primary children. In mutation mode, we also need the flag to
10486 // *unhide* children that were previously hidden, so check if the
10487 // is currently timed out, too.
10488 workInProgress.effectTag |= Update;
10489 }
10490 }
10491 if (enableSuspenseCallback && workInProgress.updateQueue !== null && workInProgress.memoizedProps.suspenseCallback != null) {
10492 // Always notify the callback
10493 workInProgress.effectTag |= Update;
10494 }
10495 break;
10496 }
10497 case Fragment:
10498 break;
10499 case Mode:
10500 break;
10501 case Profiler:
10502 break;
10503 case HostPortal:
10504 popHostContainer(workInProgress);
10505 updateHostContainer(workInProgress);
10506 break;
10507 case ContextProvider:
10508 // Pop provider fiber
10509 popProvider(workInProgress);
10510 break;
10511 case ContextConsumer:
10512 break;
10513 case MemoComponent:
10514 break;
10515 case IncompleteClassComponent:
10516 {
10517 // Same as class component case. I put it down here so that the tags are
10518 // sequential to ensure this switch is compiled to a jump table.
10519 var _Component = workInProgress.type;
10520 if (isContextProvider(_Component)) {
10521 popContext(workInProgress);
10522 }
10523 break;
10524 }
10525 case DehydratedSuspenseComponent:
10526 {
10527 if (enableSuspenseServerRenderer) {
10528 popSuspenseContext(workInProgress);
10529 if (current === null) {
10530 var _wasHydrated2 = popHydrationState(workInProgress);
10531 (function () {
10532 if (!_wasHydrated2) {
10533 {
10534 throw ReactError(Error('A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.'));
10535 }
10536 }
10537 })();
10538 if (enableSchedulerTracing) {
10539 markSpawnedWork(Never);
10540 }
10541 skipPastDehydratedSuspenseInstance(workInProgress);
10542 } else if ((workInProgress.effectTag & DidCapture) === NoEffect) {
10543 // This boundary did not suspend so it's now hydrated.
10544 // To handle any future suspense cases, we're going to now upgrade it
10545 // to a Suspense component. We detach it from the existing current fiber.
10546 current.alternate = null;
10547 workInProgress.alternate = null;
10548 workInProgress.tag = SuspenseComponent;
10549 workInProgress.memoizedState = null;
10550 workInProgress.stateNode = null;
10551 }
10552 }
10553 break;
10554 }
10555 case SuspenseListComponent:
10556 {
10557 popSuspenseContext(workInProgress);
10558
10559 var renderState = workInProgress.memoizedState;
10560
10561 if (renderState === null) {
10562 // We're running in the default, "independent" mode. We don't do anything
10563 // in this mode.
10564 break;
10565 }
10566
10567 var didSuspendAlready = (workInProgress.effectTag & DidCapture) !== NoEffect;
10568
10569 var renderedTail = renderState.rendering;
10570 if (renderedTail === null) {
10571 // We just rendered the head.
10572 if (!didSuspendAlready) {
10573 // This is the first pass. We need to figure out if anything is still
10574 // suspended in the rendered set.
10575
10576 // If new content unsuspended, but there's still some content that
10577 // didn't. Then we need to do a second pass that forces everything
10578 // to keep showing their fallbacks.
10579
10580 // We might be suspended if something in this render pass suspended, or
10581 // something in the previous committed pass suspended. Otherwise,
10582 // there's no chance so we can skip the expensive call to
10583 // findFirstSuspended.
10584 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.effectTag & DidCapture) === NoEffect);
10585 if (!cannotBeSuspended) {
10586 var row = workInProgress.child;
10587 while (row !== null) {
10588 var suspended = findFirstSuspended(row);
10589 if (suspended !== null) {
10590 didSuspendAlready = true;
10591 workInProgress.effectTag |= DidCapture;
10592 cutOffTailIfNeeded(renderState, false);
10593
10594 // If this is a newly suspended tree, it might not get committed as
10595 // part of the second pass. In that case nothing will subscribe to
10596 // its thennables. Instead, we'll transfer its thennables to the
10597 // SuspenseList so that it can retry if they resolve.
10598 // There might be multiple of these in the list but since we're
10599 // going to wait for all of them anyway, it doesn't really matter
10600 // which ones gets to ping. In theory we could get clever and keep
10601 // track of how many dependencies remain but it gets tricky because
10602 // in the meantime, we can add/remove/change items and dependencies.
10603 // We might bail out of the loop before finding any but that
10604 // doesn't matter since that means that the other boundaries that
10605 // we did find already has their listeners attached.
10606 var newThennables = suspended.updateQueue;
10607 if (newThennables !== null) {
10608 workInProgress.updateQueue = newThennables;
10609 workInProgress.effectTag |= Update;
10610 }
10611
10612 // Rerender the whole list, but this time, we'll force fallbacks
10613 // to stay in place.
10614 // Reset the effect list before doing the second pass since that's now invalid.
10615 workInProgress.firstEffect = workInProgress.lastEffect = null;
10616 // Reset the child fibers to their original state.
10617 resetChildFibers(workInProgress, renderExpirationTime);
10618
10619 // Set up the Suspense Context to force suspense and immediately
10620 // rerender the children.
10621 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
10622 return workInProgress.child;
10623 }
10624 row = row.sibling;
10625 }
10626 }
10627 } else {
10628 cutOffTailIfNeeded(renderState, false);
10629 }
10630 // Next we're going to render the tail.
10631 } else {
10632 // Append the rendered row to the child list.
10633 if (!didSuspendAlready) {
10634 var _suspended = findFirstSuspended(renderedTail);
10635 if (_suspended !== null) {
10636 workInProgress.effectTag |= DidCapture;
10637 didSuspendAlready = true;
10638 cutOffTailIfNeeded(renderState, true);
10639 // This might have been modified.
10640 if (renderState.tail === null && renderState.tailMode === 'hidden') {
10641 // We need to delete the row we just rendered.
10642 // Ensure we transfer the update queue to the parent.
10643 var _newThennables = _suspended.updateQueue;
10644 if (_newThennables !== null) {
10645 workInProgress.updateQueue = _newThennables;
10646 workInProgress.effectTag |= Update;
10647 }
10648 // Reset the effect list to what it w as before we rendered this
10649 // child. The nested children have already appended themselves.
10650 var lastEffect = workInProgress.lastEffect = renderState.lastEffect;
10651 // Remove any effects that were appended after this point.
10652 if (lastEffect !== null) {
10653 lastEffect.nextEffect = null;
10654 }
10655 // We're done.
10656 return null;
10657 }
10658 } else if (now() > renderState.tailExpiration && renderExpirationTime > Never) {
10659 // We have now passed our CPU deadline and we'll just give up further
10660 // attempts to render the main content and only render fallbacks.
10661 // The assumption is that this is usually faster.
10662 workInProgress.effectTag |= DidCapture;
10663 didSuspendAlready = true;
10664
10665 cutOffTailIfNeeded(renderState, false);
10666
10667 // Since nothing actually suspended, there will nothing to ping this
10668 // to get it started back up to attempt the next item. If we can show
10669 // them, then they really have the same priority as this render.
10670 // So we'll pick it back up the very next render pass once we've had
10671 // an opportunity to yield for paint.
10672
10673 var nextPriority = renderExpirationTime - 1;
10674 workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority;
10675 if (enableSchedulerTracing) {
10676 markSpawnedWork(nextPriority);
10677 }
10678 }
10679 }
10680 if (renderState.isBackwards) {
10681 // The effect list of the backwards tail will have been added
10682 // to the end. This breaks the guarantee that life-cycles fire in
10683 // sibling order but that isn't a strong guarantee promised by React.
10684 // Especially since these might also just pop in during future commits.
10685 // Append to the beginning of the list.
10686 renderedTail.sibling = workInProgress.child;
10687 workInProgress.child = renderedTail;
10688 } else {
10689 var previousSibling = renderState.last;
10690 if (previousSibling !== null) {
10691 previousSibling.sibling = renderedTail;
10692 } else {
10693 workInProgress.child = renderedTail;
10694 }
10695 renderState.last = renderedTail;
10696 }
10697 }
10698
10699 if (renderState.tail !== null) {
10700 // We still have tail rows to render.
10701 if (renderState.tailExpiration === 0) {
10702 // Heuristic for how long we're willing to spend rendering rows
10703 // until we just give up and show what we have so far.
10704 var TAIL_EXPIRATION_TIMEOUT_MS = 500;
10705 renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS;
10706 }
10707 // Pop a row.
10708 var next = renderState.tail;
10709 renderState.rendering = next;
10710 renderState.tail = next.sibling;
10711 renderState.lastEffect = workInProgress.lastEffect;
10712 next.sibling = null;
10713
10714 // Restore the context.
10715 // TODO: We can probably just avoid popping it instead and only
10716 // setting it the first time we go from not suspended to suspended.
10717 var suspenseContext = suspenseStackCursor.current;
10718 if (didSuspendAlready) {
10719 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
10720 } else {
10721 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
10722 }
10723 pushSuspenseContext(workInProgress, suspenseContext);
10724 // Do a pass over the next row.
10725 return next;
10726 }
10727 break;
10728 }
10729 case FundamentalComponent:
10730 {
10731 if (enableFundamentalAPI) {
10732 var fundamentalImpl = workInProgress.type.impl;
10733 var fundamentalInstance = workInProgress.stateNode;
10734
10735 if (fundamentalInstance === null) {
10736 var getInitialState = fundamentalImpl.getInitialState;
10737 var fundamentalState = void 0;
10738 if (getInitialState !== undefined) {
10739 fundamentalState = getInitialState(newProps);
10740 }
10741 fundamentalInstance = workInProgress.stateNode = createFundamentalStateInstance(workInProgress, newProps, fundamentalImpl, fundamentalState || {});
10742 var _instance6 = getFundamentalComponentInstance(fundamentalInstance);
10743 fundamentalInstance.instance = _instance6;
10744 if (fundamentalImpl.reconcileChildren === false) {
10745 return null;
10746 }
10747 appendAllChildren(_instance6, workInProgress, false, false);
10748 mountFundamentalComponent(fundamentalInstance);
10749 } else {
10750 // We fire update in commit phase
10751 var prevProps = fundamentalInstance.props;
10752 fundamentalInstance.prevProps = prevProps;
10753 fundamentalInstance.props = newProps;
10754 fundamentalInstance.currentFiber = workInProgress;
10755 if (supportsPersistence) {
10756 var _instance7 = cloneFundamentalInstance(fundamentalInstance);
10757 fundamentalInstance.instance = _instance7;
10758 appendAllChildren(_instance7, workInProgress, false, false);
10759 }
10760 var shouldUpdate = shouldUpdateFundamentalComponent(fundamentalInstance);
10761 if (shouldUpdate) {
10762 markUpdate(workInProgress);
10763 }
10764 }
10765 }
10766 break;
10767 }
10768 default:
10769 (function () {
10770 {
10771 {
10772 throw ReactError(Error('Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.'));
10773 }
10774 }
10775 })();
10776 }
10777
10778 return null;
10779}
10780
10781function mountEventResponder(responder, responderProps, instance, rootContainerInstance, fiber, respondersMap) {
10782 var responderState = emptyObject;
10783 var getInitialState = responder.getInitialState;
10784 if (getInitialState !== null) {
10785 responderState = getInitialState(responderProps);
10786 }
10787 var responderInstance = createResponderInstance(responder, responderProps, responderState, instance, fiber);
10788 mountResponderInstance(responder, responderInstance, responderProps, responderState, instance, rootContainerInstance);
10789 respondersMap.set(responder, responderInstance);
10790}
10791
10792function updateEventListener(listener, fiber, visistedResponders, respondersMap, instance, rootContainerInstance) {
10793 var responder = void 0;
10794 var props = void 0;
10795
10796 if (listener) {
10797 responder = listener.responder;
10798 props = listener.props;
10799 }
10800 (function () {
10801 if (!(responder && responder.$$typeof === REACT_RESPONDER_TYPE)) {
10802 {
10803 throw ReactError(Error('An invalid value was used as an event listener. Expect one or many event listeners created via React.unstable_useResponer().'));
10804 }
10805 }
10806 })();
10807 var listenerProps = props;
10808 if (visistedResponders.has(responder)) {
10809 // show warning
10810 {
10811 warning$1(false, 'Duplicate event responder "%s" found in event listeners. ' + 'Event listeners passed to elements cannot use the same event responder more than once.', responder.displayName);
10812 }
10813 return;
10814 }
10815 visistedResponders.add(responder);
10816 var responderInstance = respondersMap.get(responder);
10817
10818 if (responderInstance === undefined) {
10819 // Mount
10820 mountEventResponder(responder, listenerProps, instance, rootContainerInstance, fiber, respondersMap);
10821 } else {
10822 // Update
10823 responderInstance.props = listenerProps;
10824 responderInstance.fiber = fiber;
10825 }
10826}
10827
10828function updateEventListeners(listeners, instance, rootContainerInstance, fiber) {
10829 var visistedResponders = new Set();
10830 var dependencies = fiber.dependencies;
10831 if (listeners != null) {
10832 if (dependencies === null) {
10833 dependencies = fiber.dependencies = {
10834 expirationTime: NoWork,
10835 firstContext: null,
10836 responders: new Map()
10837 };
10838 }
10839 var respondersMap = dependencies.responders;
10840 if (respondersMap === null) {
10841 respondersMap = new Map();
10842 }
10843 if (isArray$2(listeners)) {
10844 for (var i = 0, length = listeners.length; i < length; i++) {
10845 var listener = listeners[i];
10846 updateEventListener(listener, fiber, visistedResponders, respondersMap, instance, rootContainerInstance);
10847 }
10848 } else {
10849 updateEventListener(listeners, fiber, visistedResponders, respondersMap, instance, rootContainerInstance);
10850 }
10851 }
10852 if (dependencies !== null) {
10853 var _respondersMap = dependencies.responders;
10854 if (_respondersMap !== null) {
10855 // Unmount
10856 var mountedResponders = Array.from(_respondersMap.keys());
10857 for (var _i = 0, _length = mountedResponders.length; _i < _length; _i++) {
10858 var mountedResponder = mountedResponders[_i];
10859 if (!visistedResponders.has(mountedResponder)) {
10860 var responderInstance = _respondersMap.get(mountedResponder);
10861 unmountResponderInstance(responderInstance);
10862 _respondersMap.delete(mountedResponder);
10863 }
10864 }
10865 }
10866 }
10867}
10868
10869function unwindWork(workInProgress, renderExpirationTime) {
10870 switch (workInProgress.tag) {
10871 case ClassComponent:
10872 {
10873 var Component = workInProgress.type;
10874 if (isContextProvider(Component)) {
10875 popContext(workInProgress);
10876 }
10877 var effectTag = workInProgress.effectTag;
10878 if (effectTag & ShouldCapture) {
10879 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
10880 return workInProgress;
10881 }
10882 return null;
10883 }
10884 case HostRoot:
10885 {
10886 popHostContainer(workInProgress);
10887 popTopLevelContextObject(workInProgress);
10888 var _effectTag = workInProgress.effectTag;
10889 (function () {
10890 if (!((_effectTag & DidCapture) === NoEffect)) {
10891 {
10892 throw ReactError(Error('The root failed to unmount after an error. This is likely a bug in React. Please file an issue.'));
10893 }
10894 }
10895 })();
10896 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
10897 return workInProgress;
10898 }
10899 case HostComponent:
10900 {
10901 // TODO: popHydrationState
10902 popHostContext(workInProgress);
10903 return null;
10904 }
10905 case SuspenseComponent:
10906 {
10907 popSuspenseContext(workInProgress);
10908 var _effectTag2 = workInProgress.effectTag;
10909 if (_effectTag2 & ShouldCapture) {
10910 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture;
10911 // Captured a suspense effect. Re-render the boundary.
10912 return workInProgress;
10913 }
10914 return null;
10915 }
10916 case DehydratedSuspenseComponent:
10917 {
10918 if (enableSuspenseServerRenderer) {
10919 // TODO: popHydrationState
10920 popSuspenseContext(workInProgress);
10921 var _effectTag3 = workInProgress.effectTag;
10922 if (_effectTag3 & ShouldCapture) {
10923 workInProgress.effectTag = _effectTag3 & ~ShouldCapture | DidCapture;
10924 // Captured a suspense effect. Re-render the boundary.
10925 return workInProgress;
10926 }
10927 }
10928 return null;
10929 }
10930 case SuspenseListComponent:
10931 {
10932 popSuspenseContext(workInProgress);
10933 // SuspenseList doesn't actually catch anything. It should've been
10934 // caught by a nested boundary. If not, it should bubble through.
10935 return null;
10936 }
10937 case HostPortal:
10938 popHostContainer(workInProgress);
10939 return null;
10940 case ContextProvider:
10941 popProvider(workInProgress);
10942 return null;
10943 default:
10944 return null;
10945 }
10946}
10947
10948function unwindInterruptedWork(interruptedWork) {
10949 switch (interruptedWork.tag) {
10950 case ClassComponent:
10951 {
10952 var childContextTypes = interruptedWork.type.childContextTypes;
10953 if (childContextTypes !== null && childContextTypes !== undefined) {
10954 popContext(interruptedWork);
10955 }
10956 break;
10957 }
10958 case HostRoot:
10959 {
10960 popHostContainer(interruptedWork);
10961 popTopLevelContextObject(interruptedWork);
10962 break;
10963 }
10964 case HostComponent:
10965 {
10966 popHostContext(interruptedWork);
10967 break;
10968 }
10969 case HostPortal:
10970 popHostContainer(interruptedWork);
10971 break;
10972 case SuspenseComponent:
10973 popSuspenseContext(interruptedWork);
10974 break;
10975 case DehydratedSuspenseComponent:
10976 if (enableSuspenseServerRenderer) {
10977 // TODO: popHydrationState
10978 popSuspenseContext(interruptedWork);
10979 }
10980 break;
10981 case SuspenseListComponent:
10982 popSuspenseContext(interruptedWork);
10983 break;
10984 case ContextProvider:
10985 popProvider(interruptedWork);
10986 break;
10987 default:
10988 break;
10989 }
10990}
10991
10992function createCapturedValue(value, source) {
10993 // If the value is an error, call this function immediately after it is thrown
10994 // so the stack is accurate.
10995 return {
10996 value: value,
10997 source: source,
10998 stack: getStackByFiberInDevAndProd(source)
10999 };
11000}
11001
11002var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
11003 var funcArgs = Array.prototype.slice.call(arguments, 3);
11004 try {
11005 func.apply(context, funcArgs);
11006 } catch (error) {
11007 this.onError(error);
11008 }
11009};
11010
11011{
11012 // In DEV mode, we swap out invokeGuardedCallback for a special version
11013 // that plays more nicely with the browser's DevTools. The idea is to preserve
11014 // "Pause on exceptions" behavior. Because React wraps all user-provided
11015 // functions in invokeGuardedCallback, and the production version of
11016 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
11017 // like caught exceptions, and the DevTools won't pause unless the developer
11018 // takes the extra step of enabling pause on caught exceptions. This is
11019 // unintuitive, though, because even though React has caught the error, from
11020 // the developer's perspective, the error is uncaught.
11021 //
11022 // To preserve the expected "Pause on exceptions" behavior, we don't use a
11023 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
11024 // DOM node, and call the user-provided callback from inside an event handler
11025 // for that fake event. If the callback throws, the error is "captured" using
11026 // a global event handler. But because the error happens in a different
11027 // event loop context, it does not interrupt the normal program flow.
11028 // Effectively, this gives us try-catch behavior without actually using
11029 // try-catch. Neat!
11030
11031 // Check that the browser supports the APIs we need to implement our special
11032 // DEV version of invokeGuardedCallback
11033 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
11034 var fakeNode = document.createElement('react');
11035
11036 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
11037 // If document doesn't exist we know for sure we will crash in this method
11038 // when we call document.createEvent(). However this can cause confusing
11039 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
11040 // So we preemptively throw with a better message instead.
11041 (function () {
11042 if (!(typeof document !== 'undefined')) {
11043 {
11044 throw ReactError(Error('The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous.'));
11045 }
11046 }
11047 })();
11048 var evt = document.createEvent('Event');
11049
11050 // Keeps track of whether the user-provided callback threw an error. We
11051 // set this to true at the beginning, then set it to false right after
11052 // calling the function. If the function errors, `didError` will never be
11053 // set to false. This strategy works even if the browser is flaky and
11054 // fails to call our global error handler, because it doesn't rely on
11055 // the error event at all.
11056 var didError = true;
11057
11058 // Keeps track of the value of window.event so that we can reset it
11059 // during the callback to let user code access window.event in the
11060 // browsers that support it.
11061 var windowEvent = window.event;
11062
11063 // Keeps track of the descriptor of window.event to restore it after event
11064 // dispatching: https://github.com/facebook/react/issues/13688
11065 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
11066
11067 // Create an event handler for our fake event. We will synchronously
11068 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
11069 // call the user-provided callback.
11070 var funcArgs = Array.prototype.slice.call(arguments, 3);
11071 function callCallback() {
11072 // We immediately remove the callback from event listeners so that
11073 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
11074 // nested call would trigger the fake event handlers of any call higher
11075 // in the stack.
11076 fakeNode.removeEventListener(evtType, callCallback, false);
11077
11078 // We check for window.hasOwnProperty('event') to prevent the
11079 // window.event assignment in both IE <= 10 as they throw an error
11080 // "Member not found" in strict mode, and in Firefox which does not
11081 // support window.event.
11082 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
11083 window.event = windowEvent;
11084 }
11085
11086 func.apply(context, funcArgs);
11087 didError = false;
11088 }
11089
11090 // Create a global error event handler. We use this to capture the value
11091 // that was thrown. It's possible that this error handler will fire more
11092 // than once; for example, if non-React code also calls `dispatchEvent`
11093 // and a handler for that event throws. We should be resilient to most of
11094 // those cases. Even if our error event handler fires more than once, the
11095 // last error event is always used. If the callback actually does error,
11096 // we know that the last error event is the correct one, because it's not
11097 // possible for anything else to have happened in between our callback
11098 // erroring and the code that follows the `dispatchEvent` call below. If
11099 // the callback doesn't error, but the error event was fired, we know to
11100 // ignore it because `didError` will be false, as described above.
11101 var error = void 0;
11102 // Use this to track whether the error event is ever called.
11103 var didSetError = false;
11104 var isCrossOriginError = false;
11105
11106 function handleWindowError(event) {
11107 error = event.error;
11108 didSetError = true;
11109 if (error === null && event.colno === 0 && event.lineno === 0) {
11110 isCrossOriginError = true;
11111 }
11112 if (event.defaultPrevented) {
11113 // Some other error handler has prevented default.
11114 // Browsers silence the error report if this happens.
11115 // We'll remember this to later decide whether to log it or not.
11116 if (error != null && typeof error === 'object') {
11117 try {
11118 error._suppressLogging = true;
11119 } catch (inner) {
11120 // Ignore.
11121 }
11122 }
11123 }
11124 }
11125
11126 // Create a fake event type.
11127 var evtType = 'react-' + (name ? name : 'invokeguardedcallback');
11128
11129 // Attach our event handlers
11130 window.addEventListener('error', handleWindowError);
11131 fakeNode.addEventListener(evtType, callCallback, false);
11132
11133 // Synchronously dispatch our fake event. If the user-provided function
11134 // errors, it will trigger our global error handler.
11135 evt.initEvent(evtType, false, false);
11136 fakeNode.dispatchEvent(evt);
11137
11138 if (windowEventDescriptor) {
11139 Object.defineProperty(window, 'event', windowEventDescriptor);
11140 }
11141
11142 if (didError) {
11143 if (!didSetError) {
11144 // The callback errored, but the error event never fired.
11145 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.');
11146 } else if (isCrossOriginError) {
11147 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.');
11148 }
11149 this.onError(error);
11150 }
11151
11152 // Remove our event listeners
11153 window.removeEventListener('error', handleWindowError);
11154 };
11155
11156 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
11157 }
11158}
11159
11160var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
11161
11162// Used by Fiber to simulate a try-catch.
11163var hasError = false;
11164var caughtError = null;
11165
11166var reporter = {
11167 onError: function (error) {
11168 hasError = true;
11169 caughtError = error;
11170 }
11171};
11172
11173/**
11174 * Call a function while guarding against errors that happens within it.
11175 * Returns an error if it throws, otherwise null.
11176 *
11177 * In production, this is implemented using a try-catch. The reason we don't
11178 * use a try-catch directly is so that we can swap out a different
11179 * implementation in DEV mode.
11180 *
11181 * @param {String} name of the guard to use for logging or debugging
11182 * @param {Function} func The function to invoke
11183 * @param {*} context The context to use when calling the function
11184 * @param {...*} args Arguments for function
11185 */
11186function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
11187 hasError = false;
11188 caughtError = null;
11189 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
11190}
11191
11192/**
11193 * Same as invokeGuardedCallback, but instead of returning an error, it stores
11194 * it in a global so it can be rethrown by `rethrowCaughtError` later.
11195 * TODO: See if caughtError and rethrowError can be unified.
11196 *
11197 * @param {String} name of the guard to use for logging or debugging
11198 * @param {Function} func The function to invoke
11199 * @param {*} context The context to use when calling the function
11200 * @param {...*} args Arguments for function
11201 */
11202
11203
11204/**
11205 * During execution of guarded functions we will capture the first error which
11206 * we will rethrow to be handled by the top level error handler.
11207 */
11208
11209
11210function hasCaughtError() {
11211 return hasError;
11212}
11213
11214function clearCaughtError() {
11215 if (hasError) {
11216 var error = caughtError;
11217 hasError = false;
11218 caughtError = null;
11219 return error;
11220 } else {
11221 (function () {
11222 {
11223 {
11224 throw ReactError(Error('clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.'));
11225 }
11226 }
11227 })();
11228 }
11229}
11230
11231// This module is forked in different environments.
11232// By default, return `true` to log errors to the console.
11233// Forks can return `false` if this isn't desirable.
11234function showErrorDialog(capturedError) {
11235 return true;
11236}
11237
11238function logCapturedError(capturedError) {
11239 var logError = showErrorDialog(capturedError);
11240
11241 // Allow injected showErrorDialog() to prevent default console.error logging.
11242 // This enables renderers like ReactNative to better manage redbox behavior.
11243 if (logError === false) {
11244 return;
11245 }
11246
11247 var error = capturedError.error;
11248 {
11249 var componentName = capturedError.componentName,
11250 componentStack = capturedError.componentStack,
11251 errorBoundaryName = capturedError.errorBoundaryName,
11252 errorBoundaryFound = capturedError.errorBoundaryFound,
11253 willRetry = capturedError.willRetry;
11254
11255 // Browsers support silencing uncaught errors by calling
11256 // `preventDefault()` in window `error` handler.
11257 // We record this information as an expando on the error.
11258
11259 if (error != null && error._suppressLogging) {
11260 if (errorBoundaryFound && willRetry) {
11261 // The error is recoverable and was silenced.
11262 // Ignore it and don't print the stack addendum.
11263 // This is handy for testing error boundaries without noise.
11264 return;
11265 }
11266 // The error is fatal. Since the silencing might have
11267 // been accidental, we'll surface it anyway.
11268 // However, the browser would have silenced the original error
11269 // so we'll print it first, and then print the stack addendum.
11270 console.error(error);
11271 // For a more detailed description of this block, see:
11272 // https://github.com/facebook/react/pull/13384
11273 }
11274
11275 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
11276
11277 var errorBoundaryMessage = void 0;
11278 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
11279 if (errorBoundaryFound && errorBoundaryName) {
11280 if (willRetry) {
11281 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
11282 } else {
11283 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
11284 }
11285 } else {
11286 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.';
11287 }
11288 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
11289
11290 // In development, we provide our own message with just the component stack.
11291 // We don't include the original error message and JS stack because the browser
11292 // has already printed it. Even if the application swallows the error, it is still
11293 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
11294 console.error(combinedMessage);
11295 }
11296}
11297
11298var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
11299{
11300 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
11301}
11302
11303var PossiblyWeakSet$1 = typeof WeakSet === 'function' ? WeakSet : Set;
11304
11305function logError(boundary, errorInfo) {
11306 var source = errorInfo.source;
11307 var stack = errorInfo.stack;
11308 if (stack === null && source !== null) {
11309 stack = getStackByFiberInDevAndProd(source);
11310 }
11311
11312 var capturedError = {
11313 componentName: source !== null ? getComponentName(source.type) : null,
11314 componentStack: stack !== null ? stack : '',
11315 error: errorInfo.value,
11316 errorBoundary: null,
11317 errorBoundaryName: null,
11318 errorBoundaryFound: false,
11319 willRetry: false
11320 };
11321
11322 if (boundary !== null && boundary.tag === ClassComponent) {
11323 capturedError.errorBoundary = boundary.stateNode;
11324 capturedError.errorBoundaryName = getComponentName(boundary.type);
11325 capturedError.errorBoundaryFound = true;
11326 capturedError.willRetry = true;
11327 }
11328
11329 try {
11330 logCapturedError(capturedError);
11331 } catch (e) {
11332 // This method must not throw, or React internal state will get messed up.
11333 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
11334 // we want to report this error outside of the normal stack as a last resort.
11335 // https://github.com/facebook/react/issues/13188
11336 setTimeout(function () {
11337 throw e;
11338 });
11339 }
11340}
11341
11342var callComponentWillUnmountWithTimer = function (current, instance) {
11343 startPhaseTimer(current, 'componentWillUnmount');
11344 instance.props = current.memoizedProps;
11345 instance.state = current.memoizedState;
11346 instance.componentWillUnmount();
11347 stopPhaseTimer();
11348};
11349
11350// Capture errors so they don't interrupt unmounting.
11351function safelyCallComponentWillUnmount(current, instance) {
11352 {
11353 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);
11354 if (hasCaughtError()) {
11355 var unmountError = clearCaughtError();
11356 captureCommitPhaseError(current, unmountError);
11357 }
11358 }
11359}
11360
11361function safelyDetachRef(current) {
11362 var ref = current.ref;
11363 if (ref !== null) {
11364 if (typeof ref === 'function') {
11365 {
11366 invokeGuardedCallback(null, ref, null, null);
11367 if (hasCaughtError()) {
11368 var refError = clearCaughtError();
11369 captureCommitPhaseError(current, refError);
11370 }
11371 }
11372 } else {
11373 ref.current = null;
11374 }
11375 }
11376}
11377
11378function safelyCallDestroy(current, destroy) {
11379 {
11380 invokeGuardedCallback(null, destroy, null);
11381 if (hasCaughtError()) {
11382 var error = clearCaughtError();
11383 captureCommitPhaseError(current, error);
11384 }
11385 }
11386}
11387
11388function commitBeforeMutationLifeCycles(current, finishedWork) {
11389 switch (finishedWork.tag) {
11390 case FunctionComponent:
11391 case ForwardRef:
11392 case SimpleMemoComponent:
11393 {
11394 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
11395 return;
11396 }
11397 case ClassComponent:
11398 {
11399 if (finishedWork.effectTag & Snapshot) {
11400 if (current !== null) {
11401 var prevProps = current.memoizedProps;
11402 var prevState = current.memoizedState;
11403 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
11404 var instance = finishedWork.stateNode;
11405 // We could update instance props and state here,
11406 // but instead we rely on them being set during last render.
11407 // TODO: revisit this when we implement resuming.
11408 {
11409 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
11410 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
11411 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
11412 }
11413 }
11414 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
11415 {
11416 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
11417 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
11418 didWarnSet.add(finishedWork.type);
11419 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
11420 }
11421 }
11422 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
11423 stopPhaseTimer();
11424 }
11425 }
11426 return;
11427 }
11428 case HostRoot:
11429 case HostComponent:
11430 case HostText:
11431 case HostPortal:
11432 case IncompleteClassComponent:
11433 // Nothing to do for these component types
11434 return;
11435 default:
11436 {
11437 (function () {
11438 {
11439 {
11440 throw ReactError(Error('This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.'));
11441 }
11442 }
11443 })();
11444 }
11445 }
11446}
11447
11448function commitHookEffectList(unmountTag, mountTag, finishedWork) {
11449 var updateQueue = finishedWork.updateQueue;
11450 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
11451 if (lastEffect !== null) {
11452 var firstEffect = lastEffect.next;
11453 var effect = firstEffect;
11454 do {
11455 if ((effect.tag & unmountTag) !== NoEffect$1) {
11456 // Unmount
11457 var destroy = effect.destroy;
11458 effect.destroy = undefined;
11459 if (destroy !== undefined) {
11460 destroy();
11461 }
11462 }
11463 if ((effect.tag & mountTag) !== NoEffect$1) {
11464 // Mount
11465 var create = effect.create;
11466 effect.destroy = create();
11467
11468 {
11469 var _destroy = effect.destroy;
11470 if (_destroy !== undefined && typeof _destroy !== 'function') {
11471 var addendum = void 0;
11472 if (_destroy === null) {
11473 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
11474 } else if (typeof _destroy.then === 'function') {
11475 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';
11476 } else {
11477 addendum = ' You returned: ' + _destroy;
11478 }
11479 warningWithoutStack$1(false, 'An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
11480 }
11481 }
11482 }
11483 effect = effect.next;
11484 } while (effect !== firstEffect);
11485 }
11486}
11487
11488function commitPassiveHookEffects(finishedWork) {
11489 if ((finishedWork.effectTag & Passive) !== NoEffect) {
11490 switch (finishedWork.tag) {
11491 case FunctionComponent:
11492 case ForwardRef:
11493 case SimpleMemoComponent:
11494 {
11495 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
11496 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
11497 break;
11498 }
11499 default:
11500 break;
11501 }
11502 }
11503}
11504
11505function commitLifeCycles(finishedRoot, current, finishedWork, committedExpirationTime) {
11506 switch (finishedWork.tag) {
11507 case FunctionComponent:
11508 case ForwardRef:
11509 case SimpleMemoComponent:
11510 {
11511 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
11512 break;
11513 }
11514 case ClassComponent:
11515 {
11516 var instance = finishedWork.stateNode;
11517 if (finishedWork.effectTag & Update) {
11518 if (current === null) {
11519 startPhaseTimer(finishedWork, 'componentDidMount');
11520 // We could update instance props and state here,
11521 // but instead we rely on them being set during last render.
11522 // TODO: revisit this when we implement resuming.
11523 {
11524 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
11525 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
11526 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
11527 }
11528 }
11529 instance.componentDidMount();
11530 stopPhaseTimer();
11531 } else {
11532 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
11533 var prevState = current.memoizedState;
11534 startPhaseTimer(finishedWork, 'componentDidUpdate');
11535 // We could update instance props and state here,
11536 // but instead we rely on them being set during last render.
11537 // TODO: revisit this when we implement resuming.
11538 {
11539 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
11540 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
11541 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
11542 }
11543 }
11544 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
11545 stopPhaseTimer();
11546 }
11547 }
11548 var updateQueue = finishedWork.updateQueue;
11549 if (updateQueue !== null) {
11550 {
11551 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
11552 !(instance.props === finishedWork.memoizedProps) ? warning$1(false, 'Expected %s props to match memoized props before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
11553 !(instance.state === finishedWork.memoizedState) ? warning$1(false, 'Expected %s state to match memoized state before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentName(finishedWork.type) || 'instance') : void 0;
11554 }
11555 }
11556 // We could update instance props and state here,
11557 // but instead we rely on them being set during last render.
11558 // TODO: revisit this when we implement resuming.
11559 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
11560 }
11561 return;
11562 }
11563 case HostRoot:
11564 {
11565 var _updateQueue = finishedWork.updateQueue;
11566 if (_updateQueue !== null) {
11567 var _instance = null;
11568 if (finishedWork.child !== null) {
11569 switch (finishedWork.child.tag) {
11570 case HostComponent:
11571 _instance = getPublicInstance(finishedWork.child.stateNode);
11572 break;
11573 case ClassComponent:
11574 _instance = finishedWork.child.stateNode;
11575 break;
11576 }
11577 }
11578 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
11579 }
11580 return;
11581 }
11582 case HostComponent:
11583 {
11584 var _instance2 = finishedWork.stateNode;
11585
11586 // Renderers may schedule work to be done after host components are mounted
11587 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
11588 // These effects should only be committed when components are first mounted,
11589 // aka when there is no current/alternate.
11590 if (current === null && finishedWork.effectTag & Update) {
11591 var type = finishedWork.type;
11592 var props = finishedWork.memoizedProps;
11593
11594 }
11595
11596 return;
11597 }
11598 case HostText:
11599 {
11600 // We have no life-cycles associated with text.
11601 return;
11602 }
11603 case HostPortal:
11604 {
11605 // We have no life-cycles associated with portals.
11606 return;
11607 }
11608 case Profiler:
11609 {
11610 if (enableProfilerTimer) {
11611 var onRender = finishedWork.memoizedProps.onRender;
11612
11613 if (typeof onRender === 'function') {
11614 if (enableSchedulerTracing) {
11615 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
11616 } else {
11617 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
11618 }
11619 }
11620 }
11621 return;
11622 }
11623 case SuspenseComponent:
11624 case SuspenseListComponent:
11625 case IncompleteClassComponent:
11626 case FundamentalComponent:
11627 return;
11628 default:
11629 {
11630 (function () {
11631 {
11632 {
11633 throw ReactError(Error('This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.'));
11634 }
11635 }
11636 })();
11637 }
11638 }
11639}
11640
11641function hideOrUnhideAllChildren(finishedWork, isHidden) {
11642 if (supportsMutation) {
11643 // We only have the top Fiber that was inserted but we need to recurse down its
11644 var node = finishedWork;
11645 while (true) {
11646 if (node.tag === HostComponent) {
11647 var instance = node.stateNode;
11648 if (isHidden) {
11649 hideInstance(instance);
11650 } else {
11651 unhideInstance(node.stateNode, node.memoizedProps);
11652 }
11653 } else if (node.tag === HostText) {
11654 var _instance3 = node.stateNode;
11655 if (isHidden) {
11656
11657 } else {
11658 unhideTextInstance(_instance3, node.memoizedProps);
11659 }
11660 } else if (node.tag === SuspenseComponent && node.memoizedState !== null) {
11661 // Found a nested Suspense component that timed out. Skip over the
11662 var fallbackChildFragment = node.child.sibling;
11663 fallbackChildFragment.return = node;
11664 node = fallbackChildFragment;
11665 continue;
11666 } else if (node.child !== null) {
11667 node.child.return = node;
11668 node = node.child;
11669 continue;
11670 }
11671 if (node === finishedWork) {
11672 return;
11673 }
11674 while (node.sibling === null) {
11675 if (node.return === null || node.return === finishedWork) {
11676 return;
11677 }
11678 node = node.return;
11679 }
11680 node.sibling.return = node.return;
11681 node = node.sibling;
11682 }
11683 }
11684}
11685
11686function commitAttachRef(finishedWork) {
11687 var ref = finishedWork.ref;
11688 if (ref !== null) {
11689 var instance = finishedWork.stateNode;
11690 var instanceToUse = void 0;
11691 switch (finishedWork.tag) {
11692 case HostComponent:
11693 instanceToUse = getPublicInstance(instance);
11694 break;
11695 default:
11696 instanceToUse = instance;
11697 }
11698 if (typeof ref === 'function') {
11699 ref(instanceToUse);
11700 } else {
11701 {
11702 if (!ref.hasOwnProperty('current')) {
11703 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
11704 }
11705 }
11706
11707 ref.current = instanceToUse;
11708 }
11709 }
11710}
11711
11712function commitDetachRef(current) {
11713 var currentRef = current.ref;
11714 if (currentRef !== null) {
11715 if (typeof currentRef === 'function') {
11716 currentRef(null);
11717 } else {
11718 currentRef.current = null;
11719 }
11720 }
11721}
11722
11723// User-originating errors (lifecycles and refs) should not interrupt
11724// deletion, so don't let them throw. Host-originating errors should
11725// interrupt deletion, so it's okay
11726function commitUnmount(current, renderPriorityLevel) {
11727 onCommitUnmount(current);
11728
11729 switch (current.tag) {
11730 case FunctionComponent:
11731 case ForwardRef:
11732 case MemoComponent:
11733 case SimpleMemoComponent:
11734 {
11735 var updateQueue = current.updateQueue;
11736 if (updateQueue !== null) {
11737 var lastEffect = updateQueue.lastEffect;
11738 if (lastEffect !== null) {
11739 var firstEffect = lastEffect.next;
11740
11741 // When the owner fiber is deleted, the destroy function of a passive
11742 // effect hook is called during the synchronous commit phase. This is
11743 // a concession to implementation complexity. Calling it in the
11744 // passive effect phase (like they usually are, when dependencies
11745 // change during an update) would require either traversing the
11746 // children of the deleted fiber again, or including unmount effects
11747 // as part of the fiber effect list.
11748 //
11749 // Because this is during the sync commit phase, we need to change
11750 // the priority.
11751 //
11752 // TODO: Reconsider this implementation trade off.
11753 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
11754 runWithPriority(priorityLevel, function () {
11755 var effect = firstEffect;
11756 do {
11757 var destroy = effect.destroy;
11758 if (destroy !== undefined) {
11759 safelyCallDestroy(current, destroy);
11760 }
11761 effect = effect.next;
11762 } while (effect !== firstEffect);
11763 });
11764 }
11765 }
11766 break;
11767 }
11768 case ClassComponent:
11769 {
11770 safelyDetachRef(current);
11771 var instance = current.stateNode;
11772 if (typeof instance.componentWillUnmount === 'function') {
11773 safelyCallComponentWillUnmount(current, instance);
11774 }
11775 return;
11776 }
11777 case HostComponent:
11778 {
11779 if (enableFlareAPI) {
11780 var dependencies = current.dependencies;
11781
11782 if (dependencies !== null) {
11783 var respondersMap = dependencies.responders;
11784 if (respondersMap !== null) {
11785 var responderInstances = Array.from(respondersMap.values());
11786 for (var i = 0, length = responderInstances.length; i < length; i++) {
11787 var responderInstance = responderInstances[i];
11788 unmountResponderInstance(responderInstance);
11789 }
11790 dependencies.responders = null;
11791 }
11792 }
11793 }
11794 safelyDetachRef(current);
11795 return;
11796 }
11797 case HostPortal:
11798 {
11799 // TODO: this is recursive.
11800 // We are also not using this parent because
11801 // the portal will get pushed immediately.
11802 if (supportsMutation) {
11803 unmountHostComponents(current, renderPriorityLevel);
11804 } else if (supportsPersistence) {
11805 emptyPortalContainer(current);
11806 }
11807 return;
11808 }
11809 case FundamentalComponent:
11810 {
11811 if (enableFundamentalAPI) {
11812 var fundamentalInstance = current.stateNode;
11813 if (fundamentalInstance !== null) {
11814 unmountFundamentalComponent(fundamentalInstance);
11815 current.stateNode = null;
11816 }
11817 }
11818 }
11819 }
11820}
11821
11822function commitNestedUnmounts(root, renderPriorityLevel) {
11823 // While we're inside a removed host node we don't want to call
11824 // removeChild on the inner nodes because they're removed by the top
11825 // call anyway. We also want to call componentWillUnmount on all
11826 // composites before this host node is removed from the tree. Therefore
11827 var node = root;
11828 while (true) {
11829 commitUnmount(node, renderPriorityLevel);
11830 // Visit children because they may contain more composite or host nodes.
11831 // Skip portals because commitUnmount() currently visits them recursively.
11832 if (node.child !== null && (
11833 // If we use mutation we drill down into portals using commitUnmount above.
11834 // If we don't use mutation we drill down into portals here instead.
11835 !supportsMutation || node.tag !== HostPortal)) {
11836 node.child.return = node;
11837 node = node.child;
11838 continue;
11839 }
11840 if (node === root) {
11841 return;
11842 }
11843 while (node.sibling === null) {
11844 if (node.return === null || node.return === root) {
11845 return;
11846 }
11847 node = node.return;
11848 }
11849 node.sibling.return = node.return;
11850 node = node.sibling;
11851 }
11852}
11853
11854function detachFiber(current) {
11855 // Cut off the return pointers to disconnect it from the tree. Ideally, we
11856 // should clear the child pointer of the parent alternate to let this
11857 // get GC:ed but we don't know which for sure which parent is the current
11858 // one so we'll settle for GC:ing the subtree of this child. This child
11859 // itself will be GC:ed when the parent updates the next time.
11860 current.return = null;
11861 current.child = null;
11862 current.memoizedState = null;
11863 current.updateQueue = null;
11864 current.dependencies = null;
11865 var alternate = current.alternate;
11866 if (alternate !== null) {
11867 alternate.return = null;
11868 alternate.child = null;
11869 alternate.memoizedState = null;
11870 alternate.updateQueue = null;
11871 alternate.dependencies = null;
11872 }
11873}
11874
11875function emptyPortalContainer(current) {
11876 if (!supportsPersistence) {
11877 return;
11878 }
11879
11880 var portal = current.stateNode;
11881 var containerInfo = portal.containerInfo;
11882
11883 var emptyChildSet = createContainerChildSet(containerInfo);
11884 replaceContainerChildren(containerInfo, emptyChildSet);
11885}
11886
11887function commitContainer(finishedWork) {
11888 if (!supportsPersistence) {
11889 return;
11890 }
11891
11892 switch (finishedWork.tag) {
11893 case ClassComponent:
11894 case HostComponent:
11895 case HostText:
11896 case FundamentalComponent:
11897 {
11898 return;
11899 }
11900 case HostRoot:
11901 case HostPortal:
11902 {
11903 var portalOrRoot = finishedWork.stateNode;
11904 var containerInfo = portalOrRoot.containerInfo,
11905 _pendingChildren = portalOrRoot.pendingChildren;
11906
11907 replaceContainerChildren(containerInfo, _pendingChildren);
11908 return;
11909 }
11910 default:
11911 {
11912 (function () {
11913 {
11914 {
11915 throw ReactError(Error('This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.'));
11916 }
11917 }
11918 })();
11919 }
11920 }
11921}
11922
11923function getHostParentFiber(fiber) {
11924 var parent = fiber.return;
11925 while (parent !== null) {
11926 if (isHostParent(parent)) {
11927 return parent;
11928 }
11929 parent = parent.return;
11930 }
11931 (function () {
11932 {
11933 {
11934 throw ReactError(Error('Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.'));
11935 }
11936 }
11937 })();
11938}
11939
11940function isHostParent(fiber) {
11941 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
11942}
11943
11944function getHostSibling(fiber) {
11945 // We're going to search forward into the tree until we find a sibling host
11946 // node. Unfortunately, if multiple insertions are done in a row we have to
11947 // search past them. This leads to exponential search for the next sibling.
11948 var node = fiber;
11949 siblings: while (true) {
11950 // If we didn't find anything, let's try the next sibling.
11951 while (node.sibling === null) {
11952 if (node.return === null || isHostParent(node.return)) {
11953 // If we pop out of the root or hit the parent the fiber we are the
11954 // last sibling.
11955 return null;
11956 }
11957 node = node.return;
11958 }
11959 node.sibling.return = node.return;
11960 node = node.sibling;
11961 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedSuspenseComponent) {
11962 // If it is not host node and, we might have a host node inside it.
11963 // Try to search down until we find one.
11964 if (node.effectTag & Placement) {
11965 // If we don't have a child, try the siblings instead.
11966 continue siblings;
11967 }
11968 // If we don't have a child, try the siblings instead.
11969 // We also skip portals because they are not part of this host tree.
11970 if (node.child === null || node.tag === HostPortal) {
11971 continue siblings;
11972 } else {
11973 node.child.return = node;
11974 node = node.child;
11975 }
11976 }
11977 // Check if this host node is stable or about to be placed.
11978 if (!(node.effectTag & Placement)) {
11979 // Found it!
11980 return node.stateNode;
11981 }
11982 }
11983}
11984
11985function commitPlacement(finishedWork) {
11986 if (!supportsMutation) {
11987 return;
11988 }
11989
11990 // Recursively insert all host nodes into the parent.
11991 var parentFiber = getHostParentFiber(finishedWork);
11992
11993 // Note: these two variables *must* always be updated together.
11994 var parent = void 0;
11995 var isContainer = void 0;
11996 var parentStateNode = parentFiber.stateNode;
11997 switch (parentFiber.tag) {
11998 case HostComponent:
11999 parent = parentStateNode;
12000 isContainer = false;
12001 break;
12002 case HostRoot:
12003 parent = parentStateNode.containerInfo;
12004 isContainer = true;
12005 break;
12006 case HostPortal:
12007 parent = parentStateNode.containerInfo;
12008 isContainer = true;
12009 break;
12010 case FundamentalComponent:
12011 if (enableFundamentalAPI) {
12012 parent = parentStateNode.instance;
12013 isContainer = false;
12014 }
12015 // eslint-disable-next-line-no-fallthrough
12016 default:
12017 (function () {
12018 {
12019 {
12020 throw ReactError(Error('Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.'));
12021 }
12022 }
12023 })();
12024 }
12025 if (parentFiber.effectTag & ContentReset) {
12026 // Reset the text content of the parent before doing any insertions
12027 parentFiber.effectTag &= ~ContentReset;
12028 }
12029
12030 var before = getHostSibling(finishedWork);
12031 // We only have the top Fiber that was inserted but we need to recurse down its
12032 // children to find all the terminal nodes.
12033 var node = finishedWork;
12034 while (true) {
12035 var isHost = node.tag === HostComponent || node.tag === HostText;
12036 if (isHost || node.tag === FundamentalComponent) {
12037 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
12038 if (before) {
12039 if (isContainer) {
12040 insertInContainerBefore(parent, stateNode, before);
12041 } else {
12042 insertBefore(parent, stateNode, before);
12043 }
12044 } else {
12045 if (isContainer) {
12046 appendChildToContainer(parent, stateNode);
12047 } else {
12048 appendChild(parent, stateNode);
12049 }
12050 }
12051 } else if (node.tag === HostPortal) {
12052 // If the insertion itself is a portal, then we don't want to traverse
12053 // down its children. Instead, we'll get insertions from each child in
12054 // the portal directly.
12055 } else if (node.child !== null) {
12056 node.child.return = node;
12057 node = node.child;
12058 continue;
12059 }
12060 if (node === finishedWork) {
12061 return;
12062 }
12063 while (node.sibling === null) {
12064 if (node.return === null || node.return === finishedWork) {
12065 return;
12066 }
12067 node = node.return;
12068 }
12069 node.sibling.return = node.return;
12070 node = node.sibling;
12071 }
12072}
12073
12074function unmountHostComponents(current, renderPriorityLevel) {
12075 // We only have the top Fiber that was deleted but we need to recurse down its
12076 var node = current;
12077
12078 // Each iteration, currentParent is populated with node's host parent if not
12079 // currentParentIsValid.
12080 var currentParentIsValid = false;
12081
12082 // Note: these two variables *must* always be updated together.
12083 var currentParent = void 0;
12084 var currentParentIsContainer = void 0;
12085
12086 while (true) {
12087 if (!currentParentIsValid) {
12088 var parent = node.return;
12089 findParent: while (true) {
12090 (function () {
12091 if (!(parent !== null)) {
12092 {
12093 throw ReactError(Error('Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.'));
12094 }
12095 }
12096 })();
12097 var parentStateNode = parent.stateNode;
12098 switch (parent.tag) {
12099 case HostComponent:
12100 currentParent = parentStateNode;
12101 currentParentIsContainer = false;
12102 break findParent;
12103 case HostRoot:
12104 currentParent = parentStateNode.containerInfo;
12105 currentParentIsContainer = true;
12106 break findParent;
12107 case HostPortal:
12108 currentParent = parentStateNode.containerInfo;
12109 currentParentIsContainer = true;
12110 break findParent;
12111 case FundamentalComponent:
12112 if (enableFundamentalAPI) {
12113 currentParent = parentStateNode.instance;
12114 currentParentIsContainer = false;
12115 }
12116 }
12117 parent = parent.return;
12118 }
12119 currentParentIsValid = true;
12120 }
12121
12122 if (node.tag === HostComponent || node.tag === HostText) {
12123 commitNestedUnmounts(node, renderPriorityLevel);
12124 // After all the children have unmounted, it is now safe to remove the
12125 // node from the tree.
12126 if (currentParentIsContainer) {
12127 removeChildFromContainer(currentParent, node.stateNode);
12128 } else {
12129 removeChild(currentParent, node.stateNode);
12130 }
12131 // Don't visit children because we already visited them.
12132 } else if (node.tag === FundamentalComponent) {
12133 var fundamentalNode = node.stateNode.instance;
12134 commitNestedUnmounts(node, renderPriorityLevel);
12135 // After all the children have unmounted, it is now safe to remove the
12136 // node from the tree.
12137 if (currentParentIsContainer) {
12138 removeChildFromContainer(currentParent, fundamentalNode);
12139 } else {
12140 removeChild(currentParent, fundamentalNode);
12141 }
12142 } else if (enableSuspenseServerRenderer && node.tag === DehydratedSuspenseComponent) {
12143 // Delete the dehydrated suspense boundary and all of its content.
12144 if (currentParentIsContainer) {
12145 clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
12146 } else {
12147 clearSuspenseBoundary(currentParent, node.stateNode);
12148 }
12149 } else if (node.tag === HostPortal) {
12150 if (node.child !== null) {
12151 // When we go into a portal, it becomes the parent to remove from.
12152 // We will reassign it back when we pop the portal on the way up.
12153 currentParent = node.stateNode.containerInfo;
12154 currentParentIsContainer = true;
12155 // Visit children because portals might contain host components.
12156 node.child.return = node;
12157 node = node.child;
12158 continue;
12159 }
12160 } else {
12161 commitUnmount(node, renderPriorityLevel);
12162 // Visit children because we may find more host components below.
12163 if (node.child !== null) {
12164 node.child.return = node;
12165 node = node.child;
12166 continue;
12167 }
12168 }
12169 if (node === current) {
12170 return;
12171 }
12172 while (node.sibling === null) {
12173 if (node.return === null || node.return === current) {
12174 return;
12175 }
12176 node = node.return;
12177 if (node.tag === HostPortal) {
12178 // When we go out of the portal, we need to restore the parent.
12179 // Since we don't keep a stack of them, we will search for it.
12180 currentParentIsValid = false;
12181 }
12182 }
12183 node.sibling.return = node.return;
12184 node = node.sibling;
12185 }
12186}
12187
12188function commitDeletion(current, renderPriorityLevel) {
12189 if (supportsMutation) {
12190 // Recursively delete all host nodes from the parent.
12191 // Detach refs and call componentWillUnmount() on the whole subtree.
12192 unmountHostComponents(current, renderPriorityLevel);
12193 } else {
12194 // Detach refs and call componentWillUnmount() on the whole subtree.
12195 commitNestedUnmounts(current, renderPriorityLevel);
12196 }
12197 detachFiber(current);
12198}
12199
12200function commitWork(current, finishedWork) {
12201 if (!supportsMutation) {
12202 switch (finishedWork.tag) {
12203 case FunctionComponent:
12204 case ForwardRef:
12205 case MemoComponent:
12206 case SimpleMemoComponent:
12207 {
12208 // Note: We currently never use MountMutation, but useLayout uses
12209 // UnmountMutation.
12210 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
12211 return;
12212 }
12213 case Profiler:
12214 {
12215 return;
12216 }
12217 case SuspenseComponent:
12218 {
12219 commitSuspenseComponent(finishedWork);
12220 attachSuspenseRetryListeners(finishedWork);
12221 return;
12222 }
12223 case SuspenseListComponent:
12224 {
12225 attachSuspenseRetryListeners(finishedWork);
12226 return;
12227 }
12228 }
12229
12230 commitContainer(finishedWork);
12231 return;
12232 }
12233
12234 switch (finishedWork.tag) {
12235 case FunctionComponent:
12236 case ForwardRef:
12237 case MemoComponent:
12238 case SimpleMemoComponent:
12239 {
12240 // Note: We currently never use MountMutation, but useLayout uses
12241 // UnmountMutation.
12242 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
12243 return;
12244 }
12245 case ClassComponent:
12246 {
12247 return;
12248 }
12249 case HostComponent:
12250 {
12251 var instance = finishedWork.stateNode;
12252 if (instance != null) {
12253 // Commit the work prepared earlier.
12254 var newProps = finishedWork.memoizedProps;
12255 // For hydration we reuse the update path but we treat the oldProps
12256 // as the newProps. The updatePayload will contain the real change in
12257 // this case.
12258 var oldProps = current !== null ? current.memoizedProps : newProps;
12259 var type = finishedWork.type;
12260 // TODO: Type the updateQueue to be specific to host components.
12261 var updatePayload = finishedWork.updateQueue;
12262 finishedWork.updateQueue = null;
12263 if (updatePayload !== null) {
12264 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
12265 }
12266 }
12267 return;
12268 }
12269 case HostText:
12270 {
12271 (function () {
12272 if (!(finishedWork.stateNode !== null)) {
12273 {
12274 throw ReactError(Error('This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue.'));
12275 }
12276 }
12277 })();
12278 var textInstance = finishedWork.stateNode;
12279 var newText = finishedWork.memoizedProps;
12280 // For hydration we reuse the update path but we treat the oldProps
12281 // as the newProps. The updatePayload will contain the real change in
12282 // this case.
12283 var oldText = current !== null ? current.memoizedProps : newText;
12284 return;
12285 }
12286 case HostRoot:
12287 {
12288 return;
12289 }
12290 case Profiler:
12291 {
12292 return;
12293 }
12294 case SuspenseComponent:
12295 {
12296 commitSuspenseComponent(finishedWork);
12297 attachSuspenseRetryListeners(finishedWork);
12298 return;
12299 }
12300 case SuspenseListComponent:
12301 {
12302 attachSuspenseRetryListeners(finishedWork);
12303 return;
12304 }
12305 case IncompleteClassComponent:
12306 {
12307 return;
12308 }
12309 case FundamentalComponent:
12310 {
12311 if (enableFundamentalAPI) {
12312 var fundamentalInstance = finishedWork.stateNode;
12313 updateFundamentalComponent(fundamentalInstance);
12314 }
12315 return;
12316 }
12317 default:
12318 {
12319 (function () {
12320 {
12321 {
12322 throw ReactError(Error('This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.'));
12323 }
12324 }
12325 })();
12326 }
12327 }
12328}
12329
12330function commitSuspenseComponent(finishedWork) {
12331 var newState = finishedWork.memoizedState;
12332
12333 var newDidTimeout = void 0;
12334 var primaryChildParent = finishedWork;
12335 if (newState === null) {
12336 newDidTimeout = false;
12337 } else {
12338 newDidTimeout = true;
12339 primaryChildParent = finishedWork.child;
12340 markCommitTimeOfFallback();
12341 }
12342
12343 if (supportsMutation && primaryChildParent !== null) {
12344 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
12345 }
12346
12347 if (enableSuspenseCallback && newState !== null) {
12348 var suspenseCallback = finishedWork.memoizedProps.suspenseCallback;
12349 if (typeof suspenseCallback === 'function') {
12350 var thenables = finishedWork.updateQueue;
12351 if (thenables !== null) {
12352 suspenseCallback(new Set(thenables));
12353 }
12354 } else {
12355 if (suspenseCallback !== undefined) {
12356 warning$1(false, 'Unexpected type for suspenseCallback.');
12357 }
12358 }
12359 }
12360}
12361
12362function attachSuspenseRetryListeners(finishedWork) {
12363 // If this boundary just timed out, then it will have a set of thenables.
12364 // For each thenable, attach a listener so that when it resolves, React
12365 var thenables = finishedWork.updateQueue;
12366 if (thenables !== null) {
12367 finishedWork.updateQueue = null;
12368 var retryCache = finishedWork.stateNode;
12369 if (retryCache === null) {
12370 retryCache = finishedWork.stateNode = new PossiblyWeakSet$1();
12371 }
12372 thenables.forEach(function (thenable) {
12373 // Memoize using the boundary fiber to prevent redundant listeners.
12374 var retry = resolveRetryThenable.bind(null, finishedWork, thenable);
12375 if (!retryCache.has(thenable)) {
12376 if (enableSchedulerTracing) {
12377 retry = unstable_wrap(retry);
12378 }
12379 retryCache.add(thenable);
12380 thenable.then(retry, retry);
12381 }
12382 });
12383 }
12384}
12385
12386function commitResetTextContent(current) {
12387 if (!supportsMutation) {
12388 return;
12389 }
12390 resetTextContent(current.stateNode);
12391}
12392
12393var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
12394var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
12395
12396function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
12397 var update = createUpdate(expirationTime, null);
12398 // Unmount the root by rendering null.
12399 update.tag = CaptureUpdate;
12400 // Caution: React DevTools currently depends on this property
12401 // being called "element".
12402 update.payload = { element: null };
12403 var error = errorInfo.value;
12404 update.callback = function () {
12405 onUncaughtError(error);
12406 logError(fiber, errorInfo);
12407 };
12408 return update;
12409}
12410
12411function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
12412 var update = createUpdate(expirationTime, null);
12413 update.tag = CaptureUpdate;
12414 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
12415 if (typeof getDerivedStateFromError === 'function') {
12416 var error = errorInfo.value;
12417 update.payload = function () {
12418 logError(fiber, errorInfo);
12419 return getDerivedStateFromError(error);
12420 };
12421 }
12422
12423 var inst = fiber.stateNode;
12424 if (inst !== null && typeof inst.componentDidCatch === 'function') {
12425 update.callback = function callback() {
12426 {
12427 markFailedErrorBoundaryForHotReloading(fiber);
12428 }
12429 if (typeof getDerivedStateFromError !== 'function') {
12430 // To preserve the preexisting retry behavior of error boundaries,
12431 // we keep track of which ones already failed during this batch.
12432 // This gets reset before we yield back to the browser.
12433 // TODO: Warn in strict mode if getDerivedStateFromError is
12434 // not defined.
12435 markLegacyErrorBoundaryAsFailed(this);
12436
12437 // Only log here if componentDidCatch is the only error boundary method defined
12438 logError(fiber, errorInfo);
12439 }
12440 var error = errorInfo.value;
12441 var stack = errorInfo.stack;
12442 this.componentDidCatch(error, {
12443 componentStack: stack !== null ? stack : ''
12444 });
12445 {
12446 if (typeof getDerivedStateFromError !== 'function') {
12447 // If componentDidCatch is the only error boundary method defined,
12448 // then it needs to call setState to recover from errors.
12449 // If no state update is scheduled then the boundary will swallow the error.
12450 !(fiber.expirationTime === Sync) ? warningWithoutStack$1(false, '%s: Error boundaries should implement getDerivedStateFromError(). ' + 'In that method, return a state update to display an error message or fallback UI.', getComponentName(fiber.type) || 'Unknown') : void 0;
12451 }
12452 }
12453 };
12454 } else {
12455 update.callback = function () {
12456 markFailedErrorBoundaryForHotReloading(fiber);
12457 };
12458 }
12459 return update;
12460}
12461
12462function attachPingListener(root, renderExpirationTime, thenable) {
12463 // Attach a listener to the promise to "ping" the root and retry. But
12464 // only if one does not already exist for the current render expiration
12465 // time (which acts like a "thread ID" here).
12466 var pingCache = root.pingCache;
12467 var threadIDs = void 0;
12468 if (pingCache === null) {
12469 pingCache = root.pingCache = new PossiblyWeakMap();
12470 threadIDs = new Set();
12471 pingCache.set(thenable, threadIDs);
12472 } else {
12473 threadIDs = pingCache.get(thenable);
12474 if (threadIDs === undefined) {
12475 threadIDs = new Set();
12476 pingCache.set(thenable, threadIDs);
12477 }
12478 }
12479 if (!threadIDs.has(renderExpirationTime)) {
12480 // Memoize using the thread ID to prevent redundant listeners.
12481 threadIDs.add(renderExpirationTime);
12482 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
12483 if (enableSchedulerTracing) {
12484 ping = unstable_wrap(ping);
12485 }
12486 thenable.then(ping, ping);
12487 }
12488}
12489
12490function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
12491 // The source fiber did not complete.
12492 sourceFiber.effectTag |= Incomplete;
12493 // Its effect list is no longer valid.
12494 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
12495
12496 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
12497 // This is a thenable.
12498 var thenable = value;
12499
12500 checkForWrongSuspensePriorityInDEV(sourceFiber);
12501
12502 var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext);
12503
12504 // Schedule the nearest Suspense to re-render the timed out view.
12505 var _workInProgress = returnFiber;
12506 do {
12507 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) {
12508 // Found the nearest boundary.
12509
12510 // Stash the promise on the boundary fiber. If the boundary times out, we'll
12511 var thenables = _workInProgress.updateQueue;
12512 if (thenables === null) {
12513 var updateQueue = new Set();
12514 updateQueue.add(thenable);
12515 _workInProgress.updateQueue = updateQueue;
12516 } else {
12517 thenables.add(thenable);
12518 }
12519
12520 // If the boundary is outside of batched mode, we should *not*
12521 // suspend the commit. Pretend as if the suspended component rendered
12522 // null and keep rendering. In the commit phase, we'll schedule a
12523 // subsequent synchronous update to re-render the Suspense.
12524 //
12525 // Note: It doesn't matter whether the component that suspended was
12526 // inside a batched mode tree. If the Suspense is outside of it, we
12527 // should *not* suspend the commit.
12528 if ((_workInProgress.mode & BatchedMode) === NoMode) {
12529 _workInProgress.effectTag |= DidCapture;
12530
12531 // We're going to commit this fiber even though it didn't complete.
12532 // But we shouldn't call any lifecycle methods or callbacks. Remove
12533 // all lifecycle effect tags.
12534 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
12535
12536 if (sourceFiber.tag === ClassComponent) {
12537 var currentSourceFiber = sourceFiber.alternate;
12538 if (currentSourceFiber === null) {
12539 // This is a new mount. Change the tag so it's not mistaken for a
12540 // completed class component. For example, we should not call
12541 // componentWillUnmount if it is deleted.
12542 sourceFiber.tag = IncompleteClassComponent;
12543 } else {
12544 // When we try rendering again, we should not reuse the current fiber,
12545 // since it's known to be in an inconsistent state. Use a force update to
12546 // prevent a bail out.
12547 var update = createUpdate(Sync, null);
12548 update.tag = ForceUpdate;
12549 enqueueUpdate(sourceFiber, update);
12550 }
12551 }
12552
12553 // The source fiber did not complete. Mark it with Sync priority to
12554 // indicate that it still has pending work.
12555 sourceFiber.expirationTime = Sync;
12556
12557 // Exit without suspending.
12558 return;
12559 }
12560
12561 // Confirmed that the boundary is in a concurrent mode tree. Continue
12562 // with the normal suspend path.
12563 //
12564 // After this we'll use a set of heuristics to determine whether this
12565 // render pass will run to completion or restart or "suspend" the commit.
12566 // The actual logic for this is spread out in different places.
12567 //
12568 // This first principle is that if we're going to suspend when we complete
12569 // a root, then we should also restart if we get an update or ping that
12570 // might unsuspend it, and vice versa. The only reason to suspend is
12571 // because you think you might want to restart before committing. However,
12572 // it doesn't make sense to restart only while in the period we're suspended.
12573 //
12574 // Restarting too aggressively is also not good because it starves out any
12575 // intermediate loading state. So we use heuristics to determine when.
12576
12577 // Suspense Heuristics
12578 //
12579 // If nothing threw a Promise or all the same fallbacks are already showing,
12580 // then don't suspend/restart.
12581 //
12582 // If this is an initial render of a new tree of Suspense boundaries and
12583 // those trigger a fallback, then don't suspend/restart. We want to ensure
12584 // that we can show the initial loading state as quickly as possible.
12585 //
12586 // If we hit a "Delayed" case, such as when we'd switch from content back into
12587 // a fallback, then we should always suspend/restart. SuspenseConfig applies to
12588 // this case. If none is defined, JND is used instead.
12589 //
12590 // If we're already showing a fallback and it gets "retried", allowing us to show
12591 // another level, but there's still an inner boundary that would show a fallback,
12592 // then we suspend/restart for 500ms since the last time we showed a fallback
12593 // anywhere in the tree. This effectively throttles progressive loading into a
12594 // consistent train of commits. This also gives us an opportunity to restart to
12595 // get to the completed state slightly earlier.
12596 //
12597 // If there's ambiguity due to batching it's resolved in preference of:
12598 // 1) "delayed", 2) "initial render", 3) "retry".
12599 //
12600 // We want to ensure that a "busy" state doesn't get force committed. We want to
12601 // ensure that new initial loading states can commit as soon as possible.
12602
12603 attachPingListener(root, renderExpirationTime, thenable);
12604
12605 _workInProgress.effectTag |= ShouldCapture;
12606 _workInProgress.expirationTime = renderExpirationTime;
12607
12608 return;
12609 } else if (enableSuspenseServerRenderer && _workInProgress.tag === DehydratedSuspenseComponent) {
12610 attachPingListener(root, renderExpirationTime, thenable);
12611
12612 // Since we already have a current fiber, we can eagerly add a retry listener.
12613 var retryCache = _workInProgress.memoizedState;
12614 if (retryCache === null) {
12615 retryCache = _workInProgress.memoizedState = new PossiblyWeakSet();
12616 var current = _workInProgress.alternate;
12617 (function () {
12618 if (!current) {
12619 {
12620 throw ReactError(Error('A dehydrated suspense boundary must commit before trying to render. This is probably a bug in React.'));
12621 }
12622 }
12623 })();
12624 current.memoizedState = retryCache;
12625 }
12626 // Memoize using the boundary fiber to prevent redundant listeners.
12627 if (!retryCache.has(thenable)) {
12628 retryCache.add(thenable);
12629 var retry = resolveRetryThenable.bind(null, _workInProgress, thenable);
12630 if (enableSchedulerTracing) {
12631 retry = unstable_wrap(retry);
12632 }
12633 thenable.then(retry, retry);
12634 }
12635 _workInProgress.effectTag |= ShouldCapture;
12636 _workInProgress.expirationTime = renderExpirationTime;
12637 return;
12638 }
12639 // This boundary already captured during this render. Continue to the next
12640 // boundary.
12641 _workInProgress = _workInProgress.return;
12642 } while (_workInProgress !== null);
12643 // No boundary was found. Fallthrough to error mode.
12644 // TODO: Use invariant so the message is stripped in prod?
12645 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));
12646 }
12647
12648 // We didn't find a boundary that could handle this type of exception. Start
12649 // over and traverse parent path again, this time treating the exception
12650 // as an error.
12651 renderDidError();
12652 value = createCapturedValue(value, sourceFiber);
12653 var workInProgress = returnFiber;
12654 do {
12655 switch (workInProgress.tag) {
12656 case HostRoot:
12657 {
12658 var _errorInfo = value;
12659 workInProgress.effectTag |= ShouldCapture;
12660 workInProgress.expirationTime = renderExpirationTime;
12661 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
12662 enqueueCapturedUpdate(workInProgress, _update);
12663 return;
12664 }
12665 case ClassComponent:
12666 // Capture and retry
12667 var errorInfo = value;
12668 var ctor = workInProgress.type;
12669 var instance = workInProgress.stateNode;
12670 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
12671 workInProgress.effectTag |= ShouldCapture;
12672 workInProgress.expirationTime = renderExpirationTime;
12673 // Schedule the error boundary to re-render using updated state
12674 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
12675 enqueueCapturedUpdate(workInProgress, _update2);
12676 return;
12677 }
12678 break;
12679 default:
12680 break;
12681 }
12682 workInProgress = workInProgress.return;
12683 } while (workInProgress !== null);
12684}
12685
12686// The scheduler is imported here *only* to detect whether it's been mocked
12687// DEV stuff
12688var ceil = Math.ceil;
12689
12690var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
12691var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
12692var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;
12693
12694
12695var NoContext = /* */0;
12696var BatchedContext = /* */1;
12697var DiscreteEventContext = /* */4;
12698var LegacyUnbatchedContext = /* */8;
12699var RenderContext = /* */16;
12700var CommitContext = /* */32;
12701
12702var RootIncomplete = 0;
12703var RootErrored = 1;
12704var RootSuspended = 2;
12705var RootSuspendedWithDelay = 3;
12706var RootCompleted = 4;
12707
12708// Describes where we are in the React execution stack
12709var executionContext = NoContext;
12710// The root we're working on
12711var workInProgressRoot = null;
12712// The fiber we're working on
12713var workInProgress = null;
12714// The expiration time we're rendering
12715var renderExpirationTime = NoWork;
12716// Whether to root completed, errored, suspended, etc.
12717var workInProgressRootExitStatus = RootIncomplete;
12718// Most recent event time among processed updates during this render.
12719// This is conceptually a time stamp but expressed in terms of an ExpirationTime
12720// because we deal mostly with expiration times in the hot path, so this avoids
12721// the conversion happening in the hot path.
12722var workInProgressRootLatestProcessedExpirationTime = Sync;
12723var workInProgressRootLatestSuspenseTimeout = Sync;
12724var workInProgressRootCanSuspendUsingConfig = null;
12725// If we're pinged while rendering we don't always restart immediately.
12726// This flag determines if it might be worthwhile to restart if an opportunity
12727// happens latere.
12728var workInProgressRootHasPendingPing = false;
12729// The most recent time we committed a fallback. This lets us ensure a train
12730// model where we don't commit new loading states in too quick succession.
12731var globalMostRecentFallbackTime = 0;
12732var FALLBACK_THROTTLE_MS = 500;
12733
12734var nextEffect = null;
12735var hasUncaughtError = false;
12736var firstUncaughtError = null;
12737var legacyErrorBoundariesThatAlreadyFailed = null;
12738
12739var rootDoesHavePassiveEffects = false;
12740var rootWithPendingPassiveEffects = null;
12741var pendingPassiveEffectsRenderPriority = NoPriority;
12742var pendingPassiveEffectsExpirationTime = NoWork;
12743
12744var rootsWithPendingDiscreteUpdates = null;
12745
12746// Use these to prevent an infinite loop of nested updates
12747var NESTED_UPDATE_LIMIT = 50;
12748var nestedUpdateCount = 0;
12749var rootWithNestedUpdates = null;
12750
12751var NESTED_PASSIVE_UPDATE_LIMIT = 50;
12752var nestedPassiveUpdateCount = 0;
12753
12754var interruptedBy = null;
12755
12756// Marks the need to reschedule pending interactions at these expiration times
12757// during the commit phase. This enables them to be traced across components
12758// that spawn new work during render. E.g. hidden boundaries, suspended SSR
12759// hydration or SuspenseList.
12760var spawnedWorkDuringRender = null;
12761
12762// Expiration times are computed by adding to the current time (the start
12763// time). However, if two updates are scheduled within the same event, we
12764// should treat their start times as simultaneous, even if the actual clock
12765// time has advanced between the first and second call.
12766
12767// In other words, because expiration times determine how updates are batched,
12768// we want all updates of like priority that occur within the same event to
12769// receive the same expiration time. Otherwise we get tearing.
12770var currentEventTime = NoWork;
12771
12772function requestCurrentTime() {
12773 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
12774 // We're inside React, so it's fine to read the actual time.
12775 return msToExpirationTime(now());
12776 }
12777 // We're not inside React, so we may be in the middle of a browser event.
12778 if (currentEventTime !== NoWork) {
12779 // Use the same start time for all updates until we enter React again.
12780 return currentEventTime;
12781 }
12782 // This is the first update since React yielded. Compute a new start time.
12783 currentEventTime = msToExpirationTime(now());
12784 return currentEventTime;
12785}
12786
12787function computeExpirationForFiber(currentTime, fiber, suspenseConfig) {
12788 var mode = fiber.mode;
12789 if ((mode & BatchedMode) === NoMode) {
12790 return Sync;
12791 }
12792
12793 var priorityLevel = getCurrentPriorityLevel();
12794 if ((mode & ConcurrentMode) === NoMode) {
12795 return priorityLevel === ImmediatePriority ? Sync : Batched;
12796 }
12797
12798 if ((executionContext & RenderContext) !== NoContext) {
12799 // Use whatever time we're already rendering
12800 return renderExpirationTime;
12801 }
12802
12803 var expirationTime = void 0;
12804 if (suspenseConfig !== null) {
12805 // Compute an expiration time based on the Suspense timeout.
12806 expirationTime = computeSuspenseExpiration(currentTime, suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
12807 } else {
12808 // Compute an expiration time based on the Scheduler priority.
12809 switch (priorityLevel) {
12810 case ImmediatePriority:
12811 expirationTime = Sync;
12812 break;
12813 case UserBlockingPriority:
12814 // TODO: Rename this to computeUserBlockingExpiration
12815 expirationTime = computeInteractiveExpiration(currentTime);
12816 break;
12817 case NormalPriority:
12818 case LowPriority:
12819 // TODO: Handle LowPriority
12820 // TODO: Rename this to... something better.
12821 expirationTime = computeAsyncExpiration(currentTime);
12822 break;
12823 case IdlePriority:
12824 expirationTime = Never;
12825 break;
12826 default:
12827 (function () {
12828 {
12829 {
12830 throw ReactError(Error('Expected a valid priority level'));
12831 }
12832 }
12833 })();
12834 }
12835 }
12836
12837 // If we're in the middle of rendering a tree, do not update at the same
12838 // expiration time that is already rendering.
12839 // TODO: We shouldn't have to do this if the update is on a different root.
12840 // Refactor computeExpirationForFiber + scheduleUpdate so we have access to
12841 // the root when we check for this condition.
12842 if (workInProgressRoot !== null && expirationTime === renderExpirationTime) {
12843 // This is a trick to move this update into a separate batch
12844 expirationTime -= 1;
12845 }
12846
12847 return expirationTime;
12848}
12849
12850
12851
12852function scheduleUpdateOnFiber(fiber, expirationTime) {
12853 checkForNestedUpdates();
12854 warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber);
12855
12856 var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);
12857 if (root === null) {
12858 warnAboutUpdateOnUnmountedFiberInDEV(fiber);
12859 return;
12860 }
12861
12862 root.pingTime = NoWork;
12863
12864 checkForInterruption(fiber, expirationTime);
12865 recordScheduleUpdate();
12866
12867 // TODO: computeExpirationForFiber also reads the priority. Pass the
12868 // priority as an argument to that function and this one.
12869 var priorityLevel = getCurrentPriorityLevel();
12870
12871 if (expirationTime === Sync) {
12872 if (
12873 // Check if we're inside unbatchedUpdates
12874 (executionContext & LegacyUnbatchedContext) !== NoContext &&
12875 // Check if we're not already rendering
12876 (executionContext & (RenderContext | CommitContext)) === NoContext) {
12877 // Register pending interactions on the root to avoid losing traced interaction data.
12878 schedulePendingInteractions(root, expirationTime);
12879
12880 // This is a legacy edge case. The initial mount of a ReactDOM.render-ed
12881 // root inside of batchedUpdates should be synchronous, but layout updates
12882 // should be deferred until the end of the batch.
12883 var callback = renderRoot(root, Sync, true);
12884 while (callback !== null) {
12885 callback = callback(true);
12886 }
12887 } else {
12888 scheduleCallbackForRoot(root, ImmediatePriority, Sync);
12889 if (executionContext === NoContext) {
12890 // Flush the synchronous work now, wnless we're already working or inside
12891 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
12892 // scheduleCallbackForFiber to preserve the ability to schedule a callback
12893 // without immediately flushing it. We only do this for user-initiated
12894 // updates, to preserve historical behavior of sync mode.
12895 flushSyncCallbackQueue();
12896 }
12897 }
12898 } else {
12899 scheduleCallbackForRoot(root, priorityLevel, expirationTime);
12900 }
12901
12902 if ((executionContext & DiscreteEventContext) !== NoContext && (
12903 // Only updates at user-blocking priority or greater are considered
12904 // discrete, even inside a discrete event.
12905 priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority)) {
12906 // This is the result of a discrete event. Track the lowest priority
12907 // discrete update per root so we can flush them early, if needed.
12908 if (rootsWithPendingDiscreteUpdates === null) {
12909 rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);
12910 } else {
12911 var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);
12912 if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {
12913 rootsWithPendingDiscreteUpdates.set(root, expirationTime);
12914 }
12915 }
12916 }
12917}
12918var scheduleWork = scheduleUpdateOnFiber;
12919
12920// This is split into a separate function so we can mark a fiber with pending
12921// work without treating it as a typical update that originates from an event;
12922// e.g. retrying a Suspense boundary isn't an update, but it does schedule work
12923// on a fiber.
12924function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
12925 // Update the source fiber's expiration time
12926 if (fiber.expirationTime < expirationTime) {
12927 fiber.expirationTime = expirationTime;
12928 }
12929 var alternate = fiber.alternate;
12930 if (alternate !== null && alternate.expirationTime < expirationTime) {
12931 alternate.expirationTime = expirationTime;
12932 }
12933 // Walk the parent path to the root and update the child expiration time.
12934 var node = fiber.return;
12935 var root = null;
12936 if (node === null && fiber.tag === HostRoot) {
12937 root = fiber.stateNode;
12938 } else {
12939 while (node !== null) {
12940 alternate = node.alternate;
12941 if (node.childExpirationTime < expirationTime) {
12942 node.childExpirationTime = expirationTime;
12943 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
12944 alternate.childExpirationTime = expirationTime;
12945 }
12946 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
12947 alternate.childExpirationTime = expirationTime;
12948 }
12949 if (node.return === null && node.tag === HostRoot) {
12950 root = node.stateNode;
12951 break;
12952 }
12953 node = node.return;
12954 }
12955 }
12956
12957 if (root !== null) {
12958 // Update the first and last pending expiration times in this root
12959 var firstPendingTime = root.firstPendingTime;
12960 if (expirationTime > firstPendingTime) {
12961 root.firstPendingTime = expirationTime;
12962 }
12963 var lastPendingTime = root.lastPendingTime;
12964 if (lastPendingTime === NoWork || expirationTime < lastPendingTime) {
12965 root.lastPendingTime = expirationTime;
12966 }
12967 }
12968
12969 return root;
12970}
12971
12972// Use this function, along with runRootCallback, to ensure that only a single
12973// callback per root is scheduled. It's still possible to call renderRoot
12974// directly, but scheduling via this function helps avoid excessive callbacks.
12975// It works by storing the callback node and expiration time on the root. When a
12976// new callback comes in, it compares the expiration time to determine if it
12977// should cancel the previous one. It also relies on commitRoot scheduling a
12978// callback to render the next level, because that means we don't need a
12979// separate callback per expiration time.
12980function scheduleCallbackForRoot(root, priorityLevel, expirationTime) {
12981 var existingCallbackExpirationTime = root.callbackExpirationTime;
12982 if (existingCallbackExpirationTime < expirationTime) {
12983 // New callback has higher priority than the existing one.
12984 var existingCallbackNode = root.callbackNode;
12985 if (existingCallbackNode !== null) {
12986 cancelCallback(existingCallbackNode);
12987 }
12988 root.callbackExpirationTime = expirationTime;
12989
12990 if (expirationTime === Sync) {
12991 // Sync React callbacks are scheduled on a special internal queue
12992 root.callbackNode = scheduleSyncCallback(runRootCallback.bind(null, root, renderRoot.bind(null, root, expirationTime)));
12993 } else {
12994 var options = null;
12995 if (!disableSchedulerTimeoutBasedOnReactExpirationTime && expirationTime !== Never) {
12996 var timeout = expirationTimeToMs(expirationTime) - now();
12997 options = { timeout: timeout };
12998 }
12999
13000 root.callbackNode = scheduleCallback(priorityLevel, runRootCallback.bind(null, root, renderRoot.bind(null, root, expirationTime)), options);
13001 if (enableUserTimingAPI && expirationTime !== Sync && (executionContext & (RenderContext | CommitContext)) === NoContext) {
13002 // Scheduled an async callback, and we're not already working. Add an
13003 // entry to the flamegraph that shows we're waiting for a callback
13004 // to fire.
13005 startRequestCallbackTimer();
13006 }
13007 }
13008 }
13009
13010 // Associate the current interactions with this new root+priority.
13011 schedulePendingInteractions(root, expirationTime);
13012}
13013
13014function runRootCallback(root, callback, isSync) {
13015 var prevCallbackNode = root.callbackNode;
13016 var continuation = null;
13017 try {
13018 continuation = callback(isSync);
13019 if (continuation !== null) {
13020 return runRootCallback.bind(null, root, continuation);
13021 } else {
13022 return null;
13023 }
13024 } finally {
13025 // If the callback exits without returning a continuation, remove the
13026 // corresponding callback node from the root. Unless the callback node
13027 // has changed, which implies that it was already cancelled by a high
13028 // priority update.
13029 if (continuation === null && prevCallbackNode === root.callbackNode) {
13030 root.callbackNode = null;
13031 root.callbackExpirationTime = NoWork;
13032 }
13033 }
13034}
13035
13036
13037
13038
13039
13040function resolveLocksOnRoot(root, expirationTime) {
13041 var firstBatch = root.firstBatch;
13042 if (firstBatch !== null && firstBatch._defer && firstBatch._expirationTime >= expirationTime) {
13043 scheduleCallback(NormalPriority, function () {
13044 firstBatch._onComplete();
13045 return null;
13046 });
13047 return true;
13048 } else {
13049 return false;
13050 }
13051}
13052
13053
13054
13055
13056
13057
13058
13059
13060
13061
13062
13063
13064
13065function flushSync(fn, a) {
13066 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
13067 (function () {
13068 {
13069 {
13070 throw ReactError(Error('flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.'));
13071 }
13072 }
13073 })();
13074 }
13075 var prevExecutionContext = executionContext;
13076 executionContext |= BatchedContext;
13077 try {
13078 return runWithPriority(ImmediatePriority, fn.bind(null, a));
13079 } finally {
13080 executionContext = prevExecutionContext;
13081 // Flush the immediate callbacks that were scheduled during this batch.
13082 // Note that this will happen even if batchedUpdates is higher up
13083 // the stack.
13084 flushSyncCallbackQueue();
13085 }
13086}
13087
13088
13089
13090function prepareFreshStack(root, expirationTime) {
13091 root.finishedWork = null;
13092 root.finishedExpirationTime = NoWork;
13093
13094 var timeoutHandle = root.timeoutHandle;
13095 if (timeoutHandle !== noTimeout) {
13096 // The root previous suspended and scheduled a timeout to commit a fallback
13097 // state. Now that we have additional work, cancel the timeout.
13098 root.timeoutHandle = noTimeout;
13099 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
13100 cancelTimeout(timeoutHandle);
13101 }
13102
13103 if (workInProgress !== null) {
13104 var interruptedWork = workInProgress.return;
13105 while (interruptedWork !== null) {
13106 unwindInterruptedWork(interruptedWork);
13107 interruptedWork = interruptedWork.return;
13108 }
13109 }
13110 workInProgressRoot = root;
13111 workInProgress = createWorkInProgress(root.current, null, expirationTime);
13112 renderExpirationTime = expirationTime;
13113 workInProgressRootExitStatus = RootIncomplete;
13114 workInProgressRootLatestProcessedExpirationTime = Sync;
13115 workInProgressRootLatestSuspenseTimeout = Sync;
13116 workInProgressRootCanSuspendUsingConfig = null;
13117 workInProgressRootHasPendingPing = false;
13118
13119 if (enableSchedulerTracing) {
13120 spawnedWorkDuringRender = null;
13121 }
13122
13123 {
13124 ReactStrictModeWarnings.discardPendingWarnings();
13125 componentsThatTriggeredHighPriSuspend = null;
13126 }
13127}
13128
13129function renderRoot(root, expirationTime, isSync) {
13130 (function () {
13131 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
13132 {
13133 throw ReactError(Error('Should not already be working.'));
13134 }
13135 }
13136 })();
13137
13138 if (enableUserTimingAPI && expirationTime !== Sync) {
13139 var didExpire = isSync;
13140 stopRequestCallbackTimer(didExpire);
13141 }
13142
13143 if (root.firstPendingTime < expirationTime) {
13144 // If there's no work left at this expiration time, exit immediately. This
13145 // happens when multiple callbacks are scheduled for a single root, but an
13146 // earlier callback flushes the work of a later one.
13147 return null;
13148 }
13149
13150 if (isSync && root.finishedExpirationTime === expirationTime) {
13151 // There's already a pending commit at this expiration time.
13152 // TODO: This is poorly factored. This case only exists for the
13153 // batch.commit() API.
13154 return commitRoot.bind(null, root);
13155 }
13156
13157 flushPassiveEffects();
13158
13159 // If the root or expiration time have changed, throw out the existing stack
13160 // and prepare a fresh one. Otherwise we'll continue where we left off.
13161 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) {
13162 prepareFreshStack(root, expirationTime);
13163 startWorkOnPendingInteractions(root, expirationTime);
13164 } else if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
13165 // We could've received an update at a lower priority while we yielded.
13166 // We're suspended in a delayed state. Once we complete this render we're
13167 // just going to try to recover at the last pending time anyway so we might
13168 // as well start doing that eagerly.
13169 // Ideally we should be able to do this even for retries but we don't yet
13170 // know if we're going to process an update which wants to commit earlier,
13171 // and this path happens very early so it would happen too often. Instead,
13172 // for that case, we'll wait until we complete.
13173 if (workInProgressRootHasPendingPing) {
13174 // We have a ping at this expiration. Let's restart to see if we get unblocked.
13175 prepareFreshStack(root, expirationTime);
13176 } else {
13177 var lastPendingTime = root.lastPendingTime;
13178 if (lastPendingTime < expirationTime) {
13179 // There's lower priority work. It might be unsuspended. Try rendering
13180 // at that level immediately, while preserving the position in the queue.
13181 return renderRoot.bind(null, root, lastPendingTime);
13182 }
13183 }
13184 }
13185
13186 // If we have a work-in-progress fiber, it means there's still work to do
13187 // in this root.
13188 if (workInProgress !== null) {
13189 var prevExecutionContext = executionContext;
13190 executionContext |= RenderContext;
13191 var prevDispatcher = ReactCurrentDispatcher.current;
13192 if (prevDispatcher === null) {
13193 // The React isomorphic package does not include a default dispatcher.
13194 // Instead the first renderer will lazily attach one, in order to give
13195 // nicer error messages.
13196 prevDispatcher = ContextOnlyDispatcher;
13197 }
13198 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
13199 var prevInteractions = null;
13200 if (enableSchedulerTracing) {
13201 prevInteractions = __interactionsRef.current;
13202 __interactionsRef.current = root.memoizedInteractions;
13203 }
13204
13205 startWorkLoopTimer(workInProgress);
13206
13207 // TODO: Fork renderRoot into renderRootSync and renderRootAsync
13208 if (isSync) {
13209 if (expirationTime !== Sync) {
13210 // An async update expired. There may be other expired updates on
13211 // this root. We should render all the expired work in a
13212 // single batch.
13213 var currentTime = requestCurrentTime();
13214 if (currentTime < expirationTime) {
13215 // Restart at the current time.
13216 executionContext = prevExecutionContext;
13217 resetContextDependencies();
13218 ReactCurrentDispatcher.current = prevDispatcher;
13219 if (enableSchedulerTracing) {
13220 __interactionsRef.current = prevInteractions;
13221 }
13222 return renderRoot.bind(null, root, currentTime);
13223 }
13224 }
13225 } else {
13226 // Since we know we're in a React event, we can clear the current
13227 // event time. The next update will compute a new event time.
13228 currentEventTime = NoWork;
13229 }
13230
13231 do {
13232 try {
13233 if (isSync) {
13234 workLoopSync();
13235 } else {
13236 workLoop();
13237 }
13238 break;
13239 } catch (thrownValue) {
13240 // Reset module-level state that was set during the render phase.
13241 resetContextDependencies();
13242 resetHooks();
13243
13244 var sourceFiber = workInProgress;
13245 if (sourceFiber === null || sourceFiber.return === null) {
13246 // Expected to be working on a non-root fiber. This is a fatal error
13247 // because there's no ancestor that can handle it; the root is
13248 // supposed to capture all errors that weren't caught by an error
13249 // boundary.
13250 prepareFreshStack(root, expirationTime);
13251 executionContext = prevExecutionContext;
13252 throw thrownValue;
13253 }
13254
13255 if (enableProfilerTimer && sourceFiber.mode & ProfileMode) {
13256 // Record the time spent rendering before an error was thrown. This
13257 // avoids inaccurate Profiler durations in the case of a
13258 // suspended render.
13259 stopProfilerTimerIfRunningAndRecordDelta(sourceFiber, true);
13260 }
13261
13262 var returnFiber = sourceFiber.return;
13263 throwException(root, returnFiber, sourceFiber, thrownValue, renderExpirationTime);
13264 workInProgress = completeUnitOfWork(sourceFiber);
13265 }
13266 } while (true);
13267
13268 executionContext = prevExecutionContext;
13269 resetContextDependencies();
13270 ReactCurrentDispatcher.current = prevDispatcher;
13271 if (enableSchedulerTracing) {
13272 __interactionsRef.current = prevInteractions;
13273 }
13274
13275 if (workInProgress !== null) {
13276 // There's still work left over. Return a continuation.
13277 stopInterruptedWorkLoopTimer();
13278 if (expirationTime !== Sync) {
13279 startRequestCallbackTimer();
13280 }
13281 return renderRoot.bind(null, root, expirationTime);
13282 }
13283 }
13284
13285 // We now have a consistent tree. The next step is either to commit it, or, if
13286 // something suspended, wait to commit it after a timeout.
13287 stopFinishedWorkLoopTimer();
13288
13289 root.finishedWork = root.current.alternate;
13290 root.finishedExpirationTime = expirationTime;
13291
13292 var isLocked = resolveLocksOnRoot(root, expirationTime);
13293 if (isLocked) {
13294 // This root has a lock that prevents it from committing. Exit. If we begin
13295 // work on the root again, without any intervening updates, it will finish
13296 // without doing additional work.
13297 return null;
13298 }
13299
13300 // Set this to null to indicate there's no in-progress render.
13301 workInProgressRoot = null;
13302
13303 switch (workInProgressRootExitStatus) {
13304 case RootIncomplete:
13305 {
13306 (function () {
13307 {
13308 {
13309 throw ReactError(Error('Should have a work-in-progress.'));
13310 }
13311 }
13312 })();
13313 }
13314 // Flow knows about invariant, so it complains if I add a break statement,
13315 // but eslint doesn't know about invariant, so it complains if I do.
13316 // eslint-disable-next-line no-fallthrough
13317 case RootErrored:
13318 {
13319 // An error was thrown. First check if there is lower priority work
13320 // scheduled on this root.
13321 var _lastPendingTime = root.lastPendingTime;
13322 if (_lastPendingTime < expirationTime) {
13323 // There's lower priority work. Before raising the error, try rendering
13324 // at the lower priority to see if it fixes it. Use a continuation to
13325 // maintain the existing priority and position in the queue.
13326 return renderRoot.bind(null, root, _lastPendingTime);
13327 }
13328 if (!isSync) {
13329 // If we're rendering asynchronously, it's possible the error was
13330 // caused by tearing due to a mutation during an event. Try rendering
13331 // one more time without yiedling to events.
13332 prepareFreshStack(root, expirationTime);
13333 scheduleSyncCallback(renderRoot.bind(null, root, expirationTime));
13334 return null;
13335 }
13336 // If we're already rendering synchronously, commit the root in its
13337 // errored state.
13338 return commitRoot.bind(null, root);
13339 }
13340 case RootSuspended:
13341 {
13342 flushSuspensePriorityWarningInDEV();
13343
13344 // We have an acceptable loading state. We need to figure out if we should
13345 // immediately commit it or wait a bit.
13346
13347 // If we have processed new updates during this render, we may now have a
13348 // new loading state ready. We want to ensure that we commit that as soon as
13349 // possible.
13350 var hasNotProcessedNewUpdates = workInProgressRootLatestProcessedExpirationTime === Sync;
13351 if (hasNotProcessedNewUpdates && !isSync &&
13352 // do not delay if we're inside an act() scope
13353 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current)) {
13354 // If we have not processed any new updates during this pass, then this is
13355 // either a retry of an existing fallback state or a hidden tree.
13356 // Hidden trees shouldn't be batched with other work and after that's
13357 // fixed it can only be a retry.
13358 // We're going to throttle committing retries so that we don't show too
13359 // many loading states too quickly.
13360 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now();
13361 // Don't bother with a very short suspense time.
13362 if (msUntilTimeout > 10) {
13363 if (workInProgressRootHasPendingPing) {
13364 // This render was pinged but we didn't get to restart earlier so try
13365 // restarting now instead.
13366 prepareFreshStack(root, expirationTime);
13367 return renderRoot.bind(null, root, expirationTime);
13368 }
13369 var _lastPendingTime2 = root.lastPendingTime;
13370 if (_lastPendingTime2 < expirationTime) {
13371 // There's lower priority work. It might be unsuspended. Try rendering
13372 // at that level.
13373 return renderRoot.bind(null, root, _lastPendingTime2);
13374 }
13375 // The render is suspended, it hasn't timed out, and there's no lower
13376 // priority work to do. Instead of committing the fallback
13377 // immediately, wait for more data to arrive.
13378 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);
13379 return null;
13380 }
13381 }
13382 // The work expired. Commit immediately.
13383 return commitRoot.bind(null, root);
13384 }
13385 case RootSuspendedWithDelay:
13386 {
13387 flushSuspensePriorityWarningInDEV();
13388
13389 if (!isSync &&
13390 // do not delay if we're inside an act() scope
13391 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current)) {
13392 // We're suspended in a state that should be avoided. We'll try to avoid committing
13393 // it for as long as the timeouts let us.
13394 if (workInProgressRootHasPendingPing) {
13395 // This render was pinged but we didn't get to restart earlier so try
13396 // restarting now instead.
13397 prepareFreshStack(root, expirationTime);
13398 return renderRoot.bind(null, root, expirationTime);
13399 }
13400 var _lastPendingTime3 = root.lastPendingTime;
13401 if (_lastPendingTime3 < expirationTime) {
13402 // There's lower priority work. It might be unsuspended. Try rendering
13403 // at that level immediately.
13404 return renderRoot.bind(null, root, _lastPendingTime3);
13405 }
13406
13407 var _msUntilTimeout = void 0;
13408 if (workInProgressRootLatestSuspenseTimeout !== Sync) {
13409 // We have processed a suspense config whose expiration time we can use as
13410 // the timeout.
13411 _msUntilTimeout = expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now();
13412 } else if (workInProgressRootLatestProcessedExpirationTime === Sync) {
13413 // This should never normally happen because only new updates cause
13414 // delayed states, so we should have processed something. However,
13415 // this could also happen in an offscreen tree.
13416 _msUntilTimeout = 0;
13417 } else {
13418 // If we don't have a suspense config, we're going to use a heuristic to
13419 var eventTimeMs = inferTimeFromExpirationTime(workInProgressRootLatestProcessedExpirationTime);
13420 var currentTimeMs = now();
13421 var timeUntilExpirationMs = expirationTimeToMs(expirationTime) - currentTimeMs;
13422 var timeElapsed = currentTimeMs - eventTimeMs;
13423 if (timeElapsed < 0) {
13424 // We get this wrong some time since we estimate the time.
13425 timeElapsed = 0;
13426 }
13427
13428 _msUntilTimeout = jnd(timeElapsed) - timeElapsed;
13429
13430 // Clamp the timeout to the expiration time.
13431 // TODO: Once the event time is exact instead of inferred from expiration time
13432 // we don't need this.
13433 if (timeUntilExpirationMs < _msUntilTimeout) {
13434 _msUntilTimeout = timeUntilExpirationMs;
13435 }
13436 }
13437
13438 // Don't bother with a very short suspense time.
13439 if (_msUntilTimeout > 10) {
13440 // The render is suspended, it hasn't timed out, and there's no lower
13441 // priority work to do. Instead of committing the fallback
13442 // immediately, wait for more data to arrive.
13443 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);
13444 return null;
13445 }
13446 }
13447 // The work expired. Commit immediately.
13448 return commitRoot.bind(null, root);
13449 }
13450 case RootCompleted:
13451 {
13452 // The work completed. Ready to commit.
13453 if (!isSync &&
13454 // do not delay if we're inside an act() scope
13455 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) && workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null) {
13456 // If we have exceeded the minimum loading delay, which probably
13457 // means we have shown a spinner already, we might have to suspend
13458 // a bit longer to ensure that the spinner is shown for enough time.
13459 var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay(workInProgressRootLatestProcessedExpirationTime, expirationTime, workInProgressRootCanSuspendUsingConfig);
13460 if (_msUntilTimeout2 > 10) {
13461 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout2);
13462 return null;
13463 }
13464 }
13465 return commitRoot.bind(null, root);
13466 }
13467 default:
13468 {
13469 (function () {
13470 {
13471 {
13472 throw ReactError(Error('Unknown root exit status.'));
13473 }
13474 }
13475 })();
13476 }
13477 }
13478}
13479
13480function markCommitTimeOfFallback() {
13481 globalMostRecentFallbackTime = now();
13482}
13483
13484function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) {
13485 if (expirationTime < workInProgressRootLatestProcessedExpirationTime && expirationTime > Never) {
13486 workInProgressRootLatestProcessedExpirationTime = expirationTime;
13487 }
13488 if (suspenseConfig !== null) {
13489 if (expirationTime < workInProgressRootLatestSuspenseTimeout && expirationTime > Never) {
13490 workInProgressRootLatestSuspenseTimeout = expirationTime;
13491 // Most of the time we only have one config and getting wrong is not bad.
13492 workInProgressRootCanSuspendUsingConfig = suspenseConfig;
13493 }
13494 }
13495}
13496
13497function renderDidSuspend() {
13498 if (workInProgressRootExitStatus === RootIncomplete) {
13499 workInProgressRootExitStatus = RootSuspended;
13500 }
13501}
13502
13503function renderDidSuspendDelayIfPossible() {
13504 if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {
13505 workInProgressRootExitStatus = RootSuspendedWithDelay;
13506 }
13507}
13508
13509function renderDidError() {
13510 if (workInProgressRootExitStatus !== RootCompleted) {
13511 workInProgressRootExitStatus = RootErrored;
13512 }
13513}
13514
13515// Called during render to determine if anything has suspended.
13516// Returns false if we're not sure.
13517function renderHasNotSuspendedYet() {
13518 // If something errored or completed, we can't really be sure,
13519 // so those are false.
13520 return workInProgressRootExitStatus === RootIncomplete;
13521}
13522
13523function inferTimeFromExpirationTime(expirationTime) {
13524 // We don't know exactly when the update was scheduled, but we can infer an
13525 // approximate start time from the expiration time.
13526 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
13527 return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
13528}
13529
13530function inferTimeFromExpirationTimeWithSuspenseConfig(expirationTime, suspenseConfig) {
13531 // We don't know exactly when the update was scheduled, but we can infer an
13532 // approximate start time from the expiration time by subtracting the timeout
13533 // that was added to the event time.
13534 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
13535 return earliestExpirationTimeMs - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
13536}
13537
13538function workLoopSync() {
13539 // Already timed out, so perform work without checking if we need to yield.
13540 while (workInProgress !== null) {
13541 workInProgress = performUnitOfWork(workInProgress);
13542 }
13543}
13544
13545function workLoop() {
13546 // Perform work until Scheduler asks us to yield
13547 while (workInProgress !== null && !shouldYield()) {
13548 workInProgress = performUnitOfWork(workInProgress);
13549 }
13550}
13551
13552function performUnitOfWork(unitOfWork) {
13553 // The current, flushed, state of this fiber is the alternate. Ideally
13554 // nothing should rely on this, but relying on it here means that we don't
13555 // need an additional field on the work in progress.
13556 var current = unitOfWork.alternate;
13557
13558 startWorkTimer(unitOfWork);
13559 setCurrentFiber(unitOfWork);
13560
13561 var next = void 0;
13562 if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) {
13563 startProfilerTimer(unitOfWork);
13564 next = beginWork$$1(current, unitOfWork, renderExpirationTime);
13565 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
13566 } else {
13567 next = beginWork$$1(current, unitOfWork, renderExpirationTime);
13568 }
13569
13570 resetCurrentFiber();
13571 unitOfWork.memoizedProps = unitOfWork.pendingProps;
13572 if (next === null) {
13573 // If this doesn't spawn new work, complete the current work.
13574 next = completeUnitOfWork(unitOfWork);
13575 }
13576
13577 ReactCurrentOwner$1.current = null;
13578 return next;
13579}
13580
13581function completeUnitOfWork(unitOfWork) {
13582 // Attempt to complete the current unit of work, then move to the next
13583 // sibling. If there are no more siblings, return to the parent fiber.
13584 workInProgress = unitOfWork;
13585 do {
13586 // The current, flushed, state of this fiber is the alternate. Ideally
13587 // nothing should rely on this, but relying on it here means that we don't
13588 // need an additional field on the work in progress.
13589 var current = workInProgress.alternate;
13590 var returnFiber = workInProgress.return;
13591
13592 // Check if the work completed or if something threw.
13593 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
13594 setCurrentFiber(workInProgress);
13595 var next = void 0;
13596 if (!enableProfilerTimer || (workInProgress.mode & ProfileMode) === NoMode) {
13597 next = completeWork(current, workInProgress, renderExpirationTime);
13598 } else {
13599 startProfilerTimer(workInProgress);
13600 next = completeWork(current, workInProgress, renderExpirationTime);
13601 // Update render duration assuming we didn't error.
13602 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
13603 }
13604 stopWorkTimer(workInProgress);
13605 resetCurrentFiber();
13606 resetChildExpirationTime(workInProgress);
13607
13608 if (next !== null) {
13609 // Completing this fiber spawned new work. Work on that next.
13610 return next;
13611 }
13612
13613 if (returnFiber !== null &&
13614 // Do not append effects to parents if a sibling failed to complete
13615 (returnFiber.effectTag & Incomplete) === NoEffect) {
13616 // Append all the effects of the subtree and this fiber onto the effect
13617 // list of the parent. The completion order of the children affects the
13618 // side-effect order.
13619 if (returnFiber.firstEffect === null) {
13620 returnFiber.firstEffect = workInProgress.firstEffect;
13621 }
13622 if (workInProgress.lastEffect !== null) {
13623 if (returnFiber.lastEffect !== null) {
13624 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
13625 }
13626 returnFiber.lastEffect = workInProgress.lastEffect;
13627 }
13628
13629 // If this fiber had side-effects, we append it AFTER the children's
13630 // side-effects. We can perform certain side-effects earlier if needed,
13631 // by doing multiple passes over the effect list. We don't want to
13632 // schedule our own side-effect on our own list because if end up
13633 // reusing children we'll schedule this effect onto itself since we're
13634 // at the end.
13635 var effectTag = workInProgress.effectTag;
13636
13637 // Skip both NoWork and PerformedWork tags when creating the effect
13638 // list. PerformedWork effect is read by React DevTools but shouldn't be
13639 // committed.
13640 if (effectTag > PerformedWork) {
13641 if (returnFiber.lastEffect !== null) {
13642 returnFiber.lastEffect.nextEffect = workInProgress;
13643 } else {
13644 returnFiber.firstEffect = workInProgress;
13645 }
13646 returnFiber.lastEffect = workInProgress;
13647 }
13648 }
13649 } else {
13650 // This fiber did not complete because something threw. Pop values off
13651 // the stack without entering the complete phase. If this is a boundary,
13652 // capture values if possible.
13653 var _next = unwindWork(workInProgress, renderExpirationTime);
13654
13655 // Because this fiber did not complete, don't reset its expiration time.
13656
13657 if (enableProfilerTimer && (workInProgress.mode & ProfileMode) !== NoMode) {
13658 // Record the render duration for the fiber that errored.
13659 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
13660
13661 // Include the time spent working on failed children before continuing.
13662 var actualDuration = workInProgress.actualDuration;
13663 var child = workInProgress.child;
13664 while (child !== null) {
13665 actualDuration += child.actualDuration;
13666 child = child.sibling;
13667 }
13668 workInProgress.actualDuration = actualDuration;
13669 }
13670
13671 if (_next !== null) {
13672 // If completing this work spawned new work, do that next. We'll come
13673 // back here again.
13674 // Since we're restarting, remove anything that is not a host effect
13675 // from the effect tag.
13676 // TODO: The name stopFailedWorkTimer is misleading because Suspense
13677 // also captures and restarts.
13678 stopFailedWorkTimer(workInProgress);
13679 _next.effectTag &= HostEffectMask;
13680 return _next;
13681 }
13682 stopWorkTimer(workInProgress);
13683
13684 if (returnFiber !== null) {
13685 // Mark the parent fiber as incomplete and clear its effect list.
13686 returnFiber.firstEffect = returnFiber.lastEffect = null;
13687 returnFiber.effectTag |= Incomplete;
13688 }
13689 }
13690
13691 var siblingFiber = workInProgress.sibling;
13692 if (siblingFiber !== null) {
13693 // If there is more work to do in this returnFiber, do that next.
13694 return siblingFiber;
13695 }
13696 // Otherwise, return to the parent
13697 workInProgress = returnFiber;
13698 } while (workInProgress !== null);
13699
13700 // We've reached the root.
13701 if (workInProgressRootExitStatus === RootIncomplete) {
13702 workInProgressRootExitStatus = RootCompleted;
13703 }
13704 return null;
13705}
13706
13707function resetChildExpirationTime(completedWork) {
13708 if (renderExpirationTime !== Never && completedWork.childExpirationTime === Never) {
13709 // The children of this component are hidden. Don't bubble their
13710 // expiration times.
13711 return;
13712 }
13713
13714 var newChildExpirationTime = NoWork;
13715
13716 // Bubble up the earliest expiration time.
13717 if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) {
13718 // In profiling mode, resetChildExpirationTime is also used to reset
13719 // profiler durations.
13720 var actualDuration = completedWork.actualDuration;
13721 var treeBaseDuration = completedWork.selfBaseDuration;
13722
13723 // When a fiber is cloned, its actualDuration is reset to 0. This value will
13724 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
13725 // When work is done, it should bubble to the parent's actualDuration. If
13726 // the fiber has not been cloned though, (meaning no work was done), then
13727 // this value will reflect the amount of time spent working on a previous
13728 // render. In that case it should not bubble. We determine whether it was
13729 // cloned by comparing the child pointer.
13730 var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;
13731
13732 var child = completedWork.child;
13733 while (child !== null) {
13734 var childUpdateExpirationTime = child.expirationTime;
13735 var childChildExpirationTime = child.childExpirationTime;
13736 if (childUpdateExpirationTime > newChildExpirationTime) {
13737 newChildExpirationTime = childUpdateExpirationTime;
13738 }
13739 if (childChildExpirationTime > newChildExpirationTime) {
13740 newChildExpirationTime = childChildExpirationTime;
13741 }
13742 if (shouldBubbleActualDurations) {
13743 actualDuration += child.actualDuration;
13744 }
13745 treeBaseDuration += child.treeBaseDuration;
13746 child = child.sibling;
13747 }
13748 completedWork.actualDuration = actualDuration;
13749 completedWork.treeBaseDuration = treeBaseDuration;
13750 } else {
13751 var _child = completedWork.child;
13752 while (_child !== null) {
13753 var _childUpdateExpirationTime = _child.expirationTime;
13754 var _childChildExpirationTime = _child.childExpirationTime;
13755 if (_childUpdateExpirationTime > newChildExpirationTime) {
13756 newChildExpirationTime = _childUpdateExpirationTime;
13757 }
13758 if (_childChildExpirationTime > newChildExpirationTime) {
13759 newChildExpirationTime = _childChildExpirationTime;
13760 }
13761 _child = _child.sibling;
13762 }
13763 }
13764
13765 completedWork.childExpirationTime = newChildExpirationTime;
13766}
13767
13768function commitRoot(root) {
13769 var renderPriorityLevel = getCurrentPriorityLevel();
13770 runWithPriority(ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel));
13771 // If there are passive effects, schedule a callback to flush them. This goes
13772 // outside commitRootImpl so that it inherits the priority of the render.
13773 if (rootWithPendingPassiveEffects !== null) {
13774 scheduleCallback(NormalPriority, function () {
13775 flushPassiveEffects();
13776 return null;
13777 });
13778 }
13779 return null;
13780}
13781
13782function commitRootImpl(root, renderPriorityLevel) {
13783 flushPassiveEffects();
13784 flushRenderPhaseStrictModeWarningsInDEV();
13785
13786 (function () {
13787 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
13788 {
13789 throw ReactError(Error('Should not already be working.'));
13790 }
13791 }
13792 })();
13793
13794 var finishedWork = root.finishedWork;
13795 var expirationTime = root.finishedExpirationTime;
13796 if (finishedWork === null) {
13797 return null;
13798 }
13799 root.finishedWork = null;
13800 root.finishedExpirationTime = NoWork;
13801
13802 (function () {
13803 if (!(finishedWork !== root.current)) {
13804 {
13805 throw ReactError(Error('Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue.'));
13806 }
13807 }
13808 })();
13809
13810 // commitRoot never returns a continuation; it always finishes synchronously.
13811 // So we can clear these now to allow a new callback to be scheduled.
13812 root.callbackNode = null;
13813 root.callbackExpirationTime = NoWork;
13814
13815 startCommitTimer();
13816
13817 // Update the first and last pending times on this root. The new first
13818 // pending time is whatever is left on the root fiber.
13819 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime;
13820 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;
13821 var firstPendingTimeBeforeCommit = childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit ? childExpirationTimeBeforeCommit : updateExpirationTimeBeforeCommit;
13822 root.firstPendingTime = firstPendingTimeBeforeCommit;
13823 if (firstPendingTimeBeforeCommit < root.lastPendingTime) {
13824 // This usually means we've finished all the work, but it can also happen
13825 // when something gets downprioritized during render, like a hidden tree.
13826 root.lastPendingTime = firstPendingTimeBeforeCommit;
13827 }
13828
13829 if (root === workInProgressRoot) {
13830 // We can reset these now that they are finished.
13831 workInProgressRoot = null;
13832 workInProgress = null;
13833 renderExpirationTime = NoWork;
13834 } else {}
13835 // This indicates that the last root we worked on is not the same one that
13836 // we're committing now. This most commonly happens when a suspended root
13837 // times out.
13838
13839
13840 // Get the list of effects.
13841 var firstEffect = void 0;
13842 if (finishedWork.effectTag > PerformedWork) {
13843 // A fiber's effect list consists only of its children, not itself. So if
13844 // the root has an effect, we need to add it to the end of the list. The
13845 // resulting list is the set that would belong to the root's parent, if it
13846 // had one; that is, all the effects in the tree including the root.
13847 if (finishedWork.lastEffect !== null) {
13848 finishedWork.lastEffect.nextEffect = finishedWork;
13849 firstEffect = finishedWork.firstEffect;
13850 } else {
13851 firstEffect = finishedWork;
13852 }
13853 } else {
13854 // There is no effect on the root.
13855 firstEffect = finishedWork.firstEffect;
13856 }
13857
13858 if (firstEffect !== null) {
13859 var prevExecutionContext = executionContext;
13860 executionContext |= CommitContext;
13861 var prevInteractions = null;
13862 if (enableSchedulerTracing) {
13863 prevInteractions = __interactionsRef.current;
13864 __interactionsRef.current = root.memoizedInteractions;
13865 }
13866
13867 // Reset this to null before calling lifecycles
13868 ReactCurrentOwner$1.current = null;
13869
13870 // The commit phase is broken into several sub-phases. We do a separate pass
13871 // of the effect list for each phase: all mutation effects come before all
13872 // layout effects, and so on.
13873
13874 // The first phase a "before mutation" phase. We use this phase to read the
13875 // state of the host tree right before we mutate it. This is where
13876 // getSnapshotBeforeUpdate is called.
13877 startCommitSnapshotEffectsTimer();
13878 prepareForCommit(root.containerInfo);
13879 nextEffect = firstEffect;
13880 do {
13881 {
13882 invokeGuardedCallback(null, commitBeforeMutationEffects, null);
13883 if (hasCaughtError()) {
13884 (function () {
13885 if (!(nextEffect !== null)) {
13886 {
13887 throw ReactError(Error('Should be working on an effect.'));
13888 }
13889 }
13890 })();
13891 var error = clearCaughtError();
13892 captureCommitPhaseError(nextEffect, error);
13893 nextEffect = nextEffect.nextEffect;
13894 }
13895 }
13896 } while (nextEffect !== null);
13897 stopCommitSnapshotEffectsTimer();
13898
13899 if (enableProfilerTimer) {
13900 // Mark the current commit time to be shared by all Profilers in this
13901 // batch. This enables them to be grouped later.
13902 recordCommitTime();
13903 }
13904
13905 // The next phase is the mutation phase, where we mutate the host tree.
13906 startCommitHostEffectsTimer();
13907 nextEffect = firstEffect;
13908 do {
13909 {
13910 invokeGuardedCallback(null, commitMutationEffects, null, renderPriorityLevel);
13911 if (hasCaughtError()) {
13912 (function () {
13913 if (!(nextEffect !== null)) {
13914 {
13915 throw ReactError(Error('Should be working on an effect.'));
13916 }
13917 }
13918 })();
13919 var _error = clearCaughtError();
13920 captureCommitPhaseError(nextEffect, _error);
13921 nextEffect = nextEffect.nextEffect;
13922 }
13923 }
13924 } while (nextEffect !== null);
13925 stopCommitHostEffectsTimer();
13926 resetAfterCommit(root.containerInfo);
13927
13928 // The work-in-progress tree is now the current tree. This must come after
13929 // the mutation phase, so that the previous tree is still current during
13930 // componentWillUnmount, but before the layout phase, so that the finished
13931 // work is current during componentDidMount/Update.
13932 root.current = finishedWork;
13933
13934 // The next phase is the layout phase, where we call effects that read
13935 // the host tree after it's been mutated. The idiomatic use case for this is
13936 // layout, but class component lifecycles also fire here for legacy reasons.
13937 startCommitLifeCyclesTimer();
13938 nextEffect = firstEffect;
13939 do {
13940 {
13941 invokeGuardedCallback(null, commitLayoutEffects, null, root, expirationTime);
13942 if (hasCaughtError()) {
13943 (function () {
13944 if (!(nextEffect !== null)) {
13945 {
13946 throw ReactError(Error('Should be working on an effect.'));
13947 }
13948 }
13949 })();
13950 var _error2 = clearCaughtError();
13951 captureCommitPhaseError(nextEffect, _error2);
13952 nextEffect = nextEffect.nextEffect;
13953 }
13954 }
13955 } while (nextEffect !== null);
13956 stopCommitLifeCyclesTimer();
13957
13958 nextEffect = null;
13959
13960 // Tell Scheduler to yield at the end of the frame, so the browser has an
13961 // opportunity to paint.
13962 requestPaint();
13963
13964 if (enableSchedulerTracing) {
13965 __interactionsRef.current = prevInteractions;
13966 }
13967 executionContext = prevExecutionContext;
13968 } else {
13969 // No effects.
13970 root.current = finishedWork;
13971 // Measure these anyway so the flamegraph explicitly shows that there were
13972 // no effects.
13973 // TODO: Maybe there's a better way to report this.
13974 startCommitSnapshotEffectsTimer();
13975 stopCommitSnapshotEffectsTimer();
13976 if (enableProfilerTimer) {
13977 recordCommitTime();
13978 }
13979 startCommitHostEffectsTimer();
13980 stopCommitHostEffectsTimer();
13981 startCommitLifeCyclesTimer();
13982 stopCommitLifeCyclesTimer();
13983 }
13984
13985 stopCommitTimer();
13986
13987 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
13988
13989 if (rootDoesHavePassiveEffects) {
13990 // This commit has passive effects. Stash a reference to them. But don't
13991 // schedule a callback until after flushing layout work.
13992 rootDoesHavePassiveEffects = false;
13993 rootWithPendingPassiveEffects = root;
13994 pendingPassiveEffectsExpirationTime = expirationTime;
13995 pendingPassiveEffectsRenderPriority = renderPriorityLevel;
13996 } else {
13997 // We are done with the effect chain at this point so let's clear the
13998 // nextEffect pointers to assist with GC. If we have passive effects, we'll
13999 // clear this in flushPassiveEffects.
14000 nextEffect = firstEffect;
14001 while (nextEffect !== null) {
14002 var nextNextEffect = nextEffect.nextEffect;
14003 nextEffect.nextEffect = null;
14004 nextEffect = nextNextEffect;
14005 }
14006 }
14007
14008 // Check if there's remaining work on this root
14009 var remainingExpirationTime = root.firstPendingTime;
14010 if (remainingExpirationTime !== NoWork) {
14011 var currentTime = requestCurrentTime();
14012 var priorityLevel = inferPriorityFromExpirationTime(currentTime, remainingExpirationTime);
14013
14014 if (enableSchedulerTracing) {
14015 if (spawnedWorkDuringRender !== null) {
14016 var expirationTimes = spawnedWorkDuringRender;
14017 spawnedWorkDuringRender = null;
14018 for (var i = 0; i < expirationTimes.length; i++) {
14019 scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);
14020 }
14021 }
14022 }
14023
14024 scheduleCallbackForRoot(root, priorityLevel, remainingExpirationTime);
14025 } else {
14026 // If there's no remaining work, we can clear the set of already failed
14027 // error boundaries.
14028 legacyErrorBoundariesThatAlreadyFailed = null;
14029 }
14030
14031 if (enableSchedulerTracing) {
14032 if (!rootDidHavePassiveEffects) {
14033 // If there are no passive effects, then we can complete the pending interactions.
14034 // Otherwise, we'll wait until after the passive effects are flushed.
14035 // Wait to do this until after remaining work has been scheduled,
14036 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.
14037 finishPendingInteractions(root, expirationTime);
14038 }
14039 }
14040
14041 onCommitRoot(finishedWork.stateNode, expirationTime);
14042
14043 if (remainingExpirationTime === Sync) {
14044 // Count the number of times the root synchronously re-renders without
14045 // finishing. If there are too many, it indicates an infinite update loop.
14046 if (root === rootWithNestedUpdates) {
14047 nestedUpdateCount++;
14048 } else {
14049 nestedUpdateCount = 0;
14050 rootWithNestedUpdates = root;
14051 }
14052 } else {
14053 nestedUpdateCount = 0;
14054 }
14055
14056 if (hasUncaughtError) {
14057 hasUncaughtError = false;
14058 var _error3 = firstUncaughtError;
14059 firstUncaughtError = null;
14060 throw _error3;
14061 }
14062
14063 if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
14064 // This is a legacy edge case. We just committed the initial mount of
14065 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
14066 // synchronously, but layout updates should be deferred until the end
14067 // of the batch.
14068 return null;
14069 }
14070
14071 // If layout work was scheduled, flush it now.
14072 flushSyncCallbackQueue();
14073 return null;
14074}
14075
14076function commitBeforeMutationEffects() {
14077 while (nextEffect !== null) {
14078 if ((nextEffect.effectTag & Snapshot) !== NoEffect) {
14079 setCurrentFiber(nextEffect);
14080 recordEffect();
14081
14082 var current = nextEffect.alternate;
14083 commitBeforeMutationLifeCycles(current, nextEffect);
14084
14085 resetCurrentFiber();
14086 }
14087 nextEffect = nextEffect.nextEffect;
14088 }
14089}
14090
14091function commitMutationEffects(renderPriorityLevel) {
14092 // TODO: Should probably move the bulk of this function to commitWork.
14093 while (nextEffect !== null) {
14094 setCurrentFiber(nextEffect);
14095
14096 var effectTag = nextEffect.effectTag;
14097
14098 if (effectTag & ContentReset) {
14099 commitResetTextContent(nextEffect);
14100 }
14101
14102 if (effectTag & Ref) {
14103 var current = nextEffect.alternate;
14104 if (current !== null) {
14105 commitDetachRef(current);
14106 }
14107 }
14108
14109 // The following switch statement is only concerned about placement,
14110 // updates, and deletions. To avoid needing to add a case for every possible
14111 // bitmap value, we remove the secondary effects from the effect tag and
14112 // switch on that value.
14113 var primaryEffectTag = effectTag & (Placement | Update | Deletion);
14114 switch (primaryEffectTag) {
14115 case Placement:
14116 {
14117 commitPlacement(nextEffect);
14118 // Clear the "placement" from effect tag so that we know that this is
14119 // inserted, before any life-cycles like componentDidMount gets called.
14120 // TODO: findDOMNode doesn't rely on this any more but isMounted does
14121 // and isMounted is deprecated anyway so we should be able to kill this.
14122 nextEffect.effectTag &= ~Placement;
14123 break;
14124 }
14125 case PlacementAndUpdate:
14126 {
14127 // Placement
14128 commitPlacement(nextEffect);
14129 // Clear the "placement" from effect tag so that we know that this is
14130 // inserted, before any life-cycles like componentDidMount gets called.
14131 nextEffect.effectTag &= ~Placement;
14132
14133 // Update
14134 var _current = nextEffect.alternate;
14135 commitWork(_current, nextEffect);
14136 break;
14137 }
14138 case Update:
14139 {
14140 var _current2 = nextEffect.alternate;
14141 commitWork(_current2, nextEffect);
14142 break;
14143 }
14144 case Deletion:
14145 {
14146 commitDeletion(nextEffect, renderPriorityLevel);
14147 break;
14148 }
14149 }
14150
14151 // TODO: Only record a mutation effect if primaryEffectTag is non-zero.
14152 recordEffect();
14153
14154 resetCurrentFiber();
14155 nextEffect = nextEffect.nextEffect;
14156 }
14157}
14158
14159function commitLayoutEffects(root, committedExpirationTime) {
14160 // TODO: Should probably move the bulk of this function to commitWork.
14161 while (nextEffect !== null) {
14162 setCurrentFiber(nextEffect);
14163
14164 var effectTag = nextEffect.effectTag;
14165
14166 if (effectTag & (Update | Callback)) {
14167 recordEffect();
14168 var current = nextEffect.alternate;
14169 commitLifeCycles(root, current, nextEffect, committedExpirationTime);
14170 }
14171
14172 if (effectTag & Ref) {
14173 recordEffect();
14174 commitAttachRef(nextEffect);
14175 }
14176
14177 if (effectTag & Passive) {
14178 rootDoesHavePassiveEffects = true;
14179 }
14180
14181 resetCurrentFiber();
14182 nextEffect = nextEffect.nextEffect;
14183 }
14184}
14185
14186function flushPassiveEffects() {
14187 if (rootWithPendingPassiveEffects === null) {
14188 return false;
14189 }
14190 var root = rootWithPendingPassiveEffects;
14191 var expirationTime = pendingPassiveEffectsExpirationTime;
14192 var renderPriorityLevel = pendingPassiveEffectsRenderPriority;
14193 rootWithPendingPassiveEffects = null;
14194 pendingPassiveEffectsExpirationTime = NoWork;
14195 pendingPassiveEffectsRenderPriority = NoPriority;
14196 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
14197 return runWithPriority(priorityLevel, flushPassiveEffectsImpl.bind(null, root, expirationTime));
14198}
14199
14200function flushPassiveEffectsImpl(root, expirationTime) {
14201 var prevInteractions = null;
14202 if (enableSchedulerTracing) {
14203 prevInteractions = __interactionsRef.current;
14204 __interactionsRef.current = root.memoizedInteractions;
14205 }
14206
14207 (function () {
14208 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
14209 {
14210 throw ReactError(Error('Cannot flush passive effects while already rendering.'));
14211 }
14212 }
14213 })();
14214 var prevExecutionContext = executionContext;
14215 executionContext |= CommitContext;
14216
14217 // Note: This currently assumes there are no passive effects on the root
14218 // fiber, because the root is not part of its own effect list. This could
14219 // change in the future.
14220 var effect = root.current.firstEffect;
14221 while (effect !== null) {
14222 {
14223 setCurrentFiber(effect);
14224 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
14225 if (hasCaughtError()) {
14226 (function () {
14227 if (!(effect !== null)) {
14228 {
14229 throw ReactError(Error('Should be working on an effect.'));
14230 }
14231 }
14232 })();
14233 var error = clearCaughtError();
14234 captureCommitPhaseError(effect, error);
14235 }
14236 resetCurrentFiber();
14237 }
14238 var nextNextEffect = effect.nextEffect;
14239 // Remove nextEffect pointer to assist GC
14240 effect.nextEffect = null;
14241 effect = nextNextEffect;
14242 }
14243
14244 if (enableSchedulerTracing) {
14245 __interactionsRef.current = prevInteractions;
14246 finishPendingInteractions(root, expirationTime);
14247 }
14248
14249 executionContext = prevExecutionContext;
14250 flushSyncCallbackQueue();
14251
14252 // If additional passive effects were scheduled, increment a counter. If this
14253 // exceeds the limit, we'll fire a warning.
14254 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
14255
14256 return true;
14257}
14258
14259function isAlreadyFailedLegacyErrorBoundary(instance) {
14260 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
14261}
14262
14263function markLegacyErrorBoundaryAsFailed(instance) {
14264 if (legacyErrorBoundariesThatAlreadyFailed === null) {
14265 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
14266 } else {
14267 legacyErrorBoundariesThatAlreadyFailed.add(instance);
14268 }
14269}
14270
14271function prepareToThrowUncaughtError(error) {
14272 if (!hasUncaughtError) {
14273 hasUncaughtError = true;
14274 firstUncaughtError = error;
14275 }
14276}
14277var onUncaughtError = prepareToThrowUncaughtError;
14278
14279function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
14280 var errorInfo = createCapturedValue(error, sourceFiber);
14281 var update = createRootErrorUpdate(rootFiber, errorInfo, Sync);
14282 enqueueUpdate(rootFiber, update);
14283 var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);
14284 if (root !== null) {
14285 scheduleCallbackForRoot(root, ImmediatePriority, Sync);
14286 }
14287}
14288
14289function captureCommitPhaseError(sourceFiber, error) {
14290 if (sourceFiber.tag === HostRoot) {
14291 // Error was thrown at the root. There is no parent, so the root
14292 // itself should capture it.
14293 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);
14294 return;
14295 }
14296
14297 var fiber = sourceFiber.return;
14298 while (fiber !== null) {
14299 if (fiber.tag === HostRoot) {
14300 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);
14301 return;
14302 } else if (fiber.tag === ClassComponent) {
14303 var ctor = fiber.type;
14304 var instance = fiber.stateNode;
14305 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
14306 var errorInfo = createCapturedValue(error, sourceFiber);
14307 var update = createClassErrorUpdate(fiber, errorInfo,
14308 // TODO: This is always sync
14309 Sync);
14310 enqueueUpdate(fiber, update);
14311 var root = markUpdateTimeFromFiberToRoot(fiber, Sync);
14312 if (root !== null) {
14313 scheduleCallbackForRoot(root, ImmediatePriority, Sync);
14314 }
14315 return;
14316 }
14317 }
14318 fiber = fiber.return;
14319 }
14320}
14321
14322function pingSuspendedRoot(root, thenable, suspendedTime) {
14323 var pingCache = root.pingCache;
14324 if (pingCache !== null) {
14325 // The thenable resolved, so we no longer need to memoize, because it will
14326 // never be thrown again.
14327 pingCache.delete(thenable);
14328 }
14329
14330 if (workInProgressRoot === root && renderExpirationTime === suspendedTime) {
14331 // Received a ping at the same priority level at which we're currently
14332 // rendering. We might want to restart this render. This should mirror
14333 // the logic of whether or not a root suspends once it completes.
14334
14335 // TODO: If we're rendering sync either due to Sync, Batched or expired,
14336 // we should probably never restart.
14337
14338 // If we're suspended with delay, we'll always suspend so we can always
14339 // restart. If we're suspended without any updates, it might be a retry.
14340 // If it's early in the retry we can restart. We can't know for sure
14341 // whether we'll eventually process an update during this render pass,
14342 // but it's somewhat unlikely that we get to a ping before that, since
14343 // getting to the root most update is usually very fast.
14344 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && workInProgressRootLatestProcessedExpirationTime === Sync && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
14345 // Restart from the root. Don't need to schedule a ping because
14346 // we're already working on this tree.
14347 prepareFreshStack(root, renderExpirationTime);
14348 } else {
14349 // Even though we can't restart right now, we might get an
14350 // opportunity later. So we mark this render as having a ping.
14351 workInProgressRootHasPendingPing = true;
14352 }
14353 return;
14354 }
14355
14356 var lastPendingTime = root.lastPendingTime;
14357 if (lastPendingTime < suspendedTime) {
14358 // The root is no longer suspended at this time.
14359 return;
14360 }
14361
14362 var pingTime = root.pingTime;
14363 if (pingTime !== NoWork && pingTime < suspendedTime) {
14364 // There's already a lower priority ping scheduled.
14365 return;
14366 }
14367
14368 // Mark the time at which this ping was scheduled.
14369 root.pingTime = suspendedTime;
14370
14371 if (root.finishedExpirationTime === suspendedTime) {
14372 // If there's a pending fallback waiting to commit, throw it away.
14373 root.finishedExpirationTime = NoWork;
14374 root.finishedWork = null;
14375 }
14376
14377 var currentTime = requestCurrentTime();
14378 var priorityLevel = inferPriorityFromExpirationTime(currentTime, suspendedTime);
14379 scheduleCallbackForRoot(root, priorityLevel, suspendedTime);
14380}
14381
14382function retryTimedOutBoundary(boundaryFiber) {
14383 // The boundary fiber (a Suspense component or SuspenseList component)
14384 // previously was rendered in its fallback state. One of the promises that
14385 // suspended it has resolved, which means at least part of the tree was
14386 // likely unblocked. Try rendering again, at a new expiration time.
14387 var currentTime = requestCurrentTime();
14388 var suspenseConfig = null; // Retries don't carry over the already committed update.
14389 var retryTime = computeExpirationForFiber(currentTime, boundaryFiber, suspenseConfig);
14390 // TODO: Special case idle priority?
14391 var priorityLevel = inferPriorityFromExpirationTime(currentTime, retryTime);
14392 var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);
14393 if (root !== null) {
14394 scheduleCallbackForRoot(root, priorityLevel, retryTime);
14395 }
14396}
14397
14398function resolveRetryThenable(boundaryFiber, thenable) {
14399 var retryCache = void 0;
14400 if (enableSuspenseServerRenderer) {
14401 switch (boundaryFiber.tag) {
14402 case SuspenseComponent:
14403 retryCache = boundaryFiber.stateNode;
14404 break;
14405 case DehydratedSuspenseComponent:
14406 retryCache = boundaryFiber.memoizedState;
14407 break;
14408 default:
14409 (function () {
14410 {
14411 {
14412 throw ReactError(Error('Pinged unknown suspense boundary type. This is probably a bug in React.'));
14413 }
14414 }
14415 })();
14416 }
14417 } else {
14418 retryCache = boundaryFiber.stateNode;
14419 }
14420
14421 if (retryCache !== null) {
14422 // The thenable resolved, so we no longer need to memoize, because it will
14423 // never be thrown again.
14424 retryCache.delete(thenable);
14425 }
14426
14427 retryTimedOutBoundary(boundaryFiber);
14428}
14429
14430// Computes the next Just Noticeable Difference (JND) boundary.
14431// The theory is that a person can't tell the difference between small differences in time.
14432// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
14433// difference in the experience. However, waiting for longer might mean that we can avoid
14434// showing an intermediate loading state. The longer we have already waited, the harder it
14435// is to tell small differences in time. Therefore, the longer we've already waited,
14436// the longer we can wait additionally. At some point we have to give up though.
14437// We pick a train model where the next boundary commits at a consistent schedule.
14438// These particular numbers are vague estimates. We expect to adjust them based on research.
14439function jnd(timeElapsed) {
14440 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
14441}
14442
14443function computeMsUntilSuspenseLoadingDelay(mostRecentEventTime, committedExpirationTime, suspenseConfig) {
14444 var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0;
14445 if (busyMinDurationMs <= 0) {
14446 return 0;
14447 }
14448 var busyDelayMs = suspenseConfig.busyDelayMs | 0;
14449
14450 // Compute the time until this render pass would expire.
14451 var currentTimeMs = now();
14452 var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig(mostRecentEventTime, suspenseConfig);
14453 var timeElapsed = currentTimeMs - eventTimeMs;
14454 if (timeElapsed <= busyDelayMs) {
14455 // If we haven't yet waited longer than the initial delay, we don't
14456 // have to wait any additional time.
14457 return 0;
14458 }
14459 var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed;
14460 // This is the value that is passed to `setTimeout`.
14461 return msUntilTimeout;
14462}
14463
14464function checkForNestedUpdates() {
14465 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
14466 nestedUpdateCount = 0;
14467 rootWithNestedUpdates = null;
14468 (function () {
14469 {
14470 {
14471 throw ReactError(Error('Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.'));
14472 }
14473 }
14474 })();
14475 }
14476
14477 {
14478 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
14479 nestedPassiveUpdateCount = 0;
14480 warning$1(false, 'Maximum update depth exceeded. This can happen when a component ' + "calls setState inside useEffect, but useEffect either doesn't " + 'have a dependency array, or one of the dependencies changes on ' + 'every render.');
14481 }
14482 }
14483}
14484
14485function flushRenderPhaseStrictModeWarningsInDEV() {
14486 {
14487 ReactStrictModeWarnings.flushLegacyContextWarning();
14488
14489 if (warnAboutDeprecatedLifecycles) {
14490 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
14491 }
14492 }
14493}
14494
14495function stopFinishedWorkLoopTimer() {
14496 var didCompleteRoot = true;
14497 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
14498 interruptedBy = null;
14499}
14500
14501function stopInterruptedWorkLoopTimer() {
14502 // TODO: Track which fiber caused the interruption.
14503 var didCompleteRoot = false;
14504 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
14505 interruptedBy = null;
14506}
14507
14508function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) {
14509 if (enableUserTimingAPI && workInProgressRoot !== null && updateExpirationTime > renderExpirationTime) {
14510 interruptedBy = fiberThatReceivedUpdate;
14511 }
14512}
14513
14514var didWarnStateUpdateForUnmountedComponent = null;
14515function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
14516 {
14517 var tag = fiber.tag;
14518 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent) {
14519 // Only warn for user-defined components, not internal ones like Suspense.
14520 return;
14521 }
14522 // We show the whole stack but dedupe on the top component's name because
14523 // the problematic code almost always lies inside that component.
14524 var componentName = getComponentName(fiber.type) || 'ReactComponent';
14525 if (didWarnStateUpdateForUnmountedComponent !== null) {
14526 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {
14527 return;
14528 }
14529 didWarnStateUpdateForUnmountedComponent.add(componentName);
14530 } else {
14531 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);
14532 }
14533 warningWithoutStack$1(false, "Can't perform a React state update on an unmounted component. This " + 'is a no-op, but it indicates a memory leak in your application. To ' + 'fix, cancel all subscriptions and asynchronous tasks in %s.%s', tag === ClassComponent ? 'the componentWillUnmount method' : 'a useEffect cleanup function', getStackByFiberInDevAndProd(fiber));
14534 }
14535}
14536
14537var beginWork$$1 = void 0;
14538if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
14539 var dummyFiber = null;
14540 beginWork$$1 = function (current, unitOfWork, expirationTime) {
14541 // If a component throws an error, we replay it again in a synchronously
14542 // dispatched event, so that the debugger will treat it as an uncaught
14543 // error See ReactErrorUtils for more information.
14544
14545 // Before entering the begin phase, copy the work-in-progress onto a dummy
14546 // fiber. If beginWork throws, we'll use this to reset the state.
14547 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
14548 try {
14549 return beginWork$1(current, unitOfWork, expirationTime);
14550 } catch (originalError) {
14551 if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {
14552 // Don't replay promises. Treat everything else like an error.
14553 throw originalError;
14554 }
14555
14556 // Keep this code in sync with renderRoot; any changes here must have
14557 // corresponding changes there.
14558 resetContextDependencies();
14559 resetHooks();
14560
14561 // Unwind the failed stack frame
14562 unwindInterruptedWork(unitOfWork);
14563
14564 // Restore the original properties of the fiber.
14565 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
14566
14567 if (enableProfilerTimer && unitOfWork.mode & ProfileMode) {
14568 // Reset the profiler timer.
14569 startProfilerTimer(unitOfWork);
14570 }
14571
14572 // Run beginWork again.
14573 invokeGuardedCallback(null, beginWork$1, null, current, unitOfWork, expirationTime);
14574
14575 if (hasCaughtError()) {
14576 var replayError = clearCaughtError();
14577 // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`.
14578 // Rethrow this error instead of the original one.
14579 throw replayError;
14580 } else {
14581 // This branch is reachable if the render phase is impure.
14582 throw originalError;
14583 }
14584 }
14585 };
14586} else {
14587 beginWork$$1 = beginWork$1;
14588}
14589
14590var didWarnAboutUpdateInRender = false;
14591var didWarnAboutUpdateInGetChildContext = false;
14592function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) {
14593 {
14594 if (fiber.tag === ClassComponent) {
14595 switch (phase) {
14596 case 'getChildContext':
14597 if (didWarnAboutUpdateInGetChildContext) {
14598 return;
14599 }
14600 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
14601 didWarnAboutUpdateInGetChildContext = true;
14602 break;
14603 case 'render':
14604 if (didWarnAboutUpdateInRender) {
14605 return;
14606 }
14607 warningWithoutStack$1(false, 'Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure function of ' + 'props and state.');
14608 didWarnAboutUpdateInRender = true;
14609 break;
14610 }
14611 }
14612 }
14613}
14614
14615// a 'shared' variable that changes when act() opens/closes in tests.
14616var IsThisRendererActing = { current: false };
14617
14618function warnIfNotScopedWithMatchingAct(fiber) {
14619 {
14620 if (warnsIfNotActing === true && IsSomeRendererActing.current === true && IsThisRendererActing.current !== true) {
14621 warningWithoutStack$1(false, "It looks like you're using the wrong act() around your test interactions.\n" + 'Be sure to use the matching version of act() corresponding to your renderer:\n\n' + '// for react-dom:\n' + "import {act} from 'react-dom/test-utils';\n" + '//...\n' + 'act(() => ...);\n\n' + '// for react-test-renderer:\n' + "import TestRenderer from 'react-test-renderer';\n" + 'const {act} = TestRenderer;\n' + '//...\n' + 'act(() => ...);' + '%s', getStackByFiberInDevAndProd(fiber));
14622 }
14623 }
14624}
14625
14626function warnIfNotCurrentlyActingEffectsInDEV(fiber) {
14627 {
14628 if (warnsIfNotActing === true && (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
14629 warningWithoutStack$1(false, 'An update to %s ran an effect, but was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber));
14630 }
14631 }
14632}
14633
14634function warnIfNotCurrentlyActingUpdatesInDEV(fiber) {
14635 {
14636 if (warnsIfNotActing === true && executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
14637 warningWithoutStack$1(false, 'An update to %s inside a test was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber));
14638 }
14639 }
14640}
14641
14642var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV;
14643
14644// In tests, we want to enforce a mocked scheduler.
14645var didWarnAboutUnmockedScheduler = false;
14646// TODO Before we release concurrent mode, revisit this and decide whether a mocked
14647// scheduler is the actual recommendation. The alternative could be a testing build,
14648// a new lib, or whatever; we dunno just yet. This message is for early adopters
14649// to get their tests right.
14650
14651function warnIfUnmockedScheduler(fiber) {
14652 {
14653 if (didWarnAboutUnmockedScheduler === false && unstable_flushAllWithoutAsserting === undefined) {
14654 if (fiber.mode & BatchedMode || fiber.mode & ConcurrentMode) {
14655 didWarnAboutUnmockedScheduler = true;
14656 warningWithoutStack$1(false, 'In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \n' + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + 'For more info, visit https://fb.me/react-mock-scheduler');
14657 } else if (warnAboutUnmockedScheduler === true) {
14658 didWarnAboutUnmockedScheduler = true;
14659 warningWithoutStack$1(false, 'Starting from React v17, the "scheduler" module will need to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \n' + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + 'For more info, visit https://fb.me/react-mock-scheduler');
14660 }
14661 }
14662 }
14663}
14664
14665var componentsThatTriggeredHighPriSuspend = null;
14666function checkForWrongSuspensePriorityInDEV(sourceFiber) {
14667 {
14668 var currentPriorityLevel = getCurrentPriorityLevel();
14669 if ((sourceFiber.mode & ConcurrentMode) !== NoEffect && (currentPriorityLevel === UserBlockingPriority || currentPriorityLevel === ImmediatePriority)) {
14670 var workInProgressNode = sourceFiber;
14671 while (workInProgressNode !== null) {
14672 // Add the component that triggered the suspense
14673 var current = workInProgressNode.alternate;
14674 if (current !== null) {
14675 // TODO: warn component that triggers the high priority
14676 // suspend is the HostRoot
14677 switch (workInProgressNode.tag) {
14678 case ClassComponent:
14679 // Loop through the component's update queue and see whether the component
14680 // has triggered any high priority updates
14681 var updateQueue = current.updateQueue;
14682 if (updateQueue !== null) {
14683 var update = updateQueue.firstUpdate;
14684 while (update !== null) {
14685 var priorityLevel = update.priority;
14686 if (priorityLevel === UserBlockingPriority || priorityLevel === ImmediatePriority) {
14687 if (componentsThatTriggeredHighPriSuspend === null) {
14688 componentsThatTriggeredHighPriSuspend = new Set([getComponentName(workInProgressNode.type)]);
14689 } else {
14690 componentsThatTriggeredHighPriSuspend.add(getComponentName(workInProgressNode.type));
14691 }
14692 break;
14693 }
14694 update = update.next;
14695 }
14696 }
14697 break;
14698 case FunctionComponent:
14699 case ForwardRef:
14700 case SimpleMemoComponent:
14701 if (workInProgressNode.memoizedState !== null && workInProgressNode.memoizedState.baseUpdate !== null) {
14702 var _update = workInProgressNode.memoizedState.baseUpdate;
14703 // Loop through the functional component's memoized state to see whether
14704 // the component has triggered any high pri updates
14705 while (_update !== null) {
14706 var priority = _update.priority;
14707 if (priority === UserBlockingPriority || priority === ImmediatePriority) {
14708 if (componentsThatTriggeredHighPriSuspend === null) {
14709 componentsThatTriggeredHighPriSuspend = new Set([getComponentName(workInProgressNode.type)]);
14710 } else {
14711 componentsThatTriggeredHighPriSuspend.add(getComponentName(workInProgressNode.type));
14712 }
14713 break;
14714 }
14715 if (_update.next === workInProgressNode.memoizedState.baseUpdate) {
14716 break;
14717 }
14718 _update = _update.next;
14719 }
14720 }
14721 break;
14722 default:
14723 break;
14724 }
14725 }
14726 workInProgressNode = workInProgressNode.return;
14727 }
14728 }
14729 }
14730}
14731
14732function flushSuspensePriorityWarningInDEV() {
14733 {
14734 if (componentsThatTriggeredHighPriSuspend !== null) {
14735 var componentNames = [];
14736 componentsThatTriggeredHighPriSuspend.forEach(function (name) {
14737 return componentNames.push(name);
14738 });
14739 componentsThatTriggeredHighPriSuspend = null;
14740
14741 if (componentNames.length > 0) {
14742 warningWithoutStack$1(false, '%s triggered a user-blocking update that suspended.' + '\n\n' + 'The fix is to split the update into multiple parts: a user-blocking ' + 'update to provide immediate feedback, and another update that ' + 'triggers the bulk of the changes.' + '\n\n' + 'Refer to the documentation for useSuspenseTransition to learn how ' + 'to implement this pattern.',
14743 // TODO: Add link to React docs with more information, once it exists
14744 componentNames.sort().join(', '));
14745 }
14746 }
14747 }
14748}
14749
14750function computeThreadID(root, expirationTime) {
14751 // Interaction threads are unique per root and expiration time.
14752 return expirationTime * 1000 + root.interactionThreadID;
14753}
14754
14755function markSpawnedWork(expirationTime) {
14756 if (!enableSchedulerTracing) {
14757 return;
14758 }
14759 if (spawnedWorkDuringRender === null) {
14760 spawnedWorkDuringRender = [expirationTime];
14761 } else {
14762 spawnedWorkDuringRender.push(expirationTime);
14763 }
14764}
14765
14766function scheduleInteractions(root, expirationTime, interactions) {
14767 if (!enableSchedulerTracing) {
14768 return;
14769 }
14770
14771 if (interactions.size > 0) {
14772 var pendingInteractionMap = root.pendingInteractionMap;
14773 var pendingInteractions = pendingInteractionMap.get(expirationTime);
14774 if (pendingInteractions != null) {
14775 interactions.forEach(function (interaction) {
14776 if (!pendingInteractions.has(interaction)) {
14777 // Update the pending async work count for previously unscheduled interaction.
14778 interaction.__count++;
14779 }
14780
14781 pendingInteractions.add(interaction);
14782 });
14783 } else {
14784 pendingInteractionMap.set(expirationTime, new Set(interactions));
14785
14786 // Update the pending async work count for the current interactions.
14787 interactions.forEach(function (interaction) {
14788 interaction.__count++;
14789 });
14790 }
14791
14792 var subscriber = __subscriberRef.current;
14793 if (subscriber !== null) {
14794 var threadID = computeThreadID(root, expirationTime);
14795 subscriber.onWorkScheduled(interactions, threadID);
14796 }
14797 }
14798}
14799
14800function schedulePendingInteractions(root, expirationTime) {
14801 // This is called when work is scheduled on a root.
14802 // It associates the current interactions with the newly-scheduled expiration.
14803 // They will be restored when that expiration is later committed.
14804 if (!enableSchedulerTracing) {
14805 return;
14806 }
14807
14808 scheduleInteractions(root, expirationTime, __interactionsRef.current);
14809}
14810
14811function startWorkOnPendingInteractions(root, expirationTime) {
14812 // This is called when new work is started on a root.
14813 if (!enableSchedulerTracing) {
14814 return;
14815 }
14816
14817 // Determine which interactions this batch of work currently includes, So that
14818 // we can accurately attribute time spent working on it, And so that cascading
14819 // work triggered during the render phase will be associated with it.
14820 var interactions = new Set();
14821 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
14822 if (scheduledExpirationTime >= expirationTime) {
14823 scheduledInteractions.forEach(function (interaction) {
14824 return interactions.add(interaction);
14825 });
14826 }
14827 });
14828
14829 // Store the current set of interactions on the FiberRoot for a few reasons:
14830 // We can re-use it in hot functions like renderRoot() without having to
14831 // recalculate it. We will also use it in commitWork() to pass to any Profiler
14832 // onRender() hooks. This also provides DevTools with a way to access it when
14833 // the onCommitRoot() hook is called.
14834 root.memoizedInteractions = interactions;
14835
14836 if (interactions.size > 0) {
14837 var subscriber = __subscriberRef.current;
14838 if (subscriber !== null) {
14839 var threadID = computeThreadID(root, expirationTime);
14840 try {
14841 subscriber.onWorkStarted(interactions, threadID);
14842 } catch (error) {
14843 // If the subscriber throws, rethrow it in a separate task
14844 scheduleCallback(ImmediatePriority, function () {
14845 throw error;
14846 });
14847 }
14848 }
14849 }
14850}
14851
14852function finishPendingInteractions(root, committedExpirationTime) {
14853 if (!enableSchedulerTracing) {
14854 return;
14855 }
14856
14857 var earliestRemainingTimeAfterCommit = root.firstPendingTime;
14858
14859 var subscriber = void 0;
14860
14861 try {
14862 subscriber = __subscriberRef.current;
14863 if (subscriber !== null && root.memoizedInteractions.size > 0) {
14864 var threadID = computeThreadID(root, committedExpirationTime);
14865 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
14866 }
14867 } catch (error) {
14868 // If the subscriber throws, rethrow it in a separate task
14869 scheduleCallback(ImmediatePriority, function () {
14870 throw error;
14871 });
14872 } finally {
14873 // Clear completed interactions from the pending Map.
14874 // Unless the render was suspended or cascading work was scheduled,
14875 // In which case– leave pending interactions until the subsequent render.
14876 var pendingInteractionMap = root.pendingInteractionMap;
14877 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
14878 // Only decrement the pending interaction count if we're done.
14879 // If there's still work at the current priority,
14880 // That indicates that we are waiting for suspense data.
14881 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
14882 pendingInteractionMap.delete(scheduledExpirationTime);
14883
14884 scheduledInteractions.forEach(function (interaction) {
14885 interaction.__count--;
14886
14887 if (subscriber !== null && interaction.__count === 0) {
14888 try {
14889 subscriber.onInteractionScheduledWorkCompleted(interaction);
14890 } catch (error) {
14891 // If the subscriber throws, rethrow it in a separate task
14892 scheduleCallback(ImmediatePriority, function () {
14893 throw error;
14894 });
14895 }
14896 }
14897 });
14898 }
14899 });
14900 }
14901}
14902
14903var onCommitFiberRoot = null;
14904var onCommitFiberUnmount = null;
14905var hasLoggedError = false;
14906
14907var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
14908
14909function injectInternals(internals) {
14910 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
14911 // No DevTools
14912 return false;
14913 }
14914 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
14915 if (hook.isDisabled) {
14916 // This isn't a real property on the hook, but it can be set to opt out
14917 // of DevTools integration and associated warnings and logs.
14918 // https://github.com/facebook/react/issues/3877
14919 return true;
14920 }
14921 if (!hook.supportsFiber) {
14922 {
14923 warningWithoutStack$1(false, 'The installed version of React DevTools is too old and will not work ' + 'with the current version of React. Please update React DevTools. ' + 'https://fb.me/react-devtools');
14924 }
14925 // DevTools exists, even though it doesn't support Fiber.
14926 return true;
14927 }
14928 try {
14929 var rendererID = hook.inject(internals);
14930 // We have successfully injected, so now it is safe to set up hooks.
14931 onCommitFiberRoot = function (root, expirationTime) {
14932 try {
14933 var didError = (root.current.effectTag & DidCapture) === DidCapture;
14934 if (enableProfilerTimer) {
14935 var currentTime = requestCurrentTime();
14936 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime);
14937 hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
14938 } else {
14939 hook.onCommitFiberRoot(rendererID, root, undefined, didError);
14940 }
14941 } catch (err) {
14942 if (true && !hasLoggedError) {
14943 hasLoggedError = true;
14944 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
14945 }
14946 }
14947 };
14948 onCommitFiberUnmount = function (fiber) {
14949 try {
14950 hook.onCommitFiberUnmount(rendererID, fiber);
14951 } catch (err) {
14952 if (true && !hasLoggedError) {
14953 hasLoggedError = true;
14954 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
14955 }
14956 }
14957 };
14958 } catch (err) {
14959 // Catch all errors because it is unsafe to throw during initialization.
14960 {
14961 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err);
14962 }
14963 }
14964 // DevTools exists
14965 return true;
14966}
14967
14968function onCommitRoot(root, expirationTime) {
14969 if (typeof onCommitFiberRoot === 'function') {
14970 onCommitFiberRoot(root, expirationTime);
14971 }
14972}
14973
14974function onCommitUnmount(fiber) {
14975 if (typeof onCommitFiberUnmount === 'function') {
14976 onCommitFiberUnmount(fiber);
14977 }
14978}
14979
14980var hasBadMapPolyfill = void 0;
14981
14982{
14983 hasBadMapPolyfill = false;
14984 try {
14985 var nonExtensibleObject = Object.preventExtensions({});
14986 var testMap = new Map([[nonExtensibleObject, null]]);
14987 var testSet = new Set([nonExtensibleObject]);
14988 // This is necessary for Rollup to not consider these unused.
14989 // https://github.com/rollup/rollup/issues/1771
14990 // TODO: we can remove these if Rollup fixes the bug.
14991 testMap.set(0, 0);
14992 testSet.add(0);
14993 } catch (e) {
14994 // TODO: Consider warning about bad polyfills
14995 hasBadMapPolyfill = true;
14996 }
14997}
14998
14999// A Fiber is work on a Component that needs to be done or was done. There can
15000// be more than one per component.
15001
15002
15003var debugCounter = void 0;
15004
15005{
15006 debugCounter = 1;
15007}
15008
15009function FiberNode(tag, pendingProps, key, mode) {
15010 // Instance
15011 this.tag = tag;
15012 this.key = key;
15013 this.elementType = null;
15014 this.type = null;
15015 this.stateNode = null;
15016
15017 // Fiber
15018 this.return = null;
15019 this.child = null;
15020 this.sibling = null;
15021 this.index = 0;
15022
15023 this.ref = null;
15024
15025 this.pendingProps = pendingProps;
15026 this.memoizedProps = null;
15027 this.updateQueue = null;
15028 this.memoizedState = null;
15029 this.dependencies = null;
15030
15031 this.mode = mode;
15032
15033 // Effects
15034 this.effectTag = NoEffect;
15035 this.nextEffect = null;
15036
15037 this.firstEffect = null;
15038 this.lastEffect = null;
15039
15040 this.expirationTime = NoWork;
15041 this.childExpirationTime = NoWork;
15042
15043 this.alternate = null;
15044
15045 if (enableProfilerTimer) {
15046 // Note: The following is done to avoid a v8 performance cliff.
15047 //
15048 // Initializing the fields below to smis and later updating them with
15049 // double values will cause Fibers to end up having separate shapes.
15050 // This behavior/bug has something to do with Object.preventExtension().
15051 // Fortunately this only impacts DEV builds.
15052 // Unfortunately it makes React unusably slow for some applications.
15053 // To work around this, initialize the fields below with doubles.
15054 //
15055 // Learn more about this here:
15056 // https://github.com/facebook/react/issues/14365
15057 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
15058 this.actualDuration = Number.NaN;
15059 this.actualStartTime = Number.NaN;
15060 this.selfBaseDuration = Number.NaN;
15061 this.treeBaseDuration = Number.NaN;
15062
15063 // It's okay to replace the initial doubles with smis after initialization.
15064 // This won't trigger the performance cliff mentioned above,
15065 // and it simplifies other profiler code (including DevTools).
15066 this.actualDuration = 0;
15067 this.actualStartTime = -1;
15068 this.selfBaseDuration = 0;
15069 this.treeBaseDuration = 0;
15070 }
15071
15072 {
15073 this._debugID = debugCounter++;
15074 this._debugSource = null;
15075 this._debugOwner = null;
15076 this._debugIsCurrentlyTiming = false;
15077 this._debugNeedsRemount = false;
15078 this._debugHookTypes = null;
15079 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
15080 Object.preventExtensions(this);
15081 }
15082 }
15083}
15084
15085// This is a constructor function, rather than a POJO constructor, still
15086// please ensure we do the following:
15087// 1) Nobody should add any instance methods on this. Instance methods can be
15088// more difficult to predict when they get optimized and they are almost
15089// never inlined properly in static compilers.
15090// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
15091// always know when it is a fiber.
15092// 3) We might want to experiment with using numeric keys since they are easier
15093// to optimize in a non-JIT environment.
15094// 4) We can easily go from a constructor to a createFiber object literal if that
15095// is faster.
15096// 5) It should be easy to port this to a C struct and keep a C implementation
15097// compatible.
15098var createFiber = function (tag, pendingProps, key, mode) {
15099 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
15100 return new FiberNode(tag, pendingProps, key, mode);
15101};
15102
15103function shouldConstruct(Component) {
15104 var prototype = Component.prototype;
15105 return !!(prototype && prototype.isReactComponent);
15106}
15107
15108function isSimpleFunctionComponent(type) {
15109 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
15110}
15111
15112function resolveLazyComponentTag(Component) {
15113 if (typeof Component === 'function') {
15114 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
15115 } else if (Component !== undefined && Component !== null) {
15116 var $$typeof = Component.$$typeof;
15117 if ($$typeof === REACT_FORWARD_REF_TYPE) {
15118 return ForwardRef;
15119 }
15120 if ($$typeof === REACT_MEMO_TYPE) {
15121 return MemoComponent;
15122 }
15123 }
15124 return IndeterminateComponent;
15125}
15126
15127// This is used to create an alternate fiber to do work on.
15128function createWorkInProgress(current, pendingProps, expirationTime) {
15129 var workInProgress = current.alternate;
15130 if (workInProgress === null) {
15131 // We use a double buffering pooling technique because we know that we'll
15132 // only ever need at most two versions of a tree. We pool the "other" unused
15133 // node that we're free to reuse. This is lazily created to avoid allocating
15134 // extra objects for things that are never updated. It also allow us to
15135 // reclaim the extra memory if needed.
15136 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
15137 workInProgress.elementType = current.elementType;
15138 workInProgress.type = current.type;
15139 workInProgress.stateNode = current.stateNode;
15140
15141 {
15142 // DEV-only fields
15143 workInProgress._debugID = current._debugID;
15144 workInProgress._debugSource = current._debugSource;
15145 workInProgress._debugOwner = current._debugOwner;
15146 workInProgress._debugHookTypes = current._debugHookTypes;
15147 }
15148
15149 workInProgress.alternate = current;
15150 current.alternate = workInProgress;
15151 } else {
15152 workInProgress.pendingProps = pendingProps;
15153
15154 // We already have an alternate.
15155 // Reset the effect tag.
15156 workInProgress.effectTag = NoEffect;
15157
15158 // The effect list is no longer valid.
15159 workInProgress.nextEffect = null;
15160 workInProgress.firstEffect = null;
15161 workInProgress.lastEffect = null;
15162
15163 if (enableProfilerTimer) {
15164 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
15165 // This prevents time from endlessly accumulating in new commits.
15166 // This has the downside of resetting values for different priority renders,
15167 // But works for yielding (the common case) and should support resuming.
15168 workInProgress.actualDuration = 0;
15169 workInProgress.actualStartTime = -1;
15170 }
15171 }
15172
15173 workInProgress.childExpirationTime = current.childExpirationTime;
15174 workInProgress.expirationTime = current.expirationTime;
15175
15176 workInProgress.child = current.child;
15177 workInProgress.memoizedProps = current.memoizedProps;
15178 workInProgress.memoizedState = current.memoizedState;
15179 workInProgress.updateQueue = current.updateQueue;
15180
15181 // Clone the dependencies object. This is mutated during the render phase, so
15182 // it cannot be shared with the current fiber.
15183 var currentDependencies = current.dependencies;
15184 workInProgress.dependencies = currentDependencies === null ? null : {
15185 expirationTime: currentDependencies.expirationTime,
15186 firstContext: currentDependencies.firstContext,
15187 responders: currentDependencies.responders
15188 };
15189
15190 // These will be overridden during the parent's reconciliation
15191 workInProgress.sibling = current.sibling;
15192 workInProgress.index = current.index;
15193 workInProgress.ref = current.ref;
15194
15195 if (enableProfilerTimer) {
15196 workInProgress.selfBaseDuration = current.selfBaseDuration;
15197 workInProgress.treeBaseDuration = current.treeBaseDuration;
15198 }
15199
15200 {
15201 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
15202 switch (workInProgress.tag) {
15203 case IndeterminateComponent:
15204 case FunctionComponent:
15205 case SimpleMemoComponent:
15206 workInProgress.type = resolveFunctionForHotReloading(current.type);
15207 break;
15208 case ClassComponent:
15209 workInProgress.type = resolveClassForHotReloading(current.type);
15210 break;
15211 case ForwardRef:
15212 workInProgress.type = resolveForwardRefForHotReloading(current.type);
15213 break;
15214 default:
15215 break;
15216 }
15217 }
15218
15219 return workInProgress;
15220}
15221
15222// Used to reuse a Fiber for a second pass.
15223function resetWorkInProgress(workInProgress, renderExpirationTime) {
15224 // This resets the Fiber to what createFiber or createWorkInProgress would
15225 // have set the values to before during the first pass. Ideally this wouldn't
15226 // be necessary but unfortunately many code paths reads from the workInProgress
15227 // when they should be reading from current and writing to workInProgress.
15228
15229 // We assume pendingProps, index, key, ref, return are still untouched to
15230 // avoid doing another reconciliation.
15231
15232 // Reset the effect tag but keep any Placement tags, since that's something
15233 // that child fiber is setting, not the reconciliation.
15234 workInProgress.effectTag &= Placement;
15235
15236 // The effect list is no longer valid.
15237 workInProgress.nextEffect = null;
15238 workInProgress.firstEffect = null;
15239 workInProgress.lastEffect = null;
15240
15241 var current = workInProgress.alternate;
15242 if (current === null) {
15243 // Reset to createFiber's initial values.
15244 workInProgress.childExpirationTime = NoWork;
15245 workInProgress.expirationTime = renderExpirationTime;
15246
15247 workInProgress.child = null;
15248 workInProgress.memoizedProps = null;
15249 workInProgress.memoizedState = null;
15250 workInProgress.updateQueue = null;
15251
15252 workInProgress.dependencies = null;
15253
15254 if (enableProfilerTimer) {
15255 // Note: We don't reset the actualTime counts. It's useful to accumulate
15256 // actual time across multiple render passes.
15257 workInProgress.selfBaseDuration = 0;
15258 workInProgress.treeBaseDuration = 0;
15259 }
15260 } else {
15261 // Reset to the cloned values that createWorkInProgress would've.
15262 workInProgress.childExpirationTime = current.childExpirationTime;
15263 workInProgress.expirationTime = current.expirationTime;
15264
15265 workInProgress.child = current.child;
15266 workInProgress.memoizedProps = current.memoizedProps;
15267 workInProgress.memoizedState = current.memoizedState;
15268 workInProgress.updateQueue = current.updateQueue;
15269
15270 // Clone the dependencies object. This is mutated during the render phase, so
15271 // it cannot be shared with the current fiber.
15272 var currentDependencies = current.dependencies;
15273 workInProgress.dependencies = currentDependencies === null ? null : {
15274 expirationTime: currentDependencies.expirationTime,
15275 firstContext: currentDependencies.firstContext,
15276 responders: currentDependencies.responders
15277 };
15278
15279 if (enableProfilerTimer) {
15280 // Note: We don't reset the actualTime counts. It's useful to accumulate
15281 // actual time across multiple render passes.
15282 workInProgress.selfBaseDuration = current.selfBaseDuration;
15283 workInProgress.treeBaseDuration = current.treeBaseDuration;
15284 }
15285 }
15286
15287 return workInProgress;
15288}
15289
15290function createHostRootFiber(tag) {
15291 var mode = void 0;
15292 if (tag === ConcurrentRoot) {
15293 mode = ConcurrentMode | BatchedMode | StrictMode;
15294 } else if (tag === BatchedRoot) {
15295 mode = BatchedMode | StrictMode;
15296 } else {
15297 mode = NoMode;
15298 }
15299
15300 if (enableProfilerTimer && isDevToolsPresent) {
15301 // Always collect profile timings when DevTools are present.
15302 // This enables DevTools to start capturing timing at any point–
15303 // Without some nodes in the tree having empty base times.
15304 mode |= ProfileMode;
15305 }
15306
15307 return createFiber(HostRoot, null, null, mode);
15308}
15309
15310function createFiberFromTypeAndProps(type, // React$ElementType
15311key, pendingProps, owner, mode, expirationTime) {
15312 var fiber = void 0;
15313
15314 var fiberTag = IndeterminateComponent;
15315 // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
15316 var resolvedType = type;
15317 if (typeof type === 'function') {
15318 if (shouldConstruct(type)) {
15319 fiberTag = ClassComponent;
15320 {
15321 resolvedType = resolveClassForHotReloading(resolvedType);
15322 }
15323 } else {
15324 {
15325 resolvedType = resolveFunctionForHotReloading(resolvedType);
15326 }
15327 }
15328 } else if (typeof type === 'string') {
15329 fiberTag = HostComponent;
15330 } else {
15331 getTag: switch (type) {
15332 case REACT_FRAGMENT_TYPE:
15333 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
15334 case REACT_CONCURRENT_MODE_TYPE:
15335 fiberTag = Mode;
15336 mode |= ConcurrentMode | BatchedMode | StrictMode;
15337 break;
15338 case REACT_STRICT_MODE_TYPE:
15339 fiberTag = Mode;
15340 mode |= StrictMode;
15341 break;
15342 case REACT_PROFILER_TYPE:
15343 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
15344 case REACT_SUSPENSE_TYPE:
15345 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
15346 case REACT_SUSPENSE_LIST_TYPE:
15347 return createFiberFromSuspenseList(pendingProps, mode, expirationTime, key);
15348 default:
15349 {
15350 if (typeof type === 'object' && type !== null) {
15351 switch (type.$$typeof) {
15352 case REACT_PROVIDER_TYPE:
15353 fiberTag = ContextProvider;
15354 break getTag;
15355 case REACT_CONTEXT_TYPE:
15356 // This is a consumer
15357 fiberTag = ContextConsumer;
15358 break getTag;
15359 case REACT_FORWARD_REF_TYPE:
15360 fiberTag = ForwardRef;
15361 {
15362 resolvedType = resolveForwardRefForHotReloading(resolvedType);
15363 }
15364 break getTag;
15365 case REACT_MEMO_TYPE:
15366 fiberTag = MemoComponent;
15367 break getTag;
15368 case REACT_LAZY_TYPE:
15369 fiberTag = LazyComponent;
15370 resolvedType = null;
15371 break getTag;
15372 case REACT_FUNDAMENTAL_TYPE:
15373 if (enableFundamentalAPI) {
15374 return createFiberFromFundamental(type, pendingProps, mode, expirationTime, key);
15375 }
15376 break;
15377 }
15378 }
15379 var info = '';
15380 {
15381 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
15382 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.';
15383 }
15384 var ownerName = owner ? getComponentName(owner.type) : null;
15385 if (ownerName) {
15386 info += '\n\nCheck the render method of `' + ownerName + '`.';
15387 }
15388 }
15389 (function () {
15390 {
15391 {
15392 throw ReactError(Error('Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: ' + (type == null ? type : typeof type) + '.' + info));
15393 }
15394 }
15395 })();
15396 }
15397 }
15398 }
15399
15400 fiber = createFiber(fiberTag, pendingProps, key, mode);
15401 fiber.elementType = type;
15402 fiber.type = resolvedType;
15403 fiber.expirationTime = expirationTime;
15404
15405 return fiber;
15406}
15407
15408function createFiberFromElement(element, mode, expirationTime) {
15409 var owner = null;
15410 {
15411 owner = element._owner;
15412 }
15413 var type = element.type;
15414 var key = element.key;
15415 var pendingProps = element.props;
15416 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
15417 {
15418 fiber._debugSource = element._source;
15419 fiber._debugOwner = element._owner;
15420 }
15421 return fiber;
15422}
15423
15424function createFiberFromFragment(elements, mode, expirationTime, key) {
15425 var fiber = createFiber(Fragment, elements, key, mode);
15426 fiber.expirationTime = expirationTime;
15427 return fiber;
15428}
15429
15430function createFiberFromFundamental(fundamentalComponent, pendingProps, mode, expirationTime, key) {
15431 var fiber = createFiber(FundamentalComponent, pendingProps, key, mode);
15432 fiber.elementType = fundamentalComponent;
15433 fiber.type = fundamentalComponent;
15434 fiber.expirationTime = expirationTime;
15435 return fiber;
15436}
15437
15438function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
15439 {
15440 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
15441 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
15442 }
15443 }
15444
15445 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
15446 // TODO: The Profiler fiber shouldn't have a type. It has a tag.
15447 fiber.elementType = REACT_PROFILER_TYPE;
15448 fiber.type = REACT_PROFILER_TYPE;
15449 fiber.expirationTime = expirationTime;
15450
15451 return fiber;
15452}
15453
15454function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
15455 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
15456
15457 // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
15458 // This needs to be fixed in getComponentName so that it relies on the tag
15459 // instead.
15460 fiber.type = REACT_SUSPENSE_TYPE;
15461 fiber.elementType = REACT_SUSPENSE_TYPE;
15462
15463 fiber.expirationTime = expirationTime;
15464 return fiber;
15465}
15466
15467function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) {
15468 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
15469 {
15470 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.
15471 // This needs to be fixed in getComponentName so that it relies on the tag
15472 // instead.
15473 fiber.type = REACT_SUSPENSE_LIST_TYPE;
15474 }
15475 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
15476 fiber.expirationTime = expirationTime;
15477 return fiber;
15478}
15479
15480function createFiberFromText(content, mode, expirationTime) {
15481 var fiber = createFiber(HostText, content, null, mode);
15482 fiber.expirationTime = expirationTime;
15483 return fiber;
15484}
15485
15486function createFiberFromHostInstanceForDeletion() {
15487 var fiber = createFiber(HostComponent, null, null, NoMode);
15488 // TODO: These should not need a type.
15489 fiber.elementType = 'DELETED';
15490 fiber.type = 'DELETED';
15491 return fiber;
15492}
15493
15494function createFiberFromPortal(portal, mode, expirationTime) {
15495 var pendingProps = portal.children !== null ? portal.children : [];
15496 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
15497 fiber.expirationTime = expirationTime;
15498 fiber.stateNode = {
15499 containerInfo: portal.containerInfo,
15500 pendingChildren: null, // Used by persistent updates
15501 implementation: portal.implementation
15502 };
15503 return fiber;
15504}
15505
15506// Used for stashing WIP properties to replay failed work in DEV.
15507function assignFiberPropertiesInDEV(target, source) {
15508 if (target === null) {
15509 // This Fiber's initial properties will always be overwritten.
15510 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
15511 target = createFiber(IndeterminateComponent, null, null, NoMode);
15512 }
15513
15514 // This is intentionally written as a list of all properties.
15515 // We tried to use Object.assign() instead but this is called in
15516 // the hottest path, and Object.assign() was too slow:
15517 // https://github.com/facebook/react/issues/12502
15518 // This code is DEV-only so size is not a concern.
15519
15520 target.tag = source.tag;
15521 target.key = source.key;
15522 target.elementType = source.elementType;
15523 target.type = source.type;
15524 target.stateNode = source.stateNode;
15525 target.return = source.return;
15526 target.child = source.child;
15527 target.sibling = source.sibling;
15528 target.index = source.index;
15529 target.ref = source.ref;
15530 target.pendingProps = source.pendingProps;
15531 target.memoizedProps = source.memoizedProps;
15532 target.updateQueue = source.updateQueue;
15533 target.memoizedState = source.memoizedState;
15534 target.dependencies = source.dependencies;
15535 target.mode = source.mode;
15536 target.effectTag = source.effectTag;
15537 target.nextEffect = source.nextEffect;
15538 target.firstEffect = source.firstEffect;
15539 target.lastEffect = source.lastEffect;
15540 target.expirationTime = source.expirationTime;
15541 target.childExpirationTime = source.childExpirationTime;
15542 target.alternate = source.alternate;
15543 if (enableProfilerTimer) {
15544 target.actualDuration = source.actualDuration;
15545 target.actualStartTime = source.actualStartTime;
15546 target.selfBaseDuration = source.selfBaseDuration;
15547 target.treeBaseDuration = source.treeBaseDuration;
15548 }
15549 target._debugID = source._debugID;
15550 target._debugSource = source._debugSource;
15551 target._debugOwner = source._debugOwner;
15552 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
15553 target._debugNeedsRemount = source._debugNeedsRemount;
15554 target._debugHookTypes = source._debugHookTypes;
15555 return target;
15556}
15557
15558// TODO: This should be lifted into the renderer.
15559
15560
15561// The following attributes are only used by interaction tracing builds.
15562// They enable interactions to be associated with their async work,
15563// And expose interaction metadata to the React DevTools Profiler plugin.
15564// Note that these attributes are only defined when the enableSchedulerTracing flag is enabled.
15565
15566
15567// Exported FiberRoot type includes all properties,
15568// To avoid requiring potentially error-prone :any casts throughout the project.
15569// Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true).
15570// The types are defined separately within this file to ensure they stay in sync.
15571// (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.)
15572
15573
15574function FiberRootNode(containerInfo, tag, hydrate) {
15575 this.tag = tag;
15576 this.current = null;
15577 this.containerInfo = containerInfo;
15578 this.pendingChildren = null;
15579 this.pingCache = null;
15580 this.finishedExpirationTime = NoWork;
15581 this.finishedWork = null;
15582 this.timeoutHandle = noTimeout;
15583 this.context = null;
15584 this.pendingContext = null;
15585 this.hydrate = hydrate;
15586 this.firstBatch = null;
15587 this.callbackNode = null;
15588 this.callbackExpirationTime = NoWork;
15589 this.firstPendingTime = NoWork;
15590 this.lastPendingTime = NoWork;
15591 this.pingTime = NoWork;
15592
15593 if (enableSchedulerTracing) {
15594 this.interactionThreadID = unstable_getThreadID();
15595 this.memoizedInteractions = new Set();
15596 this.pendingInteractionMap = new Map();
15597 }
15598}
15599
15600function createFiberRoot(containerInfo, tag, hydrate) {
15601 var root = new FiberRootNode(containerInfo, tag, hydrate);
15602
15603 // Cyclic construction. This cheats the type system right now because
15604 // stateNode is any.
15605 var uninitializedFiber = createHostRootFiber(tag);
15606 root.current = uninitializedFiber;
15607 uninitializedFiber.stateNode = root;
15608
15609 return root;
15610}
15611
15612// This lets us hook into Fiber to debug what it's doing.
15613// See https://github.com/facebook/react/pull/8033.
15614// This is not part of the public API, not even for React DevTools.
15615// You may only inject a debugTool if you work on React Fiber itself.
15616var ReactFiberInstrumentation = {
15617 debugTool: null
15618};
15619
15620var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
15621
15622// 0 is PROD, 1 is DEV.
15623// Might add PROFILE later.
15624
15625
15626var didWarnAboutNestedUpdates = void 0;
15627{
15628 didWarnAboutNestedUpdates = false;
15629
15630}
15631
15632function getContextForSubtree(parentComponent) {
15633 if (!parentComponent) {
15634 return emptyContextObject;
15635 }
15636
15637 var fiber = get(parentComponent);
15638 var parentContext = findCurrentUnmaskedContext(fiber);
15639
15640 if (fiber.tag === ClassComponent) {
15641 var Component = fiber.type;
15642 if (isContextProvider(Component)) {
15643 return processChildContext(fiber, Component, parentContext);
15644 }
15645 }
15646
15647 return parentContext;
15648}
15649
15650function scheduleRootUpdate(current$$1, element, expirationTime, suspenseConfig, callback) {
15651 {
15652 if (phase === 'render' && current$1 !== null && !didWarnAboutNestedUpdates) {
15653 didWarnAboutNestedUpdates = true;
15654 warningWithoutStack$1(false, 'Render methods should be a pure function of props and state; ' + 'triggering nested component updates from render is not allowed. ' + 'If necessary, trigger nested updates in componentDidUpdate.\n\n' + 'Check the render method of %s.', getComponentName(current$1.type) || 'Unknown');
15655 }
15656 }
15657
15658 var update = createUpdate(expirationTime, suspenseConfig);
15659 // Caution: React DevTools currently depends on this property
15660 // being called "element".
15661 update.payload = { element: element };
15662
15663 callback = callback === undefined ? null : callback;
15664 if (callback !== null) {
15665 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
15666 update.callback = callback;
15667 }
15668
15669 if (revertPassiveEffectsChange) {
15670 flushPassiveEffects();
15671 }
15672 enqueueUpdate(current$$1, update);
15673 scheduleWork(current$$1, expirationTime);
15674
15675 return expirationTime;
15676}
15677
15678function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, suspenseConfig, callback) {
15679 // TODO: If this is a nested container, this won't be the root.
15680 var current$$1 = container.current;
15681
15682 {
15683 if (ReactFiberInstrumentation_1.debugTool) {
15684 if (current$$1.alternate === null) {
15685 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
15686 } else if (element === null) {
15687 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
15688 } else {
15689 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
15690 }
15691 }
15692 }
15693
15694 var context = getContextForSubtree(parentComponent);
15695 if (container.context === null) {
15696 container.context = context;
15697 } else {
15698 container.pendingContext = context;
15699 }
15700
15701 return scheduleRootUpdate(current$$1, element, expirationTime, suspenseConfig, callback);
15702}
15703
15704function createContainer(containerInfo, tag, hydrate) {
15705 return createFiberRoot(containerInfo, tag, hydrate);
15706}
15707
15708function updateContainer(element, container, parentComponent, callback) {
15709 var current$$1 = container.current;
15710 var currentTime = requestCurrentTime();
15711 {
15712 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
15713 if ('undefined' !== typeof jest) {
15714 warnIfUnmockedScheduler(current$$1);
15715 warnIfNotScopedWithMatchingAct(current$$1);
15716 }
15717 }
15718 var suspenseConfig = requestCurrentSuspenseConfig();
15719 var expirationTime = computeExpirationForFiber(currentTime, current$$1, suspenseConfig);
15720 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, suspenseConfig, callback);
15721}
15722
15723
15724
15725
15726
15727var shouldSuspendImpl = function (fiber) {
15728 return false;
15729};
15730
15731function shouldSuspend(fiber) {
15732 return shouldSuspendImpl(fiber);
15733}
15734
15735var overrideHookState = null;
15736var overrideProps = null;
15737var scheduleUpdate = null;
15738var setSuspenseHandler = null;
15739
15740{
15741 var copyWithSetImpl = function (obj, path, idx, value) {
15742 if (idx >= path.length) {
15743 return value;
15744 }
15745 var key = path[idx];
15746 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
15747 // $FlowFixMe number or string is fine here
15748 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
15749 return updated;
15750 };
15751
15752 var copyWithSet = function (obj, path, value) {
15753 return copyWithSetImpl(obj, path, 0, value);
15754 };
15755
15756 // Support DevTools editable values for useState and useReducer.
15757 overrideHookState = function (fiber, id, path, value) {
15758 // For now, the "id" of stateful hooks is just the stateful hook index.
15759 // This may change in the future with e.g. nested hooks.
15760 var currentHook = fiber.memoizedState;
15761 while (currentHook !== null && id > 0) {
15762 currentHook = currentHook.next;
15763 id--;
15764 }
15765 if (currentHook !== null) {
15766 if (revertPassiveEffectsChange) {
15767 flushPassiveEffects();
15768 }
15769
15770 var newState = copyWithSet(currentHook.memoizedState, path, value);
15771 currentHook.memoizedState = newState;
15772 currentHook.baseState = newState;
15773
15774 // We aren't actually adding an update to the queue,
15775 // because there is no update we can add for useReducer hooks that won't trigger an error.
15776 // (There's no appropriate action type for DevTools overrides.)
15777 // As a result though, React will see the scheduled update as a noop and bailout.
15778 // Shallow cloning props works as a workaround for now to bypass the bailout check.
15779 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
15780
15781 scheduleWork(fiber, Sync);
15782 }
15783 };
15784
15785 // Support DevTools props for function components, forwardRef, memo, host components, etc.
15786 overrideProps = function (fiber, path, value) {
15787 if (revertPassiveEffectsChange) {
15788 flushPassiveEffects();
15789 }
15790 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
15791 if (fiber.alternate) {
15792 fiber.alternate.pendingProps = fiber.pendingProps;
15793 }
15794 scheduleWork(fiber, Sync);
15795 };
15796
15797 scheduleUpdate = function (fiber) {
15798 if (revertPassiveEffectsChange) {
15799 flushPassiveEffects();
15800 }
15801 scheduleWork(fiber, Sync);
15802 };
15803
15804 setSuspenseHandler = function (newShouldSuspendImpl) {
15805 shouldSuspendImpl = newShouldSuspendImpl;
15806 };
15807}
15808
15809function injectIntoDevTools(devToolsConfig) {
15810 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
15811 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
15812
15813
15814 return injectInternals(_assign({}, devToolsConfig, {
15815 overrideHookState: overrideHookState,
15816 overrideProps: overrideProps,
15817 setSuspenseHandler: setSuspenseHandler,
15818 scheduleUpdate: scheduleUpdate,
15819 currentDispatcherRef: ReactCurrentDispatcher,
15820 findHostInstanceByFiber: function (fiber) {
15821 var hostFiber = findCurrentHostFiber(fiber);
15822 if (hostFiber === null) {
15823 return null;
15824 }
15825 return hostFiber.stateNode;
15826 },
15827 findFiberByHostInstance: function (instance) {
15828 if (!findFiberByHostInstance) {
15829 // Might not be implemented by the renderer.
15830 return null;
15831 }
15832 return findFiberByHostInstance(instance);
15833 },
15834
15835 // React Refresh
15836 findHostInstancesForRefresh: findHostInstancesForRefresh,
15837 scheduleRefresh: scheduleRefresh,
15838 scheduleRoot: scheduleRoot,
15839 setRefreshHandler: setRefreshHandler,
15840 // Enables DevTools to append owner stacks to error messages in DEV mode.
15841 getCurrentFiber: function () {
15842 return current$1;
15843 }
15844 }));
15845}
15846
15847// This file intentionally does *not* have the Flow annotation.
15848// Don't add it. See `./inline-typed.js` for an explanation.
15849
15850var container = _class({
15851
15852 grab: function(){
15853 for (var i = 0; i < arguments.length; i++) arguments[i].inject(this);
15854 return this;
15855 },
15856
15857 empty: function(){
15858 var node;
15859 while (node = this.firstChild) node.eject();
15860 return this;
15861 }
15862
15863});
15864
15865function elementFrom(node){
15866 if (node.toElement) return node.toElement();
15867 if (node.getDOMNode) return node.getDOMNode();
15868 if (node.getNode) return node.getNode();
15869 return node;
15870}
15871
15872var native_1 = _class({
15873
15874 // conventions
15875
15876 toElement: function(){
15877 return this.element;
15878 },
15879
15880 getDOMNode: function(){
15881 return this.toElement();
15882 },
15883
15884 getNode: function(){
15885 return this.toElement();
15886 },
15887
15888 // placement
15889
15890 inject: function(container){
15891 (container.containerElement || elementFrom(container))
15892 .appendChild(this.element);
15893 return this;
15894 },
15895
15896 injectBefore: function(sibling){
15897 var element = elementFrom(sibling);
15898 element.parentNode.insertBefore(this.element, element);
15899 return this;
15900 },
15901
15902 eject: function(){
15903 var element = this.element, parent = element.parentNode;
15904 if (parent) parent.removeChild(element); // TODO: VML Nodes are dead after being ejected
15905 return this;
15906 },
15907
15908 // events
15909
15910 subscribe: function(type, fn, bind){
15911 if (typeof type != 'string'){ // listen type / fn with object
15912 var subscriptions = [];
15913 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
15914 return function(){ // unsubscribe
15915 for (var i = 0, l = subscriptions.length; i < l; i++)
15916 subscriptions[i]();
15917 return this;
15918 };
15919 } else { // listen to one
15920 if (!bind) bind = this;
15921 var bound;
15922 if (typeof fn === 'function'){
15923 bound = fn.bind ? fn.bind(bind)
15924 : function(){ return fn.apply(bind, arguments); };
15925 } else {
15926 bound = fn;
15927 }
15928 var element = this.element;
15929 if (element.addEventListener){
15930 element.addEventListener(type, bound, false);
15931 return function(){ // unsubscribe
15932 element.removeEventListener(type, bound, false);
15933 return this;
15934 };
15935 } else {
15936 element.attachEvent('on' + type, bound);
15937 return function(){ // unsubscribe
15938 element.detachEvent('on' + type, bound);
15939 return this;
15940 };
15941 }
15942 }
15943 }
15944
15945});
15946
15947var fps = 1000 / 60;
15948var invalids = [];
15949var renderTimer;
15950var renderInvalids = function(){
15951 clearTimeout(renderTimer);
15952 renderTimer = null;
15953 var canvases = invalids;
15954 invalids = [];
15955 for (var i = 0, l = canvases.length; i < l; i++){
15956 var c = canvases[i];
15957 c._valid = true;
15958 c.render();
15959 }
15960};
15961
15962var resolution = typeof window !== 'undefined' && window.devicePixelRatio || 1;
15963
15964var previousHit = null;
15965var previousHitSurface = null;
15966
15967var CanvasSurface = _class(native_1, container, {
15968
15969 initialize: function(width, height, existingElement){
15970 var element = this.element = existingElement || document.createElement('canvas');
15971 var context = this.context = element.getContext('2d');
15972 this._valid = true;
15973 if (width != null && height != null) this.resize(width, height);
15974
15975 element.addEventListener('mousemove', this, false);
15976 element.addEventListener('mouseout', this, false);
15977 element.addEventListener('mouseover', this, false);
15978 element.addEventListener('mouseup', this, false);
15979 element.addEventListener('mousedown', this, false);
15980 element.addEventListener('click', this, false);
15981 },
15982
15983 handleEvent: function(event){
15984 if (event.clientX == null) return;
15985 var element = this.element,
15986 rect = element.getBoundingClientRect(),
15987 x = event.clientX - rect.left - element.clientLeft,
15988 y = event.clientY - rect.top - element.clientTop,
15989 hit = this.hitTest(x, y);
15990
15991 if (hit !== previousHit){
15992 if (previousHit){
15993 previousHit.dispatch({
15994 type: 'mouseout',
15995 target: previousHit,
15996 relatedTarget: hit,
15997 sourceEvent: event
15998 });
15999 }
16000 if (hit){
16001 hit.dispatch({
16002 type: 'mouseover',
16003 target: hit,
16004 relatedTarget: previousHit,
16005 sourceEvent: event
16006 });
16007 }
16008 previousHit = hit;
16009 previousHitSurface = this;
16010 this.refreshCursor();
16011 }
16012
16013 if (hit) hit.dispatch(event);
16014 },
16015
16016 refreshCursor: function(){
16017 if (previousHitSurface !== this) return;
16018 var hit = previousHit, hitCursor = '', hitTooltip = '';
16019 while (hit){
16020 if (!hitCursor && hit._cursor){
16021 hitCursor = hit._cursor;
16022 if (hitTooltip) break;
16023 }
16024 if (!hitTooltip && hit._tooltip){
16025 hitTooltip = hit._tooltip;
16026 if (hitCursor) break;
16027 }
16028 hit = hit.parentNode;
16029 }
16030 // TODO: No way to set cursor/title on the surface
16031 this.element.style.cursor = hitCursor;
16032 this.element.title = hitTooltip;
16033 },
16034
16035 resize: function(width, height){
16036 var element = this.element;
16037 element.setAttribute('width', width * resolution);
16038 element.setAttribute('height', height * resolution);
16039 element.style.width = width + 'px';
16040 element.style.height = height + 'px';
16041 this.width = width;
16042 this.height = height;
16043 return this;
16044 },
16045
16046 invalidate: function(left, top, width, height){
16047 if (this._valid){
16048 this._valid = false;
16049 invalids.push(this);
16050 if (!renderTimer){
16051 if (window.mozRequestAnimationFrame){
16052 renderTimer = true;
16053 window.mozRequestAnimationFrame(renderInvalids);
16054 } else {
16055 renderTimer = setTimeout(renderInvalids, fps);
16056 }
16057 }
16058 }
16059 return this;
16060 },
16061
16062 hitTest: function(x, y){
16063 if (x < 0 || y < 0 || x > this.width || y > this.height) return null;
16064 var node = this.lastChild;
16065 while (node){
16066 var hit = node.hitTest(x, y);
16067 if (hit) return hit;
16068 node = node.previousSibling;
16069 }
16070 return null;
16071 },
16072
16073 render: function(){
16074 var node = this.firstChild, context = this.context;
16075 context.setTransform(resolution, 0, 0, resolution, 0, 0);
16076 context.clearRect(0, 0, this.width, this.height);
16077 while (node){
16078 node.renderTo(context, resolution, 0, 0, resolution, 0, 0);
16079 node = node.nextSibling;
16080 }
16081 this.refreshCursor();
16082 }
16083
16084});
16085
16086CanvasSurface.tagName = 'canvas';
16087
16088var surface = CanvasSurface;
16089
16090var path$2 = _class({
16091
16092 initialize: function(path){
16093 this.reset().push(path);
16094 },
16095
16096 /* parser */
16097
16098 push: function(){
16099 var p = Array.prototype.join.call(arguments, ' ')
16100 .match(/[a-df-z]|[\-+]?(?:[\d\.]e[\-+]?|[^\s\-+,a-z])+/ig);
16101 if (!p) return this;
16102
16103 var last, cmd = p[0], i = 1;
16104 while (cmd){
16105 switch (cmd){
16106 case 'm': this.move(p[i++], p[i++]); break;
16107 case 'l': this.line(p[i++], p[i++]); break;
16108 case 'c': this.curve(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
16109 case 's': this.curve(p[i++], p[i++], null, null, p[i++], p[i++]); break;
16110 case 'q': this.curve(p[i++], p[i++], p[i++], p[i++]); break;
16111 case 't': this.curve(p[i++], p[i++]); break;
16112 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;
16113 case 'h': this.line(p[i++], 0); break;
16114 case 'v': this.line(0, p[i++]); break;
16115
16116 case 'M': this.moveTo(p[i++], p[i++]); break;
16117 case 'L': this.lineTo(p[i++], p[i++]); break;
16118 case 'C': this.curveTo(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
16119 case 'S': this.curveTo(p[i++], p[i++], null, null, p[i++], p[i++]); break;
16120 case 'Q': this.curveTo(p[i++], p[i++], p[i++], p[i++]); break;
16121 case 'T': this.curveTo(p[i++], p[i++]); break;
16122 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;
16123 case 'H': this.lineTo(p[i++], this.penY); break;
16124 case 'V': this.lineTo(this.penX, p[i++]); break;
16125
16126 case 'Z': case 'z': this.close(); break;
16127 default: cmd = last; i--; continue;
16128 }
16129
16130 last = cmd;
16131 if (last == 'm') last = 'l';
16132 else if (last == 'M') last = 'L';
16133 cmd = p[i++];
16134 }
16135 return this;
16136 },
16137
16138 /* utility methods */
16139
16140 reset: function(){
16141 this.penX = this.penY = 0;
16142 this.penDownX = this.penDownY = null;
16143 this._pivotX = this._pivotY = 0;
16144 this.onReset();
16145 return this;
16146 },
16147
16148 move: function(x,y){
16149 this.onMove(this.penX, this.penY, this._pivotX = this.penX += (+x), this._pivotY = this.penY += (+y));
16150 return this;
16151 },
16152 moveTo: function(x,y){
16153 this.onMove(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
16154 return this;
16155 },
16156
16157 line: function(x,y){
16158 return this.lineTo(this.penX + (+x), this.penY + (+y));
16159 },
16160 lineTo: function(x,y){
16161 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
16162 this.onLine(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
16163 return this;
16164 },
16165
16166 curve: function(c1x, c1y, c2x, c2y, ex, ey){
16167 var x = this.penX, y = this.penY;
16168 return this.curveTo(
16169 x + (+c1x), y + (+c1y),
16170 c2x == null ? null : x + (+c2x),
16171 c2y == null ? null : y + (+c2y),
16172 ex == null ? null : x + (+ex),
16173 ey == null ? null : y + (+ey)
16174 );
16175 },
16176 curveTo: function(c1x, c1y, c2x, c2y, ex, ey){
16177 var x = this.penX, y = this.penY;
16178 if (c2x == null){
16179 c2x = +c1x; c2y = +c1y;
16180 c1x = (x * 2) - (this._pivotX || 0); c1y = (y * 2) - (this._pivotY || 0);
16181 }
16182 if (ex == null){
16183 this._pivotX = +c1x; this._pivotY = +c1y;
16184 ex = +c2x; ey = +c2y;
16185 c2x = (ex + (+c1x) * 2) / 3; c2y = (ey + (+c1y) * 2) / 3;
16186 c1x = (x + (+c1x) * 2) / 3; c1y = (y + (+c1y) * 2) / 3;
16187 } else {
16188 this._pivotX = +c2x; this._pivotY = +c2y;
16189 }
16190 if (this.penDownX == null){ this.penDownX = x; this.penDownY = y; }
16191 this.onBezierCurve(x, y, +c1x, +c1y, +c2x, +c2y, this.penX = +ex, this.penY = +ey);
16192 return this;
16193 },
16194
16195 arc: function(x, y, rx, ry, outer, counterClockwise, rotation){
16196 return this.arcTo(this.penX + (+x), this.penY + (+y), rx, ry, outer, counterClockwise, rotation);
16197 },
16198 arcTo: function(x, y, rx, ry, outer, counterClockwise, rotation){
16199 ry = Math.abs(+ry || +rx || (+y - this.penY));
16200 rx = Math.abs(+rx || (+x - this.penX));
16201
16202 if (!rx || !ry || (x == this.penX && y == this.penY)) return this.lineTo(x, y);
16203
16204 var tX = this.penX, tY = this.penY, clockwise = !+counterClockwise, large = !!+outer;
16205
16206 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad);
16207 x -= tX; y -= tY;
16208
16209 // Ellipse Center
16210 var cx = cos * x / 2 + sin * y / 2,
16211 cy = -sin * x / 2 + cos * y / 2,
16212 rxry = rx * rx * ry * ry,
16213 rycx = ry * ry * cx * cx,
16214 rxcy = rx * rx * cy * cy,
16215 a = rxry - rxcy - rycx;
16216
16217 if (a < 0){
16218 a = Math.sqrt(1 - a / rxry);
16219 rx *= a; ry *= a;
16220 cx = x / 2; cy = y / 2;
16221 } else {
16222 a = Math.sqrt(a / (rxcy + rycx));
16223 if (large == clockwise) a = -a;
16224 var cxd = -a * cy * rx / ry,
16225 cyd = a * cx * ry / rx;
16226 cx = cos * cxd - sin * cyd + x / 2;
16227 cy = sin * cxd + cos * cyd + y / 2;
16228 }
16229
16230 // Rotation + Scale Transform
16231 var xx = cos / rx, yx = sin / rx,
16232 xy = -sin / ry, yy = cos / ry;
16233
16234 // Start and End Angle
16235 var sa = Math.atan2(xy * -cx + yy * -cy, xx * -cx + yx * -cy),
16236 ea = Math.atan2(xy * (x - cx) + yy * (y - cy), xx * (x - cx) + yx * (y - cy));
16237
16238 cx += tX; cy += tY;
16239 x += tX; y += tY;
16240
16241 // Circular Arc
16242 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
16243 this.onArc(
16244 tX, tY, this._pivotX = this.penX = x, this._pivotY = this.penY = y,
16245 cx, cy, rx, ry, sa, ea, !clockwise, rotation
16246 );
16247 return this;
16248 },
16249
16250 counterArc: function(x, y, rx, ry, outer){
16251 return this.arc(x, y, rx, ry, outer, true);
16252 },
16253 counterArcTo: function(x, y, rx, ry, outer){
16254 return this.arcTo(x, y, rx, ry, outer, true);
16255 },
16256
16257 close: function(){
16258 if (this.penDownX != null){
16259 this.onClose(this.penX, this.penY, this.penX = this.penDownX, this.penY = this.penDownY);
16260 this.penDownX = null;
16261 }
16262 return this;
16263 },
16264
16265 /* overridable handlers */
16266
16267 onReset: function(){
16268 },
16269
16270 onMove: function(sx, sy, ex, ey){
16271 },
16272
16273 onLine: function(sx, sy, ex, ey){
16274 this.onBezierCurve(sx, sy, sx, sy, ex, ey, ex, ey);
16275 },
16276
16277 onBezierCurve: function(sx, sy, c1x, c1y, c2x, c2y, ex, ey){
16278 var gx = ex - sx, gy = ey - sy,
16279 g = gx * gx + gy * gy,
16280 v1, v2, cx, cy, u;
16281
16282 cx = c1x - sx; cy = c1y - sy;
16283 u = cx * gx + cy * gy;
16284
16285 if (u > g){
16286 cx -= gx;
16287 cy -= gy;
16288 } else if (u > 0 && g != 0){
16289 cx -= u/g * gx;
16290 cy -= u/g * gy;
16291 }
16292
16293 v1 = cx * cx + cy * cy;
16294
16295 cx = c2x - sx; cy = c2y - sy;
16296 u = cx * gx + cy * gy;
16297
16298 if (u > g){
16299 cx -= gx;
16300 cy -= gy;
16301 } else if (u > 0 && g != 0){
16302 cx -= u/g * gx;
16303 cy -= u/g * gy;
16304 }
16305
16306 v2 = cx * cx + cy * cy;
16307
16308 if (v1 < 0.01 && v2 < 0.01){
16309 this.onLine(sx, sy, ex, ey);
16310 return;
16311 }
16312
16313 // Avoid infinite recursion
16314 if (isNaN(v1) || isNaN(v2)){
16315 throw new Error('Bad input');
16316 }
16317
16318 // Split curve
16319 var s1x = (c1x + c2x) * 0.5, s1y = (c1y + c2y) * 0.5,
16320 l1x = (c1x + sx) * 0.5, l1y = (c1y + sy) * 0.5,
16321 l2x = (l1x + s1x) * 0.5, l2y = (l1y + s1y) * 0.5,
16322 r2x = (ex + c2x) * 0.5, r2y = (ey + c2y) * 0.5,
16323 r1x = (r2x + s1x) * 0.5, r1y = (r2y + s1y) * 0.5,
16324 l2r1x = (l2x + r1x) * 0.5, l2r1y = (l2y + r1y) * 0.5;
16325
16326 // TODO: Manual stack if necessary. Currently recursive without tail optimization.
16327 this.onBezierCurve(sx, sy, l1x, l1y, l2x, l2y, l2r1x, l2r1y);
16328 this.onBezierCurve(l2r1x, l2r1y, r1x, r1y, r2x, r2y, ex, ey);
16329 },
16330
16331 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
16332 // Inverse Rotation + Scale Transform
16333 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad),
16334 xx = cos * rx, yx = -sin * ry,
16335 xy = sin * rx, yy = cos * ry;
16336
16337 // Bezier Curve Approximation
16338 var arc = ea - sa;
16339 if (arc < 0 && !ccw) arc += Math.PI * 2;
16340 else if (arc > 0 && ccw) arc -= Math.PI * 2;
16341
16342 var n = Math.ceil(Math.abs(arc / (Math.PI / 2))),
16343 step = arc / n,
16344 k = (4 / 3) * Math.tan(step / 4);
16345
16346 var x = Math.cos(sa), y = Math.sin(sa);
16347
16348 for (var i = 0; i < n; i++){
16349 var cp1x = x - k * y, cp1y = y + k * x;
16350
16351 sa += step;
16352 x = Math.cos(sa); y = Math.sin(sa);
16353
16354 var cp2x = x + k * y, cp2y = y - k * x;
16355
16356 this.onBezierCurve(
16357 sx, sy,
16358 cx + xx * cp1x + yx * cp1y, cy + xy * cp1x + yy * cp1y,
16359 cx + xx * cp2x + yx * cp2y, cy + xy * cp2x + yy * cp2y,
16360 (sx = (cx + xx * x + yx * y)), (sy = (cy + xy * x + yy * y))
16361 );
16362 }
16363 },
16364
16365 onClose: function(sx, sy, ex, ey){
16366 this.onLine(sx, sy, ex, ey);
16367 }
16368
16369});
16370
16371var CanvasPath = _class(path$2, {
16372
16373 initialize: function(path){
16374 this.reset();
16375 if (path instanceof CanvasPath){
16376 this.path = path.path.slice(0);
16377 } else if (path){
16378 if (path.applyToPath)
16379 path.applyToPath(this);
16380 else
16381 this.push(path);
16382 }
16383 },
16384
16385 onReset: function(){
16386 this.path = [];
16387 },
16388
16389 onMove: function(sx, sy, x, y){
16390 this.path.push(function(context){
16391 context.moveTo(x, y);
16392 });
16393 },
16394
16395 onLine: function(sx, sy, x, y){
16396 this.path.push(function(context){
16397 context.lineTo(x, y);
16398 });
16399 },
16400
16401 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
16402 this.path.push(function(context){
16403 context.bezierCurveTo(p1x, p1y, p2x, p2y, x, y);
16404 });
16405 },
16406
16407 _arcToBezier: path$2.prototype.onArc,
16408
16409 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
16410 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
16411 this.path.push(function(context){
16412 context.arc(cx, cy, rx, sa, ea, ccw);
16413 });
16414 },
16415
16416 onClose: function(){
16417 this.path.push(function(context){
16418 context.closePath();
16419 });
16420 },
16421
16422 toCommands: function(){
16423 return this.path.slice(0);
16424 }
16425
16426});
16427
16428var path = CanvasPath;
16429
16430var colors = {
16431 maroon: '#800000', red: '#ff0000', orange: '#ffA500', yellow: '#ffff00', olive: '#808000',
16432 purple: '#800080', fuchsia: "#ff00ff", white: '#ffffff', lime: '#00ff00', green: '#008000',
16433 navy: '#000080', blue: '#0000ff', aqua: '#00ffff', teal: '#008080',
16434 black: '#000000', silver: '#c0c0c0', gray: '#808080'
16435};
16436
16437var map = function(array, fn){
16438 var results = [];
16439 for (var i = 0, l = array.length; i < l; i++)
16440 results[i] = fn(array[i], i);
16441 return results;
16442};
16443
16444var Color = function(color, type){
16445
16446 if (color.isColor){
16447
16448 this.red = color.red;
16449 this.green = color.green;
16450 this.blue = color.blue;
16451 this.alpha = color.alpha;
16452
16453 } else {
16454
16455 var namedColor = colors[color];
16456 if (namedColor){
16457 color = namedColor;
16458 type = 'hex';
16459 }
16460
16461 switch (typeof color){
16462 case 'string': if (!type) type = (type = color.match(/^rgb|^hsb|^hsl/)) ? type[0] : 'hex'; break;
16463 case 'object': type = type || 'rgb'; color = color.toString(); break;
16464 case 'number': type = 'hex'; color = color.toString(16); break;
16465 }
16466
16467 color = Color['parse' + type.toUpperCase()](color);
16468 this.red = color[0];
16469 this.green = color[1];
16470 this.blue = color[2];
16471 this.alpha = color[3];
16472 }
16473
16474 this.isColor = true;
16475
16476};
16477
16478var limit = function(number, min, max){
16479 return Math.min(max, Math.max(min, number));
16480};
16481
16482var listMatch = /([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,?\s*([-.\d]*\%?)/;
16483var hexMatch = /^#?([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{0,2})$/i;
16484
16485Color.parseRGB = function(color){
16486 return map(color.match(listMatch).slice(1), function(bit, i){
16487 if (bit) bit = parseFloat(bit) * (bit[bit.length - 1] == '%' ? 2.55 : 1);
16488 return (i < 3) ? Math.round(((bit %= 256) < 0) ? bit + 256 : bit) : limit(((bit === '') ? 1 : Number(bit)), 0, 1);
16489 });
16490};
16491
16492Color.parseHEX = function(color){
16493 if (color.length == 1) color = color + color + color;
16494 return map(color.match(hexMatch).slice(1), function(bit, i){
16495 if (i == 3) return (bit) ? parseInt(bit, 16) / 255 : 1;
16496 return parseInt((bit.length == 1) ? bit + bit : bit, 16);
16497 });
16498};
16499
16500Color.parseHSB = function(color){
16501 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
16502 if (bit) bit = parseFloat(bit);
16503 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
16504 else if (i < 3) return limit(Math.round(bit), 0, 100);
16505 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
16506 });
16507
16508 var a = hsb[3];
16509 var br = Math.round(hsb[2] / 100 * 255);
16510 if (hsb[1] == 0) return [br, br, br, a];
16511
16512 var hue = hsb[0];
16513 var f = hue % 60;
16514 var p = Math.round((hsb[2] * (100 - hsb[1])) / 10000 * 255);
16515 var q = Math.round((hsb[2] * (6000 - hsb[1] * f)) / 600000 * 255);
16516 var t = Math.round((hsb[2] * (6000 - hsb[1] * (60 - f))) / 600000 * 255);
16517
16518 switch (Math.floor(hue / 60)){
16519 case 0: return [br, t, p, a];
16520 case 1: return [q, br, p, a];
16521 case 2: return [p, br, t, a];
16522 case 3: return [p, q, br, a];
16523 case 4: return [t, p, br, a];
16524 default: return [br, p, q, a];
16525 }
16526};
16527
16528Color.parseHSL = function(color){
16529 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
16530 if (bit) bit = parseFloat(bit);
16531 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
16532 else if (i < 3) return limit(Math.round(bit), 0, 100);
16533 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
16534 });
16535
16536 var h = hsb[0] / 60;
16537 var s = hsb[1] / 100;
16538 var l = hsb[2] / 100;
16539 var a = hsb[3];
16540
16541 var c = (1 - Math.abs(2 * l - 1)) * s;
16542 var x = c * (1 - Math.abs(h % 2 - 1));
16543 var m = l - c / 2;
16544
16545 var p = Math.round((c + m) * 255);
16546 var q = Math.round((x + m) * 255);
16547 var t = Math.round((m) * 255);
16548
16549 switch (Math.floor(h)){
16550 case 0: return [p, q, t, a];
16551 case 1: return [q, p, t, a];
16552 case 2: return [t, p, q, a];
16553 case 3: return [t, q, p, a];
16554 case 4: return [q, t, p, a];
16555 default: return [p, t, q, a];
16556 }
16557};
16558
16559var toString = function(type, array){
16560 if (array[3] != 1) type += 'a';
16561 else array.pop();
16562 return type + '(' + array.join(', ') + ')';
16563};
16564
16565Color.prototype = {
16566
16567 toHSB: function(array){
16568 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
16569
16570 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
16571 var hue = 0, saturation = (delta != 0) ? delta / max : 0, brightness = max / 255;
16572 if (saturation){
16573 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
16574 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
16575 if ((hue /= 6) < 0) hue++;
16576 }
16577
16578 var hsb = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100), alpha];
16579
16580 return (array) ? hsb : toString('hsb', hsb);
16581 },
16582
16583 toHSL: function(array){
16584 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
16585
16586 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
16587 var hue = 0, saturation = (delta != 0) ? delta / (255 - Math.abs((max + min) - 255)) : 0, lightness = (max + min) / 512;
16588 if (saturation){
16589 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
16590 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
16591 if ((hue /= 6) < 0) hue++;
16592 }
16593
16594 var hsl = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(lightness * 100), alpha];
16595
16596 return (array) ? hsl : toString('hsl', hsl);
16597 },
16598
16599 toHEX: function(array){
16600
16601 var a = this.alpha;
16602 var alpha = ((a = Math.round((a * 255)).toString(16)).length == 1) ? a + a : a;
16603
16604 var hex = map([this.red, this.green, this.blue], function(bit){
16605 bit = bit.toString(16);
16606 return (bit.length == 1) ? '0' + bit : bit;
16607 });
16608
16609 return (array) ? hex.concat(alpha) : '#' + hex.join('') + ((alpha == 'ff') ? '' : alpha);
16610 },
16611
16612 toRGB: function(array){
16613 var rgb = [this.red, this.green, this.blue, this.alpha];
16614 return (array) ? rgb : toString('rgb', rgb);
16615 }
16616
16617};
16618
16619Color.prototype.toString = Color.prototype.toRGB;
16620
16621Color.hex = function(hex){
16622 return new Color(hex, 'hex');
16623};
16624
16625if (commonjsGlobal.hex == null) commonjsGlobal.hex = Color.hex;
16626
16627Color.hsb = function(h, s, b, a){
16628 return new Color([h || 0, s || 0, b || 0, (a == null) ? 1 : a], 'hsb');
16629};
16630
16631if (commonjsGlobal.hsb == null) commonjsGlobal.hsb = Color.hsb;
16632
16633Color.hsl = function(h, s, l, a){
16634 return new Color([h || 0, s || 0, l || 0, (a == null) ? 1 : a], 'hsl');
16635};
16636
16637if (commonjsGlobal.hsl == null) commonjsGlobal.hsl = Color.hsl;
16638
16639Color.rgb = function(r, g, b, a){
16640 return new Color([r || 0, g || 0, b || 0, (a == null) ? 1 : a], 'rgb');
16641};
16642
16643if (commonjsGlobal.rgb == null) commonjsGlobal.rgb = Color.rgb;
16644
16645Color.detach = function(color){
16646 color = new Color(color);
16647 return [Color.rgb(color.red, color.green, color.blue).toString(), color.alpha];
16648};
16649
16650var color = Color;
16651
16652var dummy = _class({
16653
16654 // placement
16655
16656 _resetPlacement: function(){
16657 var container = this.parentNode;
16658 if (container){
16659 var previous = this.previousSibling, next = this.nextSibling;
16660 if (previous){
16661 previous.nextSibling = next;
16662 } else {
16663 container.firstChild = next;
16664 }
16665 if (next){
16666 next.previousSibling = previous;
16667 } else {
16668 container.lastChild = this.previousSibling;
16669 }
16670 }
16671 this.previousSibling = null;
16672 this.nextSibling = null;
16673 this.parentNode = null;
16674 return this;
16675 },
16676
16677 inject: function(container){
16678 this._resetPlacement();
16679 var last = container.lastChild;
16680 if (last){
16681 last.nextSibling = this;
16682 this.previousSibling = last;
16683 } else {
16684 container.firstChild = this;
16685 }
16686 container.lastChild = this;
16687 this.parentNode = container;
16688 this._place();
16689 return this;
16690 },
16691
16692 injectBefore: function(sibling){
16693 this._resetPlacement();
16694 var container = sibling.parentNode;
16695 if (!container) return this;
16696 var previous = sibling.previousSibling;
16697 if (previous){
16698 previous.nextSibling = this;
16699 this.previousSibling = previous;
16700 } else {
16701 container.firstChild = this;
16702 }
16703 sibling.previousSibling = this;
16704 this.nextSibling = sibling;
16705 this.parentNode = container;
16706 this._place();
16707 return this;
16708 },
16709
16710 eject: function(){
16711 this._resetPlacement();
16712 this._place();
16713 return this;
16714 },
16715
16716 _place: function(){},
16717
16718 // events
16719
16720 dispatch: function(event){
16721 var events = this._events,
16722 listeners = events && events[event.type];
16723 if (listeners){
16724 listeners = listeners.slice(0);
16725 for (var i = 0, l = listeners.length; i < l; i++){
16726 var fn = listeners[i], result;
16727 if (typeof fn == 'function')
16728 result = fn.call(this, event);
16729 else
16730 result = fn.handleEvent(event);
16731 if (result === false) event.preventDefault();
16732 }
16733 }
16734 if (this.parentNode && this.parentNode.dispatch){
16735 this.parentNode.dispatch(event);
16736 }
16737 },
16738
16739 subscribe: function(type, fn, bind){
16740 if (typeof type != 'string'){ // listen type / fn with object
16741 var subscriptions = [];
16742 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
16743 return function(){ // unsubscribe
16744 for (var i = 0, l = subscriptions.length; i < l; i++)
16745 subscriptions[i]();
16746 return this;
16747 };
16748 } else { // listen to one
16749 var bound = typeof fn === 'function' ? fn.bind(bind || this) : fn,
16750 events = this._events || (this._events = {}),
16751 listeners = events[type] || (events[type] = []);
16752 listeners.push(bound);
16753 return function(){
16754 // unsubscribe
16755 for (var i = 0, l = listeners.length; i < l; i++){
16756 if (listeners[i] === bound){
16757 listeners.splice(i, 1);
16758 break;
16759 }
16760 }
16761 }
16762 }
16763 }
16764
16765});
16766
16767var CanvasNode = _class(transform, dummy, {
16768
16769 invalidate: function(){
16770 if (this.parentNode) this.parentNode.invalidate();
16771 if (this._layer) this._layerCache = null;
16772 return this;
16773 },
16774
16775 _place: function(){
16776 this.invalidate();
16777 },
16778
16779 _transform: function(){
16780 this.invalidate();
16781 },
16782
16783 blend: function(opacity){
16784 if (opacity >= 1 && this._layer) this._layer = null;
16785 this._opacity = opacity;
16786 if (this.parentNode) this.parentNode.invalidate();
16787 return this;
16788 },
16789
16790 // visibility
16791
16792 hide: function(){
16793 this._invisible = true;
16794 if (this.parentNode) this.parentNode.invalidate();
16795 return this;
16796 },
16797
16798 show: function(){
16799 this._invisible = false;
16800 if (this.parentNode) this.parentNode.invalidate();
16801 return this;
16802 },
16803
16804 // interaction
16805
16806 indicate: function(cursor, tooltip){
16807 this._cursor = cursor;
16808 this._tooltip = tooltip;
16809 return this.invalidate();
16810 },
16811
16812 hitTest: function(x, y){
16813 if (this._invisible) return null;
16814 var point = this.inversePoint(x, y);
16815 if (!point) return null;
16816 return this.localHitTest(point.x, point.y);
16817 },
16818
16819 // rendering
16820
16821 renderTo: function(context, xx, yx, xy, yy, x, y){
16822 var opacity = this._opacity;
16823 if (opacity == null || opacity >= 1){
16824 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
16825 }
16826
16827 // Render to a compositing layer and cache it
16828
16829 var layer = this._layer, canvas, isDirty = true,
16830 w = context.canvas.width, h = context.canvas.height;
16831 if (layer){
16832 layer.setTransform(1, 0, 0, 1, 0, 0);
16833 canvas = layer.canvas;
16834 if (canvas.width < w || canvas.height < h){
16835 canvas.width = w;
16836 canvas.height = h;
16837 } else {
16838 var c = this._layerCache;
16839 if (c && c.xx === xx && c.yx === yx && c.xy === xy
16840 && c.yy === yy && c.x === x && c.y === y){
16841 isDirty = false;
16842 } else {
16843 layer.clearRect(0, 0, w, h);
16844 }
16845 }
16846 } else {
16847 canvas = document.createElement('canvas');
16848 canvas.width = w;
16849 canvas.height = h;
16850 this._layer = layer = canvas.getContext('2d');
16851 }
16852
16853 if (isDirty){
16854 this.renderLayerTo(layer, xx, yx, xy, yy, x, y);
16855 this._layerCache = {
16856 xx: xx,
16857 yx: yx,
16858 xy: xy,
16859 yy: yy,
16860 x: x,
16861 y: y
16862 };
16863 }
16864
16865 context.globalAlpha = opacity;
16866 context.setTransform(1, 0, 0, 1, 0, 0);
16867 context.drawImage(
16868 canvas,
16869 0, 0, w, h,
16870 0, 0, w, h
16871 );
16872 context.globalAlpha = 1;
16873 }
16874
16875});
16876
16877var node = CanvasNode;
16878
16879var genericCanvas = typeof document !== 'undefined' && document.createElement('canvas');
16880var genericContext = genericCanvas && genericCanvas.getContext && genericCanvas.getContext('2d');
16881
16882function recolorImage(img, color1, color2){
16883 // TODO: Fix this experimental implementation
16884 color1 = color.detach(color1);
16885 color2 = color.detach(color2);
16886 var canvas = document.createElement('canvas'),
16887 context = canvas.getContext('2d');
16888 canvas.width = img.width;
16889 canvas.height = img.height;
16890 context.fillStyle = color2[0];
16891 context.fillRect(0, 0, img.width, img.height);
16892 context.globalCompositeOperation = 'lighter';
16893 context.drawImage(img, 0, 0);
16894 return canvas;
16895}
16896
16897var Base = _class(node, {
16898
16899 initialize: function(){
16900 this._fill = null;
16901 this._pendingFill = null;
16902 this._fillTransform = null;
16903 this._stroke = null;
16904 this._strokeCap = null;
16905 this._strokeDash = null;
16906 this._strokeJoin = null;
16907 this._strokeWidth = null;
16908 },
16909
16910 /* styles */
16911
16912 _addColors: function(gradient, stops){
16913 // Enumerate stops, assumes offsets are enumerated in order
16914 // TODO: Sort. Chrome doesn't always enumerate in expected order but requires stops to be specified in order.
16915 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++)
16916 gradient.addColorStop(i / l, new color(stops[i]).toString());
16917 else for (var offset in stops)
16918 gradient.addColorStop(offset, new color(stops[offset]).toString());
16919 return gradient;
16920 },
16921
16922
16923 fill: function(color$$1){
16924 if (arguments.length > 1) return this.fillLinear(arguments);
16925 if (this._pendingFill) this._pendingFill();
16926 this._fill = color$$1 ? new color(color$$1).toString() : null;
16927 return this.invalidate();
16928 },
16929
16930 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
16931 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
16932 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
16933 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
16934 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
16935 if (centerX == null) centerX = focusX;
16936 if (centerY == null) centerY = focusY;
16937
16938 centerX += centerX - focusX;
16939 centerY += centerY - focusY;
16940
16941 if (radiusX === 0 || radiusX === '0') return this.fillLinear(stops);
16942 var ys = radiusY / radiusX;
16943
16944 if (this._pendingFill) this._pendingFill();
16945
16946 var gradient = genericContext.createRadialGradient(focusX, focusY / ys, 0, centerX, centerY / ys, radiusX * 2);
16947
16948 // Double fill radius to simulate repeating gradient
16949 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++){
16950 gradient.addColorStop(i / l / 2, new color(stops[i]).toString());
16951 gradient.addColorStop(1 - i / l / 2, new color(stops[i]).toString());
16952 } else for (var offset in stops){
16953 gradient.addColorStop(offset / 2, new color(stops[offset]).toString());
16954 gradient.addColorStop(1- offset / 2, new color(stops[offset]).toString());
16955 }
16956
16957 this._fill = gradient;
16958 this._fillTransform = new transform(1, 0, 0, ys);
16959 return this.invalidate();
16960 },
16961
16962 fillLinear: function(stops, x1, y1, x2, y2){
16963 if (arguments.length < 5){
16964 var angle = ((x1 == null) ? 270 : x1) * Math.PI / 180;
16965
16966 var x = Math.cos(angle), y = -Math.sin(angle),
16967 l = (Math.abs(x) + Math.abs(y)) / 2,
16968 w = this.width || 1, h = this.height || 1;
16969
16970 x *= l; y *= l;
16971
16972 x1 = 0.5 - x;
16973 x2 = 0.5 + x;
16974 y1 = 0.5 - y;
16975 y2 = 0.5 + y;
16976 this._fillTransform = new transform(w, 0, 0, h);
16977 } else {
16978 this._fillTransform = null;
16979 }
16980 if (this._pendingFill) this._pendingFill();
16981 var gradient = genericContext.createLinearGradient(x1, y1, x2, y2);
16982 this._addColors(gradient, stops);
16983 this._fill = gradient;
16984 return this.invalidate();
16985 },
16986
16987 fillImage: function(url, width, height, left, top, color1, color2){
16988 if (this._pendingFill) this._pendingFill();
16989 var img = url;
16990 if (!(img instanceof Image)){
16991 img = new Image();
16992 img.src = url;
16993 }
16994 if (img.width && img.height){
16995 return this._fillImage(img, width, height, left || 0, top || 0, color1, color2);
16996 }
16997
16998 // Not yet loaded
16999 this._fill = null;
17000 var self = this,
17001 callback = function(){
17002 cancel();
17003 self._fillImage(img, width, height, left || 0, top || 0, color1, color2);
17004 },
17005 cancel = function(){
17006 img.removeEventListener('load', callback, false);
17007 self._pendingFill = null;
17008 };
17009 this._pendingFill = cancel;
17010 img.addEventListener('load', callback, false);
17011 return this;
17012 },
17013
17014 _fillImage: function(img, width, height, left, top, color1, color2){
17015 var w = width ? width / img.width : 1,
17016 h = height ? height / img.height : 1;
17017 if (color1 != null) img = recolorImage(img, color1, color2);
17018 this._fill = genericContext.createPattern(img, 'repeat');
17019 this._fillTransform = new transform(w, 0, 0, h, left || 0, top || 0);
17020 return this.invalidate();
17021 },
17022
17023 stroke: function(color$$1, width, cap, join, dash){
17024 this._stroke = color$$1 ? new color(color$$1).toString() : null;
17025 this._strokeWidth = (width != null) ? width : 1;
17026 this._strokeCap = (cap != null) ? cap : 'round';
17027 this._strokeJoin = (join != null) ? join : 'round';
17028 this._strokeDash = dash;
17029 return this.invalidate();
17030 },
17031
17032 // Rendering
17033
17034 element_renderTo: node.prototype.renderTo,
17035
17036 renderTo: function(context, xx, yx, xy, yy, x, y){
17037 var opacity = this._opacity;
17038 if (opacity == null || opacity >= 1){
17039 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
17040 }
17041 if (this._fill && this._stroke){
17042 return this.element_renderTo(context, xx, yx, xy, yy, x, y);
17043 }
17044 context.globalAlpha = opacity;
17045 var r = this.renderLayerTo(context, xx, yx, xy, yy, x, y);
17046 context.globalAlpha = 1;
17047 return r;
17048 },
17049
17050 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
17051 context.setTransform(xx, yx, xy, yy, x, y);
17052 this.renderShapeTo(context);
17053 }
17054
17055});
17056
17057Base._genericContext = genericContext;
17058
17059var base = Base;
17060
17061var shape = _class(base, {
17062
17063 base_initialize: base.prototype.initialize,
17064
17065 initialize: function(path$$1, width, height){
17066 this.base_initialize();
17067 this.width = width;
17068 this.height = height;
17069 if (path$$1 != null) this.draw(path$$1);
17070 },
17071
17072 draw: function(path$$1, width, height){
17073 if (!(path$$1 instanceof path)) path$$1 = new path(path$$1);
17074 this.path = path$$1;
17075 this._commands = path$$1.toCommands();
17076 if (width != null) this.width = width;
17077 if (height != null) this.height = height;
17078 return this.invalidate();
17079 },
17080
17081 localHitTest: function(x, y){
17082 if (!this._fill) return null;
17083 if (this.width == null || this.height == null){
17084 var context = base._genericContext, commands = this._commands;
17085 if (!commands) return null;
17086 context.beginPath();
17087 for (var i = 0, l = commands.length; i < l; i++)
17088 commands[i](context);
17089 return context.isPointInPath(x, y) ? this : null;
17090 }
17091 if (x > 0 && y > 0 && x < this.width && y < this.height){
17092 return this;
17093 }
17094 return null;
17095 },
17096
17097 renderShapeTo: function(context){
17098 if (this._invisible || !this._commands || (!this._fill && !this._stroke)) {
17099 return null;
17100 }
17101 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
17102 var commands = this._commands,
17103 fill = this._fill,
17104 stroke = this._stroke,
17105 dash = this._strokeDash;
17106
17107 context.beginPath();
17108
17109 if (dash) {
17110 if (context.setLineDash) {
17111 context.setLineDash(dash);
17112 } else {
17113 // TODO: Remove when FF supports setLineDash.
17114 context.mozDash = dash;
17115 }
17116 // TODO: Create fallback to other browsers.
17117 } else {
17118 if (context.setLineDash) {
17119 context.setLineDash([]);
17120 } else {
17121 context.mozDash = null;
17122 }
17123 }
17124
17125 for (var i = 0, l = commands.length; i < l; i++)
17126 commands[i](context);
17127
17128 if (fill){
17129 var m = this._fillTransform;
17130 if (m){
17131 context.save(); // TODO: Optimize away this by restoring the transform before stroking
17132 context.transform(m.xx, m.yx, m.xy, m.yy, m.x, m.y);
17133 context.fillStyle = fill;
17134 context.fill();
17135 context.restore();
17136 } else {
17137 context.fillStyle = fill;
17138 context.fill();
17139 }
17140 }
17141 if (stroke){
17142 context.strokeStyle = stroke;
17143 context.lineWidth = this._strokeWidth;
17144 context.lineCap = this._strokeCap;
17145 context.lineJoin = this._strokeJoin;
17146 context.stroke();
17147 }
17148 }
17149
17150});
17151
17152var group = _class(node, container, {
17153
17154 initialize: function(width, height){
17155 this.width = width;
17156 this.height = height;
17157 },
17158
17159 localHitTest: function(x, y){
17160 var node$$2 = this.lastChild;
17161 while (node$$2){
17162 var hit = node$$2.hitTest(x, y);
17163 if (hit) return hit;
17164 node$$2 = node$$2.previousSibling;
17165 }
17166 return null;
17167 },
17168
17169 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
17170 if (this._invisible) return;
17171
17172 x = xx * this.x + xy * this.y + x;
17173 y = yx * this.x + yy * this.y + y;
17174
17175 var t = xx;
17176 xx = t * this.xx + xy * this.yx;
17177 xy = t * this.xy + xy * this.yy;
17178 t = yx;
17179 yx = t * this.xx + yy * this.yx;
17180 yy = t * this.xy + yy * this.yy;
17181
17182 var node$$2 = this.firstChild;
17183 while (node$$2){
17184 node$$2.renderTo(context, xx, yx, xy, yy, x, y);
17185 node$$2 = node$$2.nextSibling;
17186 }
17187 }
17188
17189});
17190
17191var clippingrectangle = _class(node, container, {
17192
17193 initialize: function(width, height){
17194 this.width = width;
17195 this.height = height;
17196 },
17197
17198 localHitTest: function(x, y) {
17199 var node$$2 = this.lastChild;
17200 while (node$$2){
17201 var hit = node$$2.hitTest(x, y);
17202 if (hit) return hit;
17203 node$$2 = node$$2.previousSibling;
17204 }
17205 return null;
17206 },
17207
17208 renderLayerTo: function(context, xx, yx, xy, yy, x, y) {
17209 context.setTransform(xx, yx, xy, yy, x, y);
17210 context.save();
17211 // Need beginPath to fix Firefox bug. See 3354054.
17212 context.beginPath();
17213 context.rect(this.x, this.y, this.width, this.height);
17214 context.clip();
17215
17216 var node$$2 = this.firstChild;
17217 while(node$$2) {
17218 node$$2.renderTo(context, xx, yx, xy, yy, x, y);
17219 node$$2 = node$$2.nextSibling;
17220 }
17221 context.restore();
17222 }
17223});
17224
17225var fontAnchors = { middle: 'center' };
17226
17227var text = _class(base, {
17228
17229 base_initialize: base.prototype.initialize,
17230
17231 initialize: function(text, font, alignment, path){
17232 this.base_initialize();
17233 this.draw.apply(this, arguments);
17234 },
17235
17236 draw: function(text, font, alignment, path){
17237 var em;
17238 if (typeof font == 'string'){
17239 em = Number(/(\d+)/.exec(font)[0]);
17240 } else if (font){
17241 em = parseFloat(font.fontSize || font['font-size'] || '12');
17242 font = (font.fontStyle || font['font-style'] || '') + ' ' +
17243 (font.fontVariant || font['font-variant'] || '') + ' ' +
17244 (font.fontWeight || font['font-weight'] || '') + ' ' +
17245 em + 'px ' +
17246 (font.fontFamily || font['font-family'] || 'Arial');
17247 } else {
17248 font = this._font;
17249 }
17250
17251 var lines = text && text.split(/\r?\n/);
17252 this._font = font;
17253 this._fontSize = em;
17254 this._text = lines;
17255 this._alignment = fontAnchors[alignment] || alignment || 'left';
17256
17257 var context = base._genericContext;
17258
17259 context.font = this._font;
17260 context.textAlign = this._alignment;
17261 context.textBaseline = 'middle';
17262
17263 lines = this._text;
17264 var l = lines.length, width = 0;
17265 for (var i = 0; i < l; i++){
17266 var w = context.measureText(lines[i]).width;
17267 if (w > width) width = w;
17268 }
17269 this.width = width;
17270 this.height = l ? l * 1.1 * em : 0;
17271 return this.invalidate();
17272 },
17273
17274 // Interaction
17275
17276 localHitTest: function(x, y){
17277 if (!this._fill) return null;
17278 if (x > 0 && y > 0 && x < this.width && y < this.height){
17279 return this;
17280 }
17281 return null;
17282 },
17283
17284 // Rendering
17285
17286 renderShapeTo: function(context){
17287 if (this._invisible || !this._text || (!this._fill && !this._stroke)) {
17288 return null;
17289 }
17290 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
17291 var fill = this._fill,
17292 stroke = this._stroke,
17293 text = this._text,
17294 dash = this._strokeDash;
17295
17296 context.font = this._font;
17297 context.textAlign = this._alignment;
17298 context.textBaseline = 'middle';
17299
17300 var em = this._fontSize,
17301 y = em / 2,
17302 lineHeight = 1.1 * em,
17303 lines = text,
17304 l = lines.length;
17305
17306 if (fill){
17307 context.fillStyle = fill;
17308 for (var i = 0; i < l; i++)
17309 context.fillText(lines[i], 0, y + i * lineHeight);
17310 }
17311 if (stroke){
17312 if (dash) {
17313 if (context.setLineDash) {
17314 context.setLineDash(dash);
17315 } else {
17316 // TODO: Remove when FF supports setLineDash.
17317 context.mozDash = dash;
17318 }
17319 // TODO: Create fallback to other browsers.
17320 } else {
17321 if (context.setLineDash) {
17322 context.setLineDash([]);
17323 } else {
17324 context.mozDash = null;
17325 }
17326 }
17327
17328 context.strokeStyle = stroke;
17329 context.lineWidth = this._strokeWidth;
17330 context.lineCap = this._strokeCap;
17331 context.lineJoin = this._strokeJoin;
17332 for (i = 0; i < l; i++)
17333 context.strokeText(lines[i], 0, y + i * lineHeight);
17334 }
17335 }
17336
17337});
17338
17339var VMLCSS = 'behavior:url(#default#VML);display:inline-block;position:absolute;left:0px;top:0px;';
17340
17341var styleSheet;
17342var styledTags = {};
17343var styleTag = function(tag){
17344 if (styleSheet) styledTags[tag] = styleSheet.addRule('av\\:' + tag, VMLCSS);
17345};
17346
17347var init = function(document){
17348
17349 var namespaces;
17350 try { // IE9 workaround: sometimes it throws here
17351 namespaces = document.namespaces;
17352 } catch (e) {
17353 }
17354 if (!namespaces) return false;
17355
17356 namespaces.add('av', 'urn:schemas-microsoft-com:vml');
17357 namespaces.add('ao', 'urn:schemas-microsoft-com:office:office');
17358
17359 styleSheet = document.createStyleSheet();
17360 styleSheet.addRule('vml', 'display:inline-block;position:relative;overflow:hidden;');
17361/* styleTag('skew');
17362 styleTag('fill');
17363 styleTag('stroke');
17364 styleTag('path');
17365 styleTag('textpath');
17366 styleTag('group');*/
17367
17368 styleTag('vml');
17369
17370 return true;
17371
17372};
17373
17374var createElement = function(tag){
17375 if (!(tag in styledTags)) styleTag(tag);
17376 return document.createElement('av:' + tag);
17377};
17378
17379var dom = {
17380 init: init,
17381 createElement: createElement
17382};
17383
17384var precision = 100;
17385
17386var VMLSurface = _class(native_1, container, {
17387
17388 initialize: function VMLSurface(width, height, existingElement){
17389 this.element = existingElement || document.createElement('vml');
17390 this.containerElement = dom.createElement('group');
17391 this.element.appendChild(this.containerElement);
17392 if (width != null && height != null) this.resize(width, height);
17393 },
17394
17395 resize: function(width, height){
17396 this.width = width;
17397 this.height = height;
17398
17399 var style = this.element.style;
17400 style.pixelWidth = width;
17401 style.pixelHeight = height;
17402
17403 style = this.containerElement.style;
17404 style.width = width;
17405 style.height = height;
17406
17407 var halfPixel = (0.5 * precision);
17408
17409 this.containerElement.coordorigin = halfPixel + ',' + halfPixel;
17410 this.containerElement.coordsize = (width * precision) + ',' + (height * precision);
17411
17412 return this;
17413 }
17414
17415});
17416
17417VMLSurface.tagName = 'av:vml';
17418
17419var surface$2 = VMLSurface;
17420
17421var precision$1 = 100;
17422
17423var round = Math.round;
17424
17425var VMLPath = _class(path$2, {
17426
17427 initialize: function(path){
17428 this.reset();
17429 if (path instanceof VMLPath){
17430 this.path = [Array.prototype.join.call(path.path, ' ')];
17431 } else if (path){
17432 if (path.applyToPath)
17433 path.applyToPath(this);
17434 else
17435 this.push(path);
17436 }
17437 },
17438
17439 onReset: function(){
17440 this.path = [];
17441 },
17442
17443 onMove: function(sx, sy, x, y){
17444 this.path.push('m', round(x * precision$1), round(y * precision$1));
17445 },
17446
17447 onLine: function(sx, sy, x, y){
17448 this.path.push('l', round(x * precision$1), round(y * precision$1));
17449 },
17450
17451 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
17452 this.path.push('c',
17453 round(p1x * precision$1), round(p1y * precision$1),
17454 round(p2x * precision$1), round(p2y * precision$1),
17455 round(x * precision$1), round(y * precision$1)
17456 );
17457 },
17458
17459 _arcToBezier: path$2.prototype.onArc,
17460
17461 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
17462 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
17463 cx *= precision$1;
17464 cy *= precision$1;
17465 rx *= precision$1;
17466 this.path.push(ccw ? 'at' : 'wa',
17467 round(cx - rx), round(cy - rx),
17468 round(cx + rx), round(cy + rx),
17469 round(sx * precision$1), round(sy * precision$1),
17470 round(ex * precision$1), round(ey * precision$1)
17471 );
17472 },
17473
17474 onClose: function(){
17475 this.path.push('x');
17476 },
17477
17478 toVML: function(){
17479 return this.path.join(' ');
17480 }
17481
17482});
17483
17484VMLPath.prototype.toString = VMLPath.prototype.toVML;
17485
17486var path$4 = VMLPath;
17487
17488var shadow = _class(dummy, native_1, {
17489
17490 dummy_inject: dummy.prototype.inject,
17491 dummy_injectBefore: dummy.prototype.injectBefore,
17492 dummy_eject: dummy.prototype.eject,
17493 native_inject: native_1.prototype.inject,
17494 native_injectBefore: native_1.prototype.injectBefore,
17495 native_eject: native_1.prototype.eject,
17496
17497 inject: function(container){
17498 this.dummy_inject(container);
17499 this.native_inject(container);
17500 return this;
17501 },
17502
17503 injectBefore: function(sibling){
17504 this.dummy_injectBefore(sibling);
17505 this.native_injectBefore(sibling);
17506 return this;
17507 },
17508
17509 eject: function(){
17510 this.dummy_eject();
17511 this.native_eject();
17512 return this;
17513 }
17514
17515});
17516
17517var node$2 = _class(shadow, transform, {
17518
17519 initialize: function(tag){
17520 //this.uid = uniqueID();
17521 var element = this.element = dom.createElement(tag);
17522 //element.setAttribute('id', 'e' + this.uid);
17523 },
17524
17525 _place: function(){
17526 if (this.parentNode){
17527 this._transform();
17528 }
17529 },
17530
17531 // visibility
17532
17533 hide: function(){
17534 this.element.style.display = 'none';
17535 return this;
17536 },
17537
17538 show: function(){
17539 this.element.style.display = '';
17540 return this;
17541 },
17542
17543 // interaction
17544
17545 indicate: function(cursor, tooltip){
17546 if (cursor) this.element.style.cursor = cursor;
17547 if (tooltip) this.element.title = tooltip;
17548 return this;
17549 }
17550
17551});
17552
17553var precision$3 = 100;
17554
17555var defaultBox = { left: 0, top: 0, width: 500, height: 500 };
17556
17557var base$2 = _class(node$2, {
17558
17559 element_initialize: node$2.prototype.initialize,
17560
17561 initialize: function(tag){
17562 this.element_initialize(tag);
17563 var element = this.element;
17564
17565 var skew = this.skewElement = dom.createElement('skew');
17566 skew.on = true;
17567 element.appendChild(skew);
17568
17569 var fill = this.fillElement = dom.createElement('fill');
17570 fill.on = false;
17571 element.appendChild(fill);
17572
17573 var stroke = this.strokeElement = dom.createElement('stroke');
17574 stroke.on = false;
17575 element.appendChild(stroke);
17576 },
17577
17578 /* transform */
17579
17580 _transform: function(){
17581 var container = this.parentNode;
17582
17583 // Active Transformation Matrix
17584 var m = container ? new transform(container._activeTransform).transform(this) : this;
17585
17586 // Box in shape user space
17587
17588 var box = this._boxCoords || this._size || defaultBox;
17589
17590 var originX = box.left || 0,
17591 originY = box.top || 0,
17592 width = box.width || 1,
17593 height = box.height || 1;
17594
17595 // Flipped
17596 var flip = m.yx / m.xx > m.yy / m.xy;
17597 if (m.xx < 0 ? m.xy >= 0 : m.xy < 0) flip = !flip;
17598 flip = flip ? -1 : 1;
17599
17600 m = new transform().scale(flip, 1).transform(m);
17601
17602 // Rotation is approximated based on the transform
17603 var rotation = Math.atan2(-m.xy, m.yy) * 180 / Math.PI;
17604
17605 // Reverse the rotation, leaving the final transform in box space
17606 var rad = rotation * Math.PI / 180, sin = Math.sin(rad), cos = Math.cos(rad);
17607
17608 var transform$$2 = new transform(
17609 (m.xx * cos - m.xy * sin),
17610 (m.yx * cos - m.yy * sin) * flip,
17611 (m.xy * cos + m.xx * sin) * flip,
17612 (m.yy * cos + m.yx * sin)
17613 );
17614
17615 var rotationTransform = new transform().rotate(rotation, 0, 0);
17616
17617 var shapeToBox = new transform().rotate(-rotation, 0, 0).transform(m).moveTo(0,0);
17618
17619 // Scale box after reversing rotation
17620 width *= Math.abs(shapeToBox.xx);
17621 height *= Math.abs(shapeToBox.yy);
17622
17623 // Place box
17624 var left = m.x, top = m.y;
17625
17626 // Compensate for offset by center origin rotation
17627 var vx = -width / 2, vy = -height / 2;
17628 var point = rotationTransform.point(vx, vy);
17629 left -= point.x - vx;
17630 top -= point.y - vy;
17631
17632 // Adjust box position based on offset
17633 var rsm = new transform(m).moveTo(0,0);
17634 point = rsm.point(originX, originY);
17635 left += point.x;
17636 top += point.y;
17637
17638 if (flip < 0) left = -left - width;
17639
17640 // Place transformation origin
17641 var point0 = rsm.point(-originX, -originY);
17642 var point1 = rotationTransform.point(width, height);
17643 var point2 = rotationTransform.point(width, 0);
17644 var point3 = rotationTransform.point(0, height);
17645
17646 var minX = Math.min(0, point1.x, point2.x, point3.x),
17647 maxX = Math.max(0, point1.x, point2.x, point3.x),
17648 minY = Math.min(0, point1.y, point2.y, point3.y),
17649 maxY = Math.max(0, point1.y, point2.y, point3.y);
17650
17651 var transformOriginX = (point0.x - point1.x / 2) / (maxX - minX) * flip,
17652 transformOriginY = (point0.y - point1.y / 2) / (maxY - minY);
17653
17654 // Adjust the origin
17655 point = shapeToBox.point(originX, originY);
17656 originX = point.x;
17657 originY = point.y;
17658
17659 // Scale stroke
17660 var strokeWidth = this._strokeWidth;
17661 if (strokeWidth){
17662 // Scale is the hypothenus between the two vectors
17663 // TODO: Use area calculation instead
17664 var vx = m.xx + m.xy, vy = m.yy + m.yx;
17665 strokeWidth *= Math.sqrt(vx * vx + vy * vy) / Math.sqrt(2);
17666 }
17667
17668 // convert to multiplied precision space
17669 originX *= precision$3;
17670 originY *= precision$3;
17671 left *= precision$3;
17672 top *= precision$3;
17673 width *= precision$3;
17674 height *= precision$3;
17675
17676 // Set box
17677 var element = this.element;
17678 element.coordorigin = originX + ',' + originY;
17679 element.coordsize = width + ',' + height;
17680 element.style.left = left + 'px';
17681 element.style.top = top + 'px';
17682 element.style.width = width;
17683 element.style.height = height;
17684 element.style.rotation = rotation.toFixed(8);
17685 element.style.flip = flip < 0 ? 'x' : '';
17686
17687 // Set transform
17688 var skew = this.skewElement;
17689 skew.matrix = [transform$$2.xx.toFixed(4), transform$$2.xy.toFixed(4), transform$$2.yx.toFixed(4), transform$$2.yy.toFixed(4), 0, 0];
17690 skew.origin = transformOriginX + ',' + transformOriginY;
17691
17692 // Set stroke
17693 this.strokeElement.weight = strokeWidth + 'px';
17694 },
17695
17696 /* styles */
17697
17698 _createGradient: function(style, stops){
17699 var fill = this.fillElement;
17700
17701 // Temporarily eject the fill from the DOM
17702 this.element.removeChild(fill);
17703
17704 fill.type = style;
17705 fill.method = 'none';
17706 fill.rotate = true;
17707
17708 var colors = [], color1, color2;
17709
17710 var addColor = function(offset, color$$2){
17711 color$$2 = color.detach(color$$2);
17712 if (color1 == null) color1 = color2 = color$$2;
17713 else color2 = color$$2;
17714 colors.push(offset + ' ' + color$$2[0]);
17715 };
17716
17717 // Enumerate stops, assumes offsets are enumerated in order
17718 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++) addColor(i / l, stops[i]);
17719 else for (var offset in stops) addColor(offset, stops[offset]);
17720
17721 fill.color = color1[0];
17722 fill.color2 = color2[0];
17723
17724 //if (fill.colors) fill.colors.value = colors; else
17725 fill.colors = colors;
17726
17727 // Opacity order gets flipped when color stops are specified
17728 fill.opacity = color2[1];
17729 fill['ao:opacity2'] = color1[1];
17730
17731 fill.on = true;
17732 this.element.appendChild(fill);
17733 return fill;
17734 },
17735
17736 _setColor: function(type, color$$2){
17737 var element = type == 'fill' ? this.fillElement : this.strokeElement;
17738 if (color$$2 == null){
17739 element.on = false;
17740 } else {
17741 color$$2 = color.detach(color$$2);
17742 element.color = color$$2[0];
17743 element.opacity = color$$2[1];
17744 element.on = true;
17745 }
17746 },
17747
17748 fill: function(color$$2){
17749 if (arguments.length > 1){
17750 this.fillLinear(arguments);
17751 } else {
17752 this._boxCoords = defaultBox;
17753 var fill = this.fillElement;
17754 fill.type = 'solid';
17755 fill.color2 = '';
17756 fill['ao:opacity2'] = '';
17757 if (fill.colors) fill.colors.value = '';
17758 this._setColor('fill', color$$2);
17759 }
17760 return this;
17761 },
17762
17763 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
17764 var fill = this._createGradient('gradientradial', stops);
17765 if (focusX == null) focusX = this.left + this.width * 0.5;
17766 if (focusY == null) focusY = this.top + this.height * 0.5;
17767 if (radiusY == null) radiusY = radiusX || (this.height * 0.5);
17768 if (radiusX == null) radiusX = this.width * 0.5;
17769 if (centerX == null) centerX = focusX;
17770 if (centerY == null) centerY = focusY;
17771
17772 centerX += centerX - focusX;
17773 centerY += centerY - focusY;
17774
17775 var box = this._boxCoords = {
17776 left: centerX - radiusX * 2,
17777 top: centerY - radiusY * 2,
17778 width: radiusX * 4,
17779 height: radiusY * 4
17780 };
17781 focusX -= box.left;
17782 focusY -= box.top;
17783 focusX /= box.width;
17784 focusY /= box.height;
17785
17786 fill.focussize = '0 0';
17787 fill.focusposition = focusX + ',' + focusY;
17788 fill.focus = '50%';
17789
17790 this._transform();
17791
17792 return this;
17793 },
17794
17795 fillLinear: function(stops, x1, y1, x2, y2){
17796 var fill = this._createGradient('gradient', stops);
17797 fill.focus = '100%';
17798 if (arguments.length == 5){
17799 var w = Math.abs(x2 - x1), h = Math.abs(y2 - y1);
17800 this._boxCoords = {
17801 left: Math.min(x1, x2),
17802 top: Math.min(y1, y2),
17803 width: w < 1 ? h : w,
17804 height: h < 1 ? w : h
17805 };
17806 fill.angle = (360 + Math.atan2((x2 - x1) / h, (y2 - y1) / w) * 180 / Math.PI) % 360;
17807 } else {
17808 this._boxCoords = null;
17809 fill.angle = (x1 == null) ? 0 : (90 + x1) % 360;
17810 }
17811 this._transform();
17812 return this;
17813 },
17814
17815 fillImage: function(url, width, height, left, top, color1, color2){
17816 var fill = this.fillElement;
17817 if (color1 != null){
17818 color1 = color.detach(color1);
17819 if (color2 != null) color2 = color.detach(color2);
17820 fill.type = 'pattern';
17821 fill.color = color1[0];
17822 fill.color2 = color2 == null ? color1[0] : color2[0];
17823 fill.opacity = color2 == null ? 0 : color2[1];
17824 fill['ao:opacity2'] = color1[1];
17825 } else {
17826 fill.type = 'tile';
17827 fill.color = '';
17828 fill.color2 = '';
17829 fill.opacity = 1;
17830 fill['ao:opacity2'] = 1;
17831 }
17832 if (fill.colors) fill.colors.value = '';
17833 fill.rotate = true;
17834 fill.src = url;
17835
17836 fill.size = '1,1';
17837 fill.position = '0,0';
17838 fill.origin = '0,0';
17839 fill.aspect = 'ignore'; // ignore, atleast, atmost
17840 fill.on = true;
17841
17842 if (!left) left = 0;
17843 if (!top) top = 0;
17844 this._boxCoords = width ? { left: left + 0.5, top: top + 0.5, width: width, height: height } : null;
17845 this._transform();
17846 return this;
17847 },
17848
17849 /* stroke */
17850
17851 stroke: function(color$$2, width, cap, join){
17852 var stroke = this.strokeElement;
17853 this._strokeWidth = (width != null) ? width : 1;
17854 stroke.weight = (width != null) ? width + 'px' : 1;
17855 stroke.endcap = (cap != null) ? ((cap == 'butt') ? 'flat' : cap) : 'round';
17856 stroke.joinstyle = (join != null) ? join : 'round';
17857
17858 this._setColor('stroke', color$$2);
17859 return this;
17860 }
17861
17862});
17863
17864var precision$2 = 100;
17865
17866var shape$2 = _class(base$2, {
17867
17868 base_initialize: base$2.prototype.initialize,
17869
17870 initialize: function(path, width, height){
17871 this.base_initialize('shape');
17872
17873 var p = this.pathElement = dom.createElement('path');
17874 p.gradientshapeok = true;
17875 this.element.appendChild(p);
17876
17877 this.width = width;
17878 this.height = height;
17879
17880 if (path != null) this.draw(path);
17881 },
17882
17883 // SVG to VML
17884
17885 draw: function(path, width, height){
17886
17887 if (!(path instanceof path$4)) path = new path$4(path);
17888 this._vml = path.toVML();
17889 //this._size = path.measure();
17890
17891 if (width != null) this.width = width;
17892 if (height != null) this.height = height;
17893
17894 if (!this._boxCoords) this._transform();
17895 this._redraw(this._prefix, this._suffix);
17896
17897 return this;
17898 },
17899
17900 // radial gradient workaround
17901
17902 _redraw: function(prefix, suffix){
17903 var vml = this._vml || '';
17904
17905 this._prefix = prefix;
17906 this._suffix = suffix;
17907 if (prefix){
17908 vml = [
17909 prefix, vml, suffix,
17910 // Don't stroke the path with the extra ellipse, redraw the stroked path separately
17911 'ns e', vml, 'nf'
17912 ].join(' ');
17913 }
17914
17915 this.element.path = vml + 'e';
17916 },
17917
17918 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
17919 var fill = this._createGradient('gradientradial', stops);
17920 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
17921 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
17922 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
17923 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
17924 if (centerX == null) centerX = focusX;
17925 if (centerY == null) centerY = focusY;
17926
17927 centerX += centerX - focusX;
17928 centerY += centerY - focusY;
17929
17930 var cx = Math.round(centerX * precision$2),
17931 cy = Math.round(centerY * precision$2),
17932
17933 rx = Math.round(radiusX * 2 * precision$2),
17934 ry = Math.round(radiusY * 2 * precision$2),
17935
17936 arc = ['wa', cx - rx, cy - ry, cx + rx, cy + ry].join(' ');
17937
17938 this._redraw(
17939 // Resolve rendering bug
17940 ['m', cx, cy - ry, 'l', cx, cy - ry].join(' '),
17941 // Draw an ellipse around the path to force an elliptical gradient on any shape
17942 [
17943 'm', cx, cy - ry,
17944 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry,
17945 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry
17946 ].join(' ')
17947 );
17948
17949 this._boxCoords = { left: focusX - 2, top: focusY - 2, width: 4, height: 4 };
17950
17951 fill.focusposition = '0.5,0.5';
17952 fill.focussize = '0 0';
17953 fill.focus = '50%';
17954
17955 this._transform();
17956
17957 return this;
17958 }
17959
17960});
17961
17962var group$2 = _class(node$2, container, {
17963
17964 element_initialize: node$2.prototype.initialize,
17965
17966 initialize: function(width, height){
17967 this.element_initialize('group');
17968 this.width = width;
17969 this.height = height;
17970 },
17971
17972 _transform: function(){
17973 var element = this.element;
17974 element.coordorigin = '0,0';
17975 element.coordsize = '1000,1000';
17976 element.style.left = 0;
17977 element.style.top = 0;
17978 element.style.width = 1000;
17979 element.style.height = 1000;
17980 element.style.rotation = 0;
17981
17982 var container$$2 = this.parentNode;
17983 this._activeTransform = container$$2 ? new transform(container$$2._activeTransform).transform(this) : this;
17984 var node = this.firstChild;
17985 while (node){
17986 node._transform();
17987 node = node.nextSibling;
17988 }
17989 }
17990
17991});
17992
17993var clippingrectangle$2 = _class(node$2, container, {
17994
17995 element_initialize: node$2.prototype.initialize,
17996
17997 initialize: function(width, height){
17998 this.element_initialize('clippingrectangle');
17999 this.width = width;
18000 this.height = height;
18001 },
18002
18003 _transform: function(){
18004 var element = this.element;
18005 element.clip = true;
18006 element.coordorigin = -this.x + ',' + (-1 * this.y);
18007 element.coordsize = this.width + ',' + this.height;
18008 // IE8 doesn't like clipBottom. Don't ask me why.
18009 // element.style.clipBottom = this.height + this.y;
18010 element.style.clipLeft = this.x;
18011 element.style.clipRight = this.width + this.x;
18012 element.style.clipTop = this.y;
18013 element.style.left = -this.x;
18014 element.style.top = -this.y;
18015 element.style.width = this.width + this.x;
18016 element.style.height = this.height + this.y;
18017 element.style.rotation = 0;
18018
18019 var container$$2 = this.parentNode;
18020 this._activeTransform = container$$2 ? new transform(container$$2._activeTransform).transform(this) : this;
18021 var node = this.firstChild;
18022 while (node){
18023 node._transform();
18024 node = node.nextSibling;
18025 }
18026 }
18027
18028});
18029
18030var fontAnchors$1 = { start: 'left', middle: 'center', end: 'right' };
18031
18032var text$2 = _class(base$2, {
18033
18034 base_initialize: base$2.prototype.initialize,
18035
18036 initialize: function(text, font, alignment, path){
18037 this.base_initialize('shape');
18038
18039 var p = this.pathElement = dom.createElement('path');
18040 p.textpathok = true;
18041 this.element.appendChild(p);
18042
18043 p = this.textPathElement = dom.createElement("textpath");
18044 p.on = true;
18045 p.style['v-text-align'] = 'left';
18046 this.element.appendChild(p);
18047
18048 this.draw.apply(this, arguments);
18049 },
18050
18051 draw: function(text, font, alignment, path){
18052 var element = this.element,
18053 textPath = this.textPathElement,
18054 style = textPath.style;
18055
18056 textPath.string = text;
18057
18058 if (font){
18059 if (typeof font == 'string'){
18060 style.font = font;
18061 } else {
18062 for (var key in font){
18063 var ckey = key.camelCase ? key.camelCase() : key;
18064 if (ckey == 'fontFamily') style[ckey] = "'" + font[key] + "'";
18065 // NOT UNIVERSALLY SUPPORTED OPTIONS
18066 // else if (ckey == 'kerning') style['v-text-kern'] = !!font[key];
18067 // else if (ckey == 'rotateGlyphs') style['v-rotate-letters'] = !!font[key];
18068 // else if (ckey == 'letterSpacing') style['v-text-spacing'] = Number(font[key]) + '';
18069 else style[ckey] = font[key];
18070 }
18071 }
18072 }
18073
18074 if (alignment) style['v-text-align'] = fontAnchors$1[alignment] || alignment;
18075
18076 if (path){
18077 this.currentPath = path = new path$4(path);
18078 this.element.path = path.toVML();
18079 } else if (!this.currentPath){
18080 var i = -1, offsetRows = '\n';
18081 while ((i = text.indexOf('\n', i + 1)) > -1) offsetRows += '\n';
18082 textPath.string = offsetRows + textPath.string;
18083 this.element.path = 'm0,0l1,0';
18084 }
18085
18086 // Measuring the bounding box is currently necessary for gradients etc.
18087
18088 // Clone element because the element is dead once it has been in the DOM
18089 element = element.cloneNode(true);
18090 style = element.style;
18091
18092 // Reset coordinates while measuring
18093 element.coordorigin = '0,0';
18094 element.coordsize = '10000,10000';
18095 style.left = '0px';
18096 style.top = '0px';
18097 style.width = '10000px';
18098 style.height = '10000px';
18099 style.rotation = 0;
18100 element.removeChild(element.firstChild); // Remove skew
18101
18102 // Inject the clone into the document
18103
18104 var canvas = new surface$2(1, 1),
18105 group = new group$2(), // Wrapping it in a group seems to alleviate some client rect weirdness
18106 body = element.ownerDocument.body;
18107
18108 canvas.inject(body);
18109 group.element.appendChild(element);
18110 group.inject(canvas);
18111
18112 var ebb = element.getBoundingClientRect(),
18113 cbb = canvas.toElement().getBoundingClientRect();
18114
18115 canvas.eject();
18116
18117 this.left = ebb.left - cbb.left;
18118 this.top = ebb.top - cbb.top;
18119 this.width = ebb.right - ebb.left;
18120 this.height = ebb.bottom - ebb.top;
18121 this.right = ebb.right - cbb.left;
18122 this.bottom = ebb.bottom - cbb.top;
18123
18124 this._transform();
18125
18126 //this._size = { left: this.left, top: this.top, width: this.width, height: this.height};
18127 return this;
18128 }
18129
18130});
18131
18132var fastNoSideEffects = createCommonjsModule(function (module, exports) {
18133var hasCanvas = function(){
18134
18135 var canvas = document.createElement('canvas');
18136 return canvas && !!canvas.getContext;
18137
18138};
18139
18140if (hasCanvas()) {
18141 exports.Surface = surface;
18142 exports.Path = path;
18143 exports.Shape = shape;
18144 exports.Group = group;
18145 exports.ClippingRectangle = clippingrectangle;
18146 exports.Text = text;
18147} else {
18148 exports.Surface = surface$2;
18149 exports.Path = path$4;
18150 exports.Shape = shape$2;
18151 exports.Group = group$2;
18152 exports.ClippingRectangle = clippingrectangle$2;
18153 exports.Text = text$2;
18154
18155 var DOM$$1 = dom;
18156 if (typeof document !== 'undefined') DOM$$1.init(document);
18157}
18158});
18159
18160var fastNoSideEffects_1 = fastNoSideEffects.Surface;
18161var fastNoSideEffects_2 = fastNoSideEffects.Path;
18162var fastNoSideEffects_3 = fastNoSideEffects.Shape;
18163var fastNoSideEffects_4 = fastNoSideEffects.Group;
18164var fastNoSideEffects_5 = fastNoSideEffects.ClippingRectangle;
18165var fastNoSideEffects_6 = fastNoSideEffects.Text;
18166
18167var _extends = _assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
18168
18169function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
18170
18171function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
18172
18173function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18174
18175current.setCurrent(
18176// Change to 'art/modes/dom' for easier debugging via SVG
18177fastNoSideEffects);
18178
18179/** Declarative fill-type objects; API design not finalized */
18180
18181var slice = Array.prototype.slice;
18182
18183var LinearGradient = function () {
18184 function LinearGradient(stops, x1, y1, x2, y2) {
18185 _classCallCheck(this, LinearGradient);
18186
18187 this._args = slice.call(arguments);
18188 }
18189
18190 LinearGradient.prototype.applyFill = function applyFill(node) {
18191 node.fillLinear.apply(node, this._args);
18192 };
18193
18194 return LinearGradient;
18195}();
18196
18197var RadialGradient = function () {
18198 function RadialGradient(stops, fx, fy, rx, ry, cx, cy) {
18199 _classCallCheck(this, RadialGradient);
18200
18201 this._args = slice.call(arguments);
18202 }
18203
18204 RadialGradient.prototype.applyFill = function applyFill(node) {
18205 node.fillRadial.apply(node, this._args);
18206 };
18207
18208 return RadialGradient;
18209}();
18210
18211var Pattern = function () {
18212 function Pattern(url, width, height, left, top) {
18213 _classCallCheck(this, Pattern);
18214
18215 this._args = slice.call(arguments);
18216 }
18217
18218 Pattern.prototype.applyFill = function applyFill(node) {
18219 node.fillImage.apply(node, this._args);
18220 };
18221
18222 return Pattern;
18223}();
18224
18225/** React Components */
18226
18227var Surface = function (_React$Component) {
18228 _inherits(Surface, _React$Component);
18229
18230 function Surface() {
18231 _classCallCheck(this, Surface);
18232
18233 return _possibleConstructorReturn(this, _React$Component.apply(this, arguments));
18234 }
18235
18236 Surface.prototype.componentDidMount = function componentDidMount() {
18237 var _props = this.props,
18238 height = _props.height,
18239 width = _props.width;
18240
18241
18242 this._surface = current.Surface(+width, +height, this._tagRef);
18243
18244 this._mountNode = createContainer(this._surface, LegacyRoot, false);
18245 updateContainer(this.props.children, this._mountNode, this);
18246 };
18247
18248 Surface.prototype.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
18249 var props = this.props;
18250
18251 if (props.height !== prevProps.height || props.width !== prevProps.width) {
18252 this._surface.resize(+props.width, +props.height);
18253 }
18254
18255 updateContainer(this.props.children, this._mountNode, this);
18256
18257 if (this._surface.render) {
18258 this._surface.render();
18259 }
18260 };
18261
18262 Surface.prototype.componentWillUnmount = function componentWillUnmount() {
18263 updateContainer(null, this._mountNode, this);
18264 };
18265
18266 Surface.prototype.render = function render() {
18267 var _this2 = this;
18268
18269 // This is going to be a placeholder because we don't know what it will
18270 // actually resolve to because ART may render canvas, vml or svg tags here.
18271 // We only allow a subset of properties since others might conflict with
18272 // ART's properties.
18273 var props = this.props;
18274
18275 // TODO: ART's Canvas Mode overrides surface title and cursor
18276 var Tag = current.Surface.tagName;
18277
18278 return React.createElement(Tag, {
18279 ref: function (ref) {
18280 return _this2._tagRef = ref;
18281 },
18282 accessKey: props.accessKey,
18283 className: props.className,
18284 draggable: props.draggable,
18285 role: props.role,
18286 style: props.style,
18287 tabIndex: props.tabIndex,
18288 title: props.title
18289 });
18290 };
18291
18292 return Surface;
18293}(React.Component);
18294
18295var Text = function (_React$Component2) {
18296 _inherits(Text, _React$Component2);
18297
18298 function Text(props) {
18299 _classCallCheck(this, Text);
18300
18301 // We allow reading these props. Ideally we could expose the Text node as
18302 // ref directly.
18303 var _this3 = _possibleConstructorReturn(this, _React$Component2.call(this, props));
18304
18305 ['height', 'width', 'x', 'y'].forEach(function (key) {
18306 Object.defineProperty(_this3, key, {
18307 get: function () {
18308 return this._text ? this._text[key] : undefined;
18309 }
18310 });
18311 });
18312 return _this3;
18313 }
18314
18315 Text.prototype.render = function render() {
18316 var _this4 = this;
18317
18318 // This means you can't have children that render into strings...
18319 var T = TYPES.TEXT;
18320 return React.createElement(
18321 T,
18322 _extends({}, this.props, { ref: function (t) {
18323 return _this4._text = t;
18324 } }),
18325 childrenAsString(this.props.children)
18326 );
18327 };
18328
18329 return Text;
18330}(React.Component);
18331
18332injectIntoDevTools({
18333 findFiberByHostInstance: function () {
18334 return null;
18335 },
18336 bundleType: 1,
18337 version: ReactVersion,
18338 rendererPackageName: 'react-art'
18339});
18340
18341/** API */
18342
18343var ClippingRectangle = TYPES.CLIPPING_RECTANGLE;
18344var Group = TYPES.GROUP;
18345var Shape = TYPES.SHAPE;
18346var Path = current.Path;
18347
18348
18349var ReactART = Object.freeze({
18350 ClippingRectangle: ClippingRectangle,
18351 Group: Group,
18352 Shape: Shape,
18353 Path: Path,
18354 LinearGradient: LinearGradient,
18355 Pattern: Pattern,
18356 RadialGradient: RadialGradient,
18357 Surface: Surface,
18358 Text: Text,
18359 Transform: transform
18360});
18361
18362var reactArt = ReactART;
18363
18364return reactArt;
18365
18366})));